rgeo 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- 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);
|