⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 geometry.cpp

📁 一个很好的vc底层代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/********************************************************************** * $Id: Geometry.cpp,v 1.72.2.2 2005/06/22 00:46:53 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 <geos/util.h>#include <typeinfo>#include <algorithm>#include <geos/geosAlgorithm.h>#include <geos/operation.h>#include <geos/opRelate.h>#include <geos/opValid.h>#include <geos/opDistance.h>#include <geos/opOverlay.h>#include <geos/opBuffer.h>#include <geos/io.h>#include <geos/version.h>#define SHORTCIRCUIT_PREDICATES 1namespace geos {/** \mainpage  * * \section intro_sec Introduction * * Geometry Engine Open Source is a C++ port of the Java Topology Suite. * * \section getstart_sec Getting Started * * Main class is geos::Geometry, from which all geometry types * derive. * * Construction and destruction of Geometries is done * using geos::GeometryFactory. * * You'll feed it geos::CoordinateSequence * for base geometries or vectors of geometries for collections. * * If you need to construct geometric shaped geometries, you * can use geos::GeometricShapeFactory. * * GEOS version info (as a string) can be obtained using * geos::geosversion(). The JTS version this release has been * ported from is available throu geos::jtsport(). * * \section io_sect Input / Output * * For WKT input/output you can use geos::WKTReader and geos::WKTWriter * * \section exc_sect Exceptions * * Internal exceptions are thrown as pointers to geos::GEOSException. * * Other standard exceptions are not mapped to this handler, nor * does GEOSException inerit from standard exception, so you'll need * to catch both if you care (this might change in the future) * */ /* * Return current GEOS version  */stringgeosversion(){	return GEOS_VERSION;}/* * Return the version of JTS this GEOS * release has been ported from. */stringjtsport(){	return GEOS_JTS_PORT;}GeometryComponentFilter Geometry::geometryChangedFilter;const GeometryFactory* Geometry::INTERNAL_GEOMETRY_FACTORY=new GeometryFactory();Geometry::Geometry(const GeometryFactory *newFactory) {	factory=newFactory; //new GeometryFactory(*fromFactory);	SRID=factory->getSRID();	//envelope=new Envelope();	envelope=NULL;	userData=NULL;}Geometry::Geometry(const Geometry &geom) {	factory=geom.factory; //new GeometryFactory(*(geom.factory));	envelope=new Envelope(*(geom.envelope));	SRID=factory->getSRID();	userData=NULL;}boolGeometry::hasNonEmptyElements(const vector<Geometry *>* geometries) {	for (unsigned int i=0; i<geometries->size(); i++) {		if (!(*geometries)[i]->isEmpty()) {			return true;		}	}	return false;}boolGeometry::hasNullElements(const CoordinateSequence* list) {	for (int i = 0; i<list->getSize(); i++) {		if (list->getAt(i)==Coordinate::getNull()) {			return true;		}	}	return false;}boolGeometry::hasNullElements(const vector<Geometry *>* lrs) {	for (unsigned int i = 0; i<lrs->size(); i++) {		if ((*lrs)[i]==NULL) {			return true;		}	}	return false;}	//void Geometry::reversePointOrder(CoordinateSequence* coordinates) {//	int length=coordinates->getSize();//	vector<Coordinate> v(length);//	for (int i=0; i<length; i++) {//		v[i]=coordinates->getAt(length - 1 - i);//	}//	coordinates->setPoints(v);//}	//Coordinate& Geometry::minCoordinate(CoordinateSequence* coordinates){//	vector<Coordinate> v(*(coordinates->toVector()));//	sort(v.begin(),v.end(),lessThen);//	return v.front();//}//void Geometry::scroll(CoordinateSequence* coordinates,Coordinate* firstCoordinate) {//	int ind=indexOf(firstCoordinate,coordinates);//	Assert::isTrue(ind > -1);//	int length=coordinates->getSize();//	vector<Coordinate> v(length);//	for (int i=ind; i<length; i++) {//		v[i-ind]=coordinates->getAt(i);//	}//	for (int j=0; j<ind; j++) {//		v[length-ind+j]=coordinates->getAt(j);//	}//	coordinates->setPoints(v);//}////int Geometry::indexOf(Coordinate* coordinate,CoordinateSequence* coordinates) {//	for (int i=0; i<coordinates->getSize(); i++) {//		if ((*coordinate)==coordinates->getAt(i)) {//			return i;//		}//	}//	return -1;//}/** * Tests whether the distance from this <code>Geometry</code> * to another is less than or equal to a specified value. * * @param geom the Geometry to check the distance to * @param cDistance the distance value to compare * @return <code>true</code> if the geometries are less than *  <code>distance</code> apart. */bool Geometry::isWithinDistance(const Geometry *geom,double cDistance) {	const Envelope *env0=getEnvelopeInternal();	const Envelope *env1=geom->getEnvelopeInternal();	double envDist=env0->distance(env1);	//delete env0;	//delete env1;	if (envDist>cDistance)	{		return false;	}	// NOTE: this could be implemented more efficiently	double geomDist=distance(geom);	if (geomDist>cDistance)	{		return false;	}	return true;}/*** Computes the centroid of this <code>Geometry</code>.* The centroid* is equal to the centroid of the set of component Geometrys of highest* dimension (since the lower-dimension geometries contribute zero* "weight" to the centroid)** @return a {@link Point} which is the centroid of this Geometry*/Point* Geometry::getCentroid() const {	if ( isEmpty() ) {
		return NULL; 
	}	Coordinate* centPt;	int dim=getDimension();	Geometry *in = toInternalGeometry(this);	if(dim==0) {		CentroidPoint cent; 		cent.add(in);		centPt=cent.getCentroid();	} 
	else if (dim==1) {		CentroidLine cent;		cent.add(in);		centPt=cent.getCentroid();	} 
	else {		CentroidArea cent;		cent.add(in);		centPt=cent.getCentroid();	}	if ( ! centPt )	{		if ( in != this ) 
			delete(in);		return NULL;	}	Point *pt=createPointFromInternalCoord(centPt,this);	delete centPt;	if ( in != this ) 
		delete(in);	return pt;}/*** Computes an interior point of this <code>Geometry</code>.* An interior point is guaranteed to lie in the interior of the Geometry,* if it possible to calculate such a point exactly. Otherwise,* the point may lie on the boundary of the geometry.** @return a {@link Point} which is in the interior of this Geometry*/Point* Geometry::getInteriorPoint() {	const Coordinate* interiorPt;	int dim=getDimension();	Geometry *in = toInternalGeometry(this);	if (dim==0) {		InteriorPointPoint* intPt=new InteriorPointPoint(in);		interiorPt=intPt->getInteriorPoint();		delete intPt;	}
	else if (dim==1) {		InteriorPointLine* intPt=new InteriorPointLine(in);		interiorPt=intPt->getInteriorPoint();		delete intPt;	} 
	else {		InteriorPointArea* intPt=new InteriorPointArea(in);		interiorPt=intPt->getInteriorPoint();		delete intPt;	}	Point *p=createPointFromInternalCoord(interiorPt,this);	delete interiorPt;	if ( in != this )
		delete (in);	return p;}/*** Notifies this Geometry that its Coordinates have been changed by an external* party (using a CoordinateFilter, for example). The Geometry will flush* and/or update any information it has cached (such as its {@link Envelope} ).*/void Geometry::geometryChanged() {	apply_rw(&geometryChangedFilter);}/*** Notifies this Geometry that its Coordinates have been changed by an external* party. When #geometryChanged is called, this method will be called for* this Geometry and its component Geometries.* @see #apply(GeometryComponentFilter)*/void Geometry::geometryChangedAction() {	delete envelope;	envelope=NULL;}int Geometry::getSRID() const {
	return SRID;
}void Geometry::setSRID(int newSRID) {
	SRID=newSRID;
}/*** Gets the factory which contains the context in which this geometry was created.** @return the factory for this geometry*/const GeometryFactory*  Geometry::getFactory() const{	return factory;}/*** Gets the user data object for this geometry, if any.** @return the user data object, or <code>null</code> if none set*/void* Geometry::getUserData() {	return userData;}/*** A simple scheme for applications to add their own custom data to a Geometry.* An example use might be to add an object representing a Coordinate Reference System.* <p>* Note that user data objects are not present in geometries created by* construction methods.** @param userData an object, the semantics for which are defined by the* application using this Geometry*/void Geometry::setUserData(void* newUserData) {	userData=newUserData;}const PrecisionModel* Geometry::getPrecisionModel() const {	return factory->getPrecisionModel();}bool Geometry::isValid() const {	Geometry *in = toInternalGeometry(this);	IsValidOp isValidOp(in);	bool ret = isValidOp.isValid();	if (in != this) 
		delete (in);	return ret;}Geometry* Geometry::getEnvelope() const {	return getFactory()->toGeometry(getEnvelopeInternal());}const Envelope *Geometry::getEnvelopeInternal() const {	if (!envelope) {		envelope = computeEnvelopeInternal();	}	return envelope;}bool Geometry::disjoint(const Geometry *g) const{#ifdef SHORTCIRCUIT_PREDICATES	// short-circuit test	if (! getEnvelopeInternal()->intersects(g->getEnvelopeInternal()))		return true;#endif	IntersectionMatrix *im=relate(g);	bool res=im->isDisjoint();	delete im;	return res;}bool Geometry::touches(const Geometry *g) const{#ifdef SHORTCIRCUIT_PREDICATES	// short-circuit test	if (! getEnvelopeInternal()->intersects(g->getEnvelopeInternal()))		return false;#endif	IntersectionMatrix *im=relate(g);	bool res=im->isTouches(getDimension(), g->getDimension());	delete im;	return res;}bool Geometry::intersects(const Geometry *g) const{#ifdef SHORTCIRCUIT_PREDICATES	// short-circuit test	if (! getEnvelopeInternal()->intersects(g->getEnvelopeInternal()))		return false;#endif	IntersectionMatrix *im=relate(g);	bool res=im->isIntersects();	delete im;	return res;}bool Geometry::crosses(const Geometry *g) const{#ifdef SHORTCIRCUIT_PREDICATES	// short-circuit test	if (! getEnvelopeInternal()->intersects(g->getEnvelopeInternal()))		return false;#endif	IntersectionMatrix *im=relate(g);	bool res=im->isCrosses(getDimension(), g->getDimension());	delete im;	return res;}bool Geometry::within(const Geometry *g) const{#ifdef SHORTCIRCUIT_PREDICATES	// short-circuit test	if (! g->getEnvelopeInternal()->contains(getEnvelopeInternal()))		return false;#endif	IntersectionMatrix *im=relate(g);	bool res=im->isWithin();	delete im;	return res;}bool Geometry::contains(const Geometry *g) const{#ifdef SHORTCIRCUIT_PREDICATES	// short-circuit test	if (! getEnvelopeInternal()->contains(g->getEnvelopeInternal()))		return false;#endif	IntersectionMatrix *im=relate(g);	bool res=im->isContains();	delete im;	return res;}bool Geometry::overlaps(const Geometry *g) const{#ifdef SHORTCIRCUIT_PREDICATES	// short-circuit test	if (! getEnvelopeInternal()->intersects(g->getEnvelopeInternal()))		return false;#endif	IntersectionMatrix *im=relate(g);	bool res=im->isOverlaps(getDimension(), g->getDimension());	delete im;	return res;}bool Geometry::relate(const Geometry *g, string intersectionPattern) const {	IntersectionMatrix *im=relate(g);	bool res=im->matches(intersectionPattern);	delete im;	return res;}bool Geometry::equals(const Geometry *g) const {#ifdef SHORTCIRCUIT_PREDICATES	// short-circuit test	if (! getEnvelopeInternal()->equals(g->getEnvelopeInternal()))		return false;#endif	IntersectionMatrix *im=relate(g);	bool res=im->isEquals(getDimension(), g->getDimension());	delete im;	return res;}IntersectionMatrix*Geometry::relate(const Geometry *other) const	//throw(IllegalArgumentException *){	checkNotGeometryCollection(this);	checkNotGeometryCollection(other);	Geometry *in1 = toInternalGeometry(this);	Geometry *in2 = toInternalGeometry(other);	IntersectionMatrix *im = NULL;	try {		im = RelateOp::relate(in1, in2);	}	catch (...) {		if ( in1 != this ) delete (in1);		if ( in2 != other ) delete (in2);		throw;	}	if ( in1 != this ) delete (in1);	if ( in2 != other ) delete (in2);	return im;}string Geometry::toString() const {	return toText();}string Geometry::toText() const {	WKTWriter writer;	return writer.write(this);}Geometry* Geometry::buffer(double distance) const {	Geometry *in1 = toInternalGeometry(this);	Geometry *out = NULL;	try {		out = BufferOp::bufferOp(in1, distance);	}	catch(...) {		if ( in1 != this ) delete (in1);		throw;	}	if ( in1 != this ) delete (in1);	Geometry *ret = fromInternalGeometry(out);	if ( ret != out ) 
		delete (out);	return ret;}/*** The JTS algorithms assume that Geometry#getCoordinate and #getCoordinates* are fast, which may not be the case if the CoordinateSequence is not a* DefaultCoordinateSequence (e.g. if it were implemented using separate arrays* for the x- and y-values), in which case frequent construction of Coordinates* takes up much space and time. To solve this performance problem,* #toInternalGeometry converts the Geometry to a DefaultCoordinateSequence* implementation before sending it to the JTS algorithms.** Note: if the Geometry is already implemented with DefaultCoordinateSequence* it is returned untouched, so you should check returned value before* releasing memory associated with the one used as argument.*/Geometry* Geometry::toInternalGeometry(const Geometry *g) const {	if (DefaultCoordinateSequenceFactory::instance()==factory->getCoordinateSequenceFactory()) {		return (Geometry*)g;	}	return INTERNAL_GEOMETRY_FACTORY->createGeometry(g);}Geometry* Geometry::fromInternalGeometry(const Geometry* g) const {

⌨️ 快捷键说明

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