rgeo 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,23 +0,0 @@
1
- /*
2
- Geometry base class methods for GEOS wrapper
3
- */
4
-
5
-
6
- #ifndef RGEO_GEOS_GEOMETRY_INCLUDED
7
- #define RGEO_GEOS_GEOMETRY_INCLUDED
8
-
9
- #include "factory.h"
10
-
11
- RGEO_BEGIN_C
12
-
13
-
14
- /*
15
- Initializes the geometry module. This should be called after the factory
16
- module is initialized, but before any of the other modules.
17
- */
18
- void rgeo_init_geos_geometry(RGeo_Globals* globals);
19
-
20
-
21
- RGEO_END_C
22
-
23
- #endif
@@ -1,757 +0,0 @@
1
- /*
2
- Geometry collection methods for GEOS wrapper
3
- */
4
-
5
-
6
- #include "preface.h"
7
-
8
- #ifdef RGEO_GEOS_SUPPORTED
9
-
10
- #include <ruby.h>
11
- #include <geos_c.h>
12
-
13
- #include "factory.h"
14
- #include "geometry.h"
15
- #include "line_string.h"
16
- #include "polygon.h"
17
- #include "geometry_collection.h"
18
-
19
- #include "coordinates.h"
20
-
21
- RGEO_BEGIN_C
22
-
23
-
24
- /**** INTERNAL IMPLEMENTATION OF CREATE ****/
25
-
26
-
27
- // Main implementation of the "create" class method for geometry collections.
28
- // You must pass in the correct GEOS geometry type ID.
29
-
30
- static VALUE create_geometry_collection(VALUE module, int type, VALUE factory, VALUE array)
31
- {
32
- VALUE result;
33
- unsigned int len;
34
- GEOSGeometry** geoms;
35
- RGeo_FactoryData* factory_data;
36
- GEOSContextHandle_t geos_context;
37
- VALUE klass;
38
- unsigned int i;
39
- unsigned int j;
40
- VALUE klasses;
41
- VALUE cast_type;
42
- GEOSGeometry* geom;
43
- GEOSGeometry* collection;
44
- char problem;
45
- GEOSGeometry* igeom;
46
- GEOSGeometry* jgeom;
47
-
48
- result = Qnil;
49
- Check_Type(array, T_ARRAY);
50
- len = (unsigned int)RARRAY_LEN(array);
51
- geoms = ALLOC_N(GEOSGeometry*, len == 0 ? 1 : len);
52
- if (geoms) {
53
- factory_data = RGEO_FACTORY_DATA_PTR(factory);
54
- geos_context = factory_data->geos_context;
55
- klasses = Qnil;
56
- cast_type = Qnil;
57
- switch (type) {
58
- case GEOS_MULTIPOINT:
59
- cast_type = factory_data->globals->feature_point;
60
- break;
61
- case GEOS_MULTILINESTRING:
62
- cast_type = factory_data->globals->feature_line_string;
63
- break;
64
- case GEOS_MULTIPOLYGON:
65
- cast_type = factory_data->globals->feature_polygon;
66
- break;
67
- }
68
- for (i=0; i<len; ++i) {
69
- geom = rgeo_convert_to_detached_geos_geometry(rb_ary_entry(array, i), factory, cast_type, &klass);
70
- if (!geom) {
71
- break;
72
- }
73
- geoms[i] = geom;
74
- if (!NIL_P(klass) && NIL_P(klasses)) {
75
- klasses = rb_ary_new2(len);
76
- for (j=0; j<i; ++j) {
77
- rb_ary_push(klasses, Qnil);
78
- }
79
- }
80
- if (!NIL_P(klasses)) {
81
- rb_ary_push(klasses, klass);
82
- }
83
- }
84
- if (i != len) {
85
- for (j=0; j<i; ++j) {
86
- GEOSGeom_destroy_r(geos_context, geoms[j]);
87
- }
88
- }
89
- else {
90
- collection = GEOSGeom_createCollection_r(geos_context, type, geoms, len);
91
- // Due to a limitation of GEOS, the MultiPolygon assertions are not checked.
92
- // We do that manually here.
93
- if (collection && type == GEOS_MULTIPOLYGON && (factory_data->flags & 1) == 0) {
94
- problem = 0;
95
- for (i=1; i<len; ++i) {
96
- for (j=0; j<i; ++j) {
97
- igeom = geoms[i];
98
- jgeom = geoms[j];
99
- problem = GEOSRelatePattern_r(geos_context, igeom, jgeom, "2********");
100
- if (problem) {
101
- break;
102
- }
103
- problem = GEOSRelatePattern_r(geos_context, igeom, jgeom, "****1****");
104
- if (problem) {
105
- break;
106
- }
107
- }
108
- if (problem) {
109
- break;
110
- }
111
- }
112
- if (problem) {
113
- GEOSGeom_destroy_r(geos_context, collection);
114
- collection = NULL;
115
- }
116
- }
117
- if (collection) {
118
- result = rgeo_wrap_geos_geometry(factory, collection, module);
119
- RGEO_GEOMETRY_DATA_PTR(result)->klasses = klasses;
120
- }
121
- // NOTE: We are assuming that GEOS will do its own cleanup of the
122
- // element geometries if it fails to create the collection, so we
123
- // are not doing that ourselves. If that turns out not to be the
124
- // case, this will be a memory leak.
125
- }
126
- free(geoms);
127
- }
128
-
129
- return result;
130
- }
131
-
132
-
133
- /**** RUBY METHOD DEFINITIONS ****/
134
-
135
-
136
- static VALUE method_geometry_collection_eql(VALUE self, VALUE rhs)
137
- {
138
- VALUE result;
139
- RGeo_GeometryData* self_data;
140
-
141
- result = rgeo_geos_klasses_and_factories_eql(self, rhs);
142
- if (RTEST(result)) {
143
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
144
- result = rgeo_geos_geometry_collections_eql(self_data->geos_context, self_data->geom, RGEO_GEOMETRY_DATA_PTR(rhs)->geom, RGEO_FACTORY_DATA_PTR(self_data->factory)->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M);
145
- }
146
- return result;
147
- }
148
-
149
-
150
- static VALUE method_geometry_collection_hash(VALUE self)
151
- {
152
- st_index_t hash;
153
- RGeo_GeometryData* self_data;
154
- VALUE factory;
155
-
156
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
157
- factory = self_data->factory;
158
- hash = rb_hash_start(0);
159
- hash = rgeo_geos_objbase_hash(factory,
160
- RGEO_FACTORY_DATA_PTR(factory)->globals->feature_geometry_collection, hash);
161
- hash = rgeo_geos_geometry_collection_hash(self_data->geos_context, self_data->geom, hash);
162
- return LONG2FIX(rb_hash_end(hash));
163
- }
164
-
165
-
166
- static VALUE method_geometry_collection_geometry_type(VALUE self)
167
- {
168
- VALUE result;
169
- RGeo_GeometryData* self_data;
170
-
171
- result = Qnil;
172
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
173
- if (self_data->geom) {
174
- result = RGEO_FACTORY_DATA_PTR(self_data->factory)->globals->feature_geometry_collection;
175
- }
176
- return result;
177
- }
178
-
179
-
180
- static VALUE method_geometry_collection_num_geometries(VALUE self)
181
- {
182
- VALUE result;
183
- RGeo_GeometryData* self_data;
184
- const GEOSGeometry* self_geom;
185
-
186
- result = Qnil;
187
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
188
- self_geom = self_data->geom;
189
- if (self_geom) {
190
- result = INT2NUM(GEOSGetNumGeometries_r(self_data->geos_context, self_geom));
191
- }
192
- return result;
193
- }
194
-
195
-
196
- static VALUE impl_geometry_n(VALUE self, VALUE n, char allow_negatives)
197
- {
198
- VALUE result;
199
- RGeo_GeometryData* self_data;
200
- const GEOSGeometry* self_geom;
201
- VALUE klasses;
202
- int i;
203
- int len;
204
-
205
- result = Qnil;
206
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
207
- self_geom = self_data->geom;
208
- if (self_geom) {
209
- klasses = self_data->klasses;
210
- i = NUM2INT(n);
211
- if (allow_negatives || i >= 0) {
212
- GEOSContextHandle_t self_context = self_data->geos_context;
213
- len = GEOSGetNumGeometries_r(self_context, self_geom);
214
- if (i < 0) {
215
- i += len;
216
- }
217
- if (i >= 0 && i < len) {
218
- result = rgeo_wrap_geos_geometry_clone(self_data->factory,
219
- GEOSGetGeometryN_r(self_context, self_geom, i),
220
- NIL_P(klasses) ? Qnil : rb_ary_entry(klasses, i));
221
- }
222
- }
223
- }
224
- return result;
225
- }
226
-
227
-
228
- static VALUE method_geometry_collection_geometry_n(VALUE self, VALUE n)
229
- {
230
- return impl_geometry_n(self, n, 0);
231
- }
232
-
233
-
234
- static VALUE method_geometry_collection_brackets(VALUE self, VALUE n)
235
- {
236
- return impl_geometry_n(self, n, 1);
237
- }
238
-
239
-
240
- static VALUE method_geometry_collection_each(VALUE self)
241
- {
242
- RGeo_GeometryData* self_data;
243
- const GEOSGeometry* self_geom;
244
- int len;
245
- VALUE klasses;
246
- int i;
247
- VALUE elem;
248
- const GEOSGeometry* elem_geom;
249
-
250
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
251
-
252
- if (rb_block_given_p()) {
253
- self_geom = self_data->geom;
254
- if (self_geom) {
255
- GEOSContextHandle_t self_context = self_data->geos_context;
256
- len = GEOSGetNumGeometries_r(self_context, self_geom);
257
- if (len > 0) {
258
- klasses = self_data->klasses;
259
- for (i=0; i<len; ++i) {
260
- elem_geom = GEOSGetGeometryN_r(self_context, self_geom, i);
261
- elem = rgeo_wrap_geos_geometry_clone(self_data->factory, elem_geom, NIL_P(klasses) ? Qnil : rb_ary_entry(klasses, i));
262
- if (!NIL_P(elem)) {
263
- rb_yield(elem);
264
- }
265
- }
266
- }
267
- }
268
- return self;
269
- }
270
- else {
271
- return rb_funcall(self, RGEO_FACTORY_DATA_PTR(self_data->factory)->globals->id_enum_for, 0);
272
- }
273
- }
274
-
275
- static VALUE method_multi_point_geometry_type(VALUE self)
276
- {
277
- VALUE result;
278
- RGeo_GeometryData* self_data;
279
-
280
- result = Qnil;
281
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
282
- if (self_data->geom) {
283
- result = RGEO_FACTORY_DATA_PTR(self_data->factory)->globals->feature_multi_point;
284
- }
285
- return result;
286
- }
287
-
288
-
289
- static VALUE method_multi_point_hash(VALUE self)
290
- {
291
- st_index_t hash;
292
- RGeo_GeometryData* self_data;
293
- VALUE factory;
294
-
295
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
296
- factory = self_data->factory;
297
- hash = rb_hash_start(0);
298
- hash = rgeo_geos_objbase_hash(factory,
299
- RGEO_FACTORY_DATA_PTR(factory)->globals->feature_multi_point, hash);
300
- hash = rgeo_geos_geometry_collection_hash(self_data->geos_context, self_data->geom, hash);
301
- return LONG2FIX(rb_hash_end(hash));
302
- }
303
-
304
-
305
- static VALUE method_multi_point_coordinates(VALUE self)
306
- {
307
- VALUE result = Qnil;
308
- RGeo_GeometryData* self_data;
309
- const GEOSGeometry* self_geom;
310
- GEOSContextHandle_t context;
311
- const GEOSCoordSequence* coord_sequence;
312
-
313
- const GEOSGeometry* point;
314
- unsigned int count;
315
- unsigned int i;
316
- int zCoordinate;
317
-
318
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
319
- self_geom = self_data->geom;
320
-
321
- if(self_geom) {
322
- zCoordinate = RGEO_FACTORY_DATA_PTR(self_data->factory)->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M;
323
- context = self_data->geos_context;
324
- count = GEOSGetNumGeometries_r(context, self_geom);
325
- result = rb_ary_new2(count);
326
- for(i = 0; i < count; ++i) {
327
- point = GEOSGetGeometryN_r(context, self_geom, i);
328
- coord_sequence = GEOSGeom_getCoordSeq_r(context, point);
329
- rb_ary_push(result, rb_ary_pop(extract_points_from_coordinate_sequence(context, coord_sequence, zCoordinate)));
330
- }
331
- }
332
-
333
- return result;
334
- }
335
-
336
-
337
- static VALUE method_multi_line_string_geometry_type(VALUE self)
338
- {
339
- VALUE result;
340
- RGeo_GeometryData* self_data;
341
-
342
- result = Qnil;
343
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
344
- if (self_data->geom) {
345
- result = RGEO_FACTORY_DATA_PTR(self_data->factory)->globals->feature_multi_line_string;
346
- }
347
- return result;
348
- }
349
-
350
-
351
- static VALUE method_multi_line_string_hash(VALUE self)
352
- {
353
- st_index_t hash;
354
- RGeo_GeometryData* self_data;
355
- VALUE factory;
356
-
357
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
358
- factory = self_data->factory;
359
- hash = rb_hash_start(0);
360
- hash = rgeo_geos_objbase_hash(factory,
361
- RGEO_FACTORY_DATA_PTR(factory)->globals->feature_multi_line_string, hash);
362
- hash = rgeo_geos_geometry_collection_hash(self_data->geos_context, self_data->geom, hash);
363
- return LONG2FIX(rb_hash_end(hash));
364
- }
365
-
366
-
367
- static VALUE method_multi_line_string_coordinates(VALUE self)
368
- {
369
- VALUE result = Qnil;
370
- RGeo_GeometryData* self_data;
371
- const GEOSGeometry* self_geom;
372
- GEOSContextHandle_t context;
373
- const GEOSCoordSequence* coord_sequence;
374
-
375
- const GEOSGeometry* line_string;
376
- unsigned int count;
377
- unsigned int i;
378
- int zCoordinate;
379
-
380
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
381
- self_geom = self_data->geom;
382
-
383
- if(self_geom) {
384
- zCoordinate = RGEO_FACTORY_DATA_PTR(self_data->factory)->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M;
385
- context = self_data->geos_context;
386
- count = GEOSGetNumGeometries_r(context, self_geom);
387
- result = rb_ary_new2(count);
388
- for(i = 0; i < count; ++i) {
389
- line_string = GEOSGetGeometryN_r(context, self_geom, i);
390
- coord_sequence = GEOSGeom_getCoordSeq_r(context, line_string);
391
- rb_ary_push(result, extract_points_from_coordinate_sequence(context, coord_sequence, zCoordinate));
392
- }
393
- }
394
-
395
- return result;
396
- }
397
-
398
- static VALUE method_multi_line_string_length(VALUE self)
399
- {
400
- VALUE result;
401
- RGeo_GeometryData* self_data;
402
- const GEOSGeometry* self_geom;
403
- double len;
404
-
405
- result = Qnil;
406
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
407
- self_geom = self_data->geom;
408
- if (self_geom) {
409
- if (GEOSLength_r(self_data->geos_context, self_geom, &len)) {
410
- result = rb_float_new(len);
411
- }
412
- }
413
- return result;
414
- }
415
-
416
-
417
- static VALUE method_multi_line_string_is_closed(VALUE self)
418
- {
419
- VALUE result;
420
- RGeo_GeometryData* self_data;
421
- const GEOSGeometry* self_geom;
422
- GEOSContextHandle_t self_context;
423
- int len;
424
- int i;
425
- const GEOSGeometry* geom;
426
-
427
- result = Qnil;
428
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
429
- self_geom = self_data->geom;
430
- if (self_geom) {
431
- self_context = self_data->geos_context;
432
- result = Qtrue;
433
- len = GEOSGetNumGeometries_r(self_context, self_geom);
434
- if (len > 0) {
435
- for (i=0; i<len; ++i) {
436
- geom = GEOSGetGeometryN_r(self_context, self_geom, i);
437
- if (geom) {
438
- result = rgeo_is_geos_line_string_closed(self_context, self_geom);
439
- if (result != Qtrue) {
440
- break;
441
- }
442
- }
443
- }
444
- }
445
- }
446
- return result;
447
- }
448
-
449
-
450
- static VALUE method_multi_polygon_geometry_type(VALUE self)
451
- {
452
- VALUE result;
453
- RGeo_GeometryData* self_data;
454
-
455
- result = Qnil;
456
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
457
- if (self_data->geom) {
458
- result = RGEO_FACTORY_DATA_PTR(self_data->factory)->globals->feature_multi_polygon;
459
- }
460
- return result;
461
- }
462
-
463
-
464
- static VALUE method_multi_polygon_hash(VALUE self)
465
- {
466
- st_index_t hash;
467
- RGeo_GeometryData* self_data;
468
- VALUE factory;
469
-
470
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
471
- factory = self_data->factory;
472
- hash = rb_hash_start(0);
473
- hash = rgeo_geos_objbase_hash(factory,
474
- RGEO_FACTORY_DATA_PTR(factory)->globals->feature_multi_polygon, hash);
475
- hash = rgeo_geos_geometry_collection_hash(self_data->geos_context, self_data->geom, hash);
476
- return LONG2FIX(rb_hash_end(hash));
477
- }
478
-
479
-
480
- static VALUE method_multi_polygon_coordinates(VALUE self)
481
- {
482
- VALUE result = Qnil;
483
- RGeo_GeometryData* self_data;
484
- const GEOSGeometry* self_geom;
485
- GEOSContextHandle_t context;
486
-
487
- const GEOSGeometry* poly;
488
- unsigned int count;
489
- unsigned int i;
490
- int zCoordinate;
491
-
492
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
493
- self_geom = self_data->geom;
494
-
495
- if(self_geom) {
496
- zCoordinate = RGEO_FACTORY_DATA_PTR(self_data->factory)->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M;
497
- context = self_data->geos_context;
498
- count = GEOSGetNumGeometries_r(context, self_geom);
499
- result = rb_ary_new2(count);
500
- for(i = 0; i < count; ++i) {
501
- poly = GEOSGetGeometryN_r(context, self_geom, i);
502
- rb_ary_push(result, extract_points_from_polygon(context, poly, zCoordinate));
503
- }
504
- }
505
-
506
- return result;
507
- }
508
-
509
-
510
- static VALUE method_multi_polygon_area(VALUE self)
511
- {
512
- VALUE result;
513
- RGeo_GeometryData* self_data;
514
- const GEOSGeometry* self_geom;
515
- double area;
516
-
517
- result = Qnil;
518
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
519
- self_geom = self_data->geom;
520
- if (self_geom) {
521
- if (GEOSArea_r(self_data->geos_context, self_geom, &area)) {
522
- result = rb_float_new(area);
523
- }
524
- }
525
- return result;
526
- }
527
-
528
-
529
- static VALUE method_multi_polygon_centroid(VALUE self)
530
- {
531
- VALUE result;
532
- RGeo_GeometryData* self_data;
533
- const GEOSGeometry* self_geom;
534
-
535
- result = Qnil;
536
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
537
- self_geom = self_data->geom;
538
- if (self_geom) {
539
- result = rgeo_wrap_geos_geometry(self_data->factory, GEOSGetCentroid_r(self_data->geos_context, self_geom), Qnil);
540
- }
541
- return result;
542
- }
543
-
544
-
545
- static VALUE method_multi_polygon_point_on_surface(VALUE self)
546
- {
547
- VALUE result;
548
- RGeo_GeometryData* self_data;
549
- const GEOSGeometry* self_geom;
550
-
551
- result = Qnil;
552
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
553
- self_geom = self_data->geom;
554
- if (self_geom) {
555
- result = rgeo_wrap_geos_geometry(self_data->factory, GEOSPointOnSurface_r(self_data->geos_context, self_geom), Qnil);
556
- }
557
- return result;
558
- }
559
-
560
-
561
- static VALUE cmethod_geometry_collection_create(VALUE module, VALUE factory, VALUE array)
562
- {
563
- return create_geometry_collection(module, GEOS_GEOMETRYCOLLECTION, factory, array);
564
- }
565
-
566
-
567
- static VALUE cmethod_multi_point_create(VALUE module, VALUE factory, VALUE array)
568
- {
569
- return create_geometry_collection(module, GEOS_MULTIPOINT, factory, array);
570
- }
571
-
572
-
573
- static VALUE cmethod_multi_line_string_create(VALUE module, VALUE factory, VALUE array)
574
- {
575
- return create_geometry_collection(module, GEOS_MULTILINESTRING, factory, array);
576
- }
577
-
578
-
579
- static VALUE cmethod_multi_polygon_create(VALUE module, VALUE factory, VALUE array)
580
- {
581
- return create_geometry_collection(module, GEOS_MULTIPOLYGON, factory, array);
582
- }
583
-
584
-
585
- /**** INITIALIZATION FUNCTION ****/
586
-
587
-
588
- void rgeo_init_geos_geometry_collection(RGeo_Globals* globals)
589
- {
590
- VALUE geos_geometry_collection_methods;
591
- VALUE geos_multi_point_methods;
592
- VALUE geos_multi_line_string_methods;
593
- VALUE geos_multi_polygon_methods;
594
-
595
- // Class methods for geometry collection classes
596
- rb_define_module_function(globals->geos_geometry_collection, "create", cmethod_geometry_collection_create, 2);
597
- rb_define_module_function(globals->geos_multi_point, "create", cmethod_multi_point_create, 2);
598
- rb_define_module_function(globals->geos_multi_line_string, "create", cmethod_multi_line_string_create, 2);
599
- rb_define_module_function(globals->geos_multi_polygon, "create", cmethod_multi_polygon_create, 2);
600
-
601
- // Methods for GeometryCollectionImpl
602
- geos_geometry_collection_methods = rb_define_module_under(globals->geos_module, "CAPIGeometryCollectionMethods");
603
- rb_define_method(geos_geometry_collection_methods, "rep_equals?", method_geometry_collection_eql, 1);
604
- rb_define_method(geos_geometry_collection_methods, "eql?", method_geometry_collection_eql, 1);
605
- rb_define_method(geos_geometry_collection_methods, "hash", method_geometry_collection_hash, 0);
606
- rb_define_method(geos_geometry_collection_methods, "geometry_type", method_geometry_collection_geometry_type, 0);
607
- rb_define_method(geos_geometry_collection_methods, "num_geometries", method_geometry_collection_num_geometries, 0);
608
- rb_define_method(geos_geometry_collection_methods, "size", method_geometry_collection_num_geometries, 0);
609
- rb_define_method(geos_geometry_collection_methods, "geometry_n", method_geometry_collection_geometry_n, 1);
610
- rb_define_method(geos_geometry_collection_methods, "[]", method_geometry_collection_brackets, 1);
611
- rb_define_method(geos_geometry_collection_methods, "each", method_geometry_collection_each, 0);
612
-
613
-
614
- // Methods for MultiPointImpl
615
- geos_multi_point_methods = rb_define_module_under(globals->geos_module, "CAPIMultiPointMethods");
616
- rb_define_method(geos_multi_point_methods, "geometry_type", method_multi_point_geometry_type, 0);
617
- rb_define_method(geos_multi_point_methods, "hash", method_multi_point_hash, 0);
618
- rb_define_method(geos_multi_point_methods, "coordinates", method_multi_point_coordinates, 0);
619
-
620
- // Methods for MultiLineStringImpl
621
- geos_multi_line_string_methods = rb_define_module_under(globals->geos_module, "CAPIMultiLineStringMethods");
622
- rb_define_method(geos_multi_line_string_methods, "geometry_type", method_multi_line_string_geometry_type, 0);
623
- rb_define_method(geos_multi_line_string_methods, "length", method_multi_line_string_length, 0);
624
- rb_define_method(geos_multi_line_string_methods, "is_closed?", method_multi_line_string_is_closed, 0);
625
- rb_define_method(geos_multi_line_string_methods, "hash", method_multi_line_string_hash, 0);
626
- rb_define_method(geos_multi_line_string_methods, "coordinates", method_multi_line_string_coordinates, 0);
627
-
628
- // Methods for MultiPolygonImpl
629
- geos_multi_polygon_methods = rb_define_module_under(globals->geos_module, "CAPIMultiPolygonMethods");
630
- rb_define_method(geos_multi_polygon_methods, "geometry_type", method_multi_polygon_geometry_type, 0);
631
- rb_define_method(geos_multi_polygon_methods, "area", method_multi_polygon_area, 0);
632
- rb_define_method(geos_multi_polygon_methods, "centroid", method_multi_polygon_centroid, 0);
633
- rb_define_method(geos_multi_polygon_methods, "point_on_surface", method_multi_polygon_point_on_surface, 0);
634
- rb_define_method(geos_multi_polygon_methods, "hash", method_multi_polygon_hash, 0);
635
- rb_define_method(geos_multi_polygon_methods, "coordinates", method_multi_polygon_coordinates, 0);
636
- }
637
-
638
-
639
- /**** OTHER PUBLIC FUNCTIONS ****/
640
-
641
-
642
- VALUE rgeo_geos_geometry_collections_eql(GEOSContextHandle_t context, const GEOSGeometry* geom1, const GEOSGeometry* geom2, char check_z)
643
- {
644
- VALUE result;
645
- int len1;
646
- int len2;
647
- int i;
648
- const GEOSGeometry* sub_geom1;
649
- const GEOSGeometry* sub_geom2;
650
- int type1;
651
- int type2;
652
-
653
- result = Qnil;
654
- if (geom1 && geom2) {
655
- len1 = GEOSGetNumGeometries_r(context, geom1);
656
- len2 = GEOSGetNumGeometries_r(context, geom2);
657
- if (len1 >= 0 && len2 >= 0) {
658
- if (len1 == len2) {
659
- result = Qtrue;
660
- for (i=0; i<len1; ++i) {
661
- sub_geom1 = GEOSGetGeometryN_r(context, geom1, i);
662
- sub_geom2 = GEOSGetGeometryN_r(context, geom2, i);
663
- if (sub_geom1 && sub_geom2) {
664
- type1 = GEOSGeomTypeId_r(context, sub_geom1);
665
- type2 = GEOSGeomTypeId_r(context, sub_geom2);
666
- if (type1 >= 0 && type2 >= 0) {
667
- if (type1 == type2) {
668
- switch (type1) {
669
- case GEOS_POINT:
670
- case GEOS_LINESTRING:
671
- case GEOS_LINEARRING:
672
- result = rgeo_geos_coordseqs_eql(context, sub_geom1, sub_geom2, check_z);
673
- break;
674
- case GEOS_POLYGON:
675
- result = rgeo_geos_polygons_eql(context, sub_geom1, sub_geom2, check_z);
676
- break;
677
- case GEOS_GEOMETRYCOLLECTION:
678
- case GEOS_MULTIPOINT:
679
- case GEOS_MULTILINESTRING:
680
- case GEOS_MULTIPOLYGON:
681
- result = rgeo_geos_geometry_collections_eql(context, sub_geom1, sub_geom2, check_z);
682
- break;
683
- default:
684
- result = Qnil;
685
- break;
686
- }
687
- if (!RTEST(result)) {
688
- break;
689
- }
690
- }
691
- else {
692
- result = Qfalse;
693
- break;
694
- }
695
- }
696
- else {
697
- result = Qnil;
698
- break;
699
- }
700
- }
701
- else {
702
- result = Qnil;
703
- break;
704
- }
705
- }
706
- }
707
- else {
708
- result = Qfalse;
709
- }
710
- }
711
- }
712
- return result;
713
- }
714
-
715
-
716
- st_index_t rgeo_geos_geometry_collection_hash(GEOSContextHandle_t context, const GEOSGeometry* geom, st_index_t hash)
717
- {
718
- const GEOSGeometry* sub_geom;
719
- int type;
720
- unsigned int len;
721
- unsigned int i;
722
-
723
- if (geom) {
724
- len = GEOSGetNumGeometries_r(context, geom);
725
- for (i=0; i<len; ++i) {
726
- sub_geom = GEOSGetGeometryN_r(context, geom, i);
727
- if (sub_geom) {
728
- type = GEOSGeomTypeId_r(context, sub_geom);
729
- if (type >= 0) {
730
- hash = hash ^ type;
731
- switch (type) {
732
- case GEOS_POINT:
733
- case GEOS_LINESTRING:
734
- case GEOS_LINEARRING:
735
- hash = rgeo_geos_coordseq_hash(context, sub_geom, hash);
736
- break;
737
- case GEOS_POLYGON:
738
- hash = rgeo_geos_polygon_hash(context, sub_geom, hash);
739
- break;
740
- case GEOS_GEOMETRYCOLLECTION:
741
- case GEOS_MULTIPOINT:
742
- case GEOS_MULTILINESTRING:
743
- case GEOS_MULTIPOLYGON:
744
- hash = rgeo_geos_geometry_collection_hash(context, sub_geom, hash);
745
- break;
746
- }
747
- }
748
- }
749
- }
750
- }
751
- return hash;
752
- }
753
-
754
-
755
- RGEO_END_C
756
-
757
- #endif