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.
Files changed (37) hide show
  1. data/History.rdoc +6 -0
  2. data/README.rdoc +10 -7
  3. data/Version +1 -1
  4. data/ext/geos_c_impl/extconf.rb +42 -34
  5. data/ext/geos_c_impl/factory.c +56 -39
  6. data/ext/geos_c_impl/factory.h +55 -45
  7. data/ext/geos_c_impl/geometry.c +137 -93
  8. data/ext/geos_c_impl/geometry_collection.c +67 -46
  9. data/ext/geos_c_impl/line_string.c +79 -54
  10. data/ext/geos_c_impl/point.c +37 -24
  11. data/ext/geos_c_impl/polygon.c +40 -25
  12. data/ext/proj4_c_impl/extconf.rb +44 -36
  13. data/lib/rgeo/coord_sys.rb +3 -1
  14. data/lib/rgeo/geos.rb +3 -1
  15. data/lib/rgeo/geos/impl_additions.rb +12 -10
  16. data/test/coord_sys/tc_proj4.rb +1 -1
  17. data/test/geos/tc_factory.rb +1 -1
  18. data/test/geos/tc_geometry_collection.rb +1 -1
  19. data/test/geos/tc_line_string.rb +1 -1
  20. data/test/geos/tc_misc.rb +1 -1
  21. data/test/geos/tc_multi_line_string.rb +1 -1
  22. data/test/geos/tc_multi_point.rb +1 -1
  23. data/test/geos/tc_multi_polygon.rb +1 -1
  24. data/test/geos/tc_point.rb +1 -1
  25. data/test/geos/tc_polygon.rb +1 -1
  26. data/test/geos/tc_zmfactory.rb +1 -1
  27. data/test/projected_geographic/tc_geometry_collection.rb +1 -1
  28. data/test/projected_geographic/tc_line_string.rb +1 -1
  29. data/test/projected_geographic/tc_multi_line_string.rb +1 -1
  30. data/test/projected_geographic/tc_multi_point.rb +1 -1
  31. data/test/projected_geographic/tc_multi_polygon.rb +1 -1
  32. data/test/projected_geographic/tc_point.rb +1 -1
  33. data/test/projected_geographic/tc_polygon.rb +1 -1
  34. data/test/simple_cartesian/tc_calculations.rb +1 -1
  35. data/test/tc_oneoff.rb +5 -5
  36. data/test/wkrep/tc_wkt_parser.rb +4 -4
  37. metadata +3 -3
@@ -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 RGEO_GET_GEOS_GEOMETRY(self) ? Qtrue : Qfalse;
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 RGEO_FACTORY_FROM_GEOMETRY(self);
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
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
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(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom));
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
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
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 = rb_const_get_at(RGEO_GLOBALS_FROM_GEOMETRY(self)->features_module, rb_intern("Geometry"));
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
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
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(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom));
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
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
165
+ RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
166
+ const GEOSGeometry* self_geom = self_data->geom;
163
167
  if (self_geom) {
164
- GEOSGeometry* envelope = GEOSEnvelope_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom);
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(RGEO_CONTEXT_FROM_GEOMETRY(self), envelope) == GEOS_POINT &&
169
- GEOSGetNumCoordinates_r(RGEO_CONTEXT_FROM_GEOMETRY(self), envelope) == 0) {
173
+ GEOSGeomTypeId_r(geos_context, envelope) == GEOS_POINT &&
174
+ GEOSGetNumCoordinates_r(geos_context, envelope) == 0) {
170
175
  if (envelope) {
171
- GEOSGeom_destroy_r(RGEO_CONTEXT_FROM_GEOMETRY(self), envelope);
176
+ GEOSGeom_destroy_r(geos_context, envelope);
172
177
  }
173
- envelope = GEOSGeom_createCollection_r(RGEO_CONTEXT_FROM_GEOMETRY(self), GEOS_GEOMETRYCOLLECTION, NULL, 0);
178
+ envelope = GEOSGeom_createCollection_r(geos_context, GEOS_GEOMETRYCOLLECTION, NULL, 0);
174
179
  }
175
- result = rgeo_wrap_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), envelope, Qnil);
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
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
189
+ RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
190
+ const GEOSGeometry* self_geom = self_data->geom;
185
191
  if (self_geom) {
186
- GEOSGeometry* boundary = GEOSBoundary_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom);
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(RGEO_CONTEXT_FROM_GEOMETRY(self), GEOS_GEOMETRYCOLLECTION, NULL, 0);
197
+ boundary = GEOSGeom_createCollection_r(geos_context, GEOS_GEOMETRYCOLLECTION, NULL, 0);
191
198
  }
192
- result = rgeo_wrap_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), boundary, Qnil);
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
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
208
+ RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
209
+ const GEOSGeometry* self_geom = self_data->geom;
202
210
  if (self_geom) {
203
- GEOSWKTWriter* wkt_writer = RGEO_FACTORY_DATA_FROM_GEOMETRY(self)->wkt_writer;
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(RGEO_CONTEXT_FROM_GEOMETRY(self));
206
- RGEO_FACTORY_DATA_FROM_GEOMETRY(self)->wkt_writer = wkt_writer;
215
+ wkt_writer = GEOSWKTWriter_create_r(geos_context);
216
+ factory_data->wkt_writer = wkt_writer;
207
217
  }
208
- char* str = GEOSWKTWriter_write_r(RGEO_CONTEXT_FROM_GEOMETRY(self), wkt_writer, self_geom);
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(RGEO_CONTEXT_FROM_GEOMETRY(self), str);
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
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
231
+ RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
232
+ const GEOSGeometry* self_geom = self_data->geom;
222
233
  if (self_geom) {
223
- GEOSWKBWriter* wkb_writer = RGEO_FACTORY_DATA_FROM_GEOMETRY(self)->wkb_writer;
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(RGEO_CONTEXT_FROM_GEOMETRY(self));
226
- RGEO_FACTORY_DATA_FROM_GEOMETRY(self)->wkb_writer = wkb_writer;
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(RGEO_CONTEXT_FROM_GEOMETRY(self), wkb_writer, self_geom, &size);
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(RGEO_CONTEXT_FROM_GEOMETRY(self), str);
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
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
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(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom);
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
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
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(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom);
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
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
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(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom) == 1 &&
283
- GEOSisEmpty_r(RGEO_CONTEXT_FROM_GEOMETRY(rhs), rhs_geom) == 1) {
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(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom, rhs_geom);
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
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
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(RGEO_FACTORY_FROM_GEOMETRY(self), rhs, Qnil);
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(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom, rhs_geom);
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
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
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(RGEO_FACTORY_FROM_GEOMETRY(self), rhs, Qnil);
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(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom, rhs_geom);
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
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
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(RGEO_FACTORY_FROM_GEOMETRY(self), rhs, Qnil);
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(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom, rhs_geom);
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
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
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(RGEO_FACTORY_FROM_GEOMETRY(self), rhs, Qnil);
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(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom, rhs_geom);
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
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
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(RGEO_FACTORY_FROM_GEOMETRY(self), rhs, Qnil);
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(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom, rhs_geom);
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
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
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(RGEO_FACTORY_FROM_GEOMETRY(self), rhs, Qnil);
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(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom, rhs_geom);
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
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
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(RGEO_FACTORY_FROM_GEOMETRY(self), rhs, Qnil);
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(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom, rhs_geom);
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
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
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(RGEO_FACTORY_FROM_GEOMETRY(self), rhs, Qnil);
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(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom, rhs_geom, StringValuePtr(pattern));
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
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
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(RGEO_FACTORY_FROM_GEOMETRY(self), rhs, Qnil);
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(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom, rhs_geom, &dist)) {
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
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
514
+ RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
515
+ const GEOSGeometry* self_geom = self_data->geom;
489
516
  if (self_geom) {
490
- int resolution = NUM2INT(RGEO_FACTORY_DATA_FROM_GEOMETRY(self)->buffer_resolution);
491
- result = rgeo_wrap_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), GEOSBuffer_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom, rb_num2dbl(distance), resolution), Qnil);
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
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
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(RGEO_FACTORY_FROM_GEOMETRY(self), GEOSConvexHull_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom), Qnil);
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
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
540
+ RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
541
+ const GEOSGeometry* self_geom = self_data->geom;
512
542
  if (self_geom) {
513
- const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), rhs, Qnil);
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(RGEO_FACTORY_FROM_GEOMETRY(self), GEOSIntersection_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom, rhs_geom), Qnil);
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
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
556
+ RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
557
+ const GEOSGeometry* self_geom = self_data->geom;
526
558
  if (self_geom) {
527
- const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), rhs, Qnil);
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(RGEO_FACTORY_FROM_GEOMETRY(self), GEOSUnion_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom, rhs_geom), Qnil);
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
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
572
+ RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
573
+ const GEOSGeometry* self_geom = self_data->geom;
540
574
  if (self_geom) {
541
- const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), rhs, Qnil);
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(RGEO_FACTORY_FROM_GEOMETRY(self), GEOSDifference_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom, rhs_geom), Qnil);
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
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
588
+ RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
589
+ const GEOSGeometry* self_geom = self_data->geom;
554
590
  if (self_geom) {
555
- const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), rhs, Qnil);
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(RGEO_FACTORY_FROM_GEOMETRY(self), GEOSSymDifference_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom, rhs_geom), Qnil);
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
- GEOSGeometry* self_geom = RGEO_GEOMETRY_DATA_PTR(self)->geom;
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(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom);
576
- RGEO_GEOMETRY_DATA_PTR(self)->geom = NULL;
577
- RGEO_GEOMETRY_DATA_PTR(self)->factory = Qnil;
578
- RGEO_GEOMETRY_DATA_PTR(self)->klasses = Qnil;
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
- GEOSGeometry* clone_geom = GEOSGeom_clone_r(RGEO_CONTEXT_FROM_GEOMETRY(orig), geom);
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(RGEO_CONTEXT_FROM_GEOMETRY(orig), clone_geom, GEOSGetSRID_r(RGEO_CONTEXT_FROM_GEOMETRY(orig), geom));
587
- RGEO_GEOMETRY_DATA_PTR(self)->geom = clone_geom;
588
- RGEO_GEOMETRY_DATA_PTR(self)->factory = RGEO_FACTORY_FROM_GEOMETRY(orig);
589
- RGEO_GEOMETRY_DATA_PTR(self)->klasses = RGEO_KLASSES_FROM_GEOMETRY(orig);
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);