📄 ugkgeometrycollection.cpp
字号:
// ugkgeometrycollection.cpp: implementation of the UGKGeometryCollection class.////////////////////////////////////////////////////////////////////////#include "ugkgeometrycollection.h"#include "ugk_memopr.h"#include "ugkpolygon.h"UGKGeometryCollection::UGKGeometryCollection(){ nGeomCount = 0; papoGeoms = NULL; nCoordinateDimension = 2;}UGKGeometryCollection::~UGKGeometryCollection(){ empty(); nCoordinateDimension = 2;}/************************************************************************//* empty() *//************************************************************************/void UGKGeometryCollection::empty(){ if( papoGeoms != NULL ) { for( int i = 0; i < nGeomCount; i++ ) { delete papoGeoms[i]; } UGK_Free(papoGeoms) ; } nGeomCount = 0; papoGeoms = NULL;}/************************************************************************//* clone() *//************************************************************************/UGKGeometry *UGKGeometryCollection::clone() const{ UGKGeometryCollection *poNewGC; poNewGC = new UGKGeometryCollection; for( int i = 0; i < nGeomCount; i++ ) { poNewGC->addGeometry( papoGeoms[i] ); } return poNewGC;}/************************************************************************//* getGeometryType() *//************************************************************************/UGKwkbGeometryType UGKGeometryCollection::getGeometryType() const{ if( getCoordinateDimension() == 3 ) return wkbGeometryCollection25D; else return wkbGeometryCollection;}/************************************************************************//* getDimension() *//************************************************************************/int UGKGeometryCollection::getDimension() const{ return 2; // This isn't strictly correct. It should be based on members.}/************************************************************************//* getCoordinateDimension() *//* *//* Returning 2 is a dubious solution. This should at least be *//* overridden by some of the subclasses. *//************************************************************************/int UGKGeometryCollection::getCoordinateDimension() const{ if( nCoordinateDimension == 0 ) { ((UGKGeometryCollection *)this)->nCoordinateDimension = 2; for( int i = 0; i < nGeomCount; i++ ) if( papoGeoms[i]->getCoordinateDimension() == 3 ) ((UGKGeometryCollection *)this)->nCoordinateDimension = 3; } return nCoordinateDimension;}/************************************************************************//* flattenTo2D() *//************************************************************************/void UGKGeometryCollection::flattenTo2D(){ for( int i = 0; i < nGeomCount; i++ ) papoGeoms[i]->flattenTo2D(); nCoordinateDimension = 2;}/************************************************************************//* getGeometryName() *//************************************************************************/const char * UGKGeometryCollection::getGeometryName() const{ return "GEOMETRYCOLLECTION";}/************************************************************************//* getNumGeometries() *//************************************************************************//** * Fetch number of geometries in container. * * This method relates to the SFCOM IGeometryCollect::get_NumGeometries() * method. * * @return count of children geometries. May be zero. */int UGKGeometryCollection::getNumGeometries() const{ return nGeomCount;}/************************************************************************//* getGeometryRef() *//************************************************************************//** * Fetch geometry from container. * * This method returns a pointer to an geometry within the container. The * returned geometry remains owned by the container, and should not be * modified. The pointer is only valid untill the next change to the * geometry container. Use IGeometry::clone() to make a copy. * * * @param i the index of the geometry to fetch, between 0 and * getNumGeometries() - 1. * @return pointer to requested geometry. */UGKGeometry * UGKGeometryCollection::getGeometryRef( int i ) { if( i < 0 || i >= nGeomCount ) return NULL; else return papoGeoms[i];}const UGKGeometry * UGKGeometryCollection::getGeometryRef( int i ) const{ if( i < 0 || i >= nGeomCount ) return NULL; else return papoGeoms[i];}/************************************************************************//* addGeometry() *//* *//* Add a new geometry to a collection. Subclasses should *//* override this to verify the type of the new geometry, and *//* then call this method to actually add it. *//************************************************************************//** * Add a geometry to the container. * * Some subclasses of UGKGeometryCollection restrict the types of geometry * that can be added, and may return an error. The passed geometry is cloned * to make an internal copy. * * @param poNewGeom geometry to add to the container. * * @return UGKERR_NONE if successful, or UGKERR_UNSUPPORTED_GEOMETRY_TYPE if * the geometry type is illegal for the type of geometry container. */UGKErr UGKGeometryCollection::addGeometry( const UGKGeometry * poNewGeom ){ UGKGeometry *poClone = poNewGeom->clone(); UGKErr eErr; eErr = addGeometryDirectly( poClone ); if( eErr != UGKERR_NONE ) delete poClone; return eErr;}/************************************************************************//* addGeometryDirectly() *//* *//* Add a new geometry to a collection. Subclasses should *//* override this to verify the type of the new geometry, and *//* then call this method to actually add it. *//************************************************************************//** * Add a geometry directly to the container. * * Some subclasses of UGKGeometryCollection restrict the types of geometry * that can be added, and may return an error. Ownership of the passed * geometry is taken by the container rather than cloning as addGeometry() * does. * * * @param poNewGeom geometry to add to the container. * * @return UGKERR_NONE if successful, or UGKERR_UNSUPPORTED_GEOMETRY_TYPE if * the geometry type is illegal for the type of geometry container. */UGKErr UGKGeometryCollection::addGeometryDirectly( UGKGeometry * poNewGeom ){ papoGeoms = (UGKGeometry **) UGK_Realloc( papoGeoms, sizeof(void*) * (nGeomCount+1) ); papoGeoms[nGeomCount] = poNewGeom; nGeomCount++; if( poNewGeom->getCoordinateDimension() == 3 ) nCoordinateDimension = 3; return UGKERR_NONE;}/************************************************************************//* removeGeometry() *//************************************************************************//** * Remove a geometry from the container. * * Removing a geometry will cause the geometry count to drop by one, and all * "higher" geometries will shuffle down one in index. * * * @param iGeom the index of the geometry to delete. A value of -1 is a * special flag meaning that all geometries should be removed. * * @param bDelete if TRUE the geometry will be deallocated, otherwise it will * not. The default is TRUE as the container is considered to own the * geometries in it. * * @return UGKERR_NONE if successful, or UGKERR_FAILURE if the index is * out of range. */UGKErr UGKGeometryCollection::removeGeometry( int iGeom, int bDelete ){ if( iGeom < -1 || iGeom >= nGeomCount ) return UGKERR_FAILURE; // Special case. if( iGeom == -1 ) { while( nGeomCount > 0 ) removeGeometry( nGeomCount-1, bDelete ); return UGKERR_NONE; } if( bDelete ) delete papoGeoms[iGeom]; memmove( papoGeoms + iGeom, papoGeoms + iGeom + 1, sizeof(void*) * (nGeomCount-iGeom-1) ); nGeomCount--; return UGKERR_NONE;}/************************************************************************//* WkbSize() *//* *//* Return the size of this object in well known binary *//* representation including the byte order, and type information. *//************************************************************************/int UGKGeometryCollection::WkbSize() const{ int nSize = 9; for( int i = 0; i < nGeomCount; i++ ) { nSize += papoGeoms[i]->WkbSize(); } return nSize;}/************************************************************************//* getEnvelope() *//************************************************************************/void UGKGeometryCollection::getEnvelope( UGKEnvelope * psEnvelope ) const{ UGKEnvelope oGeomEnv; if( nGeomCount == 0 ) return; papoGeoms[0]->getEnvelope( psEnvelope ); for( int iGeom = 1; iGeom < nGeomCount; iGeom++ ) { papoGeoms[iGeom]->getEnvelope( &oGeomEnv ); if( psEnvelope->MinX > oGeomEnv.MinX ) psEnvelope->MinX = oGeomEnv.MinX; if( psEnvelope->MinY > oGeomEnv.MinY ) psEnvelope->MinY = oGeomEnv.MinY; if( psEnvelope->MaxX < oGeomEnv.MaxX ) psEnvelope->MaxX = oGeomEnv.MaxX; if( psEnvelope->MaxY < oGeomEnv.MaxY ) psEnvelope->MaxY = oGeomEnv.MaxY; }}/************************************************************************//* Equals() *//************************************************************************/UGKBool UGKGeometryCollection::Equals( UGKGeometry * poOther ) const{ UGKGeometryCollection *poOGC = (UGKGeometryCollection *) poOther; if( poOGC == this ) return TRUE; if( poOther->getGeometryType() != getGeometryType() ) return FALSE; if( getNumGeometries() != poOGC->getNumGeometries() ) return FALSE; // we should eventually test the SRS. for( int iGeom = 0; iGeom < nGeomCount; iGeom++ ) { if( !getGeometryRef(iGeom)->Equals(poOGC->getGeometryRef(iGeom)) ) return FALSE; } return TRUE;}/************************************************************************//* closeRings() *//************************************************************************/void UGKGeometryCollection::closeRings(){ for( int iGeom = 0; iGeom < nGeomCount; iGeom++ ) { if( wkbFlatten(papoGeoms[iGeom]->getGeometryType()) == wkbPolygon ) ((UGKPolygon *) papoGeoms[iGeom])->closeRings(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -