📄 ogrgeometry.cpp
字号:
/******************************************************************************
* $Id: ogrgeometry.cpp 10646 2007-01-18 02:38:10Z warmerdam $
*
* Project: OpenGIS Simple Features Reference Implementation
* Purpose: Implements a few base methods on OGRGeometry.
* 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 "ogr_geos.h"
#include <assert.h>
CPL_CVSID("$Id: ogrgeometry.cpp 10646 2007-01-18 02:38:10Z warmerdam $");
int OGRGeometry::bGenerate_DB2_V72_BYTE_ORDER = FALSE;
#ifdef HAVE_GEOS
static void _GEOSErrorHandler(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
CPLErrorV( CE_Failure, CPLE_AppDefined, fmt, args );
va_end(args);
}
static void _GEOSWarningHandler(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
CPLErrorV( CE_Warning, CPLE_AppDefined, fmt, args );
va_end(args);
}
#endif
/************************************************************************/
/* OGRGeometry() */
/************************************************************************/
OGRGeometry::OGRGeometry()
{
poSRS = NULL;
nCoordDimension = 2;
}
/************************************************************************/
/* ~OGRGeometry() */
/************************************************************************/
OGRGeometry::~OGRGeometry()
{
if( poSRS != NULL )
poSRS->Release();
}
/************************************************************************/
/* dumpReadable() */
/************************************************************************/
/**
* Dump geometry in well known text format to indicated output file.
*
* This method is the same as the C function OGR_G_DumpReadable().
*
* @param fp the text file to write the geometry to.
* @param pszPrefix the prefix to put on each line of output.
*/
void OGRGeometry::dumpReadable( FILE * fp, const char * pszPrefix ) const
{
char *pszWkt = NULL;
if( pszPrefix == NULL )
pszPrefix = "";
if( fp == NULL )
fp = stdout;
if( exportToWkt( &pszWkt ) == OGRERR_NONE )
{
fprintf( fp, "%s%s\n", pszPrefix, pszWkt );
CPLFree( pszWkt );
}
}
/************************************************************************/
/* OGR_G_DumpReadable() */
/************************************************************************/
/**
* Dump geometry in well known text format to indicated output file.
*
* This method is the same as the CPP method OGRGeometry::dumpReadable.
*
* @param hGeom handle on the geometry to dump.
* @param fp the text file to write the geometry to.
* @param pszPrefix the prefix to put on each line of output.
*/
void OGR_G_DumpReadable( OGRGeometryH hGeom, FILE *fp, const char *pszPrefix )
{
((OGRGeometry *) hGeom)->dumpReadable( fp, pszPrefix );
}
/************************************************************************/
/* assignSpatialReference() */
/************************************************************************/
/**
* \fn void OGRGeometry::assignSpatialReference( OGRSpatialReference * poSR );
*
* Assign spatial reference to this object. Any existing spatial reference
* is replaced, but under no circumstances does this result in the object
* being reprojected. It is just changing the interpretation of the existing
* geometry. Note that assigning a spatial reference increments the
* reference count on the OGRSpatialReference, but does not copy it.
*
* This is similar to the SFCOM IGeometry::put_SpatialReference() method.
*
* This method is the same as the C function OGR_G_AssignSpatialReference().
*
* @param poSR new spatial reference system to apply.
*/
void OGRGeometry::assignSpatialReference( OGRSpatialReference * poSR )
{
if( poSRS != NULL )
poSRS->Release();
poSRS = poSR;
if( poSRS != NULL )
poSRS->Reference();
}
/************************************************************************/
/* OGR_G_AssignSpatialReference() */
/************************************************************************/
/**
* Assign spatial reference to this object. Any existing spatial reference
* is replaced, but under no circumstances does this result in the object
* being reprojected. It is just changing the interpretation of the existing
* geometry. Note that assigning a spatial reference increments the
* reference count on the OGRSpatialReference, but does not copy it.
*
* This is similar to the SFCOM IGeometry::put_SpatialReference() method.
*
* This function is the same as the CPP method
* OGRGeometry::assignSpatialReference.
*
* @param hGeom handle on the geometry to apply the new spatial reference
* system.
* @param hSRS handle on the new spatial reference system to apply.
*/
void OGR_G_AssignSpatialReference( OGRGeometryH hGeom,
OGRSpatialReferenceH hSRS )
{
((OGRGeometry *) hGeom)->assignSpatialReference( (OGRSpatialReference *)
hSRS );
}
/************************************************************************/
/* Intersects() */
/************************************************************************/
/**
* Do these features intersect?
*
* Determines whether two geometries intersect. If GEOS is enabled, then
* this is done in rigerous fashion otherwise TRUE is returned if the
* envelopes (bounding boxes) of the two features overlap.
*
* The poOtherGeom argument may be safely NULL, but in this case the method
* will always return TRUE. That is, a NULL geometry is treated as being
* everywhere.
*
* This method is the same as the C function OGR_G_Intersects().
*
* @param poOtherGeom the other geometry to test against.
*
* @return TRUE if the geometries intersect, otherwise FALSE.
*/
OGRBoolean OGRGeometry::Intersects( OGRGeometry *poOtherGeom ) const
{
OGREnvelope oEnv1, oEnv2;
if( this == NULL || poOtherGeom == NULL )
return TRUE;
this->getEnvelope( &oEnv1 );
poOtherGeom->getEnvelope( &oEnv2 );
if( oEnv1.MaxX < oEnv2.MinX
|| oEnv1.MaxY < oEnv2.MinY
|| oEnv2.MaxX < oEnv1.MinX
|| oEnv2.MaxY < oEnv1.MinY )
return FALSE;
#ifndef HAVE_GEOS
// Without GEOS we assume that envelope overlap is equivelent to
// actual intersection.
return TRUE;
#else
GEOSGeom hThisGeosGeom = NULL;
GEOSGeom hOtherGeosGeom = NULL;
hThisGeosGeom = exportToGEOS();
hOtherGeosGeom = poOtherGeom->exportToGEOS();
if( hThisGeosGeom != NULL && hOtherGeosGeom != NULL )
{
OGRBoolean bResult;
if( GEOSIntersects( hThisGeosGeom, hOtherGeosGeom ) != 0 )
bResult = TRUE;
else
bResult = FALSE;
GEOSGeom_destroy( hThisGeosGeom );
GEOSGeom_destroy( hOtherGeosGeom );
return bResult;
}
else
{
return TRUE;
}
#endif /* HAVE_GEOS */
}
// Old API compatibility function.
OGRBoolean OGRGeometry::Intersect( OGRGeometry *poOtherGeom ) const
{
return Intersects( poOtherGeom );
}
/************************************************************************/
/* OGR_G_Intersect() */
/************************************************************************/
/**
* Do these features intersect?
*
* Currently this is not implemented in a rigerous fashion, and generally
* just tests whether the envelopes of the two features intersect. Eventually
* this will be made rigerous.
*
* This function is the same as the CPP method OGRGeometry::Intersects.
*
* @param hGeom handle on the first geometry.
* @param hOtherGeom handle on the other geometry to test against.
*
* @return TRUE if the geometries intersect, otherwise FALSE.
*/
int OGR_G_Intersects( OGRGeometryH hGeom, OGRGeometryH hOtherGeom )
{
return ((OGRGeometry *) hGeom)->Intersects( (OGRGeometry *) hOtherGeom );
}
int OGR_G_Intersect( OGRGeometryH hGeom, OGRGeometryH hOtherGeom )
{
return ((OGRGeometry *) hGeom)->Intersects( (OGRGeometry *) hOtherGeom );
}
/************************************************************************/
/* transformTo() */
/************************************************************************/
/**
* Transform geometry to new spatial reference system.
*
* This method will transform the coordinates of a geometry from
* their current spatial reference system to a new target spatial
* reference system. Normally this means reprojecting the vectors,
* but it could include datum shifts, and changes of units.
*
* This method will only work if the geometry already has an assigned
* spatial reference system, and if it is transformable to the target
* coordinate system.
*
* Because this method requires internal creation and initialization of an
* OGRCoordinateTransformation object it is significantly more expensive to
* use this method to transform many geometries than it is to create the
* OGRCoordinateTransformation in advance, and call transform() with that
* transformation. This method exists primarily for convenience when only
* transforming a single geometry.
*
* This method is the same as the C function OGR_G_TransformTo().
*
* @param poSR spatial reference system to transform to.
*
* @return OGRERR_NONE on success, or an error code.
*/
OGRErr OGRGeometry::transformTo( OGRSpatialReference *poSR )
{
#ifdef DISABLE_OGRGEOM_TRANSFORM
return OGRERR_FAILURE;
#else
OGRCoordinateTransformation *poCT;
OGRErr eErr;
if( getSpatialReference() == NULL || poSR == NULL )
return OGRERR_FAILURE;
poCT = OGRCreateCoordinateTransformation( getSpatialReference(), poSR );
if( poCT == NULL )
return OGRERR_FAILURE;
eErr = transform( poCT );
delete poCT;
return eErr;
#endif
}
/************************************************************************/
/* OGR_G_TransformTo() */
/************************************************************************/
/**
* Transform geometry to new spatial reference system.
*
* This function will transform the coordinates of a geometry from
* their current spatial reference system to a new target spatial
* reference system. Normally this means reprojecting the vectors,
* but it could include datum shifts, and changes of units.
*
* This function will only work if the geometry already has an assigned
* spatial reference system, and if it is transformable to the target
* coordinate system.
*
* Because this function requires internal creation and initialization of an
* OGRCoordinateTransformation object it is significantly more expensive to
* use this function to transform many geometries than it is to create the
* OGRCoordinateTransformation in advance, and call transform() with that
* transformation. This function exists primarily for convenience when only
* transforming a single geometry.
*
* This function is the same as the CPP method OGRGeometry::transformTo.
*
* @param hGeom handle on the geometry to apply the transform to.
* @param hSRS handle on the spatial reference system to apply.
*
* @return OGRERR_NONE on success, or an error code.
*/
OGRErr OGR_G_TransformTo( OGRGeometryH hGeom, OGRSpatialReferenceH hSRS )
{
return ((OGRGeometry *) hGeom)->transformTo((OGRSpatialReference *) hSRS);
}
/**
* \fn OGRErr OGRGeometry::transform( OGRCoordinateTransformation *poCT );
*
* Apply arbitrary coordinate transformation to geometry.
*
* This method will transform the coordinates of a geometry from
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -