?? ogrgeometrycollection.cpp
字號:
/******************************************************************************
* $Id: ogrgeometrycollection.cpp 10646 2007-01-18 02:38:10Z warmerdam $
*
* Project: OpenGIS Simple Features Reference Implementation
* Purpose: The OGRGeometryCollection class.
* Author: Frank Warmerdam, warmerdam@pobox.com
*
******************************************************************************
* Copyright (c) 1999, Frank Warmerdam
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
****************************************************************************/
#include "ogr_geometry.h"
#include "ogr_p.h"
CPL_CVSID("$Id: ogrgeometrycollection.cpp 10646 2007-01-18 02:38:10Z warmerdam $");
/************************************************************************/
/* OGRGeometryCollection() */
/************************************************************************/
/**
* Create an empty geometry collection.
*/
OGRGeometryCollection::OGRGeometryCollection()
{
nGeomCount = 0;
papoGeoms = NULL;
nCoordinateDimension = 2;
}
/************************************************************************/
/* ~OGRGeometryCollection() */
/************************************************************************/
OGRGeometryCollection::~OGRGeometryCollection()
{
empty();
nCoordinateDimension = 2;
}
/************************************************************************/
/* empty() */
/************************************************************************/
void OGRGeometryCollection::empty()
{
if( papoGeoms != NULL )
{
for( int i = 0; i < nGeomCount; i++ )
{
delete papoGeoms[i];
}
OGRFree( papoGeoms );
}
nGeomCount = 0;
papoGeoms = NULL;
}
/************************************************************************/
/* clone() */
/************************************************************************/
OGRGeometry *OGRGeometryCollection::clone() const
{
OGRGeometryCollection *poNewGC;
poNewGC = new OGRGeometryCollection;
poNewGC->assignSpatialReference( getSpatialReference() );
for( int i = 0; i < nGeomCount; i++ )
{
poNewGC->addGeometry( papoGeoms[i] );
}
return poNewGC;
}
/************************************************************************/
/* getGeometryType() */
/************************************************************************/
OGRwkbGeometryType OGRGeometryCollection::getGeometryType() const
{
if( getCoordinateDimension() == 3 )
return wkbGeometryCollection25D;
else
return wkbGeometryCollection;
}
/************************************************************************/
/* getDimension() */
/************************************************************************/
int OGRGeometryCollection::getDimension() const
{
return 2; // This isn't strictly correct. It should be based on members.
}
/************************************************************************/
/* flattenTo2D() */
/************************************************************************/
void OGRGeometryCollection::flattenTo2D()
{
for( int i = 0; i < nGeomCount; i++ )
papoGeoms[i]->flattenTo2D();
nCoordinateDimension = 2;
}
/************************************************************************/
/* getGeometryName() */
/************************************************************************/
const char * OGRGeometryCollection::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 OGRGeometryCollection::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.
*
* This method relates to the SFCOM IGeometryCollection::get_Geometry() method.
*
* @param i the index of the geometry to fetch, between 0 and
* getNumGeometries() - 1.
* @return pointer to requested geometry.
*/
OGRGeometry * OGRGeometryCollection::getGeometryRef( int i )
{
if( i < 0 || i >= nGeomCount )
return NULL;
else
return papoGeoms[i];
}
const OGRGeometry * OGRGeometryCollection::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 OGRGeometryCollection restrict the types of geometry
* that can be added, and may return an error. The passed geometry is cloned
* to make an internal copy.
*
* There is no SFCOM analog to this method.
*
* This method is the same as the C function OGR_G_AddGeometry().
*
* @param poNewGeom geometry to add to the container.
*
* @return OGRERR_NONE if successful, or OGRERR_UNSUPPORTED_GEOMETRY_TYPE if
* the geometry type is illegal for the type of geometry container.
*/
OGRErr OGRGeometryCollection::addGeometry( const OGRGeometry * poNewGeom )
{
OGRGeometry *poClone = poNewGeom->clone();
OGRErr eErr;
eErr = addGeometryDirectly( poClone );
if( eErr != OGRERR_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 OGRGeometryCollection 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.
*
* This method is the same as the C function OGR_G_AddGeometryDirectly().
*
* There is no SFCOM analog to this method.
*
* @param poNewGeom geometry to add to the container.
*
* @return OGRERR_NONE if successful, or OGRERR_UNSUPPORTED_GEOMETRY_TYPE if
* the geometry type is illegal for the type of geometry container.
*/
OGRErr OGRGeometryCollection::addGeometryDirectly( OGRGeometry * poNewGeom )
{
papoGeoms = (OGRGeometry **) OGRRealloc( papoGeoms,
sizeof(void*) * (nGeomCount+1) );
papoGeoms[nGeomCount] = poNewGeom;
nGeomCount++;
if( poNewGeom->getCoordinateDimension() == 3 )
nCoordinateDimension = 3;
return OGRERR_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.
*
* There is no SFCOM analog to this method.
*
* This method is the same as the C function OGR_G_RemoveGeometry().
*
* @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 OGRERR_NONE if successful, or OGRERR_FAILURE if the index is
* out of range.
*/
OGRErr OGRGeometryCollection::removeGeometry( int iGeom, int bDelete )
{
if( iGeom < -1 || iGeom >= nGeomCount )
return OGRERR_FAILURE;
// Special case.
if( iGeom == -1 )
{
while( nGeomCount > 0 )
removeGeometry( nGeomCount-1, bDelete );
return OGRERR_NONE;
}
if( bDelete )
delete papoGeoms[iGeom];
memmove( papoGeoms + iGeom, papoGeoms + iGeom + 1,
sizeof(void*) * (nGeomCount-iGeom-1) );
nGeomCount--;
return OGRERR_NONE;
}
/************************************************************************/
/* WkbSize() */
/* */
/* Return the size of this object in well known binary */
/* representation including the byte order, and type information. */
/************************************************************************/
int OGRGeometryCollection::WkbSize() const
{
int nSize = 9;
for( int i = 0; i < nGeomCount; i++ )
{
nSize += papoGeoms[i]->WkbSize();
}
return nSize;
}
/************************************************************************/
/* importFromWkb() */
/* */
/* Initialize from serialized stream in well known binary */
/* format. */
/************************************************************************/
OGRErr OGRGeometryCollection::importFromWkb( unsigned char * pabyData,
int nSize )
{
OGRwkbByteOrder eByteOrder;
int nDataOffset;
if( nSize < 9 && nSize != -1 )
return OGRERR_NOT_ENOUGH_DATA;
/* -------------------------------------------------------------------- */
/* Get the byte order byte. */
/* -------------------------------------------------------------------- */
eByteOrder = DB2_V72_FIX_BYTE_ORDER((OGRwkbByteOrder) *pabyData);
CPLAssert( eByteOrder == wkbXDR || eByteOrder == wkbNDR );
/* -------------------------------------------------------------------- */
/* Get the geometry feature type. For now we assume that */
/* geometry type is between 0 and 255 so we only have to fetch */
/* one byte. */
/* -------------------------------------------------------------------- */
#ifdef DEBUG
OGRwkbGeometryType eGeometryType;
if( eByteOrder == wkbNDR )
{
eGeometryType = (OGRwkbGeometryType) pabyData[1];
}
else
{
eGeometryType = (OGRwkbGeometryType) pabyData[4];
}
CPLAssert( eGeometryType == wkbGeometryCollection
|| eGeometryType == wkbMultiPolygon
|| eGeometryType == wkbMultiLineString
|| eGeometryType == wkbMultiPoint );
#endif
/* -------------------------------------------------------------------- */
/* Do we already have some existing geometry objects? */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -