GEOS: opValid.h Source File

- Main Page
- Namespaces
- Classes
- Files
- Related Pages

# 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