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
data/History.rdoc CHANGED
@@ -1,3 +1,9 @@
1
+ === 0.2.1 / 2010-12-09
2
+
3
+ * Now compatible with Rubinius (version 1.1 or later).
4
+ * Now partially compatible with JRuby (1.5 or later). A bunch of tests fail because GEOS and Proj4 are not available, hence there is no projection support and no complete Cartesian implementation. But at least RGeo loads and the basic operations work.
5
+ * Some minor optimizations in the GEOS glue code.
6
+
1
7
  === 0.2.0 / 2010-12-07
2
8
 
3
9
  This is the first public alpha version of RGeo. With this version, we are soft-locking the API interfaces and will try to retain backwards compatibility from this point. Incompatible API changes may still be done, but only if considered necessary.
data/README.rdoc CHANGED
@@ -39,14 +39,14 @@ Several optional modules are currently available:
39
39
  * <b>activerecord-postgis-adapter</b>
40
40
  * and more to come...
41
41
 
42
- === Requirements
42
+ === Dependencies
43
43
 
44
- RGeo has the following requirements:
44
+ RGeo is known to work with the following Ruby implementations:
45
45
 
46
- * Ruby 1.8.7 or later. Ruby 1.9.2 or later preferred.
47
- Rubinius and JRuby are not yet supported.
48
- * The build system assumes a unix-like environment. Windows builds may be
49
- possible, but not likely "out of the box".
46
+ * Standard "MRI" Ruby 1.8.7 or later. (1.9.2 or later preferred.)
47
+ * Rubinius 1.1 or later.
48
+ * Partial support for JRuby 1.5 or later, but a bunch of features are
49
+ missing because GEOS and Proj are not available from Java.
50
50
 
51
51
  Some features also require the following:
52
52
 
@@ -59,6 +59,9 @@ Some features also require the following:
59
59
  may be available via your operating system's package manager, or from
60
60
  http://trac.osgeo.org/proj
61
61
 
62
+ Note: The build system assumes a unix-like environment. Windows builds
63
+ may be possible, but not likely "out of the box".
64
+
62
65
  === Installation
63
66
 
64
67
  Install RGeo as a gem:
@@ -100,7 +103,7 @@ the core library includes:
100
103
  * Implementation of the OGC coordinate system spec.
101
104
  * Integration with spatial reference system databases.
102
105
  * Ellipsoidal geography implementation, probably utilizing geographiclib.
103
- * Rubinius and JRuby support.
106
+ * JRuby support via the JTS library.
104
107
  * Windows build support.
105
108
 
106
109
  Each of the current add-on modules also has its own feature roadmap, and
data/Version CHANGED
@@ -1 +1 @@
1
- 0.2.0
1
+ 0.2.1
@@ -34,39 +34,47 @@
34
34
  ;
35
35
 
36
36
 
37
- require 'mkmf'
38
-
39
- header_dirs_ =
40
- [
41
- '/usr/local/include',
42
- '/usr/local/geos/include',
43
- '/opt/local/include',
44
- ::Config::CONFIG['includedir'],
45
- '/usr/include',
46
- ]
47
- lib_dirs_ =
48
- [
49
- '/usr/local/lib',
50
- '/usr/local/geos/lib',
51
- '/opt/local/lib',
52
- ::Config::CONFIG['libdir'],
53
- '/usr/lib',
54
- ]
55
- header_dirs_.delete_if{ |path_| !::File.directory?(path_) }
56
- lib_dirs_.delete_if{ |path_| !::File.directory?(path_) }
57
-
58
- found_geos_ = false
59
- header_dirs_, lib_dirs_ = dir_config('geos', header_dirs_, lib_dirs_)
60
- if have_header('geos_c.h')
61
- $libs << ' -lgeos -lgeos_c'
62
- if have_func('initGEOS_r', 'geos_c.h')
63
- found_geos_ = true
64
- else
65
- $libs.gsub!(' -lgeos -lgeos_c', '')
37
+ if ::RUBY_DESCRIPTION =~ /^jruby\s/
38
+
39
+ ::File.open('Makefile', 'w'){ |f_| f_.write(".PHONY: install\ninstall:\n") }
40
+
41
+ else
42
+
43
+ require 'mkmf'
44
+
45
+ header_dirs_ =
46
+ [
47
+ '/usr/local/include',
48
+ '/usr/local/geos/include',
49
+ '/opt/local/include',
50
+ ::Config::CONFIG['includedir'],
51
+ '/usr/include',
52
+ ]
53
+ lib_dirs_ =
54
+ [
55
+ '/usr/local/lib',
56
+ '/usr/local/geos/lib',
57
+ '/opt/local/lib',
58
+ ::Config::CONFIG['libdir'],
59
+ '/usr/lib',
60
+ ]
61
+ header_dirs_.delete_if{ |path_| !::File.directory?(path_) }
62
+ lib_dirs_.delete_if{ |path_| !::File.directory?(path_) }
63
+
64
+ found_geos_ = false
65
+ header_dirs_, lib_dirs_ = dir_config('geos', header_dirs_, lib_dirs_)
66
+ if have_header('geos_c.h')
67
+ $libs << ' -lgeos -lgeos_c'
68
+ if have_func('initGEOS_r', 'geos_c.h')
69
+ found_geos_ = true
70
+ else
71
+ $libs.gsub!(' -lgeos -lgeos_c', '')
72
+ end
66
73
  end
74
+ unless found_geos_
75
+ puts "**** WARNING: Unable to find GEOS headers or GEOS version is too old."
76
+ puts "**** Compiling without GEOS support."
77
+ end
78
+ create_makefile('rgeo/geos/geos_c_impl')
79
+
67
80
  end
68
- unless found_geos_
69
- puts "**** WARNING: Unable to find GEOS headers or GEOS version is too old."
70
- puts "**** Compiling without GEOS support."
71
- end
72
- create_makefile('rgeo/geos/geos_c_impl')
@@ -69,19 +69,20 @@ static void message_handler(const char* fmt, ...)
69
69
 
70
70
  static void destroy_factory_func(RGeo_FactoryData* data)
71
71
  {
72
+ GEOSContextHandle_t context = data->geos_context;
72
73
  if (data->wkt_reader) {
73
- GEOSWKTReader_destroy_r(data->geos_context, data->wkt_reader);
74
+ GEOSWKTReader_destroy_r(context, data->wkt_reader);
74
75
  }
75
76
  if (data->wkb_reader) {
76
- GEOSWKBReader_destroy_r(data->geos_context, data->wkb_reader);
77
+ GEOSWKBReader_destroy_r(context, data->wkb_reader);
77
78
  }
78
79
  if (data->wkt_writer) {
79
- GEOSWKTWriter_destroy_r(data->geos_context, data->wkt_writer);
80
+ GEOSWKTWriter_destroy_r(context, data->wkt_writer);
80
81
  }
81
82
  if (data->wkb_writer) {
82
- GEOSWKBWriter_destroy_r(data->geos_context, data->wkb_writer);
83
+ GEOSWKBWriter_destroy_r(context, data->wkb_writer);
83
84
  }
84
- finishGEOS_r(data->geos_context);
85
+ finishGEOS_r(context);
85
86
  free(data);
86
87
  }
87
88
 
@@ -92,7 +93,7 @@ static void destroy_factory_func(RGeo_FactoryData* data)
92
93
  static void destroy_geometry_func(RGeo_GeometryData* data)
93
94
  {
94
95
  if (data->geom) {
95
- GEOSGeom_destroy_r(RGEO_CONTEXT_FROM_FACTORY(data->factory), data->geom);
96
+ GEOSGeom_destroy_r(data->geos_context, data->geom);
96
97
  }
97
98
  free(data);
98
99
  }
@@ -153,14 +154,16 @@ static VALUE method_factory_flags(VALUE self)
153
154
  static VALUE method_factory_parse_wkt(VALUE self, VALUE str)
154
155
  {
155
156
  Check_Type(str, T_STRING);
156
- GEOSWKTReader* wkt_reader = RGEO_FACTORY_DATA_PTR(self)->wkt_reader;
157
+ RGeo_FactoryData* self_data = RGEO_FACTORY_DATA_PTR(self);
158
+ GEOSContextHandle_t self_context = self_data->geos_context;
159
+ GEOSWKTReader* wkt_reader = self_data->wkt_reader;
157
160
  if (!wkt_reader) {
158
- wkt_reader = GEOSWKTReader_create_r(RGEO_CONTEXT_FROM_FACTORY(self));
159
- RGEO_FACTORY_DATA_PTR(self)->wkt_reader = wkt_reader;
161
+ wkt_reader = GEOSWKTReader_create_r(self_context);
162
+ self_data->wkt_reader = wkt_reader;
160
163
  }
161
164
  VALUE result = Qnil;
162
165
  if (wkt_reader) {
163
- GEOSGeometry* geom = GEOSWKTReader_read_r(RGEO_CONTEXT_FROM_FACTORY(self), wkt_reader, RSTRING_PTR(str));
166
+ GEOSGeometry* geom = GEOSWKTReader_read_r(self_context, wkt_reader, RSTRING_PTR(str));
164
167
  if (geom) {
165
168
  result = rgeo_wrap_geos_geometry(self, geom, Qnil);
166
169
  }
@@ -172,14 +175,16 @@ static VALUE method_factory_parse_wkt(VALUE self, VALUE str)
172
175
  static VALUE method_factory_parse_wkb(VALUE self, VALUE str)
173
176
  {
174
177
  Check_Type(str, T_STRING);
175
- GEOSWKBReader* wkb_reader = RGEO_FACTORY_DATA_PTR(self)->wkb_reader;
178
+ RGeo_FactoryData* self_data = RGEO_FACTORY_DATA_PTR(self);
179
+ GEOSContextHandle_t self_context = self_data->geos_context;
180
+ GEOSWKBReader* wkb_reader = self_data->wkb_reader;
176
181
  if (!wkb_reader) {
177
- wkb_reader = GEOSWKBReader_create_r(RGEO_CONTEXT_FROM_FACTORY(self));
178
- RGEO_FACTORY_DATA_PTR(self)->wkb_reader = wkb_reader;
182
+ wkb_reader = GEOSWKBReader_create_r(self_context);
183
+ self_data->wkb_reader = wkb_reader;
179
184
  }
180
185
  VALUE result = Qnil;
181
186
  if (wkb_reader) {
182
- GEOSGeometry* geom = GEOSWKBReader_read_r(RGEO_CONTEXT_FROM_FACTORY(self), wkb_reader, (unsigned char*)RSTRING_PTR(str), (size_t)RSTRING_LEN(str));
187
+ GEOSGeometry* geom = GEOSWKBReader_read_r(self_context, wkb_reader, (unsigned char*)RSTRING_PTR(str), (size_t)RSTRING_LEN(str));
183
188
  if (geom) {
184
189
  result = rgeo_wrap_geos_geometry(self, geom, Qnil);
185
190
  }
@@ -223,7 +228,7 @@ RGeo_Globals* rgeo_init_geos_factory()
223
228
  RGeo_Globals* globals = ALLOC(RGeo_Globals);
224
229
  VALUE rgeo_module = rb_define_module("RGeo");
225
230
  globals->geos_module = rb_define_module_under(rgeo_module, "Geos");
226
- globals->features_module = rb_define_module_under(rgeo_module, "Feature");
231
+ globals->feature_module = rb_define_module_under(rgeo_module, "Feature");
227
232
 
228
233
  // Add C methods to the factory.
229
234
  VALUE geos_factory_class = rb_const_get_at(globals->geos_module, rb_intern("Factory"));
@@ -250,54 +255,58 @@ VALUE rgeo_wrap_geos_geometry(VALUE factory, GEOSGeometry* geom, VALUE klass)
250
255
  {
251
256
  VALUE result = Qnil;
252
257
  if (geom || !NIL_P(klass)) {
258
+ RGeo_FactoryData* factory_data = NIL_P(factory) ? NULL : RGEO_FACTORY_DATA_PTR(factory);
259
+ GEOSContextHandle_t factory_context = factory_data ? factory_data->geos_context : NULL;
253
260
  VALUE klasses = Qnil;
254
261
  if (TYPE(klass) != T_CLASS) {
255
- const char* klass_name = NULL;
262
+ RGeo_Globals* globals = factory_data->globals;
263
+ VALUE inferred_klass = Qnil;
256
264
  char is_collection = 0;
257
- switch (GEOSGeomTypeId_r(RGEO_CONTEXT_FROM_FACTORY(factory), geom)) {
265
+ switch (GEOSGeomTypeId_r(factory_context, geom)) {
258
266
  case GEOS_POINT:
259
- klass_name = "PointImpl";
267
+ inferred_klass = globals->geos_point;
260
268
  break;
261
269
  case GEOS_LINESTRING:
262
- klass_name = "LineStringImpl";
270
+ inferred_klass = globals->geos_line_string;
263
271
  break;
264
272
  case GEOS_LINEARRING:
265
- klass_name = "LinearRingImpl";
273
+ inferred_klass = globals->geos_linear_ring;
266
274
  break;
267
275
  case GEOS_POLYGON:
268
- klass_name = "PolygonImpl";
276
+ inferred_klass = globals->geos_polygon;
269
277
  break;
270
278
  case GEOS_MULTIPOINT:
271
- klass_name = "MultiPointImpl";
279
+ inferred_klass = globals->geos_multi_point;
272
280
  is_collection = 1;
273
281
  break;
274
282
  case GEOS_MULTILINESTRING:
275
- klass_name = "MultiLineStringImpl";
283
+ inferred_klass = globals->geos_multi_line_string;
276
284
  is_collection = 1;
277
285
  break;
278
286
  case GEOS_MULTIPOLYGON:
279
- klass_name = "MultiPolygonImpl";
287
+ inferred_klass = globals->geos_multi_polygon;
280
288
  is_collection = 1;
281
289
  break;
282
290
  case GEOS_GEOMETRYCOLLECTION:
283
- klass_name = "GeometryCollectionImpl";
291
+ inferred_klass = globals->geos_geometry_collection;
284
292
  is_collection = 1;
285
293
  break;
286
294
  default:
287
- klass_name = "GeometryImpl";
295
+ inferred_klass = globals->geos_geometry;
288
296
  break;
289
297
  }
290
298
  if (TYPE(klass) == T_ARRAY && is_collection) {
291
299
  klasses = klass;
292
300
  }
293
- klass = rb_const_get_at(RGEO_GLOBALS_FROM_FACTORY(factory)->geos_module, rb_intern(klass_name));
301
+ klass = inferred_klass;
294
302
  }
295
303
  RGeo_GeometryData* data = ALLOC(RGeo_GeometryData);
296
304
  if (data) {
297
305
  if (geom) {
298
- GEOSSetSRID_r(RGEO_CONTEXT_FROM_FACTORY(factory), geom, RGEO_FACTORY_DATA_PTR(factory)->srid);
306
+ GEOSSetSRID_r(factory_context, geom, factory_data->srid);
299
307
  }
300
308
  data->geom = geom;
309
+ data->geos_context = factory_context;
301
310
  data->factory = factory;
302
311
  data->klasses = klasses;
303
312
  result = Data_Wrap_Struct(klass, mark_geometry_func, destroy_geometry_func, data);
@@ -311,7 +320,7 @@ VALUE rgeo_wrap_geos_geometry_clone(VALUE factory, const GEOSGeometry* geom, VAL
311
320
  {
312
321
  VALUE result = Qnil;
313
322
  if (geom) {
314
- GEOSGeometry* clone_geom = GEOSGeom_clone_r(RGEO_CONTEXT_FROM_FACTORY(factory), geom);
323
+ GEOSGeometry* clone_geom = GEOSGeom_clone_r(RGEO_FACTORY_DATA_PTR(factory)->geos_context, geom);
315
324
  if (clone_geom) {
316
325
  result = rgeo_wrap_geos_geometry(factory, clone_geom, klass);
317
326
  }
@@ -322,10 +331,16 @@ VALUE rgeo_wrap_geos_geometry_clone(VALUE factory, const GEOSGeometry* geom, VAL
322
331
 
323
332
  const GEOSGeometry* rgeo_convert_to_geos_geometry(VALUE factory, VALUE obj, VALUE type)
324
333
  {
325
- VALUE object = rb_funcall(RGEO_GLOBALS_FROM_FACTORY(factory)->features_module, rb_intern("cast"), 3, obj, factory, type);
334
+ VALUE object;
335
+ if (NIL_P(type) && RGEO_GEOMETRY_DATA_PTR(obj)->factory == factory) {
336
+ object = obj;
337
+ }
338
+ else {
339
+ object = rb_funcall(RGEO_FACTORY_DATA_PTR(factory)->globals->feature_module, rb_intern("cast"), 3, obj, factory, type);
340
+ }
326
341
  const GEOSGeometry* geom = NULL;
327
342
  if (!NIL_P(object)) {
328
- geom = RGEO_GET_GEOS_GEOMETRY(object);
343
+ geom = RGEO_GEOMETRY_DATA_PTR(object)->geom;
329
344
  }
330
345
  return geom;
331
346
  }
@@ -336,19 +351,21 @@ GEOSGeometry* rgeo_convert_to_detached_geos_geometry(VALUE obj, VALUE factory, V
336
351
  if (klasses) {
337
352
  *klasses = Qnil;
338
353
  }
339
- VALUE object = rb_funcall(RGEO_GLOBALS_FROM_FACTORY(factory)->features_module, rb_intern("cast"), 5, obj, factory, type, ID2SYM(rb_intern("force_new")), ID2SYM(rb_intern("keep_subtype")));
354
+ VALUE object = rb_funcall(RGEO_FACTORY_DATA_PTR(factory)->globals->feature_module, rb_intern("cast"), 5, obj, factory, type, ID2SYM(rb_intern("force_new")), ID2SYM(rb_intern("keep_subtype")));
340
355
  GEOSGeometry* geom = NULL;
341
356
  if (!NIL_P(object)) {
342
- geom = RGEO_GEOMETRY_DATA_PTR(object)->geom;
357
+ RGeo_GeometryData* object_data = RGEO_GEOMETRY_DATA_PTR(object);
358
+ geom = object_data->geom;
343
359
  if (klasses) {
344
- *klasses = RGEO_KLASSES_FROM_GEOMETRY(object);
360
+ *klasses = object_data->klasses;
345
361
  if (NIL_P(*klasses)) {
346
362
  *klasses = CLASS_OF(object);
347
363
  }
348
364
  }
349
- RGEO_GEOMETRY_DATA_PTR(object)->geom = NULL;
350
- RGEO_GEOMETRY_DATA_PTR(object)->factory = Qnil;
351
- RGEO_GEOMETRY_DATA_PTR(object)->klasses = Qnil;
365
+ object_data->geom = NULL;
366
+ object_data->geos_context = NULL;
367
+ object_data->factory = Qnil;
368
+ object_data->klasses = Qnil;
352
369
  }
353
370
  return geom;
354
371
  }
@@ -362,7 +379,7 @@ char rgeo_is_geos_object(VALUE obj)
362
379
 
363
380
  const GEOSGeometry* rgeo_get_geos_geometry_safe(VALUE obj)
364
381
  {
365
- return (TYPE(obj) == T_DATA && RDATA(obj)->dfree == (RUBY_DATA_FUNC)destroy_geometry_func) ? RGEO_GET_GEOS_GEOMETRY(obj) : NULL;
382
+ return (TYPE(obj) == T_DATA && RDATA(obj)->dfree == (RUBY_DATA_FUNC)destroy_geometry_func) ? (const GEOSGeometry*)(RGEO_GEOMETRY_DATA_PTR(obj)->geom) : NULL;
366
383
  }
367
384
 
368
385
 
@@ -440,7 +457,7 @@ VALUE rgeo_geos_klasses_and_factories_eql(VALUE obj1, VALUE obj2)
440
457
  result = Qfalse;
441
458
  }
442
459
  else {
443
- result = rb_funcall(RGEO_FACTORY_FROM_GEOMETRY(obj1), rb_intern("eql?"), 1, RGEO_FACTORY_FROM_GEOMETRY(obj2));
460
+ result = rb_funcall(RGEO_GEOMETRY_DATA_PTR(obj1)->factory, rb_intern("eql?"), 1, RGEO_GEOMETRY_DATA_PTR(obj2)->factory);
444
461
  }
445
462
  return result;
446
463
  }
@@ -44,20 +44,44 @@
44
44
  RGEO_BEGIN_C
45
45
 
46
46
 
47
- // Per-interpreter globals
48
-
47
+ /*
48
+ Per-interpreter globals.
49
+ Most of these are cached references to commonly used classes and modules
50
+ so we don't have to do a lot of constant lookups.
51
+ */
49
52
  typedef struct {
50
- VALUE features_module;
53
+ VALUE feature_module;
54
+ VALUE feature_geometry;
55
+ VALUE feature_point;
56
+ VALUE feature_line_string;
57
+ VALUE feature_linear_ring;
58
+ VALUE feature_line;
59
+ VALUE feature_polygon;
60
+ VALUE feature_geometry_collection;
61
+ VALUE feature_multi_point;
62
+ VALUE feature_multi_line_string;
63
+ VALUE feature_multi_polygon;
51
64
  VALUE geos_module;
65
+ VALUE geos_geometry;
66
+ VALUE geos_point;
67
+ VALUE geos_line_string;
68
+ VALUE geos_linear_ring;
69
+ VALUE geos_line;
70
+ VALUE geos_polygon;
71
+ VALUE geos_geometry_collection;
72
+ VALUE geos_multi_point;
73
+ VALUE geos_multi_line_string;
74
+ VALUE geos_multi_polygon;
52
75
  } RGeo_Globals;
53
76
 
54
77
 
55
- // Wrapped structure for Factory objects.
56
- // A factory encapsulates the GEOS context, and GEOS serializer settings.
57
- // It also stores the SRID for all geometries created by this factory,
58
- // and the resolution for buffers created for this factory's geometries.
59
- // Finally, it provides easy access to the globals.
60
-
78
+ /*
79
+ Wrapped structure for Factory objects.
80
+ A factory encapsulates the GEOS context, and GEOS serializer settings.
81
+ It also stores the SRID for all geometries created by this factory,
82
+ and the resolution for buffers created for this factory's geometries.
83
+ Finally, it provides easy access to the globals.
84
+ */
61
85
  typedef struct {
62
86
  RGeo_Globals* globals;
63
87
  GEOSContextHandle_t geos_context;
@@ -76,20 +100,30 @@ typedef struct {
76
100
  #define RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M 6
77
101
 
78
102
 
79
- // Wrapped structure for Geometry objects.
80
- // Includes a handle to the underlying GEOS geometry itself (which could
81
- // be null for an uninitialized geometry).
82
- // It also provides a handle to the factory that created this geometry.
83
- // The klasses object is used by geometry collections. Its value is
84
- // generally an array of the ruby classes for the colletion's elements,
85
- // so that we can reproduce the exact class for those elements in cases
86
- // where the class cannot be inferred directly from the GEOS type (as
87
- // in Line objects, which have no GEOS type). Any array element, or the
88
- // array itself, could be Qnil, indicating fall back to the default
89
- // inferred from the GEOS type.
90
-
103
+ /*
104
+ Wrapped structure for Geometry objects.
105
+ Includes a handle to the underlying GEOS geometry itself (which could
106
+ be null for an uninitialized geometry).
107
+ It also provides a handle to the factory that created this geometry.
108
+
109
+ The klasses object is used by geometry collections. Its value is
110
+ generally an array of the ruby classes for the colletion's elements,
111
+ so that we can reproduce the exact class for those elements in cases
112
+ where the class cannot be inferred directly from the GEOS type (as
113
+ in Line objects, which have no GEOS type). Any array element, or the
114
+ array itself, could be Qnil, indicating fall back to the default
115
+ inferred from the GEOS type.
116
+
117
+ The GEOS context handle is also included here. Ideally, it would be
118
+ available by following the factory reference and getting it from the
119
+ factory data. However, one use case is in the destroy_geometry_func
120
+ in factory.c, and Rubinius 1.1.1 seems to crash when you try to
121
+ evaluate a DATA_PTR from that function, so we copy the context handle
122
+ here so the destroy_geometry_func can get to it.
123
+ */
91
124
  typedef struct {
92
125
  GEOSGeometry* geom;
126
+ GEOSContextHandle_t geos_context;
93
127
  VALUE factory;
94
128
  VALUE klasses;
95
129
  } RGeo_GeometryData;
@@ -101,30 +135,6 @@ typedef struct {
101
135
  // Returns the RGeo_GeometryData* given a ruby Geometry object
102
136
  #define RGEO_GEOMETRY_DATA_PTR(geometry) ((RGeo_GeometryData*)DATA_PTR(geometry))
103
137
 
104
- // Returns a pointer to the globals given a ruby Factory object
105
- #define RGEO_GLOBALS_FROM_FACTORY(factory) (RGEO_FACTORY_DATA_PTR(factory)->globals)
106
-
107
- // Returns the GEOS context handle given a ruby Factory object
108
- #define RGEO_CONTEXT_FROM_FACTORY(factory) (RGEO_FACTORY_DATA_PTR(factory)->geos_context)
109
-
110
- // Returns the ruby Factory object given a ruby Geometry object
111
- #define RGEO_FACTORY_FROM_GEOMETRY(geometry) (RGEO_GEOMETRY_DATA_PTR(geometry)->factory)
112
-
113
- // Returns the klasses object given a ruby Geometry object
114
- #define RGEO_KLASSES_FROM_GEOMETRY(geometry) (RGEO_GEOMETRY_DATA_PTR(geometry)->klasses)
115
-
116
- // Returns the RGeo_FactoryData* given a ruby Geometry object
117
- #define RGEO_FACTORY_DATA_FROM_GEOMETRY(geometry) RGEO_FACTORY_DATA_PTR(RGEO_FACTORY_FROM_GEOMETRY(geometry))
118
-
119
- // Returns the GEOS geometry handle given a ruby Geometry object
120
- #define RGEO_GET_GEOS_GEOMETRY(geometry) ((const GEOSGeometry*)(RGEO_GEOMETRY_DATA_PTR(geometry)->geom))
121
-
122
- // Returns the GEOS context handle given a ruby Geometry object
123
- #define RGEO_CONTEXT_FROM_GEOMETRY(geometry) RGEO_CONTEXT_FROM_FACTORY(RGEO_FACTORY_FROM_GEOMETRY(geometry))
124
-
125
- // Returns a pointer to the globals given a ruby Geometry object
126
- #define RGEO_GLOBALS_FROM_GEOMETRY(geometry) RGEO_GLOBALS_FROM_FACTORY(RGEO_FACTORY_FROM_GEOMETRY(geometry))
127
-
128
138
 
129
139
  /*
130
140
  Initializes the factory module. This should be called first in the