1 : /******************************************************************************
2 : * $Id: ogr_api.cpp 16574 2009-03-14 13:09:10Z rouault $
3 : *
4 : * Project: OpenGIS Simple Features Reference Implementation
5 : * Purpose: C API Functions that don't correspond one-to-one with C++
6 : * methods, such as the "simplified" geometry access functions.
7 : * Author: Frank Warmerdam, warmerdam@pobox.com
8 : *
9 : ******************************************************************************
10 : * Copyright (c) 2002, Frank Warmerdam
11 : *
12 : * Permission is hereby granted, free of charge, to any person obtaining a
13 : * copy of this software and associated documentation files (the "Software"),
14 : * to deal in the Software without restriction, including without limitation
15 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16 : * and/or sell copies of the Software, and to permit persons to whom the
17 : * Software is furnished to do so, subject to the following conditions:
18 : *
19 : * The above copyright notice and this permission notice shall be included
20 : * in all copies or substantial portions of the Software.
21 : *
22 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28 : * DEALINGS IN THE SOFTWARE.
29 : ****************************************************************************/
30 :
31 : #include "ogr_geometry.h"
32 : #include "ogr_api.h"
33 : #include "cpl_error.h"
34 :
35 : /************************************************************************/
36 : /* OGR_G_GetPointCount() */
37 : /************************************************************************/
38 : /**
39 : * \brief Fetch number of points from a geometry.
40 : *
41 : * Only wkbPoint[25D] or wkbLineString[25D] may return a valid value.
42 : * Other geometry types will silently return 0.
43 : *
44 : * @param hGeom handle to the geometry from which to get the number of points.
45 : * @return the number of points.
46 : */
47 :
48 2219 : int OGR_G_GetPointCount( OGRGeometryH hGeom )
49 :
50 : {
51 2219 : switch( wkbFlatten(((OGRGeometry *) hGeom)->getGeometryType()) )
52 : {
53 : case wkbPoint:
54 360 : return 1;
55 :
56 : case wkbLineString:
57 : {
58 1204 : OGRLineString *poLine = (OGRLineString *) hGeom;
59 1204 : return poLine->getNumPoints();
60 : }
61 :
62 : default:
63 : // autotest/pymod/ogrtest.py calls this method on any geometry. So keep silent
64 : //CPLError(CE_Failure, CPLE_NotSupported, "Incompatible geometry for operation");
65 655 : return 0;
66 : }
67 : }
68 :
69 : /************************************************************************/
70 : /* OGR_G_GetX() */
71 : /************************************************************************/
72 : /**
73 : * \brief Fetch the x coordinate of a point from a geometry.
74 : *
75 : * @param hGeom handle to the geometry from which to get the x coordinate.
76 : * @param i point to get the x coordinate.
77 : * @return the X coordinate of this point.
78 : */
79 :
80 10836 : double OGR_G_GetX( OGRGeometryH hGeom, int i )
81 :
82 : {
83 10836 : switch( wkbFlatten(((OGRGeometry *) hGeom)->getGeometryType()) )
84 : {
85 : case wkbPoint:
86 : {
87 244 : if( i == 0 )
88 244 : return ((OGRPoint *) hGeom)->getX();
89 : else
90 : {
91 0 : CPLError(CE_Failure, CPLE_NotSupported, "Only i == 0 is supported");
92 0 : return 0.0;
93 : }
94 : }
95 :
96 : case wkbLineString:
97 10592 : return ((OGRLineString *) hGeom)->getX( i );
98 :
99 : default:
100 0 : CPLError(CE_Failure, CPLE_NotSupported, "Incompatible geometry for operation");
101 0 : return 0.0;
102 : }
103 : }
104 :
105 : /************************************************************************/
106 : /* OGR_G_GetY() */
107 : /************************************************************************/
108 : /**
109 : * \brief Fetch the x coordinate of a point from a geometry.
110 : *
111 : * @param hGeom handle to the geometry from which to get the y coordinate.
112 : * @param i point to get the Y coordinate.
113 : * @return the Y coordinate of this point.
114 : */
115 :
116 10836 : double OGR_G_GetY( OGRGeometryH hGeom, int i )
117 :
118 : {
119 10836 : switch( wkbFlatten(((OGRGeometry *) hGeom)->getGeometryType()) )
120 : {
121 : case wkbPoint:
122 : {
123 244 : if( i == 0 )
124 244 : return ((OGRPoint *) hGeom)->getY();
125 : else
126 : {
127 0 : CPLError(CE_Failure, CPLE_NotSupported, "Only i == 0 is supported");
128 0 : return 0.0;
129 : }
130 : }
131 :
132 : case wkbLineString:
133 10592 : return ((OGRLineString *) hGeom)->getY( i );
134 :
135 : default:
136 0 : CPLError(CE_Failure, CPLE_NotSupported, "Incompatible geometry for operation");
137 0 : return 0.0;
138 : }
139 : }
140 :
141 : /************************************************************************/
142 : /* OGR_G_GetZ() */
143 : /************************************************************************/
144 : /**
145 : * \brief Fetch the z coordinate of a point from a geometry.
146 : *
147 : * @param hGeom handle to the geometry from which to get the Z coordinate.
148 : * @param i point to get the Z coordinate.
149 : * @return the Z coordinate of this point.
150 : */
151 :
152 10834 : double OGR_G_GetZ( OGRGeometryH hGeom, int i )
153 :
154 : {
155 10834 : switch( wkbFlatten(((OGRGeometry *) hGeom)->getGeometryType()) )
156 : {
157 : case wkbPoint:
158 : {
159 242 : if( i == 0 )
160 242 : return ((OGRPoint *) hGeom)->getZ();
161 : else
162 : {
163 0 : CPLError(CE_Failure, CPLE_NotSupported, "Only i == 0 is supported");
164 0 : return 0.0;
165 : }
166 : }
167 :
168 : case wkbLineString:
169 10592 : return ((OGRLineString *) hGeom)->getZ( i );
170 :
171 : default:
172 0 : CPLError(CE_Failure, CPLE_NotSupported, "Incompatible geometry for operation");
173 0 : return 0.0;
174 : }
175 : }
176 :
177 : /************************************************************************/
178 : /* OGR_G_GetPoint() */
179 : /************************************************************************/
180 :
181 : /**
182 : * \brief Fetch a point in line string or a point geometry.
183 : *
184 : * @param hGeom handle to the geometry from which to get the coordinates.
185 : * @param i the vertex to fetch, from 0 to getNumPoints()-1, zero for a point.
186 : * @param pdfX value of x coordinate.
187 : * @param pdfY value of y coordinate.
188 : * @param pdfZ value of z coordinate.
189 : */
190 :
191 0 : void OGR_G_GetPoint( OGRGeometryH hGeom, int i,
192 : double *pdfX, double *pdfY, double *pdfZ )
193 :
194 : {
195 0 : switch( wkbFlatten(((OGRGeometry *) hGeom)->getGeometryType()) )
196 : {
197 : case wkbPoint:
198 : {
199 0 : if( i == 0 )
200 : {
201 0 : *pdfX = ((OGRPoint *)hGeom)->getX();
202 0 : *pdfY = ((OGRPoint *)hGeom)->getY();
203 0 : if( pdfZ != NULL )
204 0 : *pdfZ = ((OGRPoint *)hGeom)->getZ();
205 : }
206 : else
207 : {
208 0 : CPLError(CE_Failure, CPLE_NotSupported, "Only i == 0 is supported");
209 : }
210 : }
211 0 : break;
212 :
213 : case wkbLineString:
214 : {
215 0 : *pdfX = ((OGRLineString *) hGeom)->getX( i );
216 0 : *pdfY = ((OGRLineString *) hGeom)->getY( i );
217 0 : if( pdfZ != NULL )
218 0 : *pdfZ = ((OGRLineString *) hGeom)->getZ( i );
219 : }
220 0 : break;
221 :
222 : default:
223 0 : CPLError(CE_Failure, CPLE_NotSupported, "Incompatible geometry for operation");
224 : break;
225 : }
226 0 : }
227 :
228 : /************************************************************************/
229 : /* OGR_G_SetPoint() */
230 : /************************************************************************/
231 : /**
232 : * \brief Set the location of a vertex in a point or linestring geometry.
233 : *
234 : * If iPoint is larger than the number of existing
235 : * points in the linestring, the point count will be increased to
236 : * accomodate the request.
237 : *
238 : * @param hGeom handle to the geometry to add a vertex to.
239 : * @param i the index of the vertex to assign (zero based) or
240 : * zero for a point.
241 : * @param dfX input X coordinate to assign.
242 : * @param dfY input Y coordinate to assign.
243 : * @param dfZ input Z coordinate to assign (defaults to zero).
244 : */
245 :
246 4354 : void OGR_G_SetPoint( OGRGeometryH hGeom, int i,
247 : double dfX, double dfY, double dfZ )
248 :
249 : {
250 4354 : switch( wkbFlatten(((OGRGeometry *) hGeom)->getGeometryType()) )
251 : {
252 : case wkbPoint:
253 : {
254 4 : if( i == 0 )
255 : {
256 4 : ((OGRPoint *) hGeom)->setX( dfX );
257 4 : ((OGRPoint *) hGeom)->setY( dfY );
258 4 : ((OGRPoint *) hGeom)->setZ( dfZ );
259 : }
260 : else
261 : {
262 0 : CPLError(CE_Failure, CPLE_NotSupported, "Only i == 0 is supported");
263 : }
264 : }
265 4 : break;
266 :
267 : case wkbLineString:
268 4350 : ((OGRLineString *) hGeom)->setPoint( i, dfX, dfY, dfZ );
269 4350 : break;
270 :
271 : default:
272 0 : CPLError(CE_Failure, CPLE_NotSupported, "Incompatible geometry for operation");
273 : break;
274 : }
275 4354 : }
276 :
277 : /************************************************************************/
278 : /* OGR_G_SetPoint_2D() */
279 : /************************************************************************/
280 : /**
281 : * \brief Set the location of a vertex in a point or linestring geometry.
282 : *
283 : * If iPoint is larger than the number of existing
284 : * points in the linestring, the point count will be increased to
285 : * accomodate the request.
286 : *
287 : * @param hGeom handle to the geometry to add a vertex to.
288 : * @param i the index of the vertex to assign (zero based) or
289 : * zero for a point.
290 : * @param dfX input X coordinate to assign.
291 : * @param dfY input Y coordinate to assign.
292 : */
293 :
294 980 : void OGR_G_SetPoint_2D( OGRGeometryH hGeom, int i,
295 : double dfX, double dfY )
296 :
297 : {
298 980 : switch( wkbFlatten(((OGRGeometry *) hGeom)->getGeometryType()) )
299 : {
300 : case wkbPoint:
301 : {
302 0 : if( i == 0 )
303 : {
304 0 : ((OGRPoint *) hGeom)->setX( dfX );
305 0 : ((OGRPoint *) hGeom)->setY( dfY );
306 : }
307 : else
308 : {
309 0 : CPLError(CE_Failure, CPLE_NotSupported, "Only i == 0 is supported");
310 : }
311 : }
312 0 : break;
313 :
314 : case wkbLineString:
315 980 : ((OGRLineString *) hGeom)->setPoint( i, dfX, dfY );
316 980 : break;
317 :
318 : default:
319 0 : CPLError(CE_Failure, CPLE_NotSupported, "Incompatible geometry for operation");
320 : break;
321 : }
322 980 : }
323 :
324 : /************************************************************************/
325 : /* OGR_G_AddPoint() */
326 : /************************************************************************/
327 : /**
328 : * \brief Add a point to a geometry (line string or point).
329 : *
330 : * The vertex count of the line string is increased by one, and assigned from
331 : * the passed location value.
332 : *
333 : * @param hGeom handle to the geometry to add a point to.
334 : * @param dfX x coordinate of point to add.
335 : * @param dfY y coordinate of point to add.
336 : * @param dfZ z coordinate of point to add.
337 : */
338 :
339 5 : void OGR_G_AddPoint( OGRGeometryH hGeom,
340 : double dfX, double dfY, double dfZ )
341 :
342 : {
343 5 : switch( wkbFlatten(((OGRGeometry *) hGeom)->getGeometryType()) )
344 : {
345 : case wkbPoint:
346 : {
347 0 : ((OGRPoint *) hGeom)->setX( dfX );
348 0 : ((OGRPoint *) hGeom)->setY( dfY );
349 0 : ((OGRPoint *) hGeom)->setZ( dfZ );
350 : }
351 0 : break;
352 :
353 : case wkbLineString:
354 5 : ((OGRLineString *) hGeom)->addPoint( dfX, dfY, dfZ );
355 5 : break;
356 :
357 : default:
358 0 : CPLError(CE_Failure, CPLE_NotSupported, "Incompatible geometry for operation");
359 : break;
360 : }
361 5 : }
362 :
363 : /************************************************************************/
364 : /* OGR_G_AddPoint() */
365 : /************************************************************************/
366 : /**
367 : * \brief Add a point to a geometry (line string or point).
368 : *
369 : * The vertex count of the line string is increased by one, and assigned from
370 : * the passed location value.
371 : *
372 : * @param hGeom handle to the geometry to add a point to.
373 : * @param dfX x coordinate of point to add.
374 : * @param dfY y coordinate of point to add.
375 : */
376 :
377 110 : void OGR_G_AddPoint_2D( OGRGeometryH hGeom,
378 : double dfX, double dfY )
379 :
380 : {
381 110 : switch( wkbFlatten(((OGRGeometry *) hGeom)->getGeometryType()) )
382 : {
383 : case wkbPoint:
384 : {
385 10 : ((OGRPoint *) hGeom)->setX( dfX );
386 10 : ((OGRPoint *) hGeom)->setY( dfY );
387 : }
388 10 : break;
389 :
390 : case wkbLineString:
391 100 : ((OGRLineString *) hGeom)->addPoint( dfX, dfY );
392 100 : break;
393 :
394 : default:
395 0 : CPLError(CE_Failure, CPLE_NotSupported, "Incompatible geometry for operation");
396 : break;
397 : }
398 110 : }
399 :
400 : /************************************************************************/
401 : /* OGR_G_GetGeometryCount() */
402 : /************************************************************************/
403 : /**
404 : * \brief Fetch the number of elements in a geometry or number of geometries in container.
405 : *
406 : * Only geometries of type wkbPolygon[25D], wkbMultiPoint[25D], wkbMultiLineString[25D],
407 : * wkbMultiPolygon[25D] or wkbGeometryCollection[25D] may return a valid value.
408 : * Other geometry types will silently return 0.
409 : *
410 : * @param hGeom single geometry or geometry container from which to get
411 : * the number of elements.
412 : * @return the number of elements.
413 : */
414 :
415 2888 : int OGR_G_GetGeometryCount( OGRGeometryH hGeom )
416 :
417 : {
418 2888 : switch( wkbFlatten(((OGRGeometry *) hGeom)->getGeometryType()) )
419 : {
420 : case wkbPolygon:
421 988 : if( ((OGRPolygon *)hGeom)->getExteriorRing() == NULL )
422 3 : return 0;
423 : else
424 985 : return ((OGRPolygon *)hGeom)->getNumInteriorRings() + 1;
425 :
426 : case wkbMultiPoint:
427 : case wkbMultiLineString:
428 : case wkbMultiPolygon:
429 : case wkbGeometryCollection:
430 344 : return ((OGRGeometryCollection *)hGeom)->getNumGeometries();
431 :
432 : default:
433 : // autotest/pymod/ogrtest.py calls this method on any geometry. So keep silent
434 : //CPLError(CE_Failure, CPLE_NotSupported, "Incompatible geometry for operation");
435 1556 : return 0;
436 : }
437 : }
438 :
439 : /************************************************************************/
440 : /* OGR_G_GetGeometryRef() */
441 : /************************************************************************/
442 :
443 : /**
444 : * \brief Fetch geometry from a geometry container.
445 : *
446 : * This function returns an handle to a geometry within the container.
447 : * The returned geometry remains owned by the container, and should not be
448 : * modified. The handle is only valid untill the next change to the
449 : * geometry container. Use OGR_G_Clone() to make a copy.
450 : *
451 : * This function relates to the SFCOM
452 : * IGeometryCollection::get_Geometry() method.
453 : *
454 : * This function is the same as the CPP method
455 : * OGRGeometryCollection::getGeometryRef().
456 : *
457 : * @param hGeom handle to the geometry container from which to get a
458 : * geometry from.
459 : * @param iSubGeom the index of the geometry to fetch, between 0 and
460 : * getNumGeometries() - 1.
461 : * @return handle to the requested geometry.
462 : */
463 :
464 1002 : OGRGeometryH OGR_G_GetGeometryRef( OGRGeometryH hGeom, int iSubGeom )
465 :
466 : {
467 1002 : switch( wkbFlatten(((OGRGeometry *) hGeom)->getGeometryType()) )
468 : {
469 : case wkbPolygon:
470 576 : if( iSubGeom == 0 )
471 : return (OGRGeometryH)
472 492 : ((OGRPolygon *)hGeom)->getExteriorRing();
473 : else
474 : return (OGRGeometryH)
475 84 : ((OGRPolygon *)hGeom)->getInteriorRing(iSubGeom-1);
476 :
477 : case wkbMultiPoint:
478 : case wkbMultiLineString:
479 : case wkbMultiPolygon:
480 : case wkbGeometryCollection:
481 : return (OGRGeometryH)
482 426 : ((OGRGeometryCollection *)hGeom)->getGeometryRef( iSubGeom );
483 :
484 : default:
485 0 : CPLError(CE_Failure, CPLE_NotSupported, "Incompatible geometry for operation");
486 0 : return 0;
487 : }
488 : }
489 :
490 : /************************************************************************/
491 : /* OGR_G_AddGeometry() */
492 : /************************************************************************/
493 :
494 : /**
495 : * \brief Add a geometry to a geometry container.
496 : *
497 : * Some subclasses of OGRGeometryCollection restrict the types of geometry
498 : * that can be added, and may return an error. The passed geometry is cloned
499 : * to make an internal copy.
500 : *
501 : * There is no SFCOM analog to this method.
502 : *
503 : * This function is the same as the CPP method
504 : * OGRGeometryCollection::addGeometry.
505 : *
506 : * @param hGeom existing geometry container.
507 : * @param hNewSubGeom geometry to add to the container.
508 : *
509 : * @return OGRERR_NONE if successful, or OGRERR_UNSUPPORTED_GEOMETRY_TYPE if
510 : * the geometry type is illegal for the type of existing geometry.
511 : */
512 :
513 38 : OGRErr OGR_G_AddGeometry( OGRGeometryH hGeom, OGRGeometryH hNewSubGeom )
514 :
515 : {
516 38 : switch( wkbFlatten(((OGRGeometry *) hGeom)->getGeometryType()) )
517 : {
518 : case wkbPolygon:
519 : {
520 8 : OGRLinearRing *poRing = (OGRLinearRing *) hNewSubGeom;
521 :
522 16 : if( poRing->WkbSize() != 0
523 8 : || wkbFlatten(poRing->getGeometryType()) != wkbLineString )
524 0 : return OGRERR_UNSUPPORTED_GEOMETRY_TYPE;
525 : else
526 : {
527 8 : ((OGRPolygon *)hGeom)->addRing( poRing );
528 8 : return OGRERR_NONE;
529 : }
530 : }
531 :
532 : case wkbMultiPoint:
533 : case wkbMultiLineString:
534 : case wkbMultiPolygon:
535 : case wkbGeometryCollection:
536 : return ((OGRGeometryCollection *)hGeom)->addGeometry(
537 30 : (OGRGeometry *) hNewSubGeom );
538 :
539 : default:
540 0 : return OGRERR_UNSUPPORTED_OPERATION;
541 : }
542 : }
543 :
544 : /************************************************************************/
545 : /* OGR_G_AddGeometryDirectly() */
546 : /************************************************************************/
547 : /**
548 : * \brief Add a geometry directly to an existing geometry container.
549 : *
550 : * Some subclasses of OGRGeometryCollection restrict the types of geometry
551 : * that can be added, and may return an error. Ownership of the passed
552 : * geometry is taken by the container rather than cloning as addGeometry()
553 : * does.
554 : *
555 : * This function is the same as the CPP method
556 : * OGRGeometryCollection::addGeometryDirectly.
557 : *
558 : * There is no SFCOM analog to this method.
559 : *
560 : * @param hGeom existing geometry.
561 : * @param hNewSubGeom geometry to add to the existing geometry.
562 : *
563 : * @return OGRERR_NONE if successful, or OGRERR_UNSUPPORTED_GEOMETRY_TYPE if
564 : * the geometry type is illegal for the type of geometry container.
565 : */
566 :
567 203 : OGRErr OGR_G_AddGeometryDirectly( OGRGeometryH hGeom,
568 : OGRGeometryH hNewSubGeom )
569 :
570 : {
571 203 : switch( wkbFlatten(((OGRGeometry *) hGeom)->getGeometryType()) )
572 : {
573 : case wkbPolygon:
574 : {
575 186 : OGRLinearRing *poRing = (OGRLinearRing *) hNewSubGeom;
576 :
577 372 : if( poRing->WkbSize() != 0
578 186 : || wkbFlatten(poRing->getGeometryType()) != wkbLineString )
579 0 : return OGRERR_UNSUPPORTED_GEOMETRY_TYPE;
580 : else
581 : {
582 186 : ((OGRPolygon *)hGeom)->addRingDirectly( poRing );
583 186 : return OGRERR_NONE;
584 : }
585 : }
586 :
587 : case wkbMultiPoint:
588 : case wkbMultiLineString:
589 : case wkbMultiPolygon:
590 : case wkbGeometryCollection:
591 : return ((OGRGeometryCollection *)hGeom)->addGeometryDirectly(
592 17 : (OGRGeometry *) hNewSubGeom );
593 :
594 : default:
595 0 : return OGRERR_UNSUPPORTED_OPERATION;
596 : }
597 : }
598 :
599 : /************************************************************************/
600 : /* OGR_G_RemoveGeometry() */
601 : /************************************************************************/
602 :
603 : /**
604 : * \brief Remove a geometry from an exiting geometry container.
605 : *
606 : * Removing a geometry will cause the geometry count to drop by one, and all
607 : * "higher" geometries will shuffle down one in index.
608 : *
609 : * There is no SFCOM analog to this method.
610 : *
611 : * This function is the same as the CPP method
612 : * OGRGeometryCollection::removeGeometry().
613 : *
614 : * @param hGeom the existing geometry to delete from.
615 : * @param iGeom the index of the geometry to delete. A value of -1 is a
616 : * special flag meaning that all geometries should be removed.
617 : *
618 : * @param bDelete if TRUE the geometry will be destroyed, otherwise it will
619 : * not. The default is TRUE as the existing geometry is considered to own the
620 : * geometries in it.
621 : *
622 : * @return OGRERR_NONE if successful, or OGRERR_FAILURE if the index is
623 : * out of range.
624 : */
625 :
626 :
627 :
628 0 : OGRErr OGR_G_RemoveGeometry( OGRGeometryH hGeom, int iGeom, int bDelete )
629 :
630 : {
631 0 : switch( wkbFlatten(((OGRGeometry *) hGeom)->getGeometryType()) )
632 : {
633 : case wkbPolygon:
634 : {
635 : CPLError( CE_Failure, CPLE_AppDefined,
636 0 : "OGR_G_RemoveGeometry() not supported on polygons yet." );
637 0 : return OGRERR_UNSUPPORTED_OPERATION;
638 : }
639 :
640 : case wkbMultiPoint:
641 : case wkbMultiLineString:
642 : case wkbMultiPolygon:
643 : case wkbGeometryCollection:
644 0 : return ((OGRGeometryCollection *)hGeom)->removeGeometry( iGeom,bDelete);
645 :
646 : default:
647 0 : return OGRERR_UNSUPPORTED_OPERATION;
648 : }
649 : }
650 :
651 : /************************************************************************/
652 : /* OGR_G_GetArea() */
653 : /************************************************************************/
654 :
655 : /**
656 : * \brief Compute geometry area.
657 : *
658 : * Computes the area for an OGRLinearRing, OGRPolygon or OGRMultiPolygon.
659 : * Undefined for all other geometry types (returns zero).
660 : *
661 : * This function utilizes the C++ get_Area() methods such as
662 : * OGRPolygon::get_Area().
663 : *
664 : * @param hGeom the geometry to operate on.
665 : * @return the area or 0.0 for unsupported geometry types.
666 : */
667 :
668 7 : double OGR_G_GetArea( OGRGeometryH hGeom )
669 :
670 : {
671 7 : VALIDATE_POINTER1( hGeom, "OGR_G_GetArea", 0 );
672 :
673 7 : double fArea = 0.0;
674 :
675 7 : switch( wkbFlatten(((OGRGeometry *) hGeom)->getGeometryType()) )
676 : {
677 : case wkbPolygon:
678 4 : fArea = ((OGRPolygon *) hGeom)->get_Area();
679 4 : break;
680 :
681 : case wkbMultiPolygon:
682 1 : fArea = ((OGRMultiPolygon *) hGeom)->get_Area();
683 1 : break;
684 :
685 : case wkbLinearRing:
686 : case wkbLineString:
687 : /* This test below is required to filter out wkbLineString geometries
688 : * not being of type of wkbLinearRing.
689 : */
690 2 : if( EQUAL( ((OGRGeometry*) hGeom)->getGeometryName(), "LINEARRING" ) )
691 : {
692 2 : fArea = ((OGRLinearRing *) hGeom)->get_Area();
693 : }
694 2 : break;
695 :
696 : case wkbGeometryCollection:
697 0 : fArea = ((OGRGeometryCollection *) hGeom)->get_Area();
698 0 : break;
699 :
700 : default:
701 : CPLError( CE_Warning, CPLE_AppDefined,
702 0 : "OGR_G_GetArea() called against non-surface geometry type." );
703 :
704 0 : fArea = 0.0;
705 : }
706 :
707 7 : return fArea;
708 : }
709 :
|