isvalidop.cpp
来自「一个很好的vc底层代码」· C++ 代码 · 共 570 行 · 第 1/2 页
CPP
570 行
/********************************************************************** * $Id: IsValidOp.cpp,v 1.27.2.1 2005/05/23 16:57:05 strk Exp $ * * GEOS - Geometry Engine Open Source * http://geos.refractions.net * * Copyright (C) 2001-2002 Vivid Solutions Inc. * * This is free software; you can redistribute and/or modify it under * the terms of the GNU Lesser General Public Licence as published * by the Free Software Foundation. * See the COPYING file for more information. * **********************************************************************/#include <geos/opValid.h>#include <stdio.h>#include <typeinfo>#include <set>#include <geos/util.h>namespace geos {const Coordinate& IsValidOp::findPtNotNode(const CoordinateSequence *testCoords,const LinearRing *searchRing, GeometryGraph *graph) { // find edge corresponding to searchRing. Edge *searchEdge=graph->findEdge(searchRing); // find a point in the testCoords which is not a node of the searchRing EdgeIntersectionList *eiList=searchEdge->getEdgeIntersectionList(); // somewhat inefficient - is there a better way? (Use a node map, for instance?) for(int i=0;i<testCoords->getSize(); i++) { const Coordinate& pt=testCoords->getAt(i); if (!eiList->isIntersection(pt)) { return pt; } } return Coordinate::getNull();}IsValidOp::IsValidOp(const Geometry *geom){ isChecked=false; validErr=NULL; parentGeometry=geom;}IsValidOp::~IsValidOp(){ delete validErr;}bool IsValidOp::isValid() { checkValid(parentGeometry); return validErr==NULL;}/* * Checks whether a coordinate is valid for processing. * Coordinates are valid iff their x and y coordinates are in the * range of the floating point representation. * * @param coord the coordinate to validate * @return <code>true</code> if the coordinate is valid */bool IsValidOp::isValid(const Coordinate &coord) { if (! finite(coord.x) ) return false; if (! finite(coord.y) ) return false; return true;}TopologyValidationError *IsValidOp::getValidationError(){ checkValid(parentGeometry); return validErr;}voidIsValidOp::checkValid(const Geometry *g){ const GeometryCollection *gc; if (isChecked) return; validErr=NULL; if (g->isEmpty()) return; if (typeid(*g)==typeid(Point)) checkValid((Point *)g); else if (typeid(*g)==typeid(LinearRing)) checkValid((LinearRing*)g); else if (typeid(*g)==typeid(LineString)) checkValid((LineString*)g); else if (typeid(*g)==typeid(Polygon)) checkValid((Polygon*)g); else if (typeid(*g)==typeid(MultiPolygon)) checkValid((MultiPolygon*)g); else if ((gc=dynamic_cast<const GeometryCollection *>(g))) checkValid(gc); else throw new UnsupportedOperationException();}/* * Checks validity of a Point. */void IsValidOp::checkValid(const Point *g){ CoordinateSequence *cs = g->getCoordinates(); checkInvalidCoordinates(cs); delete cs;}/* * Checks validity of a LineString. Almost anything goes for linestrings! */void IsValidOp::checkValid(const LineString *g){ checkInvalidCoordinates(g->getCoordinatesRO()); if (validErr != NULL) return; GeometryGraph *graph=new GeometryGraph(0,g); checkTooFewPoints(graph); delete graph;}/*** Checks validity of a LinearRing.*/void IsValidOp::checkValid(const LinearRing *g){ checkInvalidCoordinates(g->getCoordinatesRO()); if (validErr != NULL) return; GeometryGraph *graph = new GeometryGraph(0, g); checkTooFewPoints(graph); if (validErr!=NULL) { delete graph; return; } LineIntersector *li = new RobustLineIntersector(); delete graph->computeSelfNodes(li, true); checkNoSelfIntersectingRings(graph); delete li; delete graph;}/*** Checks the validity of a polygon.* Sets the validErr flag.*/void IsValidOp::checkValid(const Polygon *g){ checkInvalidCoordinates(g); if (validErr != NULL) return; auto_ptr<GeometryGraph> graph(new GeometryGraph(0,g)); checkTooFewPoints(graph.get()); if (validErr!=NULL) { return; } checkConsistentArea(graph.get()); if (validErr!=NULL) { return; } checkNoSelfIntersectingRings(graph.get()); if (validErr!=NULL) { return; } checkHolesInShell(g,graph.get()); if (validErr!=NULL) { return; } //SLOWcheckHolesNotNested(g); checkHolesNotNested(g,graph.get()); if (validErr!=NULL) { return; } checkConnectedInteriors(graph.get());}voidIsValidOp::checkValid(const MultiPolygon *g){ for (int i=0; i<g->getNumGeometries(); i++) { checkInvalidCoordinates((const Polygon *)g->getGeometryN(i)); if (validErr != NULL) return; } GeometryGraph *graph=new GeometryGraph(0,g); checkTooFewPoints(graph); if (validErr!=NULL) { delete graph; return; } checkConsistentArea(graph); if (validErr!=NULL) { delete graph; return; } checkNoSelfIntersectingRings(graph); if (validErr!=NULL) { delete graph; return; } for(int i=0;i<g->getNumGeometries();i++) { Polygon *p=(Polygon*)g->getGeometryN(i); checkHolesInShell(p,graph); if (validErr!=NULL) { delete graph; return; } } for(int i=0;i<g->getNumGeometries();i++) { Polygon *p=(Polygon*)g->getGeometryN(i); //checkDisjointHolesNotNested(p); checkHolesNotNested(p,graph); if (validErr!=NULL) { delete graph; return; } } checkShellsNotNested(g,graph); if (validErr!=NULL) { delete graph; return; } checkConnectedInteriors(graph); delete graph;}void IsValidOp::checkValid(const GeometryCollection *gc) { for(int i=0;i<gc->getNumGeometries();i++) { const Geometry *g=gc->getGeometryN(i); checkValid(g); if (validErr!=NULL) return; }}void IsValidOp::checkTooFewPoints(GeometryGraph *graph) { if (graph->hasTooFewPoints()) { validErr=new TopologyValidationError( TopologyValidationError::TOO_FEW_POINTS, graph->getInvalidPoint()); return; }}void IsValidOp::checkConsistentArea(GeometryGraph *graph) { auto_ptr<ConsistentAreaTester> cat(new ConsistentAreaTester(graph)); bool isValidArea=cat->isNodeConsistentArea(); if (!isValidArea) { validErr=new TopologyValidationError( TopologyValidationError::SELF_INTERSECTION, cat->getInvalidPoint()); return; } if (cat->hasDuplicateRings()) { validErr=new TopologyValidationError( TopologyValidationError::DUPLICATE_RINGS, cat->getInvalidPoint()); }}void IsValidOp::checkNoSelfIntersectingRings(GeometryGraph *graph) { vector<Edge*> *edges=graph->getEdges(); for(int i=0;i<(int)edges->size();i++) { Edge *e=(*edges)[i]; checkSelfIntersectingRing(e->getEdgeIntersectionList()); if(validErr!=NULL) return; }}/*** check that a ring does not self-intersect, except at its endpoints.* Algorithm is to count the number of times each node along edge occurs.* If any occur more than once, that must be a self-intersection.*/void IsValidOp::checkSelfIntersectingRing(EdgeIntersectionList *eiList) { set<Coordinate,CoordLT> *nodeSet=new set<Coordinate,CoordLT>(); bool isFirst=true; vector<EdgeIntersection*> *l=eiList->list; for(int i=0;i<(int)l->size();i++) { EdgeIntersection *ei=(*l)[i]; if (isFirst) { isFirst=false; continue; } if (nodeSet->find(ei->coord)!=nodeSet->end()) { validErr=new TopologyValidationError( TopologyValidationError::RING_SELF_INTERSECTION, ei->coord); delete nodeSet; return; } else { nodeSet->insert(ei->coord); } } delete nodeSet;}/* NO LONGER NEEDED AS OF JTS Ver 1.2
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?