1 /*
2
3 gg_geoscvt.c -- Gaia / GEOS conversion [Geometry]
4
5 version 5.0, 2020 August 1
6
7 Author: Sandro Furieri a.furieri@lqt.it
8
9 ------------------------------------------------------------------------------
10
11 Version: MPL 1.1/GPL 2.0/LGPL 2.1
12
13 The contents of this file are subject to the Mozilla Public License Version
14 1.1 (the "License"); you may not use this file except in compliance with
15 the License. You may obtain a copy of the License at
16 http://www.mozilla.org/MPL/
17
18 Software distributed under the License is distributed on an "AS IS" basis,
19 WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
20 for the specific language governing rights and limitations under the
21 License.
22
23 The Original Code is the SpatiaLite library
24
25 The Initial Developer of the Original Code is Alessandro Furieri
26
27 Portions created by the Initial Developer are Copyright (C) 2008-2021
28 the Initial Developer. All Rights Reserved.
29
30 Contributor(s):
31
32 Alternatively, the contents of this file may be used under the terms of
33 either the GNU General Public License Version 2 or later (the "GPL"), or
34 the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
35 in which case the provisions of the GPL or the LGPL are applicable instead
36 of those above. If you wish to allow use of your version of this file only
37 under the terms of either the GPL or the LGPL, and not to allow others to
38 use your version of this file under the terms of the MPL, indicate your
39 decision by deleting the provisions above and replace them with the notice
40 and other provisions required by the GPL or the LGPL. If you do not delete
41 the provisions above, a recipient may use your version of this file under
42 the terms of any one of the MPL, the GPL or the LGPL.
43
44 */
45
46 #include <sys/types.h>
47 #include <stdlib.h>
48 #include <stdio.h>
49
50 #if defined(_WIN32) && !defined(__MINGW32__)
51 #include "config-msvc.h"
52 #else
53 #include "config.h"
54 #endif
55
56 #ifndef OMIT_GEOS /* including GEOS */
57 #ifdef GEOS_REENTRANT
58 #ifdef GEOS_ONLY_REENTRANT
59 #define GEOS_USE_ONLY_R_API /* only fully thread-safe GEOS API */
60 #endif
61 #endif
62 #include <geos_c.h>
63 #endif
64
65 #include <spatialite_private.h>
66 #include <spatialite/sqlite.h>
67
68 #include <spatialite/gaiageo.h>
69
70 #ifndef OMIT_GEOS /* including GEOS */
71
72 static GEOSGeometry *
toGeosGeometry(const void * cache,GEOSContextHandle_t handle,const gaiaGeomCollPtr gaia,int mode)73 toGeosGeometry (const void *cache, GEOSContextHandle_t handle,
74 const gaiaGeomCollPtr gaia, int mode)
75 {
76 /* converting a GAIA Geometry into a GEOS Geometry */
77 int pts = 0;
78 int lns = 0;
79 int pgs = 0;
80 int type;
81 int geos_type;
82 unsigned int dims;
83 int iv;
84 int ib;
85 int nItem;
86 double x;
87 double y;
88 double z;
89 double m;
90 double x0 = 0.0;
91 double y0 = 0.0;
92 double z0 = 0.0;
93 gaiaPointPtr pt;
94 gaiaLinestringPtr ln;
95 gaiaPolygonPtr pg;
96 gaiaRingPtr rng;
97 GEOSGeometry *geos = NULL;
98 GEOSGeometry *geos_ext;
99 GEOSGeometry *geos_int;
100 GEOSGeometry *geos_item;
101 GEOSGeometry **geos_holes;
102 GEOSGeometry **geos_coll;
103 GEOSCoordSequence *cs;
104 int ring_points;
105 int n_items;
106
107 #ifdef GEOS_USE_ONLY_R_API /* only fully thread-safe GEOS API */
108 if (handle == NULL)
109 return NULL;
110 #endif
111 if (!gaia)
112 return NULL;
113
114
115 pt = gaia->FirstPoint;
116 while (pt)
117 {
118 /* counting how many POINTs are there */
119 pts++;
120 pt = pt->Next;
121 }
122 ln = gaia->FirstLinestring;
123 while (ln)
124 {
125 /* counting how many LINESTRINGs are there */
126 lns++;
127 ln = ln->Next;
128 }
129 pg = gaia->FirstPolygon;
130 while (pg)
131 {
132 /* counting how many POLYGONs are there */
133 pgs++;
134 pg = pg->Next;
135 }
136 if (mode == GAIA2GEOS_ONLY_POINTS && pts == 0)
137 return NULL;
138 if (mode == GAIA2GEOS_ONLY_LINESTRINGS && lns == 0)
139 return NULL;
140 if (mode == GAIA2GEOS_ONLY_POLYGONS && pgs == 0)
141 return NULL;
142 if (pts == 0 && lns == 0 && pgs == 0)
143 return NULL;
144 else if (pts == 1 && lns == 0 && pgs == 0)
145 {
146 if (gaia->DeclaredType == GAIA_MULTIPOINT)
147 type = GAIA_MULTIPOINT;
148 else if (gaia->DeclaredType == GAIA_GEOMETRYCOLLECTION)
149 type = GAIA_GEOMETRYCOLLECTION;
150 else
151 type = GAIA_POINT;
152 }
153 else if (pts == 0 && lns == 1 && pgs == 0)
154 {
155 if (gaia->DeclaredType == GAIA_MULTILINESTRING)
156 type = GAIA_MULTILINESTRING;
157 else if (gaia->DeclaredType == GAIA_GEOMETRYCOLLECTION)
158 type = GAIA_GEOMETRYCOLLECTION;
159 else
160 type = GAIA_LINESTRING;
161 }
162 else if (pts == 0 && lns == 0 && pgs == 1)
163 {
164 if (gaia->DeclaredType == GAIA_MULTIPOLYGON)
165 type = GAIA_MULTIPOLYGON;
166 else if (gaia->DeclaredType == GAIA_GEOMETRYCOLLECTION)
167 type = GAIA_GEOMETRYCOLLECTION;
168 else
169 type = GAIA_POLYGON;
170 }
171 else if (pts > 1 && lns == 0 && pgs == 0)
172 {
173 if (gaia->DeclaredType == GAIA_GEOMETRYCOLLECTION)
174 type = GAIA_GEOMETRYCOLLECTION;
175 else
176 type = GAIA_MULTIPOINT;
177 }
178 else if (pts == 0 && lns > 1 && pgs == 0)
179 {
180 if (gaia->DeclaredType == GAIA_GEOMETRYCOLLECTION)
181 type = GAIA_GEOMETRYCOLLECTION;
182 else
183 type = GAIA_MULTILINESTRING;
184 }
185 else if (pts == 0 && lns == 0 && pgs > 1)
186 {
187 if (gaia->DeclaredType == GAIA_GEOMETRYCOLLECTION)
188 type = GAIA_GEOMETRYCOLLECTION;
189 else
190 type = GAIA_MULTIPOLYGON;
191 }
192 else
193 type = GAIA_GEOMETRYCOLLECTION;
194 switch (gaia->DimensionModel)
195 {
196 case GAIA_XY_Z:
197 case GAIA_XY_Z_M:
198 dims = 3;
199 break;
200 default:
201 dims = 2;
202 break;
203 };
204 switch (type)
205 {
206 case GAIA_POINT:
207 if (mode == GAIA2GEOS_ALL || mode == GAIA2GEOS_ONLY_POINTS)
208 {
209 pt = gaia->FirstPoint;
210 if (handle != NULL)
211 {
212 cs = GEOSCoordSeq_create_r (handle, 1, dims);
213 switch (gaia->DimensionModel)
214 {
215 case GAIA_XY_Z:
216 case GAIA_XY_Z_M:
217 GEOSCoordSeq_setX_r (handle, cs, 0, pt->X);
218 GEOSCoordSeq_setY_r (handle, cs, 0, pt->Y);
219 GEOSCoordSeq_setZ_r (handle, cs, 0, pt->Z);
220 break;
221 default:
222 GEOSCoordSeq_setX_r (handle, cs, 0, pt->X);
223 GEOSCoordSeq_setY_r (handle, cs, 0, pt->Y);
224 break;
225 };
226 geos = GEOSGeom_createPoint_r (handle, cs);
227 }
228 else
229 {
230 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
231 cs = GEOSCoordSeq_create (1, dims);
232 switch (gaia->DimensionModel)
233 {
234 case GAIA_XY_Z:
235 case GAIA_XY_Z_M:
236 GEOSCoordSeq_setX (cs, 0, pt->X);
237 GEOSCoordSeq_setY (cs, 0, pt->Y);
238 GEOSCoordSeq_setZ (cs, 0, pt->Z);
239 break;
240 default:
241 GEOSCoordSeq_setX (cs, 0, pt->X);
242 GEOSCoordSeq_setY (cs, 0, pt->Y);
243 break;
244 };
245 geos = GEOSGeom_createPoint (cs);
246 #endif
247 }
248 }
249 break;
250 case GAIA_LINESTRING:
251 if (mode == GAIA2GEOS_ALL || mode == GAIA2GEOS_ONLY_LINESTRINGS)
252 {
253 ln = gaia->FirstLinestring;
254 if (handle != NULL)
255 cs = GEOSCoordSeq_create_r (handle, ln->Points, dims);
256 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
257 else
258 cs = GEOSCoordSeq_create (ln->Points, dims);
259 #endif
260 for (iv = 0; iv < ln->Points; iv++)
261 {
262 switch (ln->DimensionModel)
263 {
264 case GAIA_XY_Z:
265 gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z);
266 if (handle != NULL)
267 {
268 GEOSCoordSeq_setX_r (handle, cs, iv, x);
269 GEOSCoordSeq_setY_r (handle, cs, iv, y);
270 GEOSCoordSeq_setZ_r (handle, cs, iv, z);
271 }
272 else
273 {
274 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
275 GEOSCoordSeq_setX (cs, iv, x);
276 GEOSCoordSeq_setY (cs, iv, y);
277 GEOSCoordSeq_setZ (cs, iv, z);
278 #endif
279 }
280 break;
281 case GAIA_XY_M:
282 gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
283 if (handle != NULL)
284 {
285 GEOSCoordSeq_setX_r (handle, cs, iv, x);
286 GEOSCoordSeq_setY_r (handle, cs, iv, y);
287 }
288 else
289 {
290 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
291 GEOSCoordSeq_setX (cs, iv, x);
292 GEOSCoordSeq_setY (cs, iv, y);
293 #endif
294 }
295 break;
296 case GAIA_XY_Z_M:
297 gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m);
298 if (handle != NULL)
299 {
300 GEOSCoordSeq_setX_r (handle, cs, iv, x);
301 GEOSCoordSeq_setY_r (handle, cs, iv, y);
302 GEOSCoordSeq_setZ_r (handle, cs, iv, z);
303 }
304 else
305 {
306 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
307 GEOSCoordSeq_setX (cs, iv, x);
308 GEOSCoordSeq_setY (cs, iv, y);
309 GEOSCoordSeq_setZ (cs, iv, z);
310 #endif
311 }
312 break;
313 default:
314 gaiaGetPoint (ln->Coords, iv, &x, &y);
315 if (handle != NULL)
316 {
317 GEOSCoordSeq_setX_r (handle, cs, iv, x);
318 GEOSCoordSeq_setY_r (handle, cs, iv, y);
319 }
320 else
321 {
322 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
323 GEOSCoordSeq_setX (cs, iv, x);
324 GEOSCoordSeq_setY (cs, iv, y);
325 #endif
326 }
327 break;
328 };
329 }
330 if (handle != NULL)
331 geos = GEOSGeom_createLineString_r (handle, cs);
332 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
333 else
334 geos = GEOSGeom_createLineString (cs);
335 #endif
336 }
337 break;
338 case GAIA_POLYGON:
339 if (mode == GAIA2GEOS_ALL || mode == GAIA2GEOS_ONLY_POLYGONS)
340 {
341 pg = gaia->FirstPolygon;
342 rng = pg->Exterior;
343 /* exterior ring */
344 ring_points = rng->Points;
345 if (cache)
346 {
347 if (gaiaIsNotClosedRing_r (cache, rng))
348 ring_points++;
349 }
350 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
351 else
352 {
353 if (gaiaIsNotClosedRing (rng))
354 ring_points++;
355 }
356 #endif
357 if (handle != NULL)
358 cs = GEOSCoordSeq_create_r (handle, ring_points, dims);
359 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
360 else
361 cs = GEOSCoordSeq_create (ring_points, dims);
362 #endif
363 for (iv = 0; iv < rng->Points; iv++)
364 {
365 switch (rng->DimensionModel)
366 {
367 case GAIA_XY_Z:
368 gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
369 if (iv == 0)
370 {
371 /* saving the first vertex */
372 x0 = x;
373 y0 = y;
374 z0 = z;
375 }
376 if (handle != NULL)
377 {
378 GEOSCoordSeq_setX_r (handle, cs, iv, x);
379 GEOSCoordSeq_setY_r (handle, cs, iv, y);
380 GEOSCoordSeq_setZ_r (handle, cs, iv, z);
381 }
382 else
383 {
384 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
385 GEOSCoordSeq_setX (cs, iv, x);
386 GEOSCoordSeq_setY (cs, iv, y);
387 GEOSCoordSeq_setZ (cs, iv, z);
388 #endif
389 }
390 break;
391 case GAIA_XY_M:
392 gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
393 if (iv == 0)
394 {
395 /* saving the first vertex */
396 x0 = x;
397 y0 = y;
398 }
399 if (handle != NULL)
400 {
401 GEOSCoordSeq_setX_r (handle, cs, iv, x);
402 GEOSCoordSeq_setY_r (handle, cs, iv, y);
403 }
404 else
405 {
406 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
407 GEOSCoordSeq_setX (cs, iv, x);
408 GEOSCoordSeq_setY (cs, iv, y);
409 #endif
410 }
411 break;
412 case GAIA_XY_Z_M:
413 gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
414 if (iv == 0)
415 {
416 /* saving the first vertex */
417 x0 = x;
418 y0 = y;
419 z0 = z;
420 }
421 if (handle != NULL)
422 {
423 GEOSCoordSeq_setX_r (handle, cs, iv, x);
424 GEOSCoordSeq_setY_r (handle, cs, iv, y);
425 GEOSCoordSeq_setZ_r (handle, cs, iv, z);
426 }
427 else
428 {
429 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
430 GEOSCoordSeq_setX (cs, iv, x);
431 GEOSCoordSeq_setY (cs, iv, y);
432 GEOSCoordSeq_setZ (cs, iv, z);
433 #endif
434 }
435 break;
436 default:
437 gaiaGetPoint (rng->Coords, iv, &x, &y);
438 if (iv == 0)
439 {
440 /* saving the first vertex */
441 x0 = x;
442 y0 = y;
443 }
444 if (handle != NULL)
445 {
446 GEOSCoordSeq_setX_r (handle, cs, iv, x);
447 GEOSCoordSeq_setY_r (handle, cs, iv, y);
448 }
449 else
450 {
451 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
452 GEOSCoordSeq_setX (cs, iv, x);
453 GEOSCoordSeq_setY (cs, iv, y);
454 #endif
455 }
456 break;
457 };
458 }
459 if (ring_points > rng->Points)
460 {
461 /* ensuring Ring's closure */
462 iv = ring_points - 1;
463 switch (rng->DimensionModel)
464 {
465 case GAIA_XY_Z:
466 case GAIA_XY_Z_M:
467 if (handle != NULL)
468 {
469 GEOSCoordSeq_setX_r (handle, cs, iv, x0);
470 GEOSCoordSeq_setY_r (handle, cs, iv, y0);
471 GEOSCoordSeq_setZ_r (handle, cs, iv, z0);
472 }
473 else
474 {
475 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
476 GEOSCoordSeq_setX (cs, iv, x0);
477 GEOSCoordSeq_setY (cs, iv, y0);
478 GEOSCoordSeq_setZ (cs, iv, z0);
479 #endif
480 }
481 break;
482 default:
483 if (handle != NULL)
484 {
485 GEOSCoordSeq_setX_r (handle, cs, iv, x0);
486 GEOSCoordSeq_setY_r (handle, cs, iv, y0);
487 }
488 else
489 {
490 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
491 GEOSCoordSeq_setX (cs, iv, x0);
492 GEOSCoordSeq_setY (cs, iv, y0);
493 #endif
494 }
495 break;
496 };
497 }
498 if (handle != NULL)
499 geos_ext = GEOSGeom_createLinearRing_r (handle, cs);
500 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
501 else
502 geos_ext = GEOSGeom_createLinearRing (cs);
503 #endif
504 geos_holes = NULL;
505 if (pg->NumInteriors > 0)
506 {
507 geos_holes =
508 malloc (sizeof (GEOSGeometry *) * pg->NumInteriors);
509 for (ib = 0; ib < pg->NumInteriors; ib++)
510 {
511 /* interior ring */
512 rng = pg->Interiors + ib;
513 ring_points = rng->Points;
514 if (cache != NULL)
515 {
516 if (gaiaIsNotClosedRing_r (cache, rng))
517 ring_points++;
518 }
519 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
520 else
521 {
522 if (gaiaIsNotClosedRing (rng))
523 ring_points++;
524 }
525 #endif
526 if (handle != NULL)
527 cs = GEOSCoordSeq_create_r (handle, ring_points,
528 dims);
529 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
530 else
531 cs = GEOSCoordSeq_create (ring_points, dims);
532 #endif
533 for (iv = 0; iv < rng->Points; iv++)
534 {
535 switch (rng->DimensionModel)
536 {
537 case GAIA_XY_Z:
538 gaiaGetPointXYZ (rng->Coords, iv, &x,
539 &y, &z);
540 if (iv == 0)
541 {
542 /* saving the first vertex */
543 x0 = x;
544 y0 = y;
545 z0 = z;
546 }
547 if (handle != NULL)
548 {
549 GEOSCoordSeq_setX_r (handle, cs,
550 iv, x);
551 GEOSCoordSeq_setY_r (handle, cs,
552 iv, y);
553 GEOSCoordSeq_setZ_r (handle, cs,
554 iv, z);
555 }
556 else
557 {
558 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
559 GEOSCoordSeq_setX (cs, iv, x);
560 GEOSCoordSeq_setY (cs, iv, y);
561 GEOSCoordSeq_setZ (cs, iv, z);
562 #endif
563 }
564 break;
565 case GAIA_XY_M:
566 gaiaGetPointXYM (rng->Coords, iv, &x,
567 &y, &m);
568 if (iv == 0)
569 {
570 /* saving the first vertex */
571 x0 = x;
572 y0 = y;
573 }
574 if (handle != NULL)
575 {
576 GEOSCoordSeq_setX_r (handle, cs,
577 iv, x);
578 GEOSCoordSeq_setY_r (handle, cs,
579 iv, y);
580 }
581 else
582 {
583 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
584 GEOSCoordSeq_setX (cs, iv, x);
585 GEOSCoordSeq_setY (cs, iv, y);
586 #endif
587 }
588 break;
589 case GAIA_XY_Z_M:
590 gaiaGetPointXYZM (rng->Coords, iv, &x,
591 &y, &z, &m);
592 if (iv == 0)
593 {
594 /* saving the first vertex */
595 x0 = x;
596 y0 = y;
597 z0 = z;
598 }
599 if (handle != NULL)
600 {
601 GEOSCoordSeq_setX_r (handle, cs,
602 iv, x);
603 GEOSCoordSeq_setY_r (handle, cs,
604 iv, y);
605 GEOSCoordSeq_setZ_r (handle, cs,
606 iv, z);
607 }
608 else
609 {
610 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
611 GEOSCoordSeq_setX (cs, iv, x);
612 GEOSCoordSeq_setY (cs, iv, y);
613 GEOSCoordSeq_setZ (cs, iv, z);
614 #endif
615 }
616 break;
617 default:
618 gaiaGetPoint (rng->Coords, iv, &x, &y);
619 if (iv == 0)
620 {
621 /* saving the first vertex */
622 x0 = x;
623 y0 = y;
624 }
625 if (handle != NULL)
626 {
627 GEOSCoordSeq_setX_r (handle, cs,
628 iv, x);
629 GEOSCoordSeq_setY_r (handle, cs,
630 iv, y);
631 }
632 else
633 {
634 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
635 GEOSCoordSeq_setX (cs, iv, x);
636 GEOSCoordSeq_setY (cs, iv, y);
637 #endif
638 }
639 break;
640 };
641 }
642 if (ring_points > rng->Points)
643 {
644 /* ensuring Ring's closure */
645 iv = ring_points - 1;
646 switch (rng->DimensionModel)
647 {
648 case GAIA_XY_Z:
649 case GAIA_XY_Z_M:
650 if (handle != NULL)
651 {
652 GEOSCoordSeq_setX_r (handle, cs,
653 iv, x0);
654 GEOSCoordSeq_setY_r (handle, cs,
655 iv, y0);
656 GEOSCoordSeq_setZ_r (handle, cs,
657 iv, z0);
658 }
659 else
660 {
661 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
662 GEOSCoordSeq_setX (cs, iv, x0);
663 GEOSCoordSeq_setY (cs, iv, y0);
664 GEOSCoordSeq_setZ (cs, iv, z0);
665 #endif
666 }
667 break;
668 default:
669 if (handle != NULL)
670 {
671 GEOSCoordSeq_setX_r (handle, cs,
672 iv, x0);
673 GEOSCoordSeq_setY_r (handle, cs,
674 iv, y0);
675 }
676 else
677 {
678 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
679 GEOSCoordSeq_setX (cs, iv, x0);
680 GEOSCoordSeq_setY (cs, iv, y0);
681 #endif
682 }
683 break;
684 };
685 }
686 if (handle != NULL)
687 geos_int =
688 GEOSGeom_createLinearRing_r (handle, cs);
689 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
690 else
691 geos_int = GEOSGeom_createLinearRing (cs);
692 #endif
693 *(geos_holes + ib) = geos_int;
694 }
695 }
696 if (handle != NULL)
697 geos =
698 GEOSGeom_createPolygon_r (handle, geos_ext, geos_holes,
699 pg->NumInteriors);
700 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
701 else
702 geos =
703 GEOSGeom_createPolygon (geos_ext, geos_holes,
704 pg->NumInteriors);
705 #endif
706 if (geos_holes)
707 free (geos_holes);
708 }
709 break;
710 case GAIA_MULTIPOINT:
711 case GAIA_MULTILINESTRING:
712 case GAIA_MULTIPOLYGON:
713 case GAIA_GEOMETRYCOLLECTION:
714 nItem = 0;
715 if (mode == GAIA2GEOS_ONLY_POINTS)
716 {
717 geos_coll = malloc (sizeof (GEOSGeometry *) * (pts));
718 n_items = pts;
719 }
720 else if (mode == GAIA2GEOS_ONLY_LINESTRINGS)
721 {
722 geos_coll = malloc (sizeof (GEOSGeometry *) * (lns));
723 n_items = lns;
724 }
725 else if (mode == GAIA2GEOS_ONLY_POLYGONS)
726 {
727 geos_coll = malloc (sizeof (GEOSGeometry *) * (pgs));
728 n_items = pgs;
729 }
730 else
731 {
732 geos_coll =
733 malloc (sizeof (GEOSGeometry *) * (pts + lns + pgs));
734 n_items = pts + lns + pgs;
735 }
736 if (mode == GAIA2GEOS_ALL || mode == GAIA2GEOS_ONLY_POINTS)
737 {
738 pt = gaia->FirstPoint;
739 while (pt)
740 {
741 if (handle != NULL)
742 cs = GEOSCoordSeq_create_r (handle, 1, dims);
743 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
744 else
745 cs = GEOSCoordSeq_create (1, dims);
746 #endif
747 switch (pt->DimensionModel)
748 {
749 case GAIA_XY_Z:
750 case GAIA_XY_Z_M:
751 if (handle != NULL)
752 {
753 GEOSCoordSeq_setX_r (handle, cs, 0, pt->X);
754 GEOSCoordSeq_setY_r (handle, cs, 0, pt->Y);
755 GEOSCoordSeq_setZ_r (handle, cs, 0, pt->Z);
756 }
757 else
758 {
759 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
760 GEOSCoordSeq_setX (cs, 0, pt->X);
761 GEOSCoordSeq_setY (cs, 0, pt->Y);
762 GEOSCoordSeq_setZ (cs, 0, pt->Z);
763 #endif
764 }
765 break;
766 default:
767 if (handle != NULL)
768 {
769 GEOSCoordSeq_setX_r (handle, cs, 0, pt->X);
770 GEOSCoordSeq_setY_r (handle, cs, 0, pt->Y);
771 }
772 else
773 {
774 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
775 GEOSCoordSeq_setX (cs, 0, pt->X);
776 GEOSCoordSeq_setY (cs, 0, pt->Y);
777 #endif
778 }
779 break;
780 };
781 if (handle != NULL)
782 geos_item = GEOSGeom_createPoint_r (handle, cs);
783 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
784 else
785 geos_item = GEOSGeom_createPoint (cs);
786 #endif
787 *(geos_coll + nItem++) = geos_item;
788 pt = pt->Next;
789 }
790 }
791 if (mode == GAIA2GEOS_ALL || mode == GAIA2GEOS_ONLY_LINESTRINGS)
792 {
793 ln = gaia->FirstLinestring;
794 while (ln)
795 {
796 if (handle != NULL)
797 cs = GEOSCoordSeq_create_r (handle, ln->Points, dims);
798 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
799 else
800 cs = GEOSCoordSeq_create (ln->Points, dims);
801 #endif
802 for (iv = 0; iv < ln->Points; iv++)
803 {
804 switch (ln->DimensionModel)
805 {
806 case GAIA_XY_Z:
807 gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z);
808 if (handle != NULL)
809 {
810 GEOSCoordSeq_setX_r (handle, cs, iv, x);
811 GEOSCoordSeq_setY_r (handle, cs, iv, y);
812 GEOSCoordSeq_setZ_r (handle, cs, iv, z);
813 }
814 else
815 {
816 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
817 GEOSCoordSeq_setX (cs, iv, x);
818 GEOSCoordSeq_setY (cs, iv, y);
819 GEOSCoordSeq_setZ (cs, iv, z);
820 #endif
821 }
822 break;
823 case GAIA_XY_M:
824 gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
825 if (handle != NULL)
826 {
827 GEOSCoordSeq_setX_r (handle, cs, iv, x);
828 GEOSCoordSeq_setY_r (handle, cs, iv, y);
829 }
830 else
831 {
832 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
833 GEOSCoordSeq_setX (cs, iv, x);
834 GEOSCoordSeq_setY (cs, iv, y);
835 #endif
836 }
837 break;
838 case GAIA_XY_Z_M:
839 gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z,
840 &m);
841 if (handle != NULL)
842 {
843 GEOSCoordSeq_setX_r (handle, cs, iv, x);
844 GEOSCoordSeq_setY_r (handle, cs, iv, y);
845 GEOSCoordSeq_setZ_r (handle, cs, iv, z);
846 }
847 else
848 {
849 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
850 GEOSCoordSeq_setX (cs, iv, x);
851 GEOSCoordSeq_setY (cs, iv, y);
852 GEOSCoordSeq_setZ (cs, iv, z);
853 #endif
854 }
855 break;
856 default:
857 gaiaGetPoint (ln->Coords, iv, &x, &y);
858 if (handle != NULL)
859 {
860 GEOSCoordSeq_setX_r (handle, cs, iv, x);
861 GEOSCoordSeq_setY_r (handle, cs, iv, y);
862 }
863 else
864 {
865 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
866 GEOSCoordSeq_setX (cs, iv, x);
867 GEOSCoordSeq_setY (cs, iv, y);
868 #endif
869 }
870 break;
871 };
872 }
873 if (handle != NULL)
874 geos_item = GEOSGeom_createLineString_r (handle, cs);
875 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
876 else
877 geos_item = GEOSGeom_createLineString (cs);
878 #endif
879 *(geos_coll + nItem++) = geos_item;
880 ln = ln->Next;
881 }
882 }
883 if (mode == GAIA2GEOS_ALL || mode == GAIA2GEOS_ONLY_POLYGONS)
884 {
885 pg = gaia->FirstPolygon;
886 while (pg)
887 {
888 rng = pg->Exterior;
889 /* exterior ring */
890 ring_points = rng->Points;
891 if (cache != NULL)
892 {
893 if (gaiaIsNotClosedRing_r (cache, rng))
894 ring_points++;
895 }
896 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
897 else
898 {
899 if (gaiaIsNotClosedRing (rng))
900 ring_points++;
901 }
902 #endif
903 if (handle != NULL)
904 cs = GEOSCoordSeq_create_r (handle, ring_points,
905 dims);
906 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
907 else
908 cs = GEOSCoordSeq_create (ring_points, dims);
909 #endif
910 for (iv = 0; iv < rng->Points; iv++)
911 {
912 switch (rng->DimensionModel)
913 {
914 case GAIA_XY_Z:
915 gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
916 if (iv == 0)
917 {
918 /* saving the first vertex */
919 x0 = x;
920 y0 = y;
921 z0 = z;
922 }
923 if (handle != NULL)
924 {
925 GEOSCoordSeq_setX_r (handle, cs, iv, x);
926 GEOSCoordSeq_setY_r (handle, cs, iv, y);
927 GEOSCoordSeq_setZ_r (handle, cs, iv, z);
928 }
929 else
930 {
931 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
932 GEOSCoordSeq_setX (cs, iv, x);
933 GEOSCoordSeq_setY (cs, iv, y);
934 GEOSCoordSeq_setZ (cs, iv, z);
935 #endif
936 }
937 break;
938 case GAIA_XY_M:
939 gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
940 if (iv == 0)
941 {
942 /* saving the first vertex */
943 x0 = x;
944 y0 = y;
945 }
946 if (handle != NULL)
947 {
948 GEOSCoordSeq_setX_r (handle, cs, iv, x);
949 GEOSCoordSeq_setY_r (handle, cs, iv, y);
950 }
951 else
952 {
953 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
954 GEOSCoordSeq_setX (cs, iv, x);
955 GEOSCoordSeq_setY (cs, iv, y);
956 #endif
957 }
958 break;
959 case GAIA_XY_Z_M:
960 gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z,
961 &m);
962 if (iv == 0)
963 {
964 /* saving the first vertex */
965 x0 = x;
966 y0 = y;
967 z0 = z;
968 }
969 if (handle != NULL)
970 {
971 GEOSCoordSeq_setX_r (handle, cs, iv, x);
972 GEOSCoordSeq_setY_r (handle, cs, iv, y);
973 GEOSCoordSeq_setZ_r (handle, cs, iv, z);
974 }
975 else
976 {
977 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
978 GEOSCoordSeq_setX (cs, iv, x);
979 GEOSCoordSeq_setY (cs, iv, y);
980 GEOSCoordSeq_setZ (cs, iv, z);
981 #endif
982 }
983 break;
984 default:
985 gaiaGetPoint (rng->Coords, iv, &x, &y);
986 if (iv == 0)
987 {
988 /* saving the first vertex */
989 x0 = x;
990 y0 = y;
991 }
992 if (handle != NULL)
993 {
994 GEOSCoordSeq_setX_r (handle, cs, iv, x);
995 GEOSCoordSeq_setY_r (handle, cs, iv, y);
996 }
997 else
998 {
999 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1000 GEOSCoordSeq_setX (cs, iv, x);
1001 GEOSCoordSeq_setY (cs, iv, y);
1002 #endif
1003 }
1004 break;
1005 };
1006 }
1007 if (ring_points > rng->Points)
1008 {
1009 /* ensuring Ring's closure */
1010 iv = ring_points - 1;
1011 switch (rng->DimensionModel)
1012 {
1013 case GAIA_XY_Z:
1014 case GAIA_XY_Z_M:
1015 if (handle != NULL)
1016 {
1017 GEOSCoordSeq_setX_r (handle, cs, iv,
1018 x0);
1019 GEOSCoordSeq_setY_r (handle, cs, iv,
1020 y0);
1021 GEOSCoordSeq_setZ_r (handle, cs, iv,
1022 z0);
1023 }
1024 else
1025 {
1026 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1027 GEOSCoordSeq_setX (cs, iv, x0);
1028 GEOSCoordSeq_setY (cs, iv, y0);
1029 GEOSCoordSeq_setZ (cs, iv, z0);
1030 #endif
1031 }
1032 break;
1033 default:
1034 if (handle != NULL)
1035 {
1036 GEOSCoordSeq_setX_r (handle, cs, iv,
1037 x0);
1038 GEOSCoordSeq_setY_r (handle, cs, iv,
1039 y0);
1040 }
1041 else
1042 {
1043 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1044 GEOSCoordSeq_setX (cs, iv, x0);
1045 GEOSCoordSeq_setY (cs, iv, y0);
1046 #endif
1047 }
1048 break;
1049 };
1050 }
1051 if (handle != NULL)
1052 geos_ext = GEOSGeom_createLinearRing_r (handle, cs);
1053 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1054 else
1055 geos_ext = GEOSGeom_createLinearRing (cs);
1056 #endif
1057 geos_holes = NULL;
1058 if (pg->NumInteriors > 0)
1059 {
1060 geos_holes =
1061 malloc (sizeof (GEOSGeometry *) *
1062 pg->NumInteriors);
1063 for (ib = 0; ib < pg->NumInteriors; ib++)
1064 {
1065 /* interior ring */
1066 rng = pg->Interiors + ib;
1067 ring_points = rng->Points;
1068 if (cache != NULL)
1069 {
1070 if (gaiaIsNotClosedRing_r (cache, rng))
1071 ring_points++;
1072 }
1073 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1074 else
1075 {
1076 if (gaiaIsNotClosedRing (rng))
1077 ring_points++;
1078 }
1079 #endif
1080 if (handle != NULL)
1081 cs = GEOSCoordSeq_create_r (handle,
1082 ring_points,
1083 dims);
1084 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1085 else
1086 cs = GEOSCoordSeq_create (ring_points,
1087 dims);
1088 #endif
1089 for (iv = 0; iv < rng->Points; iv++)
1090 {
1091 switch (rng->DimensionModel)
1092 {
1093 case GAIA_XY_Z:
1094 gaiaGetPointXYZ (rng->Coords, iv,
1095 &x, &y, &z);
1096 if (iv == 0)
1097 {
1098 /* saving the first vertex */
1099 x0 = x;
1100 y0 = y;
1101 z0 = z;
1102 }
1103 if (handle != NULL)
1104 {
1105 GEOSCoordSeq_setX_r (handle,
1106 cs, iv,
1107 x);
1108 GEOSCoordSeq_setY_r (handle,
1109 cs, iv,
1110 y);
1111 GEOSCoordSeq_setZ_r (handle,
1112 cs, iv,
1113 z);
1114 }
1115 else
1116 {
1117 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1118 GEOSCoordSeq_setX (cs, iv,
1119 x);
1120 GEOSCoordSeq_setY (cs, iv,
1121 y);
1122 GEOSCoordSeq_setZ (cs, iv,
1123 z);
1124 #endif
1125 }
1126 break;
1127 case GAIA_XY_M:
1128 gaiaGetPointXYM (rng->Coords, iv,
1129 &x, &y, &m);
1130 if (iv == 0)
1131 {
1132 /* saving the first vertex */
1133 x0 = x;
1134 y0 = y;
1135 }
1136 if (handle != NULL)
1137 {
1138 GEOSCoordSeq_setX_r (handle,
1139 cs, iv,
1140 x);
1141 GEOSCoordSeq_setY_r (handle,
1142 cs, iv,
1143 y);
1144 }
1145 else
1146 {
1147 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1148 GEOSCoordSeq_setX (cs, iv,
1149 x);
1150 GEOSCoordSeq_setY (cs, iv,
1151 y);
1152 #endif
1153 }
1154 break;
1155 case GAIA_XY_Z_M:
1156 gaiaGetPointXYZM (rng->Coords, iv,
1157 &x, &y, &z, &m);
1158 if (iv == 0)
1159 {
1160 /* saving the first vertex */
1161 x0 = x;
1162 y0 = y;
1163 z0 = z;
1164 }
1165 if (handle != NULL)
1166 {
1167 GEOSCoordSeq_setX_r (handle,
1168 cs, iv,
1169 x);
1170 GEOSCoordSeq_setY_r (handle,
1171 cs, iv,
1172 y);
1173 GEOSCoordSeq_setZ_r (handle,
1174 cs, iv,
1175 z);
1176 }
1177 else
1178 {
1179 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1180 GEOSCoordSeq_setX (cs, iv,
1181 x);
1182 GEOSCoordSeq_setY (cs, iv,
1183 y);
1184 GEOSCoordSeq_setZ (cs, iv,
1185 z);
1186 #endif
1187 }
1188 break;
1189 default:
1190 gaiaGetPoint (rng->Coords, iv, &x,
1191 &y);
1192 if (iv == 0)
1193 {
1194 /* saving the first vertex */
1195 x0 = x;
1196 y0 = y;
1197 }
1198 if (handle != NULL)
1199 {
1200 GEOSCoordSeq_setX_r (handle,
1201 cs, iv,
1202 x);
1203 GEOSCoordSeq_setY_r (handle,
1204 cs, iv,
1205 y);
1206 }
1207 else
1208 {
1209 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1210 GEOSCoordSeq_setX (cs, iv,
1211 x);
1212 GEOSCoordSeq_setY (cs, iv,
1213 y);
1214 #endif
1215 }
1216 break;
1217 };
1218 }
1219 if (ring_points > rng->Points)
1220 {
1221 /* ensuring Ring's closure */
1222 iv = ring_points - 1;
1223 switch (rng->DimensionModel)
1224 {
1225 case GAIA_XY_Z:
1226 case GAIA_XY_Z_M:
1227 if (handle != NULL)
1228 {
1229 GEOSCoordSeq_setX_r (handle,
1230 cs, iv,
1231 x0);
1232 GEOSCoordSeq_setY_r (handle,
1233 cs, iv,
1234 y0);
1235 GEOSCoordSeq_setZ_r (handle,
1236 cs, iv,
1237 z0);
1238 }
1239 else
1240 {
1241 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1242 GEOSCoordSeq_setX (cs, iv,
1243 x0);
1244 GEOSCoordSeq_setY (cs, iv,
1245 y0);
1246 GEOSCoordSeq_setZ (cs, iv,
1247 z0);
1248 #endif
1249 }
1250 break;
1251 default:
1252 if (handle != NULL)
1253 {
1254 GEOSCoordSeq_setX_r (handle,
1255 cs, iv,
1256 x0);
1257 GEOSCoordSeq_setY_r (handle,
1258 cs, iv,
1259 y0);
1260 }
1261 else
1262 {
1263 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1264 GEOSCoordSeq_setX (cs, iv,
1265 x0);
1266 GEOSCoordSeq_setY (cs, iv,
1267 y0);
1268 #endif
1269 }
1270 break;
1271 };
1272 }
1273 if (handle != NULL)
1274 geos_int =
1275 GEOSGeom_createLinearRing_r (handle,
1276 cs);
1277 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1278 else
1279 geos_int = GEOSGeom_createLinearRing (cs);
1280 #endif
1281 *(geos_holes + ib) = geos_int;
1282 }
1283 }
1284 if (handle != NULL)
1285 geos_item =
1286 GEOSGeom_createPolygon_r (handle, geos_ext,
1287 geos_holes,
1288 pg->NumInteriors);
1289 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1290 else
1291 geos_item =
1292 GEOSGeom_createPolygon (geos_ext, geos_holes,
1293 pg->NumInteriors);
1294 #endif
1295 if (geos_holes)
1296 free (geos_holes);
1297 *(geos_coll + nItem++) = geos_item;
1298 pg = pg->Next;
1299 }
1300 }
1301 geos_type = GEOS_GEOMETRYCOLLECTION;
1302 if (type == GAIA_MULTIPOINT)
1303 geos_type = GEOS_MULTIPOINT;
1304 if (type == GAIA_MULTILINESTRING)
1305 geos_type = GEOS_MULTILINESTRING;
1306 if (type == GAIA_MULTIPOLYGON)
1307 geos_type = GEOS_MULTIPOLYGON;
1308 if (handle != NULL)
1309 geos =
1310 GEOSGeom_createCollection_r (handle, geos_type, geos_coll,
1311 n_items);
1312 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1313 else
1314 geos = GEOSGeom_createCollection (geos_type, geos_coll, n_items);
1315 #endif
1316 if (geos_coll)
1317 free (geos_coll);
1318 break;
1319 default:
1320 geos = NULL;
1321 };
1322 if (geos)
1323 {
1324 if (handle != NULL)
1325 GEOSSetSRID_r (handle, geos, gaia->Srid);
1326 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1327 else
1328 GEOSSetSRID (geos, gaia->Srid);
1329 #endif
1330 }
1331 return geos;
1332 }
1333
1334 static gaiaGeomCollPtr
fromGeosGeometry(GEOSContextHandle_t handle,const GEOSGeometry * geos,const int dimension_model)1335 fromGeosGeometry (GEOSContextHandle_t handle, const GEOSGeometry * geos,
1336 const int dimension_model)
1337 {
1338 /* converting a GEOS Geometry into a GAIA Geometry */
1339 int type;
1340 int itemType;
1341 unsigned int dims;
1342 int iv;
1343 int ib;
1344 int it;
1345 int sub_it;
1346 int nItems;
1347 int nSubItems;
1348 int holes;
1349 unsigned int points;
1350 double x;
1351 double y;
1352 double z;
1353 const GEOSCoordSequence *cs;
1354 const GEOSGeometry *geos_ring;
1355 const GEOSGeometry *geos_item;
1356 const GEOSGeometry *geos_sub_item;
1357 gaiaGeomCollPtr gaia = NULL;
1358 gaiaLinestringPtr ln;
1359 gaiaPolygonPtr pg;
1360 gaiaRingPtr rng;
1361
1362 #ifdef GEOS_USE_ONLY_R_API /* only fully thread-safe GEOS API */
1363 if (handle == NULL)
1364 return NULL;
1365 #endif
1366 if (!geos)
1367 return NULL;
1368
1369 if (handle != NULL)
1370 type = GEOSGeomTypeId_r (handle, geos);
1371 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1372 else
1373 type = GEOSGeomTypeId (geos);
1374 #endif
1375 switch (type)
1376 {
1377 case GEOS_POINT:
1378 if (dimension_model == GAIA_XY_Z)
1379 gaia = gaiaAllocGeomCollXYZ ();
1380 else if (dimension_model == GAIA_XY_M)
1381 gaia = gaiaAllocGeomCollXYM ();
1382 else if (dimension_model == GAIA_XY_Z_M)
1383 gaia = gaiaAllocGeomCollXYZM ();
1384 else
1385 gaia = gaiaAllocGeomColl ();
1386 gaia->DeclaredType = GAIA_POINT;
1387 if (handle != NULL)
1388 {
1389 gaia->Srid = GEOSGetSRID_r (handle, geos);
1390 cs = GEOSGeom_getCoordSeq_r (handle, geos);
1391 GEOSCoordSeq_getDimensions_r (handle, cs, &dims);
1392 }
1393 else
1394 {
1395 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1396 gaia->Srid = GEOSGetSRID (geos);
1397 cs = GEOSGeom_getCoordSeq (geos);
1398 GEOSCoordSeq_getDimensions (cs, &dims);
1399 #endif
1400 }
1401 if (dims == 3)
1402 {
1403 if (handle != NULL)
1404 {
1405 GEOSCoordSeq_getX_r (handle, cs, 0, &x);
1406 GEOSCoordSeq_getY_r (handle, cs, 0, &y);
1407 GEOSCoordSeq_getZ_r (handle, cs, 0, &z);
1408 }
1409 else
1410 {
1411 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1412 GEOSCoordSeq_getX (cs, 0, &x);
1413 GEOSCoordSeq_getY (cs, 0, &y);
1414 GEOSCoordSeq_getZ (cs, 0, &z);
1415 #endif
1416 }
1417 }
1418 else
1419 {
1420 if (handle != NULL)
1421 {
1422 GEOSCoordSeq_getX_r (handle, cs, 0, &x);
1423 GEOSCoordSeq_getY_r (handle, cs, 0, &y);
1424 }
1425 else
1426 {
1427 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1428 GEOSCoordSeq_getX (cs, 0, &x);
1429 GEOSCoordSeq_getY (cs, 0, &y);
1430 #endif
1431 }
1432 z = 0.0;
1433 }
1434 if (dimension_model == GAIA_XY_Z)
1435 gaiaAddPointToGeomCollXYZ (gaia, x, y, z);
1436 else if (dimension_model == GAIA_XY_M)
1437 gaiaAddPointToGeomCollXYM (gaia, x, y, 0.0);
1438 else if (dimension_model == GAIA_XY_Z_M)
1439 gaiaAddPointToGeomCollXYZM (gaia, x, y, z, 0.0);
1440 else
1441 gaiaAddPointToGeomColl (gaia, x, y);
1442 break;
1443 case GEOS_LINESTRING:
1444 if (dimension_model == GAIA_XY_Z)
1445 gaia = gaiaAllocGeomCollXYZ ();
1446 else if (dimension_model == GAIA_XY_M)
1447 gaia = gaiaAllocGeomCollXYM ();
1448 else if (dimension_model == GAIA_XY_Z_M)
1449 gaia = gaiaAllocGeomCollXYZM ();
1450 else
1451 gaia = gaiaAllocGeomColl ();
1452 gaia->DeclaredType = GAIA_LINESTRING;
1453 if (handle != NULL)
1454 {
1455 gaia->Srid = GEOSGetSRID_r (handle, geos);
1456 cs = GEOSGeom_getCoordSeq_r (handle, geos);
1457 GEOSCoordSeq_getDimensions_r (handle, cs, &dims);
1458 GEOSCoordSeq_getSize_r (handle, cs, &points);
1459 }
1460 else
1461 {
1462 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1463 gaia->Srid = GEOSGetSRID (geos);
1464 cs = GEOSGeom_getCoordSeq (geos);
1465 GEOSCoordSeq_getDimensions (cs, &dims);
1466 GEOSCoordSeq_getSize (cs, &points);
1467 #endif
1468 }
1469 ln = gaiaAddLinestringToGeomColl (gaia, points);
1470 for (iv = 0; iv < (int) points; iv++)
1471 {
1472 if (dims == 3)
1473 {
1474 if (handle != NULL)
1475 {
1476 GEOSCoordSeq_getX_r (handle, cs, iv, &x);
1477 GEOSCoordSeq_getY_r (handle, cs, iv, &y);
1478 GEOSCoordSeq_getZ_r (handle, cs, iv, &z);
1479 }
1480 else
1481 {
1482 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1483 GEOSCoordSeq_getX (cs, iv, &x);
1484 GEOSCoordSeq_getY (cs, iv, &y);
1485 GEOSCoordSeq_getZ (cs, iv, &z);
1486 #endif
1487 }
1488 }
1489 else
1490 {
1491 if (handle != NULL)
1492 {
1493 GEOSCoordSeq_getX_r (handle, cs, iv, &x);
1494 GEOSCoordSeq_getY_r (handle, cs, iv, &y);
1495 }
1496 else
1497 {
1498 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1499 GEOSCoordSeq_getX (cs, iv, &x);
1500 GEOSCoordSeq_getY (cs, iv, &y);
1501 #endif
1502 }
1503 z = 0.0;
1504 }
1505 if (dimension_model == GAIA_XY_Z)
1506 {
1507 gaiaSetPointXYZ (ln->Coords, iv, x, y, z);
1508 }
1509 else if (dimension_model == GAIA_XY_M)
1510 {
1511 gaiaSetPointXYM (ln->Coords, iv, x, y, 0.0);
1512 }
1513 else if (dimension_model == GAIA_XY_Z_M)
1514 {
1515 gaiaSetPointXYZM (ln->Coords, iv, x, y, z, 0.0);
1516 }
1517 else
1518 {
1519 gaiaSetPoint (ln->Coords, iv, x, y);
1520 }
1521 }
1522 break;
1523 case GEOS_POLYGON:
1524 if (dimension_model == GAIA_XY_Z)
1525 gaia = gaiaAllocGeomCollXYZ ();
1526 else if (dimension_model == GAIA_XY_M)
1527 gaia = gaiaAllocGeomCollXYM ();
1528 else if (dimension_model == GAIA_XY_Z_M)
1529 gaia = gaiaAllocGeomCollXYZM ();
1530 else
1531 gaia = gaiaAllocGeomColl ();
1532 gaia->DeclaredType = GAIA_POLYGON;
1533 if (handle != NULL)
1534 gaia->Srid = GEOSGetSRID_r (handle, geos);
1535 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1536 else
1537 gaia->Srid = GEOSGetSRID (geos);
1538 #endif
1539 /* exterior ring */
1540 if (handle != NULL)
1541 {
1542 holes = GEOSGetNumInteriorRings_r (handle, geos);
1543 geos_ring = GEOSGetExteriorRing_r (handle, geos);
1544 cs = GEOSGeom_getCoordSeq_r (handle, geos_ring);
1545 GEOSCoordSeq_getDimensions_r (handle, cs, &dims);
1546 GEOSCoordSeq_getSize_r (handle, cs, &points);
1547 }
1548 else
1549 {
1550 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1551 holes = GEOSGetNumInteriorRings (geos);
1552 geos_ring = GEOSGetExteriorRing (geos);
1553 cs = GEOSGeom_getCoordSeq (geos_ring);
1554 GEOSCoordSeq_getDimensions (cs, &dims);
1555 GEOSCoordSeq_getSize (cs, &points);
1556 #endif
1557 }
1558 pg = gaiaAddPolygonToGeomColl (gaia, points, holes);
1559 rng = pg->Exterior;
1560 for (iv = 0; iv < (int) points; iv++)
1561 {
1562 if (dims == 3)
1563 {
1564 if (handle != NULL)
1565 {
1566 GEOSCoordSeq_getX_r (handle, cs, iv, &x);
1567 GEOSCoordSeq_getY_r (handle, cs, iv, &y);
1568 GEOSCoordSeq_getZ_r (handle, cs, iv, &z);
1569 }
1570 else
1571 {
1572 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1573 GEOSCoordSeq_getX (cs, iv, &x);
1574 GEOSCoordSeq_getY (cs, iv, &y);
1575 GEOSCoordSeq_getZ (cs, iv, &z);
1576 #endif
1577 }
1578 }
1579 else
1580 {
1581 if (handle != NULL)
1582 {
1583 GEOSCoordSeq_getX_r (handle, cs, iv, &x);
1584 GEOSCoordSeq_getY_r (handle, cs, iv, &y);
1585 }
1586 else
1587 {
1588 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1589 GEOSCoordSeq_getX (cs, iv, &x);
1590 GEOSCoordSeq_getY (cs, iv, &y);
1591 #endif
1592 }
1593 z = 0.0;
1594 }
1595 if (dimension_model == GAIA_XY_Z)
1596 {
1597 gaiaSetPointXYZ (rng->Coords, iv, x, y, z);
1598 }
1599 else if (dimension_model == GAIA_XY_M)
1600 {
1601 gaiaSetPointXYM (rng->Coords, iv, x, y, 0.0);
1602 }
1603 else if (dimension_model == GAIA_XY_Z_M)
1604 {
1605 gaiaSetPointXYZM (rng->Coords, iv, x, y, z, 0.0);
1606 }
1607 else
1608 {
1609 gaiaSetPoint (rng->Coords, iv, x, y);
1610 }
1611 }
1612 for (ib = 0; ib < holes; ib++)
1613 {
1614 /* interior rings */
1615 if (handle != NULL)
1616 {
1617 geos_ring = GEOSGetInteriorRingN_r (handle, geos, ib);
1618 cs = GEOSGeom_getCoordSeq_r (handle, geos_ring);
1619 GEOSCoordSeq_getDimensions_r (handle, cs, &dims);
1620 GEOSCoordSeq_getSize_r (handle, cs, &points);
1621 }
1622 else
1623 {
1624 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1625 geos_ring = GEOSGetInteriorRingN (geos, ib);
1626 cs = GEOSGeom_getCoordSeq (geos_ring);
1627 GEOSCoordSeq_getDimensions (cs, &dims);
1628 GEOSCoordSeq_getSize (cs, &points);
1629 #endif
1630 }
1631 rng = gaiaAddInteriorRing (pg, ib, points);
1632 for (iv = 0; iv < (int) points; iv++)
1633 {
1634 if (dims == 3)
1635 {
1636 if (handle != NULL)
1637 {
1638 GEOSCoordSeq_getX_r (handle, cs, iv, &x);
1639 GEOSCoordSeq_getY_r (handle, cs, iv, &y);
1640 GEOSCoordSeq_getZ_r (handle, cs, iv, &z);
1641 }
1642 else
1643 {
1644 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1645 GEOSCoordSeq_getX (cs, iv, &x);
1646 GEOSCoordSeq_getY (cs, iv, &y);
1647 GEOSCoordSeq_getZ (cs, iv, &z);
1648 #endif
1649 }
1650 }
1651 else
1652 {
1653 if (handle != NULL)
1654 {
1655 GEOSCoordSeq_getX_r (handle, cs, iv, &x);
1656 GEOSCoordSeq_getY_r (handle, cs, iv, &y);
1657 }
1658 else
1659 {
1660 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1661 GEOSCoordSeq_getX (cs, iv, &x);
1662 GEOSCoordSeq_getY (cs, iv, &y);
1663 #endif
1664 }
1665 z = 0.0;
1666 }
1667 if (dimension_model == GAIA_XY_Z)
1668 {
1669 gaiaSetPointXYZ (rng->Coords, iv, x, y, z);
1670 }
1671 else if (dimension_model == GAIA_XY_M)
1672 {
1673 gaiaSetPointXYM (rng->Coords, iv, x, y, 0.0);
1674 }
1675 else if (dimension_model == GAIA_XY_Z_M)
1676 {
1677 gaiaSetPointXYZM (rng->Coords, iv, x, y, z, 0.0);
1678 }
1679 else
1680 {
1681 gaiaSetPoint (rng->Coords, iv, x, y);
1682 }
1683 }
1684 }
1685 break;
1686 case GEOS_MULTIPOINT:
1687 case GEOS_MULTILINESTRING:
1688 case GEOS_MULTIPOLYGON:
1689 case GEOS_GEOMETRYCOLLECTION:
1690 if (dimension_model == GAIA_XY_Z)
1691 gaia = gaiaAllocGeomCollXYZ ();
1692 else if (dimension_model == GAIA_XY_M)
1693 gaia = gaiaAllocGeomCollXYM ();
1694 else if (dimension_model == GAIA_XY_Z_M)
1695 gaia = gaiaAllocGeomCollXYZM ();
1696 else
1697 gaia = gaiaAllocGeomColl ();
1698 if (type == GEOS_MULTIPOINT)
1699 gaia->DeclaredType = GAIA_MULTIPOINT;
1700 else if (type == GEOS_MULTILINESTRING)
1701 gaia->DeclaredType = GAIA_MULTILINESTRING;
1702 else if (type == GEOS_MULTIPOLYGON)
1703 gaia->DeclaredType = GAIA_MULTIPOLYGON;
1704 else
1705 gaia->DeclaredType = GAIA_GEOMETRYCOLLECTION;
1706 if (handle != NULL)
1707 {
1708 gaia->Srid = GEOSGetSRID_r (handle, geos);
1709 nItems = GEOSGetNumGeometries_r (handle, geos);
1710 }
1711 else
1712 {
1713 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1714 gaia->Srid = GEOSGetSRID (geos);
1715 nItems = GEOSGetNumGeometries (geos);
1716 #endif
1717 }
1718 for (it = 0; it < nItems; it++)
1719 {
1720 /* looping on elementaty geometries */
1721 if (handle != NULL)
1722 {
1723 geos_item = GEOSGetGeometryN_r (handle, geos, it);
1724 itemType = GEOSGeomTypeId_r (handle, geos_item);
1725 }
1726 else
1727 {
1728 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1729 geos_item = GEOSGetGeometryN (geos, it);
1730 itemType = GEOSGeomTypeId (geos_item);
1731 #endif
1732 }
1733 switch (itemType)
1734 {
1735 case GEOS_POINT:
1736 if (handle != NULL)
1737 {
1738 cs = GEOSGeom_getCoordSeq_r (handle, geos_item);
1739 GEOSCoordSeq_getDimensions_r (handle, cs, &dims);
1740 }
1741 else
1742 {
1743 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1744 cs = GEOSGeom_getCoordSeq (geos_item);
1745 GEOSCoordSeq_getDimensions (cs, &dims);
1746 #endif
1747 }
1748 if (dims == 3)
1749 {
1750 if (handle != NULL)
1751 {
1752 GEOSCoordSeq_getX_r (handle, cs, 0, &x);
1753 GEOSCoordSeq_getY_r (handle, cs, 0, &y);
1754 GEOSCoordSeq_getZ_r (handle, cs, 0, &z);
1755 }
1756 else
1757 {
1758 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1759 GEOSCoordSeq_getX (cs, 0, &x);
1760 GEOSCoordSeq_getY (cs, 0, &y);
1761 GEOSCoordSeq_getZ (cs, 0, &z);
1762 #endif
1763 }
1764 }
1765 else
1766 {
1767 if (handle != NULL)
1768 {
1769 GEOSCoordSeq_getX_r (handle, cs, 0, &x);
1770 GEOSCoordSeq_getY_r (handle, cs, 0, &y);
1771 }
1772 else
1773 {
1774 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1775 GEOSCoordSeq_getX (cs, 0, &x);
1776 GEOSCoordSeq_getY (cs, 0, &y);
1777 #endif
1778 }
1779 z = 0.0;
1780 }
1781 if (dimension_model == GAIA_XY_Z)
1782 gaiaAddPointToGeomCollXYZ (gaia, x, y, z);
1783 else if (dimension_model == GAIA_XY_M)
1784 gaiaAddPointToGeomCollXYM (gaia, x, y, 0.0);
1785 else if (dimension_model == GAIA_XY_Z_M)
1786 gaiaAddPointToGeomCollXYZM (gaia, x, y, z, 0.0);
1787 else
1788 gaiaAddPointToGeomColl (gaia, x, y);
1789 break;
1790 case GEOS_LINESTRING:
1791 if (handle != NULL)
1792 {
1793 cs = GEOSGeom_getCoordSeq_r (handle, geos_item);
1794 GEOSCoordSeq_getDimensions_r (handle, cs, &dims);
1795 GEOSCoordSeq_getSize_r (handle, cs, &points);
1796 }
1797 else
1798 {
1799 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1800 cs = GEOSGeom_getCoordSeq (geos_item);
1801 GEOSCoordSeq_getDimensions (cs, &dims);
1802 GEOSCoordSeq_getSize (cs, &points);
1803 #endif
1804 }
1805 ln = gaiaAddLinestringToGeomColl (gaia, points);
1806 for (iv = 0; iv < (int) points; iv++)
1807 {
1808 if (dims == 3)
1809 {
1810 if (handle != NULL)
1811 {
1812 GEOSCoordSeq_getX_r (handle, cs, iv,
1813 &x);
1814 GEOSCoordSeq_getY_r (handle, cs, iv,
1815 &y);
1816 GEOSCoordSeq_getZ_r (handle, cs, iv,
1817 &z);
1818 }
1819 else
1820 {
1821 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1822 GEOSCoordSeq_getX (cs, iv, &x);
1823 GEOSCoordSeq_getY (cs, iv, &y);
1824 GEOSCoordSeq_getZ (cs, iv, &z);
1825 #endif
1826 }
1827 }
1828 else
1829 {
1830 if (handle != NULL)
1831 {
1832 GEOSCoordSeq_getX_r (handle, cs, iv,
1833 &x);
1834 GEOSCoordSeq_getY_r (handle, cs, iv,
1835 &y);
1836 }
1837 else
1838 {
1839 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1840 GEOSCoordSeq_getX (cs, iv, &x);
1841 GEOSCoordSeq_getY (cs, iv, &y);
1842 #endif
1843 }
1844 z = 0.0;
1845 }
1846 if (dimension_model == GAIA_XY_Z)
1847 {
1848 gaiaSetPointXYZ (ln->Coords, iv, x, y, z);
1849 }
1850 else if (dimension_model == GAIA_XY_M)
1851 {
1852 gaiaSetPointXYM (ln->Coords, iv, x, y, 0.0);
1853 }
1854 else if (dimension_model == GAIA_XY_Z_M)
1855 {
1856 gaiaSetPointXYZM (ln->Coords, iv, x, y, z,
1857 0.0);
1858 }
1859 else
1860 {
1861 gaiaSetPoint (ln->Coords, iv, x, y);
1862 }
1863 }
1864 break;
1865 case GEOS_MULTILINESTRING:
1866 if (handle != NULL)
1867 nSubItems =
1868 GEOSGetNumGeometries_r (handle, geos_item);
1869 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1870 else
1871 nSubItems = GEOSGetNumGeometries (geos_item);
1872 #endif
1873 for (sub_it = 0; sub_it < nSubItems; sub_it++)
1874 {
1875 /* looping on elementaty geometries */
1876 if (handle != NULL)
1877 {
1878 geos_sub_item =
1879 GEOSGetGeometryN_r (handle, geos_item,
1880 sub_it);
1881 cs = GEOSGeom_getCoordSeq_r (handle,
1882 geos_sub_item);
1883 GEOSCoordSeq_getDimensions_r (handle, cs,
1884 &dims);
1885 GEOSCoordSeq_getSize_r (handle, cs, &points);
1886 }
1887 else
1888 {
1889 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1890 geos_sub_item =
1891 GEOSGetGeometryN (geos_item, sub_it);
1892 cs = GEOSGeom_getCoordSeq (geos_sub_item);
1893 GEOSCoordSeq_getDimensions (cs, &dims);
1894 GEOSCoordSeq_getSize (cs, &points);
1895 #endif
1896 }
1897 ln = gaiaAddLinestringToGeomColl (gaia, points);
1898 for (iv = 0; iv < (int) points; iv++)
1899 {
1900 if (dims == 3)
1901 {
1902 if (handle != NULL)
1903 {
1904 GEOSCoordSeq_getX_r (handle, cs,
1905 iv, &x);
1906 GEOSCoordSeq_getY_r (handle, cs,
1907 iv, &y);
1908 GEOSCoordSeq_getZ_r (handle, cs,
1909 iv, &z);
1910 }
1911 else
1912 {
1913 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1914 GEOSCoordSeq_getX (cs, iv, &x);
1915 GEOSCoordSeq_getY (cs, iv, &y);
1916 GEOSCoordSeq_getZ (cs, iv, &z);
1917 #endif
1918 }
1919 }
1920 else
1921 {
1922 if (handle != NULL)
1923 {
1924 GEOSCoordSeq_getX_r (handle, cs,
1925 iv, &x);
1926 GEOSCoordSeq_getY_r (handle, cs,
1927 iv, &y);
1928 }
1929 else
1930 {
1931 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1932 GEOSCoordSeq_getX (cs, iv, &x);
1933 GEOSCoordSeq_getY (cs, iv, &y);
1934 #endif
1935 }
1936 z = 0.0;
1937 }
1938 if (dimension_model == GAIA_XY_Z)
1939 {
1940 gaiaSetPointXYZ (ln->Coords, iv, x, y,
1941 z);
1942 }
1943 else if (dimension_model == GAIA_XY_M)
1944 {
1945 gaiaSetPointXYM (ln->Coords, iv, x, y,
1946 0.0);
1947 }
1948 else if (dimension_model == GAIA_XY_Z_M)
1949 {
1950 gaiaSetPointXYZM (ln->Coords, iv, x, y,
1951 z, 0.0);
1952 }
1953 else
1954 {
1955 gaiaSetPoint (ln->Coords, iv, x, y);
1956 }
1957 }
1958 }
1959 break;
1960 case GEOS_POLYGON:
1961 /* exterior ring */
1962 if (handle != NULL)
1963 {
1964 holes =
1965 GEOSGetNumInteriorRings_r (handle, geos_item);
1966 geos_ring =
1967 GEOSGetExteriorRing_r (handle, geos_item);
1968 cs = GEOSGeom_getCoordSeq_r (handle, geos_ring);
1969 GEOSCoordSeq_getDimensions_r (handle, cs, &dims);
1970 GEOSCoordSeq_getSize_r (handle, cs, &points);
1971 }
1972 else
1973 {
1974 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
1975 holes = GEOSGetNumInteriorRings (geos_item);
1976 geos_ring = GEOSGetExteriorRing (geos_item);
1977 cs = GEOSGeom_getCoordSeq (geos_ring);
1978 GEOSCoordSeq_getDimensions (cs, &dims);
1979 GEOSCoordSeq_getSize (cs, &points);
1980 #endif
1981 }
1982 pg = gaiaAddPolygonToGeomColl (gaia, points, holes);
1983 rng = pg->Exterior;
1984 for (iv = 0; iv < (int) points; iv++)
1985 {
1986 if (dims == 3)
1987 {
1988 if (handle != NULL)
1989 {
1990 GEOSCoordSeq_getX_r (handle, cs, iv,
1991 &x);
1992 GEOSCoordSeq_getY_r (handle, cs, iv,
1993 &y);
1994 GEOSCoordSeq_getZ_r (handle, cs, iv,
1995 &z);
1996 }
1997 else
1998 {
1999 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
2000 GEOSCoordSeq_getX (cs, iv, &x);
2001 GEOSCoordSeq_getY (cs, iv, &y);
2002 GEOSCoordSeq_getZ (cs, iv, &z);
2003 #endif
2004 }
2005 }
2006 else
2007 {
2008 if (handle != NULL)
2009 {
2010 GEOSCoordSeq_getX_r (handle, cs, iv,
2011 &x);
2012 GEOSCoordSeq_getY_r (handle, cs, iv,
2013 &y);
2014 }
2015 else
2016 {
2017 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
2018 GEOSCoordSeq_getX (cs, iv, &x);
2019 GEOSCoordSeq_getY (cs, iv, &y);
2020 #endif
2021 }
2022 z = 0.0;
2023 }
2024 if (dimension_model == GAIA_XY_Z)
2025 {
2026 gaiaSetPointXYZ (rng->Coords, iv, x, y, z);
2027 }
2028 else if (dimension_model == GAIA_XY_M)
2029 {
2030 gaiaSetPointXYM (rng->Coords, iv, x, y, 0.0);
2031 }
2032 else if (dimension_model == GAIA_XY_Z_M)
2033 {
2034 gaiaSetPointXYZM (rng->Coords, iv, x, y, z,
2035 0.0);
2036 }
2037 else
2038 {
2039 gaiaSetPoint (rng->Coords, iv, x, y);
2040 }
2041 }
2042 for (ib = 0; ib < holes; ib++)
2043 {
2044 /* interior rings */
2045 if (handle != NULL)
2046 {
2047 geos_ring =
2048 GEOSGetInteriorRingN_r (handle, geos_item,
2049 ib);
2050 cs = GEOSGeom_getCoordSeq_r (handle,
2051 geos_ring);
2052 GEOSCoordSeq_getDimensions_r (handle, cs,
2053 &dims);
2054 GEOSCoordSeq_getSize_r (handle, cs, &points);
2055 }
2056 else
2057 {
2058 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
2059 geos_ring =
2060 GEOSGetInteriorRingN (geos_item, ib);
2061 cs = GEOSGeom_getCoordSeq (geos_ring);
2062 GEOSCoordSeq_getDimensions (cs, &dims);
2063 GEOSCoordSeq_getSize (cs, &points);
2064 #endif
2065 }
2066 rng = gaiaAddInteriorRing (pg, ib, points);
2067 for (iv = 0; iv < (int) points; iv++)
2068 {
2069 if (dims == 3)
2070 {
2071 if (handle != NULL)
2072 {
2073 GEOSCoordSeq_getX_r (handle, cs,
2074 iv, &x);
2075 GEOSCoordSeq_getY_r (handle, cs,
2076 iv, &y);
2077 GEOSCoordSeq_getZ_r (handle, cs,
2078 iv, &z);
2079 }
2080 else
2081 {
2082 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
2083 GEOSCoordSeq_getX (cs, iv, &x);
2084 GEOSCoordSeq_getY (cs, iv, &y);
2085 GEOSCoordSeq_getZ (cs, iv, &z);
2086 #endif
2087 }
2088 }
2089 else
2090 {
2091 if (handle != NULL)
2092 {
2093 GEOSCoordSeq_getX_r (handle, cs,
2094 iv, &x);
2095 GEOSCoordSeq_getY_r (handle, cs,
2096 iv, &y);
2097 }
2098 else
2099 {
2100 #ifndef GEOS_USE_ONLY_R_API /* obsolete versions non fully thread-safe */
2101 GEOSCoordSeq_getX (cs, iv, &x);
2102 GEOSCoordSeq_getY (cs, iv, &y);
2103 #endif
2104 }
2105 z = 0.0;
2106 }
2107 if (dimension_model == GAIA_XY_Z)
2108 {
2109 gaiaSetPointXYZ (rng->Coords, iv, x, y,
2110 z);
2111 }
2112 else if (dimension_model == GAIA_XY_M)
2113 {
2114 gaiaSetPointXYM (rng->Coords, iv, x, y,
2115 0.0);
2116 }
2117 else if (dimension_model == GAIA_XY_Z_M)
2118 {
2119 gaiaSetPointXYZM (rng->Coords, iv, x, y,
2120 z, 0.0);
2121 }
2122 else
2123 {
2124 gaiaSetPoint (rng->Coords, iv, x, y);
2125 }
2126 }
2127 }
2128 break;
2129 };
2130 }
2131 break;
2132 };
2133 return gaia;
2134 }
2135
2136 GAIAGEO_DECLARE void *
gaiaToGeos(const gaiaGeomCollPtr gaia)2137 gaiaToGeos (const gaiaGeomCollPtr gaia)
2138 {
2139 /* converting a GAIA Geometry into a GEOS Geometry */
2140 return toGeosGeometry (NULL, NULL, gaia, GAIA2GEOS_ALL);
2141 }
2142
2143 GAIAGEO_DECLARE void *
gaiaToGeos_r(const void * p_cache,const gaiaGeomCollPtr gaia)2144 gaiaToGeos_r (const void *p_cache, const gaiaGeomCollPtr gaia)
2145 {
2146 /* converting a GAIA Geometry into a GEOS Geometry */
2147 struct splite_internal_cache *cache =
2148 (struct splite_internal_cache *) p_cache;
2149 GEOSContextHandle_t handle = NULL;
2150 if (cache == NULL)
2151 return NULL;
2152 if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
2153 || cache->magic2 != SPATIALITE_CACHE_MAGIC2)
2154 return NULL;
2155 handle = cache->GEOS_handle;
2156 if (handle == NULL)
2157 return NULL;
2158 return toGeosGeometry (cache, handle, gaia, GAIA2GEOS_ALL);
2159 }
2160
2161 GAIAGEO_DECLARE void *
gaiaToGeosSelective(const gaiaGeomCollPtr gaia,int mode)2162 gaiaToGeosSelective (const gaiaGeomCollPtr gaia, int mode)
2163 {
2164 /* converting a GAIA Geometry into a GEOS Geometry (selected type) */
2165 if (mode == GAIA2GEOS_ONLY_POINTS || mode == GAIA2GEOS_ONLY_LINESTRINGS
2166 || mode == GAIA2GEOS_ONLY_POLYGONS)
2167 ;
2168 else
2169 mode = GAIA2GEOS_ALL;
2170 return toGeosGeometry (NULL, NULL, gaia, mode);
2171 }
2172
2173 GAIAGEO_DECLARE void *
gaiaToGeosSelective_r(const void * p_cache,const gaiaGeomCollPtr gaia,int mode)2174 gaiaToGeosSelective_r (const void *p_cache, const gaiaGeomCollPtr gaia,
2175 int mode)
2176 {
2177 /* converting a GAIA Geometry into a GEOS Geometry (selected type) */
2178 struct splite_internal_cache *cache =
2179 (struct splite_internal_cache *) p_cache;
2180 GEOSContextHandle_t handle = NULL;
2181 if (cache == NULL)
2182 return NULL;
2183 if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
2184 || cache->magic2 != SPATIALITE_CACHE_MAGIC2)
2185 return NULL;
2186 handle = cache->GEOS_handle;
2187 if (handle == NULL)
2188 return NULL;
2189 if (mode == GAIA2GEOS_ONLY_POINTS || mode == GAIA2GEOS_ONLY_LINESTRINGS
2190 || mode == GAIA2GEOS_ONLY_POLYGONS)
2191 ;
2192 else
2193 mode = GAIA2GEOS_ALL;
2194 return toGeosGeometry (cache, handle, gaia, mode);
2195 }
2196
2197 GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaFromGeos_XY(const void * xgeos)2198 gaiaFromGeos_XY (const void *xgeos)
2199 {
2200 /* converting a GEOS Geometry into a GAIA Geometry [XY] */
2201 const GEOSGeometry *geos = xgeos;
2202 return fromGeosGeometry (NULL, geos, GAIA_XY);
2203 }
2204
2205 GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaFromGeos_XYZ(const void * xgeos)2206 gaiaFromGeos_XYZ (const void *xgeos)
2207 {
2208 /* converting a GEOS Geometry into a GAIA Geometry [XYZ] */
2209 const GEOSGeometry *geos = xgeos;
2210 return fromGeosGeometry (NULL, geos, GAIA_XY_Z);
2211 }
2212
2213 GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaFromGeos_XYM(const void * xgeos)2214 gaiaFromGeos_XYM (const void *xgeos)
2215 {
2216 /* converting a GEOS Geometry into a GAIA Geometry [XYM] */
2217 const GEOSGeometry *geos = xgeos;
2218 return fromGeosGeometry (NULL, geos, GAIA_XY_M);
2219 }
2220
2221 GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaFromGeos_XYZM(const void * xgeos)2222 gaiaFromGeos_XYZM (const void *xgeos)
2223 {
2224 /* converting a GEOS Geometry into a GAIA Geometry [XYZM] */
2225 const GEOSGeometry *geos = xgeos;
2226 return fromGeosGeometry (NULL, geos, GAIA_XY_Z_M);
2227 }
2228
2229 GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaFromGeos_XY_r(const void * p_cache,const void * xgeos)2230 gaiaFromGeos_XY_r (const void *p_cache, const void *xgeos)
2231 {
2232 /* converting a GEOS Geometry into a GAIA Geometry [XY] */
2233 const GEOSGeometry *geos = xgeos;
2234 struct splite_internal_cache *cache =
2235 (struct splite_internal_cache *) p_cache;
2236 GEOSContextHandle_t handle = NULL;
2237 if (cache == NULL)
2238 return NULL;
2239 if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
2240 || cache->magic2 != SPATIALITE_CACHE_MAGIC2)
2241 return NULL;
2242 handle = cache->GEOS_handle;
2243 if (handle == NULL)
2244 return NULL;
2245 return fromGeosGeometry (handle, geos, GAIA_XY);
2246 }
2247
2248 GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaFromGeos_XYZ_r(const void * p_cache,const void * xgeos)2249 gaiaFromGeos_XYZ_r (const void *p_cache, const void *xgeos)
2250 {
2251 /* converting a GEOS Geometry into a GAIA Geometry [XYZ] */
2252 const GEOSGeometry *geos = xgeos;
2253 struct splite_internal_cache *cache =
2254 (struct splite_internal_cache *) p_cache;
2255 GEOSContextHandle_t handle = NULL;
2256 if (cache == NULL)
2257 return NULL;
2258 if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
2259 || cache->magic2 != SPATIALITE_CACHE_MAGIC2)
2260 return NULL;
2261 handle = cache->GEOS_handle;
2262 if (handle == NULL)
2263 return NULL;
2264 return fromGeosGeometry (handle, geos, GAIA_XY_Z);
2265 }
2266
2267 GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaFromGeos_XYM_r(const void * p_cache,const void * xgeos)2268 gaiaFromGeos_XYM_r (const void *p_cache, const void *xgeos)
2269 {
2270 /* converting a GEOS Geometry into a GAIA Geometry [XYM] */
2271 const GEOSGeometry *geos = xgeos;
2272 struct splite_internal_cache *cache =
2273 (struct splite_internal_cache *) p_cache;
2274 GEOSContextHandle_t handle = NULL;
2275 if (cache == NULL)
2276 return NULL;
2277 if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
2278 || cache->magic2 != SPATIALITE_CACHE_MAGIC2)
2279 return NULL;
2280 handle = cache->GEOS_handle;
2281 if (handle == NULL)
2282 return NULL;
2283 return fromGeosGeometry (handle, geos, GAIA_XY_M);
2284 }
2285
2286 GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaFromGeos_XYZM_r(const void * p_cache,const void * xgeos)2287 gaiaFromGeos_XYZM_r (const void *p_cache, const void *xgeos)
2288 {
2289 /* converting a GEOS Geometry into a GAIA Geometry [XYZM] */
2290 const GEOSGeometry *geos = xgeos;
2291 struct splite_internal_cache *cache =
2292 (struct splite_internal_cache *) p_cache;
2293 GEOSContextHandle_t handle = NULL;
2294 if (cache == NULL)
2295 return NULL;
2296 if (cache->magic1 != SPATIALITE_CACHE_MAGIC1
2297 || cache->magic2 != SPATIALITE_CACHE_MAGIC2)
2298 return NULL;
2299 handle = cache->GEOS_handle;
2300 if (handle == NULL)
2301 return NULL;
2302 return fromGeosGeometry (handle, geos, GAIA_XY_Z_M);
2303 }
2304
2305 #endif /* end including GEOS */
2306