📄 ogrgeometryfactory.cpp
字号:
/******************************************************************************
* $Id: ogrgeometryfactory.cpp 10646 2007-01-18 02:38:10Z warmerdam $
*
* Project: OpenGIS Simple Features Reference Implementation
* Purpose: Factory for converting geometry to and from well known binary
* format.
* 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_api.h"
#include "ogr_p.h"
#include <assert.h>
#include "ogr_geos.h"
CPL_CVSID("$Id: ogrgeometryfactory.cpp 10646 2007-01-18 02:38:10Z warmerdam $");
/************************************************************************/
/* createFromWkb() */
/************************************************************************/
/**
* Create a geometry object of the appropriate type from it's well known
* binary representation.
*
* Note that if nBytes is passed as zero, no checking can be done on whether
* the pabyData is sufficient. This can result in a crash if the input
* data is corrupt. This function returns no indication of the number of
* bytes from the data source actually used to represent the returned
* geometry object. Use OGRGeometry::WkbSize() on the returned geometry to
* establish the number of bytes it required in WKB format.
*
* Also note that this is a static method, and that there
* is no need to instantiate an OGRGeometryFactory object.
*
* The C function OGR_G_CreateFromWkb() is the same as this method.
*
* @param pabyData pointer to the input BLOB data.
* @param poSR pointer to the spatial reference to be assigned to the
* created geometry object. This may be NULL.
* @param ppoReturn the newly created geometry object will be assigned to the
* indicated pointer on return. This will be NULL in case
* of failure.
* @param nBytes the number of bytes available in pabyData, or -1 if it isn't
* known.
*
* @return OGRERR_NONE if all goes well, otherwise any of
* OGRERR_NOT_ENOUGH_DATA, OGRERR_UNSUPPORTED_GEOMETRY_TYPE, or
* OGRERR_CORRUPT_DATA may be returned.
*/
OGRErr OGRGeometryFactory::createFromWkb(unsigned char *pabyData,
OGRSpatialReference * poSR,
OGRGeometry **ppoReturn,
int nBytes )
{
OGRwkbGeometryType eGeometryType;
OGRwkbByteOrder eByteOrder;
OGRErr eErr;
OGRGeometry *poGeom;
*ppoReturn = NULL;
if( nBytes < 5 && nBytes != -1 )
return OGRERR_NOT_ENOUGH_DATA;
/* -------------------------------------------------------------------- */
/* Get the byte order byte. The extra tests are to work around */
/* bug sin the WKB of DB2 v7.2 as identified by Safe Software. */
/* -------------------------------------------------------------------- */
eByteOrder = DB2_V72_FIX_BYTE_ORDER((OGRwkbByteOrder) *pabyData);
if( eByteOrder != wkbXDR && eByteOrder != wkbNDR )
{
CPLDebug( "OGR",
"OGRGeometryFactory::createFromWkb() - got corrupt data.\n"
"%02X%02X%02X%02X%02X%02X%02X%02X\n",
pabyData[0],
pabyData[1],
pabyData[2],
pabyData[3],
pabyData[4],
pabyData[5],
pabyData[6],
pabyData[7],
pabyData[8] );
return OGRERR_CORRUPT_DATA;
}
/* -------------------------------------------------------------------- */
/* 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. */
/* -------------------------------------------------------------------- */
if( eByteOrder == wkbNDR )
eGeometryType = (OGRwkbGeometryType) pabyData[1];
else
eGeometryType = (OGRwkbGeometryType) pabyData[4];
/* -------------------------------------------------------------------- */
/* Instantiate a geometry of the appropriate type, and */
/* initialize from the input stream. */
/* -------------------------------------------------------------------- */
poGeom = createGeometry( eGeometryType );
if( poGeom == NULL )
return OGRERR_UNSUPPORTED_GEOMETRY_TYPE;
/* -------------------------------------------------------------------- */
/* Import from binary. */
/* -------------------------------------------------------------------- */
eErr = poGeom->importFromWkb( pabyData, nBytes );
/* -------------------------------------------------------------------- */
/* Assign spatial reference system. */
/* -------------------------------------------------------------------- */
if( eErr == OGRERR_NONE )
{
poGeom->assignSpatialReference( poSR );
*ppoReturn = poGeom;
}
else
{
delete poGeom;
}
return eErr;
}
/************************************************************************/
/* OGR_G_CreateFromWkb() */
/************************************************************************/
/**
* Create a geometry object of the appropriate type from it's well known
* binary representation.
*
* Note that if nBytes is passed as zero, no checking can be done on whether
* the pabyData is sufficient. This can result in a crash if the input
* data is corrupt. This function returns no indication of the number of
* bytes from the data source actually used to represent the returned
* geometry object. Use OGR_G_WkbSize() on the returned geometry to
* establish the number of bytes it required in WKB format.
*
* The OGRGeometryFactory::createFromWkb() CPP method is the same as this
* function.
*
* @param pabyData pointer to the input BLOB data.
* @param hSRS handle to the spatial reference to be assigned to the
* created geometry object. This may be NULL.
* @param phGeometry the newly created geometry object will
* be assigned to the indicated handle on return. This will be NULL in case
* of failure.
* @param nBytes the number of bytes of data available in pabyData, or -1
* if it is not known, but assumed to be sufficient.
*
* @return OGRERR_NONE if all goes well, otherwise any of
* OGRERR_NOT_ENOUGH_DATA, OGRERR_UNSUPPORTED_GEOMETRY_TYPE, or
* OGRERR_CORRUPT_DATA may be returned.
*/
OGRErr CPL_DLL OGR_G_CreateFromWkb( unsigned char *pabyData,
OGRSpatialReferenceH hSRS,
OGRGeometryH *phGeometry,
int nBytes )
{
return OGRGeometryFactory::createFromWkb( pabyData,
(OGRSpatialReference *) hSRS,
(OGRGeometry **) phGeometry,
nBytes );
}
/************************************************************************/
/* createFromWkt() */
/************************************************************************/
/**
* Create a geometry object of the appropriate type from it's well known
* text representation.
*
* The C function OGR_G_CreateFromWkt() is the same as this method.
*
* @param ppszData input zero terminated string containing well known text
* representation of the geometry to be created. The pointer
* is updated to point just beyond that last character consumed.
* @param poSR pointer to the spatial reference to be assigned to the
* created geometry object. This may be NULL.
* @param ppoReturn the newly created geometry object will be assigned to the
* indicated pointer on return. This will be NULL if the
* method fails.
*
* <b>Example:</b>
*
* <pre>
* const char* wkt= "POINT(0 0)";
*
* // cast because OGR_G_CreateFromWkt will move the pointer
* char* pszWkt = (char*) wkt.c_str();
* OGRSpatialReferenceH ref = OSRNewSpatialReference(NULL);
* OGRGeometryH new_geom;
* OGRErr err = OGR_G_CreateFromWkt(&pszWkt, ref, &new_geom);
* </pre>
*
*
*
* @return OGRERR_NONE if all goes well, otherwise any of
* OGRERR_NOT_ENOUGH_DATA, OGRERR_UNSUPPORTED_GEOMETRY_TYPE, or
* OGRERR_CORRUPT_DATA may be returned.
*/
OGRErr OGRGeometryFactory::createFromWkt(char **ppszData,
OGRSpatialReference * poSR,
OGRGeometry **ppoReturn )
{
OGRErr eErr;
char szToken[OGR_WKT_TOKEN_MAX];
char *pszInput = *ppszData;
OGRGeometry *poGeom;
*ppoReturn = NULL;
/* -------------------------------------------------------------------- */
/* Get the first token, which should be the geometry type. */
/* -------------------------------------------------------------------- */
if( OGRWktReadToken( pszInput, szToken ) == NULL )
return OGRERR_CORRUPT_DATA;
/* -------------------------------------------------------------------- */
/* Instantiate a geometry of the appropriate type. */
/* -------------------------------------------------------------------- */
if( EQUAL(szToken,"POINT") )
{
poGeom = new OGRPoint();
}
else if( EQUAL(szToken,"LINESTRING") )
{
poGeom = new OGRLineString();
}
else if( EQUAL(szToken,"POLYGON") )
{
poGeom = new OGRPolygon();
}
else if( EQUAL(szToken,"GEOMETRYCOLLECTION") )
{
poGeom = new OGRGeometryCollection();
}
else if( EQUAL(szToken,"MULTIPOLYGON") )
{
poGeom = new OGRMultiPolygon();
}
else if( EQUAL(szToken,"MULTIPOINT") )
{
poGeom = new OGRMultiPoint();
}
else if( EQUAL(szToken,"MULTILINESTRING") )
{
poGeom = new OGRMultiLineString();
}
else
{
return OGRERR_UNSUPPORTED_GEOMETRY_TYPE;
}
/* -------------------------------------------------------------------- */
/* Do the import. */
/* -------------------------------------------------------------------- */
eErr = poGeom->importFromWkt( &pszInput );
/* -------------------------------------------------------------------- */
/* Assign spatial reference system. */
/* -------------------------------------------------------------------- */
if( eErr == OGRERR_NONE )
{
poGeom->assignSpatialReference( poSR );
*ppoReturn = poGeom;
*ppszData = pszInput;
}
else
{
delete poGeom;
}
return eErr;
}
/************************************************************************/
/* OGR_G_CreateFromWkt() */
/************************************************************************/
/**
* Create a geometry object of the appropriate type from it's well known
* text representation.
*
* The OGRGeometryFactory::createFromWkt CPP method is the same as this
* function.
*
* @param ppszData input zero terminated string containing well known text
* representation of the geometry to be created. The pointer
* is updated to point just beyond that last character consumed.
* @param hSRS handle to the spatial reference to be assigned to the
* created geometry object. This may be NULL.
* @param phGeometry the newly created geometry object will be assigned to the
* indicated handle on return. This will be NULL if the
* method fails.
*
* @return OGRERR_NONE if all goes well, otherwise any of
* OGRERR_NOT_ENOUGH_DATA, OGRERR_UNSUPPORTED_GEOMETRY_TYPE, or
* OGRERR_CORRUPT_DATA may be returned.
*/
OGRErr CPL_DLL OGR_G_CreateFromWkt( char **ppszData,
OGRSpatialReferenceH hSRS,
OGRGeometryH *phGeometry )
{
return OGRGeometryFactory::createFromWkt( ppszData,
(OGRSpatialReference *) hSRS,
(OGRGeometry **) phGeometry );
}
/************************************************************************/
/* createGeometry() */
/************************************************************************/
/**
* Create an empty geometry of desired type.
*
* This is equivelent to allocating the desired geometry with new, but
* the allocation is guaranteed to take place in the context of the
* GDAL/OGR heap.
*
* This method is the same as the C function OGR_G_CreateGeometry().
*
* @param eGeometryType the type code of the geometry class to be instantiated.
*
* @return the newly create geometry or NULL on failure.
*/
OGRGeometry *
OGRGeometryFactory::createGeometry( OGRwkbGeometryType eGeometryType )
{
switch( wkbFlatten(eGeometryType) )
{
case wkbPoint:
return new OGRPoint();
case wkbLineString:
return new OGRLineString();
case wkbPolygon:
return new OGRPolygon();
case wkbGeometryCollection:
return new OGRGeometryCollection();
case wkbMultiPolygon:
return new OGRMultiPolygon();
case wkbMultiPoint:
return new OGRMultiPoint();
case wkbMultiLineString:
return new OGRMultiLineString();
case wkbLinearRing:
return new OGRLinearRing();
default:
return NULL;
}
return NULL;
}
/************************************************************************/
/* OGR_G_CreateGeometry() */
/************************************************************************/
/**
* Create an empty geometry of desired type.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -