polygon.cpp

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

CPP
346
字号
/********************************************************************** * $Id: Polygon.cpp,v 1.45.2.1 2005/05/24 07:29:36 strk Exp $ * * GEOS - Geometry Engine Open Source * http://geos.refractions.net * * Copyright (C) 2001-2002 Vivid Solutions Inc. * Copyright (C) 2005 Refractions Research 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/geom.h>#include <typeinfo>#include <geos/geosAlgorithm.h>namespace geos {Polygon::Polygon(const Polygon &p): Geometry(p.getFactory()){	shell=new LinearRing(*p.shell);	holes=new vector<Geometry *>();	for(int i=0;i<(int)p.holes->size();i++) {		LinearRing *h=new LinearRing(* (LinearRing*)(*p.holes)[i]);		holes->push_back(h);	}}/** Constructs a <code>Polygon</code> with the given exterior* and interior boundaries.** @param  shell     the outer boundary of the new <code>Polygon</code>,*                   or <code>null</code> or an empty*                   <code>LinearRing</code> if the empty geometry*                   is to be created.** @param  holes     the <code>LinearRings</code> defining the inner*                   boundaries of the new <code>Polygon</code>, or*                   <code>null</code> or empty <code>LinearRing</code>s*                   if the empty  geometry is to be created.** Polygon will take ownership of Shell and Holes LinearRings**/Polygon::Polygon(LinearRing *newShell, vector<Geometry *> *newHoles, const GeometryFactory *newFactory): Geometry(newFactory){	if (newShell==NULL) {		shell=getFactory()->createLinearRing(NULL);	}	else	{		if (newShell->isEmpty() && hasNonEmptyElements(newHoles)) {			delete newShell;			delete newHoles;			throw new IllegalArgumentException("shell is empty but holes are not");		}		shell=newShell;	}	if (newHoles==NULL)	{		holes=new vector<Geometry *>();	}	else	{		if (hasNullElements(newHoles)) {			delete newShell;			delete newHoles;			throw new IllegalArgumentException("holes must not contain null elements");		}		for (unsigned int i=0; i<newHoles->size(); i++)			if ( (*newHoles)[i]->getGeometryTypeId() != GEOS_LINEARRING)				throw new IllegalArgumentException("holes must be LinearRings");		holes=newHoles;	}}Geometry *Polygon::clone() const {	return new Polygon(*this);}CoordinateSequence* Polygon::getCoordinates() const {	if (isEmpty()) {		return getFactory()->getCoordinateSequenceFactory()->create(NULL);	}	vector<Coordinate> *cl = new vector<Coordinate>;	int k = -1;	const CoordinateSequence* shellCoords=shell->getCoordinatesRO();	for (int x = 0; x < shellCoords->getSize(); x++) {		k++;		cl->push_back(shellCoords->getAt(x));	}	for (unsigned int i = 0; i < holes->size(); i++) {		const CoordinateSequence* childCoords=((LinearRing *)(*holes)[i])->getCoordinatesRO();		for (int j = 0; j < childCoords->getSize(); j++) {			k++;			cl->push_back(childCoords->getAt(j));		}	}	return getFactory()->getCoordinateSequenceFactory()->create(cl);}int Polygon::getNumPoints() const {	int numPoints = shell->getNumPoints();	for (unsigned int i = 0; i < holes->size(); i++) {		numPoints += ((LinearRing *)(*holes)[i])->getNumPoints();	}	return numPoints;}int Polygon::getDimension() const {	return 2;}int Polygon::getBoundaryDimension() const {	return 1;}bool Polygon::isEmpty() const {	return shell->isEmpty();}bool Polygon::isSimple() const {	return true;}const LineString* Polygon::getExteriorRing() const {	return shell;}int Polygon::getNumInteriorRing() const {	return (int)holes->size();}const LineString* Polygon::getInteriorRingN(int n) const {	return (LineString *) (*holes)[n];}string Polygon::getGeometryType() const {	return "Polygon";}// Returns a newly allocated Geometry objectGeometry* Polygon::getBoundary() const {	if (isEmpty()) {		return getFactory()->createGeometryCollection(NULL);	}	if ( ! holes->size() )	{		return new LineString(*shell);	}	vector<Geometry *> *rings = new vector<Geometry *>(holes->size()+1);	(*rings)[0]=new LineString(*shell);	for (unsigned int i=0; i<holes->size(); i++) {		(*rings)[i + 1] = new LineString((const LineString &)*(*holes)[i]);	}	MultiLineString *ret = getFactory()->createMultiLineString(rings);	return ret;}Envelope* Polygon::computeEnvelopeInternal() const {	return new Envelope(*(shell->getEnvelopeInternal()));}bool Polygon::equalsExact(const Geometry *other, double tolerance) const {	if (!isEquivalentClass(other)) {		return false;	}	const Polygon* otherPolygon=dynamic_cast<const Polygon*>(other);	if (typeid(*(otherPolygon->shell))!=typeid(Geometry)) {		return false;	}	Geometry* otherPolygonShell=dynamic_cast<Geometry *>(otherPolygon->shell);	if (!shell->equalsExact(otherPolygonShell, tolerance)) {		return false;	}	if (holes->size()!=otherPolygon->holes->size()) {		return false;	}	for (unsigned int i = 0; i < holes->size(); i++) {		if (!((LinearRing *)(*holes)[i])->equalsExact((*(otherPolygon->holes))[i],tolerance)) {			return false;		}	}	return true;}void Polygon::apply_ro(CoordinateFilter *filter) const {	shell->apply_ro(filter);	for (unsigned int i = 0; i < holes->size(); i++) {		((LinearRing *)(*holes)[i])->apply_ro(filter);	}}void Polygon::apply_rw(CoordinateFilter *filter) {	shell->apply_rw(filter);	for (unsigned int i = 0; i < holes->size(); i++) {		((LinearRing *)(*holes)[i])->apply_rw(filter);	}}void Polygon::apply_rw(GeometryFilter *filter) {	filter->filter_rw(this);}void Polygon::apply_ro(GeometryFilter *filter) const {	filter->filter_ro(this);}Geometry* Polygon::convexHull() const {	return getExteriorRing()->convexHull();}void Polygon::normalize() {	normalize(shell, true);	for (unsigned int i = 0; i < holes->size(); i++) {		normalize((LinearRing *)(*holes)[i], false);	}	sort(holes->begin(),holes->end(),greaterThen);}int Polygon::compareToSameClass(const Geometry *p) const {	return shell->compareToSameClass(((Polygon*)p)->shell);}void Polygon::normalize(LinearRing *ring, bool clockwise) {	if (ring->isEmpty()) {		return;	}	CoordinateSequence* uniqueCoordinates=ring->getCoordinates();	uniqueCoordinates->deleteAt(uniqueCoordinates->getSize()-1);	const Coordinate* minCoordinate=CoordinateSequence::minCoordinate(uniqueCoordinates);	CoordinateSequence::scroll(uniqueCoordinates, minCoordinate);	uniqueCoordinates->add(uniqueCoordinates->getAt(0));	if (CGAlgorithms::isCCW(uniqueCoordinates)==clockwise) {		CoordinateSequence::reverse(uniqueCoordinates);	}	ring->setPoints(uniqueCoordinates);	delete(uniqueCoordinates);}const Coordinate* Polygon::getCoordinate() const {	return shell->getCoordinate();}/**  Returns the area of this <code>Polygon</code>**@return the area of the polygon*/double Polygon::getArea() const {	double area=0.0;	area+=fabs(CGAlgorithms::signedArea(shell->getCoordinatesRO()));	for(unsigned int i=0;i<holes->size();i++) {		CoordinateSequence *h=(*holes)[i]->getCoordinates();        	area-=fabs(CGAlgorithms::signedArea(h));		delete h;	}	return area;}/** * Returns the perimeter of this <code>Polygon</code> * * @return the perimeter of the polygon */double Polygon::getLength() const {	double len=0.0;	len+=shell->getLength();	for(unsigned int i=0;i<holes->size();i++) {        len+=(*holes)[i]->getLength();	}	return len;}void Polygon::apply_ro(GeometryComponentFilter *filter) const {	filter->filter_ro(this);	shell->apply_ro(filter);	for(unsigned int i=0;i<holes->size();i++) {        	(*holes)[i]->apply_ro(filter);	}}void Polygon::apply_rw(GeometryComponentFilter *filter) {	filter->filter_rw(this);	shell->apply_rw(filter);	for(unsigned int i=0;i<holes->size();i++) {        	(*holes)[i]->apply_rw(filter);	}}Polygon::~Polygon(){	delete shell;	for(int i=0;i<(int)holes->size();i++) {		delete (*holes)[i];	}	delete holes;}GeometryTypeIdPolygon::getGeometryTypeId() const {	return GEOS_POLYGON;}} // namespace geos/********************************************************************** * $Log: Polygon.cpp,v $ * Revision 1.45.2.1  2005/05/24 07:29:36  strk * Fixed polygon::getBoundary() to never return (MULTI)LinearRings. * * Revision 1.45  2004/12/08 13:54:43  strk * gcc warnings checked and fixed, general cleanups. * * Revision 1.44  2004/11/12 18:12:05  strk * Changed ::getBoundary() to return LineString if polygon has no holes. * (has required to pass OGC conformance test T20) * * Revision 1.43  2004/07/27 16:35:46  strk * Geometry::getEnvelopeInternal() changed to return a const Envelope *. * This should reduce object copies as once computed the envelope of a * geometry remains the same. * * Revision 1.42  2004/07/22 07:04:49  strk * Documented missing geometry functions. * * Revision 1.41  2004/07/13 08:33:52  strk * Added missing virtual destructor to virtual classes. * Fixed implicit unsigned int -> int casts * * Revision 1.40  2004/07/08 19:34:49  strk * Mirrored JTS interface of CoordinateSequence, factory and * default implementations. * Added DefaultCoordinateSequenceFactory::instance() function. * **********************************************************************/

⌨️ 快捷键说明

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