GEOS  3.6.2
OverlayOp.h
00001 /**********************************************************************
00002  *
00003  * GEOS - Geometry Engine Open Source
00004  * http://geos.osgeo.org
00005  *
00006  * Copyright (C) 2006 Refractions Research Inc.
00007  *
00008  * This is free software; you can redistribute and/or modify it under
00009  * the terms of the GNU Lesser General Public Licence as published
00010  * by the Free Software Foundation. 
00011  * See the COPYING file for more information.
00012  *
00013  ***********************************************************************
00014  *
00015  * Last port: operation/overlay/OverlayOp.java r567 (JTS-1.12+)
00016  *
00017  **********************************************************************/
00018 
00019 #ifndef GEOS_OP_OVERLAY_OVERLAYOP_H
00020 #define GEOS_OP_OVERLAY_OVERLAYOP_H
00021 
00022 #include <geos/export.h>
00023 
00024 #include <geos/operation/GeometryGraphOperation.h> // for inheritance
00025 #include <geos/geomgraph/EdgeList.h> // for composition
00026 #include <geos/algorithm/PointLocator.h> // for composition
00027 #include <geos/geomgraph/PlanarGraph.h> // for inline (GeometryGraph->PlanarGraph)
00028 
00029 #include <vector>
00030 
00031 #ifdef _MSC_VER
00032 #pragma warning(push)
00033 #pragma warning(disable: 4251) // warning C4251: needs to have dll-interface to be used by clients of class
00034 #endif
00035 
00036 // Forward declarations
00037 namespace geos {
00038         namespace geom {
00039                 class Geometry;
00040                 class Coordinate;
00041                 class Envelope;
00042                 class GeometryFactory;
00043                 class Polygon;
00044                 class LineString;
00045                 class Point;
00046         }
00047         namespace geomgraph {
00048                 class Label;
00049                 class Edge;
00050                 class Node;
00051         }
00052         namespace operation {
00053                 namespace overlay {
00054                         class ElevationMatrix;
00055                 }
00056         }
00057 }
00058 
00059 namespace geos {
00060 namespace operation { // geos::operation
00061 namespace overlay { // geos::operation::overlay
00062 
00064 //
00068 class GEOS_DLL OverlayOp: public GeometryGraphOperation {
00069 
00070 public:
00071 
00073         //
00077         enum OpCode {
00079                 opINTERSECTION = 1,
00081                 opUNION = 2,
00083                 opDIFFERENCE = 3,
00085                 opSYMDIFFERENCE = 4
00086         };
00087 
00097         static geom::Geometry* overlayOp(const geom::Geometry *geom0,
00098                         const geom::Geometry *geom1,
00099                         OpCode opCode);
00100                 //throw(TopologyException *);
00101 
00114         static bool isResultOfOp(const geomgraph::Label& label, OpCode opCode);
00115 
00117         //
00120         static bool isResultOfOp(int loc0, int loc1, OpCode opCode);
00121 
00123         // 
00127         OverlayOp(const geom::Geometry *g0, const geom::Geometry *g1);
00128 
00129         virtual ~OverlayOp(); // FIXME: virtual ?
00130 
00140         geom::Geometry* getResultGeometry(OpCode overlayOpCode);
00141                 // throw(TopologyException *);
00142 
00148         geomgraph::PlanarGraph& getGraph() { return graph; }
00149 
00157         bool isCoveredByLA(const geom::Coordinate& coord);
00158 
00165         bool isCoveredByA(const geom::Coordinate& coord);
00166 
00167         /*
00168          * @return true if the coord is located in the interior or boundary of
00169          * a geometry in the list.
00170          */
00171 
00172 protected:
00173 
00182         void insertUniqueEdge(geomgraph::Edge *e);
00183 
00184 private:
00185 
00186         algorithm::PointLocator ptLocator;
00187 
00188         const geom::GeometryFactory *geomFact;
00189 
00190         geom::Geometry *resultGeom;
00191 
00192         geomgraph::PlanarGraph graph;
00193 
00194         geomgraph::EdgeList edgeList;
00195 
00196         std::vector<geom::Polygon*> *resultPolyList;
00197 
00198         std::vector<geom::LineString*> *resultLineList;
00199 
00200         std::vector<geom::Point*> *resultPointList;
00201 
00202         void computeOverlay(OpCode opCode); // throw(TopologyException *);
00203 
00204         void insertUniqueEdges(std::vector<geomgraph::Edge*> *edges, const geom::Envelope *env=0);
00205 
00206         /*
00207          * If either of the GeometryLocations for the existing label is
00208          * exactly opposite to the one in the labelToMerge,
00209          * this indicates a dimensional collapse has happened.
00210          * In this case, convert the label for that Geometry to a Line label
00211          */
00212         //Not needed
00213         //void checkDimensionalCollapse(geomgraph::Label labelToMerge, geomgraph::Label existingLabel);
00214 
00226         void computeLabelsFromDepths();
00227 
00232         void replaceCollapsedEdges();
00233 
00244         void copyPoints(int argIndex, const geom::Envelope *env=0);
00245 
00254         void computeLabelling(); // throw(TopologyException *);
00255 
00263         void mergeSymLabels();
00264 
00265         void updateNodeLabelling();
00266 
00284         void labelIncompleteNodes();
00285 
00289         void labelIncompleteNode(geomgraph::Node *n, int targetIndex);
00290 
00302         void findResultAreaEdges(OpCode opCode);
00303 
00308         void cancelDuplicateResultEdges();
00309 
00314         bool isCovered(const geom::Coordinate& coord,
00315                         std::vector<geom::Geometry*> *geomList);
00316 
00321         bool isCovered(const geom::Coordinate& coord,
00322                         std::vector<geom::Polygon*> *geomList);
00323 
00328         bool isCovered(const geom::Coordinate& coord,
00329                         std::vector<geom::LineString*> *geomList);
00330 
00335         geom::Geometry* computeGeometry(
00336                         std::vector<geom::Point*> *nResultPointList,
00337                         std::vector<geom::LineString*> *nResultLineList,
00338                         std::vector<geom::Polygon*> *nResultPolyList);
00339 
00341         std::vector<geomgraph::Edge *>dupEdges;
00342 
00347         int mergeZ(geomgraph::Node *n, const geom::Polygon *poly) const;
00348 
00354         int mergeZ(geomgraph::Node *n, const geom::LineString *line) const;
00355 
00359         double avgz[2];
00360         bool avgzcomputed[2];
00361 
00362         double getAverageZ(int targetIndex);
00363         static double getAverageZ(const geom::Polygon *poly);
00364 
00365         ElevationMatrix *elevationMatrix;
00366 
00369         void checkObviouslyWrongResult(OpCode opCode);
00370 
00371 };
00372 
00376 struct overlayOp {
00377 
00378         OverlayOp::OpCode opCode;
00379 
00380         overlayOp(OverlayOp::OpCode code)
00381                 :
00382                 opCode(code)
00383         {}
00384 
00385         geom::Geometry* operator() (const geom::Geometry* g0,
00386                                     const geom::Geometry* g1)
00387         {
00388                 return OverlayOp::overlayOp(g0, g1, opCode);
00389         }
00390 
00391 };
00392 
00393 } // namespace geos::operation::overlay
00394 } // namespace geos::operation
00395 } // namespace geos
00396 
00397 #ifdef _MSC_VER
00398 #pragma warning(pop)
00399 #endif
00400 
00401 #endif // ndef GEOS_OP_OVERLAY_OVERLAYOP_H