LCOV - code coverage report
Current view: directory - ogr - ogrgeometry.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 764 640 83.8 %
Date: 2012-12-26 Functions: 108 86 79.6 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrgeometry.cpp 25268 2012-11-29 20:21:41Z rouault $
       3                 :  *
       4                 :  * Project:  OpenGIS Simple Features Reference Implementation
       5                 :  * Purpose:  Implements a few base methods on OGRGeometry.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 1999, Frank Warmerdam
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : #include "ogr_geometry.h"
      31                 : #include "ogr_api.h"
      32                 : #include "ogr_p.h"
      33                 : #include "ogr_geos.h"
      34                 : #include "cpl_multiproc.h"
      35                 : #include <assert.h>
      36                 : 
      37                 : CPL_CVSID("$Id: ogrgeometry.cpp 25268 2012-11-29 20:21:41Z rouault $");
      38                 : 
      39                 : int OGRGeometry::bGenerate_DB2_V72_BYTE_ORDER = FALSE;
      40                 : 
      41                 : #ifdef HAVE_GEOS
      42               0 : static void _GEOSErrorHandler(const char *fmt, ...)
      43                 : {
      44                 :     va_list args;
      45                 : 
      46               0 :     va_start(args, fmt);
      47               0 :     CPLErrorV( CE_Failure, CPLE_AppDefined, fmt, args );
      48               0 :     va_end(args);
      49               0 : }
      50                 : 
      51               1 : static void _GEOSWarningHandler(const char *fmt, ...)
      52                 : {
      53                 :     va_list args;
      54                 : 
      55               1 :     va_start(args, fmt);
      56               1 :     CPLErrorV( CE_Warning, CPLE_AppDefined, fmt, args );
      57               1 :     va_end(args);
      58               1 : }
      59                 : #endif
      60                 : 
      61                 : /************************************************************************/
      62                 : /*                            OGRGeometry()                             */
      63                 : /************************************************************************/
      64                 : 
      65         1096671 : OGRGeometry::OGRGeometry()
      66                 : 
      67                 : {
      68         1096671 :     poSRS = NULL;
      69         1096671 :     nCoordDimension = 2;
      70         1096671 : }
      71                 : 
      72                 : /************************************************************************/
      73                 : /*                            ~OGRGeometry()                            */
      74                 : /************************************************************************/
      75                 : 
      76         1096721 : OGRGeometry::~OGRGeometry()
      77                 : 
      78                 : {
      79         1096721 :     if( poSRS != NULL )
      80          739157 :         poSRS->Release();
      81         1096721 : }
      82                 : 
      83                 : /************************************************************************/
      84                 : /*                            dumpReadable()                            */
      85                 : /************************************************************************/
      86                 : 
      87                 : /**
      88                 :  * \brief Dump geometry in well known text format to indicated output file.
      89                 :  *
      90                 :  * A few options can be defined to change the default dump :
      91                 :  * <ul>
      92                 :  * <li>DISPLAY_GEOMETRY=NO : to hide the dump of the geometry</li>
      93                 :  * <li>DISPLAY_GEOMETRY=WKT or YES (default) : dump the geometry as a WKT</li>
      94                 :  * <li>DISPLAY_GEOMETRY=SUMMARY : to get only a summary of the geometry</li>
      95                 :  * </ul>
      96                 :  *
      97                 :  * This method is the same as the C function OGR_G_DumpReadable().
      98                 :  *
      99                 :  * @param fp the text file to write the geometry to.
     100                 :  * @param pszPrefix the prefix to put on each line of output.
     101                 :  * @param papszOptions NULL terminated list of options (may be NULL)
     102                 :  */
     103                 : 
     104              57 : void OGRGeometry::dumpReadable( FILE * fp, const char * pszPrefix, char** papszOptions ) const
     105                 : 
     106                 : {
     107              57 :     char        *pszWkt = NULL;
     108                 :     
     109              57 :     if( pszPrefix == NULL )
     110               0 :         pszPrefix = "";
     111                 : 
     112              57 :     if( fp == NULL )
     113               0 :         fp = stdout;
     114                 : 
     115                 :     const char* pszDisplayGeometry =
     116              57 :                 CSLFetchNameValue(papszOptions, "DISPLAY_GEOMETRY");
     117              67 :     if (pszDisplayGeometry != NULL && EQUAL(pszDisplayGeometry, "SUMMARY"))
     118                 :     {
     119                 :         OGRLineString *poLine;
     120                 :         OGRPolygon *poPoly;
     121                 :         OGRLinearRing *poRing;
     122                 :         OGRGeometryCollection *poColl;
     123              10 :         fprintf( fp, "%s%s : ", pszPrefix, getGeometryName() );
     124              10 :         switch( getGeometryType() )
     125                 :         {
     126                 :             case wkbUnknown:
     127                 :             case wkbNone:
     128                 :             case wkbPoint:
     129                 :             case wkbPoint25D:
     130               0 :                 fprintf( fp, "\n");
     131               0 :                 break;
     132                 :             case wkbLineString:
     133                 :             case wkbLineString25D:
     134               0 :                 poLine = (OGRLineString*)this;
     135               0 :                 fprintf( fp, "%d points\n", poLine->getNumPoints() );
     136               0 :                 break;
     137                 :             case wkbPolygon:
     138                 :             case wkbPolygon25D:
     139                 :             {
     140                 :                 int ir;
     141                 :                 int nRings;
     142              10 :                 poPoly = (OGRPolygon*)this;
     143              10 :                 poRing = poPoly->getExteriorRing();
     144              10 :                 nRings = poPoly->getNumInteriorRings();
     145              10 :                 if (poRing == NULL)
     146               0 :                     fprintf( fp, "empty");
     147                 :                 else
     148                 :                 {
     149              10 :                     fprintf( fp, "%d points", poRing->getNumPoints() );
     150              10 :                     if (nRings)
     151                 :                     {
     152               0 :                         fprintf( fp, ", %d inner rings (", nRings);
     153               0 :                         for( ir = 0; ir < nRings; ir++)
     154                 :                         {
     155               0 :                             if (ir)
     156               0 :                                 fprintf( fp, ", ");
     157                 :                             fprintf( fp, "%d points",
     158               0 :                                     poPoly->getInteriorRing(ir)->getNumPoints() );
     159                 :                         }
     160               0 :                         fprintf( fp, ")");
     161                 :                     }
     162                 :                 }
     163              10 :                 fprintf( fp, "\n");
     164              10 :                 break;
     165                 :             }
     166                 :             case wkbMultiPoint:
     167                 :             case wkbMultiPoint25D:
     168                 :             case wkbMultiLineString:
     169                 :             case wkbMultiLineString25D:
     170                 :             case wkbMultiPolygon:
     171                 :             case wkbMultiPolygon25D:
     172                 :             case wkbGeometryCollection:
     173                 :             case wkbGeometryCollection25D:
     174                 :             {
     175                 :                 int ig;
     176               0 :                 poColl = (OGRGeometryCollection*)this;
     177               0 :                 fprintf( fp, "%d geometries:\n", poColl->getNumGeometries() );
     178               0 :                 for ( ig = 0; ig < poColl->getNumGeometries(); ig++)
     179                 :                 {
     180               0 :                     OGRGeometry * poChild = (OGRGeometry*)poColl->getGeometryRef(ig);
     181               0 :                     fprintf( fp, "%s", pszPrefix);
     182               0 :                     poChild->dumpReadable( fp, pszPrefix, papszOptions );
     183                 :                 }
     184                 :                 break;
     185                 :             }
     186                 :             case wkbLinearRing:
     187                 :                 break;
     188                 :         }
     189                 :     }
     190              47 :     else if (pszDisplayGeometry == NULL || CSLTestBoolean(pszDisplayGeometry) ||
     191                 :              EQUAL(pszDisplayGeometry, "WKT"))
     192                 :     {
     193              47 :         if( exportToWkt( &pszWkt ) == OGRERR_NONE )
     194                 :         {
     195              47 :             fprintf( fp, "%s%s\n", pszPrefix, pszWkt );
     196              47 :             CPLFree( pszWkt );
     197                 :         }
     198                 :     }
     199              57 : }
     200                 : 
     201                 : /************************************************************************/
     202                 : /*                         OGR_G_DumpReadable()                         */
     203                 : /************************************************************************/
     204                 : /**
     205                 :  * \brief Dump geometry in well known text format to indicated output file.
     206                 :  *
     207                 :  * This method is the same as the CPP method OGRGeometry::dumpReadable.
     208                 :  *
     209                 :  * @param hGeom handle on the geometry to dump.
     210                 :  * @param fp the text file to write the geometry to.
     211                 :  * @param pszPrefix the prefix to put on each line of output.
     212                 :  */
     213                 : 
     214               0 : void OGR_G_DumpReadable( OGRGeometryH hGeom, FILE *fp, const char *pszPrefix )
     215                 : 
     216                 : {
     217               0 :     VALIDATE_POINTER0( hGeom, "OGR_G_DumpReadable" );
     218                 : 
     219               0 :     ((OGRGeometry *) hGeom)->dumpReadable( fp, pszPrefix );
     220                 : }
     221                 : 
     222                 : /************************************************************************/
     223                 : /*                       assignSpatialReference()                       */
     224                 : /************************************************************************/
     225                 : 
     226                 : /**
     227                 :  * \fn void OGRGeometry::assignSpatialReference( OGRSpatialReference * poSR );
     228                 :  *
     229                 :  * \brief Assign spatial reference to this object.
     230                 :  *
     231                 :  * Any existing spatial reference
     232                 :  * is replaced, but under no circumstances does this result in the object
     233                 :  * being reprojected.  It is just changing the interpretation of the existing
     234                 :  * geometry.  Note that assigning a spatial reference increments the
     235                 :  * reference count on the OGRSpatialReference, but does not copy it. 
     236                 :  *
     237                 :  * This is similar to the SFCOM IGeometry::put_SpatialReference() method.
     238                 :  *
     239                 :  * This method is the same as the C function OGR_G_AssignSpatialReference().
     240                 :  *
     241                 :  * @param poSR new spatial reference system to apply.
     242                 :  */
     243                 : 
     244          924650 : void OGRGeometry::assignSpatialReference( OGRSpatialReference * poSR )
     245                 : 
     246                 : {
     247          924650 :     if( poSRS != NULL )
     248           28831 :         poSRS->Release();
     249                 : 
     250          924650 :     poSRS = poSR;
     251          924650 :     if( poSRS != NULL )
     252          767988 :         poSRS->Reference();
     253          924650 : }
     254                 : 
     255                 : /************************************************************************/
     256                 : /*                    OGR_G_AssignSpatialReference()                    */
     257                 : /************************************************************************/
     258                 : /**
     259                 :  * \brief Assign spatial reference to this object.
     260                 :  *
     261                 :  * Any existing spatial reference
     262                 :  * is replaced, but under no circumstances does this result in the object
     263                 :  * being reprojected.  It is just changing the interpretation of the existing
     264                 :  * geometry.  Note that assigning a spatial reference increments the
     265                 :  * reference count on the OGRSpatialReference, but does not copy it. 
     266                 :  *
     267                 :  * This is similar to the SFCOM IGeometry::put_SpatialReference() method.
     268                 :  *
     269                 :  * This function is the same as the CPP method 
     270                 :  * OGRGeometry::assignSpatialReference.
     271                 :  *
     272                 :  * @param hGeom handle on the geometry to apply the new spatial reference 
     273                 :  * system.
     274                 :  * @param hSRS handle on the  new spatial reference system to apply.
     275                 :  */
     276                 : 
     277             396 : void OGR_G_AssignSpatialReference( OGRGeometryH hGeom, 
     278                 :                                    OGRSpatialReferenceH hSRS )
     279                 : 
     280                 : {
     281             396 :     VALIDATE_POINTER0( hGeom, "OGR_G_AssignSpatialReference" );
     282                 : 
     283                 :     ((OGRGeometry *) hGeom)->assignSpatialReference( (OGRSpatialReference *)
     284             396 :                                                      hSRS );
     285                 : }
     286                 : 
     287                 : /************************************************************************/
     288                 : /*                             Intersects()                             */
     289                 : /************************************************************************/
     290                 : 
     291                 : /**
     292                 :  * \brief Do these features intersect?
     293                 :  *
     294                 :  * Determines whether two geometries intersect.  If GEOS is enabled, then
     295                 :  * this is done in rigerous fashion otherwise TRUE is returned if the
     296                 :  * envelopes (bounding boxes) of the two features overlap. 
     297                 :  *
     298                 :  * The poOtherGeom argument may be safely NULL, but in this case the method
     299                 :  * will always return TRUE.   That is, a NULL geometry is treated as being
     300                 :  * everywhere. 
     301                 :  *
     302                 :  * This method is the same as the C function OGR_G_Intersects().
     303                 :  *
     304                 :  * @param poOtherGeom the other geometry to test against.  
     305                 :  *
     306                 :  * @return TRUE if the geometries intersect, otherwise FALSE.
     307                 :  */
     308                 : 
     309              25 : OGRBoolean OGRGeometry::Intersects( OGRGeometry *poOtherGeom ) const
     310                 : 
     311                 : {
     312              25 :     OGREnvelope         oEnv1, oEnv2;
     313                 : 
     314              25 :     if( this == NULL || poOtherGeom == NULL )
     315               0 :         return TRUE;
     316                 : 
     317              25 :     this->getEnvelope( &oEnv1 );
     318              25 :     poOtherGeom->getEnvelope( &oEnv2 );
     319                 : 
     320              25 :     if( oEnv1.MaxX < oEnv2.MinX
     321                 :         || oEnv1.MaxY < oEnv2.MinY
     322                 :         || oEnv2.MaxX < oEnv1.MinX
     323                 :         || oEnv2.MaxY < oEnv1.MinY )
     324              15 :         return FALSE;
     325                 : 
     326                 : #ifndef HAVE_GEOS
     327                 : 
     328                 :     // Without GEOS we assume that envelope overlap is equivelent to
     329                 :     // actual intersection.
     330                 :     return TRUE;
     331                 : 
     332                 : #else
     333                 : 
     334              10 :     GEOSGeom hThisGeosGeom = NULL;
     335              10 :     GEOSGeom hOtherGeosGeom = NULL;
     336                 : 
     337              10 :     hThisGeosGeom = exportToGEOS();
     338              10 :     hOtherGeosGeom = poOtherGeom->exportToGEOS();
     339                 :     
     340              10 :     OGRBoolean bResult = FALSE;
     341              10 :     if( hThisGeosGeom != NULL && hOtherGeosGeom != NULL )
     342                 :     {
     343              10 :         if( GEOSIntersects( hThisGeosGeom, hOtherGeosGeom ) != 0 )
     344              10 :             bResult = TRUE;
     345                 :         else
     346               0 :             bResult = FALSE;
     347                 :     }
     348                 : 
     349              10 :     GEOSGeom_destroy( hThisGeosGeom );
     350              10 :     GEOSGeom_destroy( hOtherGeosGeom );
     351                 : 
     352              10 :     return bResult;
     353                 : #endif /* HAVE_GEOS */
     354                 : }
     355                 : 
     356                 : // Old API compatibility function.                                 
     357                 : 
     358               0 : OGRBoolean OGRGeometry::Intersect( OGRGeometry *poOtherGeom ) const
     359                 : 
     360                 : {
     361               0 :     return Intersects( poOtherGeom );
     362                 : }
     363                 : 
     364                 : /************************************************************************/
     365                 : /*                          OGR_G_Intersects()                          */
     366                 : /************************************************************************/
     367                 : /**
     368                 :  * \brief Do these features intersect?
     369                 :  *
     370                 :  * Currently this is not implemented in a rigerous fashion, and generally
     371                 :  * just tests whether the envelopes of the two features intersect.  Eventually
     372                 :  * this will be made rigerous.
     373                 :  *
     374                 :  * This function is the same as the CPP method OGRGeometry::Intersects.
     375                 :  *
     376                 :  * @param hGeom handle on the first geometry.
     377                 :  * @param hOtherGeom handle on the other geometry to test against.
     378                 :  *
     379                 :  * @return TRUE if the geometries intersect, otherwise FALSE.
     380                 :  */
     381                 : 
     382               2 : int OGR_G_Intersects( OGRGeometryH hGeom, OGRGeometryH hOtherGeom )
     383                 : 
     384                 : {
     385               2 :     VALIDATE_POINTER1( hGeom, "OGR_G_Intersects", FALSE );
     386               2 :     VALIDATE_POINTER1( hOtherGeom, "OGR_G_Intersects", FALSE );
     387                 : 
     388               2 :     return ((OGRGeometry *) hGeom)->Intersects( (OGRGeometry *) hOtherGeom );
     389                 : }
     390                 : 
     391               0 : int OGR_G_Intersect( OGRGeometryH hGeom, OGRGeometryH hOtherGeom )
     392                 : 
     393                 : {
     394               0 :     VALIDATE_POINTER1( hGeom, "OGR_G_Intersect", FALSE );
     395               0 :     VALIDATE_POINTER1( hOtherGeom, "OGR_G_Intersect", FALSE );
     396                 : 
     397               0 :     return ((OGRGeometry *) hGeom)->Intersects( (OGRGeometry *) hOtherGeom );
     398                 : }
     399                 : 
     400                 : /************************************************************************/
     401                 : /*                            transformTo()                             */
     402                 : /************************************************************************/
     403                 : 
     404                 : /**
     405                 :  * \brief Transform geometry to new spatial reference system.
     406                 :  *
     407                 :  * This method will transform the coordinates of a geometry from
     408                 :  * their current spatial reference system to a new target spatial
     409                 :  * reference system.  Normally this means reprojecting the vectors,
     410                 :  * but it could include datum shifts, and changes of units. 
     411                 :  *
     412                 :  * This method will only work if the geometry already has an assigned
     413                 :  * spatial reference system, and if it is transformable to the target
     414                 :  * coordinate system.
     415                 :  *
     416                 :  * Because this method requires internal creation and initialization of an
     417                 :  * OGRCoordinateTransformation object it is significantly more expensive to
     418                 :  * use this method to transform many geometries than it is to create the
     419                 :  * OGRCoordinateTransformation in advance, and call transform() with that
     420                 :  * transformation.  This method exists primarily for convenience when only
     421                 :  * transforming a single geometry.
     422                 :  *
     423                 :  * This method is the same as the C function OGR_G_TransformTo().
     424                 :  * 
     425                 :  * @param poSR spatial reference system to transform to.
     426                 :  *
     427                 :  * @return OGRERR_NONE on success, or an error code.
     428                 :  */
     429                 : 
     430              27 : OGRErr OGRGeometry::transformTo( OGRSpatialReference *poSR )
     431                 : 
     432                 : {
     433                 : #ifdef DISABLE_OGRGEOM_TRANSFORM
     434                 :     return OGRERR_FAILURE;
     435                 : #else
     436                 :     OGRCoordinateTransformation *poCT;
     437                 :     OGRErr eErr;
     438                 : 
     439              27 :     if( getSpatialReference() == NULL || poSR == NULL )
     440              26 :         return OGRERR_FAILURE;
     441                 : 
     442               1 :     poCT = OGRCreateCoordinateTransformation( getSpatialReference(), poSR );
     443               1 :     if( poCT == NULL )
     444               0 :         return OGRERR_FAILURE;
     445                 : 
     446               1 :     eErr = transform( poCT );
     447                 : 
     448               1 :     delete poCT;
     449                 : 
     450               1 :     return eErr;
     451                 : #endif
     452                 : }
     453                 : 
     454                 : /************************************************************************/
     455                 : /*                         OGR_G_TransformTo()                          */
     456                 : /************************************************************************/
     457                 : /**
     458                 :  * \brief Transform geometry to new spatial reference system.
     459                 :  *
     460                 :  * This function will transform the coordinates of a geometry from
     461                 :  * their current spatial reference system to a new target spatial
     462                 :  * reference system.  Normally this means reprojecting the vectors,
     463                 :  * but it could include datum shifts, and changes of units. 
     464                 :  *
     465                 :  * This function will only work if the geometry already has an assigned
     466                 :  * spatial reference system, and if it is transformable to the target
     467                 :  * coordinate system.
     468                 :  *
     469                 :  * Because this function requires internal creation and initialization of an
     470                 :  * OGRCoordinateTransformation object it is significantly more expensive to
     471                 :  * use this function to transform many geometries than it is to create the
     472                 :  * OGRCoordinateTransformation in advance, and call transform() with that
     473                 :  * transformation.  This function exists primarily for convenience when only
     474                 :  * transforming a single geometry.
     475                 :  *
     476                 :  * This function is the same as the CPP method OGRGeometry::transformTo.
     477                 :  * 
     478                 :  * @param hGeom handle on the geometry to apply the transform to.
     479                 :  * @param hSRS handle on the spatial reference system to apply.
     480                 :  *
     481                 :  * @return OGRERR_NONE on success, or an error code.
     482                 :  */
     483                 : 
     484               1 : OGRErr OGR_G_TransformTo( OGRGeometryH hGeom, OGRSpatialReferenceH hSRS )
     485                 : 
     486                 : {
     487               1 :     VALIDATE_POINTER1( hGeom, "OGR_G_TransformTo", OGRERR_FAILURE );
     488                 : 
     489               1 :     return ((OGRGeometry *) hGeom)->transformTo((OGRSpatialReference *) hSRS);
     490                 : }
     491                 : 
     492                 : /**
     493                 :  * \fn OGRErr OGRGeometry::transform( OGRCoordinateTransformation *poCT );
     494                 :  *
     495                 :  * \brief Apply arbitrary coordinate transformation to geometry.
     496                 :  *
     497                 :  * This method will transform the coordinates of a geometry from
     498                 :  * their current spatial reference system to a new target spatial
     499                 :  * reference system.  Normally this means reprojecting the vectors,
     500                 :  * but it could include datum shifts, and changes of units. 
     501                 :  * 
     502                 :  * Note that this method does not require that the geometry already
     503                 :  * have a spatial reference system.  It will be assumed that they can
     504                 :  * be treated as having the source spatial reference system of the
     505                 :  * OGRCoordinateTransformation object, and the actual SRS of the geometry
     506                 :  * will be ignored.  On successful completion the output OGRSpatialReference
     507                 :  * of the OGRCoordinateTransformation will be assigned to the geometry.
     508                 :  *
     509                 :  * This method is the same as the C function OGR_G_Transform().
     510                 :  *
     511                 :  * @param poCT the transformation to apply.
     512                 :  *
     513                 :  * @return OGRERR_NONE on success or an error code.
     514                 :  */
     515                 : 
     516                 : /************************************************************************/
     517                 : /*                          OGR_G_Transform()                           */
     518                 : /************************************************************************/
     519                 : /**
     520                 :  * \brief Apply arbitrary coordinate transformation to geometry.
     521                 :  *
     522                 :  * This function will transform the coordinates of a geometry from
     523                 :  * their current spatial reference system to a new target spatial
     524                 :  * reference system.  Normally this means reprojecting the vectors,
     525                 :  * but it could include datum shifts, and changes of units. 
     526                 :  * 
     527                 :  * Note that this function does not require that the geometry already
     528                 :  * have a spatial reference system.  It will be assumed that they can
     529                 :  * be treated as having the source spatial reference system of the
     530                 :  * OGRCoordinateTransformation object, and the actual SRS of the geometry
     531                 :  * will be ignored.  On successful completion the output OGRSpatialReference
     532                 :  * of the OGRCoordinateTransformation will be assigned to the geometry.
     533                 :  *
     534                 :  * This function is the same as the CPP method OGRGeometry::transform.
     535                 :  *
     536                 :  * @param hGeom handle on the geometry to apply the transform to.
     537                 :  * @param hTransform handle on the transformation to apply.
     538                 :  *
     539                 :  * @return OGRERR_NONE on success or an error code.
     540                 :  */
     541                 : 
     542              21 : OGRErr OGR_G_Transform( OGRGeometryH hGeom, 
     543                 :                         OGRCoordinateTransformationH hTransform )
     544                 : 
     545                 : {
     546              21 :     VALIDATE_POINTER1( hGeom, "OGR_G_Transform", OGRERR_FAILURE );
     547                 : 
     548                 :     return ((OGRGeometry *) hGeom)->transform(
     549              21 :         (OGRCoordinateTransformation *) hTransform );
     550                 : }
     551                 : 
     552                 : /**
     553                 :  * \fn int OGRGeometry::getDimension() const;
     554                 :  *
     555                 :  * \brief Get the dimension of this object.
     556                 :  *
     557                 :  * This method corresponds to the SFCOM IGeometry::GetDimension() method.
     558                 :  * It indicates the dimension of the object, but does not indicate the
     559                 :  * dimension of the underlying space (as indicated by
     560                 :  * OGRGeometry::getCoordinateDimension()).
     561                 :  *
     562                 :  * This method is the same as the C function OGR_G_GetDimension().
     563                 :  *
     564                 :  * @return 0 for points, 1 for lines and 2 for surfaces.
     565                 :  */
     566                 : 
     567                 : 
     568                 : /************************************************************************/
     569                 : /*                  OGRGeometry::segmentize()                           */
     570                 : /************************************************************************/
     571                 : /**
     572                 :  *
     573                 :  * \brief Modify the geometry such it has no segment longer then the given distance.
     574                 :  *
     575                 :  * Interpolated points will have Z and M values (if needed) set to 0.
     576                 :  * Distance computation is performed in 2d only
     577                 :  *
     578                 :  * This function is the same as the C function OGR_G_Segmentize()
     579                 :  *
     580                 :  * @param dfMaxLength the maximum distance between 2 points after segmentization
     581                 :  */
     582                 : 
     583               0 : void OGRGeometry::segmentize( double dfMaxLength )
     584                 : {
     585                 :     /* Do nothing */
     586               0 : }
     587                 : 
     588                 : /************************************************************************/
     589                 : /*                         OGR_G_Segmentize()                           */
     590                 : /************************************************************************/
     591                 : 
     592                 : /**
     593                 :  *
     594                 :  * \brief Modify the geometry such it has no segment longer then the given distance.
     595                 :  *
     596                 :  * Interpolated points will have Z and M values (if needed) set to 0.
     597                 :  * Distance computation is performed in 2d only
     598                 :  *
     599                 :  * This function is the same as the CPP method OGRGeometry::segmentize().
     600                 :  *
     601                 :  * @param hGeom handle on the geometry to segmentize
     602                 :  * @param dfMaxLength the maximum distance between 2 points after segmentization
     603                 :  */
     604                 : 
     605               1 : void   CPL_DLL OGR_G_Segmentize(OGRGeometryH hGeom, double dfMaxLength )
     606                 : {
     607               1 :     VALIDATE_POINTER0( hGeom, "OGR_G_Segmentize" );
     608                 : 
     609               1 :     if (dfMaxLength <= 0)
     610                 :     {
     611                 :         CPLError(CE_Failure, CPLE_AppDefined,
     612               0 :                  "dfMaxLength must be strictly positive");
     613               0 :         return;
     614                 :     }
     615               1 :     ((OGRGeometry *) hGeom)->segmentize( dfMaxLength );
     616                 : }
     617                 : 
     618                 : /************************************************************************/
     619                 : /*                         OGR_G_GetDimension()                         */
     620                 : /************************************************************************/
     621                 : /**
     622                 :  *
     623                 :  * \brief Get the dimension of this geometry.
     624                 :  *
     625                 :  * This function corresponds to the SFCOM IGeometry::GetDimension() method.
     626                 :  * It indicates the dimension of the geometry, but does not indicate the
     627                 :  * dimension of the underlying space (as indicated by
     628                 :  * OGR_G_GetCoordinateDimension() function).
     629                 :  *
     630                 :  * This function is the same as the CPP method OGRGeometry::getDimension().
     631                 :  *
     632                 :  * @param hGeom handle on the geometry to get the dimension from.
     633                 :  * @return 0 for points, 1 for lines and 2 for surfaces.
     634                 :  */
     635                 : 
     636               1 : int OGR_G_GetDimension( OGRGeometryH hGeom )
     637                 : 
     638                 : {
     639               1 :     VALIDATE_POINTER1( hGeom, "OGR_G_GetDimension", 0 );
     640                 : 
     641               1 :     return ((OGRGeometry *) hGeom)->getDimension();
     642                 : }
     643                 : 
     644                 : /************************************************************************/
     645                 : /*                       getCoordinateDimension()                       */
     646                 : /************************************************************************/
     647                 : /**
     648                 :  * \brief Get the dimension of the coordinates in this object.
     649                 :  *
     650                 :  * This method corresponds to the SFCOM IGeometry::GetDimension() method.
     651                 :  *
     652                 :  * This method is the same as the C function OGR_G_GetCoordinateDimension().
     653                 :  *
     654                 :  * @return in practice this will return 2 or 3. It can also return 0 in the
     655                 :  * case of an empty point.
     656                 :  */
     657                 : 
     658         5211496 : int OGRGeometry::getCoordinateDimension() const
     659                 : 
     660                 : {
     661         5211496 :     return nCoordDimension;
     662                 : }
     663                 : 
     664                 : /************************************************************************/
     665                 : /*                    OGR_G_GetCoordinateDimension()                    */
     666                 : /************************************************************************/
     667                 : /**
     668                 :  *
     669                 :  * \brief Get the dimension of the coordinates in this geometry.
     670                 :  *
     671                 :  * This function corresponds to the SFCOM IGeometry::GetDimension() method.
     672                 :  *
     673                 :  * This function is the same as the CPP method 
     674                 :  * OGRGeometry::getCoordinateDimension().
     675                 :  *
     676                 :  * @param hGeom handle on the geometry to get the dimension of the 
     677                 :  * coordinates from.
     678                 :  *
     679                 :  * @return in practice this will return 2 or 3. It can also return 0 in the
     680                 :  * case of an empty point.
     681                 :  */
     682                 : 
     683             193 : int OGR_G_GetCoordinateDimension( OGRGeometryH hGeom )
     684                 : 
     685                 : {
     686             193 :     VALIDATE_POINTER1( hGeom, "OGR_G_GetCoordinateDimension", 0 );
     687                 : 
     688             193 :     return ((OGRGeometry *) hGeom)->getCoordinateDimension();
     689                 : }
     690                 : 
     691                 : /************************************************************************/
     692                 : /*                       setCoordinateDimension()                       */
     693                 : /************************************************************************/
     694                 : 
     695                 : /**
     696                 :  * \brief Set the coordinate dimension. 
     697                 :  *
     698                 :  * This method sets the explicit coordinate dimension.  Setting the coordinate
     699                 :  * dimension of a geometry to 2 should zero out any existing Z values.  Setting
     700                 :  * the dimension of a geometry collection will not necessarily affect the
     701                 :  * children geometries. 
     702                 :  *
     703                 :  * @param nNewDimension New coordinate dimension value, either 2 or 3.
     704                 :  */
     705                 : 
     706             751 : void OGRGeometry::setCoordinateDimension( int nNewDimension )
     707                 : 
     708                 : {
     709             751 :     nCoordDimension = nNewDimension;
     710             751 : }
     711                 : 
     712                 : /************************************************************************/
     713                 : /*                    OGR_G_SetCoordinateDimension()                    */
     714                 : /************************************************************************/
     715                 : 
     716                 : /**
     717                 :  * \brief Set the coordinate dimension.
     718                 :  *
     719                 :  * This method sets the explicit coordinate dimension.  Setting the coordinate
     720                 :  * dimension of a geometry to 2 should zero out any existing Z values.  Setting
     721                 :  * the dimension of a geometry collection will not necessarily affect the
     722                 :  * children geometries.
     723                 :  *
     724                 :  * @param hGeom handle on the geometry to set the dimension of the
     725                 :  * coordinates.
     726                 :  * @param nNewDimension New coordinate dimension value, either 2 or 3.
     727                 :  */
     728                 : 
     729              81 : void OGR_G_SetCoordinateDimension( OGRGeometryH hGeom, int nNewDimension)
     730                 : 
     731                 : {
     732              81 :     VALIDATE_POINTER0( hGeom, "OGR_G_SetCoordinateDimension" );
     733                 : 
     734              81 :     ((OGRGeometry *) hGeom)->setCoordinateDimension( nNewDimension );
     735                 : }
     736                 : 
     737                 : /**
     738                 :  * \fn int OGRGeometry::Equals( OGRGeometry *poOtherGeom ) const;
     739                 :  *
     740                 :  * \brief Returns TRUE if two geometries are equivalent.
     741                 :  *
     742                 :  * This method is the same as the C function OGR_G_Equals().
     743                 :  *
     744                 :  * @return TRUE if equivalent or FALSE otherwise.
     745                 :  */
     746                 : 
     747                 : 
     748                 : // Backward compatibility method.
     749                 : 
     750               0 : int OGRGeometry::Equal( OGRGeometry *poOtherGeom ) const
     751                 : {
     752               0 :     return Equals( poOtherGeom );
     753                 : }
     754                 : 
     755                 : /************************************************************************/
     756                 : /*                            OGR_G_Equals()                            */
     757                 : /************************************************************************/
     758                 : 
     759                 : /**
     760                 :  * \brief Returns TRUE if two geometries are equivalent.
     761                 :  *
     762                 :  * This function is the same as the CPP method OGRGeometry::Equals() method.
     763                 :  *
     764                 :  * @param hGeom handle on the first geometry.
     765                 :  * @param hOther handle on the other geometry to test against.
     766                 :  * @return TRUE if equivalent or FALSE otherwise.
     767                 :  */
     768                 : 
     769           35547 : int OGR_G_Equals( OGRGeometryH hGeom, OGRGeometryH hOther )
     770                 : 
     771                 : {
     772           35547 :     VALIDATE_POINTER1( hGeom, "OGR_G_Equals", FALSE );
     773                 : 
     774           35547 :     if (hGeom == NULL) {
     775               0 :         CPLError ( CE_Failure, CPLE_ObjectNull, "hGeom was NULL in OGR_G_Equals");
     776               0 :         return 0;
     777                 :     }
     778                 : 
     779           35547 :     if (hOther == NULL) {
     780               0 :         CPLError ( CE_Failure, CPLE_ObjectNull, "hOther was NULL in OGR_G_Equals");
     781               0 :         return 0;
     782                 :     }
     783                 :     
     784           35547 :     return ((OGRGeometry *) hGeom)->Equals( (OGRGeometry *) hOther );
     785                 : }
     786                 : 
     787               0 : int OGR_G_Equal( OGRGeometryH hGeom, OGRGeometryH hOther )
     788                 : 
     789                 : {
     790               0 :     if (hGeom == NULL) {
     791               0 :         CPLError ( CE_Failure, CPLE_ObjectNull, "hGeom was NULL in OGR_G_Equal");
     792               0 :         return 0;
     793                 :     }
     794                 : 
     795               0 :     if (hOther == NULL) {
     796               0 :         CPLError ( CE_Failure, CPLE_ObjectNull, "hOther was NULL in OGR_G_Equal");
     797               0 :         return 0;
     798                 :     }
     799                 : 
     800               0 :     return ((OGRGeometry *) hGeom)->Equals( (OGRGeometry *) hOther );
     801                 : }
     802                 : 
     803                 : 
     804                 : /**
     805                 :  * \fn int OGRGeometry::WkbSize() const;
     806                 :  *
     807                 :  * \brief Returns size of related binary representation.
     808                 :  *
     809                 :  * This method returns the exact number of bytes required to hold the
     810                 :  * well known binary representation of this geometry object.  Its computation
     811                 :  * may be slightly expensive for complex geometries.
     812                 :  *
     813                 :  * This method relates to the SFCOM IWks::WkbSize() method.
     814                 :  *
     815                 :  * This method is the same as the C function OGR_G_WkbSize().
     816                 :  *
     817                 :  * @return size of binary representation in bytes.
     818                 :  */
     819                 : 
     820                 : /************************************************************************/
     821                 : /*                           OGR_G_WkbSize()                            */
     822                 : /************************************************************************/
     823                 : /**
     824                 :  * \brief Returns size of related binary representation.
     825                 :  *
     826                 :  * This function returns the exact number of bytes required to hold the
     827                 :  * well known binary representation of this geometry object.  Its computation
     828                 :  * may be slightly expensive for complex geometries.
     829                 :  *
     830                 :  * This function relates to the SFCOM IWks::WkbSize() method.
     831                 :  *
     832                 :  * This function is the same as the CPP method OGRGeometry::WkbSize().
     833                 :  *
     834                 :  * @param hGeom handle on the geometry to get the binary size from.
     835                 :  * @return size of binary representation in bytes.
     836                 :  */
     837                 : 
     838              57 : int OGR_G_WkbSize( OGRGeometryH hGeom )
     839                 : 
     840                 : {
     841              57 :     VALIDATE_POINTER1( hGeom, "OGR_G_WkbSize", 0 );
     842                 : 
     843              57 :     return ((OGRGeometry *) hGeom)->WkbSize();
     844                 : }
     845                 : 
     846                 : /**
     847                 :  * \fn void OGRGeometry::getEnvelope(OGREnvelope *psEnvelope) const;
     848                 :  *
     849                 :  * \brief Computes and returns the bounding envelope for this geometry in the passed psEnvelope structure.
     850                 :  *
     851                 :  * This method is the same as the C function OGR_G_GetEnvelope().
     852                 :  *
     853                 :  * @param psEnvelope the structure in which to place the results.
     854                 :  */
     855                 : 
     856                 : /************************************************************************/
     857                 : /*                         OGR_G_GetEnvelope()                          */
     858                 : /************************************************************************/
     859                 : /**
     860                 :  * \brief Computes and returns the bounding envelope for this geometry in the passed psEnvelope structure.
     861                 :  *
     862                 :  * This function is the same as the CPP method OGRGeometry::getEnvelope().
     863                 :  *
     864                 :  * @param hGeom handle of the geometry to get envelope from.
     865                 :  * @param psEnvelope the structure in which to place the results.
     866                 :  */
     867                 : 
     868           17537 : void OGR_G_GetEnvelope( OGRGeometryH hGeom, OGREnvelope *psEnvelope )
     869                 : 
     870                 : {
     871           17537 :     VALIDATE_POINTER0( hGeom, "OGR_G_GetEnvelope" );
     872                 : 
     873           17537 :     ((OGRGeometry *) hGeom)->getEnvelope( psEnvelope );
     874                 : }
     875                 : 
     876                 : /**
     877                 :  * \fn void OGRGeometry::getEnvelope(OGREnvelope3D *psEnvelope) const;
     878                 :  *
     879                 :  * \brief Computes and returns the bounding envelope (3D) for this geometry in the passed psEnvelope structure.
     880                 :  *
     881                 :  * This method is the same as the C function OGR_G_GetEnvelope3D().
     882                 :  *
     883                 :  * @param psEnvelope the structure in which to place the results.
     884                 :  *
     885                 :  * @since OGR 1.9.0
     886                 :  */
     887                 : 
     888                 : /************************************************************************/
     889                 : /*                        OGR_G_GetEnvelope3D()                         */
     890                 : /************************************************************************/
     891                 : /**
     892                 :  * \brief Computes and returns the bounding envelope (3D) for this geometry in the passed psEnvelope structure.
     893                 :  *
     894                 :  * This function is the same as the CPP method OGRGeometry::getEnvelope().
     895                 :  *
     896                 :  * @param hGeom handle of the geometry to get envelope from.
     897                 :  * @param psEnvelope the structure in which to place the results.
     898                 :  *
     899                 :  * @since OGR 1.9.0
     900                 :  */
     901                 : 
     902               7 : void OGR_G_GetEnvelope3D( OGRGeometryH hGeom, OGREnvelope3D *psEnvelope )
     903                 : 
     904                 : {
     905               7 :     VALIDATE_POINTER0( hGeom, "OGR_G_GetEnvelope3D" );
     906                 : 
     907               7 :     ((OGRGeometry *) hGeom)->getEnvelope( psEnvelope );
     908                 : }
     909                 : 
     910                 : /**
     911                 :  * \fn OGRErr OGRGeometry::importFromWkb( unsigned char * pabyData, int nSize);
     912                 :  *
     913                 :  * \brief Assign geometry from well known binary data.
     914                 :  *
     915                 :  * The object must have already been instantiated as the correct derived
     916                 :  * type of geometry object to match the binaries type.  This method is used
     917                 :  * by the OGRGeometryFactory class, but not normally called by application
     918                 :  * code.  
     919                 :  * 
     920                 :  * This method relates to the SFCOM IWks::ImportFromWKB() method.
     921                 :  *
     922                 :  * This method is the same as the C function OGR_G_ImportFromWkb().
     923                 :  *
     924                 :  * @param pabyData the binary input data.
     925                 :  * @param nSize the size of pabyData in bytes, or zero if not known.
     926                 :  *
     927                 :  * @return OGRERR_NONE if all goes well, otherwise any of
     928                 :  * OGRERR_NOT_ENOUGH_DATA, OGRERR_UNSUPPORTED_GEOMETRY_TYPE, or
     929                 :  * OGRERR_CORRUPT_DATA may be returned.
     930                 :  */
     931                 : 
     932                 : /************************************************************************/
     933                 : /*                        OGR_G_ImportFromWkb()                         */
     934                 : /************************************************************************/
     935                 : /**
     936                 :  * \brief Assign geometry from well known binary data.
     937                 :  *
     938                 :  * The object must have already been instantiated as the correct derived
     939                 :  * type of geometry object to match the binaries type.
     940                 :  *
     941                 :  * This function relates to the SFCOM IWks::ImportFromWKB() method.
     942                 :  *
     943                 :  * This function is the same as the CPP method OGRGeometry::importFromWkb().
     944                 :  *
     945                 :  * @param hGeom handle on the geometry to assign the well know binary data to.
     946                 :  * @param pabyData the binary input data.
     947                 :  * @param nSize the size of pabyData in bytes, or zero if not known.
     948                 :  *
     949                 :  * @return OGRERR_NONE if all goes well, otherwise any of
     950                 :  * OGRERR_NOT_ENOUGH_DATA, OGRERR_UNSUPPORTED_GEOMETRY_TYPE, or
     951                 :  * OGRERR_CORRUPT_DATA may be returned.
     952                 :  */
     953                 : 
     954               0 : OGRErr OGR_G_ImportFromWkb( OGRGeometryH hGeom, 
     955                 :                             unsigned char *pabyData, int nSize )
     956                 : 
     957                 : {
     958               0 :     VALIDATE_POINTER1( hGeom, "OGR_G_ImportFromWkb", OGRERR_FAILURE );
     959                 : 
     960               0 :     return ((OGRGeometry *) hGeom)->importFromWkb( pabyData, nSize );
     961                 : }
     962                 : 
     963                 : /**
     964                 :  * \fn OGRErr OGRGeometry::exportToWkb( OGRwkbByteOrder eByteOrder,
     965                 :                                         unsigned char * pabyData ) const;
     966                 :  *
     967                 :  * \brief Convert a geometry into well known binary format.
     968                 :  *
     969                 :  * This method relates to the SFCOM IWks::ExportToWKB() method.
     970                 :  *
     971                 :  * This method is the same as the C function OGR_G_ExportToWkb().
     972                 :  *
     973                 :  * @param eByteOrder One of wkbXDR or wkbNDR indicating MSB or LSB byte order
     974                 :  *               respectively.
     975                 :  * @param pabyData a buffer into which the binary representation is
     976                 :  *                      written.  This buffer must be at least
     977                 :  *                      OGRGeometry::WkbSize() byte in size.
     978                 :  *
     979                 :  * @return Currently OGRERR_NONE is always returned.
     980                 :  */
     981                 : 
     982                 : /************************************************************************/
     983                 : /*                         OGR_G_ExportToWkb()                          */
     984                 : /************************************************************************/
     985                 : /**
     986                 :  * \brief Convert a geometry into well known binary format.
     987                 :  *
     988                 :  * This function relates to the SFCOM IWks::ExportToWKB() method.
     989                 :  *
     990                 :  * This function is the same as the CPP method OGRGeometry::exportToWkb().
     991                 :  *
     992                 :  * @param hGeom handle on the geometry to convert to a well know binary 
     993                 :  * data from.
     994                 :  * @param eOrder One of wkbXDR or wkbNDR indicating MSB or LSB byte order
     995                 :  *               respectively.
     996                 :  * @param pabyDstBuffer a buffer into which the binary representation is
     997                 :  *                      written.  This buffer must be at least
     998                 :  *                      OGR_G_WkbSize() byte in size.
     999                 :  *
    1000                 :  * @return Currently OGRERR_NONE is always returned.
    1001                 :  */
    1002                 : 
    1003              57 : OGRErr OGR_G_ExportToWkb( OGRGeometryH hGeom, OGRwkbByteOrder eOrder,
    1004                 :                           unsigned char *pabyDstBuffer )
    1005                 : 
    1006                 : {
    1007              57 :     VALIDATE_POINTER1( hGeom, "OGR_G_ExportToWkb", OGRERR_FAILURE );
    1008                 : 
    1009              57 :     return ((OGRGeometry *) hGeom)->exportToWkb( eOrder, pabyDstBuffer );
    1010                 : }
    1011                 : 
    1012                 : /**
    1013                 :  * \fn OGRErr OGRGeometry::importFromWkt( char ** ppszInput );
    1014                 :  *
    1015                 :  * \brief Assign geometry from well known text data.
    1016                 :  *
    1017                 :  * The object must have already been instantiated as the correct derived
    1018                 :  * type of geometry object to match the text type.  This method is used
    1019                 :  * by the OGRGeometryFactory class, but not normally called by application
    1020                 :  * code.  
    1021                 :  * 
    1022                 :  * This method relates to the SFCOM IWks::ImportFromWKT() method.
    1023                 :  *
    1024                 :  * This method is the same as the C function OGR_G_ImportFromWkt().
    1025                 :  *
    1026                 :  * @param ppszInput pointer to a pointer to the source text.  The pointer is
    1027                 :  *                    updated to pointer after the consumed text.
    1028                 :  *
    1029                 :  * @return OGRERR_NONE if all goes well, otherwise any of
    1030                 :  * OGRERR_NOT_ENOUGH_DATA, OGRERR_UNSUPPORTED_GEOMETRY_TYPE, or
    1031                 :  * OGRERR_CORRUPT_DATA may be returned.
    1032                 :  */
    1033                 : 
    1034                 : /************************************************************************/
    1035                 : /*                        OGR_G_ImportFromWkt()                         */
    1036                 : /************************************************************************/
    1037                 : /**
    1038                 :  * \brief Assign geometry from well known text data.
    1039                 :  *
    1040                 :  * The object must have already been instantiated as the correct derived
    1041                 :  * type of geometry object to match the text type.
    1042                 :  * 
    1043                 :  * This function relates to the SFCOM IWks::ImportFromWKT() method.
    1044                 :  *
    1045                 :  * This function is the same as the CPP method OGRGeometry::importFromWkt().
    1046                 :  *
    1047                 :  * @param hGeom handle on the  geometry to assign well know text data to.
    1048                 :  * @param ppszSrcText pointer to a pointer to the source text.  The pointer is
    1049                 :  *                    updated to pointer after the consumed text.
    1050                 :  *
    1051                 :  * @return OGRERR_NONE if all goes well, otherwise any of
    1052                 :  * OGRERR_NOT_ENOUGH_DATA, OGRERR_UNSUPPORTED_GEOMETRY_TYPE, or
    1053                 :  * OGRERR_CORRUPT_DATA may be returned.
    1054                 :  */
    1055                 : 
    1056               0 : OGRErr OGR_G_ImportFromWkt( OGRGeometryH hGeom, char ** ppszSrcText )
    1057                 : 
    1058                 : {
    1059               0 :     VALIDATE_POINTER1( hGeom, "OGR_G_ImportFromWkt", OGRERR_FAILURE );
    1060                 : 
    1061               0 :     return ((OGRGeometry *) hGeom)->importFromWkt( ppszSrcText );
    1062                 : }
    1063                 : 
    1064                 : /**
    1065                 :  * \fn OGRErr OGRGeometry::exportToWkt( char ** ppszDstText ) const;
    1066                 :  *
    1067                 :  * \brief Convert a geometry into well known text format.
    1068                 :  *
    1069                 :  * This method relates to the SFCOM IWks::ExportToWKT() method.
    1070                 :  *
    1071                 :  * This method is the same as the C function OGR_G_ExportToWkt().
    1072                 :  *
    1073                 :  * @param ppszDstText a text buffer is allocated by the program, and assigned
    1074                 :  *                    to the passed pointer. After use, *ppszDstText should be
    1075                 :  *                    freed with OGRFree().
    1076                 :  *
    1077                 :  * @return Currently OGRERR_NONE is always returned.
    1078                 :  */
    1079                 : 
    1080                 : /************************************************************************/
    1081                 : /*                         OGR_G_ExportToWkt()                          */
    1082                 : /************************************************************************/
    1083                 : /**
    1084                 :  * \brief Convert a geometry into well known text format.
    1085                 :  *
    1086                 :  * This function relates to the SFCOM IWks::ExportToWKT() method.
    1087                 :  *
    1088                 :  * This function is the same as the CPP method OGRGeometry::exportToWkt().
    1089                 :  *
    1090                 :  * @param hGeom handle on the geometry to convert to a text format from.
    1091                 :  * @param ppszSrcText a text buffer is allocated by the program, and assigned
    1092                 :  *                    to the passed pointer. After use, *ppszDstText should be
    1093                 :  *                    freed with OGRFree().
    1094                 :  *
    1095                 :  * @return Currently OGRERR_NONE is always returned.
    1096                 :  */
    1097                 : 
    1098            1194 : OGRErr OGR_G_ExportToWkt( OGRGeometryH hGeom, char **ppszSrcText )
    1099                 : 
    1100                 : {
    1101            1194 :     VALIDATE_POINTER1( hGeom, "OGR_G_ExportToWkt", OGRERR_FAILURE );
    1102                 : 
    1103            1194 :     return ((OGRGeometry *) hGeom)->exportToWkt( ppszSrcText );
    1104                 : }
    1105                 : 
    1106                 : /**
    1107                 :  * \fn OGRwkbGeometryType OGRGeometry::getGeometryType() const;
    1108                 :  *
    1109                 :  * \brief Fetch geometry type.
    1110                 :  *
    1111                 :  * Note that the geometry type may include the 2.5D flag.  To get a 2D
    1112                 :  * flattened version of the geometry type apply the wkbFlatten() macro
    1113                 :  * to the return result.
    1114                 :  *
    1115                 :  * This method is the same as the C function OGR_G_GetGeometryType().
    1116                 :  *
    1117                 :  * @return the geometry type code.
    1118                 :  */
    1119                 : 
    1120                 : /************************************************************************/
    1121                 : /*                       OGR_G_GetGeometryType()                        */
    1122                 : /************************************************************************/
    1123                 : /**
    1124                 :  * \brief Fetch geometry type.
    1125                 :  *
    1126                 :  * Note that the geometry type may include the 2.5D flag.  To get a 2D
    1127                 :  * flattened version of the geometry type apply the wkbFlatten() macro
    1128                 :  * to the return result.
    1129                 :  *
    1130                 :  * This function is the same as the CPP method OGRGeometry::getGeometryType().
    1131                 :  *
    1132                 :  * @param hGeom handle on the geometry to get type from.
    1133                 :  * @return the geometry type code.
    1134                 :  */
    1135                 : 
    1136             433 : OGRwkbGeometryType OGR_G_GetGeometryType( OGRGeometryH hGeom )
    1137                 : 
    1138                 : {
    1139             433 :     VALIDATE_POINTER1( hGeom, "OGR_G_GetGeometryType", wkbUnknown );
    1140                 : 
    1141             433 :     return ((OGRGeometry *) hGeom)->getGeometryType();
    1142                 : }
    1143                 : 
    1144                 : /**
    1145                 :  * \fn const char * OGRGeometry::getGeometryName() const;
    1146                 :  *
    1147                 :  * \brief Fetch WKT name for geometry type.
    1148                 :  *
    1149                 :  * There is no SFCOM analog to this method.  
    1150                 :  *
    1151                 :  * This method is the same as the C function OGR_G_GetGeometryName().
    1152                 :  *
    1153                 :  * @return name used for this geometry type in well known text format.  The
    1154                 :  * returned pointer is to a static internal string and should not be modified
    1155                 :  * or freed.
    1156                 :  */
    1157                 : 
    1158                 : /************************************************************************/
    1159                 : /*                       OGR_G_GetGeometryName()                        */
    1160                 : /************************************************************************/
    1161                 : /**
    1162                 :  * \brief Fetch WKT name for geometry type.
    1163                 :  *
    1164                 :  * There is no SFCOM analog to this function.  
    1165                 :  *
    1166                 :  * This function is the same as the CPP method OGRGeometry::getGeometryName().
    1167                 :  *
    1168                 :  * @param hGeom handle on the geometry to get name from.
    1169                 :  * @return name used for this geometry type in well known text format.
    1170                 :  */
    1171                 : 
    1172            2976 : const char *OGR_G_GetGeometryName( OGRGeometryH hGeom )
    1173                 : 
    1174                 : {
    1175            2976 :     VALIDATE_POINTER1( hGeom, "OGR_G_GetGeometryName", "" );
    1176                 : 
    1177            2976 :     return ((OGRGeometry *) hGeom)->getGeometryName();
    1178                 : }
    1179                 : 
    1180                 : /**
    1181                 :  * \fn OGRGeometry *OGRGeometry::clone() const;
    1182                 :  *
    1183                 :  * \brief Make a copy of this object.
    1184                 :  *
    1185                 :  * This method relates to the SFCOM IGeometry::clone() method.
    1186                 :  *
    1187                 :  * This method is the same as the C function OGR_G_Clone().
    1188                 :  * 
    1189                 :  * @return a new object instance with the same geometry, and spatial
    1190                 :  * reference system as the original.
    1191                 :  */
    1192                 : 
    1193                 : /************************************************************************/
    1194                 : /*                            OGR_G_Clone()                             */
    1195                 : /************************************************************************/
    1196                 : /**
    1197                 :  * \brief Make a copy of this object.
    1198                 :  *
    1199                 :  * This function relates to the SFCOM IGeometry::clone() method.
    1200                 :  *
    1201                 :  * This function is the same as the CPP method OGRGeometry::clone().
    1202                 :  * 
    1203                 :  * @param hGeom handle on the geometry to clone from.
    1204                 :  * @return an handle on the  copy of the geometry with the spatial
    1205                 :  * reference system as the original.
    1206                 :  */
    1207                 : 
    1208           20033 : OGRGeometryH OGR_G_Clone( OGRGeometryH hGeom )
    1209                 : 
    1210                 : {
    1211           20033 :     VALIDATE_POINTER1( hGeom, "OGR_G_Clone", NULL );
    1212                 : 
    1213           20033 :     return (OGRGeometryH) ((OGRGeometry *) hGeom)->clone();
    1214                 : }
    1215                 : 
    1216                 : /**
    1217                 :  * \fn OGRSpatialReference *OGRGeometry::getSpatialReference();
    1218                 :  *
    1219                 :  * \brief Returns spatial reference system for object.
    1220                 :  *
    1221                 :  * This method relates to the SFCOM IGeometry::get_SpatialReference() method.
    1222                 :  *
    1223                 :  * This method is the same as the C function OGR_G_GetSpatialReference().
    1224                 :  *
    1225                 :  * @return a reference to the spatial reference object.  The object may be
    1226                 :  * shared with many geometry objects, and should not be modified.
    1227                 :  */
    1228                 : 
    1229                 : /************************************************************************/
    1230                 : /*                     OGR_G_GetSpatialReference()                      */
    1231                 : /************************************************************************/
    1232                 : /**
    1233                 :  * \brief Returns spatial reference system for geometry.
    1234                 :  *
    1235                 :  * This function relates to the SFCOM IGeometry::get_SpatialReference() method.
    1236                 :  *
    1237                 :  * This function is the same as the CPP method 
    1238                 :  * OGRGeometry::getSpatialReference().
    1239                 :  *
    1240                 :  * @param hGeom handle on the geometry to get spatial reference from.
    1241                 :  * @return a reference to the spatial reference geometry.
    1242                 :  */
    1243                 : 
    1244              13 : OGRSpatialReferenceH OGR_G_GetSpatialReference( OGRGeometryH hGeom )
    1245                 : 
    1246                 : {
    1247              13 :     VALIDATE_POINTER1( hGeom, "OGR_G_GetSpatialReference", NULL );
    1248                 : 
    1249                 :     return (OGRSpatialReferenceH) 
    1250              13 :         ((OGRGeometry *) hGeom)->getSpatialReference();
    1251                 : }
    1252                 : 
    1253                 : /**
    1254                 :  * \fn void OGRGeometry::empty();
    1255                 :  *
    1256                 :  * \brief Clear geometry information.
    1257                 :  * This restores the geometry to it's initial
    1258                 :  * state after construction, and before assignment of actual geometry.
    1259                 :  *
    1260                 :  * This method relates to the SFCOM IGeometry::Empty() method.
    1261                 :  *
    1262                 :  * This method is the same as the C function OGR_G_Empty().
    1263                 :  */
    1264                 : 
    1265                 : /************************************************************************/
    1266                 : /*                            OGR_G_Empty()                             */
    1267                 : /************************************************************************/
    1268                 : /**
    1269                 :  * \brief Clear geometry information.
    1270                 :  * This restores the geometry to it's initial
    1271                 :  * state after construction, and before assignment of actual geometry.
    1272                 :  *
    1273                 :  * This function relates to the SFCOM IGeometry::Empty() method.
    1274                 :  *
    1275                 :  * This function is the same as the CPP method OGRGeometry::empty().
    1276                 :  *
    1277                 :  * @param hGeom handle on the geometry to empty.
    1278                 :  */
    1279                 : 
    1280               2 : void OGR_G_Empty( OGRGeometryH hGeom )
    1281                 : 
    1282                 : {
    1283               2 :     VALIDATE_POINTER0( hGeom, "OGR_G_Empty" );
    1284                 : 
    1285               2 :     ((OGRGeometry *) hGeom)->empty();
    1286                 : }
    1287                 : 
    1288                 : /**
    1289                 :  * \fn OGRBoolean OGRGeometry::IsEmpty() const;
    1290                 :  *
    1291                 :  * \brief Returns TRUE (non-zero) if the object has no points.
    1292                 :  *
    1293                 :  * Normally this
    1294                 :  * returns FALSE except between when an object is instantiated and points
    1295                 :  * have been assigned.
    1296                 :  *
    1297                 :  * This method relates to the SFCOM IGeometry::IsEmpty() method.
    1298                 :  *
    1299                 :  * @return TRUE if object is empty, otherwise FALSE.
    1300                 :  */
    1301                 : 
    1302                 : /************************************************************************/
    1303                 : /*                         OGR_G_IsEmpty()                              */
    1304                 : /************************************************************************/
    1305                 : 
    1306                 : /**
    1307                 :  * \brief Test if the geometry is empty.
    1308                 :  *
    1309                 :  * This method is the same as the CPP method OGRGeometry::IsEmpty().
    1310                 :  *
    1311                 :  * @param hGeom The Geometry to test.
    1312                 :  *
    1313                 :  * @return TRUE if the geometry has no points, otherwise FALSE.  
    1314                 :  */
    1315                 : 
    1316              58 : int OGR_G_IsEmpty( OGRGeometryH hGeom )
    1317                 : 
    1318                 : {
    1319              58 :     VALIDATE_POINTER1( hGeom, "OGR_G_IsEmpty", TRUE );
    1320                 : 
    1321              58 :     return ((OGRGeometry *) hGeom)->IsEmpty();
    1322                 : }
    1323                 : 
    1324                 : /************************************************************************/
    1325                 : /*                              IsValid()                               */
    1326                 : /************************************************************************/
    1327                 : 
    1328                 : /**
    1329                 :  * \brief Test if the geometry is valid.
    1330                 :  *
    1331                 :  * This method is the same as the C function OGR_G_IsValid().
    1332                 :  *
    1333                 :  * This method is built on the GEOS library, check it for the definition
    1334                 :  * of the geometry operation.
    1335                 :  * If OGR is built without the GEOS library, this method will always return 
    1336                 :  * FALSE. 
    1337                 :  *
    1338                 :  *
    1339                 :  * @return TRUE if the geometry has no points, otherwise FALSE.  
    1340                 :  */
    1341                 : 
    1342                 : OGRBoolean
    1343               3 : OGRGeometry::IsValid(  ) const
    1344                 : 
    1345                 : {
    1346                 : #ifndef HAVE_GEOS
    1347                 : 
    1348                 :     return FALSE;
    1349                 : 
    1350                 : #else
    1351                 : 
    1352               3 :     OGRBoolean bResult = FALSE;
    1353               3 :     GEOSGeom hThisGeosGeom = NULL;
    1354                 :     
    1355               3 :     hThisGeosGeom = exportToGEOS();
    1356                 : 
    1357               3 :     if( hThisGeosGeom != NULL  )
    1358                 :     {
    1359               3 :         bResult = GEOSisValid( hThisGeosGeom );
    1360               3 :         GEOSGeom_destroy( hThisGeosGeom );
    1361                 :     }
    1362                 : 
    1363               3 :     return bResult;
    1364                 : 
    1365                 : #endif /* HAVE_GEOS */
    1366                 : }
    1367                 : 
    1368                 : /************************************************************************/
    1369                 : /*                           OGR_G_IsValid()                            */
    1370                 : /************************************************************************/
    1371                 : 
    1372                 : /**
    1373                 :  * \brief Test if the geometry is valid.
    1374                 :  *
    1375                 :  * This function is the same as the C++ method OGRGeometry::IsValid().
    1376                 :  *
    1377                 :  * This function is built on the GEOS library, check it for the definition
    1378                 :  * of the geometry operation.
    1379                 :  * If OGR is built without the GEOS library, this function will always return 
    1380                 :  * FALSE. 
    1381                 :  *
    1382                 :  * @param hGeom The Geometry to test.
    1383                 :  *
    1384                 :  * @return TRUE if the geometry has no points, otherwise FALSE.  
    1385                 :  */
    1386                 : 
    1387               3 : int OGR_G_IsValid( OGRGeometryH hGeom )
    1388                 : 
    1389                 : {
    1390               3 :     VALIDATE_POINTER1( hGeom, "OGR_G_IsValid", FALSE );
    1391                 : 
    1392               3 :     return ((OGRGeometry *) hGeom)->IsValid();
    1393                 : }
    1394                 : 
    1395                 : /************************************************************************/
    1396                 : /*                              IsSimple()                               */
    1397                 : /************************************************************************/
    1398                 : 
    1399                 : /**
    1400                 :  * \brief Test if the geometry is simple.
    1401                 :  *
    1402                 :  * This method is the same as the C function OGR_G_IsSimple().
    1403                 :  *
    1404                 :  * This method is built on the GEOS library, check it for the definition
    1405                 :  * of the geometry operation.
    1406                 :  * If OGR is built without the GEOS library, this method will always return 
    1407                 :  * FALSE. 
    1408                 :  *
    1409                 :  *
    1410                 :  * @return TRUE if the geometry has no points, otherwise FALSE.  
    1411                 :  */
    1412                 : 
    1413                 : OGRBoolean
    1414               2 : OGRGeometry::IsSimple(  ) const
    1415                 : 
    1416                 : {
    1417                 : #ifndef HAVE_GEOS
    1418                 : 
    1419                 :     return FALSE;
    1420                 : 
    1421                 : #else
    1422                 : 
    1423               2 :     OGRBoolean bResult = FALSE;
    1424               2 :     GEOSGeom hThisGeosGeom = NULL;
    1425                 :     
    1426               2 :     hThisGeosGeom = exportToGEOS();
    1427                 : 
    1428               2 :     if( hThisGeosGeom != NULL  )
    1429                 :     {
    1430               2 :         bResult = GEOSisSimple( hThisGeosGeom );
    1431               2 :         GEOSGeom_destroy( hThisGeosGeom );
    1432                 :     }
    1433                 : 
    1434               2 :     return bResult;
    1435                 : 
    1436                 : #endif /* HAVE_GEOS */
    1437                 : }
    1438                 : 
    1439                 : 
    1440                 : /**
    1441                 :  * \brief Returns TRUE if the geometry is simple.
    1442                 :  * 
    1443                 :  * Returns TRUE if the geometry has no anomalous geometric points, such
    1444                 :  * as self intersection or self tangency. The description of each
    1445                 :  * instantiable geometric class will include the specific conditions that
    1446                 :  * cause an instance of that class to be classified as not simple.
    1447                 :  *
    1448                 :  * This function is the same as the c++ method OGRGeometry::IsSimple() method.
    1449                 :  *
    1450                 :  * If OGR is built without the GEOS library, this function will always return 
    1451                 :  * FALSE.
    1452                 :  *
    1453                 :  * @param hGeom The Geometry to test.
    1454                 :  *
    1455                 :  * @return TRUE if object is simple, otherwise FALSE.
    1456                 :  */
    1457                 : 
    1458               2 : int OGR_G_IsSimple( OGRGeometryH hGeom )
    1459                 : 
    1460                 : {
    1461               2 :     VALIDATE_POINTER1( hGeom, "OGR_G_IsSimple", TRUE );
    1462                 : 
    1463               2 :     return ((OGRGeometry *) hGeom)->IsSimple();
    1464                 : }
    1465                 : 
    1466                 : /************************************************************************/
    1467                 : /*                              IsRing()                               */
    1468                 : /************************************************************************/
    1469                 : 
    1470                 : /**
    1471                 :  * \brief Test if the geometry is a ring
    1472                 :  *
    1473                 :  * This method is the same as the C function OGR_G_IsRing().
    1474                 :  *
    1475                 :  * This method is built on the GEOS library, check it for the definition
    1476                 :  * of the geometry operation.
    1477                 :  * If OGR is built without the GEOS library, this method will always return 
    1478                 :  * FALSE. 
    1479                 :  *
    1480                 :  *
    1481                 :  * @return TRUE if the geometry has no points, otherwise FALSE.  
    1482                 :  */
    1483                 : 
    1484                 : OGRBoolean
    1485               1 : OGRGeometry::IsRing(  ) const
    1486                 : 
    1487                 : {
    1488                 : #ifndef HAVE_GEOS
    1489                 : 
    1490                 :     return FALSE;
    1491                 : 
    1492                 : #else
    1493                 : 
    1494               1 :     OGRBoolean bResult = FALSE;
    1495               1 :     GEOSGeom hThisGeosGeom = NULL;
    1496                 :     
    1497               1 :     hThisGeosGeom = exportToGEOS();
    1498                 : 
    1499               1 :     if( hThisGeosGeom != NULL  )
    1500                 :     {
    1501               1 :         bResult = GEOSisRing( hThisGeosGeom );
    1502               1 :         GEOSGeom_destroy( hThisGeosGeom );
    1503                 :     }
    1504                 : 
    1505               1 :     return bResult;
    1506                 : 
    1507                 : #endif /* HAVE_GEOS */
    1508                 : }
    1509                 : 
    1510                 : /************************************************************************/
    1511                 : /*                            OGR_G_IsRing()                            */
    1512                 : /************************************************************************/
    1513                 : 
    1514                 : /**
    1515                 :  * \brief Test if the geometry is a ring
    1516                 :  *
    1517                 :  * This function is the same as the C++ method OGRGeometry::IsRing().
    1518                 :  *
    1519                 :  * This function is built on the GEOS library, check it for the definition
    1520                 :  * of the geometry operation.
    1521                 :  * If OGR is built without the GEOS library, this function will always return 
    1522                 :  * FALSE. 
    1523                 :  *
    1524                 :  * @param hGeom The Geometry to test.
    1525                 :  *
    1526                 :  * @return TRUE if the geometry has no points, otherwise FALSE.  
    1527                 :  */
    1528                 : 
    1529               1 : int OGR_G_IsRing( OGRGeometryH hGeom )
    1530                 : 
    1531                 : {
    1532               1 :     VALIDATE_POINTER1( hGeom, "OGR_G_IsRing", FALSE );
    1533                 : 
    1534               1 :     return ((OGRGeometry *) hGeom)->IsRing();
    1535                 : }
    1536                 : 
    1537                 : /************************************************************************/
    1538                 : /*                     OGRFromOGCGeomType()                             */
    1539                 : /*      Map OGCgeometry format type to corresponding                    */
    1540                 : /*      OGR constants.                                                  */
    1541                 : /************************************************************************/
    1542                 : 
    1543           11463 : OGRwkbGeometryType OGRFromOGCGeomType( const char *pszGeomType )
    1544                 : {
    1545           11463 :     if ( EQUAL(pszGeomType, "POINT") )
    1546            3766 :         return wkbPoint;
    1547            7697 :     else if ( EQUAL(pszGeomType, "LINESTRING") )
    1548             945 :         return wkbLineString;
    1549            6752 :     else if ( EQUAL(pszGeomType, "POLYGON") )
    1550            1988 :         return wkbPolygon;
    1551            4764 :     else if ( EQUAL(pszGeomType, "MULTIPOINT") )
    1552              81 :         return wkbMultiPoint;
    1553            4683 :     else if ( EQUAL(pszGeomType, "MULTILINESTRING") )
    1554             757 :         return wkbMultiLineString;
    1555            3926 :     else if ( EQUAL(pszGeomType, "MULTIPOLYGON") )
    1556            2722 :         return wkbMultiPolygon;
    1557            1204 :     else if ( EQUAL(pszGeomType, "GEOMETRYCOLLECTION") )
    1558              18 :         return wkbGeometryCollection;
    1559                 :     else
    1560            1186 :         return wkbUnknown;
    1561                 : }
    1562                 : 
    1563                 : /************************************************************************/
    1564                 : /*                     OGRToOGCGeomType()                               */
    1565                 : /*      Map OGR geometry format constants to corresponding              */
    1566                 : /*      OGC geometry type                                               */
    1567                 : /************************************************************************/
    1568                 : 
    1569             203 : const char * OGRToOGCGeomType( OGRwkbGeometryType eGeomType )
    1570                 : {
    1571             203 :     switch ( wkbFlatten(eGeomType) )
    1572                 :     {
    1573                 :         case wkbUnknown:
    1574             101 :             return "GEOMETRY";
    1575                 :         case wkbPoint:
    1576              10 :             return "POINT";
    1577                 :         case wkbLineString:
    1578              22 :             return "LINESTRING";
    1579                 :         case wkbPolygon:
    1580              23 :             return "POLYGON";
    1581                 :         case wkbMultiPoint:
    1582               6 :             return "MULTIPOINT";
    1583                 :         case wkbMultiLineString:
    1584               6 :             return "MULTILINESTRING";
    1585                 :         case wkbMultiPolygon:
    1586               8 :             return "MULTIPOLYGON";
    1587                 :         case wkbGeometryCollection:
    1588              18 :             return "GEOMETRYCOLLECTION";
    1589                 :         default:
    1590               9 :             return "";
    1591                 :     }
    1592                 : }
    1593                 : 
    1594                 : /************************************************************************/
    1595                 : /*                       OGRGeometryTypeToName()                        */
    1596                 : /************************************************************************/
    1597                 : 
    1598                 : /**
    1599                 :  * \brief Fetch a human readable name corresponding to an OGRwkBGeometryType value.
    1600                 :  * The returned value should not be modified, or freed by the application.
    1601                 :  *
    1602                 :  * This function is C callable.
    1603                 :  *
    1604                 :  * @param eType the geometry type.
    1605                 :  *
    1606                 :  * @return internal human readable string, or NULL on failure.
    1607                 :  */
    1608                 : 
    1609           11251 : const char *OGRGeometryTypeToName( OGRwkbGeometryType eType )
    1610                 : 
    1611                 : {
    1612           11251 :     bool b2D = wkbFlatten(eType) == eType;
    1613                 : 
    1614           11251 :     switch( wkbFlatten(eType) )
    1615                 :     {
    1616                 :       case wkbUnknown:
    1617            1096 :         if( b2D )
    1618            1095 :             return "Unknown (any)";
    1619                 :         else
    1620               1 :             return "3D Unknown (any)";
    1621                 : 
    1622                 :       case wkbPoint:
    1623            3752 :         if( b2D )
    1624            3695 :             return "Point";
    1625                 :         else
    1626              57 :             return "3D Point";
    1627                 : 
    1628                 :       case wkbLineString:
    1629             924 :         if( b2D )
    1630             847 :             return "Line String";
    1631                 :         else
    1632              77 :             return "3D Line String";
    1633                 : 
    1634                 :       case wkbPolygon:
    1635            1933 :         if( b2D )
    1636            1932 :             return "Polygon";
    1637                 :         else
    1638               1 :             return "3D Polygon";
    1639                 : 
    1640                 :       case wkbMultiPoint:
    1641              77 :         if( b2D )
    1642              76 :             return "Multi Point";
    1643                 :         else
    1644               1 :             return "3D Multi Point";
    1645                 : 
    1646                 :       case wkbMultiLineString:
    1647             753 :         if( b2D )
    1648             752 :             return "Multi Line String";
    1649                 :         else
    1650               1 :             return "3D Multi Line String";
    1651                 : 
    1652                 :       case wkbMultiPolygon:
    1653            2712 :         if( b2D )
    1654            2711 :             return "Multi Polygon";
    1655                 :         else
    1656               1 :             return "3D Multi Polygon";
    1657                 : 
    1658                 :       case wkbGeometryCollection:
    1659               2 :         if( b2D )
    1660               1 :             return "Geometry Collection";
    1661                 :         else
    1662               1 :             return "3D Geometry Collection";
    1663                 : 
    1664                 :       case wkbNone:
    1665               1 :         return "None";
    1666                 : 
    1667                 :       default:
    1668                 :       {
    1669                 :           // OGRThreadSafety: This static is judged to be a very low risk 
    1670                 :           // for thread safety because it is only used in case of error, 
    1671                 :           // and the worst that can happen is reporting the wrong code
    1672                 :           // in the generated message.
    1673                 :           static char szWorkName[33];
    1674               1 :           sprintf( szWorkName, "Unrecognised: %d", (int) eType );
    1675               1 :           return szWorkName;
    1676                 :       }
    1677                 :     }
    1678                 : }
    1679                 : 
    1680                 : /************************************************************************/
    1681                 : /*                       OGRMergeGeometryTypes()                        */
    1682                 : /************************************************************************/
    1683                 : 
    1684                 : /**
    1685                 :  * \brief Find common geometry type.
    1686                 :  *
    1687                 :  * Given two geometry types, find the most specific common
    1688                 :  * type.  Normally used repeatedly with the geometries in a
    1689                 :  * layer to try and establish the most specific geometry type
    1690                 :  * that can be reported for the layer.
    1691                 :  *
    1692                 :  * NOTE: wkbUnknown is the "worst case" indicating a mixture of
    1693                 :  * geometry types with nothing in common but the base geometry
    1694                 :  * type.  wkbNone should be used to indicate that no geometries
    1695                 :  * have been encountered yet, and means the first geometry
    1696                 :  * encounted will establish the preliminary type.
    1697                 :  * 
    1698                 :  * @param eMain the first input geometry type.
    1699                 :  * @param eExtra the second input geometry type.
    1700                 :  *
    1701                 :  * @return the merged geometry type.
    1702                 :  */
    1703                 : 
    1704                 : OGRwkbGeometryType 
    1705             403 : OGRMergeGeometryTypes( OGRwkbGeometryType eMain,
    1706                 :                        OGRwkbGeometryType eExtra )
    1707                 : 
    1708                 : {
    1709             403 :     int n25DFlag = 0;
    1710             403 :     OGRwkbGeometryType eFMain = wkbFlatten(eMain);
    1711             403 :     OGRwkbGeometryType eFExtra = wkbFlatten(eExtra);
    1712                 :         
    1713             403 :     if( eFMain != eMain || eFExtra != eExtra )
    1714               2 :         n25DFlag = wkb25DBit;
    1715                 : 
    1716             403 :     if( eFMain == wkbUnknown || eFExtra == wkbUnknown )
    1717              36 :         return (OGRwkbGeometryType) (((int) wkbUnknown) | n25DFlag);
    1718                 : 
    1719             367 :     if( eFMain == wkbNone )
    1720              38 :         return eExtra;
    1721                 : 
    1722             329 :     if( eFExtra == wkbNone )
    1723               0 :         return eMain;
    1724                 : 
    1725             329 :     if( eFMain == eFExtra )
    1726             326 :         return (OGRwkbGeometryType) (((int) eFMain) | n25DFlag);
    1727                 : 
    1728                 :     // Both are geometry collections.
    1729               3 :     if( (eFMain == wkbGeometryCollection
    1730                 :          || eFMain == wkbMultiPoint
    1731                 :          || eFMain == wkbMultiLineString
    1732                 :          || eFMain == wkbMultiPolygon)
    1733                 :         && (eFExtra == wkbGeometryCollection
    1734                 :             || eFExtra == wkbMultiPoint
    1735                 :             || eFExtra == wkbMultiLineString
    1736                 :             || eFMain == wkbMultiPolygon) )
    1737                 :     {
    1738               1 :         return (OGRwkbGeometryType) (((int) wkbGeometryCollection) | n25DFlag);
    1739                 :     }
    1740                 : 
    1741                 :     // Nothing apparently in common.
    1742               2 :     return (OGRwkbGeometryType) (((int) wkbUnknown) | n25DFlag);
    1743                 : }
    1744                 : 
    1745                 : /**
    1746                 :  * \fn void OGRGeometry::flattenTo2D();
    1747                 :  *
    1748                 :  * \brief Convert geometry to strictly 2D.
    1749                 :  * In a sense this converts all Z coordinates
    1750                 :  * to 0.0.
    1751                 :  *
    1752                 :  * This method is the same as the C function OGR_G_FlattenTo2D().
    1753                 :  */
    1754                 : 
    1755                 : /************************************************************************/
    1756                 : /*                         OGR_G_FlattenTo2D()                          */
    1757                 : /************************************************************************/
    1758                 : /**
    1759                 :  * \brief Convert geometry to strictly 2D.
    1760                 :  * In a sense this converts all Z coordinates
    1761                 :  * to 0.0.
    1762                 :  *
    1763                 :  * This function is the same as the CPP method OGRGeometry::flattenTo2D().
    1764                 :  *
    1765                 :  * @param hGeom handle on the geometry to convert.
    1766                 :  */
    1767                 : 
    1768               1 : void OGR_G_FlattenTo2D( OGRGeometryH hGeom )
    1769                 : 
    1770                 : {
    1771               1 :     ((OGRGeometry *) hGeom)->flattenTo2D();
    1772               1 : }
    1773                 : 
    1774                 : /************************************************************************/
    1775                 : /*                            exportToGML()                             */
    1776                 : /************************************************************************/
    1777                 : 
    1778                 : /**
    1779                 :  * \fn char *OGRGeometry::exportToGML( const char* const * papszOptions = NULL ) const;
    1780                 :  *
    1781                 :  * \brief Convert a geometry into GML format.
    1782                 :  *
    1783                 :  * The GML geometry is expressed directly in terms of GML basic data
    1784                 :  * types assuming the this is available in the gml namespace.  The returned
    1785                 :  * string should be freed with CPLFree() when no longer required.
    1786                 :  *
    1787                 :  * The supported options in OGR 1.8.0 are :
    1788                 :  * <ul>
    1789                 :  * <li> FORMAT=GML3. Otherwise it will default to GML 2.1.2 output.
    1790                 :  * <li> GML3_LINESTRING_ELEMENT=curve. (Only valid for FORMAT=GML3) To use gml:Curve element for linestrings.
    1791                 :  *     Otherwise gml:LineString will be used .
    1792                 :  * <li> GML3_LONGSRS=YES/NO. (Only valid for FORMAT=GML3) Default to YES. If YES, SRS with EPSG authority will
    1793                 :  *      be written with the "urn:ogc:def:crs:EPSG::" prefix.
    1794                 :  *      In the case, if the SRS is a geographic SRS without explicit AXIS order, but that the same SRS authority code
    1795                 :  *      imported with ImportFromEPSGA() should be treated as lat/long, then the function will take care of coordinate order swapping.
    1796                 :  *      If set to NO, SRS with EPSG authority will be written with the "EPSG:" prefix, even if they are in lat/long order.
    1797                 :  * </ul>
    1798                 :  *
    1799                 :  * This method is the same as the C function OGR_G_ExportToGMLEx().
    1800                 :  *
    1801                 :  * @param papszOptions NULL-terminated list of options.
    1802                 :  * @return A GML fragment or NULL in case of error.
    1803                 :  */
    1804                 : 
    1805              70 : char *OGRGeometry::exportToGML( const char* const * papszOptions ) const
    1806                 : {
    1807              70 :     return OGR_G_ExportToGMLEx( (OGRGeometryH) this, (char**)papszOptions );
    1808                 : }
    1809                 : 
    1810                 : /************************************************************************/
    1811                 : /*                            exportToKML()                             */
    1812                 : /************************************************************************/
    1813                 : 
    1814                 : /**
    1815                 :  * \fn char *OGRGeometry::exportToKML() const;
    1816                 :  *
    1817                 :  * \brief Convert a geometry into KML format.
    1818                 :  *
    1819                 :  * The returned string should be freed with CPLFree() when no longer required.
    1820                 :  *
    1821                 :  * This method is the same as the C function OGR_G_ExportToKML().
    1822                 :  *
    1823                 :  * @return A KML fragment or NULL in case of error.
    1824                 :  */
    1825                 : 
    1826               0 : char *OGRGeometry::exportToKML() const
    1827                 : {
    1828                 : #ifndef _WIN32_WCE
    1829                 : #ifdef OGR_ENABLED
    1830               0 :     return OGR_G_ExportToKML( (OGRGeometryH) this, NULL );
    1831                 : #else
    1832                 :     CPLError( CE_Failure, CPLE_AppDefined,
    1833                 :               "OGRGeometry::exportToKML() not supported in builds without OGR drivers." );
    1834                 :     return NULL;
    1835                 : #endif
    1836                 : #else
    1837                 :     CPLError( CE_Failure, CPLE_AppDefined,
    1838                 :               "OGRGeometry::exportToKML() not supported in the WinCE build." );
    1839                 :     return NULL;
    1840                 : #endif
    1841                 : }
    1842                 : 
    1843                 : /************************************************************************/
    1844                 : /*                            exportToJson()                             */
    1845                 : /************************************************************************/
    1846                 : 
    1847                 : /**
    1848                 :  * \fn char *OGRGeometry::exportToJson() const;
    1849                 :  *
    1850                 :  * \brief Convert a geometry into GeoJSON format.
    1851                 :  *
    1852                 :  * The returned string should be freed with CPLFree() when no longer required.
    1853                 :  *
    1854                 :  * This method is the same as the C function OGR_G_ExportToJson().
    1855                 :  *
    1856                 :  * @return A GeoJSON fragment or NULL in case of error.
    1857                 :  */
    1858                 : 
    1859               0 : char *OGRGeometry::exportToJson() const
    1860                 : {
    1861                 : #ifndef _WIN32_WCE
    1862                 : #ifdef OGR_ENABLED
    1863               0 :     OGRGeometry* poGeometry = const_cast<OGRGeometry*>(this);
    1864               0 :     return OGR_G_ExportToJson( (OGRGeometryH) (poGeometry) );
    1865                 : #else
    1866                 :     CPLError( CE_Failure, CPLE_AppDefined,
    1867                 :               "OGRGeometry::exportToJson() not supported in builds without OGR drivers." );
    1868                 :     return NULL;
    1869                 : #endif
    1870                 : #else
    1871                 :     CPLError( CE_Failure, CPLE_AppDefined,
    1872                 :               "OGRGeometry::exportToJson() not supported in the WinCE build." );
    1873                 :     return NULL;
    1874                 : #endif
    1875                 : }
    1876                 : 
    1877                 : /************************************************************************/
    1878                 : /*                 OGRSetGenerate_DB2_V72_BYTE_ORDER()                  */
    1879                 : /************************************************************************/
    1880                 : 
    1881                 : /**
    1882                 :   * \brief Special entry point to enable the hack for generating DB2 V7.2 style WKB.
    1883                 :   *
    1884                 :   * DB2 seems to have placed  (and require) an extra 0x30 or'ed with the byte order in
    1885                 :   * WKB.  This entry point is used to turn on or off the
    1886                 :   * generation of such WKB.
    1887                 :   */
    1888               4 : OGRErr OGRSetGenerate_DB2_V72_BYTE_ORDER( int bGenerate_DB2_V72_BYTE_ORDER )
    1889                 : 
    1890                 : {
    1891                 : #if defined(HACK_FOR_IBM_DB2_V72)
    1892               4 :     OGRGeometry::bGenerate_DB2_V72_BYTE_ORDER = bGenerate_DB2_V72_BYTE_ORDER;
    1893               4 :     return OGRERR_NONE;
    1894                 : #else
    1895                 :     if( bGenerate_DB2_V72_BYTE_ORDER )
    1896                 :         return OGRERR_FAILURE;
    1897                 :     else
    1898                 :         return OGRERR_NONE;
    1899                 : #endif
    1900                 : }
    1901                 : /************************************************************************/
    1902                 : /*                 OGRGetGenerate_DB2_V72_BYTE_ORDER()                  */
    1903                 : /*                                                                      */
    1904                 : /*      This is a special entry point to get the value of static flag   */
    1905                 : /*      OGRGeometry::bGenerate_DB2_V72_BYTE_ORDER.                      */
    1906                 : /************************************************************************/
    1907               0 : int OGRGetGenerate_DB2_V72_BYTE_ORDER()
    1908                 : {
    1909               0 :    return OGRGeometry::bGenerate_DB2_V72_BYTE_ORDER;
    1910                 : }
    1911                 : 
    1912                 : /************************************************************************/
    1913                 : /*                            exportToGEOS()                            */
    1914                 : /************************************************************************/
    1915                 : 
    1916           21402 : GEOSGeom OGRGeometry::exportToGEOS() const
    1917                 : 
    1918                 : {
    1919                 : #ifndef HAVE_GEOS
    1920                 : 
    1921                 :     CPLError( CE_Failure, CPLE_NotSupported, 
    1922                 :               "GEOS support not enabled." );
    1923                 :     return NULL;
    1924                 : 
    1925                 : #else
    1926                 : 
    1927                 :     static void *hGEOSInitMutex = NULL;
    1928                 :     static int bGEOSInitialized = FALSE;
    1929                 : 
    1930           21402 :     CPLMutexHolderD( &hGEOSInitMutex );
    1931                 : 
    1932           21402 :     if( !bGEOSInitialized )
    1933                 :     {
    1934              45 :         bGEOSInitialized = TRUE;
    1935              45 :         initGEOS( _GEOSWarningHandler, _GEOSErrorHandler );
    1936                 :     }
    1937                 : 
    1938                 :     /* POINT EMPTY is exported to WKB as if it were POINT(0 0) */
    1939                 :     /* so that particular case is necessary */
    1940           21402 :     if (wkbFlatten(getGeometryType()) == wkbPoint &&
    1941                 :         nCoordDimension == 0)
    1942                 :     {
    1943               1 :         return GEOSGeomFromWKT("POINT EMPTY");
    1944                 :     }
    1945                 : 
    1946           21401 :     GEOSGeom hGeom = NULL;
    1947                 :     size_t nDataSize;
    1948           21401 :     unsigned char *pabyData = NULL;
    1949                 : 
    1950           21401 :     nDataSize = WkbSize();
    1951           21401 :     pabyData = (unsigned char *) CPLMalloc(nDataSize);
    1952           21401 :     if( exportToWkb( wkbNDR, pabyData ) == OGRERR_NONE )
    1953           21401 :         hGeom = GEOSGeomFromWKB_buf( pabyData, nDataSize );
    1954                 : 
    1955           21401 :     CPLFree( pabyData );
    1956                 : 
    1957           21401 :     return hGeom;
    1958                 : 
    1959                 : #endif /* HAVE_GEOS */
    1960                 : }
    1961                 : 
    1962                 : 
    1963                 : /************************************************************************/
    1964                 : /*                              Distance()                              */
    1965                 : /************************************************************************/
    1966                 : 
    1967                 : /**
    1968                 :  * \brief Compute distance between two geometries.
    1969                 :  *
    1970                 :  * Returns the shortest distance between the two geometries. 
    1971                 :  *
    1972                 :  * This method is the same as the C function OGR_G_Distance().
    1973                 :  *
    1974                 :  * This method is built on the GEOS library, check it for the definition
    1975                 :  * of the geometry operation.
    1976                 :  * If OGR is built without the GEOS library, this method will always fail, 
    1977                 :  * issuing a CPLE_NotSupported error. 
    1978                 :  *
    1979                 :  * @param poOtherGeom the other geometry to compare against.
    1980                 :  *
    1981                 :  * @return the distance between the geometries or -1 if an error occurs.
    1982                 :  */
    1983                 : 
    1984               1 : double OGRGeometry::Distance( const OGRGeometry *poOtherGeom ) const
    1985                 : 
    1986                 : {
    1987               1 :     if( NULL == poOtherGeom )
    1988                 :     {
    1989               0 :         CPLDebug( "OGR", "OGRGeometry::Distance called with NULL geometry pointer" );
    1990               0 :         return -1.0;
    1991                 :     }
    1992                 : 
    1993                 : #ifndef HAVE_GEOS
    1994                 : 
    1995                 :     CPLError( CE_Failure, CPLE_NotSupported, 
    1996                 :               "GEOS support not enabled." );
    1997                 :     return -1.0;
    1998                 : 
    1999                 : #else
    2000                 : 
    2001                 :     // GEOSGeom is a pointer
    2002               1 :     GEOSGeom hThis = NULL;
    2003               1 :     GEOSGeom hOther = NULL;
    2004                 : 
    2005               1 :     hOther = poOtherGeom->exportToGEOS();
    2006               1 :     hThis = exportToGEOS();
    2007                 :    
    2008               1 :     int bIsErr = 0;
    2009               1 :     double dfDistance = 0.0;
    2010                 : 
    2011               1 :     if( hThis != NULL && hOther != NULL )
    2012                 :     {
    2013               1 :         bIsErr = GEOSDistance( hThis, hOther, &dfDistance );
    2014                 :     }
    2015                 : 
    2016               1 :     GEOSGeom_destroy( hThis );
    2017               1 :     GEOSGeom_destroy( hOther );
    2018                 : 
    2019               1 :     if ( bIsErr > 0 ) 
    2020                 :     {
    2021               1 :         return dfDistance;
    2022                 :     }
    2023                 : 
    2024                 :     /* Calculations error */
    2025               0 :     return -1.0;
    2026                 : 
    2027                 : #endif /* HAVE_GEOS */
    2028                 : }
    2029                 : 
    2030                 : /************************************************************************/
    2031                 : /*                           OGR_G_Distance()                           */
    2032                 : /************************************************************************/
    2033                 : /**
    2034                 :  * \brief Compute distance between two geometries.
    2035                 :  *
    2036                 :  * Returns the shortest distance between the two geometries. 
    2037                 :  *
    2038                 :  * This function is the same as the C++ method OGRGeometry::Distance().
    2039                 :  *
    2040                 :  * This function is built on the GEOS library, check it for the definition
    2041                 :  * of the geometry operation.
    2042                 :  * If OGR is built without the GEOS library, this function will always fail, 
    2043                 :  * issuing a CPLE_NotSupported error. 
    2044                 :  *
    2045                 :  * @param hFirst the first geometry to compare against.
    2046                 :  * @param hOther the other geometry to compare against.
    2047                 :  *
    2048                 :  * @return the distance between the geometries or -1 if an error occurs.
    2049                 :  */
    2050                 : 
    2051                 : 
    2052               1 : double OGR_G_Distance( OGRGeometryH hFirst, OGRGeometryH hOther )
    2053                 : 
    2054                 : {
    2055               1 :     VALIDATE_POINTER1( hFirst, "OGR_G_Distance", 0.0 );
    2056                 : 
    2057               1 :     return ((OGRGeometry *) hFirst)->Distance( (OGRGeometry *) hOther );
    2058                 : }
    2059                 : 
    2060                 : /************************************************************************/
    2061                 : /*                             ConvexHull()                             */
    2062                 : /************************************************************************/
    2063                 : 
    2064                 : /**
    2065                 :  * \brief Compute convex hull.
    2066                 :  *
    2067                 :  * A new geometry object is created and returned containing the convex
    2068                 :  * hull of the geometry on which the method is invoked.  
    2069                 :  *
    2070                 :  * This method is the same as the C function OGR_G_ConvexHull().
    2071                 :  *
    2072                 :  * This method is built on the GEOS library, check it for the definition
    2073                 :  * of the geometry operation.
    2074                 :  * If OGR is built without the GEOS library, this method will always fail, 
    2075                 :  * issuing a CPLE_NotSupported error. 
    2076                 :  *
    2077                 :  * @return a newly allocated geometry now owned by the caller, or NULL on failure.
    2078                 :  */
    2079                 : 
    2080               1 : OGRGeometry *OGRGeometry::ConvexHull() const
    2081                 : 
    2082                 : {
    2083                 : #ifndef HAVE_GEOS
    2084                 : 
    2085                 :     CPLError( CE_Failure, CPLE_NotSupported, 
    2086                 :               "GEOS support not enabled." );
    2087                 :     return NULL;
    2088                 : 
    2089                 : #else
    2090                 : 
    2091               1 :     GEOSGeom hGeosGeom = NULL;
    2092               1 :     GEOSGeom hGeosHull = NULL;
    2093               1 :     OGRGeometry *poHullOGRGeom = NULL;
    2094                 : 
    2095               1 :     hGeosGeom = exportToGEOS();
    2096               1 :     if( hGeosGeom != NULL )
    2097                 :     {
    2098               1 :         hGeosHull = GEOSConvexHull( hGeosGeom );
    2099               1 :         GEOSGeom_destroy( hGeosGeom );
    2100                 : 
    2101               1 :         if( hGeosHull != NULL )
    2102                 :         {
    2103               1 :             poHullOGRGeom = OGRGeometryFactory::createFromGEOS(hGeosHull);
    2104               1 :             if( poHullOGRGeom != NULL && getSpatialReference() != NULL )
    2105               0 :                 poHullOGRGeom->assignSpatialReference(getSpatialReference());
    2106               1 :             GEOSGeom_destroy( hGeosHull);
    2107                 :         }
    2108                 :     }
    2109                 : 
    2110               1 :     return poHullOGRGeom;
    2111                 : 
    2112                 : #endif /* HAVE_GEOS */
    2113                 : }
    2114                 : 
    2115                 : /************************************************************************/
    2116                 : /*                          OGR_G_ConvexHull()                          */
    2117                 : /************************************************************************/
    2118                 : /**
    2119                 :  * \brief Compute convex hull.
    2120                 :  *
    2121                 :  * A new geometry object is created and returned containing the convex
    2122                 :  * hull of the geometry on which the method is invoked.  
    2123                 :  *
    2124                 :  * This function is the same as the C++ method OGRGeometry::ConvexHull().
    2125                 :  *
    2126                 :  * This function is built on the GEOS library, check it for the definition
    2127                 :  * of the geometry operation.
    2128                 :  * If OGR is built without the GEOS library, this function will always fail, 
    2129                 :  * issuing a CPLE_NotSupported error. 
    2130                 :  *
    2131                 :  * @param hTarget The Geometry to calculate the convex hull of.
    2132                 :  *
    2133                 :  * @return a handle to a newly allocated geometry now owned by the caller,
    2134                 :  *         or NULL on failure.
    2135                 :  */
    2136                 : 
    2137               1 : OGRGeometryH OGR_G_ConvexHull( OGRGeometryH hTarget )
    2138                 : 
    2139                 : {
    2140               1 :     VALIDATE_POINTER1( hTarget, "OGR_G_ConvexHull", NULL );
    2141                 : 
    2142               1 :     return (OGRGeometryH) ((OGRGeometry *) hTarget)->ConvexHull();
    2143                 : }
    2144                 : 
    2145                 : /************************************************************************/
    2146                 : /*                            Boundary()                                */
    2147                 : /************************************************************************/
    2148                 : 
    2149                 : /**
    2150                 :  * \brief Compute boundary.
    2151                 :  *
    2152                 :  * A new geometry object is created and returned containing the boundary
    2153                 :  * of the geometry on which the method is invoked.  
    2154                 :  *
    2155                 :  * This method is the same as the C function OGR_G_Boundary().
    2156                 :  *
    2157                 :  * This method is built on the GEOS library, check it for the definition
    2158                 :  * of the geometry operation.
    2159                 :  * If OGR is built without the GEOS library, this method will always fail, 
    2160                 :  * issuing a CPLE_NotSupported error. 
    2161                 :  *
    2162                 :  * @return a newly allocated geometry now owned by the caller, or NULL on failure.
    2163                 :  *
    2164                 :  * @since OGR 1.8.0
    2165                 :  */
    2166                 : 
    2167               6 : OGRGeometry *OGRGeometry::Boundary() const
    2168                 : 
    2169                 : {
    2170                 : #ifndef HAVE_GEOS
    2171                 : 
    2172                 :     CPLError( CE_Failure, CPLE_NotSupported, 
    2173                 :               "GEOS support not enabled." );
    2174                 :     return NULL;
    2175                 : 
    2176                 : #else
    2177                 :     
    2178               6 :     GEOSGeom hGeosGeom = NULL;
    2179               6 :     GEOSGeom hGeosProduct = NULL;
    2180               6 :     OGRGeometry *poOGRProduct = NULL;
    2181                 : 
    2182               6 :     hGeosGeom = exportToGEOS();
    2183               6 :     if( hGeosGeom != NULL )
    2184                 :     {
    2185               6 :         hGeosProduct = GEOSBoundary( hGeosGeom );
    2186               6 :         GEOSGeom_destroy( hGeosGeom );
    2187                 : 
    2188               6 :         if( hGeosProduct != NULL )
    2189                 :         {
    2190               6 :             poOGRProduct = OGRGeometryFactory::createFromGEOS(hGeosProduct);
    2191               6 :             if( poOGRProduct != NULL && getSpatialReference() != NULL )
    2192               0 :                 poOGRProduct->assignSpatialReference(getSpatialReference());
    2193               6 :             GEOSGeom_destroy( hGeosProduct );
    2194                 :         }
    2195                 :     }
    2196                 : 
    2197               6 :     return poOGRProduct;
    2198                 : 
    2199                 : #endif /* HAVE_GEOS */
    2200                 : }
    2201                 : 
    2202                 : 
    2203                 : /**
    2204                 :  * \brief Compute boundary (deprecated)
    2205                 :  *
    2206                 :  * @deprecated
    2207                 :  *
    2208                 :  * @see Boundary()
    2209                 :  */
    2210               0 : OGRGeometry *OGRGeometry::getBoundary() const
    2211                 : 
    2212                 : {
    2213               0 :     return Boundary();
    2214                 : }
    2215                 : 
    2216                 : /************************************************************************/
    2217                 : /*                         OGR_G_Boundary()                             */
    2218                 : /************************************************************************/
    2219                 : /**
    2220                 :  * \brief Compute boundary.
    2221                 :  *
    2222                 :  * A new geometry object is created and returned containing the boundary
    2223                 :  * of the geometry on which the method is invoked.  
    2224                 :  *
    2225                 :  * This function is the same as the C++ method OGR_G_Boundary().
    2226                 :  *
    2227                 :  * This function is built on the GEOS library, check it for the definition
    2228                 :  * of the geometry operation.
    2229                 :  * If OGR is built without the GEOS library, this function will always fail, 
    2230                 :  * issuing a CPLE_NotSupported error. 
    2231                 :  *
    2232                 :  * @param hTarget The Geometry to calculate the boundary of.
    2233                 :  *
    2234                 :  * @return a handle to a newly allocated geometry now owned by the caller,
    2235                 :  *         or NULL on failure.
    2236                 :  *
    2237                 :  * @since OGR 1.8.0
    2238                 :  */
    2239               6 : OGRGeometryH OGR_G_Boundary( OGRGeometryH hTarget )
    2240                 : 
    2241                 : {
    2242               6 :     VALIDATE_POINTER1( hTarget, "OGR_G_Boundary", NULL );
    2243                 : 
    2244               6 :     return (OGRGeometryH) ((OGRGeometry *) hTarget)->Boundary();
    2245                 : }
    2246                 : 
    2247                 : /**
    2248                 :  * \brief Compute boundary (deprecated)
    2249                 :  *
    2250                 :  * @deprecated
    2251                 :  *
    2252                 :  * @see OGR_G_Boundary()
    2253                 :  */
    2254               0 : OGRGeometryH OGR_G_GetBoundary( OGRGeometryH hTarget )
    2255                 : 
    2256                 : {
    2257               0 :     VALIDATE_POINTER1( hTarget, "OGR_G_GetBoundary", NULL );
    2258                 : 
    2259               0 :     return (OGRGeometryH) ((OGRGeometry *) hTarget)->Boundary();
    2260                 : }
    2261                 : 
    2262                 : /************************************************************************/
    2263                 : /*                               Buffer()                               */
    2264                 : /************************************************************************/
    2265                 : 
    2266                 : /**
    2267                 :  * \brief Compute buffer of geometry.
    2268                 :  *
    2269                 :  * Builds a new geometry containing the buffer region around the geometry
    2270                 :  * on which it is invoked.  The buffer is a polygon containing the region within
    2271                 :  * the buffer distance of the original geometry.  
    2272                 :  *
    2273                 :  * Some buffer sections are properly described as curves, but are converted to
    2274                 :  * approximate polygons.  The nQuadSegs parameter can be used to control how many
    2275                 :  * segements should be used to define a 90 degree curve - a quadrant of a circle. 
    2276                 :  * A value of 30 is a reasonable default.  Large values result in large numbers
    2277                 :  * of vertices in the resulting buffer geometry while small numbers reduce the 
    2278                 :  * accuracy of the result. 
    2279                 :  *
    2280                 :  * This method is the same as the C function OGR_G_Buffer().
    2281                 :  *
    2282                 :  * This method is built on the GEOS library, check it for the definition
    2283                 :  * of the geometry operation.
    2284                 :  * If OGR is built without the GEOS library, this method will always fail, 
    2285                 :  * issuing a CPLE_NotSupported error. 
    2286                 :  *
    2287                 :  * @param dfDist the buffer distance to be applied. 
    2288                 :  *
    2289                 :  * @param nQuadSegs the number of segments used to approximate a 90 degree (quadrant) of
    2290                 :  * curvature. 
    2291                 :  *
    2292                 :  * @return the newly created geometry, or NULL if an error occurs. 
    2293                 :  */
    2294                 : 
    2295               1 : OGRGeometry *OGRGeometry::Buffer( double dfDist, int nQuadSegs ) const
    2296                 : 
    2297                 : {
    2298                 : #ifndef HAVE_GEOS
    2299                 : 
    2300                 :     CPLError( CE_Failure, CPLE_NotSupported, 
    2301                 :               "GEOS support not enabled." );
    2302                 :     return NULL;
    2303                 : 
    2304                 : #else
    2305                 : 
    2306               1 :     GEOSGeom hGeosGeom = NULL;
    2307               1 :     GEOSGeom hGeosProduct = NULL;
    2308               1 :     OGRGeometry *poOGRProduct = NULL;
    2309                 : 
    2310               1 :     hGeosGeom = exportToGEOS();
    2311               1 :     if( hGeosGeom != NULL )
    2312                 :     {
    2313               1 :         hGeosProduct = GEOSBuffer( hGeosGeom, dfDist, nQuadSegs );
    2314               1 :         GEOSGeom_destroy( hGeosGeom );
    2315                 : 
    2316               1 :         if( hGeosProduct != NULL )
    2317                 :         {
    2318               1 :             poOGRProduct = OGRGeometryFactory::createFromGEOS(hGeosProduct);
    2319               1 :             if( poOGRProduct != NULL && getSpatialReference() != NULL )
    2320               0 :                 poOGRProduct->assignSpatialReference(getSpatialReference());
    2321               1 :             GEOSGeom_destroy( hGeosProduct );
    2322                 :         }
    2323                 :     }
    2324                 : 
    2325               1 :     return poOGRProduct;
    2326                 : 
    2327                 : #endif /* HAVE_GEOS */
    2328                 : }
    2329                 : 
    2330                 : /************************************************************************/
    2331                 : /*                            OGR_G_Buffer()                            */
    2332                 : /************************************************************************/
    2333                 : 
    2334                 : /**
    2335                 :  * \brief Compute buffer of geometry.
    2336                 :  *
    2337                 :  * Builds a new geometry containing the buffer region around the geometry
    2338                 :  * on which it is invoked.  The buffer is a polygon containing the region within
    2339                 :  * the buffer distance of the original geometry.  
    2340                 :  *
    2341                 :  * Some buffer sections are properly described as curves, but are converted to
    2342                 :  * approximate polygons.  The nQuadSegs parameter can be used to control how many
    2343                 :  * segements should be used to define a 90 degree curve - a quadrant of a circle. 
    2344                 :  * A value of 30 is a reasonable default.  Large values result in large numbers
    2345                 :  * of vertices in the resulting buffer geometry while small numbers reduce the 
    2346                 :  * accuracy of the result. 
    2347                 :  *
    2348                 :  * This function is the same as the C++ method OGRGeometry::Buffer().
    2349                 :  *
    2350                 :  * This function is built on the GEOS library, check it for the definition
    2351                 :  * of the geometry operation.
    2352                 :  * If OGR is built without the GEOS library, this function will always fail, 
    2353                 :  * issuing a CPLE_NotSupported error. 
    2354                 :  *
    2355                 :  * @param hTarget the geometry.
    2356                 :  * @param dfDist the buffer distance to be applied. 
    2357                 :  *
    2358                 :  * @param nQuadSegs the number of segments used to approximate a 90 degree
    2359                 :  * (quadrant) of curvature. 
    2360                 :  *
    2361                 :  * @return the newly created geometry, or NULL if an error occurs. 
    2362                 :  */
    2363                 : 
    2364               1 : OGRGeometryH OGR_G_Buffer( OGRGeometryH hTarget, double dfDist, int nQuadSegs )
    2365                 : 
    2366                 : {
    2367               1 :     VALIDATE_POINTER1( hTarget, "OGR_G_Buffer", NULL );
    2368                 : 
    2369               1 :     return (OGRGeometryH) ((OGRGeometry *) hTarget)->Buffer( dfDist, nQuadSegs );
    2370                 : }
    2371                 : 
    2372                 : /************************************************************************/
    2373                 : /*                            Intersection()                            */
    2374                 : /************************************************************************/
    2375                 : 
    2376                 : /**
    2377                 :  * \brief Compute intersection.
    2378                 :  *
    2379                 :  * Generates a new geometry which is the region of intersection of the
    2380                 :  * two geometries operated on.  The Intersects() method can be used to test if
    2381                 :  * two geometries intersect. 
    2382                 :  *
    2383                 :  * This method is the same as the C function OGR_G_Intersection().
    2384                 :  *
    2385                 :  * This method is built on the GEOS library, check it for the definition
    2386                 :  * of the geometry operation.
    2387                 :  * If OGR is built without the GEOS library, this method will always fail, 
    2388                 :  * issuing a CPLE_NotSupported error. 
    2389                 :  *
    2390                 :  * @param poOtherGeom the other geometry intersected with "this" geometry.
    2391                 :  *
    2392                 :  * @return a new geometry representing the intersection or NULL if there is
    2393                 :  * no intersection or an error occurs.
    2394                 :  */
    2395                 : 
    2396             108 : OGRGeometry *OGRGeometry::Intersection( const OGRGeometry *poOtherGeom ) const
    2397                 : 
    2398                 : {
    2399                 : #ifndef HAVE_GEOS
    2400                 : 
    2401                 :     CPLError( CE_Failure, CPLE_NotSupported, 
    2402                 :               "GEOS support not enabled." );
    2403                 :     return NULL;
    2404                 : 
    2405                 : #else
    2406                 : 
    2407             108 :     GEOSGeom hThisGeosGeom = NULL;
    2408             108 :     GEOSGeom hOtherGeosGeom = NULL;
    2409             108 :     GEOSGeom hGeosProduct = NULL;
    2410             108 :     OGRGeometry *poOGRProduct = NULL;
    2411                 : 
    2412             108 :     hThisGeosGeom = exportToGEOS();
    2413             108 :     hOtherGeosGeom = poOtherGeom->exportToGEOS();
    2414             108 :     if( hThisGeosGeom != NULL && hOtherGeosGeom != NULL )
    2415                 :     {
    2416             108 :         hGeosProduct = GEOSIntersection( hThisGeosGeom, hOtherGeosGeom );
    2417                 : 
    2418             108 :         if( hGeosProduct != NULL )
    2419                 :         {
    2420             108 :             poOGRProduct = OGRGeometryFactory::createFromGEOS(hGeosProduct);
    2421             108 :             if( poOGRProduct != NULL && getSpatialReference() != NULL &&
    2422                 :                 poOtherGeom->getSpatialReference() != NULL &&
    2423                 :                 poOtherGeom->getSpatialReference()->IsSame(getSpatialReference()) )
    2424                 :             {
    2425               0 :                 poOGRProduct->assignSpatialReference(getSpatialReference());
    2426                 :             }
    2427             108 :             GEOSGeom_destroy( hGeosProduct );
    2428                 :         }
    2429                 :     }
    2430             108 :     GEOSGeom_destroy( hThisGeosGeom );
    2431             108 :     GEOSGeom_destroy( hOtherGeosGeom );
    2432                 : 
    2433             108 :     return poOGRProduct;
    2434                 : 
    2435                 : #endif /* HAVE_GEOS */
    2436                 : }
    2437                 : 
    2438                 : /************************************************************************/
    2439                 : /*                         OGR_G_Intersection()                         */
    2440                 : /************************************************************************/
    2441                 : 
    2442                 : /**
    2443                 :  * \brief Compute intersection.
    2444                 :  *
    2445                 :  * Generates a new geometry which is the region of intersection of the
    2446                 :  * two geometries operated on.  The OGR_G_Intersects() function can be used to
    2447                 :  * test if two geometries intersect. 
    2448                 :  *
    2449                 :  * This function is the same as the C++ method OGRGeometry::Intersection().
    2450                 :  *
    2451                 :  * This function is built on the GEOS library, check it for the definition
    2452                 :  * of the geometry operation.
    2453                 :  * If OGR is built without the GEOS library, this function will always fail, 
    2454                 :  * issuing a CPLE_NotSupported error. 
    2455                 :  *
    2456                 :  * @param hThis the geometry.
    2457                 :  * @param hOther the other geometry.
    2458                 :  *
    2459                 :  * @return a new geometry representing the intersection or NULL if there is
    2460                 :  * no intersection or an error occurs.
    2461                 :  */
    2462                 : 
    2463              45 : OGRGeometryH OGR_G_Intersection( OGRGeometryH hThis, OGRGeometryH hOther )
    2464                 : 
    2465                 : {
    2466              45 :     VALIDATE_POINTER1( hThis, "OGR_G_Intersection", NULL );
    2467                 : 
    2468                 :     return (OGRGeometryH) 
    2469              45 :         ((OGRGeometry *) hThis)->Intersection( (OGRGeometry *) hOther );
    2470                 : }
    2471                 : 
    2472                 : /************************************************************************/
    2473                 : /*                               Union()                                */
    2474                 : /************************************************************************/
    2475                 : 
    2476                 : /**
    2477                 :  * \brief Compute union.
    2478                 :  *
    2479                 :  * Generates a new geometry which is the region of union of the
    2480                 :  * two geometries operated on.  
    2481                 :  *
    2482                 :  * This method is the same as the C function OGR_G_Union().
    2483                 :  *
    2484                 :  * This method is built on the GEOS library, check it for the definition
    2485                 :  * of the geometry operation.
    2486                 :  * If OGR is built without the GEOS library, this method will always fail, 
    2487                 :  * issuing a CPLE_NotSupported error. 
    2488                 :  *
    2489                 :  * @param poOtherGeom the other geometry unioned with "this" geometry.
    2490                 :  *
    2491                 :  * @return a new geometry representing the union or NULL if an error occurs.
    2492                 :  */
    2493                 : 
    2494              35 : OGRGeometry *OGRGeometry::Union( const OGRGeometry *poOtherGeom ) const
    2495                 : 
    2496                 : {
    2497                 : #ifndef HAVE_GEOS
    2498                 : 
    2499                 :     CPLError( CE_Failure, CPLE_NotSupported, 
    2500                 :               "GEOS support not enabled." );
    2501                 :     return NULL;
    2502                 : 
    2503                 : #else
    2504                 : 
    2505              35 :     GEOSGeom hThisGeosGeom = NULL;
    2506              35 :     GEOSGeom hOtherGeosGeom = NULL;
    2507              35 :     GEOSGeom hGeosProduct = NULL;
    2508              35 :     OGRGeometry *poOGRProduct = NULL;
    2509                 : 
    2510              35 :     hThisGeosGeom = exportToGEOS();
    2511              35 :     hOtherGeosGeom = poOtherGeom->exportToGEOS();
    2512              35 :     if( hThisGeosGeom != NULL && hOtherGeosGeom != NULL )
    2513                 :     {
    2514              35 :         hGeosProduct = GEOSUnion( hThisGeosGeom, hOtherGeosGeom );
    2515                 : 
    2516              35 :         if( hGeosProduct != NULL )
    2517                 :         {
    2518              35 :             poOGRProduct = OGRGeometryFactory::createFromGEOS(hGeosProduct);
    2519              35 :             if( poOGRProduct != NULL && getSpatialReference() != NULL &&
    2520                 :                 poOtherGeom->getSpatialReference() != NULL &&
    2521                 :                 poOtherGeom->getSpatialReference()->IsSame(getSpatialReference()) )
    2522                 :             {
    2523               0 :                 poOGRProduct->assignSpatialReference(getSpatialReference());
    2524                 :             }
    2525              35 :             GEOSGeom_destroy( hGeosProduct );
    2526                 :         }
    2527                 :     }
    2528              35 :     GEOSGeom_destroy( hThisGeosGeom );
    2529              35 :     GEOSGeom_destroy( hOtherGeosGeom );
    2530                 : 
    2531              35 :     return poOGRProduct;
    2532                 : 
    2533                 : #endif /* HAVE_GEOS */
    2534                 : }
    2535                 : 
    2536                 : /************************************************************************/
    2537                 : /*                            OGR_G_Union()                             */
    2538                 : /************************************************************************/
    2539                 : 
    2540                 : /**
    2541                 :  * \brief Compute union.
    2542                 :  *
    2543                 :  * Generates a new geometry which is the region of union of the
    2544                 :  * two geometries operated on.  
    2545                 :  *
    2546                 :  * This function is the same as the C++ method OGRGeometry::Union().
    2547                 :  *
    2548                 :  * This function is built on the GEOS library, check it for the definition
    2549                 :  * of the geometry operation.
    2550                 :  * If OGR is built without the GEOS library, this function will always fail, 
    2551                 :  * issuing a CPLE_NotSupported error. 
    2552                 :  *
    2553                 :  * @param hThis the geometry.
    2554                 :  * @param hOther the other geometry.
    2555                 :  *
    2556                 :  * @return a new geometry representing the union or NULL if an error occurs.
    2557                 :  */
    2558                 : 
    2559               3 : OGRGeometryH OGR_G_Union( OGRGeometryH hThis, OGRGeometryH hOther )
    2560                 : 
    2561                 : {
    2562               3 :     VALIDATE_POINTER1( hThis, "OGR_G_Union", NULL );
    2563                 : 
    2564                 :     return (OGRGeometryH) 
    2565               3 :         ((OGRGeometry *) hThis)->Union( (OGRGeometry *) hOther );
    2566                 : }
    2567                 : 
    2568                 : /************************************************************************/
    2569                 : /*                               UnionCascaded()                        */
    2570                 : /************************************************************************/
    2571                 : 
    2572                 : /**
    2573                 :  * \brief Compute union using cascading.
    2574                 :  *
    2575                 :  * This method is the same as the C function OGR_G_UnionCascaded().
    2576                 :  *
    2577                 :  * This method is built on the GEOS library, check it for the definition
    2578                 :  * of the geometry operation.
    2579                 :  * If OGR is built without the GEOS library, this method will always fail, 
    2580                 :  * issuing a CPLE_NotSupported error. 
    2581                 :  *
    2582                 :  * @return a new geometry representing the union or NULL if an error occurs.
    2583                 :  *
    2584                 :  * @since OGR 1.8.0
    2585                 :  */
    2586                 : 
    2587               1 : OGRGeometry *OGRGeometry::UnionCascaded() const
    2588                 : 
    2589                 : {
    2590                 : #ifndef HAVE_GEOS
    2591                 : 
    2592                 :     CPLError( CE_Failure, CPLE_NotSupported, 
    2593                 :               "GEOS support not enabled." );
    2594                 :     return NULL;
    2595                 : 
    2596                 : /* GEOS >= 3.1.0 */
    2597                 : #elif GEOS_VERSION_MAJOR > 3 || (GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR >= 1)
    2598                 : 
    2599               1 :     GEOSGeom hThisGeosGeom = NULL;
    2600               1 :     GEOSGeom hGeosProduct = NULL;
    2601               1 :     OGRGeometry *poOGRProduct = NULL;
    2602                 : 
    2603               1 :     hThisGeosGeom = exportToGEOS();
    2604               1 :     if( hThisGeosGeom != NULL )
    2605                 :     {
    2606               1 :         hGeosProduct = GEOSUnionCascaded( hThisGeosGeom );
    2607               1 :         GEOSGeom_destroy( hThisGeosGeom );
    2608                 : 
    2609               1 :         if( hGeosProduct != NULL )
    2610                 :         {
    2611               1 :             poOGRProduct = OGRGeometryFactory::createFromGEOS(hGeosProduct);
    2612               1 :             if( poOGRProduct != NULL && getSpatialReference() != NULL )
    2613               0 :                 poOGRProduct->assignSpatialReference(getSpatialReference());
    2614               1 :             GEOSGeom_destroy( hGeosProduct );
    2615                 :         }
    2616                 :     }
    2617                 : 
    2618               1 :     return poOGRProduct;
    2619                 : 
    2620                 : #else
    2621                 :     CPLError( CE_Failure, CPLE_NotSupported,
    2622                 :               "GEOS >= 3.1.0 required for UnionCascaded() support." );
    2623                 :     return NULL;
    2624                 : #endif /* HAVE_GEOS */
    2625                 : }
    2626                 : 
    2627                 : /************************************************************************/
    2628                 : /*                            OGR_G_UnionCascaded()                     */
    2629                 : /************************************************************************/
    2630                 : 
    2631                 : /**
    2632                 :  * \brief Compute union using cascading.
    2633                 :  *
    2634                 :  * This function is the same as the C++ method OGRGeometry::UnionCascaded().
    2635                 :  *
    2636                 :  * This function is built on the GEOS library, check it for the definition
    2637                 :  * of the geometry operation.
    2638                 :  * If OGR is built without the GEOS library, this function will always fail, 
    2639                 :  * issuing a CPLE_NotSupported error. 
    2640                 :  *
    2641                 :  * @param hThis the geometry.
    2642                 :  *
    2643                 :  * @return a new geometry representing the union or NULL if an error occurs.
    2644                 :  */
    2645                 : 
    2646               1 : OGRGeometryH OGR_G_UnionCascaded( OGRGeometryH hThis )
    2647                 : 
    2648                 : {
    2649               1 :     VALIDATE_POINTER1( hThis, "OGR_G_UnionCascaded", NULL );
    2650                 : 
    2651                 :     return (OGRGeometryH) 
    2652               1 :         ((OGRGeometry *) hThis)->UnionCascaded();
    2653                 : }
    2654                 : 
    2655                 : /************************************************************************/
    2656                 : /*                             Difference()                             */
    2657                 : /************************************************************************/
    2658                 : 
    2659                 : /**
    2660                 :  * \brief Compute difference.
    2661                 :  *
    2662                 :  * Generates a new geometry which is the region of this geometry with the
    2663                 :  * region of the second geometry removed. 
    2664                 :  *
    2665                 :  * This method is the same as the C function OGR_G_Difference().
    2666                 :  *
    2667                 :  * This method is built on the GEOS library, check it for the definition
    2668                 :  * of the geometry operation.
    2669                 :  * If OGR is built without the GEOS library, this method will always fail, 
    2670                 :  * issuing a CPLE_NotSupported error. 
    2671                 :  *
    2672                 :  * @param poOtherGeom the other geometry removed from "this" geometry.
    2673                 :  *
    2674                 :  * @return a new geometry representing the difference or NULL if the 
    2675                 :  * difference is empty or an error occurs.
    2676                 :  */
    2677                 : 
    2678              15 : OGRGeometry *OGRGeometry::Difference( const OGRGeometry *poOtherGeom ) const
    2679                 : 
    2680                 : {
    2681                 : #ifndef HAVE_GEOS
    2682                 : 
    2683                 :     CPLError( CE_Failure, CPLE_NotSupported, 
    2684                 :               "GEOS support not enabled." );
    2685                 :     return NULL;
    2686                 : 
    2687                 : #else
    2688                 :     
    2689              15 :     GEOSGeom hThisGeosGeom = NULL;
    2690              15 :     GEOSGeom hOtherGeosGeom = NULL;
    2691              15 :     GEOSGeom hGeosProduct = NULL;
    2692              15 :     OGRGeometry *poOGRProduct = NULL;
    2693                 : 
    2694              15 :     hThisGeosGeom = exportToGEOS();
    2695              15 :     hOtherGeosGeom = poOtherGeom->exportToGEOS();
    2696              15 :     if( hThisGeosGeom != NULL && hOtherGeosGeom != NULL )
    2697                 :     {
    2698              15 :         hGeosProduct = GEOSDifference( hThisGeosGeom, hOtherGeosGeom );
    2699                 : 
    2700              15 :         if( hGeosProduct != NULL )
    2701                 :         {
    2702              15 :             poOGRProduct = OGRGeometryFactory::createFromGEOS(hGeosProduct);
    2703              15 :             if( poOGRProduct != NULL && getSpatialReference() != NULL &&
    2704                 :                 poOtherGeom->getSpatialReference() != NULL &&
    2705                 :                 poOtherGeom->getSpatialReference()->IsSame(getSpatialReference()) )
    2706                 :             {
    2707               0 :                 poOGRProduct->assignSpatialReference(getSpatialReference());
    2708                 :             }
    2709              15 :             GEOSGeom_destroy( hGeosProduct );
    2710                 :         }
    2711                 :     }
    2712              15 :     GEOSGeom_destroy( hThisGeosGeom );
    2713              15 :     GEOSGeom_destroy( hOtherGeosGeom );
    2714                 : 
    2715              15 :     return poOGRProduct;
    2716                 : 
    2717                 : #endif /* HAVE_GEOS */
    2718                 : }
    2719                 : 
    2720                 : /************************************************************************/
    2721                 : /*                          OGR_G_Difference()                          */
    2722                 : /************************************************************************/
    2723                 : 
    2724                 : /**
    2725                 :  * \brief Compute difference.
    2726                 :  *
    2727                 :  * Generates a new geometry which is the region of this geometry with the
    2728                 :  * region of the other geometry removed. 
    2729                 :  *
    2730                 :  * This function is the same as the C++ method OGRGeometry::Difference().
    2731                 :  *
    2732                 :  * This function is built on the GEOS library, check it for the definition
    2733                 :  * of the geometry operation.
    2734                 :  * If OGR is built without the GEOS library, this function will always fail, 
    2735                 :  * issuing a CPLE_NotSupported error. 
    2736                 :  *
    2737                 :  * @param hThis the geometry.
    2738                 :  * @param hOther the other geometry.
    2739                 :  *
    2740                 :  * @return a new geometry representing the difference or NULL if the 
    2741                 :  * difference is empty or an error occurs.
    2742                 :  */
    2743                 : 
    2744               1 : OGRGeometryH OGR_G_Difference( OGRGeometryH hThis, OGRGeometryH hOther )
    2745                 : 
    2746                 : {
    2747               1 :     VALIDATE_POINTER1( hThis, "OGR_G_Difference", NULL );
    2748                 : 
    2749                 :     return (OGRGeometryH) 
    2750               1 :         ((OGRGeometry *) hThis)->Difference( (OGRGeometry *) hOther );
    2751                 : }
    2752                 : 
    2753                 : /************************************************************************/
    2754                 : /*                        SymDifference()                               */
    2755                 : /************************************************************************/
    2756                 : 
    2757                 : /**
    2758                 :  * \brief Compute symmetric difference.
    2759                 :  *
    2760                 :  * Generates a new geometry which is the symmetric difference of this
    2761                 :  * geometry and the second geometry passed into the method.
    2762                 :  *
    2763                 :  * This method is the same as the C function OGR_G_SymDifference().
    2764                 :  *
    2765                 :  * This method is built on the GEOS library, check it for the definition
    2766                 :  * of the geometry operation.
    2767                 :  * If OGR is built without the GEOS library, this method will always fail, 
    2768                 :  * issuing a CPLE_NotSupported error. 
    2769                 :  *
    2770                 :  * @param poOtherGeom the other geometry.
    2771                 :  *
    2772                 :  * @return a new geometry representing the symmetric difference or NULL if the 
    2773                 :  * difference is empty or an error occurs.
    2774                 :  *
    2775                 :  * @since OGR 1.8.0
    2776                 :  */
    2777                 : 
    2778                 : OGRGeometry *
    2779               2 : OGRGeometry::SymDifference( const OGRGeometry *poOtherGeom ) const
    2780                 : 
    2781                 : {
    2782                 : #ifndef HAVE_GEOS
    2783                 : 
    2784                 :     CPLError( CE_Failure, CPLE_NotSupported, 
    2785                 :               "GEOS support not enabled." );
    2786                 :     return NULL;
    2787                 : 
    2788                 : #else
    2789                 : 
    2790               2 :     GEOSGeom hThisGeosGeom = NULL;
    2791               2 :     GEOSGeom hOtherGeosGeom = NULL;
    2792               2 :     GEOSGeom hGeosProduct = NULL;
    2793               2 :     OGRGeometry *poOGRProduct = NULL;
    2794                 : 
    2795               2 :     hThisGeosGeom = exportToGEOS();
    2796               2 :     hOtherGeosGeom = poOtherGeom->exportToGEOS();
    2797               2 :     if( hThisGeosGeom != NULL && hOtherGeosGeom != NULL )
    2798                 :     {
    2799               2 :         hGeosProduct = GEOSSymDifference( hThisGeosGeom, hOtherGeosGeom );
    2800                 : 
    2801               2 :         if( hGeosProduct != NULL )
    2802                 :         {
    2803               2 :             poOGRProduct = OGRGeometryFactory::createFromGEOS(hGeosProduct);
    2804               2 :             if( poOGRProduct != NULL && getSpatialReference() != NULL &&
    2805                 :                 poOtherGeom->getSpatialReference() != NULL &&
    2806                 :                 poOtherGeom->getSpatialReference()->IsSame(getSpatialReference()) )
    2807                 :             {
    2808               0 :                 poOGRProduct->assignSpatialReference(getSpatialReference());
    2809                 :             }
    2810               2 :             GEOSGeom_destroy( hGeosProduct );
    2811                 :         }
    2812                 :     }
    2813               2 :     GEOSGeom_destroy( hThisGeosGeom );
    2814               2 :     GEOSGeom_destroy( hOtherGeosGeom );
    2815                 : 
    2816               2 :     return poOGRProduct;
    2817                 : 
    2818                 : #endif /* HAVE_GEOS */
    2819                 : }
    2820                 : 
    2821                 : 
    2822                 : /**
    2823                 :  * \brief Compute symmetric difference (deprecated)
    2824                 :  *
    2825                 :  * @deprecated
    2826                 :  *
    2827                 :  * @see OGRGeometry::SymDifference()
    2828                 :  */
    2829                 : OGRGeometry *
    2830               0 : OGRGeometry::SymmetricDifference( const OGRGeometry *poOtherGeom ) const
    2831                 : 
    2832                 : {
    2833               0 :     return SymDifference( poOtherGeom );
    2834                 : }
    2835                 : 
    2836                 : /************************************************************************/
    2837                 : /*                      OGR_G_SymDifference()                           */
    2838                 : /************************************************************************/
    2839                 : 
    2840                 : /**
    2841                 :  * \brief Compute symmetric difference.
    2842                 :  *
    2843                 :  * Generates a new geometry which is the symmetric difference of this
    2844                 :  * geometry and the other geometry.
    2845                 :  *
    2846                 :  * This function is the same as the C++ method OGRGeometry::SymmetricDifference().
    2847                 :  *
    2848                 :  * This function is built on the GEOS library, check it for the definition
    2849                 :  * of the geometry operation.
    2850                 :  * If OGR is built without the GEOS library, this function will always fail, 
    2851                 :  * issuing a CPLE_NotSupported error. 
    2852                 :  *
    2853                 :  * @param hThis the geometry.
    2854                 :  * @param hOther the other geometry.
    2855                 :  *
    2856                 :  * @return a new geometry representing the symmetric difference or NULL if the 
    2857                 :  * difference is empty or an error occurs.
    2858                 :  *
    2859                 :  * @since OGR 1.8.0
    2860                 :  */
    2861                 : 
    2862               2 : OGRGeometryH OGR_G_SymDifference( OGRGeometryH hThis, OGRGeometryH hOther )
    2863                 : 
    2864                 : {
    2865               2 :     VALIDATE_POINTER1( hThis, "OGR_G_SymDifference", NULL );
    2866                 : 
    2867                 :     return (OGRGeometryH) 
    2868               2 :         ((OGRGeometry *) hThis)->SymDifference( (OGRGeometry *) hOther );
    2869                 : }
    2870                 : 
    2871                 : /**
    2872                 :  * \brief Compute symmetric difference (deprecated)
    2873                 :  *
    2874                 :  * @deprecated
    2875                 :  *
    2876                 :  * @see OGR_G_SymmetricDifference()
    2877                 :  */
    2878               0 : OGRGeometryH OGR_G_SymmetricDifference( OGRGeometryH hThis, OGRGeometryH hOther )
    2879                 : 
    2880                 : {
    2881               0 :     VALIDATE_POINTER1( hThis, "OGR_G_SymmetricDifference", NULL );
    2882                 : 
    2883                 :     return (OGRGeometryH) 
    2884               0 :         ((OGRGeometry *) hThis)->SymDifference( (OGRGeometry *) hOther );
    2885                 : }
    2886                 : 
    2887                 : /************************************************************************/
    2888                 : /*                              Disjoint()                              */
    2889                 : /************************************************************************/
    2890                 : 
    2891                 : /**
    2892                 :  * \brief Test for disjointness.
    2893                 :  *
    2894                 :  * Tests if this geometry and the other passed into the method are disjoint. 
    2895                 :  *
    2896                 :  * This method is the same as the C function OGR_G_Disjoint().
    2897                 :  *
    2898                 :  * This method is built on the GEOS library, check it for the definition
    2899                 :  * of the geometry operation.
    2900                 :  * If OGR is built without the GEOS library, this method will always fail, 
    2901                 :  * issuing a CPLE_NotSupported error. 
    2902                 :  *
    2903                 :  * @param poOtherGeom the geometry to compare to this geometry.
    2904                 :  *
    2905                 :  * @return TRUE if they are disjoint, otherwise FALSE.  
    2906                 :  */
    2907                 : 
    2908                 : OGRBoolean
    2909               2 : OGRGeometry::Disjoint( const OGRGeometry *poOtherGeom ) const
    2910                 : 
    2911                 : {
    2912                 : #ifndef HAVE_GEOS
    2913                 : 
    2914                 :     CPLError( CE_Failure, CPLE_NotSupported, 
    2915                 :               "GEOS support not enabled." );
    2916                 :     return FALSE;
    2917                 : 
    2918                 : #else
    2919                 : 
    2920               2 :     GEOSGeom hThisGeosGeom = NULL;
    2921               2 :     GEOSGeom hOtherGeosGeom = NULL;
    2922               2 :     OGRBoolean bResult = FALSE;
    2923                 : 
    2924               2 :     hThisGeosGeom = exportToGEOS();
    2925               2 :     hOtherGeosGeom = poOtherGeom->exportToGEOS();
    2926               2 :     if( hThisGeosGeom != NULL && hOtherGeosGeom != NULL )
    2927                 :     {
    2928               2 :         bResult = GEOSDisjoint( hThisGeosGeom, hOtherGeosGeom );
    2929                 :     }
    2930               2 :     GEOSGeom_destroy( hThisGeosGeom );
    2931               2 :     GEOSGeom_destroy( hOtherGeosGeom );
    2932                 : 
    2933               2 :     return bResult;
    2934                 : 
    2935                 : #endif /* HAVE_GEOS */
    2936                 : }
    2937                 : 
    2938                 : /************************************************************************/
    2939                 : /*                           OGR_G_Disjoint()                           */
    2940                 : /************************************************************************/
    2941                 : 
    2942                 : /**
    2943                 :  * \brief Test for disjointness.
    2944                 :  *
    2945                 :  * Tests if this geometry and the other geometry are disjoint. 
    2946                 :  *
    2947                 :  * This function is the same as the C++ method OGRGeometry::Disjoint().
    2948                 :  *
    2949                 :  * This function is built on the GEOS library, check it for the definition
    2950                 :  * of the geometry operation.
    2951                 :  * If OGR is built without the GEOS library, this function will always fail, 
    2952                 :  * issuing a CPLE_NotSupported error. 
    2953                 :  *
    2954                 :  * @param hThis the geometry to compare.
    2955                 :  * @param hOther the other geometry to compare.
    2956                 :  *
    2957                 :  * @return TRUE if they are disjoint, otherwise FALSE.  
    2958                 :  */
    2959               2 : int OGR_G_Disjoint( OGRGeometryH hThis, OGRGeometryH hOther )
    2960                 : 
    2961                 : {
    2962               2 :     VALIDATE_POINTER1( hThis, "OGR_G_Disjoint", FALSE );
    2963                 : 
    2964               2 :     return ((OGRGeometry *) hThis)->Disjoint( (OGRGeometry *) hOther );
    2965                 : }
    2966                 : 
    2967                 : /************************************************************************/
    2968                 : /*                              Touches()                               */
    2969                 : /************************************************************************/
    2970                 : 
    2971                 : /**
    2972                 :  * \brief Test for touching.
    2973                 :  *
    2974                 :  * Tests if this geometry and the other passed into the method are touching.
    2975                 :  *
    2976                 :  * This method is the same as the C function OGR_G_Touches().
    2977                 :  *
    2978                 :  * This method is built on the GEOS library, check it for the definition
    2979                 :  * of the geometry operation.
    2980                 :  * If OGR is built without the GEOS library, this method will always fail, 
    2981                 :  * issuing a CPLE_NotSupported error. 
    2982                 :  *
    2983                 :  * @param poOtherGeom the geometry to compare to this geometry.
    2984                 :  *
    2985                 :  * @return TRUE if they are touching, otherwise FALSE.  
    2986                 :  */
    2987                 : 
    2988                 : OGRBoolean
    2989               2 : OGRGeometry::Touches( const OGRGeometry *poOtherGeom ) const
    2990                 : 
    2991                 : {
    2992                 : #ifndef HAVE_GEOS
    2993                 : 
    2994                 :     CPLError( CE_Failure, CPLE_NotSupported, 
    2995                 :               "GEOS support not enabled." );
    2996                 :     return FALSE;
    2997                 : 
    2998                 : #else
    2999                 : 
    3000               2 :     GEOSGeom hThisGeosGeom = NULL;
    3001               2 :     GEOSGeom hOtherGeosGeom = NULL;
    3002               2 :     OGRBoolean bResult = FALSE;
    3003                 : 
    3004               2 :     hThisGeosGeom = exportToGEOS();
    3005               2 :     hOtherGeosGeom = poOtherGeom->exportToGEOS();
    3006                 : 
    3007               2 :     if( hThisGeosGeom != NULL && hOtherGeosGeom != NULL )
    3008                 :     {
    3009               2 :         bResult = GEOSTouches( hThisGeosGeom, hOtherGeosGeom );
    3010                 :     }
    3011               2 :     GEOSGeom_destroy( hThisGeosGeom );
    3012               2 :     GEOSGeom_destroy( hOtherGeosGeom );
    3013                 : 
    3014               2 :     return bResult;
    3015                 : 
    3016                 : #endif /* HAVE_GEOS */
    3017                 : }
    3018                 : 
    3019                 : /************************************************************************/
    3020                 : /*                           OGR_G_Touches()                            */
    3021                 : /************************************************************************/
    3022                 : /**
    3023                 :  * \brief Test for touching.
    3024                 :  *
    3025                 :  * Tests if this geometry and the other geometry are touching.
    3026                 :  *
    3027                 :  * This function is the same as the C++ method OGRGeometry::Touches().
    3028                 :  *
    3029                 :  * This function is built on the GEOS library, check it for the definition
    3030                 :  * of the geometry operation.
    3031                 :  * If OGR is built without the GEOS library, this function will always fail, 
    3032                 :  * issuing a CPLE_NotSupported error. 
    3033                 :  *
    3034                 :  * @param hThis the geometry to compare.
    3035                 :  * @param hOther the other geometry to compare.
    3036                 :  *
    3037                 :  * @return TRUE if they are touching, otherwise FALSE.  
    3038                 :  */
    3039                 : 
    3040               2 : int OGR_G_Touches( OGRGeometryH hThis, OGRGeometryH hOther )
    3041                 : 
    3042                 : {
    3043               2 :     VALIDATE_POINTER1( hThis, "OGR_G_Touches", FALSE );
    3044                 : 
    3045               2 :     return ((OGRGeometry *) hThis)->Touches( (OGRGeometry *) hOther );
    3046                 : }
    3047                 : 
    3048                 : /************************************************************************/
    3049                 : /*                              Crosses()                               */
    3050                 : /************************************************************************/
    3051                 : 
    3052                 : /**
    3053                 :  * \brief Test for crossing.
    3054                 :  *
    3055                 :  * Tests if this geometry and the other passed into the method are crossing.
    3056                 :  *
    3057                 :  * This method is the same as the C function OGR_G_Crosses().
    3058                 :  *
    3059                 :  * This method is built on the GEOS library, check it for the definition
    3060                 :  * of the geometry operation.
    3061                 :  * If OGR is built without the GEOS library, this method will always fail, 
    3062                 :  * issuing a CPLE_NotSupported error. 
    3063                 :  *
    3064                 :  * @param poOtherGeom the geometry to compare to this geometry.
    3065                 :  *
    3066                 :  * @return TRUE if they are crossing, otherwise FALSE.  
    3067                 :  */
    3068                 : 
    3069                 : OGRBoolean
    3070               2 : OGRGeometry::Crosses( const OGRGeometry *poOtherGeom ) const
    3071                 : 
    3072                 : {
    3073                 : #ifndef HAVE_GEOS
    3074                 : 
    3075                 :     CPLError( CE_Failure, CPLE_NotSupported, 
    3076                 :               "GEOS support not enabled." );
    3077                 :     return FALSE;
    3078                 : 
    3079                 : #else
    3080                 : 
    3081               2 :     GEOSGeom hThisGeosGeom = NULL;
    3082               2 :     GEOSGeom hOtherGeosGeom = NULL;
    3083               2 :     OGRBoolean bResult = FALSE;
    3084                 : 
    3085               2 :     hThisGeosGeom = exportToGEOS();
    3086               2 :     hOtherGeosGeom = poOtherGeom->exportToGEOS();
    3087                 : 
    3088               2 :     if( hThisGeosGeom != NULL && hOtherGeosGeom != NULL )
    3089                 :     {
    3090               2 :         bResult = GEOSCrosses( hThisGeosGeom, hOtherGeosGeom );
    3091                 :     }
    3092               2 :     GEOSGeom_destroy( hThisGeosGeom );
    3093               2 :     GEOSGeom_destroy( hOtherGeosGeom );
    3094                 : 
    3095               2 :     return bResult;
    3096                 : 
    3097                 : #endif /* HAVE_GEOS */
    3098                 : }
    3099                 : 
    3100                 : /************************************************************************/
    3101                 : /*                           OGR_G_Crosses()                            */
    3102                 : /************************************************************************/
    3103                 : /**
    3104                 :  * \brief Test for crossing.
    3105                 :  *
    3106                 :  * Tests if this geometry and the other geometry are crossing.
    3107                 :  *
    3108                 :  * This function is the same as the C++ method OGRGeometry::Crosses().
    3109                 :  *
    3110                 :  * This function is built on the GEOS library, check it for the definition
    3111                 :  * of the geometry operation.
    3112                 :  * If OGR is built without the GEOS library, this function will always fail, 
    3113                 :  * issuing a CPLE_NotSupported error. 
    3114                 :  *
    3115                 :  * @param hThis the geometry to compare.
    3116                 :  * @param hOther the other geometry to compare.
    3117                 :  *
    3118                 :  * @return TRUE if they are crossing, otherwise FALSE.  
    3119                 :  */
    3120                 : 
    3121               2 : int OGR_G_Crosses( OGRGeometryH hThis, OGRGeometryH hOther )
    3122                 : 
    3123                 : {
    3124               2 :     VALIDATE_POINTER1( hThis, "OGR_G_Crosses", FALSE );
    3125                 : 
    3126               2 :     return ((OGRGeometry *) hThis)->Crosses( (OGRGeometry *) hOther );
    3127                 : }
    3128                 : 
    3129                 : /************************************************************************/
    3130                 : /*                               Within()                               */
    3131                 : /************************************************************************/
    3132                 : 
    3133                 : /**
    3134                 :  * \brief Test for containment.
    3135                 :  *
    3136                 :  * Tests if actual geometry object is within the passed geometry.
    3137                 :  *
    3138                 :  * This method is the same as the C function OGR_G_Within().
    3139                 :  *
    3140                 :  * This method is built on the GEOS library, check it for the definition
    3141                 :  * of the geometry operation.
    3142                 :  * If OGR is built without the GEOS library, this method will always fail, 
    3143                 :  * issuing a CPLE_NotSupported error. 
    3144                 :  *
    3145                 :  * @param poOtherGeom the geometry to compare to this geometry.
    3146                 :  *
    3147                 :  * @return TRUE if poOtherGeom is within this geometry, otherwise FALSE.  
    3148                 :  */
    3149                 : 
    3150                 : OGRBoolean
    3151               3 : OGRGeometry::Within( const OGRGeometry *poOtherGeom ) const
    3152                 : 
    3153                 : {
    3154                 : #ifndef HAVE_GEOS
    3155                 : 
    3156                 :     CPLError( CE_Failure, CPLE_NotSupported, 
    3157                 :               "GEOS support not enabled." );
    3158                 :     return FALSE;
    3159                 : 
    3160                 : #else
    3161                 : 
    3162               3 :     GEOSGeom hThisGeosGeom = NULL;
    3163               3 :     GEOSGeom hOtherGeosGeom = NULL;
    3164               3 :     OGRBoolean bResult = FALSE;
    3165                 : 
    3166               3 :     hThisGeosGeom = exportToGEOS();
    3167               3 :     hOtherGeosGeom = poOtherGeom->exportToGEOS();
    3168               3 :     if( hThisGeosGeom != NULL && hOtherGeosGeom != NULL )
    3169                 :     {
    3170               3 :         bResult = GEOSWithin( hThisGeosGeom, hOtherGeosGeom );
    3171                 :     }
    3172               3 :     GEOSGeom_destroy( hThisGeosGeom );
    3173               3 :     GEOSGeom_destroy( hOtherGeosGeom );
    3174                 : 
    3175               3 :     return bResult;
    3176                 : 
    3177                 : #endif /* HAVE_GEOS */
    3178                 : }
    3179                 : 
    3180                 : /************************************************************************/
    3181                 : /*                            OGR_G_Within()                            */
    3182                 : /************************************************************************/
    3183                 : 
    3184                 : /**
    3185                 :  * \brief Test for containment.
    3186                 :  *
    3187                 :  * Tests if this geometry is within the other geometry.
    3188                 :  *
    3189                 :  * This function is the same as the C++ method OGRGeometry::Within().
    3190                 :  *
    3191                 :  * This function is built on the GEOS library, check it for the definition
    3192                 :  * of the geometry operation.
    3193                 :  * If OGR is built without the GEOS library, this function will always fail, 
    3194                 :  * issuing a CPLE_NotSupported error. 
    3195                 :  *
    3196                 :  * @param hThis the geometry to compare.
    3197                 :  * @param hOther the other geometry to compare.
    3198                 :  *
    3199                 :  * @return TRUE if hThis is within hOther, otherwise FALSE.  
    3200                 :  */
    3201               3 : int OGR_G_Within( OGRGeometryH hThis, OGRGeometryH hOther )
    3202                 : 
    3203                 : {
    3204               3 :     VALIDATE_POINTER1( hThis, "OGR_G_Within", FALSE );
    3205                 : 
    3206               3 :     return ((OGRGeometry *) hThis)->Within( (OGRGeometry *) hOther );
    3207                 : }
    3208                 : 
    3209                 : /************************************************************************/
    3210                 : /*                              Contains()                              */
    3211                 : /************************************************************************/
    3212                 : 
    3213                 : /**
    3214                 :  * \brief Test for containment.
    3215                 :  *
    3216                 :  * Tests if actual geometry object contains the passed geometry.
    3217                 :  *
    3218                 :  * This method is the same as the C function OGR_G_Contains().
    3219                 :  *
    3220                 :  * This method is built on the GEOS library, check it for the definition
    3221                 :  * of the geometry operation.
    3222                 :  * If OGR is built without the GEOS library, this method will always fail, 
    3223                 :  * issuing a CPLE_NotSupported error. 
    3224                 :  *
    3225                 :  * @param poOtherGeom the geometry to compare to this geometry.
    3226                 :  *
    3227                 :  * @return TRUE if poOtherGeom contains this geometry, otherwise FALSE.  
    3228                 :  */
    3229                 : 
    3230                 : OGRBoolean
    3231               2 : OGRGeometry::Contains( const OGRGeometry *poOtherGeom ) const
    3232                 : 
    3233                 : {
    3234                 : #ifndef HAVE_GEOS
    3235                 : 
    3236                 :     CPLError( CE_Failure, CPLE_NotSupported, 
    3237                 :               "GEOS support not enabled." );
    3238                 :     return FALSE;
    3239                 : 
    3240                 : #else
    3241                 : 
    3242               2 :     GEOSGeom hThisGeosGeom = NULL;
    3243               2 :     GEOSGeom hOtherGeosGeom = NULL;
    3244               2 :     OGRBoolean bResult = FALSE;
    3245                 : 
    3246               2 :     hThisGeosGeom = exportToGEOS();
    3247               2 :     hOtherGeosGeom = poOtherGeom->exportToGEOS();
    3248               2 :     if( hThisGeosGeom != NULL && hOtherGeosGeom != NULL )
    3249                 :     {
    3250               2 :         bResult = GEOSContains( hThisGeosGeom, hOtherGeosGeom );
    3251                 :     }
    3252               2 :     GEOSGeom_destroy( hThisGeosGeom );
    3253               2 :     GEOSGeom_destroy( hOtherGeosGeom );
    3254                 : 
    3255               2 :     return bResult;
    3256                 : 
    3257                 : #endif /* HAVE_GEOS */
    3258                 : }
    3259                 : 
    3260                 : /************************************************************************/
    3261                 : /*                            OGR_G_Contains()                            */
    3262                 : /************************************************************************/
    3263                 : 
    3264                 : /**
    3265                 :  * \brief Test for containment.
    3266                 :  *
    3267                 :  * Tests if this geometry contains the other geometry.
    3268                 :  *
    3269                 :  * This function is the same as the C++ method OGRGeometry::Contains().
    3270                 :  *
    3271                 :  * This function is built on the GEOS library, check it for the definition
    3272                 :  * of the geometry operation.
    3273                 :  * If OGR is built without the GEOS library, this function will always fail, 
    3274                 :  * issuing a CPLE_NotSupported error. 
    3275                 :  *
    3276                 :  * @param hThis the geometry to compare.
    3277                 :  * @param hOther the other geometry to compare.
    3278                 :  *
    3279                 :  * @return TRUE if hThis contains hOther geometry, otherwise FALSE.  
    3280                 :  */
    3281               2 : int OGR_G_Contains( OGRGeometryH hThis, OGRGeometryH hOther )
    3282                 : 
    3283                 : {
    3284               2 :     VALIDATE_POINTER1( hThis, "OGR_G_Contains", FALSE );
    3285                 : 
    3286               2 :     return ((OGRGeometry *) hThis)->Contains( (OGRGeometry *) hOther );
    3287                 : }
    3288                 : 
    3289                 : /************************************************************************/
    3290                 : /*                              Overlaps()                              */
    3291                 : /************************************************************************/
    3292                 : 
    3293                 : /**
    3294                 :  * \brief Test for overlap.
    3295                 :  *
    3296                 :  * Tests if this geometry and the other passed into the method overlap, that is
    3297                 :  * their intersection has a non-zero area. 
    3298                 :  *
    3299                 :  * This method is the same as the C function OGR_G_Overlaps().
    3300                 :  *
    3301                 :  * This method is built on the GEOS library, check it for the definition
    3302                 :  * of the geometry operation.
    3303                 :  * If OGR is built without the GEOS library, this method will always fail, 
    3304                 :  * issuing a CPLE_NotSupported error. 
    3305                 :  *
    3306                 :  * @param poOtherGeom the geometry to compare to this geometry.
    3307                 :  *
    3308                 :  * @return TRUE if they are overlapping, otherwise FALSE.  
    3309                 :  */
    3310                 : 
    3311                 : OGRBoolean
    3312               2 : OGRGeometry::Overlaps( const OGRGeometry *poOtherGeom ) const
    3313                 : 
    3314                 : {
    3315                 : #ifndef HAVE_GEOS
    3316                 : 
    3317                 :     CPLError( CE_Failure, CPLE_NotSupported, 
    3318                 :               "GEOS support not enabled." );
    3319                 :     return FALSE;
    3320                 : 
    3321                 : #else
    3322                 : 
    3323               2 :     GEOSGeom hThisGeosGeom = NULL;
    3324               2 :     GEOSGeom hOtherGeosGeom = NULL;
    3325               2 :     OGRBoolean bResult = FALSE;
    3326                 : 
    3327               2 :     hThisGeosGeom = exportToGEOS();
    3328               2 :     hOtherGeosGeom = poOtherGeom->exportToGEOS();
    3329               2 :     if( hThisGeosGeom != NULL && hOtherGeosGeom != NULL )
    3330                 :     {
    3331               2 :         bResult = GEOSOverlaps( hThisGeosGeom, hOtherGeosGeom );
    3332                 :     }
    3333               2 :     GEOSGeom_destroy( hThisGeosGeom );
    3334               2 :     GEOSGeom_destroy( hOtherGeosGeom );
    3335                 : 
    3336               2 :     return bResult;
    3337                 : 
    3338                 : #endif /* HAVE_GEOS */
    3339                 : }
    3340                 : 
    3341                 : /************************************************************************/
    3342                 : /*                           OGR_G_Overlaps()                           */
    3343                 : /************************************************************************/
    3344                 : /**
    3345                 :  * \brief Test for overlap.
    3346                 :  *
    3347                 :  * Tests if this geometry and the other geometry overlap, that is their
    3348                 :  * intersection has a non-zero area. 
    3349                 :  *
    3350                 :  * This function is the same as the C++ method OGRGeometry::Overlaps().
    3351                 :  *
    3352                 :  * This function is built on the GEOS library, check it for the definition
    3353                 :  * of the geometry operation.
    3354                 :  * If OGR is built without the GEOS library, this function will always fail, 
    3355                 :  * issuing a CPLE_NotSupported error. 
    3356                 :  *
    3357                 :  * @param hThis the geometry to compare.
    3358                 :  * @param hOther the other geometry to compare.
    3359                 :  *
    3360                 :  * @return TRUE if they are overlapping, otherwise FALSE.  
    3361                 :  */
    3362                 : 
    3363               2 : int OGR_G_Overlaps( OGRGeometryH hThis, OGRGeometryH hOther )
    3364                 : 
    3365                 : {
    3366               2 :     VALIDATE_POINTER1( hThis, "OGR_G_Overlaps", FALSE );
    3367                 : 
    3368               2 :     return ((OGRGeometry *) hThis)->Overlaps( (OGRGeometry *) hOther );
    3369                 : }
    3370                 : 
    3371                 : /************************************************************************/
    3372                 : /*                             closeRings()                             */
    3373                 : /************************************************************************/
    3374                 : 
    3375                 : /**
    3376                 :  * \brief Force rings to be closed.
    3377                 :  *
    3378                 :  * If this geometry, or any contained geometries has polygon rings that 
    3379                 :  * are not closed, they will be closed by adding the starting point at
    3380                 :  * the end. 
    3381                 :  */
    3382                 : 
    3383              16 : void OGRGeometry::closeRings()
    3384                 : 
    3385                 : {
    3386              16 : }
    3387                 : 
    3388                 : /************************************************************************/
    3389                 : /*                          OGR_G_CloseRings()                          */
    3390                 : /************************************************************************/
    3391                 : 
    3392                 : /**
    3393                 :  * \brief Force rings to be closed.
    3394                 :  *
    3395                 :  * If this geometry, or any contained geometries has polygon rings that
    3396                 :  * are not closed, they will be closed by adding the starting point at
    3397                 :  * the end.
    3398                 :  *
    3399                 :  * @param hGeom handle to the geometry.
    3400                 :  */
    3401                 : 
    3402               4 : void OGR_G_CloseRings( OGRGeometryH hGeom )
    3403                 : 
    3404                 : {
    3405               4 :     VALIDATE_POINTER0( hGeom, "OGR_G_CloseRings" );
    3406                 : 
    3407               4 :     ((OGRGeometry *) hGeom)->closeRings();
    3408                 : }
    3409                 : 
    3410                 : /************************************************************************/
    3411                 : /*                              Centroid()                              */
    3412                 : /************************************************************************/
    3413                 : 
    3414                 : /**
    3415                 :  * \brief Compute the geometry centroid.
    3416                 :  *
    3417                 :  * The centroid location is applied to the passed in OGRPoint object.
    3418                 :  * The centroid is not necessarily within the geometry.  
    3419                 :  *
    3420                 :  * This method relates to the SFCOM ISurface::get_Centroid() method
    3421                 :  * however the current implementation based on GEOS can operate on other
    3422                 :  * geometry types such as multipoint, linestring, geometrycollection such as
    3423                 :  * multipolygons.
    3424                 :  * OGC SF SQL 1.1 defines the operation for surfaces (polygons).
    3425                 :  * SQL/MM-Part 3 defines the operation for surfaces and multisurfaces (multipolygons).
    3426                 :  *
    3427                 :  * This function is the same as the C function OGR_G_Centroid().
    3428                 :  *
    3429                 :  * This function is built on the GEOS library, check it for the definition
    3430                 :  * of the geometry operation.
    3431                 :  * If OGR is built without the GEOS library, this function will always fail, 
    3432                 :  * issuing a CPLE_NotSupported error. 
    3433                 :  *
    3434                 :  * @return OGRERR_NONE on success or OGRERR_FAILURE on error.
    3435                 :  *
    3436                 :  * @since OGR 1.8.0 as a OGRGeometry method (previously was restricted to OGRPolygon)
    3437                 :  */
    3438                 : 
    3439               4 : int OGRGeometry::Centroid( OGRPoint *poPoint ) const
    3440                 : 
    3441                 : {
    3442               4 :     if( poPoint == NULL )
    3443               0 :         return OGRERR_FAILURE;
    3444                 : 
    3445                 : #ifndef HAVE_GEOS
    3446                 :     // notdef ... not implemented yet.
    3447                 :     CPLError( CE_Failure, CPLE_NotSupported, 
    3448                 :               "GEOS support not enabled." );
    3449                 :     return OGRERR_FAILURE;
    3450                 : 
    3451                 : #else
    3452                 : 
    3453               4 :     GEOSGeom hThisGeosGeom = NULL;
    3454               4 :     GEOSGeom hOtherGeosGeom = NULL;
    3455                 :     
    3456               4 :     hThisGeosGeom = exportToGEOS();
    3457                 : 
    3458               4 :     if( hThisGeosGeom != NULL )
    3459                 :     {
    3460               4 :       hOtherGeosGeom = GEOSGetCentroid( hThisGeosGeom );
    3461               4 :         GEOSGeom_destroy( hThisGeosGeom );
    3462                 : 
    3463               4 :         if( hOtherGeosGeom == NULL )
    3464               0 :             return OGRERR_FAILURE;
    3465                 : 
    3466                 :         OGRGeometry *poCentroidGeom =
    3467               4 :             OGRGeometryFactory::createFromGEOS( hOtherGeosGeom );
    3468                 : 
    3469               4 :         GEOSGeom_destroy( hOtherGeosGeom );
    3470                 : 
    3471               4 :         if (poCentroidGeom == NULL)
    3472               0 :             return OGRERR_FAILURE;
    3473               4 :         if (wkbFlatten(poCentroidGeom->getGeometryType()) != wkbPoint)
    3474                 :         {
    3475               0 :             delete poCentroidGeom;
    3476               0 :             return OGRERR_FAILURE;
    3477                 :         }
    3478                 : 
    3479               4 :         if( poCentroidGeom != NULL && getSpatialReference() != NULL )
    3480               0 :             poCentroidGeom->assignSpatialReference(getSpatialReference());
    3481                 : 
    3482               4 :         OGRPoint *poCentroid = (OGRPoint *) poCentroidGeom;
    3483               4 :         if( !poCentroid->IsEmpty() )
    3484                 :         {
    3485               3 :             poPoint->setX( poCentroid->getX() );
    3486               3 :             poPoint->setY( poCentroid->getY() );
    3487                 :         }
    3488                 :         else
    3489                 :         {
    3490               1 :             poPoint->empty();
    3491                 :         }
    3492                 : 
    3493               4 :         delete poCentroidGeom;
    3494                 : 
    3495               4 :       return OGRERR_NONE;
    3496                 :     }
    3497                 :     else
    3498                 :     {
    3499               0 :       return OGRERR_FAILURE;
    3500                 :     }
    3501                 : 
    3502                 : #endif /* HAVE_GEOS */
    3503                 : }
    3504                 : 
    3505                 : /************************************************************************/
    3506                 : /*                           OGR_G_Centroid()                           */
    3507                 : /************************************************************************/
    3508                 : 
    3509                 : /**
    3510                 :  * \brief Compute the geometry centroid.
    3511                 :  *
    3512                 :  * The centroid location is applied to the passed in OGRPoint object.
    3513                 :  * The centroid is not necessarily within the geometry.  
    3514                 :  *
    3515                 :  * This method relates to the SFCOM ISurface::get_Centroid() method
    3516                 :  * however the current implementation based on GEOS can operate on other
    3517                 :  * geometry types such as multipoint, linestring, geometrycollection such as
    3518                 :  * multipolygons.
    3519                 :  * OGC SF SQL 1.1 defines the operation for surfaces (polygons).
    3520                 :  * SQL/MM-Part 3 defines the operation for surfaces and multisurfaces (multipolygons).
    3521                 :  *
    3522                 :  * This function is the same as the C++ method OGRGeometry::Centroid().
    3523                 :  *
    3524                 :  * This function is built on the GEOS library, check it for the definition
    3525                 :  * of the geometry operation.
    3526                 :  * If OGR is built without the GEOS library, this function will always fail, 
    3527                 :  * issuing a CPLE_NotSupported error. 
    3528                 :  *
    3529                 :  * @return OGRERR_NONE on success or OGRERR_FAILURE on error.
    3530                 :  */
    3531                 : 
    3532               4 : int OGR_G_Centroid( OGRGeometryH hGeom, OGRGeometryH hCentroidPoint )
    3533                 : 
    3534                 : {
    3535               4 :     VALIDATE_POINTER1( hGeom, "OGR_G_Centroid", OGRERR_FAILURE );
    3536                 : 
    3537               4 :     OGRGeometry *poGeom = ((OGRGeometry *) hGeom);
    3538               4 :     OGRPoint *poCentroid = ((OGRPoint *) hCentroidPoint);
    3539                 :     
    3540               4 :     if( poCentroid == NULL )
    3541               0 :         return OGRERR_FAILURE;
    3542                 : 
    3543               4 :     if( wkbFlatten(poCentroid->getGeometryType()) != wkbPoint )
    3544                 :     {
    3545                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    3546               0 :                   "Passed wrong geometry type as centroid argument." );
    3547               0 :         return OGRERR_FAILURE;
    3548                 :     }
    3549                 : 
    3550               4 :     return poGeom->Centroid( poCentroid );
    3551                 : }
    3552                 : 
    3553                 : /************************************************************************/
    3554                 : /*                        OGR_G_PointOnSurface()                        */
    3555                 : /************************************************************************/
    3556                 : 
    3557                 : /**
    3558                 :  * \brief Returns a point guaranteed to lie on the surface.
    3559                 :  *
    3560                 :  * This method relates to the SFCOM ISurface::get_PointOnSurface() method
    3561                 :  * however the current implementation based on GEOS can operate on other
    3562                 :  * geometry types than the types that are supported by SQL/MM-Part 3 :
    3563                 :  * surfaces (polygons) and multisurfaces (multipolygons).
    3564                 :  *
    3565                 :  * This method is built on the GEOS library, check it for the definition
    3566                 :  * of the geometry operation.
    3567                 :  * If OGR is built without the GEOS library, this method will always fail, 
    3568                 :  * issuing a CPLE_NotSupported error. 
    3569                 :  *
    3570                 :  * @param hGeom the geometry to operate on. 
    3571                 :  * @return a point guaranteed to lie on the surface or NULL if an error
    3572                 :  *         occured.
    3573                 :  *
    3574                 :  * @since OGR 1.10
    3575                 :  */
    3576                 : 
    3577               1 : OGRGeometryH OGR_G_PointOnSurface( OGRGeometryH hGeom )
    3578                 : 
    3579                 : {
    3580               1 :     VALIDATE_POINTER1( hGeom, "OGR_G_PointOnSurface", NULL );
    3581                 : 
    3582                 : #ifndef HAVE_GEOS
    3583                 :     CPLError( CE_Failure, CPLE_NotSupported, 
    3584                 :               "GEOS support not enabled." );
    3585                 :     return NULL;
    3586                 : #else
    3587               1 :     GEOSGeom hThisGeosGeom = NULL;
    3588               1 :     GEOSGeom hOtherGeosGeom = NULL;
    3589               1 :     OGRGeometry* poThis = (OGRGeometry*) hGeom;
    3590                 : 
    3591               1 :     hThisGeosGeom = poThis->exportToGEOS();
    3592                 :  
    3593               1 :     if( hThisGeosGeom != NULL )
    3594                 :     {
    3595               1 :         hOtherGeosGeom = GEOSPointOnSurface( hThisGeosGeom );
    3596               1 :         GEOSGeom_destroy( hThisGeosGeom );
    3597                 : 
    3598               1 :         if( hOtherGeosGeom == NULL )
    3599               0 :             return NULL;
    3600                 : 
    3601                 :         OGRGeometry *poInsidePointGeom = (OGRGeometry *) 
    3602               1 :             OGRGeometryFactory::createFromGEOS( hOtherGeosGeom );
    3603                 :  
    3604               1 :         GEOSGeom_destroy( hOtherGeosGeom );
    3605                 : 
    3606               1 :         if (poInsidePointGeom == NULL)
    3607               0 :             return NULL;
    3608               1 :         if (wkbFlatten(poInsidePointGeom->getGeometryType()) != wkbPoint)
    3609                 :         {
    3610               0 :             delete poInsidePointGeom;
    3611               0 :             return NULL;
    3612                 :         }
    3613                 : 
    3614               1 :         if( poInsidePointGeom != NULL && poThis->getSpatialReference() != NULL )
    3615               0 :             poInsidePointGeom->assignSpatialReference(poThis->getSpatialReference());
    3616                 : 
    3617               1 :         return (OGRGeometryH) poInsidePointGeom;
    3618                 :     }
    3619                 :     else
    3620                 :     {
    3621               0 :         return NULL;
    3622                 :     }
    3623                 : #endif
    3624                 : }
    3625                 : 
    3626                 : /************************************************************************/
    3627                 : /*                              Simplify()                              */
    3628                 : /************************************************************************/
    3629                 : 
    3630                 : /**
    3631                 :  * \brief Simplify the geometry.
    3632                 :  *
    3633                 :  * This function is the same as the C function OGR_G_Simplify().
    3634                 :  *
    3635                 :  * This function is built on the GEOS library, check it for the definition
    3636                 :  * of the geometry operation.
    3637                 :  * If OGR is built without the GEOS library, this function will always fail, 
    3638                 :  * issuing a CPLE_NotSupported error. 
    3639                 :  *
    3640                 :  * @param dTolerance the distance tolerance for the simplification.
    3641                 :  *
    3642                 :  * @return the simplified geometry or NULL if an error occurs.
    3643                 :  *
    3644                 :  * @since OGR 1.8.0
    3645                 :  */
    3646                 : 
    3647               1 : OGRGeometry *OGRGeometry::Simplify(double dTolerance) const
    3648                 : 
    3649                 : {
    3650                 : #ifndef HAVE_GEOS
    3651                 : 
    3652                 :     CPLError( CE_Failure, CPLE_NotSupported, 
    3653                 :               "GEOS support not enabled." );
    3654                 :     return NULL;
    3655                 : 
    3656                 : /* GEOS >= 3.0.0 */
    3657                 : #elif GEOS_CAPI_VERSION_MAJOR >= 2 || (GEOS_CAPI_VERSION_MAJOR == 1 && GEOS_CAPI_VERSION_MINOR >= 4)
    3658                 : 
    3659               1 :     GEOSGeom hThisGeosGeom = NULL;
    3660               1 :     GEOSGeom hGeosProduct = NULL;
    3661               1 :     OGRGeometry *poOGRProduct = NULL;
    3662                 : 
    3663               1 :     hThisGeosGeom = exportToGEOS();
    3664               1 :     if( hThisGeosGeom != NULL ) 
    3665                 :     {
    3666               1 :         hGeosProduct = GEOSSimplify( hThisGeosGeom, dTolerance );
    3667               1 :         GEOSGeom_destroy( hThisGeosGeom );
    3668               1 :         if( hGeosProduct != NULL )
    3669                 :         {
    3670               1 :             poOGRProduct = OGRGeometryFactory::createFromGEOS( hGeosProduct );
    3671               1 :             if( poOGRProduct != NULL && getSpatialReference() != NULL )
    3672               0 :                 poOGRProduct->assignSpatialReference(getSpatialReference());
    3673               1 :             GEOSGeom_destroy( hGeosProduct );
    3674                 :         }
    3675                 :     }
    3676               1 :     return poOGRProduct;
    3677                 : 
    3678                 : #else
    3679                 :     CPLError( CE_Failure, CPLE_NotSupported,
    3680                 :               "GEOS >= 3.0.0 required for Simplify() support." );
    3681                 :     return NULL;
    3682                 : #endif /* HAVE_GEOS */
    3683                 : 
    3684                 : }
    3685                 : 
    3686                 : /************************************************************************/
    3687                 : /*                         OGR_G_Simplify()                             */
    3688                 : /************************************************************************/
    3689                 : 
    3690                 : /**
    3691                 :  * \brief Compute a simplified geometry.
    3692                 :  *
    3693                 :  * This function is the same as the C++ method OGRGeometry::Simplify().
    3694                 :  *
    3695                 :  * This function is built on the GEOS library, check it for the definition
    3696                 :  * of the geometry operation.
    3697                 :  * If OGR is built without the GEOS library, this function will always fail, 
    3698                 :  * issuing a CPLE_NotSupported error. 
    3699                 :  *
    3700                 :  * @param hThis the geometry.
    3701                 :  * @param dTolerance the distance tolerance for the simplification.
    3702                 :  *
    3703                 :  * @return the simplified geometry or NULL if an error occurs.
    3704                 :  *
    3705                 :  * @since OGR 1.8.0
    3706                 :  */
    3707                 : 
    3708               1 : OGRGeometryH OGR_G_Simplify( OGRGeometryH hThis, double dTolerance )
    3709                 : 
    3710                 : {
    3711               1 :     VALIDATE_POINTER1( hThis, "OGR_G_Simplify", NULL );
    3712               1 :     return (OGRGeometryH) ((OGRGeometry *) hThis)->Simplify( dTolerance );
    3713                 : }
    3714                 : 
    3715                 : /************************************************************************/
    3716                 : /*                         SimplifyPreserveTopology()                   */
    3717                 : /************************************************************************/
    3718                 : 
    3719                 : /**
    3720                 :  * \brief Simplify the geometry while preserving topology.
    3721                 :  *
    3722                 :  * This function is the same as the C function OGR_G_SimplifyPreserveTopology().
    3723                 :  *
    3724                 :  * This function is built on the GEOS library, check it for the definition
    3725                 :  * of the geometry operation.
    3726                 :  * If OGR is built without the GEOS library, this function will always fail,
    3727                 :  * issuing a CPLE_NotSupported error.
    3728                 :  *
    3729                 :  * @param dTolerance the distance tolerance for the simplification.
    3730                 :  *
    3731                 :  * @return the simplified geometry or NULL if an error occurs.
    3732                 :  *
    3733                 :  * @since OGR 1.9.0
    3734                 :  */
    3735                 : 
    3736               1 : OGRGeometry *OGRGeometry::SimplifyPreserveTopology(double dTolerance) const
    3737                 : 
    3738                 : {
    3739                 : #ifndef HAVE_GEOS
    3740                 : 
    3741                 :     CPLError( CE_Failure, CPLE_NotSupported,
    3742                 :               "GEOS support not enabled." );
    3743                 :     return NULL;
    3744                 : 
    3745                 : /* GEOS >= 3.0.0 */
    3746                 : #elif GEOS_CAPI_VERSION_MAJOR >= 2 || (GEOS_CAPI_VERSION_MAJOR == 1 && GEOS_CAPI_VERSION_MINOR >= 4)
    3747                 : 
    3748               1 :     GEOSGeom hThisGeosGeom = NULL;
    3749               1 :     GEOSGeom hGeosProduct = NULL;
    3750               1 :     OGRGeometry *poOGRProduct = NULL;
    3751                 : 
    3752               1 :     hThisGeosGeom = exportToGEOS();
    3753               1 :     if( hThisGeosGeom != NULL )
    3754                 :     {
    3755               1 :         hGeosProduct = GEOSTopologyPreserveSimplify( hThisGeosGeom, dTolerance );
    3756               1 :         GEOSGeom_destroy( hThisGeosGeom );
    3757               1 :         if( hGeosProduct != NULL )
    3758                 :         {
    3759               1 :             poOGRProduct = OGRGeometryFactory::createFromGEOS( hGeosProduct );
    3760               1 :             if( poOGRProduct != NULL && getSpatialReference() != NULL )
    3761               0 :                 poOGRProduct->assignSpatialReference(getSpatialReference());
    3762               1 :             GEOSGeom_destroy( hGeosProduct );
    3763                 :         }
    3764                 :     }
    3765               1 :     return poOGRProduct;
    3766                 : 
    3767                 : #else
    3768                 :     CPLError( CE_Failure, CPLE_NotSupported,
    3769                 :               "GEOS >= 3.0.0 required for SimplifyPreserveTopology() support." );
    3770                 :     return NULL;
    3771                 : #endif /* HAVE_GEOS */
    3772                 : 
    3773                 : }
    3774                 : 
    3775                 : /************************************************************************/
    3776                 : /*                     OGR_G_SimplifyPreserveTopology()                 */
    3777                 : /************************************************************************/
    3778                 : 
    3779                 : /**
    3780                 :  * \brief Simplify the geometry while preserving topology.
    3781                 :  *
    3782                 :  * This function is the same as the C++ method OGRGeometry::SimplifyPreserveTopology().
    3783                 :  *
    3784                 :  * This function is built on the GEOS library, check it for the definition
    3785                 :  * of the geometry operation.
    3786                 :  * If OGR is built without the GEOS library, this function will always fail,
    3787                 :  * issuing a CPLE_NotSupported error.
    3788                 :  *
    3789                 :  * @param hThis the geometry.
    3790                 :  * @param dTolerance the distance tolerance for the simplification.
    3791                 :  *
    3792                 :  * @return the simplified geometry or NULL if an error occurs.
    3793                 :  *
    3794                 :  * @since OGR 1.9.0
    3795                 :  */
    3796                 : 
    3797               1 : OGRGeometryH OGR_G_SimplifyPreserveTopology( OGRGeometryH hThis, double dTolerance )
    3798                 : 
    3799                 : {
    3800               1 :     VALIDATE_POINTER1( hThis, "OGR_G_SimplifyPreserveTopology", NULL );
    3801               1 :     return (OGRGeometryH) ((OGRGeometry *) hThis)->SimplifyPreserveTopology( dTolerance );
    3802                 : }
    3803                 : 
    3804                 : /************************************************************************/
    3805                 : /*                             Polygonize()                             */
    3806                 : /************************************************************************/
    3807                 : /* Contributor: Alessandro Furieri, a.furieri@lqt.it                    */
    3808                 : /* Developed for Faunalia (http://www.faunalia.it) with funding from    */
    3809                 : /* Regione Toscana - Settore SISTEMA INFORMATIVO TERRITORIALE ED        */
    3810                 : /*                   AMBIENTALE                                         */
    3811                 : /************************************************************************/
    3812                 : 
    3813                 : /**
    3814                 :  * \brief Polygonizes a set of sparse edges.
    3815                 :  *
    3816                 :  * A new geometry object is created and returned containing a collection
    3817                 :  * of reassembled Polygons: NULL will be returned if the input collection
    3818                 :  * doesn't corresponds to a MultiLinestring, or when reassembling Edges
    3819                 :  * into Polygons is impossible due to topogical inconsistencies.
    3820                 :  *
    3821                 :  * This method is the same as the C function OGR_G_Polygonize().
    3822                 :  *
    3823                 :  * This method is built on the GEOS library, check it for the definition
    3824                 :  * of the geometry operation.
    3825                 :  * If OGR is built without the GEOS library, this method will always fail, 
    3826                 :  * issuing a CPLE_NotSupported error. 
    3827                 :  *
    3828                 :  * @return a newly allocated geometry now owned by the caller, or NULL on failure.
    3829                 :  *
    3830                 :  * @since OGR 1.9.0
    3831                 :  */
    3832                 : 
    3833              66 : OGRGeometry *OGRGeometry::Polygonize() const
    3834                 : 
    3835                 : {
    3836                 : #ifndef HAVE_GEOS
    3837                 : 
    3838                 :     CPLError( CE_Failure, CPLE_NotSupported, 
    3839                 :               "GEOS support not enabled." );
    3840                 :     return NULL;
    3841                 : 
    3842                 : #else
    3843                 : 
    3844              66 :     OGRGeometryCollection *poColl = NULL;
    3845             132 :     if( wkbFlatten(getGeometryType()) == wkbGeometryCollection ||
    3846              66 :         wkbFlatten(getGeometryType()) == wkbMultiLineString )
    3847              66 :         poColl = (OGRGeometryCollection *)this;
    3848                 :     else
    3849               0 :         return NULL;
    3850                 : 
    3851              66 :     int iCount = poColl->getNumGeometries();
    3852                 : 
    3853              66 :     GEOSGeom *hGeosGeomList = NULL;
    3854              66 :     GEOSGeom hGeosPolygs = NULL;
    3855              66 :     OGRGeometry *poPolygsOGRGeom = NULL;
    3856              66 :     int bError = FALSE;
    3857                 : 
    3858              66 :     hGeosGeomList = new GEOSGeom [iCount];
    3859             420 :     for ( int ig = 0; ig < iCount; ig++)
    3860                 :     {
    3861             354 :         GEOSGeom hGeosGeom = NULL;
    3862             354 :         OGRGeometry * poChild = (OGRGeometry*)poColl->getGeometryRef(ig);
    3863             708 :         if( poChild == NULL ||
    3864             354 :             wkbFlatten(poChild->getGeometryType()) != wkbLineString )
    3865               0 :             bError = TRUE;
    3866                 :         else
    3867                 :         {
    3868             354 :             hGeosGeom = poChild->exportToGEOS();
    3869             354 :             if( hGeosGeom == NULL)
    3870               0 :                 bError = TRUE;
    3871                 :         }
    3872             354 :         *(hGeosGeomList + ig) = hGeosGeom;
    3873                 :     }
    3874                 : 
    3875              66 :     if( bError == FALSE )
    3876                 :     {
    3877              66 :         hGeosPolygs = GEOSPolygonize( hGeosGeomList, iCount );
    3878                 : 
    3879              66 :         if( hGeosPolygs != NULL )
    3880                 :         {
    3881              66 :             poPolygsOGRGeom = OGRGeometryFactory::createFromGEOS(hGeosPolygs);
    3882              66 :             if( poPolygsOGRGeom != NULL && getSpatialReference() != NULL )
    3883               0 :                 poPolygsOGRGeom->assignSpatialReference(getSpatialReference());
    3884              66 :             GEOSGeom_destroy( hGeosPolygs);
    3885                 :         }
    3886                 :     }
    3887                 : 
    3888             420 :     for ( int ig = 0; ig < iCount; ig++)
    3889                 :     {
    3890             354 :         GEOSGeom hGeosGeom = *(hGeosGeomList + ig);
    3891             354 :         if( hGeosGeom != NULL)
    3892             354 :             GEOSGeom_destroy( hGeosGeom );
    3893                 :     }
    3894              66 :     delete [] hGeosGeomList;
    3895                 : 
    3896              66 :     return poPolygsOGRGeom;
    3897                 : 
    3898                 : #endif /* HAVE_GEOS */
    3899                 : }
    3900                 : 
    3901                 : /************************************************************************/
    3902                 : /*                          OGR_G_Polygonize()                          */
    3903                 : /************************************************************************/
    3904                 : /**
    3905                 :  * \brief Polygonizes a set of sparse edges.
    3906                 :  *
    3907                 :  * A new geometry object is created and returned containing a collection
    3908                 :  * of reassembled Polygons: NULL will be returned if the input collection
    3909                 :  * doesn't corresponds to a MultiLinestring, or when reassembling Edges
    3910                 :  * into Polygons is impossible due to topogical inconsistencies.  
    3911                 :  *
    3912                 :  * This function is the same as the C++ method OGRGeometry::Polygonize().
    3913                 :  *
    3914                 :  * This function is built on the GEOS library, check it for the definition
    3915                 :  * of the geometry operation.
    3916                 :  * If OGR is built without the GEOS library, this function will always fail, 
    3917                 :  * issuing a CPLE_NotSupported error. 
    3918                 :  *
    3919                 :  * @param hTarget The Geometry to be polygonized.
    3920                 :  *
    3921                 :  * @return a handle to a newly allocated geometry now owned by the caller,
    3922                 :  *         or NULL on failure.
    3923                 :  *
    3924                 :  * @since OGR 1.9.0
    3925                 :  */
    3926                 : 
    3927               0 : OGRGeometryH OGR_G_Polygonize( OGRGeometryH hTarget )
    3928                 : 
    3929                 : {
    3930               0 :     VALIDATE_POINTER1( hTarget, "OGR_G_Polygonize", NULL );
    3931                 : 
    3932               0 :     return (OGRGeometryH) ((OGRGeometry *) hTarget)->Polygonize();
    3933                 : }
    3934                 : 
    3935                 : /************************************************************************/
    3936                 : /*                               swapXY()                               */
    3937                 : /************************************************************************/
    3938                 : 
    3939                 : /**
    3940                 :  * \brief Swap x and y coordinates.
    3941                 :  *
    3942                 :  * @since OGR 1.8.0
    3943                 :  */
    3944                 : 
    3945               0 : void OGRGeometry::swapXY()
    3946                 : 
    3947                 : {
    3948               0 : }
    3949                 : 
    3950                 : /************************************************************************/
    3951                 : /*                        Prepared geometry API                         */
    3952                 : /************************************************************************/
    3953                 : 
    3954                 : /* GEOS >= 3.1.0 for prepared geometries */
    3955                 : #if defined(HAVE_GEOS) && (GEOS_VERSION_MAJOR > 3 || (GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR >= 1))
    3956                 : #define HAVE_GEOS_PREPARED_GEOMETRY
    3957                 : #endif
    3958                 : 
    3959                 : #ifdef HAVE_GEOS_PREPARED_GEOMETRY
    3960                 : struct _OGRPreparedGeometry
    3961                 : {
    3962                 :     GEOSGeom                      hGEOSGeom;
    3963                 :     const GEOSPreparedGeometry*   poPreparedGEOSGeom;
    3964                 : };
    3965                 : #endif
    3966                 : 
    3967                 : /************************************************************************/
    3968                 : /*                       OGRHasPreparedGeometrySupport()                */
    3969                 : /************************************************************************/
    3970                 : 
    3971               0 : int OGRHasPreparedGeometrySupport()
    3972                 : {
    3973                 : #ifdef HAVE_GEOS_PREPARED_GEOMETRY
    3974               0 :     return TRUE;
    3975                 : #else
    3976                 :     return FALSE;
    3977                 : #endif
    3978                 : }
    3979                 : 
    3980                 : /************************************************************************/
    3981                 : /*                         OGRCreatePreparedGeometry()                  */
    3982                 : /************************************************************************/
    3983                 : 
    3984           17766 : OGRPreparedGeometry* OGRCreatePreparedGeometry( const OGRGeometry* poGeom )
    3985                 : {
    3986                 : #ifdef HAVE_GEOS_PREPARED_GEOMETRY
    3987           17766 :     GEOSGeom hGEOSGeom = poGeom->exportToGEOS();
    3988           17766 :     if( hGEOSGeom == NULL )
    3989               0 :         return NULL;
    3990           17766 :     const GEOSPreparedGeometry* poPreparedGEOSGeom = GEOSPrepare(hGEOSGeom);
    3991           17766 :     if( poPreparedGEOSGeom == NULL )
    3992                 :     {
    3993               0 :         GEOSGeom_destroy( hGEOSGeom );
    3994               0 :         return NULL;
    3995                 :     }
    3996                 : 
    3997           17766 :     OGRPreparedGeometry* poPreparedGeom = new OGRPreparedGeometry;
    3998           17766 :     poPreparedGeom->hGEOSGeom = hGEOSGeom;
    3999           17766 :     poPreparedGeom->poPreparedGEOSGeom = poPreparedGEOSGeom;
    4000                 : 
    4001           17766 :     return poPreparedGeom;
    4002                 : #else
    4003                 :     return NULL;
    4004                 : #endif
    4005                 : }
    4006                 : 
    4007                 : /************************************************************************/
    4008                 : /*                        OGRDestroyPreparedGeometry()                  */
    4009                 : /************************************************************************/
    4010                 : 
    4011           17766 : void OGRDestroyPreparedGeometry( OGRPreparedGeometry* poPreparedGeom )
    4012                 : {
    4013                 : #ifdef HAVE_GEOS_PREPARED_GEOMETRY
    4014           17766 :     if( poPreparedGeom != NULL )
    4015                 :     {
    4016           17766 :         GEOSPreparedGeom_destroy(poPreparedGeom->poPreparedGEOSGeom);
    4017           17766 :         GEOSGeom_destroy( poPreparedGeom->hGEOSGeom );
    4018           17766 :         delete poPreparedGeom;
    4019                 :     }
    4020                 : #endif
    4021           17766 : }
    4022                 : 
    4023                 : /************************************************************************/
    4024                 : /*                      OGRPreparedGeometryIntersects()                 */
    4025                 : /************************************************************************/
    4026                 : 
    4027            2891 : int OGRPreparedGeometryIntersects( const OGRPreparedGeometry* poPreparedGeom,
    4028                 :                                    const OGRGeometry* poOtherGeom )
    4029                 : {
    4030                 : #ifdef HAVE_GEOS_PREPARED_GEOMETRY
    4031            2891 :     if( poPreparedGeom == NULL || poOtherGeom == NULL )
    4032               0 :         return FALSE;
    4033                 : 
    4034            2891 :     GEOSGeom hGEOSOtherGeom = poOtherGeom->exportToGEOS();
    4035            2891 :     if( hGEOSOtherGeom == NULL )
    4036               0 :         return FALSE;
    4037                 : 
    4038                 :     int bRet = GEOSPreparedIntersects(poPreparedGeom->poPreparedGEOSGeom,
    4039            2891 :                                       hGEOSOtherGeom);
    4040            2891 :     GEOSGeom_destroy( hGEOSOtherGeom );
    4041                 : 
    4042            2891 :     return bRet;
    4043                 : #else
    4044                 :     return FALSE;
    4045                 : #endif
    4046                 : }

Generated by: LCOV version 1.7