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 + -
显示快捷键?