00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 #ifndef GEOS_OPVALID_H
00063 #define GEOS_OPVALID_H
00064
00065 #include <memory>
00066 #include <string>
00067 #include <vector>
00068 #include <map>
00069 #include <geos/platform.h>
00070 #include <geos/opRelate.h>
00071 #include <geos/indexSweepline.h>
00072 #include <geos/indexQuadtree.h>
00073
00074 namespace geos {
00075
00076
00077
00078
00079
00080
00081
00082 class SimpleNestedRingTester {
00083 public:
00084 SimpleNestedRingTester(GeometryGraph *newGraph);
00085 ~SimpleNestedRingTester();
00086 void add(LinearRing *ring);
00087 Coordinate& getNestedPoint();
00088 bool isNonNested();
00089 private:
00090 CGAlgorithms *cga;
00091 GeometryGraph *graph;
00092 vector<LinearRing*> *rings;
00093 Coordinate nestedPt;
00094 };
00095
00096
00097
00098
00099
00100
00101 class TopologyValidationError {
00102 public:
00103 enum errorEnum {
00104 eError,
00105 REPEATED_POINT,
00106 HOLE_OUTSIDE_SHELL,
00107 NESTED_HOLES,
00108 DISCONNECTED_INTERIOR,
00109 SELF_INTERSECTION,
00110 RING_SELF_INTERSECTION,
00111 NESTED_SHELLS,
00112 DUPLICATE_RINGS,
00113 TOO_FEW_POINTS,
00114 INVALID_COORDINATE
00115 };
00116
00117 TopologyValidationError(int newErrorType,Coordinate newPt);
00118 TopologyValidationError(int newErrorType);
00119 Coordinate& getCoordinate();
00120 string getMessage();
00121 int getErrorType();
00122 string toString();
00123 private:
00124 static string errMsg[];
00125 int errorType;
00126 Coordinate pt;
00127 };
00128
00129
00130
00131
00132
00133
00134 class RepeatedPointTester {
00135 public:
00136 RepeatedPointTester() {};
00137 Coordinate& getCoordinate();
00138 bool hasRepeatedPoint(const Geometry *g);
00139 bool hasRepeatedPoint(const CoordinateSequence *coord);
00140 private:
00141 Coordinate repeatedCoord;
00142 bool hasRepeatedPoint(const Polygon *p);
00143 bool hasRepeatedPoint(const GeometryCollection *gc);
00144 bool hasRepeatedPoint(const MultiPolygon *gc);
00145 bool hasRepeatedPoint(const MultiLineString *gc);
00146 };
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161 class ConsistentAreaTester {
00162 private:
00163 LineIntersector *li;
00164 GeometryGraph *geomGraph;
00165 RelateNodeGraph *nodeGraph;
00166
00167 Coordinate invalidPoint;
00172 bool isNodeEdgeAreaLabelsConsistent();
00173 public:
00174 ConsistentAreaTester(GeometryGraph *newGeomGraph);
00175 ~ConsistentAreaTester();
00179 Coordinate& getInvalidPoint();
00180 bool isNodeConsistentArea();
00196 bool hasDuplicateRings();
00197 };
00198
00199
00200
00201
00202
00203
00204
00205
00206 class SweeplineNestedRingTester {
00207 public:
00208 SweeplineNestedRingTester(GeometryGraph *newGraph);
00209 ~SweeplineNestedRingTester();
00210 Coordinate& getNestedPoint();
00211 void add(LinearRing* ring);
00212 bool isNonNested();
00213 bool isInside(LinearRing *innerRing,LinearRing *searchRing);
00214 class OverlapAction: public SweepLineOverlapAction {
00215 public:
00216 bool isNonNested;
00217 OverlapAction(SweeplineNestedRingTester *p);
00218 void overlap(SweepLineInterval *s0, SweepLineInterval *s1);
00219 private:
00220 SweeplineNestedRingTester *parent;
00221 };
00222 private:
00223 CGAlgorithms *cga;
00224 GeometryGraph *graph;
00225 vector<LinearRing*> *rings;
00226 Envelope *totalEnv;
00227 SweepLineIndex *sweepLine;
00228 Coordinate nestedPt;
00229 void buildIndex();
00230 };
00231
00232
00233
00234
00235
00236
00237
00238 class QuadtreeNestedRingTester {
00239 public:
00240 QuadtreeNestedRingTester(GeometryGraph *newGraph);
00241 virtual ~QuadtreeNestedRingTester();
00242 Coordinate& getNestedPoint();
00243 void add(LinearRing *ring);
00244 bool isNonNested();
00245 private:
00246 GeometryGraph *graph;
00247 vector<LinearRing*> *rings;
00248 Envelope *totalEnv;
00249 Quadtree *qt;
00250 Coordinate nestedPt;
00251 void buildQuadtree();
00252 };
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266 class ConnectedInteriorTester {
00267 public:
00268 ConnectedInteriorTester(GeometryGraph *newGeomGraph);
00269 ~ConnectedInteriorTester();
00270 Coordinate& getCoordinate();
00271 bool isInteriorsConnected();
00272 static const Coordinate& findDifferentPoint(const CoordinateSequence *coord, const Coordinate& pt);
00273 private:
00274 GeometryFactory *geometryFactory;
00275 CGAlgorithms *cga;
00276 GeometryGraph *geomGraph;
00277
00278
00279 Coordinate disconnectedRingcoord;
00280 void setAllEdgesInResult(PlanarGraph *graph);
00281 vector<EdgeRing*>* buildEdgeRings(vector<EdgeEnd*> *dirEdges);
00286 void visitShellInteriors(const Geometry *g, PlanarGraph *graph);
00287 void visitInteriorRing(const LineString *ring, PlanarGraph *graph);
00298 bool hasUnvisitedShellEdge(vector<EdgeRing*> *edgeRings);
00299 protected:
00300 void visitLinkedDirectedEdges(DirectedEdge *start);
00301 };
00302
00303
00304
00305
00306
00307
00308 class IsValidOp {
00309 friend class Unload;
00310 public:
00317 static const Coordinate& findPtNotNode(const CoordinateSequence *testCoords,const LinearRing *searchRing, GeometryGraph *graph);
00318
00327 static bool isValid(const Coordinate &coord);
00328
00329 IsValidOp(const Geometry *geom);
00330 virtual ~IsValidOp();
00331 bool isValid();
00332 TopologyValidationError* getValidationError();
00333 private:
00334 const Geometry *parentGeometry;
00335 bool isChecked;
00336 TopologyValidationError* validErr;
00337 void checkValid(const Geometry *g);
00338 void checkValid(const Point *g);
00339 void checkValid(const LinearRing *g);
00340 void checkValid(const LineString *g);
00341 void checkValid(const Polygon *g);
00342 void checkValid(const MultiPolygon *g);
00343 void checkValid(const GeometryCollection *gc);
00344 void checkConsistentArea(GeometryGraph *graph);
00345 void checkNoSelfIntersectingRings(GeometryGraph *graph);
00351 void checkSelfIntersectingRing(EdgeIntersectionList *eiList);
00352 void checkTooFewPoints(GeometryGraph *graph);
00361 void checkHolesInShell(const Polygon *p,GeometryGraph *graph);
00362
00375 void checkHolesNotNested(const Polygon *p,GeometryGraph *graph);
00376
00390 void checkShellsNotNested(const MultiPolygon *mp,GeometryGraph *graph);
00400 void checkShellNotNested(const LinearRing *shell,const Polygon *p,GeometryGraph *graph);
00404 const Coordinate& checkShellInsideHole(const LinearRing *shell,const LinearRing *hole,GeometryGraph *graph);
00405 void checkConnectedInteriors(GeometryGraph *graph);
00406 void checkInvalidCoordinates(const CoordinateSequence *cs);
00407 void checkInvalidCoordinates(const Polygon *poly);
00408 };
00409
00410 }
00411 #endif