1 : /******************************************************************************
2 : * $Id: ogr_api.cpp 19391 2010-04-12 18:02:38Z 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 2581 : int OGR_G_GetPointCount( OGRGeometryH hGeom )
49 :
50 : {
51 2581 : VALIDATE_POINTER1( hGeom, "OGR_G_GetPointCount", 0 );
52 :
53 2581 : switch( wkbFlatten(((OGRGeometry *) hGeom)->getGeometryType()) )
54 : {
55 : case wkbPoint:
56 408 : return 1;
57 :
58 : case wkbLineString:
59 : {
60 1414 : OGRLineString *poLine = (OGRLineString *) hGeom;
61 1414 : return poLine->getNumPoints();
62 : }
63 :
64 : default:
65 : // autotest/pymod/ogrtest.py calls this method on any geometry. So keep silent
66 : //CPLError(CE_Failure, CPLE_NotSupported, "Incompatible geometry for operation");
67 759 : return 0;
68 : }
69 : }
70 :
71 : /************************************************************************/
72 : /* OGR_G_GetX() */
73 : /************************************************************************/
74 : /**
75 : * \brief Fetch the x coordinate of a point from a geometry.
76 : *
77 : * @param hGeom handle to the geometry from which to get the x coordinate.
78 : * @param i point to get the x coordinate.
79 : * @return the X coordinate of this point.
80 : */
81 :
82 13194 : double OGR_G_GetX( OGRGeometryH hGeom, int i )
83 :
84 : {
85 13194 : VALIDATE_POINTER1( hGeom, "OGR_G_GetX", 0 );
86 :
87 13194 : switch( wkbFlatten(((OGRGeometry *) hGeom)->getGeometryType()) )
88 : {
89 : case wkbPoint:
90 : {
91 276 : if( i == 0 )
92 276 : return ((OGRPoint *) hGeom)->getX();
93 : else
94 : {
95 0 : CPLError(CE_Failure, CPLE_NotSupported, "Only i == 0 is supported");
96 0 : return 0.0;
97 : }
98 : }
99 :
100 : case wkbLineString:
101 12918 : return ((OGRLineString *) hGeom)->getX( i );
102 :
103 : default:
104 0 : CPLError(CE_Failure, CPLE_NotSupported, "Incompatible geometry for operation");
105 0 : return 0.0;
106 : }
107 : }
108 :
109 : /************************************************************************/
110 : /* OGR_G_GetY() */
111 : /************************************************************************/
112 : /**
113 : * \brief Fetch the x coordinate of a point from a geometry.
114 : *
115 : * @param hGeom handle to the geometry from which to get the y coordinate.
116 : * @param i point to get the Y coordinate.
117 : * @return the Y coordinate of this point.
118 : */
119 :
120 13194 : double OGR_G_GetY( OGRGeometryH hGeom, int i )
121 :
122 : {
123 13194 : VALIDATE_POINTER1( hGeom, "OGR_G_GetY", 0 );
124 :
125 13194 : switch( wkbFlatten(((OGRGeometry *) hGeom)->getGeometryType()) )
126 : {
127 : case wkbPoint:
128 : {
129 276 : if( i == 0 )
130 276 : return ((OGRPoint *) hGeom)->getY();
131 : else
132 : {
133 0 : CPLError(CE_Failure, CPLE_NotSupported, "Only i == 0 is supported");
134 0 : return 0.0;
135 : }
136 : }
137 :
138 : case wkbLineString:
139 12918 : return ((OGRLineString *) hGeom)->getY( i );
140 :
141 : default:
142 0 : CPLError(CE_Failure, CPLE_NotSupported, "Incompatible geometry for operation");
143 0 : return 0.0;
144 : }
145 : }
146 :
147 : /************************************************************************/
148 : /* OGR_G_GetZ() */
149 : /************************************************************************/
150 : /**
151 : * \brief Fetch the z coordinate of a point from a geometry.
152 : *
153 : * @param hGeom handle to the geometry from which to get the Z coordinate.
154 : * @param i point to get the Z coordinate.
155 : * @return the Z coordinate of this point.
156 : */
157 :
158 13193 : double OGR_G_GetZ( OGRGeometryH hGeom, int i )
159 :
160 : {
161 13193 : VALIDATE_POINTER1( hGeom, "OGR_G_GetZ", 0 );
162 :
163 13193 : switch( wkbFlatten(((OGRGeometry *) hGeom)->getGeometryType()) )
164 : {
165 : case wkbPoint:
166 : {
167 274 : if( i == 0 )
168 274 : return ((OGRPoint *) hGeom)->getZ();
169 : else
170 : {
171 0 : CPLError(CE_Failure, CPLE_NotSupported, "Only i == 0 is supported");
172 0 : return 0.0;
173 : }
174 : }
175 :
176 : case wkbLineString:
177 12919 : return ((OGRLineString *) hGeom)->getZ( i );
178 :
179 : default:
180 0 : CPLError(CE_Failure, CPLE_NotSupported, "Incompatible geometry for operation");
181 0 : return 0.0;
182 : }
183 : }
184 :
185 : /************************************************************************/
186 : /* OGR_G_GetPoint() */
187 : /************************************************************************/
188 :
189 : /**
190 : * \brief Fetch a point in line string or a point geometry.
191 : *
192 : * @param hGeom handle to the geometry from which to get the coordinates.
193 : * @param i the vertex to fetch, from 0 to getNumPoints()-1, zero for a point.
194 : * @param pdfX value of x coordinate.
195 : * @param pdfY value of y coordinate.
196 : * @param pdfZ value of z coordinate.
197 : */
198 :
199 : void OGR_G_GetPoint( OGRGeometryH hGeom, int i,
200 0 : double *pdfX, double *pdfY, double *pdfZ )
201 :
202 : {
203 0 : VALIDATE_POINTER0( hGeom, "OGR_G_GetPoint" );
204 :
205 0 : switch( wkbFlatten(((OGRGeometry *) hGeom)->getGeometryType()) )
206 : {
207 : case wkbPoint:
208 : {
209 0 : if( i == 0 )
210 : {
211 0 : *pdfX = ((OGRPoint *)hGeom)->getX();
212 0 : *pdfY = ((OGRPoint *)hGeom)->getY();
213 0 : if( pdfZ != NULL )
214 0 : *pdfZ = ((OGRPoint *)hGeom)->getZ();
215 : }
216 : else
217 : {
218 0 : CPLError(CE_Failure, CPLE_NotSupported, "Only i == 0 is supported");
219 : }
220 : }
221 0 : break;
222 :
223 : case wkbLineString:
224 : {
225 0 : *pdfX = ((OGRLineString *) hGeom)->getX( i );
226 0 : *pdfY = ((OGRLineString *) hGeom)->getY( i );
227 0 : if( pdfZ != NULL )
228 0 : *pdfZ = ((OGRLineString *) hGeom)->getZ( i );
229 : }
230 0 : break;
231 :
232 : default:
233 0 : CPLError(CE_Failure, CPLE_NotSupported, "Incompatible geometry for operation");
234 : break;
235 : }
236 : }
237 :
238 : /************************************************************************/
239 : /* OGR_G_SetPoint() */
240 : /************************************************************************/
241 : /**
242 : * \brief Set the location of a vertex in a point or linestring geometry.
243 : *
244 : * If iPoint is larger than the number of existing
245 : * points in the linestring, the point count will be increased to
246 : * accomodate the request.
247 : *
248 : * @param hGeom handle to the geometry to add a vertex to.
249 : * @param i the index of the vertex to assign (zero based) or
250 : * zero for a point.
251 : * @param dfX input X coordinate to assign.
252 : * @param dfY input Y coordinate to assign.
253 : * @param dfZ input Z coordinate to assign (defaults to zero).
254 : */
255 :
256 : void OGR_G_SetPoint( OGRGeometryH hGeom, int i,
257 21519 : double dfX, double dfY, double dfZ )
258 :
259 : {
260 21519 : VALIDATE_POINTER0( hGeom, "OGR_G_SetPoint" );
261 :
262 21519 : switch( wkbFlatten(((OGRGeometry *) hGeom)->getGeometryType()) )
263 : {
264 : case wkbPoint:
265 : {
266 4 : if( i == 0 )
267 : {
268 4 : ((OGRPoint *) hGeom)->setX( dfX );
269 4 : ((OGRPoint *) hGeom)->setY( dfY );
270 4 : ((OGRPoint *) hGeom)->setZ( dfZ );
271 : }
272 : else
273 : {
274 0 : CPLError(CE_Failure, CPLE_NotSupported, "Only i == 0 is supported");
275 : }
276 : }
277 4 : break;
278 :
279 : case wkbLineString:
280 21515 : ((OGRLineString *) hGeom)->setPoint( i, dfX, dfY, dfZ );
281 21515 : break;
282 :
283 : default:
284 0 : CPLError(CE_Failure, CPLE_NotSupported, "Incompatible geometry for operation");
285 : break;
286 : }
287 : }
288 :
289 : /************************************************************************/
290 : /* OGR_G_SetPoint_2D() */
291 : /************************************************************************/
292 : /**
293 : * \brief Set the location of a vertex in a point or linestring geometry.
294 : *
295 : * If iPoint is larger than the number of existing
296 : * points in the linestring, the point count will be increased to
297 : * accomodate the request.
298 : *
299 : * @param hGeom handle to the geometry to add a vertex to.
300 : * @param i the index of the vertex to assign (zero based) or
301 : * zero for a point.
302 : * @param dfX input X coordinate to assign.
303 : * @param dfY input Y coordinate to assign.
304 : */
305 :
306 : void OGR_G_SetPoint_2D( OGRGeometryH hGeom, int i,
307 1256 : double dfX, double dfY )
308 :
309 : {
310 1256 : VALIDATE_POINTER0( hGeom, "OGR_G_SetPoint_2D" );
311 :
312 1256 : switch( wkbFlatten(((OGRGeometry *) hGeom)->getGeometryType()) )
313 : {
314 : case wkbPoint:
315 : {
316 0 : if( i == 0 )
317 : {
318 0 : ((OGRPoint *) hGeom)->setX( dfX );
319 0 : ((OGRPoint *) hGeom)->setY( dfY );
320 : }
321 : else
322 : {
323 0 : CPLError(CE_Failure, CPLE_NotSupported, "Only i == 0 is supported");
324 : }
325 : }
326 0 : break;
327 :
328 : case wkbLineString:
329 1256 : ((OGRLineString *) hGeom)->setPoint( i, dfX, dfY );
330 1256 : break;
331 :
332 : default:
333 0 : CPLError(CE_Failure, CPLE_NotSupported, "Incompatible geometry for operation");
334 : break;
335 : }
336 : }
337 :
338 : /************************************************************************/
339 : /* OGR_G_AddPoint() */
340 : /************************************************************************/
341 : /**
342 : * \brief Add a point to a geometry (line string or point).
343 : *
344 : * The vertex count of the line string is increased by one, and assigned from
345 : * the passed location value.
346 : *
347 : * @param hGeom handle to the geometry to add a point to.
348 : * @param dfX x coordinate of point to add.
349 : * @param dfY y coordinate of point to add.
350 : * @param dfZ z coordinate of point to add.
351 : */
352 :
353 : void OGR_G_AddPoint( OGRGeometryH hGeom,
354 10 : double dfX, double dfY, double dfZ )
355 :
356 : {
357 10 : VALIDATE_POINTER0( hGeom, "OGR_G_AddPoint" );
358 :
359 10 : switch( wkbFlatten(((OGRGeometry *) hGeom)->getGeometryType()) )
360 : {
361 : case wkbPoint:
362 : {
363 0 : ((OGRPoint *) hGeom)->setX( dfX );
364 0 : ((OGRPoint *) hGeom)->setY( dfY );
365 0 : ((OGRPoint *) hGeom)->setZ( dfZ );
366 : }
367 0 : break;
368 :
369 : case wkbLineString:
370 10 : ((OGRLineString *) hGeom)->addPoint( dfX, dfY, dfZ );
371 10 : break;
372 :
373 : default:
374 0 : CPLError(CE_Failure, CPLE_NotSupported, "Incompatible geometry for operation");
375 : break;
376 : }
377 : }
378 :
379 : /************************************************************************/
380 : /* OGR_G_AddPoint() */
381 : /************************************************************************/
382 : /**
383 : * \brief Add a point to a geometry (line string or point).
384 : *
385 : * The vertex count of the line string is increased by one, and assigned from
386 : * the passed location value.
387 : *
388 : * @param hGeom handle to the geometry to add a point to.
389 : * @param dfX x coordinate of point to add.
390 : * @param dfY y coordinate of point to add.
391 : */
392 :
393 : void OGR_G_AddPoint_2D( OGRGeometryH hGeom,
394 225 : double dfX, double dfY )
395 :
396 : {
397 225 : VALIDATE_POINTER0( hGeom, "OGR_G_AddPoint_2D" );
398 :
399 225 : switch( wkbFlatten(((OGRGeometry *) hGeom)->getGeometryType()) )
400 : {
401 : case wkbPoint:
402 : {
403 10 : ((OGRPoint *) hGeom)->setX( dfX );
404 10 : ((OGRPoint *) hGeom)->setY( dfY );
405 : }
406 10 : break;
407 :
408 : case wkbLineString:
409 215 : ((OGRLineString *) hGeom)->addPoint( dfX, dfY );
410 215 : break;
411 :
412 : default:
413 0 : CPLError(CE_Failure, CPLE_NotSupported, "Incompatible geometry for operation");
414 : break;
415 : }
416 : }
417 :
418 : /************************************************************************/
419 : /* OGR_G_GetGeometryCount() */
420 : /************************************************************************/
421 : /**
422 : * \brief Fetch the number of elements in a geometry or number of geometries in container.
423 : *
424 : * Only geometries of type wkbPolygon[25D], wkbMultiPoint[25D], wkbMultiLineString[25D],
425 : * wkbMultiPolygon[25D] or wkbGeometryCollection[25D] may return a valid value.
426 : * Other geometry types will silently return 0.
427 : *
428 : * For a polygon, the returned number is the number of rings (exterior ring + interior rings).
429 : *
430 : * @param hGeom single geometry or geometry container from which to get
431 : * the number of elements.
432 : * @return the number of elements.
433 : */
434 :
435 3353 : int OGR_G_GetGeometryCount( OGRGeometryH hGeom )
436 :
437 : {
438 3353 : VALIDATE_POINTER1( hGeom, "OGR_G_GetGeometryCount", 0 );
439 :
440 3353 : switch( wkbFlatten(((OGRGeometry *) hGeom)->getGeometryType()) )
441 : {
442 : case wkbPolygon:
443 1139 : if( ((OGRPolygon *)hGeom)->getExteriorRing() == NULL )
444 3 : return 0;
445 : else
446 1136 : return ((OGRPolygon *)hGeom)->getNumInteriorRings() + 1;
447 :
448 : case wkbMultiPoint:
449 : case wkbMultiLineString:
450 : case wkbMultiPolygon:
451 : case wkbGeometryCollection:
452 412 : return ((OGRGeometryCollection *)hGeom)->getNumGeometries();
453 :
454 : default:
455 : // autotest/pymod/ogrtest.py calls this method on any geometry. So keep silent
456 : //CPLError(CE_Failure, CPLE_NotSupported, "Incompatible geometry for operation");
457 1802 : return 0;
458 : }
459 : }
460 :
461 : /************************************************************************/
462 : /* OGR_G_GetGeometryRef() */
463 : /************************************************************************/
464 :
465 : /**
466 : * \brief Fetch geometry from a geometry container.
467 : *
468 : * This function returns an handle to a geometry within the container.
469 : * The returned geometry remains owned by the container, and should not be
470 : * modified. The handle is only valid untill the next change to the
471 : * geometry container. Use OGR_G_Clone() to make a copy.
472 : *
473 : * This function relates to the SFCOM
474 : * IGeometryCollection::get_Geometry() method.
475 : *
476 : * This function is the same as the CPP method
477 : * OGRGeometryCollection::getGeometryRef().
478 : *
479 : * For a polygon, OGR_G_GetGeometryRef(iSubGeom) returns the exterior ring
480 : * if iSubGeom == 0, and the interior rings for iSubGeom > 0.
481 : *
482 : * @param hGeom handle to the geometry container from which to get a
483 : * geometry from.
484 : * @param iSubGeom the index of the geometry to fetch, between 0 and
485 : * getNumGeometries() - 1.
486 : * @return handle to the requested geometry.
487 : */
488 :
489 1185 : OGRGeometryH OGR_G_GetGeometryRef( OGRGeometryH hGeom, int iSubGeom )
490 :
491 : {
492 1185 : VALIDATE_POINTER1( hGeom, "OGR_G_GetGeometryRef", NULL );
493 :
494 1185 : switch( wkbFlatten(((OGRGeometry *) hGeom)->getGeometryType()) )
495 : {
496 : case wkbPolygon:
497 665 : if( iSubGeom == 0 )
498 : return (OGRGeometryH)
499 575 : ((OGRPolygon *)hGeom)->getExteriorRing();
500 : else
501 : return (OGRGeometryH)
502 90 : ((OGRPolygon *)hGeom)->getInteriorRing(iSubGeom-1);
503 :
504 : case wkbMultiPoint:
505 : case wkbMultiLineString:
506 : case wkbMultiPolygon:
507 : case wkbGeometryCollection:
508 : return (OGRGeometryH)
509 520 : ((OGRGeometryCollection *)hGeom)->getGeometryRef( iSubGeom );
510 :
511 : default:
512 0 : CPLError(CE_Failure, CPLE_NotSupported, "Incompatible geometry for operation");
513 0 : return 0;
514 : }
515 : }
516 :
517 : /************************************************************************/
518 : /* OGR_G_AddGeometry() */
519 : /************************************************************************/
520 :
521 : /**
522 : * \brief Add a geometry to a geometry container.
523 : *
524 : * Some subclasses of OGRGeometryCollection restrict the types of geometry
525 : * that can be added, and may return an error. The passed geometry is cloned
526 : * to make an internal copy.
527 : *
528 : * There is no SFCOM analog to this method.
529 : *
530 : * This function is the same as the CPP method
531 : * OGRGeometryCollection::addGeometry.
532 : *
533 : * For a polygon, hNewSubGeom must be a linearring. If the polygon is empty,
534 : * the first added subgeometry will be the exterior ring. The next ones will be
535 : * the interior rings.
536 : *
537 : * @param hGeom existing geometry container.
538 : * @param hNewSubGeom geometry to add to the container.
539 : *
540 : * @return OGRERR_NONE if successful, or OGRERR_UNSUPPORTED_GEOMETRY_TYPE if
541 : * the geometry type is illegal for the type of existing geometry.
542 : */
543 :
544 40 : OGRErr OGR_G_AddGeometry( OGRGeometryH hGeom, OGRGeometryH hNewSubGeom )
545 :
546 : {
547 40 : VALIDATE_POINTER1( hGeom, "OGR_G_AddGeometry", OGRERR_UNSUPPORTED_OPERATION );
548 40 : VALIDATE_POINTER1( hNewSubGeom, "OGR_G_AddGeometry", OGRERR_UNSUPPORTED_OPERATION );
549 :
550 40 : switch( wkbFlatten(((OGRGeometry *) hGeom)->getGeometryType()) )
551 : {
552 : case wkbPolygon:
553 : {
554 10 : if( !EQUAL( ((OGRGeometry*) hNewSubGeom)->getGeometryName(), "LINEARRING" ) )
555 : {
556 0 : return OGRERR_UNSUPPORTED_GEOMETRY_TYPE;
557 : }
558 : else
559 : {
560 10 : ((OGRPolygon *)hGeom)->addRing( (OGRLinearRing *) hNewSubGeom );
561 10 : return OGRERR_NONE;
562 : }
563 : }
564 :
565 : case wkbMultiPoint:
566 : case wkbMultiLineString:
567 : case wkbMultiPolygon:
568 : case wkbGeometryCollection:
569 : return ((OGRGeometryCollection *)hGeom)->addGeometry(
570 30 : (OGRGeometry *) hNewSubGeom );
571 :
572 : default:
573 0 : return OGRERR_UNSUPPORTED_OPERATION;
574 : }
575 : }
576 :
577 : /************************************************************************/
578 : /* OGR_G_AddGeometryDirectly() */
579 : /************************************************************************/
580 : /**
581 : * \brief Add a geometry directly to an existing geometry container.
582 : *
583 : * Some subclasses of OGRGeometryCollection restrict the types of geometry
584 : * that can be added, and may return an error. Ownership of the passed
585 : * geometry is taken by the container rather than cloning as addGeometry()
586 : * does.
587 : *
588 : * This function is the same as the CPP method
589 : * OGRGeometryCollection::addGeometryDirectly.
590 : *
591 : * There is no SFCOM analog to this method.
592 : *
593 : * For a polygon, hNewSubGeom must be a linearring. If the polygon is empty,
594 : * the first added subgeometry will be the exterior ring. The next ones will be
595 : * the interior rings.
596 : *
597 : * @param hGeom existing geometry.
598 : * @param hNewSubGeom geometry to add to the existing geometry.
599 : *
600 : * @return OGRERR_NONE if successful, or OGRERR_UNSUPPORTED_GEOMETRY_TYPE if
601 : * the geometry type is illegal for the type of geometry container.
602 : */
603 :
604 : OGRErr OGR_G_AddGeometryDirectly( OGRGeometryH hGeom,
605 273 : OGRGeometryH hNewSubGeom )
606 :
607 : {
608 273 : VALIDATE_POINTER1( hGeom, "OGR_G_AddGeometryDirectly", OGRERR_UNSUPPORTED_OPERATION );
609 273 : VALIDATE_POINTER1( hNewSubGeom, "OGR_G_AddGeometryDirectly", OGRERR_UNSUPPORTED_OPERATION );
610 :
611 273 : switch( wkbFlatten(((OGRGeometry *) hGeom)->getGeometryType()) )
612 : {
613 : case wkbPolygon:
614 : {
615 256 : if( !EQUAL( ((OGRGeometry*) hNewSubGeom)->getGeometryName(), "LINEARRING" ) )
616 : {
617 0 : return OGRERR_UNSUPPORTED_GEOMETRY_TYPE;
618 : }
619 : else
620 : {
621 256 : ((OGRPolygon *)hGeom)->addRingDirectly( (OGRLinearRing *) hNewSubGeom );
622 256 : return OGRERR_NONE;
623 : }
624 : }
625 :
626 : case wkbMultiPoint:
627 : case wkbMultiLineString:
628 : case wkbMultiPolygon:
629 : case wkbGeometryCollection:
630 : return ((OGRGeometryCollection *)hGeom)->addGeometryDirectly(
631 17 : (OGRGeometry *) hNewSubGeom );
632 :
633 : default:
634 0 : return OGRERR_UNSUPPORTED_OPERATION;
635 : }
636 : }
637 :
638 : /************************************************************************/
639 : /* OGR_G_RemoveGeometry() */
640 : /************************************************************************/
641 :
642 : /**
643 : * \brief Remove a geometry from an exiting geometry container.
644 : *
645 : * Removing a geometry will cause the geometry count to drop by one, and all
646 : * "higher" geometries will shuffle down one in index.
647 : *
648 : * There is no SFCOM analog to this method.
649 : *
650 : * This function is the same as the CPP method
651 : * OGRGeometryCollection::removeGeometry().
652 : *
653 : * @param hGeom the existing geometry to delete from.
654 : * @param iGeom the index of the geometry to delete. A value of -1 is a
655 : * special flag meaning that all geometries should be removed.
656 : *
657 : * @param bDelete if TRUE the geometry will be destroyed, otherwise it will
658 : * not. The default is TRUE as the existing geometry is considered to own the
659 : * geometries in it.
660 : *
661 : * @return OGRERR_NONE if successful, or OGRERR_FAILURE if the index is
662 : * out of range.
663 : */
664 :
665 :
666 :
667 0 : OGRErr OGR_G_RemoveGeometry( OGRGeometryH hGeom, int iGeom, int bDelete )
668 :
669 : {
670 0 : VALIDATE_POINTER1( hGeom, "OGR_G_GetArea", 0 );
671 :
672 0 : switch( wkbFlatten(((OGRGeometry *) hGeom)->getGeometryType()) )
673 : {
674 : case wkbPolygon:
675 : {
676 : CPLError( CE_Failure, CPLE_AppDefined,
677 0 : "OGR_G_RemoveGeometry() not supported on polygons yet." );
678 0 : return OGRERR_UNSUPPORTED_OPERATION;
679 : }
680 :
681 : case wkbMultiPoint:
682 : case wkbMultiLineString:
683 : case wkbMultiPolygon:
684 : case wkbGeometryCollection:
685 0 : return ((OGRGeometryCollection *)hGeom)->removeGeometry( iGeom,bDelete);
686 :
687 : default:
688 0 : return OGRERR_UNSUPPORTED_OPERATION;
689 : }
690 : }
691 :
692 : /************************************************************************/
693 : /* OGR_G_GetArea() */
694 : /************************************************************************/
695 :
696 : /**
697 : * \brief Compute geometry area.
698 : *
699 : * Computes the area for an OGRLinearRing, OGRPolygon or OGRMultiPolygon.
700 : * Undefined for all other geometry types (returns zero).
701 : *
702 : * This function utilizes the C++ get_Area() methods such as
703 : * OGRPolygon::get_Area().
704 : *
705 : * @param hGeom the geometry to operate on.
706 : * @return the area or 0.0 for unsupported geometry types.
707 : */
708 :
709 8 : double OGR_G_GetArea( OGRGeometryH hGeom )
710 :
711 : {
712 8 : VALIDATE_POINTER1( hGeom, "OGR_G_GetArea", 0 );
713 :
714 8 : double fArea = 0.0;
715 :
716 8 : switch( wkbFlatten(((OGRGeometry *) hGeom)->getGeometryType()) )
717 : {
718 : case wkbPolygon:
719 4 : fArea = ((OGRPolygon *) hGeom)->get_Area();
720 4 : break;
721 :
722 : case wkbMultiPolygon:
723 1 : fArea = ((OGRMultiPolygon *) hGeom)->get_Area();
724 1 : break;
725 :
726 : case wkbLinearRing:
727 : case wkbLineString:
728 : /* This test below is required to filter out wkbLineString geometries
729 : * not being of type of wkbLinearRing.
730 : */
731 3 : if( EQUAL( ((OGRGeometry*) hGeom)->getGeometryName(), "LINEARRING" ) )
732 : {
733 3 : fArea = ((OGRLinearRing *) hGeom)->get_Area();
734 : }
735 3 : break;
736 :
737 : case wkbGeometryCollection:
738 0 : fArea = ((OGRGeometryCollection *) hGeom)->get_Area();
739 0 : break;
740 :
741 : default:
742 : CPLError( CE_Warning, CPLE_AppDefined,
743 0 : "OGR_G_GetArea() called against non-surface geometry type." );
744 :
745 0 : fArea = 0.0;
746 : }
747 :
748 8 : return fArea;
749 : }
750 :
|