geometrygraph.cpp
来自「一个很好的vc底层代码」· C++ 代码 · 共 546 行 · 第 1/2 页
CPP
546 行
/********************************************************************** * $Id: GeometryGraph.cpp,v 1.10 2004/11/22 11:34:49 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/geomgraph.h>#include <typeinfo>#include <geos/util.h>#ifndef DEBUG#define DEBUG 0#endifnamespace geos {/* * This method implements the Boundary Determination Rule * for determining whether * a component (node or edge) that appears multiple times in elements * of a MultiGeometry is in the boundary or the interior of the Geometry * * The SFS uses the "Mod-2 Rule", which this function implements * * An alternative (and possibly more intuitive) rule would be * the "At Most One Rule": * isInBoundary = (componentCount == 1) */boolGeometryGraph::isInBoundary(int boundaryCount){ // the "Mod-2 Rule" return boundaryCount%2==1;}intGeometryGraph::determineBoundary(int boundaryCount){ return isInBoundary(boundaryCount)?Location::BOUNDARY : Location::INTERIOR;}GeometryGraph::GeometryGraph():PlanarGraph(){ lineEdgeMap=new map<const LineString*,Edge*,LineStringLT>(); useBoundaryDeterminationRule=false; boundaryNodes=NULL; parentGeom=NULL; hasTooFewPointsVar=false;}GeometryGraph::~GeometryGraph(){// map<LineString*,Edge*,LineStringLT>::iterator it=lineEdgeMap->begin();// for (;it!=lineEdgeMap->end();it++) {// Edge *e=it->second;// delete e;// } delete lineEdgeMap;}GeometryGraph::GeometryGraph(int newArgIndex, const Geometry *newParentGeom): PlanarGraph(){ hasTooFewPointsVar=false; boundaryNodes=NULL; lineEdgeMap=new map<const LineString*,Edge*,LineStringLT>(); useBoundaryDeterminationRule=false; argIndex=newArgIndex; parentGeom=newParentGeom; if (parentGeom!=NULL) { try { add(parentGeom); } catch(...) { delete lineEdgeMap; throw; } }}EdgeSetIntersector*GeometryGraph::createEdgeSetIntersector(){ // various options for computing intersections, from slowest to fastest //private EdgeSetIntersector esi = new SimpleEdgeSetIntersector(); //private EdgeSetIntersector esi = new MonotoneChainIntersector(); //private EdgeSetIntersector esi = new NonReversingChainIntersector(); //private EdgeSetIntersector esi = new SimpleSweepLineIntersector(); //private EdgeSetIntersector esi = new MCSweepLineIntersector(); //return new SimpleEdgeSetIntersector(); return new SimpleMCSweepLineIntersector();}//NO LONGER USED/*** This constructor is used by clients that wish to add Edges explicitly,* rather than adding a Geometry. (An example is BufferOp).*///GeometryGraph::GeometryGraph(int newArgIndex, const PrecisionModel *newPrecisionModel, int newSRID):PlanarGraph(){// boundaryNodes=NULL;// lineEdgeMap=new map<const LineString*,Edge*,LineStringLT>();// useBoundaryDeterminationRule=false;// argIndex=newArgIndex;// parentGeom=NULL;// precisionModel=newPrecisionModel;// SRID=newSRID;// hasTooFewPointsVar=false;//}////const PrecisionModel* GeometryGraph::getPrecisionModel(){// return precisionModel;//}////int GeometryGraph::getSRID() {// return SRID;//}constGeometry* GeometryGraph::getGeometry(){ return parentGeom;}vector<Node*>*GeometryGraph::getBoundaryNodes(){ if (boundaryNodes==NULL) boundaryNodes=nodes->getBoundaryNodes(argIndex); return boundaryNodes;}CoordinateSequence*GeometryGraph::getBoundaryPoints(){ vector<Node*> *coll=getBoundaryNodes(); CoordinateSequence *pts=new DefaultCoordinateSequence((int)coll->size()); int i=0; for (vector<Node*>::iterator it=coll->begin();it<coll->end();it++) { Node *node=*it; pts->setAt(node->getCoordinate(),i++); } delete coll; return pts;}Edge*GeometryGraph::findEdge(const LineString *line){ return lineEdgeMap->find(line)->second;}voidGeometryGraph::computeSplitEdges(vector<Edge*> *edgelist){#if DEBUG cerr<<"["<<this<<"] GeometryGraph::computeSplitEdges() scanning "<<edges->size()<<" local and "<<edgelist->size()<<" provided edges"<<endl;#endif for (vector<Edge*>::iterator i=edges->begin();i<edges->end();i++) { Edge *e=*i;#if DEBUG cerr<<" "<<e->print()<<" adding split edges from arg"<<endl;#endif e->eiList->addSplitEdges(edgelist); }}voidGeometryGraph::add(const Geometry *g) //throw (UnsupportedOperationException *){ if (g->isEmpty()) return; // check if this Geometry should obey the Boundary Determination Rule // all collections except MultiPolygons obey the rule if ((typeid(*g)==typeid(GeometryCollection)) || (typeid(*g)==typeid(MultiPoint)) || (typeid(*g)==typeid(MultiLineString)) && !(typeid(*g)==typeid(MultiPolygon))) useBoundaryDeterminationRule=true; if (typeid(*g)==typeid(Polygon)) addPolygon((Polygon*) g); else if (typeid(*g)==typeid(LineString)) addLineString((LineString*) g); else if (typeid(*g)==typeid(LinearRing)) addLineString((LineString*) g); else if (typeid(*g)==typeid(Point)) addPoint((Point*) g); else if (typeid(*g)==typeid(MultiPoint)) addCollection((MultiPoint*) g); else if (typeid(*g)==typeid(MultiLineString)) addCollection((MultiLineString*) g); else if (typeid(*g)==typeid(MultiPolygon)) addCollection((MultiPolygon*) g); else if (typeid(*g)==typeid(GeometryCollection)) addCollection((GeometryCollection*) g); else { string out=typeid(*g).name(); throw new UnsupportedOperationException("GeometryGraph::add(Geometry *): unknown geometry type: "+out); }}voidGeometryGraph::addCollection(const GeometryCollection *gc){ for (int i=0;i<gc->getNumGeometries();i++) { const Geometry *g=gc->getGeometryN(i); add(g); }}/* * Add a Point to the graph. */voidGeometryGraph::addPoint(const Point *p){ const Coordinate& coord=*(p->getCoordinate()); insertPoint(argIndex,coord,Location::INTERIOR);}/* * The left and right topological location arguments assume that the ring * is oriented CW. * If the ring is in the opposite orientation, * the left and right locations must be interchanged. */voidGeometryGraph::addPolygonRing(const LinearRing *lr, int cwLeft, int cwRight) // throw IllegalArgumentException (see below){ const CoordinateSequence *lrcl; lrcl = lr->getCoordinatesRO(); CoordinateSequence* coord=CoordinateSequence::removeRepeatedPoints(lrcl); if (coord->getSize()<4) { hasTooFewPointsVar=true; invalidPoint=coord->getAt(0); // its now a Coordinate delete coord; return; } int left=cwLeft; int right=cwRight; /* * the isCCW call might throw an * IllegalArgumentException if degenerate ring does * not contain 3 distinct points. */ try { if (cga->isCCW(coord)) { left=cwRight; right=cwLeft; } } catch(...) { delete coord; throw; } Edge *e=new Edge(coord,new Label(argIndex,Location::BOUNDARY,left,right)); (*lineEdgeMap)[lr]=e; insertEdge(e);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?