rgeo 0.2.0 → 0.2.1

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