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 : }
|