rgeo 0.3.2 → 0.3.3
Sign up to get free protection for your applications and to get access to all the features.
- data/History.rdoc +8 -0
- data/Version +1 -1
- data/ext/geos_c_impl/extconf.rb +2 -2
- data/ext/geos_c_impl/factory.c +93 -42
- data/ext/geos_c_impl/geometry.c +327 -146
- data/ext/geos_c_impl/geometry_collection.c +157 -75
- data/ext/geos_c_impl/line_string.c +200 -93
- data/ext/geos_c_impl/main.c +3 -1
- data/ext/geos_c_impl/point.c +60 -28
- data/ext/geos_c_impl/polygon.c +108 -50
- data/ext/proj4_c_impl/extconf.rb +2 -2
- data/ext/proj4_c_impl/main.c +68 -30
- data/lib/rgeo/cartesian/bounding_box.rb +1 -1
- data/lib/rgeo/feature/factory.rb +7 -6
- data/lib/rgeo/feature/geometry.rb +4 -3
- data/lib/rgeo/geographic/projected_feature_methods.rb +1 -1
- data/lib/rgeo/geos/interface.rb +1 -1
- data/lib/rgeo/wkrep/wkt_parser.rb +7 -1
- data/test/wkrep/tc_wkt_parser.rb +13 -0
- metadata +3 -3
data/History.rdoc
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
=== 0.3.3 / 2011-12-19
|
2
|
+
|
3
|
+
* Recognizes MultiPoint WKTs in which individual points are not contained in parens. This is technically incorrect syntax, but apparently there are examples in the wild so we are now supporting it. (Reported by J Smith.)
|
4
|
+
* The Geos CAPI implementation sometimes returned the wrong result from GeometryCollection#geometry_n. Fixed.
|
5
|
+
* Fixed a hang when validating certain projected linestrings. (Patch contributed by Toby Rahilly.)
|
6
|
+
* Several rdoc updates (including a contribution by Andy Allan).
|
7
|
+
* Separated declarations and code in the C extensions to avert warnings on some compilers.
|
8
|
+
|
1
9
|
=== 0.3.2 / 2011-08-11
|
2
10
|
|
3
11
|
* Some objects can now be serialized and deserialized via Marshal or YAML. Supported objects include OGC coordinate systems, Proj4 coordinate systems, and WKRep parsers/generators. Factories and geometries will be supported shortly.
|
data/Version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.3
|
data/ext/geos_c_impl/extconf.rb
CHANGED
@@ -50,7 +50,7 @@ else
|
|
50
50
|
'/opt/geos/include',
|
51
51
|
'/opt/include',
|
52
52
|
'/Library/Frameworks/GEOS.framework/unix/include',
|
53
|
-
::
|
53
|
+
::RbConfig::CONFIG['includedir'],
|
54
54
|
'/usr/include',
|
55
55
|
]
|
56
56
|
lib_dirs_ =
|
@@ -61,7 +61,7 @@ else
|
|
61
61
|
'/opt/geos/lib',
|
62
62
|
'/opt/lib',
|
63
63
|
'/Library/Frameworks/GEOS.framework/unix/lib',
|
64
|
-
::
|
64
|
+
::RbConfig::CONFIG['libdir'],
|
65
65
|
'/usr/lib',
|
66
66
|
]
|
67
67
|
header_dirs_.delete_if{ |path_| !::File.directory?(path_) }
|
data/ext/geos_c_impl/factory.c
CHANGED
@@ -92,10 +92,12 @@ static void destroy_factory_func(RGeo_FactoryData* data)
|
|
92
92
|
|
93
93
|
static void destroy_geometry_func(RGeo_GeometryData* data)
|
94
94
|
{
|
95
|
+
const GEOSPreparedGeometry* prep;
|
96
|
+
|
95
97
|
if (data->geom) {
|
96
98
|
GEOSGeom_destroy_r(data->geos_context, data->geom);
|
97
99
|
}
|
98
|
-
|
100
|
+
prep = data->prep;
|
99
101
|
if (prep && prep != (const GEOSPreparedGeometry*)1 && prep != (const GEOSPreparedGeometry*)2 &&
|
100
102
|
prep != (const GEOSPreparedGeometry*)3)
|
101
103
|
{
|
@@ -173,17 +175,23 @@ static VALUE method_factory_flags(VALUE self)
|
|
173
175
|
|
174
176
|
static VALUE method_factory_parse_wkt(VALUE self, VALUE str)
|
175
177
|
{
|
178
|
+
RGeo_FactoryData* self_data;
|
179
|
+
GEOSContextHandle_t self_context;
|
180
|
+
GEOSWKTReader* wkt_reader;
|
181
|
+
VALUE result;
|
182
|
+
GEOSGeometry* geom;
|
183
|
+
|
176
184
|
Check_Type(str, T_STRING);
|
177
|
-
|
178
|
-
|
179
|
-
|
185
|
+
self_data = RGEO_FACTORY_DATA_PTR(self);
|
186
|
+
self_context = self_data->geos_context;
|
187
|
+
wkt_reader = self_data->wkt_reader;
|
180
188
|
if (!wkt_reader) {
|
181
189
|
wkt_reader = GEOSWKTReader_create_r(self_context);
|
182
190
|
self_data->wkt_reader = wkt_reader;
|
183
191
|
}
|
184
|
-
|
192
|
+
result = Qnil;
|
185
193
|
if (wkt_reader) {
|
186
|
-
|
194
|
+
geom = GEOSWKTReader_read_r(self_context, wkt_reader, RSTRING_PTR(str));
|
187
195
|
if (geom) {
|
188
196
|
result = rgeo_wrap_geos_geometry(self, geom, Qnil);
|
189
197
|
}
|
@@ -194,17 +202,23 @@ static VALUE method_factory_parse_wkt(VALUE self, VALUE str)
|
|
194
202
|
|
195
203
|
static VALUE method_factory_parse_wkb(VALUE self, VALUE str)
|
196
204
|
{
|
205
|
+
RGeo_FactoryData* self_data;
|
206
|
+
GEOSContextHandle_t self_context;
|
207
|
+
GEOSWKBReader* wkb_reader;
|
208
|
+
VALUE result;
|
209
|
+
GEOSGeometry* geom;
|
210
|
+
|
197
211
|
Check_Type(str, T_STRING);
|
198
|
-
|
199
|
-
|
200
|
-
|
212
|
+
self_data = RGEO_FACTORY_DATA_PTR(self);
|
213
|
+
self_context = self_data->geos_context;
|
214
|
+
wkb_reader = self_data->wkb_reader;
|
201
215
|
if (!wkb_reader) {
|
202
216
|
wkb_reader = GEOSWKBReader_create_r(self_context);
|
203
217
|
self_data->wkb_reader = wkb_reader;
|
204
218
|
}
|
205
|
-
|
219
|
+
result = Qnil;
|
206
220
|
if (wkb_reader) {
|
207
|
-
|
221
|
+
geom = GEOSWKBReader_read_r(self_context, wkb_reader, (unsigned char*)RSTRING_PTR(str), (size_t)RSTRING_LEN(str));
|
208
222
|
if (geom) {
|
209
223
|
result = rgeo_wrap_geos_geometry(self, geom, Qnil);
|
210
224
|
}
|
@@ -216,12 +230,17 @@ static VALUE method_factory_parse_wkb(VALUE self, VALUE str)
|
|
216
230
|
static VALUE cmethod_factory_create(VALUE klass, VALUE flags, VALUE srid, VALUE buffer_resolution,
|
217
231
|
VALUE wkt_generator, VALUE wkb_generator)
|
218
232
|
{
|
219
|
-
VALUE result
|
220
|
-
RGeo_FactoryData* data
|
233
|
+
VALUE result;
|
234
|
+
RGeo_FactoryData* data;
|
235
|
+
GEOSContextHandle_t context;
|
236
|
+
VALUE wrapped_globals;
|
237
|
+
|
238
|
+
result = Qnil;
|
239
|
+
data = ALLOC(RGeo_FactoryData);
|
221
240
|
if (data) {
|
222
|
-
|
241
|
+
context = initGEOS_r(message_handler, message_handler);
|
223
242
|
if (context) {
|
224
|
-
|
243
|
+
wrapped_globals = rb_const_get_at(klass, rb_intern("INTERNAL_CGLOBALS"));
|
225
244
|
data->globals = (RGeo_Globals*)DATA_PTR(wrapped_globals);
|
226
245
|
data->geos_context = context;
|
227
246
|
data->flags = NUM2INT(flags);
|
@@ -248,14 +267,19 @@ static VALUE cmethod_factory_create(VALUE klass, VALUE flags, VALUE srid, VALUE
|
|
248
267
|
|
249
268
|
RGeo_Globals* rgeo_init_geos_factory()
|
250
269
|
{
|
251
|
-
RGeo_Globals* globals
|
252
|
-
VALUE rgeo_module
|
270
|
+
RGeo_Globals* globals;
|
271
|
+
VALUE rgeo_module;
|
272
|
+
VALUE geos_factory_class;
|
273
|
+
VALUE wrapped_globals;
|
274
|
+
|
275
|
+
globals = ALLOC(RGeo_Globals);
|
276
|
+
rgeo_module = rb_define_module("RGeo");
|
253
277
|
globals->geos_module = rb_define_module_under(rgeo_module, "Geos");
|
254
278
|
globals->feature_module = rb_define_module_under(rgeo_module, "Feature");
|
255
279
|
globals->global_mixins = rb_const_get_at(rb_const_get_at(globals->feature_module, rb_intern("MixinCollection")), rb_intern("GLOBAL"));
|
256
280
|
|
257
281
|
// Add C methods to the factory.
|
258
|
-
|
282
|
+
geos_factory_class = rb_const_get_at(globals->geos_module, rb_intern("Factory"));
|
259
283
|
rb_define_method(geos_factory_class, "_parse_wkt_impl", method_factory_parse_wkt, 1);
|
260
284
|
rb_define_method(geos_factory_class, "_parse_wkb_impl", method_factory_parse_wkb, 1);
|
261
285
|
rb_define_method(geos_factory_class, "_srid", method_factory_srid, 0);
|
@@ -265,7 +289,7 @@ RGeo_Globals* rgeo_init_geos_factory()
|
|
265
289
|
|
266
290
|
// Wrap the globals in a Ruby object and store it off so we have access
|
267
291
|
// to it later. Each factory instance will reference it internally.
|
268
|
-
|
292
|
+
wrapped_globals = Data_Wrap_Struct(rb_cObject, mark_globals_func, destroy_globals_func, globals);
|
269
293
|
rb_define_const(geos_factory_class, "INTERNAL_CGLOBALS", wrapped_globals);
|
270
294
|
|
271
295
|
return globals;
|
@@ -277,15 +301,24 @@ RGeo_Globals* rgeo_init_geos_factory()
|
|
277
301
|
|
278
302
|
VALUE rgeo_wrap_geos_geometry(VALUE factory, GEOSGeometry* geom, VALUE klass)
|
279
303
|
{
|
280
|
-
VALUE result
|
304
|
+
VALUE result;
|
305
|
+
RGeo_FactoryData* factory_data;
|
306
|
+
GEOSContextHandle_t factory_context;
|
307
|
+
VALUE klasses;
|
308
|
+
RGeo_Globals* globals;
|
309
|
+
VALUE inferred_klass;
|
310
|
+
char is_collection;
|
311
|
+
RGeo_GeometryData* data;
|
312
|
+
|
313
|
+
result = Qnil;
|
281
314
|
if (geom || !NIL_P(klass)) {
|
282
|
-
|
283
|
-
|
284
|
-
|
315
|
+
factory_data = NIL_P(factory) ? NULL : RGEO_FACTORY_DATA_PTR(factory);
|
316
|
+
factory_context = factory_data ? factory_data->geos_context : NULL;
|
317
|
+
klasses = Qnil;
|
285
318
|
if (TYPE(klass) != T_CLASS) {
|
286
|
-
|
287
|
-
|
288
|
-
|
319
|
+
globals = factory_data->globals;
|
320
|
+
inferred_klass = Qnil;
|
321
|
+
is_collection = 0;
|
289
322
|
switch (GEOSGeomTypeId_r(factory_context, geom)) {
|
290
323
|
case GEOS_POINT:
|
291
324
|
inferred_klass = globals->geos_point;
|
@@ -324,7 +357,7 @@ VALUE rgeo_wrap_geos_geometry(VALUE factory, GEOSGeometry* geom, VALUE klass)
|
|
324
357
|
}
|
325
358
|
klass = inferred_klass;
|
326
359
|
}
|
327
|
-
|
360
|
+
data = ALLOC(RGeo_GeometryData);
|
328
361
|
if (data) {
|
329
362
|
if (geom) {
|
330
363
|
GEOSSetSRID_r(factory_context, geom, factory_data->srid);
|
@@ -344,9 +377,12 @@ VALUE rgeo_wrap_geos_geometry(VALUE factory, GEOSGeometry* geom, VALUE klass)
|
|
344
377
|
|
345
378
|
VALUE rgeo_wrap_geos_geometry_clone(VALUE factory, const GEOSGeometry* geom, VALUE klass)
|
346
379
|
{
|
347
|
-
VALUE result
|
380
|
+
VALUE result;
|
381
|
+
GEOSGeometry* clone_geom;
|
382
|
+
|
383
|
+
result = Qnil;
|
348
384
|
if (geom) {
|
349
|
-
|
385
|
+
clone_geom = GEOSGeom_clone_r(RGEO_FACTORY_DATA_PTR(factory)->geos_context, geom);
|
350
386
|
if (clone_geom) {
|
351
387
|
result = rgeo_wrap_geos_geometry(factory, clone_geom, klass);
|
352
388
|
}
|
@@ -358,13 +394,15 @@ VALUE rgeo_wrap_geos_geometry_clone(VALUE factory, const GEOSGeometry* geom, VAL
|
|
358
394
|
const GEOSGeometry* rgeo_convert_to_geos_geometry(VALUE factory, VALUE obj, VALUE type)
|
359
395
|
{
|
360
396
|
VALUE object;
|
397
|
+
const GEOSGeometry* geom;
|
398
|
+
|
361
399
|
if (NIL_P(type) && RGEO_GEOMETRY_DATA_PTR(obj)->factory == factory) {
|
362
400
|
object = obj;
|
363
401
|
}
|
364
402
|
else {
|
365
403
|
object = rb_funcall(RGEO_FACTORY_DATA_PTR(factory)->globals->feature_module, rb_intern("cast"), 3, obj, factory, type);
|
366
404
|
}
|
367
|
-
|
405
|
+
geom = NULL;
|
368
406
|
if (!NIL_P(object)) {
|
369
407
|
geom = RGEO_GEOMETRY_DATA_PTR(object)->geom;
|
370
408
|
}
|
@@ -374,13 +412,18 @@ const GEOSGeometry* rgeo_convert_to_geos_geometry(VALUE factory, VALUE obj, VALU
|
|
374
412
|
|
375
413
|
GEOSGeometry* rgeo_convert_to_detached_geos_geometry(VALUE obj, VALUE factory, VALUE type, VALUE* klasses)
|
376
414
|
{
|
415
|
+
VALUE object;
|
416
|
+
GEOSGeometry* geom;
|
417
|
+
RGeo_GeometryData* object_data;
|
418
|
+
const GEOSPreparedGeometry* prep;
|
419
|
+
|
377
420
|
if (klasses) {
|
378
421
|
*klasses = Qnil;
|
379
422
|
}
|
380
|
-
|
381
|
-
|
423
|
+
object = rb_funcall(RGEO_FACTORY_DATA_PTR(factory)->globals->feature_module, rb_intern("cast"), 5, obj, factory, type, ID2SYM(rb_intern("force_new")), ID2SYM(rb_intern("keep_subtype")));
|
424
|
+
geom = NULL;
|
382
425
|
if (!NIL_P(object)) {
|
383
|
-
|
426
|
+
object_data = RGEO_GEOMETRY_DATA_PTR(object);
|
384
427
|
geom = object_data->geom;
|
385
428
|
if (klasses) {
|
386
429
|
*klasses = object_data->klasses;
|
@@ -388,7 +431,7 @@ GEOSGeometry* rgeo_convert_to_detached_geos_geometry(VALUE obj, VALUE factory, V
|
|
388
431
|
*klasses = CLASS_OF(object);
|
389
432
|
}
|
390
433
|
}
|
391
|
-
|
434
|
+
prep = object_data->prep;
|
392
435
|
if (prep && prep != (GEOSPreparedGeometry*)1 && prep != (GEOSPreparedGeometry*)2) {
|
393
436
|
GEOSPreparedGeom_destroy_r(object_data->geos_context, prep);
|
394
437
|
}
|
@@ -416,18 +459,24 @@ const GEOSGeometry* rgeo_get_geos_geometry_safe(VALUE obj)
|
|
416
459
|
|
417
460
|
VALUE rgeo_geos_coordseqs_eql(GEOSContextHandle_t context, const GEOSGeometry* geom1, const GEOSGeometry* geom2, char check_z)
|
418
461
|
{
|
419
|
-
VALUE result
|
462
|
+
VALUE result;
|
463
|
+
const GEOSCoordSequence* cs1;
|
464
|
+
const GEOSCoordSequence* cs2;
|
465
|
+
unsigned int len1;
|
466
|
+
unsigned int len2;
|
467
|
+
unsigned int i;
|
468
|
+
double val1, val2;
|
469
|
+
|
470
|
+
result = Qnil;
|
420
471
|
if (geom1 && geom2) {
|
421
|
-
|
422
|
-
|
472
|
+
cs1 = GEOSGeom_getCoordSeq_r(context, geom1);
|
473
|
+
cs2 = GEOSGeom_getCoordSeq_r(context, geom2);
|
423
474
|
if (cs1 && cs2) {
|
424
|
-
|
425
|
-
|
475
|
+
len1 = 0;
|
476
|
+
len2 = 0;
|
426
477
|
if (GEOSCoordSeq_getSize_r(context, cs1, &len1) && GEOSCoordSeq_getSize_r(context, cs2, &len2)) {
|
427
478
|
if (len1 == len2) {
|
428
479
|
result = Qtrue;
|
429
|
-
unsigned int i;
|
430
|
-
double val1, val2;
|
431
480
|
for (i=0; i<len1; ++i) {
|
432
481
|
if (GEOSCoordSeq_getX_r(context, cs1, i, &val1) && GEOSCoordSeq_getX_r(context, cs2, i, &val2)) {
|
433
482
|
if (val1 == val2) {
|
@@ -483,7 +532,9 @@ VALUE rgeo_geos_coordseqs_eql(GEOSContextHandle_t context, const GEOSGeometry* g
|
|
483
532
|
|
484
533
|
VALUE rgeo_geos_klasses_and_factories_eql(VALUE obj1, VALUE obj2)
|
485
534
|
{
|
486
|
-
VALUE result
|
535
|
+
VALUE result;
|
536
|
+
|
537
|
+
result = Qnil;
|
487
538
|
if (rb_obj_class(obj1) != rb_obj_class(obj2)) {
|
488
539
|
result = Qfalse;
|
489
540
|
}
|
data/ext/geos_c_impl/geometry.c
CHANGED
@@ -57,8 +57,12 @@ RGEO_BEGIN_C
|
|
57
57
|
|
58
58
|
static int compute_dimension(GEOSContextHandle_t context, const GEOSGeometry* geom)
|
59
59
|
{
|
60
|
-
int result
|
61
|
-
int size
|
60
|
+
int result;
|
61
|
+
int size;
|
62
|
+
int i;
|
63
|
+
int dim;
|
64
|
+
|
65
|
+
result = -1;
|
62
66
|
if (geom) {
|
63
67
|
switch (GEOSGeomTypeId_r(context, geom)) {
|
64
68
|
case GEOS_POINT:
|
@@ -89,7 +93,7 @@ static int compute_dimension(GEOSContextHandle_t context, const GEOSGeometry* ge
|
|
89
93
|
case GEOS_GEOMETRYCOLLECTION:
|
90
94
|
size = GEOSGetNumGeometries_r(context, geom);
|
91
95
|
for (i=0; i<size; ++i) {
|
92
|
-
|
96
|
+
dim = compute_dimension(context, GEOSGetGeometryN_r(context, geom, i));
|
93
97
|
if (dim > result) {
|
94
98
|
result = dim;
|
95
99
|
}
|
@@ -105,7 +109,9 @@ static int compute_dimension(GEOSContextHandle_t context, const GEOSGeometry* ge
|
|
105
109
|
|
106
110
|
static const GEOSPreparedGeometry* rgeo_request_prepared_geometry(RGeo_GeometryData* object_data)
|
107
111
|
{
|
108
|
-
const GEOSPreparedGeometry* prep
|
112
|
+
const GEOSPreparedGeometry* prep;
|
113
|
+
|
114
|
+
prep = object_data->prep;
|
109
115
|
if (prep == (const GEOSPreparedGeometry*)1) {
|
110
116
|
object_data->prep = (GEOSPreparedGeometry*)2;
|
111
117
|
prep = NULL;
|
@@ -155,7 +161,9 @@ static VALUE method_geometry_set_factory(VALUE self, VALUE factory)
|
|
155
161
|
|
156
162
|
static VALUE method_geometry_prepared_p(VALUE self)
|
157
163
|
{
|
158
|
-
const GEOSPreparedGeometry* prep
|
164
|
+
const GEOSPreparedGeometry* prep;
|
165
|
+
|
166
|
+
prep = RGEO_GEOMETRY_DATA_PTR(self)->prep;
|
159
167
|
return (prep && prep != (const GEOSPreparedGeometry*)1 &&
|
160
168
|
prep != (const GEOSPreparedGeometry*)2 &&
|
161
169
|
prep != (GEOSPreparedGeometry*)3) ? Qtrue : Qfalse;
|
@@ -164,11 +172,14 @@ static VALUE method_geometry_prepared_p(VALUE self)
|
|
164
172
|
|
165
173
|
static VALUE method_geometry_prepare(VALUE self)
|
166
174
|
{
|
167
|
-
RGeo_GeometryData* self_data
|
175
|
+
RGeo_GeometryData* self_data;
|
176
|
+
const GEOSPreparedGeometry* prep;
|
177
|
+
|
178
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
168
179
|
if (self_data->geom) {
|
169
|
-
|
180
|
+
prep = self_data->prep;
|
170
181
|
if (!prep || prep == (const GEOSPreparedGeometry*)1 || prep == (const GEOSPreparedGeometry*)2) {
|
171
|
-
|
182
|
+
prep = GEOSPrepare_r(self_data->geos_context, self_data->geom);
|
172
183
|
if (prep) {
|
173
184
|
self_data->prep = prep;
|
174
185
|
}
|
@@ -183,9 +194,13 @@ static VALUE method_geometry_prepare(VALUE self)
|
|
183
194
|
|
184
195
|
static VALUE method_geometry_dimension(VALUE self)
|
185
196
|
{
|
186
|
-
VALUE result
|
187
|
-
RGeo_GeometryData* self_data
|
188
|
-
const GEOSGeometry* self_geom
|
197
|
+
VALUE result;
|
198
|
+
RGeo_GeometryData* self_data;
|
199
|
+
const GEOSGeometry* self_geom;
|
200
|
+
|
201
|
+
result = Qnil;
|
202
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
203
|
+
self_geom = self_data->geom;
|
189
204
|
if (self_geom) {
|
190
205
|
result = INT2NUM(compute_dimension(self_data->geos_context, self_geom));
|
191
206
|
}
|
@@ -195,9 +210,13 @@ static VALUE method_geometry_dimension(VALUE self)
|
|
195
210
|
|
196
211
|
static VALUE method_geometry_geometry_type(VALUE self)
|
197
212
|
{
|
198
|
-
VALUE result
|
199
|
-
RGeo_GeometryData* self_data
|
200
|
-
const GEOSGeometry* self_geom
|
213
|
+
VALUE result;
|
214
|
+
RGeo_GeometryData* self_data;
|
215
|
+
const GEOSGeometry* self_geom;
|
216
|
+
|
217
|
+
result = Qnil;
|
218
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
219
|
+
self_geom = self_data->geom;
|
201
220
|
if (self_geom) {
|
202
221
|
result = RGEO_FACTORY_DATA_PTR(self_data->factory)->globals->feature_geometry;
|
203
222
|
}
|
@@ -207,9 +226,13 @@ static VALUE method_geometry_geometry_type(VALUE self)
|
|
207
226
|
|
208
227
|
static VALUE method_geometry_srid(VALUE self)
|
209
228
|
{
|
210
|
-
VALUE result
|
211
|
-
RGeo_GeometryData* self_data
|
212
|
-
const GEOSGeometry* self_geom
|
229
|
+
VALUE result;
|
230
|
+
RGeo_GeometryData* self_data;
|
231
|
+
const GEOSGeometry* self_geom;
|
232
|
+
|
233
|
+
result = Qnil;
|
234
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
235
|
+
self_geom = self_data->geom;
|
213
236
|
if (self_geom) {
|
214
237
|
result = INT2NUM(GEOSGetSRID_r(self_data->geos_context, self_geom));
|
215
238
|
}
|
@@ -219,12 +242,18 @@ static VALUE method_geometry_srid(VALUE self)
|
|
219
242
|
|
220
243
|
static VALUE method_geometry_envelope(VALUE self)
|
221
244
|
{
|
222
|
-
VALUE result
|
223
|
-
RGeo_GeometryData* self_data
|
224
|
-
const GEOSGeometry* self_geom
|
245
|
+
VALUE result;
|
246
|
+
RGeo_GeometryData* self_data;
|
247
|
+
const GEOSGeometry* self_geom;
|
248
|
+
GEOSContextHandle_t geos_context;
|
249
|
+
GEOSGeometry* envelope;
|
250
|
+
|
251
|
+
result = Qnil;
|
252
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
253
|
+
self_geom = self_data->geom;
|
225
254
|
if (self_geom) {
|
226
|
-
|
227
|
-
|
255
|
+
geos_context = self_data->geos_context;
|
256
|
+
envelope = GEOSEnvelope_r(geos_context, self_geom);
|
228
257
|
// GEOS returns an "empty" point for an empty collection's envelope.
|
229
258
|
// We don't allow that type, so we replace it with an empty collection.
|
230
259
|
if (!envelope ||
|
@@ -243,12 +272,18 @@ static VALUE method_geometry_envelope(VALUE self)
|
|
243
272
|
|
244
273
|
static VALUE method_geometry_boundary(VALUE self)
|
245
274
|
{
|
246
|
-
VALUE result
|
247
|
-
RGeo_GeometryData* self_data
|
248
|
-
const GEOSGeometry* self_geom
|
275
|
+
VALUE result;
|
276
|
+
RGeo_GeometryData* self_data;
|
277
|
+
const GEOSGeometry* self_geom;
|
278
|
+
GEOSContextHandle_t geos_context;
|
279
|
+
GEOSGeometry* boundary;
|
280
|
+
|
281
|
+
result = Qnil;
|
282
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
283
|
+
self_geom = self_data->geom;
|
249
284
|
if (self_geom) {
|
250
|
-
|
251
|
-
|
285
|
+
geos_context = self_data->geos_context;
|
286
|
+
boundary = GEOSBoundary_r(geos_context, self_geom);
|
252
287
|
if (boundary) {
|
253
288
|
result = rgeo_wrap_geos_geometry(self_data->factory, boundary, Qnil);
|
254
289
|
}
|
@@ -259,23 +294,32 @@ static VALUE method_geometry_boundary(VALUE self)
|
|
259
294
|
|
260
295
|
static VALUE method_geometry_as_text(VALUE self)
|
261
296
|
{
|
262
|
-
VALUE result
|
263
|
-
RGeo_GeometryData* self_data
|
264
|
-
const GEOSGeometry* self_geom
|
297
|
+
VALUE result;
|
298
|
+
RGeo_GeometryData* self_data;
|
299
|
+
const GEOSGeometry* self_geom;
|
300
|
+
RGeo_FactoryData* factory_data;
|
301
|
+
VALUE wkt_generator;
|
302
|
+
GEOSWKTWriter* wkt_writer;
|
303
|
+
GEOSContextHandle_t geos_context;
|
304
|
+
char* str;
|
305
|
+
|
306
|
+
result = Qnil;
|
307
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
308
|
+
self_geom = self_data->geom;
|
265
309
|
if (self_geom) {
|
266
|
-
|
267
|
-
|
310
|
+
factory_data = RGEO_FACTORY_DATA_PTR(self_data->factory);
|
311
|
+
wkt_generator = factory_data->wkrep_wkt_generator;
|
268
312
|
if (!NIL_P(wkt_generator)) {
|
269
313
|
result = rb_funcall(wkt_generator, rb_intern("generate"), 1, self);
|
270
314
|
}
|
271
315
|
else {
|
272
|
-
|
273
|
-
|
316
|
+
wkt_writer = factory_data->wkt_writer;
|
317
|
+
geos_context = self_data->geos_context;
|
274
318
|
if (!wkt_writer) {
|
275
319
|
wkt_writer = GEOSWKTWriter_create_r(geos_context);
|
276
320
|
factory_data->wkt_writer = wkt_writer;
|
277
321
|
}
|
278
|
-
|
322
|
+
str = GEOSWKTWriter_write_r(geos_context, wkt_writer, self_geom);
|
279
323
|
if (str) {
|
280
324
|
result = rb_str_new2(str);
|
281
325
|
GEOSFree_r(geos_context, str);
|
@@ -288,24 +332,33 @@ static VALUE method_geometry_as_text(VALUE self)
|
|
288
332
|
|
289
333
|
static VALUE method_geometry_as_binary(VALUE self)
|
290
334
|
{
|
291
|
-
VALUE result
|
292
|
-
RGeo_GeometryData* self_data
|
293
|
-
const GEOSGeometry* self_geom
|
335
|
+
VALUE result;
|
336
|
+
RGeo_GeometryData* self_data;
|
337
|
+
const GEOSGeometry* self_geom;
|
338
|
+
RGeo_FactoryData* factory_data;
|
339
|
+
VALUE wkb_generator;
|
340
|
+
GEOSWKBWriter* wkb_writer;
|
341
|
+
GEOSContextHandle_t geos_context;
|
342
|
+
size_t size;
|
343
|
+
char* str;
|
344
|
+
|
345
|
+
result = Qnil;
|
346
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
347
|
+
self_geom = self_data->geom;
|
294
348
|
if (self_geom) {
|
295
|
-
|
296
|
-
|
349
|
+
factory_data = RGEO_FACTORY_DATA_PTR(self_data->factory);
|
350
|
+
wkb_generator = factory_data->wkrep_wkb_generator;
|
297
351
|
if (!NIL_P(wkb_generator)) {
|
298
352
|
result = rb_funcall(wkb_generator, rb_intern("generate"), 1, self);
|
299
353
|
}
|
300
354
|
else {
|
301
|
-
|
302
|
-
|
355
|
+
wkb_writer = factory_data->wkb_writer;
|
356
|
+
geos_context = self_data->geos_context;
|
303
357
|
if (!wkb_writer) {
|
304
358
|
wkb_writer = GEOSWKBWriter_create_r(geos_context);
|
305
359
|
factory_data->wkb_writer = wkb_writer;
|
306
360
|
}
|
307
|
-
|
308
|
-
char* str = (char*)GEOSWKBWriter_write_r(geos_context, wkb_writer, self_geom, &size);
|
361
|
+
str = (char*)GEOSWKBWriter_write_r(geos_context, wkb_writer, self_geom, &size);
|
309
362
|
if (str) {
|
310
363
|
result = rb_str_new(str, size);
|
311
364
|
GEOSFree_r(geos_context, str);
|
@@ -318,11 +371,16 @@ static VALUE method_geometry_as_binary(VALUE self)
|
|
318
371
|
|
319
372
|
static VALUE method_geometry_is_empty(VALUE self)
|
320
373
|
{
|
321
|
-
VALUE result
|
322
|
-
RGeo_GeometryData* self_data
|
323
|
-
const GEOSGeometry* self_geom
|
374
|
+
VALUE result;
|
375
|
+
RGeo_GeometryData* self_data;
|
376
|
+
const GEOSGeometry* self_geom;
|
377
|
+
char val;
|
378
|
+
|
379
|
+
result = Qnil;
|
380
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
381
|
+
self_geom = self_data->geom;
|
324
382
|
if (self_geom) {
|
325
|
-
|
383
|
+
val = GEOSisEmpty_r(self_data->geos_context, self_geom);
|
326
384
|
if (val == 0) {
|
327
385
|
result = Qfalse;
|
328
386
|
}
|
@@ -336,11 +394,16 @@ static VALUE method_geometry_is_empty(VALUE self)
|
|
336
394
|
|
337
395
|
static VALUE method_geometry_is_simple(VALUE self)
|
338
396
|
{
|
339
|
-
VALUE result
|
340
|
-
RGeo_GeometryData* self_data
|
341
|
-
const GEOSGeometry* self_geom
|
397
|
+
VALUE result;
|
398
|
+
RGeo_GeometryData* self_data;
|
399
|
+
const GEOSGeometry* self_geom;
|
400
|
+
char val;
|
401
|
+
|
402
|
+
result = Qnil;
|
403
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
404
|
+
self_geom = self_data->geom;
|
342
405
|
if (self_geom) {
|
343
|
-
|
406
|
+
val = GEOSisSimple_r(self_data->geos_context, self_geom);
|
344
407
|
if (val == 0) {
|
345
408
|
result = Qfalse;
|
346
409
|
}
|
@@ -354,13 +417,20 @@ static VALUE method_geometry_is_simple(VALUE self)
|
|
354
417
|
|
355
418
|
static VALUE method_geometry_equals(VALUE self, VALUE rhs)
|
356
419
|
{
|
357
|
-
VALUE result
|
358
|
-
RGeo_GeometryData* self_data
|
359
|
-
const GEOSGeometry* self_geom
|
420
|
+
VALUE result;
|
421
|
+
RGeo_GeometryData* self_data;
|
422
|
+
const GEOSGeometry* self_geom;
|
423
|
+
const GEOSGeometry* rhs_geom;
|
424
|
+
GEOSContextHandle_t self_context;
|
425
|
+
char val;
|
426
|
+
|
427
|
+
result = Qnil;
|
428
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
429
|
+
self_geom = self_data->geom;
|
360
430
|
if (self_geom) {
|
361
|
-
|
431
|
+
rhs_geom = rgeo_get_geos_geometry_safe(rhs);
|
362
432
|
if (rhs_geom) {
|
363
|
-
|
433
|
+
self_context = self_data->geos_context;
|
364
434
|
// GEOS has a bug where empty geometries are not spatially equal
|
365
435
|
// to each other. Work around this case first.
|
366
436
|
if (GEOSisEmpty_r(self_context, self_geom) == 1 &&
|
@@ -368,7 +438,7 @@ static VALUE method_geometry_equals(VALUE self, VALUE rhs)
|
|
368
438
|
result = Qtrue;
|
369
439
|
}
|
370
440
|
else {
|
371
|
-
|
441
|
+
val = GEOSEquals_r(self_context, self_geom, rhs_geom);
|
372
442
|
if (val == 0) {
|
373
443
|
result = Qfalse;
|
374
444
|
}
|
@@ -391,15 +461,23 @@ static VALUE method_geometry_eql(VALUE self, VALUE rhs)
|
|
391
461
|
|
392
462
|
static VALUE method_geometry_disjoint(VALUE self, VALUE rhs)
|
393
463
|
{
|
394
|
-
VALUE result
|
395
|
-
RGeo_GeometryData* self_data
|
396
|
-
const GEOSGeometry* self_geom
|
464
|
+
VALUE result;
|
465
|
+
RGeo_GeometryData* self_data;
|
466
|
+
const GEOSGeometry* self_geom;
|
467
|
+
const GEOSGeometry* rhs_geom;
|
468
|
+
char val;
|
469
|
+
#ifdef RGEO_GEOS_SUPPORTS_PREPARED2
|
470
|
+
const GEOSPreparedGeometry* prep;
|
471
|
+
#endif
|
472
|
+
|
473
|
+
result = Qnil;
|
474
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
475
|
+
self_geom = self_data->geom;
|
397
476
|
if (self_geom) {
|
398
|
-
|
477
|
+
rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
|
399
478
|
if (rhs_geom) {
|
400
|
-
char val;
|
401
479
|
#ifdef RGEO_GEOS_SUPPORTS_PREPARED2
|
402
|
-
|
480
|
+
prep = rgeo_request_prepared_geometry(self_data);
|
403
481
|
if (prep)
|
404
482
|
val = GEOSPreparedDisjoint_r(self_data->geos_context, prep, rhs_geom);
|
405
483
|
else
|
@@ -419,15 +497,23 @@ static VALUE method_geometry_disjoint(VALUE self, VALUE rhs)
|
|
419
497
|
|
420
498
|
static VALUE method_geometry_intersects(VALUE self, VALUE rhs)
|
421
499
|
{
|
422
|
-
VALUE result
|
423
|
-
RGeo_GeometryData* self_data
|
424
|
-
const GEOSGeometry* self_geom
|
500
|
+
VALUE result;
|
501
|
+
RGeo_GeometryData* self_data;
|
502
|
+
const GEOSGeometry* self_geom;
|
503
|
+
const GEOSGeometry* rhs_geom;
|
504
|
+
char val;
|
505
|
+
#ifdef RGEO_GEOS_SUPPORTS_PREPARED1
|
506
|
+
const GEOSPreparedGeometry* prep;
|
507
|
+
#endif
|
508
|
+
|
509
|
+
result = Qnil;
|
510
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
511
|
+
self_geom = self_data->geom;
|
425
512
|
if (self_geom) {
|
426
|
-
|
513
|
+
rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
|
427
514
|
if (rhs_geom) {
|
428
|
-
char val;
|
429
515
|
#ifdef RGEO_GEOS_SUPPORTS_PREPARED1
|
430
|
-
|
516
|
+
prep = rgeo_request_prepared_geometry(self_data);
|
431
517
|
if (prep)
|
432
518
|
val = GEOSPreparedIntersects_r(self_data->geos_context, prep, rhs_geom);
|
433
519
|
else
|
@@ -447,15 +533,23 @@ static VALUE method_geometry_intersects(VALUE self, VALUE rhs)
|
|
447
533
|
|
448
534
|
static VALUE method_geometry_touches(VALUE self, VALUE rhs)
|
449
535
|
{
|
450
|
-
VALUE result
|
451
|
-
RGeo_GeometryData* self_data
|
452
|
-
const GEOSGeometry* self_geom
|
536
|
+
VALUE result;
|
537
|
+
RGeo_GeometryData* self_data;
|
538
|
+
const GEOSGeometry* self_geom;
|
539
|
+
const GEOSGeometry* rhs_geom;
|
540
|
+
char val;
|
541
|
+
#ifdef RGEO_GEOS_SUPPORTS_PREPARED2
|
542
|
+
const GEOSPreparedGeometry* prep;
|
543
|
+
#endif
|
544
|
+
|
545
|
+
result = Qnil;
|
546
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
547
|
+
self_geom = self_data->geom;
|
453
548
|
if (self_geom) {
|
454
|
-
|
549
|
+
rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
|
455
550
|
if (rhs_geom) {
|
456
|
-
char val;
|
457
551
|
#ifdef RGEO_GEOS_SUPPORTS_PREPARED2
|
458
|
-
|
552
|
+
prep = rgeo_request_prepared_geometry(self_data);
|
459
553
|
if (prep)
|
460
554
|
val = GEOSPreparedTouches_r(self_data->geos_context, prep, rhs_geom);
|
461
555
|
else
|
@@ -475,15 +569,23 @@ static VALUE method_geometry_touches(VALUE self, VALUE rhs)
|
|
475
569
|
|
476
570
|
static VALUE method_geometry_crosses(VALUE self, VALUE rhs)
|
477
571
|
{
|
478
|
-
VALUE result
|
479
|
-
RGeo_GeometryData* self_data
|
480
|
-
const GEOSGeometry* self_geom
|
572
|
+
VALUE result;
|
573
|
+
RGeo_GeometryData* self_data;
|
574
|
+
const GEOSGeometry* self_geom;
|
575
|
+
const GEOSGeometry* rhs_geom;
|
576
|
+
char val;
|
577
|
+
#ifdef RGEO_GEOS_SUPPORTS_PREPARED2
|
578
|
+
const GEOSPreparedGeometry* prep;
|
579
|
+
#endif
|
580
|
+
|
581
|
+
result = Qnil;
|
582
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
583
|
+
self_geom = self_data->geom;
|
481
584
|
if (self_geom) {
|
482
|
-
|
585
|
+
rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
|
483
586
|
if (rhs_geom) {
|
484
|
-
char val;
|
485
587
|
#ifdef RGEO_GEOS_SUPPORTS_PREPARED2
|
486
|
-
|
588
|
+
prep = rgeo_request_prepared_geometry(self_data);
|
487
589
|
if (prep)
|
488
590
|
val = GEOSPreparedCrosses_r(self_data->geos_context, prep, rhs_geom);
|
489
591
|
else
|
@@ -503,15 +605,23 @@ static VALUE method_geometry_crosses(VALUE self, VALUE rhs)
|
|
503
605
|
|
504
606
|
static VALUE method_geometry_within(VALUE self, VALUE rhs)
|
505
607
|
{
|
506
|
-
VALUE result
|
507
|
-
RGeo_GeometryData* self_data
|
508
|
-
const GEOSGeometry* self_geom
|
608
|
+
VALUE result;
|
609
|
+
RGeo_GeometryData* self_data;
|
610
|
+
const GEOSGeometry* self_geom;
|
611
|
+
const GEOSGeometry* rhs_geom;
|
612
|
+
char val;
|
613
|
+
#ifdef RGEO_GEOS_SUPPORTS_PREPARED2
|
614
|
+
const GEOSPreparedGeometry* prep;
|
615
|
+
#endif
|
616
|
+
|
617
|
+
result = Qnil;
|
618
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
619
|
+
self_geom = self_data->geom;
|
509
620
|
if (self_geom) {
|
510
|
-
|
621
|
+
rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
|
511
622
|
if (rhs_geom) {
|
512
|
-
char val;
|
513
623
|
#ifdef RGEO_GEOS_SUPPORTS_PREPARED2
|
514
|
-
|
624
|
+
prep = rgeo_request_prepared_geometry(self_data);
|
515
625
|
if (prep)
|
516
626
|
val = GEOSPreparedWithin_r(self_data->geos_context, prep, rhs_geom);
|
517
627
|
else
|
@@ -531,15 +641,23 @@ static VALUE method_geometry_within(VALUE self, VALUE rhs)
|
|
531
641
|
|
532
642
|
static VALUE method_geometry_contains(VALUE self, VALUE rhs)
|
533
643
|
{
|
534
|
-
VALUE result
|
535
|
-
RGeo_GeometryData* self_data
|
536
|
-
const GEOSGeometry* self_geom
|
644
|
+
VALUE result;
|
645
|
+
RGeo_GeometryData* self_data;
|
646
|
+
const GEOSGeometry* self_geom;
|
647
|
+
const GEOSGeometry* rhs_geom;
|
648
|
+
char val;
|
649
|
+
#ifdef RGEO_GEOS_SUPPORTS_PREPARED1
|
650
|
+
const GEOSPreparedGeometry* prep;
|
651
|
+
#endif
|
652
|
+
|
653
|
+
result = Qnil;
|
654
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
655
|
+
self_geom = self_data->geom;
|
537
656
|
if (self_geom) {
|
538
|
-
|
657
|
+
rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
|
539
658
|
if (rhs_geom) {
|
540
|
-
char val;
|
541
659
|
#ifdef RGEO_GEOS_SUPPORTS_PREPARED1
|
542
|
-
|
660
|
+
prep = rgeo_request_prepared_geometry(self_data);
|
543
661
|
if (prep)
|
544
662
|
val = GEOSPreparedContains_r(self_data->geos_context, prep, rhs_geom);
|
545
663
|
else
|
@@ -559,15 +677,23 @@ static VALUE method_geometry_contains(VALUE self, VALUE rhs)
|
|
559
677
|
|
560
678
|
static VALUE method_geometry_overlaps(VALUE self, VALUE rhs)
|
561
679
|
{
|
562
|
-
VALUE result
|
563
|
-
RGeo_GeometryData* self_data
|
564
|
-
const GEOSGeometry* self_geom
|
680
|
+
VALUE result;
|
681
|
+
RGeo_GeometryData* self_data;
|
682
|
+
const GEOSGeometry* self_geom;
|
683
|
+
const GEOSGeometry* rhs_geom;
|
684
|
+
char val;
|
685
|
+
#ifdef RGEO_GEOS_SUPPORTS_PREPARED2
|
686
|
+
const GEOSPreparedGeometry* prep;
|
687
|
+
#endif
|
688
|
+
|
689
|
+
result = Qnil;
|
690
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
691
|
+
self_geom = self_data->geom;
|
565
692
|
if (self_geom) {
|
566
|
-
|
693
|
+
rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
|
567
694
|
if (rhs_geom) {
|
568
|
-
char val;
|
569
695
|
#ifdef RGEO_GEOS_SUPPORTS_PREPARED2
|
570
|
-
|
696
|
+
prep = rgeo_request_prepared_geometry(self_data);
|
571
697
|
if (prep)
|
572
698
|
val = GEOSPreparedOverlaps_r(self_data->geos_context, prep, rhs_geom);
|
573
699
|
else
|
@@ -587,13 +713,19 @@ static VALUE method_geometry_overlaps(VALUE self, VALUE rhs)
|
|
587
713
|
|
588
714
|
static VALUE method_geometry_relate(VALUE self, VALUE rhs, VALUE pattern)
|
589
715
|
{
|
590
|
-
VALUE result
|
591
|
-
RGeo_GeometryData* self_data
|
592
|
-
const GEOSGeometry* self_geom
|
716
|
+
VALUE result;
|
717
|
+
RGeo_GeometryData* self_data;
|
718
|
+
const GEOSGeometry* self_geom;
|
719
|
+
const GEOSGeometry* rhs_geom;
|
720
|
+
char val;
|
721
|
+
|
722
|
+
result = Qnil;
|
723
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
724
|
+
self_geom = self_data->geom;
|
593
725
|
if (self_geom) {
|
594
|
-
|
726
|
+
rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
|
595
727
|
if (rhs_geom) {
|
596
|
-
|
728
|
+
val = GEOSRelatePattern_r(self_data->geos_context, self_geom, rhs_geom, StringValuePtr(pattern));
|
597
729
|
if (val == 0) {
|
598
730
|
result = Qfalse;
|
599
731
|
}
|
@@ -608,13 +740,18 @@ static VALUE method_geometry_relate(VALUE self, VALUE rhs, VALUE pattern)
|
|
608
740
|
|
609
741
|
static VALUE method_geometry_distance(VALUE self, VALUE rhs)
|
610
742
|
{
|
611
|
-
VALUE result
|
612
|
-
RGeo_GeometryData* self_data
|
613
|
-
const GEOSGeometry* self_geom
|
743
|
+
VALUE result;
|
744
|
+
RGeo_GeometryData* self_data;
|
745
|
+
const GEOSGeometry* self_geom;
|
746
|
+
const GEOSGeometry* rhs_geom;
|
747
|
+
double dist;
|
748
|
+
|
749
|
+
result = Qnil;
|
750
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
751
|
+
self_geom = self_data->geom;
|
614
752
|
if (self_geom) {
|
615
|
-
|
753
|
+
rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
|
616
754
|
if (rhs_geom) {
|
617
|
-
double dist;
|
618
755
|
if (GEOSDistance_r(self_data->geos_context, self_geom, rhs_geom, &dist)) {
|
619
756
|
result = rb_float_new(dist);
|
620
757
|
}
|
@@ -626,12 +763,18 @@ static VALUE method_geometry_distance(VALUE self, VALUE rhs)
|
|
626
763
|
|
627
764
|
static VALUE method_geometry_buffer(VALUE self, VALUE distance)
|
628
765
|
{
|
629
|
-
VALUE result
|
630
|
-
RGeo_GeometryData* self_data
|
631
|
-
const GEOSGeometry* self_geom
|
766
|
+
VALUE result;
|
767
|
+
RGeo_GeometryData* self_data;
|
768
|
+
const GEOSGeometry* self_geom;
|
769
|
+
VALUE factory;
|
770
|
+
int resolution;
|
771
|
+
|
772
|
+
result = Qnil;
|
773
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
774
|
+
self_geom = self_data->geom;
|
632
775
|
if (self_geom) {
|
633
|
-
|
634
|
-
|
776
|
+
factory = self_data->factory;
|
777
|
+
resolution = NUM2INT(RGEO_FACTORY_DATA_PTR(factory)->buffer_resolution);
|
635
778
|
result = rgeo_wrap_geos_geometry(factory, GEOSBuffer_r(self_data->geos_context, self_geom, rb_num2dbl(distance), resolution), Qnil);
|
636
779
|
}
|
637
780
|
return result;
|
@@ -640,9 +783,13 @@ static VALUE method_geometry_buffer(VALUE self, VALUE distance)
|
|
640
783
|
|
641
784
|
static VALUE method_geometry_convex_hull(VALUE self)
|
642
785
|
{
|
643
|
-
VALUE result
|
644
|
-
RGeo_GeometryData* self_data
|
645
|
-
const GEOSGeometry* self_geom
|
786
|
+
VALUE result;
|
787
|
+
RGeo_GeometryData* self_data;
|
788
|
+
const GEOSGeometry* self_geom;
|
789
|
+
|
790
|
+
result = Qnil;
|
791
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
792
|
+
self_geom = self_data->geom;
|
646
793
|
if (self_geom) {
|
647
794
|
result = rgeo_wrap_geos_geometry(self_data->factory, GEOSConvexHull_r(self_data->geos_context, self_geom), Qnil);
|
648
795
|
}
|
@@ -652,12 +799,18 @@ static VALUE method_geometry_convex_hull(VALUE self)
|
|
652
799
|
|
653
800
|
static VALUE method_geometry_intersection(VALUE self, VALUE rhs)
|
654
801
|
{
|
655
|
-
VALUE result
|
656
|
-
RGeo_GeometryData* self_data
|
657
|
-
const GEOSGeometry* self_geom
|
802
|
+
VALUE result;
|
803
|
+
RGeo_GeometryData* self_data;
|
804
|
+
const GEOSGeometry* self_geom;
|
805
|
+
VALUE factory;
|
806
|
+
const GEOSGeometry* rhs_geom;
|
807
|
+
|
808
|
+
result = Qnil;
|
809
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
810
|
+
self_geom = self_data->geom;
|
658
811
|
if (self_geom) {
|
659
|
-
|
660
|
-
|
812
|
+
factory = self_data->factory;
|
813
|
+
rhs_geom = rgeo_convert_to_geos_geometry(factory, rhs, Qnil);
|
661
814
|
if (rhs_geom) {
|
662
815
|
result = rgeo_wrap_geos_geometry(factory, GEOSIntersection_r(self_data->geos_context, self_geom, rhs_geom), Qnil);
|
663
816
|
}
|
@@ -668,12 +821,18 @@ static VALUE method_geometry_intersection(VALUE self, VALUE rhs)
|
|
668
821
|
|
669
822
|
static VALUE method_geometry_union(VALUE self, VALUE rhs)
|
670
823
|
{
|
671
|
-
VALUE result
|
672
|
-
RGeo_GeometryData* self_data
|
673
|
-
const GEOSGeometry* self_geom
|
824
|
+
VALUE result;
|
825
|
+
RGeo_GeometryData* self_data;
|
826
|
+
const GEOSGeometry* self_geom;
|
827
|
+
VALUE factory;
|
828
|
+
const GEOSGeometry* rhs_geom;
|
829
|
+
|
830
|
+
result = Qnil;
|
831
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
832
|
+
self_geom = self_data->geom;
|
674
833
|
if (self_geom) {
|
675
|
-
|
676
|
-
|
834
|
+
factory = self_data->factory;
|
835
|
+
rhs_geom = rgeo_convert_to_geos_geometry(factory, rhs, Qnil);
|
677
836
|
if (rhs_geom) {
|
678
837
|
result = rgeo_wrap_geos_geometry(factory, GEOSUnion_r(self_data->geos_context, self_geom, rhs_geom), Qnil);
|
679
838
|
}
|
@@ -684,12 +843,18 @@ static VALUE method_geometry_union(VALUE self, VALUE rhs)
|
|
684
843
|
|
685
844
|
static VALUE method_geometry_difference(VALUE self, VALUE rhs)
|
686
845
|
{
|
687
|
-
VALUE result
|
688
|
-
RGeo_GeometryData* self_data
|
689
|
-
const GEOSGeometry* self_geom
|
846
|
+
VALUE result;
|
847
|
+
RGeo_GeometryData* self_data;
|
848
|
+
const GEOSGeometry* self_geom;
|
849
|
+
VALUE factory;
|
850
|
+
const GEOSGeometry* rhs_geom;
|
851
|
+
|
852
|
+
result = Qnil;
|
853
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
854
|
+
self_geom = self_data->geom;
|
690
855
|
if (self_geom) {
|
691
|
-
|
692
|
-
|
856
|
+
factory = self_data->factory;
|
857
|
+
rhs_geom = rgeo_convert_to_geos_geometry(factory, rhs, Qnil);
|
693
858
|
if (rhs_geom) {
|
694
859
|
result = rgeo_wrap_geos_geometry(factory, GEOSDifference_r(self_data->geos_context, self_geom, rhs_geom), Qnil);
|
695
860
|
}
|
@@ -700,12 +865,18 @@ static VALUE method_geometry_difference(VALUE self, VALUE rhs)
|
|
700
865
|
|
701
866
|
static VALUE method_geometry_sym_difference(VALUE self, VALUE rhs)
|
702
867
|
{
|
703
|
-
VALUE result
|
704
|
-
RGeo_GeometryData* self_data
|
705
|
-
const GEOSGeometry* self_geom
|
868
|
+
VALUE result;
|
869
|
+
RGeo_GeometryData* self_data;
|
870
|
+
const GEOSGeometry* self_geom;
|
871
|
+
VALUE factory;
|
872
|
+
const GEOSGeometry* rhs_geom;
|
873
|
+
|
874
|
+
result = Qnil;
|
875
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
876
|
+
self_geom = self_data->geom;
|
706
877
|
if (self_geom) {
|
707
|
-
|
708
|
-
|
878
|
+
factory = self_data->factory;
|
879
|
+
rhs_geom = rgeo_convert_to_geos_geometry(factory, rhs, Qnil);
|
709
880
|
if (rhs_geom) {
|
710
881
|
result = rgeo_wrap_geos_geometry(factory, GEOSSymDifference_r(self_data->geos_context, self_geom, rhs_geom), Qnil);
|
711
882
|
}
|
@@ -722,13 +893,21 @@ static VALUE alloc_geometry(VALUE klass)
|
|
722
893
|
|
723
894
|
static VALUE method_geometry_initialize_copy(VALUE self, VALUE orig)
|
724
895
|
{
|
896
|
+
RGeo_GeometryData* self_data;
|
897
|
+
const GEOSPreparedGeometry* prep;
|
898
|
+
const GEOSGeometry* geom;
|
899
|
+
RGeo_GeometryData* orig_data;
|
900
|
+
GEOSContextHandle_t orig_context;
|
901
|
+
GEOSGeometry* clone_geom;
|
902
|
+
RGeo_FactoryData* factory_data;
|
903
|
+
|
725
904
|
// Clear out any existing value
|
726
|
-
|
905
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
727
906
|
if (self_data->geom) {
|
728
907
|
GEOSGeom_destroy_r(self_data->geos_context, self_data->geom);
|
729
908
|
self_data->geom = NULL;
|
730
909
|
}
|
731
|
-
|
910
|
+
prep = self_data->prep;
|
732
911
|
if (prep && prep != (GEOSPreparedGeometry*)1 && prep != (GEOSPreparedGeometry*)2) {
|
733
912
|
GEOSPreparedGeom_destroy_r(self_data->geos_context, prep);
|
734
913
|
}
|
@@ -738,13 +917,13 @@ static VALUE method_geometry_initialize_copy(VALUE self, VALUE orig)
|
|
738
917
|
self_data->klasses = Qnil;
|
739
918
|
|
740
919
|
// Copy value from orig
|
741
|
-
|
920
|
+
geom = rgeo_get_geos_geometry_safe(orig);
|
742
921
|
if (geom) {
|
743
|
-
|
744
|
-
|
745
|
-
|
922
|
+
orig_data = RGEO_GEOMETRY_DATA_PTR(orig);
|
923
|
+
orig_context = orig_data->geos_context;
|
924
|
+
clone_geom = GEOSGeom_clone_r(orig_context, geom);
|
746
925
|
if (clone_geom) {
|
747
|
-
|
926
|
+
factory_data = RGEO_FACTORY_DATA_PTR(orig_data->factory);
|
748
927
|
GEOSSetSRID_r(orig_context, clone_geom, GEOSGetSRID_r(orig_context, geom));
|
749
928
|
self_data->geom = clone_geom;
|
750
929
|
self_data->geos_context = orig_context;
|
@@ -763,7 +942,9 @@ static VALUE method_geometry_initialize_copy(VALUE self, VALUE orig)
|
|
763
942
|
|
764
943
|
void rgeo_init_geos_geometry(RGeo_Globals* globals)
|
765
944
|
{
|
766
|
-
VALUE geos_geometry_class
|
945
|
+
VALUE geos_geometry_class;
|
946
|
+
|
947
|
+
geos_geometry_class = rb_define_class_under(globals->geos_module, "GeometryImpl", rb_cObject);
|
767
948
|
globals->geos_geometry = geos_geometry_class;
|
768
949
|
globals->feature_geometry = rb_const_get_at(globals->feature_module, rb_intern("Geometry"));
|
769
950
|
rb_funcall(globals->global_mixins, rb_intern("include_in_class"), 2,
|