opValid.h

00001 /**********************************************************************
00002  * $Id: opValid.h,v 1.7.4.1 2006/05/16 14:38:07 strk Exp $
00003  *
00004  * GEOS - Geometry Engine Open Source
00005  * http://geos.refractions.net
00006  *
00007  * Copyright (C) 2001-2002 Vivid Solutions Inc.
00008  *
00009  * This is free software; you can redistribute and/or modify it under
00010  * the terms of the GNU Lesser General Public Licence as published
00011  * by the Free Software Foundation. 
00012  * See the COPYING file for more information.
00013  *
00014  **********************************************************************
00015  * $Log: opValid.h,v $
00016  * Revision 1.7.4.1  2006/05/16 14:38:07  strk
00017  * Gave error enum a name and renamed ERROR to eError (to avoid clash with
00018  * win32 headers)
00019  *
00020  * Revision 1.7  2004/11/05 11:41:57  strk
00021  * Made IsValidOp handle IllegalArgumentException throw from GeometryGraph
00022  * as a sign of invalidity (just for Polygon geometries).
00023  * Removed leaks generated by this specific exception.
00024  *
00025  * Revision 1.6  2004/09/13 12:39:14  strk
00026  * Made Point and MultiPoint subject to Validity tests.
00027  *
00028  * Revision 1.5  2004/09/13 10:12:49  strk
00029  * Added invalid coordinates checks in IsValidOp.
00030  * Cleanups.
00031  *
00032  * Revision 1.4  2004/09/13 09:18:10  strk
00033  * Added IsValidOp::isValid(Coordinate &)
00034  *
00035  * Revision 1.3  2004/07/19 13:19:31  strk
00036  * Documentation fixes
00037  *
00038  * Revision 1.2  2004/07/08 19:34:49  strk
00039  * Mirrored JTS interface of CoordinateSequence, factory and
00040  * default implementations.
00041  * Added DefaultCoordinateSequenceFactory::instance() function.
00042  *
00043  * Revision 1.1  2004/07/02 13:20:42  strk
00044  * Header files moved under geos/ dir.
00045  *
00046  * Revision 1.15  2004/05/18 00:02:37  ybychkov
00047  * IsValidOp::checkShellNotNested() bugfix from JTS 1.4.1 (not released yet) has been added.
00048  *
00049  * Revision 1.14  2004/03/29 06:59:24  ybychkov
00050  * "noding/snapround" package ported (JTS 1.4);
00051  * "operation", "operation/valid", "operation/relate" and "operation/overlay" upgraded to JTS 1.4;
00052  * "geom" partially upgraded.
00053  *
00054  * Revision 1.13  2003/11/07 01:23:42  pramsey
00055  * Add standard CVS headers licence notices and copyrights to all cpp and h
00056  * files.
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  * Tests whether any of a set of {@link LinearRing}s are
00078  * nested inside another ring in the set, using a simple O(n^2)
00079  * comparison.
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;  // used to find non-node vertices
00092         vector<LinearRing*> *rings;
00093         Coordinate nestedPt;
00094 };
00095 
00096 /*
00097  * Contains information about the nature and location of a {@link Geometry}
00098  * validation error
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  * Implements the appropriate checks for repeated points
00131  * (consecutive identical coordinates) as defined in the
00132  * JTS spec.
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  * Checks that a {@link GeometryGraph} representing an area
00150  * (a {@link Polygon} or {@link MultiPolygon} )
00151  * is consistent with the SFS semantics for area geometries.
00152  * Checks include:
00153  * <ul>
00154  * <li>testing for rings which self-intersect (both properly
00155  * and at nodes)
00156  * <li>testing for duplicate rings
00157  * </ul>
00158  * If an inconsistency if found the location of the problem
00159  * is recorded.
00160  */
00161 class ConsistentAreaTester {
00162 private:
00163         LineIntersector *li;
00164         GeometryGraph *geomGraph;
00165         RelateNodeGraph *nodeGraph;
00166         // the intersection point found (if any)
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  * Tests whether any of a set of {@link LinearRing}s are
00202  * nested inside another ring in the set, using a {@link SweepLineIndex}
00203  * index to speed up the comparisons.
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;  // used to find non-node vertices
00225         vector<LinearRing*> *rings;
00226         Envelope *totalEnv;
00227         SweepLineIndex *sweepLine;
00228         Coordinate nestedPt;
00229         void buildIndex();
00230 };
00231 
00232 /*
00233  * Tests whether any of a set of {@link LinearRing}s are
00234  * nested inside another ring in the set, using a {@link Quadtree}
00235  * index to speed up the comparisons.
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;  // used to find non-node vertices
00247         vector<LinearRing*> *rings;
00248         Envelope *totalEnv;
00249         Quadtree *qt;
00250         Coordinate nestedPt;
00251         void buildQuadtree();
00252 };
00253 
00254 /*
00255  * This class tests that the interior of an area {@link Geometry}
00256  *  ({@link Polygon}  or {@link MultiPolygon} )
00257  * is connected.  An area Geometry is invalid if the interior is disconnected.
00258  * This can happen if:
00259  * <ul>
00260  * <li>one or more holes either form a chain touching the shell at two places
00261  * <li>one or more holes form a ring around a portion of the interior
00262  * </ul>
00263  * If an inconsistency if found the location of the problem
00264  * is recorded.
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         // save a coordinate for any disconnected interior found
00278         // the coordinate will be somewhere on the ring surrounding the disconnected interior
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  * Implements the algorithsm required to compute the <code>isValid()</code> method
00305  * for {@link Geometry}s.
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;  // the base Geometry to be validated
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 //      void OLDcheckHolesInShell(Polygon *p);
00375         void checkHolesNotNested(const Polygon *p,GeometryGraph *graph);
00376 //      void SLOWcheckHolesNotNested(Polygon *p);
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

Generated on Fri Mar 14 13:02:53 2008 for GEOS by  doxygen 1.5.4