edgeendstar.cpp

来自「一个很好的vc底层代码」· C++ 代码 · 共 392 行

CPP
392
字号
/********************************************************************** * $Id: EdgeEndStar.cpp,v 1.9 2004/12/08 13:54:43 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 <geos/util.h>#define DEBUG 0namespace geos {EdgeEndStar::EdgeEndStar(){	ptInAreaLocation[0]=Location::UNDEF;	ptInAreaLocation[1]=Location::UNDEF;	edgeMap=new map<EdgeEnd*,void*,EdgeEndLT>();	edgeList=NULL;}EdgeEndStar::~EdgeEndStar(){//	map<EdgeEnd*,void*,EdgeEndLT>::iterator	it=edgeMap->begin();//	for (;it!=edgeMap->end();it++) {//		EdgeEnd *ee=(EdgeEnd*) it->second;////		void *ee= it->second;//		delete ee;//	}	delete edgeMap;	delete edgeList;}void EdgeEndStar::insert(EdgeEnd *e){	delete e;}/** * Insert an EdgeEnd into the map, and clear the edgeList cache, * since the list of edges has now changed */void EdgeEndStar::insertEdgeEnd(EdgeEnd *e,void* obj){	edgeMap->insert(pair<EdgeEnd*,void*>(e,obj));//	(*edgeMap)[e]=obj;	delete edgeList;	edgeList=NULL;  // edge list has changed - clear the cache}/** * @return the coordinate for the node this star is based at */Coordinate&EdgeEndStar::getCoordinate(){	if (getEdges()->size()==0)		return *(new Coordinate(DoubleNotANumber,DoubleNotANumber,DoubleNotANumber));	vector<EdgeEnd*>::iterator it=getIterator();	EdgeEnd *e=*it;	return e->getCoordinate();}int EdgeEndStar::getDegree(){	return (int)edgeMap->size();}vector<EdgeEnd*>*EdgeEndStar::getEdges(){	map<EdgeEnd*,void*,EdgeEndLT>::iterator mapIter;	if (edgeList==NULL) {		edgeList=new vector<EdgeEnd*>();		for(mapIter=edgeMap->begin();mapIter!=edgeMap->end();mapIter++) {//			edgeList->push_back(mapIter->first);			EdgeEnd *e=(EdgeEnd*) mapIter->second;			edgeList->push_back(e);		}	}//cout << endl << "edgeList:" << endl;//for(int i=0;i<(int)edgeList->size();i++) {//	cout << endl << (*edgeList)[i]->print() << endl;//}	return edgeList;}vector<EdgeEnd*>::iteratorEdgeEndStar::getIterator(){	return getEdges()->begin();}EdgeEnd*EdgeEndStar::getNextCW(EdgeEnd *ee){	getEdges();	int i=0;	for(unsigned int j=0;j<edgeList->size();j++)	{		//if (ee->compareTo( *(edgeList->at(j)))==0) 		if (ee->compareTo((*edgeList)[j])==0)		{			i=j;			break;		}	}	int iNextCW=i-1;	if (i==0) iNextCW=(int)edgeList->size()-1;	return (*edgeList)[iNextCW];}voidEdgeEndStar::computeLabelling(vector<GeometryGraph*> *geom)	//throw(TopologyException *){	computeEdgeEndLabels();	// Propagate side labels  around the edges in the star	// for each parent Geometry	//	// these calls can throw a TopologyException	propagateSideLabels(0);	propagateSideLabels(1);	/**	 * If there are edges that still have null labels for a geometry	 * this must be because there are no area edges for that geometry	 * incident on this node.	 * In this case, to label the edge for that geometry we must test	 * whether the edge is in the interior of the geometry.	 * To do this it suffices to determine whether the node for the	 * edge is in the interior of an area.	 * If so, the edge has location INTERIOR for the geometry.	 * In all other cases (e.g. the node is on a line, on a point, or	 * not on the geometry at all) the edge	 * has the location EXTERIOR for the geometry.	 * 	 * Note that the edge cannot be on the BOUNDARY of the geometry,	 * since then there would have been a parallel edge from the	 * Geometry at this node also labelled BOUNDARY	 * and this edge would have been labelled in the previous step.	 *	 * This code causes a problem when dimensional collapses are present,	 * since it may try and determine the location of a node where a	 * dimensional collapse has occurred.	 * The point should be considered to be on the EXTERIOR	 * of the polygon, but locate() will return INTERIOR, since it is	 * passed the original Geometry, not the collapsed version.	 *	 * If there are incident edges which are Line edges labelled BOUNDARY,	 * then they must be edges resulting from dimensional collapses.	 * In this case the other edges can be labelled EXTERIOR for this	 * Geometry.	 *	 * MD 8/11/01 - NOT TRUE!  The collapsed edges may in fact be in the	 * interior of the Geometry, which means the other edges should be	 * labelled INTERIOR for this Geometry.	 * Not sure how solve this...  Possibly labelling needs to be split	 * into several phases:	 * area label propagation, symLabel merging, then finally null label	 * resolution.	 */	bool hasDimensionalCollapseEdge[2]={false,false};	vector<EdgeEnd*>::iterator it;	for (it=getIterator();it<edgeList->end();it++) {		EdgeEnd *e=*it;		Label *label=e->getLabel();		for(int geomi=0; geomi<2; geomi++)		{			if (label->isLine(geomi) && label->getLocation(geomi)==Location::BOUNDARY)				hasDimensionalCollapseEdge[geomi]=true;		}	}	for (it=getIterator();it<edgeList->end();it++) {		EdgeEnd *e=*it;		Label *label=e->getLabel();		for(int geomi=0;geomi<2;geomi++){			if (label->isAnyNull(geomi)) {				int loc=Location::UNDEF;				if (hasDimensionalCollapseEdge[geomi]){					loc=Location::EXTERIOR;				}else {					Coordinate& p=e->getCoordinate();					loc=getLocation(geomi,p,geom);				}				label->setAllLocationsIfNull(geomi,loc);			}		}	}}voidEdgeEndStar::computeEdgeEndLabels(){	// Compute edge label for each EdgeEnd	vector<EdgeEnd*>::iterator it;	for (it=getIterator(); it<edgeList->end(); it++)	{		EdgeEnd *e=*it;		e->computeLabel();	}}intEdgeEndStar::getLocation(int geomIndex,Coordinate& p,vector<GeometryGraph*> *geom){	// compute location only on demand	if (ptInAreaLocation[geomIndex]==Location::UNDEF)	{        	ptInAreaLocation[geomIndex]=SimplePointInAreaLocator::locate(p,(*geom)[geomIndex]->getGeometry());	}	return ptInAreaLocation[geomIndex];}bool EdgeEndStar::isAreaLabelsConsistent(){	computeEdgeEndLabels();	return checkAreaLabelsConsistent(0);}bool EdgeEndStar::checkAreaLabelsConsistent(int geomIndex){	// Since edges are stored in CCW order around the node,	// As we move around the ring we move from the right to the left side of the edge	vector<EdgeEnd*> *edges=getEdges();	// if no edges, trivially consistent	if (edges->size()<=0)		return true;	// initialize startLoc to location of last L side (if any)	int lastEdgeIndex=(int)edges->size()-1;	Label *startLabel=((*edgeList)[lastEdgeIndex])->getLabel();	int startLoc=startLabel->getLocation(geomIndex,Position::LEFT);	Assert::isTrue(startLoc!=Location::UNDEF, "Found unlabelled area edge");	int currLoc=startLoc;	for (vector<EdgeEnd*>::iterator it=getIterator();it<edgeList->end();it++) {		EdgeEnd *e=*it;		Label *eLabel=e->getLabel();		// we assume that we are only checking a area		Assert::isTrue(eLabel->isArea(geomIndex), "Found non-area edge");		int leftLoc=eLabel->getLocation(geomIndex,Position::LEFT);		int rightLoc=eLabel->getLocation(geomIndex,Position::RIGHT);		// check that edge is really a boundary between inside and outside!		if (leftLoc==rightLoc) {			return false;		}		// check side location conflict		//Assert.isTrue(rightLoc == currLoc, "side location conflict " + locStr);		if (rightLoc!=currLoc) {			return false;		}		currLoc=leftLoc;	}	return true;}voidEdgeEndStar::propagateSideLabels(int geomIndex)	//throw(TopologyException *){	// Since edges are stored in CCW order around the node,	// As we move around the ring we move from the right to the	// left side of the edge	int startLoc=Location::UNDEF ;	// initialize loc to location of last L side (if any)	vector<EdgeEnd*>::iterator it;	for (it=getIterator();it<edgeList->end();it++)	{		EdgeEnd *e=*it;		Label *label=e->getLabel();		if (label->isArea(geomIndex) &&			label->getLocation(geomIndex,Position::LEFT)!=Location::UNDEF)			startLoc=label->getLocation(geomIndex,Position::LEFT);	}	// no labelled sides found, so no labels to propagate	if (startLoc==Location::UNDEF) return;	int currLoc=startLoc;	for (it=getIterator();it<edgeList->end();it++) {		EdgeEnd *e=*it;		Label *label=e->getLabel();		// set null ON values to be in current location		if (label->getLocation(geomIndex,Position::ON)==Location::UNDEF)			label->setLocation(geomIndex,Position::ON,currLoc);		// set side labels (if any)		// if (label.isArea())  //ORIGINAL		if (label->isArea(geomIndex))		{			int leftLoc=label->getLocation(geomIndex,Position::LEFT);			int rightLoc=label->getLocation(geomIndex,Position::RIGHT);			// if there is a right location, that is the next location to propagate			if (rightLoc!=Location::UNDEF) {				if (rightLoc!=currLoc)					throw new TopologyException("side location conflict",&(e->getCoordinate()));				if (leftLoc==Location::UNDEF) {					Assert::shouldNeverReachHere("found single null side (at " + (e->getCoordinate()).toString() + ")");				}				currLoc=leftLoc;			} else {				/**				 * RHS is null - LHS must be null too.				 * This must be an edge from the other				 * geometry, which has no location				 * labelling for this geometry.				 * This edge must lie wholly inside or				 * outside the other geometry (which is				 * determined by the current location).				 * Assign both sides to be the current				 * location.				 */				Assert::isTrue(label->getLocation(geomIndex,					Position::LEFT)==Location::UNDEF,					"found single null side");				label->setLocation(geomIndex,Position::RIGHT,					currLoc);				label->setLocation(geomIndex,Position::LEFT,					currLoc);			}		}	}}int EdgeEndStar::findIndex(EdgeEnd *eSearch){	getIterator();   // force edgelist to be computed	for (unsigned int i=0; i<edgeList->size(); i++ ) {		EdgeEnd *e=(*edgeList)[i];//		if (e->compareTo(eSearch)) return i;		if (e==eSearch) return i;	}	return -1;}stringEdgeEndStar::print(){	string out="EdgeEndStar:   " + getCoordinate().toString()+"\n";	for (vector<EdgeEnd*>::iterator it=getIterator();it<edgeList->end();it++)	{		EdgeEnd *e=*it;		out+=e->print();	}	return out;}}/********************************************************************** * $Log: EdgeEndStar.cpp,v $ * Revision 1.9  2004/12/08 13:54:43  strk * gcc warnings checked and fixed, general cleanups. * * Revision 1.8  2004/11/23 19:53:06  strk * Had LineIntersector compute Z by interpolation. * * Revision 1.7  2004/11/22 11:34:49  strk * More debugging lines and comments/indentation cleanups * * Revision 1.6  2004/11/17 08:13:16  strk * Indentation changes. * Some Z_COMPUTATION activated by default. * * Revision 1.5  2004/11/01 16:43:04  strk * Added Profiler code. * Temporarly patched a bug in DoubleBits (must check drawbacks). * Various cleanups and speedups. * * Revision 1.4  2004/10/21 22:29:54  strk * Indentation changes and some more COMPUTE_Z rules * * Revision 1.3  2004/07/02 13:28:26  strk * Fixed all #include lines to reflect headers layout change. * Added client application build tips in README. * * Revision 1.2  2004/05/03 10:43:42  strk * Exception specification considered harmful - left as comment. * * Revision 1.1  2004/03/19 09:48:45  ybychkov * "geomgraph" and "geomgraph/indexl" upgraded to JTS 1.4 * * Revision 1.18  2003/11/12 15:43:38  strk * Added some more throw specifications * * Revision 1.17  2003/11/07 01:23:42  pramsey * Add standard CVS headers licence notices and copyrights to all cpp and h * files. * * **********************************************************************/

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?