rgeo 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.rdoc +6 -0
- data/README.rdoc +10 -7
- data/Version +1 -1
- data/ext/geos_c_impl/extconf.rb +42 -34
- data/ext/geos_c_impl/factory.c +56 -39
- data/ext/geos_c_impl/factory.h +55 -45
- data/ext/geos_c_impl/geometry.c +137 -93
- data/ext/geos_c_impl/geometry_collection.c +67 -46
- data/ext/geos_c_impl/line_string.c +79 -54
- data/ext/geos_c_impl/point.c +37 -24
- data/ext/geos_c_impl/polygon.c +40 -25
- data/ext/proj4_c_impl/extconf.rb +44 -36
- data/lib/rgeo/coord_sys.rb +3 -1
- data/lib/rgeo/geos.rb +3 -1
- data/lib/rgeo/geos/impl_additions.rb +12 -10
- data/test/coord_sys/tc_proj4.rb +1 -1
- data/test/geos/tc_factory.rb +1 -1
- data/test/geos/tc_geometry_collection.rb +1 -1
- data/test/geos/tc_line_string.rb +1 -1
- data/test/geos/tc_misc.rb +1 -1
- data/test/geos/tc_multi_line_string.rb +1 -1
- data/test/geos/tc_multi_point.rb +1 -1
- data/test/geos/tc_multi_polygon.rb +1 -1
- data/test/geos/tc_point.rb +1 -1
- data/test/geos/tc_polygon.rb +1 -1
- data/test/geos/tc_zmfactory.rb +1 -1
- data/test/projected_geographic/tc_geometry_collection.rb +1 -1
- data/test/projected_geographic/tc_line_string.rb +1 -1
- data/test/projected_geographic/tc_multi_line_string.rb +1 -1
- data/test/projected_geographic/tc_multi_point.rb +1 -1
- data/test/projected_geographic/tc_multi_polygon.rb +1 -1
- data/test/projected_geographic/tc_point.rb +1 -1
- data/test/projected_geographic/tc_polygon.rb +1 -1
- data/test/simple_cartesian/tc_calculations.rb +1 -1
- data/test/tc_oneoff.rb +5 -5
- data/test/wkrep/tc_wkt_parser.rb +4 -4
- metadata +3 -3
data/ext/geos_c_impl/geometry.c
CHANGED
@@ -106,13 +106,13 @@ static int compute_dimension(GEOSContextHandle_t context, const GEOSGeometry* ge
|
|
106
106
|
|
107
107
|
static VALUE method_geometry_initialized_p(VALUE self)
|
108
108
|
{
|
109
|
-
return
|
109
|
+
return RGEO_GEOMETRY_DATA_PTR(self)->geom ? Qtrue : Qfalse;
|
110
110
|
}
|
111
111
|
|
112
112
|
|
113
113
|
static VALUE method_geometry_factory(VALUE self)
|
114
114
|
{
|
115
|
-
return
|
115
|
+
return RGEO_GEOMETRY_DATA_PTR(self)->factory;
|
116
116
|
}
|
117
117
|
|
118
118
|
|
@@ -126,9 +126,10 @@ static VALUE method_geometry_set_factory(VALUE self, VALUE factory)
|
|
126
126
|
static VALUE method_geometry_dimension(VALUE self)
|
127
127
|
{
|
128
128
|
VALUE result = Qnil;
|
129
|
-
|
129
|
+
RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
130
|
+
const GEOSGeometry* self_geom = self_data->geom;
|
130
131
|
if (self_geom) {
|
131
|
-
result = INT2NUM(compute_dimension(
|
132
|
+
result = INT2NUM(compute_dimension(self_data->geos_context, self_geom));
|
132
133
|
}
|
133
134
|
return result;
|
134
135
|
}
|
@@ -137,9 +138,10 @@ static VALUE method_geometry_dimension(VALUE self)
|
|
137
138
|
static VALUE method_geometry_geometry_type(VALUE self)
|
138
139
|
{
|
139
140
|
VALUE result = Qnil;
|
140
|
-
|
141
|
+
RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
142
|
+
const GEOSGeometry* self_geom = self_data->geom;
|
141
143
|
if (self_geom) {
|
142
|
-
result =
|
144
|
+
result = RGEO_FACTORY_DATA_PTR(self_data->factory)->globals->feature_geometry;
|
143
145
|
}
|
144
146
|
return result;
|
145
147
|
}
|
@@ -148,9 +150,10 @@ static VALUE method_geometry_geometry_type(VALUE self)
|
|
148
150
|
static VALUE method_geometry_srid(VALUE self)
|
149
151
|
{
|
150
152
|
VALUE result = Qnil;
|
151
|
-
|
153
|
+
RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
154
|
+
const GEOSGeometry* self_geom = self_data->geom;
|
152
155
|
if (self_geom) {
|
153
|
-
result = INT2NUM(GEOSGetSRID_r(
|
156
|
+
result = INT2NUM(GEOSGetSRID_r(self_data->geos_context, self_geom));
|
154
157
|
}
|
155
158
|
return result;
|
156
159
|
}
|
@@ -159,20 +162,22 @@ static VALUE method_geometry_srid(VALUE self)
|
|
159
162
|
static VALUE method_geometry_envelope(VALUE self)
|
160
163
|
{
|
161
164
|
VALUE result = Qnil;
|
162
|
-
|
165
|
+
RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
166
|
+
const GEOSGeometry* self_geom = self_data->geom;
|
163
167
|
if (self_geom) {
|
164
|
-
|
168
|
+
GEOSContextHandle_t geos_context = self_data->geos_context;
|
169
|
+
GEOSGeometry* envelope = GEOSEnvelope_r(geos_context, self_geom);
|
165
170
|
// GEOS returns an "empty" point for an empty collection's envelope.
|
166
171
|
// We don't allow that type, so we replace it with an empty collection.
|
167
172
|
if (!envelope ||
|
168
|
-
GEOSGeomTypeId_r(
|
169
|
-
GEOSGetNumCoordinates_r(
|
173
|
+
GEOSGeomTypeId_r(geos_context, envelope) == GEOS_POINT &&
|
174
|
+
GEOSGetNumCoordinates_r(geos_context, envelope) == 0) {
|
170
175
|
if (envelope) {
|
171
|
-
GEOSGeom_destroy_r(
|
176
|
+
GEOSGeom_destroy_r(geos_context, envelope);
|
172
177
|
}
|
173
|
-
envelope = GEOSGeom_createCollection_r(
|
178
|
+
envelope = GEOSGeom_createCollection_r(geos_context, GEOS_GEOMETRYCOLLECTION, NULL, 0);
|
174
179
|
}
|
175
|
-
result = rgeo_wrap_geos_geometry(
|
180
|
+
result = rgeo_wrap_geos_geometry(self_data->factory, envelope, Qnil);
|
176
181
|
}
|
177
182
|
return result;
|
178
183
|
}
|
@@ -181,15 +186,17 @@ static VALUE method_geometry_envelope(VALUE self)
|
|
181
186
|
static VALUE method_geometry_boundary(VALUE self)
|
182
187
|
{
|
183
188
|
VALUE result = Qnil;
|
184
|
-
|
189
|
+
RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
190
|
+
const GEOSGeometry* self_geom = self_data->geom;
|
185
191
|
if (self_geom) {
|
186
|
-
|
192
|
+
GEOSContextHandle_t geos_context = self_data->geos_context;
|
193
|
+
GEOSGeometry* boundary = GEOSBoundary_r(geos_context, self_geom);
|
187
194
|
// GEOS returns NULL for the boundary of an empty collection.
|
188
195
|
// Replace that with an empty collection.
|
189
196
|
if (!boundary) {
|
190
|
-
boundary = GEOSGeom_createCollection_r(
|
197
|
+
boundary = GEOSGeom_createCollection_r(geos_context, GEOS_GEOMETRYCOLLECTION, NULL, 0);
|
191
198
|
}
|
192
|
-
result = rgeo_wrap_geos_geometry(
|
199
|
+
result = rgeo_wrap_geos_geometry(self_data->factory, boundary, Qnil);
|
193
200
|
}
|
194
201
|
return result;
|
195
202
|
}
|
@@ -198,17 +205,20 @@ static VALUE method_geometry_boundary(VALUE self)
|
|
198
205
|
static VALUE method_geometry_as_text(VALUE self)
|
199
206
|
{
|
200
207
|
VALUE result = Qnil;
|
201
|
-
|
208
|
+
RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
209
|
+
const GEOSGeometry* self_geom = self_data->geom;
|
202
210
|
if (self_geom) {
|
203
|
-
|
211
|
+
RGeo_FactoryData* factory_data = RGEO_FACTORY_DATA_PTR(self_data->factory);
|
212
|
+
GEOSWKTWriter* wkt_writer = factory_data->wkt_writer;
|
213
|
+
GEOSContextHandle_t geos_context = self_data->geos_context;
|
204
214
|
if (!wkt_writer) {
|
205
|
-
wkt_writer = GEOSWKTWriter_create_r(
|
206
|
-
|
215
|
+
wkt_writer = GEOSWKTWriter_create_r(geos_context);
|
216
|
+
factory_data->wkt_writer = wkt_writer;
|
207
217
|
}
|
208
|
-
char* str = GEOSWKTWriter_write_r(
|
218
|
+
char* str = GEOSWKTWriter_write_r(geos_context, wkt_writer, self_geom);
|
209
219
|
if (str) {
|
210
220
|
result = rb_str_new2(str);
|
211
|
-
GEOSFree_r(
|
221
|
+
GEOSFree_r(geos_context, str);
|
212
222
|
}
|
213
223
|
}
|
214
224
|
return result;
|
@@ -218,18 +228,21 @@ static VALUE method_geometry_as_text(VALUE self)
|
|
218
228
|
static VALUE method_geometry_as_binary(VALUE self)
|
219
229
|
{
|
220
230
|
VALUE result = Qnil;
|
221
|
-
|
231
|
+
RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
232
|
+
const GEOSGeometry* self_geom = self_data->geom;
|
222
233
|
if (self_geom) {
|
223
|
-
|
234
|
+
RGeo_FactoryData* factory_data = RGEO_FACTORY_DATA_PTR(self_data->factory);
|
235
|
+
GEOSWKBWriter* wkb_writer = factory_data->wkb_writer;
|
236
|
+
GEOSContextHandle_t geos_context = self_data->geos_context;
|
224
237
|
if (!wkb_writer) {
|
225
|
-
wkb_writer = GEOSWKBWriter_create_r(
|
226
|
-
|
238
|
+
wkb_writer = GEOSWKBWriter_create_r(geos_context);
|
239
|
+
factory_data->wkb_writer = wkb_writer;
|
227
240
|
}
|
228
241
|
size_t size;
|
229
|
-
char* str = (char*)GEOSWKBWriter_write_r(
|
242
|
+
char* str = (char*)GEOSWKBWriter_write_r(geos_context, wkb_writer, self_geom, &size);
|
230
243
|
if (str) {
|
231
244
|
result = rb_str_new(str, size);
|
232
|
-
GEOSFree_r(
|
245
|
+
GEOSFree_r(geos_context, str);
|
233
246
|
}
|
234
247
|
}
|
235
248
|
return result;
|
@@ -239,9 +252,10 @@ static VALUE method_geometry_as_binary(VALUE self)
|
|
239
252
|
static VALUE method_geometry_is_empty(VALUE self)
|
240
253
|
{
|
241
254
|
VALUE result = Qnil;
|
242
|
-
|
255
|
+
RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
256
|
+
const GEOSGeometry* self_geom = self_data->geom;
|
243
257
|
if (self_geom) {
|
244
|
-
char val = GEOSisEmpty_r(
|
258
|
+
char val = GEOSisEmpty_r(self_data->geos_context, self_geom);
|
245
259
|
if (val == 0) {
|
246
260
|
result = Qfalse;
|
247
261
|
}
|
@@ -256,9 +270,10 @@ static VALUE method_geometry_is_empty(VALUE self)
|
|
256
270
|
static VALUE method_geometry_is_simple(VALUE self)
|
257
271
|
{
|
258
272
|
VALUE result = Qnil;
|
259
|
-
|
273
|
+
RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
274
|
+
const GEOSGeometry* self_geom = self_data->geom;
|
260
275
|
if (self_geom) {
|
261
|
-
char val = GEOSisSimple_r(
|
276
|
+
char val = GEOSisSimple_r(self_data->geos_context, self_geom);
|
262
277
|
if (val == 0) {
|
263
278
|
result = Qfalse;
|
264
279
|
}
|
@@ -273,18 +288,20 @@ static VALUE method_geometry_is_simple(VALUE self)
|
|
273
288
|
static VALUE method_geometry_equals(VALUE self, VALUE rhs)
|
274
289
|
{
|
275
290
|
VALUE result = Qnil;
|
276
|
-
|
291
|
+
RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
292
|
+
const GEOSGeometry* self_geom = self_data->geom;
|
277
293
|
if (self_geom) {
|
278
294
|
const GEOSGeometry* rhs_geom = rgeo_get_geos_geometry_safe(rhs);
|
279
295
|
if (rhs_geom) {
|
296
|
+
GEOSContextHandle_t self_context = self_data->geos_context;
|
280
297
|
// GEOS has a bug where empty geometries are not spatially equal
|
281
298
|
// to each other. Work around this case first.
|
282
|
-
if (GEOSisEmpty_r(
|
283
|
-
GEOSisEmpty_r(
|
299
|
+
if (GEOSisEmpty_r(self_context, self_geom) == 1 &&
|
300
|
+
GEOSisEmpty_r(RGEO_GEOMETRY_DATA_PTR(rhs)->geos_context, rhs_geom) == 1) {
|
284
301
|
result = Qtrue;
|
285
302
|
}
|
286
303
|
else {
|
287
|
-
char val = GEOSEquals_r(
|
304
|
+
char val = GEOSEquals_r(self_context, self_geom, rhs_geom);
|
288
305
|
if (val == 0) {
|
289
306
|
result = Qfalse;
|
290
307
|
}
|
@@ -308,11 +325,12 @@ static VALUE method_geometry_eql(VALUE self, VALUE rhs)
|
|
308
325
|
static VALUE method_geometry_disjoint(VALUE self, VALUE rhs)
|
309
326
|
{
|
310
327
|
VALUE result = Qnil;
|
311
|
-
|
328
|
+
RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
329
|
+
const GEOSGeometry* self_geom = self_data->geom;
|
312
330
|
if (self_geom) {
|
313
|
-
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(
|
331
|
+
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
|
314
332
|
if (rhs_geom) {
|
315
|
-
char val = GEOSDisjoint_r(
|
333
|
+
char val = GEOSDisjoint_r(self_data->geos_context, self_geom, rhs_geom);
|
316
334
|
if (val == 0) {
|
317
335
|
result = Qfalse;
|
318
336
|
}
|
@@ -328,11 +346,12 @@ static VALUE method_geometry_disjoint(VALUE self, VALUE rhs)
|
|
328
346
|
static VALUE method_geometry_intersects(VALUE self, VALUE rhs)
|
329
347
|
{
|
330
348
|
VALUE result = Qnil;
|
331
|
-
|
349
|
+
RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
350
|
+
const GEOSGeometry* self_geom = self_data->geom;
|
332
351
|
if (self_geom) {
|
333
|
-
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(
|
352
|
+
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
|
334
353
|
if (rhs_geom) {
|
335
|
-
char val = GEOSIntersects_r(
|
354
|
+
char val = GEOSIntersects_r(self_data->geos_context, self_geom, rhs_geom);
|
336
355
|
if (val == 0) {
|
337
356
|
result = Qfalse;
|
338
357
|
}
|
@@ -348,11 +367,12 @@ static VALUE method_geometry_intersects(VALUE self, VALUE rhs)
|
|
348
367
|
static VALUE method_geometry_touches(VALUE self, VALUE rhs)
|
349
368
|
{
|
350
369
|
VALUE result = Qnil;
|
351
|
-
|
370
|
+
RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
371
|
+
const GEOSGeometry* self_geom = self_data->geom;
|
352
372
|
if (self_geom) {
|
353
|
-
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(
|
373
|
+
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
|
354
374
|
if (rhs_geom) {
|
355
|
-
char val = GEOSTouches_r(
|
375
|
+
char val = GEOSTouches_r(self_data->geos_context, self_geom, rhs_geom);
|
356
376
|
if (val == 0) {
|
357
377
|
result = Qfalse;
|
358
378
|
}
|
@@ -368,11 +388,12 @@ static VALUE method_geometry_touches(VALUE self, VALUE rhs)
|
|
368
388
|
static VALUE method_geometry_crosses(VALUE self, VALUE rhs)
|
369
389
|
{
|
370
390
|
VALUE result = Qnil;
|
371
|
-
|
391
|
+
RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
392
|
+
const GEOSGeometry* self_geom = self_data->geom;
|
372
393
|
if (self_geom) {
|
373
|
-
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(
|
394
|
+
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
|
374
395
|
if (rhs_geom) {
|
375
|
-
char val = GEOSCrosses_r(
|
396
|
+
char val = GEOSCrosses_r(self_data->geos_context, self_geom, rhs_geom);
|
376
397
|
if (val == 0) {
|
377
398
|
result = Qfalse;
|
378
399
|
}
|
@@ -388,11 +409,12 @@ static VALUE method_geometry_crosses(VALUE self, VALUE rhs)
|
|
388
409
|
static VALUE method_geometry_within(VALUE self, VALUE rhs)
|
389
410
|
{
|
390
411
|
VALUE result = Qnil;
|
391
|
-
|
412
|
+
RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
413
|
+
const GEOSGeometry* self_geom = self_data->geom;
|
392
414
|
if (self_geom) {
|
393
|
-
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(
|
415
|
+
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
|
394
416
|
if (rhs_geom) {
|
395
|
-
char val = GEOSWithin_r(
|
417
|
+
char val = GEOSWithin_r(self_data->geos_context, self_geom, rhs_geom);
|
396
418
|
if (val == 0) {
|
397
419
|
result = Qfalse;
|
398
420
|
}
|
@@ -408,11 +430,12 @@ static VALUE method_geometry_within(VALUE self, VALUE rhs)
|
|
408
430
|
static VALUE method_geometry_contains(VALUE self, VALUE rhs)
|
409
431
|
{
|
410
432
|
VALUE result = Qnil;
|
411
|
-
|
433
|
+
RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
434
|
+
const GEOSGeometry* self_geom = self_data->geom;
|
412
435
|
if (self_geom) {
|
413
|
-
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(
|
436
|
+
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
|
414
437
|
if (rhs_geom) {
|
415
|
-
char val = GEOSContains_r(
|
438
|
+
char val = GEOSContains_r(self_data->geos_context, self_geom, rhs_geom);
|
416
439
|
if (val == 0) {
|
417
440
|
result = Qfalse;
|
418
441
|
}
|
@@ -428,11 +451,12 @@ static VALUE method_geometry_contains(VALUE self, VALUE rhs)
|
|
428
451
|
static VALUE method_geometry_overlaps(VALUE self, VALUE rhs)
|
429
452
|
{
|
430
453
|
VALUE result = Qnil;
|
431
|
-
|
454
|
+
RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
455
|
+
const GEOSGeometry* self_geom = self_data->geom;
|
432
456
|
if (self_geom) {
|
433
|
-
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(
|
457
|
+
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
|
434
458
|
if (rhs_geom) {
|
435
|
-
char val = GEOSOverlaps_r(
|
459
|
+
char val = GEOSOverlaps_r(self_data->geos_context, self_geom, rhs_geom);
|
436
460
|
if (val == 0) {
|
437
461
|
result = Qfalse;
|
438
462
|
}
|
@@ -448,11 +472,12 @@ static VALUE method_geometry_overlaps(VALUE self, VALUE rhs)
|
|
448
472
|
static VALUE method_geometry_relate(VALUE self, VALUE rhs, VALUE pattern)
|
449
473
|
{
|
450
474
|
VALUE result = Qnil;
|
451
|
-
|
475
|
+
RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
476
|
+
const GEOSGeometry* self_geom = self_data->geom;
|
452
477
|
if (self_geom) {
|
453
|
-
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(
|
478
|
+
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
|
454
479
|
if (rhs_geom) {
|
455
|
-
char val = GEOSRelatePattern_r(
|
480
|
+
char val = GEOSRelatePattern_r(self_data->geos_context, self_geom, rhs_geom, StringValuePtr(pattern));
|
456
481
|
if (val == 0) {
|
457
482
|
result = Qfalse;
|
458
483
|
}
|
@@ -468,12 +493,13 @@ static VALUE method_geometry_relate(VALUE self, VALUE rhs, VALUE pattern)
|
|
468
493
|
static VALUE method_geometry_distance(VALUE self, VALUE rhs)
|
469
494
|
{
|
470
495
|
VALUE result = Qnil;
|
471
|
-
|
496
|
+
RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
497
|
+
const GEOSGeometry* self_geom = self_data->geom;
|
472
498
|
if (self_geom) {
|
473
|
-
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(
|
499
|
+
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
|
474
500
|
if (rhs_geom) {
|
475
501
|
double dist;
|
476
|
-
if (GEOSDistance_r(
|
502
|
+
if (GEOSDistance_r(self_data->geos_context, self_geom, rhs_geom, &dist)) {
|
477
503
|
result = rb_float_new(dist);
|
478
504
|
}
|
479
505
|
}
|
@@ -485,10 +511,12 @@ static VALUE method_geometry_distance(VALUE self, VALUE rhs)
|
|
485
511
|
static VALUE method_geometry_buffer(VALUE self, VALUE distance)
|
486
512
|
{
|
487
513
|
VALUE result = Qnil;
|
488
|
-
|
514
|
+
RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
515
|
+
const GEOSGeometry* self_geom = self_data->geom;
|
489
516
|
if (self_geom) {
|
490
|
-
|
491
|
-
|
517
|
+
VALUE factory = self_data->factory;
|
518
|
+
int resolution = NUM2INT(RGEO_FACTORY_DATA_PTR(factory)->buffer_resolution);
|
519
|
+
result = rgeo_wrap_geos_geometry(factory, GEOSBuffer_r(self_data->geos_context, self_geom, rb_num2dbl(distance), resolution), Qnil);
|
492
520
|
}
|
493
521
|
return result;
|
494
522
|
}
|
@@ -497,9 +525,10 @@ static VALUE method_geometry_buffer(VALUE self, VALUE distance)
|
|
497
525
|
static VALUE method_geometry_convex_hull(VALUE self)
|
498
526
|
{
|
499
527
|
VALUE result = Qnil;
|
500
|
-
|
528
|
+
RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
529
|
+
const GEOSGeometry* self_geom = self_data->geom;
|
501
530
|
if (self_geom) {
|
502
|
-
result = rgeo_wrap_geos_geometry(
|
531
|
+
result = rgeo_wrap_geos_geometry(self_data->factory, GEOSConvexHull_r(self_data->geos_context, self_geom), Qnil);
|
503
532
|
}
|
504
533
|
return result;
|
505
534
|
}
|
@@ -508,11 +537,13 @@ static VALUE method_geometry_convex_hull(VALUE self)
|
|
508
537
|
static VALUE method_geometry_intersection(VALUE self, VALUE rhs)
|
509
538
|
{
|
510
539
|
VALUE result = Qnil;
|
511
|
-
|
540
|
+
RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
541
|
+
const GEOSGeometry* self_geom = self_data->geom;
|
512
542
|
if (self_geom) {
|
513
|
-
|
543
|
+
VALUE factory = self_data->factory;
|
544
|
+
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(factory, rhs, Qnil);
|
514
545
|
if (rhs_geom) {
|
515
|
-
result = rgeo_wrap_geos_geometry(
|
546
|
+
result = rgeo_wrap_geos_geometry(factory, GEOSIntersection_r(self_data->geos_context, self_geom, rhs_geom), Qnil);
|
516
547
|
}
|
517
548
|
}
|
518
549
|
return result;
|
@@ -522,11 +553,13 @@ static VALUE method_geometry_intersection(VALUE self, VALUE rhs)
|
|
522
553
|
static VALUE method_geometry_union(VALUE self, VALUE rhs)
|
523
554
|
{
|
524
555
|
VALUE result = Qnil;
|
525
|
-
|
556
|
+
RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
557
|
+
const GEOSGeometry* self_geom = self_data->geom;
|
526
558
|
if (self_geom) {
|
527
|
-
|
559
|
+
VALUE factory = self_data->factory;
|
560
|
+
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(factory, rhs, Qnil);
|
528
561
|
if (rhs_geom) {
|
529
|
-
result = rgeo_wrap_geos_geometry(
|
562
|
+
result = rgeo_wrap_geos_geometry(factory, GEOSUnion_r(self_data->geos_context, self_geom, rhs_geom), Qnil);
|
530
563
|
}
|
531
564
|
}
|
532
565
|
return result;
|
@@ -536,11 +569,13 @@ static VALUE method_geometry_union(VALUE self, VALUE rhs)
|
|
536
569
|
static VALUE method_geometry_difference(VALUE self, VALUE rhs)
|
537
570
|
{
|
538
571
|
VALUE result = Qnil;
|
539
|
-
|
572
|
+
RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
573
|
+
const GEOSGeometry* self_geom = self_data->geom;
|
540
574
|
if (self_geom) {
|
541
|
-
|
575
|
+
VALUE factory = self_data->factory;
|
576
|
+
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(factory, rhs, Qnil);
|
542
577
|
if (rhs_geom) {
|
543
|
-
result = rgeo_wrap_geos_geometry(
|
578
|
+
result = rgeo_wrap_geos_geometry(factory, GEOSDifference_r(self_data->geos_context, self_geom, rhs_geom), Qnil);
|
544
579
|
}
|
545
580
|
}
|
546
581
|
return result;
|
@@ -550,11 +585,13 @@ static VALUE method_geometry_difference(VALUE self, VALUE rhs)
|
|
550
585
|
static VALUE method_geometry_sym_difference(VALUE self, VALUE rhs)
|
551
586
|
{
|
552
587
|
VALUE result = Qnil;
|
553
|
-
|
588
|
+
RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
589
|
+
const GEOSGeometry* self_geom = self_data->geom;
|
554
590
|
if (self_geom) {
|
555
|
-
|
591
|
+
VALUE factory = self_data->factory;
|
592
|
+
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(factory, rhs, Qnil);
|
556
593
|
if (rhs_geom) {
|
557
|
-
result = rgeo_wrap_geos_geometry(
|
594
|
+
result = rgeo_wrap_geos_geometry(factory, GEOSSymDifference_r(self_data->geos_context, self_geom, rhs_geom), Qnil);
|
558
595
|
}
|
559
596
|
}
|
560
597
|
return result;
|
@@ -570,23 +607,28 @@ static VALUE alloc_geometry(VALUE klass)
|
|
570
607
|
static VALUE method_geometry_initialize_copy(VALUE self, VALUE orig)
|
571
608
|
{
|
572
609
|
// Clear out any existing value
|
573
|
-
|
610
|
+
RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
611
|
+
GEOSGeometry* self_geom = self_data->geom;
|
574
612
|
if (self_geom) {
|
575
|
-
GEOSGeom_destroy_r(
|
576
|
-
|
577
|
-
|
578
|
-
|
613
|
+
GEOSGeom_destroy_r(self_data->geos_context, self_geom);
|
614
|
+
self_data->geom = NULL;
|
615
|
+
self_data->geos_context = NULL;
|
616
|
+
self_data->factory = Qnil;
|
617
|
+
self_data->klasses = Qnil;
|
579
618
|
}
|
580
619
|
|
581
620
|
// Copy value from orig
|
582
621
|
const GEOSGeometry* geom = rgeo_get_geos_geometry_safe(orig);
|
583
622
|
if (geom) {
|
584
|
-
|
623
|
+
RGeo_GeometryData* orig_data = RGEO_GEOMETRY_DATA_PTR(orig);
|
624
|
+
GEOSContextHandle_t orig_context = orig_data->geos_context;
|
625
|
+
GEOSGeometry* clone_geom = GEOSGeom_clone_r(orig_context, geom);
|
585
626
|
if (clone_geom) {
|
586
|
-
GEOSSetSRID_r(
|
587
|
-
|
588
|
-
|
589
|
-
|
627
|
+
GEOSSetSRID_r(orig_context, clone_geom, GEOSGetSRID_r(orig_context, geom));
|
628
|
+
self_data->geom = clone_geom;
|
629
|
+
self_data->geos_context = orig_context;
|
630
|
+
self_data->factory = orig_data->factory;
|
631
|
+
self_data->klasses = orig_data->klasses;
|
590
632
|
}
|
591
633
|
}
|
592
634
|
return self;
|
@@ -599,6 +641,8 @@ static VALUE method_geometry_initialize_copy(VALUE self, VALUE orig)
|
|
599
641
|
void rgeo_init_geos_geometry(RGeo_Globals* globals)
|
600
642
|
{
|
601
643
|
VALUE geos_geometry_class = rb_define_class_under(globals->geos_module, "GeometryImpl", rb_cObject);
|
644
|
+
globals->geos_geometry = geos_geometry_class;
|
645
|
+
globals->feature_geometry = rb_const_get_at(globals->feature_module, rb_intern("Geometry"));
|
602
646
|
|
603
647
|
rb_define_alloc_func(geos_geometry_class, alloc_geometry);
|
604
648
|
rb_define_method(geos_geometry_class, "_set_factory", method_geometry_set_factory, 1);
|