rgeo 2.3.1 → 3.0.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 (97) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +6 -0
  3. data/README.md +23 -14
  4. data/ext/geos_c_impl/analysis.c +30 -25
  5. data/ext/geos_c_impl/analysis.h +8 -7
  6. data/ext/geos_c_impl/coordinates.c +27 -21
  7. data/ext/geos_c_impl/coordinates.h +5 -2
  8. data/ext/geos_c_impl/errors.c +19 -10
  9. data/ext/geos_c_impl/errors.h +11 -4
  10. data/ext/geos_c_impl/extconf.rb +42 -28
  11. data/ext/geos_c_impl/factory.c +540 -451
  12. data/ext/geos_c_impl/factory.h +105 -95
  13. data/ext/geos_c_impl/geometry.c +593 -387
  14. data/ext/geos_c_impl/geometry.h +10 -5
  15. data/ext/geos_c_impl/geometry_collection.c +306 -339
  16. data/ext/geos_c_impl/geometry_collection.h +6 -20
  17. data/ext/geos_c_impl/globals.c +169 -0
  18. data/ext/geos_c_impl/globals.h +46 -0
  19. data/ext/geos_c_impl/line_string.c +271 -231
  20. data/ext/geos_c_impl/line_string.h +5 -8
  21. data/ext/geos_c_impl/main.c +16 -16
  22. data/ext/geos_c_impl/point.c +65 -67
  23. data/ext/geos_c_impl/point.h +4 -7
  24. data/ext/geos_c_impl/polygon.c +137 -135
  25. data/ext/geos_c_impl/polygon.h +11 -11
  26. data/ext/geos_c_impl/preface.h +16 -10
  27. data/ext/geos_c_impl/ruby_more.c +67 -0
  28. data/ext/geos_c_impl/ruby_more.h +25 -0
  29. data/lib/rgeo/cartesian/analysis.rb +5 -3
  30. data/lib/rgeo/cartesian/bounding_box.rb +74 -79
  31. data/lib/rgeo/cartesian/calculations.rb +64 -33
  32. data/lib/rgeo/cartesian/factory.rb +57 -102
  33. data/lib/rgeo/cartesian/feature_classes.rb +68 -46
  34. data/lib/rgeo/cartesian/feature_methods.rb +67 -25
  35. data/lib/rgeo/cartesian/interface.rb +6 -41
  36. data/lib/rgeo/cartesian/planar_graph.rb +373 -0
  37. data/lib/rgeo/cartesian/sweepline_intersector.rb +147 -0
  38. data/lib/rgeo/cartesian/valid_op.rb +69 -0
  39. data/lib/rgeo/cartesian.rb +3 -0
  40. data/lib/rgeo/coord_sys/cs/entities.rb +303 -99
  41. data/lib/rgeo/coord_sys/cs/factories.rb +0 -2
  42. data/lib/rgeo/coord_sys/cs/wkt_parser.rb +90 -42
  43. data/lib/rgeo/coord_sys.rb +1 -20
  44. data/lib/rgeo/error.rb +15 -0
  45. data/lib/rgeo/feature/curve.rb +0 -11
  46. data/lib/rgeo/feature/factory.rb +26 -36
  47. data/lib/rgeo/feature/factory_generator.rb +6 -14
  48. data/lib/rgeo/feature/geometry.rb +146 -66
  49. data/lib/rgeo/feature/geometry_collection.rb +16 -9
  50. data/lib/rgeo/feature/line_string.rb +4 -5
  51. data/lib/rgeo/feature/linear_ring.rb +0 -1
  52. data/lib/rgeo/feature/multi_curve.rb +0 -6
  53. data/lib/rgeo/feature/multi_surface.rb +3 -4
  54. data/lib/rgeo/feature/point.rb +4 -5
  55. data/lib/rgeo/feature/polygon.rb +1 -2
  56. data/lib/rgeo/feature/surface.rb +3 -4
  57. data/lib/rgeo/feature/types.rb +69 -85
  58. data/lib/rgeo/geographic/factory.rb +98 -125
  59. data/lib/rgeo/geographic/interface.rb +69 -166
  60. data/lib/rgeo/geographic/projected_feature_classes.rb +21 -9
  61. data/lib/rgeo/geographic/projected_feature_methods.rb +67 -42
  62. data/lib/rgeo/geographic/projected_window.rb +36 -22
  63. data/lib/rgeo/geographic/{proj4_projector.rb → projector.rb} +3 -5
  64. data/lib/rgeo/geographic/simple_mercator_projector.rb +26 -25
  65. data/lib/rgeo/geographic/spherical_feature_classes.rb +29 -9
  66. data/lib/rgeo/geographic/spherical_feature_methods.rb +86 -9
  67. data/lib/rgeo/geographic/spherical_math.rb +17 -20
  68. data/lib/rgeo/geographic.rb +1 -1
  69. data/lib/rgeo/geos/capi_factory.rb +87 -158
  70. data/lib/rgeo/geos/capi_feature_classes.rb +50 -36
  71. data/lib/rgeo/geos/ffi_factory.rb +105 -173
  72. data/lib/rgeo/geos/ffi_feature_classes.rb +34 -10
  73. data/lib/rgeo/geos/ffi_feature_methods.rb +105 -127
  74. data/lib/rgeo/geos/interface.rb +20 -59
  75. data/lib/rgeo/geos/utils.rb +5 -5
  76. data/lib/rgeo/geos/zm_factory.rb +53 -95
  77. data/lib/rgeo/geos/zm_feature_methods.rb +30 -33
  78. data/lib/rgeo/geos.rb +8 -8
  79. data/lib/rgeo/impl_helper/basic_geometry_collection_methods.rb +9 -22
  80. data/lib/rgeo/impl_helper/basic_geometry_methods.rb +1 -2
  81. data/lib/rgeo/impl_helper/basic_line_string_methods.rb +28 -56
  82. data/lib/rgeo/impl_helper/basic_point_methods.rb +2 -14
  83. data/lib/rgeo/impl_helper/basic_polygon_methods.rb +17 -26
  84. data/lib/rgeo/impl_helper/utils.rb +21 -0
  85. data/lib/rgeo/impl_helper/valid_op.rb +350 -0
  86. data/lib/rgeo/impl_helper/validity_check.rb +139 -0
  87. data/lib/rgeo/impl_helper.rb +1 -0
  88. data/lib/rgeo/version.rb +1 -1
  89. data/lib/rgeo/wkrep/wkb_generator.rb +73 -63
  90. data/lib/rgeo/wkrep/wkb_parser.rb +33 -31
  91. data/lib/rgeo/wkrep/wkt_generator.rb +52 -45
  92. data/lib/rgeo/wkrep/wkt_parser.rb +48 -35
  93. data/lib/rgeo.rb +1 -3
  94. metadata +50 -13
  95. data/lib/rgeo/coord_sys/srs_database/entry.rb +0 -107
  96. data/lib/rgeo/coord_sys/srs_database/sr_org.rb +0 -64
  97. data/lib/rgeo/coord_sys/srs_database/url_reader.rb +0 -65
@@ -2,191 +2,261 @@
2
2
  Factory and utility functions for GEOS wrapper
3
3
  */
4
4
 
5
-
6
5
  #include "preface.h"
7
6
 
8
7
  #ifdef RGEO_GEOS_SUPPORTED
9
8
 
10
- #include <ruby.h>
11
9
  #include <geos_c.h>
10
+ #include <ruby.h>
12
11
 
12
+ #include "errors.h"
13
13
  #include "factory.h"
14
14
  #include "geometry.h"
15
- #include "point.h"
15
+ #include "geometry_collection.h"
16
+ #include "globals.h"
16
17
  #include "line_string.h"
18
+ #include "point.h"
17
19
  #include "polygon.h"
18
- #include "geometry_collection.h"
19
- #include "errors.h"
20
+ #include "ruby_more.h"
20
21
 
21
22
  RGEO_BEGIN_C
22
23
 
23
-
24
24
  /**** RUBY AND GEOS CALLBACKS ****/
25
25
 
26
-
27
- // NOP message handler. GEOS requires that a message handler be set
28
- // for every context handle.
29
-
30
- static void message_handler(const char* fmt, ...)
31
- {
32
- }
33
-
34
-
35
26
  // Destroy function for factory data. We destroy any serialization
36
- // objects that have been created for the factory, and then destroy
37
- // the GEOS context, before freeing the factory data itself.
27
+ // objects that have been created for the factory before freeing
28
+ // the factory data itself.
38
29
 
39
- static void destroy_factory_func(RGeo_FactoryData* data)
30
+ static void
31
+ destroy_factory_func(void* data)
40
32
  {
41
- GEOSContextHandle_t context;
33
+ RGeo_FactoryData* factory_data;
42
34
 
43
- context = data->geos_context;
44
- if (data->wkt_reader) {
45
- GEOSWKTReader_destroy_r(context, data->wkt_reader);
35
+ factory_data = (RGeo_FactoryData*)data;
36
+ if (factory_data->wkt_reader) {
37
+ GEOSWKTReader_destroy(factory_data->wkt_reader);
46
38
  }
47
- if (data->wkb_reader) {
48
- GEOSWKBReader_destroy_r(context, data->wkb_reader);
39
+ if (factory_data->wkb_reader) {
40
+ GEOSWKBReader_destroy(factory_data->wkb_reader);
49
41
  }
50
- if (data->wkt_writer) {
51
- GEOSWKTWriter_destroy_r(context, data->wkt_writer);
42
+ if (factory_data->wkt_writer) {
43
+ GEOSWKTWriter_destroy(factory_data->wkt_writer);
52
44
  }
53
- if (data->wkb_writer) {
54
- GEOSWKBWriter_destroy_r(context, data->wkb_writer);
45
+ if (factory_data->wkb_writer) {
46
+ GEOSWKBWriter_destroy(factory_data->wkb_writer);
55
47
  }
56
- if (data->psych_wkt_reader) {
57
- GEOSWKTReader_destroy_r(context, data->psych_wkt_reader);
48
+ if (factory_data->psych_wkt_reader) {
49
+ GEOSWKTReader_destroy(factory_data->psych_wkt_reader);
58
50
  }
59
- if (data->marshal_wkb_reader) {
60
- GEOSWKBReader_destroy_r(context, data->marshal_wkb_reader);
51
+ if (factory_data->marshal_wkb_reader) {
52
+ GEOSWKBReader_destroy(factory_data->marshal_wkb_reader);
61
53
  }
62
- if (data->psych_wkt_writer) {
63
- GEOSWKTWriter_destroy_r(context, data->psych_wkt_writer);
54
+ if (factory_data->psych_wkt_writer) {
55
+ GEOSWKTWriter_destroy(factory_data->psych_wkt_writer);
64
56
  }
65
- if (data->marshal_wkb_writer) {
66
- GEOSWKBWriter_destroy_r(context, data->marshal_wkb_writer);
57
+ if (factory_data->marshal_wkb_writer) {
58
+ GEOSWKBWriter_destroy(factory_data->marshal_wkb_writer);
67
59
  }
68
- finishGEOS_r(context);
69
- free(data);
60
+ FREE(factory_data);
70
61
  }
71
62
 
72
-
73
63
  // Destroy function for geometry data. We destroy the internal
74
64
  // GEOS geometry (if present) before freeing the data itself.
75
65
 
76
- static void destroy_geometry_func(RGeo_GeometryData* data)
66
+ static void
67
+ destroy_geometry_func(void* data)
77
68
  {
69
+ RGeo_GeometryData* geometry_data;
78
70
  const GEOSPreparedGeometry* prep;
79
71
 
80
- if (data->geom) {
81
- GEOSGeom_destroy_r(data->geos_context, data->geom);
72
+ geometry_data = (RGeo_GeometryData*)data;
73
+ if (geometry_data->geom) {
74
+ GEOSGeom_destroy(geometry_data->geom);
82
75
  }
83
- prep = data->prep;
84
- if (prep && prep != (const GEOSPreparedGeometry*)1 && prep != (const GEOSPreparedGeometry*)2 &&
85
- prep != (const GEOSPreparedGeometry*)3)
86
- {
87
- GEOSPreparedGeom_destroy_r(data->geos_context, prep);
76
+ prep = geometry_data->prep;
77
+ if (prep && prep != (const GEOSPreparedGeometry*)1 &&
78
+ prep != (const GEOSPreparedGeometry*)2 &&
79
+ prep != (const GEOSPreparedGeometry*)3) {
80
+ GEOSPreparedGeom_destroy(prep);
88
81
  }
89
- free(data);
82
+ FREE(geometry_data);
90
83
  }
91
84
 
92
-
93
85
  // Mark function for factory data. This marks the wkt and wkb generator
94
86
  // handles so they don't get collected.
95
87
 
96
- static void mark_factory_func(RGeo_FactoryData* data)
88
+ static void
89
+ mark_factory_func(void* data)
97
90
  {
98
- if (!NIL_P(data->wkrep_wkt_generator)) {
99
- rb_gc_mark(data->wkrep_wkt_generator);
100
- }
101
- if (!NIL_P(data->wkrep_wkb_generator)) {
102
- rb_gc_mark(data->wkrep_wkb_generator);
91
+ RGeo_FactoryData* factory_data;
92
+
93
+ factory_data = (RGeo_FactoryData*)data;
94
+ if (!NIL_P(factory_data->wkrep_wkt_generator)) {
95
+ mark(factory_data->wkrep_wkt_generator);
103
96
  }
104
- if (!NIL_P(data->wkrep_wkt_parser)) {
105
- rb_gc_mark(data->wkrep_wkt_parser);
97
+ if (!NIL_P(factory_data->wkrep_wkb_generator)) {
98
+ mark(factory_data->wkrep_wkb_generator);
106
99
  }
107
- if (!NIL_P(data->wkrep_wkb_parser)) {
108
- rb_gc_mark(data->wkrep_wkb_parser);
100
+ if (!NIL_P(factory_data->wkrep_wkt_parser)) {
101
+ mark(factory_data->wkrep_wkt_parser);
109
102
  }
110
- if (!NIL_P(data->proj4_obj)) {
111
- rb_gc_mark(data->proj4_obj);
103
+ if (!NIL_P(factory_data->wkrep_wkb_parser)) {
104
+ mark(factory_data->wkrep_wkb_parser);
112
105
  }
113
- if (!NIL_P(data->coord_sys_obj)) {
114
- rb_gc_mark(data->coord_sys_obj);
106
+ if (!NIL_P(factory_data->coord_sys_obj)) {
107
+ mark(factory_data->coord_sys_obj);
115
108
  }
116
109
  }
117
110
 
118
-
119
111
  // Mark function for geometry data. This marks the factory and klasses
120
112
  // held by the geometry so those don't get collected.
121
113
 
122
- static void mark_geometry_func(RGeo_GeometryData* data)
114
+ static void
115
+ mark_geometry_func(void* data)
123
116
  {
124
- if (!NIL_P(data->factory)) {
125
- rb_gc_mark(data->factory);
117
+ RGeo_GeometryData* geometry_data;
118
+
119
+ geometry_data = (RGeo_GeometryData*)data;
120
+ if (!NIL_P(geometry_data->factory)) {
121
+ mark(geometry_data->factory);
126
122
  }
127
- if (!NIL_P(data->klasses)) {
128
- rb_gc_mark(data->klasses);
123
+ if (!NIL_P(geometry_data->klasses)) {
124
+ mark(geometry_data->klasses);
129
125
  }
130
126
  }
131
127
 
132
-
133
- // Destroy function for globals data. We don't need to destroy any
134
- // auxiliary data for now...
135
-
136
- static void destroy_globals_func(RGeo_Globals* data)
128
+ #ifdef HAVE_RB_GC_MARK_MOVABLE
129
+ static void
130
+ compact_factory_func(void* data)
137
131
  {
138
- free(data);
139
- }
140
-
132
+ RGeo_FactoryData* factory_data;
141
133
 
142
- // Mark function for globals data. This should mark any globals that
143
- // need to be held through garbage collection (none at the moment.)
134
+ factory_data = (RGeo_FactoryData*)data;
135
+ if (!NIL_P(factory_data->wkrep_wkt_generator)) {
136
+ factory_data->wkrep_wkt_generator =
137
+ rb_gc_location(factory_data->wkrep_wkt_generator);
138
+ }
139
+ if (!NIL_P(factory_data->wkrep_wkb_generator)) {
140
+ factory_data->wkrep_wkb_generator =
141
+ rb_gc_location(factory_data->wkrep_wkb_generator);
142
+ }
143
+ if (!NIL_P(factory_data->wkrep_wkt_parser)) {
144
+ factory_data->wkrep_wkt_parser =
145
+ rb_gc_location(factory_data->wkrep_wkt_parser);
146
+ }
147
+ if (!NIL_P(factory_data->wkrep_wkb_parser)) {
148
+ factory_data->wkrep_wkb_parser =
149
+ rb_gc_location(factory_data->wkrep_wkb_parser);
150
+ }
151
+ if (!NIL_P(factory_data->coord_sys_obj)) {
152
+ factory_data->coord_sys_obj = rb_gc_location(factory_data->coord_sys_obj);
153
+ }
154
+ }
144
155
 
145
- static void mark_globals_func(RGeo_Globals* data)
156
+ static void
157
+ compact_geometry_func(void* data)
146
158
  {
159
+ RGeo_GeometryData* geometry_data;
160
+
161
+ geometry_data = (RGeo_GeometryData*)data;
162
+ if (!NIL_P(geometry_data->factory)) {
163
+ geometry_data->factory = rb_gc_location(geometry_data->factory);
164
+ }
165
+ if (!NIL_P(geometry_data->klasses)) {
166
+ geometry_data->klasses = rb_gc_location(geometry_data->klasses);
167
+ }
147
168
  }
169
+ #endif
148
170
 
171
+ const rb_data_type_t rgeo_factory_type = { .wrap_struct_name = "RGeo/Factory",
172
+ .function = {
173
+ .dmark = mark_factory_func,
174
+ .dfree = destroy_factory_func,
175
+ #ifdef HAVE_RB_GC_MARK_MOVABLE
176
+ .dcompact = compact_factory_func,
177
+ #endif
178
+ } };
179
+
180
+ const rb_data_type_t rgeo_geometry_type = { .wrap_struct_name = "RGeo/Geometry",
181
+ .function = {
182
+ .dmark = mark_geometry_func,
183
+ .dfree = destroy_geometry_func,
184
+ #ifdef HAVE_RB_GC_MARK_MOVABLE
185
+ .dcompact = compact_geometry_func,
186
+ #endif
187
+ } };
149
188
 
150
189
  /**** RUBY METHOD DEFINITIONS ****/
151
190
 
152
-
153
- static VALUE method_factory_srid(VALUE self)
191
+ static VALUE
192
+ method_factory_srid(VALUE self)
154
193
  {
155
194
  return INT2NUM(RGEO_FACTORY_DATA_PTR(self)->srid);
156
195
  }
157
196
 
158
-
159
- static VALUE method_factory_buffer_resolution(VALUE self)
197
+ static VALUE
198
+ method_factory_buffer_resolution(VALUE self)
160
199
  {
161
200
  return INT2NUM(RGEO_FACTORY_DATA_PTR(self)->buffer_resolution);
162
201
  }
163
202
 
164
-
165
- static VALUE method_factory_flags(VALUE self)
203
+ static VALUE
204
+ method_factory_flags(VALUE self)
166
205
  {
167
206
  return INT2NUM(RGEO_FACTORY_DATA_PTR(self)->flags);
168
207
  }
169
208
 
209
+ VALUE
210
+ method_factory_supports_z_p(VALUE self)
211
+ {
212
+ return RGEO_FACTORY_DATA_PTR(self)->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z
213
+ ? Qtrue
214
+ : Qfalse;
215
+ }
216
+
217
+ VALUE
218
+ method_factory_supports_m_p(VALUE self)
219
+ {
220
+ return RGEO_FACTORY_DATA_PTR(self)->flags & RGEO_FACTORYFLAGS_SUPPORTS_M
221
+ ? Qtrue
222
+ : Qfalse;
223
+ }
224
+
225
+ VALUE
226
+ method_factory_supports_z_or_m_p(VALUE self)
227
+ {
228
+ return RGEO_FACTORY_DATA_PTR(self)->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M
229
+ ? Qtrue
230
+ : Qfalse;
231
+ }
232
+
233
+ VALUE
234
+ method_factory_prepare_heuristic_p(VALUE self)
235
+ {
236
+ return RGEO_FACTORY_DATA_PTR(self)->flags &
237
+ RGEO_FACTORYFLAGS_PREPARE_HEURISTIC
238
+ ? Qtrue
239
+ : Qfalse;
240
+ }
170
241
 
171
- static VALUE method_factory_parse_wkt(VALUE self, VALUE str)
242
+ static VALUE
243
+ method_factory_parse_wkt(VALUE self, VALUE str)
172
244
  {
173
245
  RGeo_FactoryData* self_data;
174
- GEOSContextHandle_t self_context;
175
246
  GEOSWKTReader* wkt_reader;
176
247
  VALUE result;
177
248
  GEOSGeometry* geom;
178
249
 
179
250
  Check_Type(str, T_STRING);
180
251
  self_data = RGEO_FACTORY_DATA_PTR(self);
181
- self_context = self_data->geos_context;
182
252
  wkt_reader = self_data->wkt_reader;
183
253
  if (!wkt_reader) {
184
- wkt_reader = GEOSWKTReader_create_r(self_context);
254
+ wkt_reader = GEOSWKTReader_create();
185
255
  self_data->wkt_reader = wkt_reader;
186
256
  }
187
257
  result = Qnil;
188
258
  if (wkt_reader) {
189
- geom = GEOSWKTReader_read_r(self_context, wkt_reader, RSTRING_PTR(str));
259
+ geom = GEOSWKTReader_read(wkt_reader, RSTRING_PTR(str));
190
260
  if (geom) {
191
261
  result = rgeo_wrap_geos_geometry(self, geom, Qnil);
192
262
  }
@@ -194,26 +264,31 @@ static VALUE method_factory_parse_wkt(VALUE self, VALUE str)
194
264
  return result;
195
265
  }
196
266
 
197
-
198
- static VALUE method_factory_parse_wkb(VALUE self, VALUE str)
267
+ static VALUE
268
+ method_factory_parse_wkb(VALUE self, VALUE str)
199
269
  {
200
270
  RGeo_FactoryData* self_data;
201
- GEOSContextHandle_t self_context;
202
271
  GEOSWKBReader* wkb_reader;
203
272
  VALUE result;
204
273
  GEOSGeometry* geom;
274
+ char* c_str;
205
275
 
206
276
  Check_Type(str, T_STRING);
207
277
  self_data = RGEO_FACTORY_DATA_PTR(self);
208
- self_context = self_data->geos_context;
209
278
  wkb_reader = self_data->wkb_reader;
210
279
  if (!wkb_reader) {
211
- wkb_reader = GEOSWKBReader_create_r(self_context);
280
+ wkb_reader = GEOSWKBReader_create();
212
281
  self_data->wkb_reader = wkb_reader;
213
282
  }
214
283
  result = Qnil;
215
284
  if (wkb_reader) {
216
- geom = GEOSWKBReader_read_r(self_context, wkb_reader, (unsigned char*)RSTRING_PTR(str), (size_t)RSTRING_LEN(str));
285
+ c_str = RSTRING_PTR(str);
286
+ if (c_str[0] == '\x00' || c_str[0] == '\x01')
287
+ geom = GEOSWKBReader_read(
288
+ wkb_reader, (unsigned char*)c_str, (size_t)RSTRING_LEN(str));
289
+ else
290
+ geom = GEOSWKBReader_readHEX(
291
+ wkb_reader, (unsigned char*)c_str, (size_t)RSTRING_LEN(str));
217
292
  if (geom) {
218
293
  result = rgeo_wrap_geos_geometry(self, geom, Qnil);
219
294
  }
@@ -221,26 +296,25 @@ static VALUE method_factory_parse_wkb(VALUE self, VALUE str)
221
296
  return result;
222
297
  }
223
298
 
224
-
225
- static VALUE method_factory_read_for_marshal(VALUE self, VALUE str)
299
+ static VALUE
300
+ method_factory_read_for_marshal(VALUE self, VALUE str)
226
301
  {
227
302
  RGeo_FactoryData* self_data;
228
- GEOSContextHandle_t self_context;
229
303
  GEOSWKBReader* wkb_reader;
230
304
  VALUE result;
231
305
  GEOSGeometry* geom;
232
306
 
233
307
  Check_Type(str, T_STRING);
234
308
  self_data = RGEO_FACTORY_DATA_PTR(self);
235
- self_context = self_data->geos_context;
236
309
  wkb_reader = self_data->marshal_wkb_reader;
237
310
  if (!wkb_reader) {
238
- wkb_reader = GEOSWKBReader_create_r(self_context);
311
+ wkb_reader = GEOSWKBReader_create();
239
312
  self_data->marshal_wkb_reader = wkb_reader;
240
313
  }
241
314
  result = Qnil;
242
315
  if (wkb_reader) {
243
- geom = GEOSWKBReader_read_r(self_context, wkb_reader, (unsigned char*)RSTRING_PTR(str), (size_t)RSTRING_LEN(str));
316
+ geom = GEOSWKBReader_read(
317
+ wkb_reader, (unsigned char*)RSTRING_PTR(str), (size_t)RSTRING_LEN(str));
244
318
  if (geom) {
245
319
  result = rgeo_wrap_geos_geometry(self, geom, Qnil);
246
320
  }
@@ -248,26 +322,24 @@ static VALUE method_factory_read_for_marshal(VALUE self, VALUE str)
248
322
  return result;
249
323
  }
250
324
 
251
-
252
- static VALUE method_factory_read_for_psych(VALUE self, VALUE str)
325
+ static VALUE
326
+ method_factory_read_for_psych(VALUE self, VALUE str)
253
327
  {
254
328
  RGeo_FactoryData* self_data;
255
- GEOSContextHandle_t self_context;
256
329
  GEOSWKTReader* wkt_reader;
257
330
  VALUE result;
258
331
  GEOSGeometry* geom;
259
332
 
260
333
  Check_Type(str, T_STRING);
261
334
  self_data = RGEO_FACTORY_DATA_PTR(self);
262
- self_context = self_data->geos_context;
263
335
  wkt_reader = self_data->psych_wkt_reader;
264
336
  if (!wkt_reader) {
265
- wkt_reader = GEOSWKTReader_create_r(self_context);
337
+ wkt_reader = GEOSWKTReader_create();
266
338
  self_data->psych_wkt_reader = wkt_reader;
267
339
  }
268
340
  result = Qnil;
269
341
  if (wkt_reader) {
270
- geom = GEOSWKTReader_read_r(self_context, wkt_reader, RSTRING_PTR(str));
342
+ geom = GEOSWKTReader_read(wkt_reader, RSTRING_PTR(str));
271
343
  if (geom) {
272
344
  result = rgeo_wrap_geos_geometry(self, geom, Qnil);
273
345
  }
@@ -275,43 +347,40 @@ static VALUE method_factory_read_for_psych(VALUE self, VALUE str)
275
347
  return result;
276
348
  }
277
349
 
350
+ #ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
351
+ static VALUE marshal_wkb_generator;
352
+ #endif
278
353
 
279
- static VALUE method_factory_write_for_marshal(VALUE self, VALUE obj)
354
+ static VALUE
355
+ method_factory_write_for_marshal(VALUE self, VALUE obj)
280
356
  {
281
357
  RGeo_FactoryData* self_data;
282
- GEOSContextHandle_t self_context;
283
358
  GEOSWKBWriter* wkb_writer;
284
359
  const GEOSGeometry* geom;
285
360
  VALUE result;
286
361
  char* str;
287
362
  size_t size;
288
363
  char has_3d;
289
- #ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
290
- RGeo_Globals* globals;
291
- VALUE wkb_generator;
292
- #endif
293
364
 
294
365
  self_data = RGEO_FACTORY_DATA_PTR(self);
295
- self_context = self_data->geos_context;
296
366
  has_3d = self_data->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M;
297
367
  #ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
298
368
  if (has_3d) {
299
- globals = self_data->globals;
300
- wkb_generator = globals->marshal_wkb_generator;
301
- if (NIL_P(wkb_generator)) {
302
- wkb_generator = rb_funcall(
303
- rb_const_get_at(globals->geos_module, rb_intern("Utils")),
304
- rb_intern("marshal_wkb_generator"), 0);
305
- globals->marshal_wkb_generator = wkb_generator;
369
+ if (NIL_P(marshal_wkb_generator)) {
370
+ marshal_wkb_generator =
371
+ rb_funcall(rb_const_get_at(rgeo_geos_module, rb_intern("Utils")),
372
+ rb_intern("marshal_wkb_generator"),
373
+ 0);
306
374
  }
307
- return rb_funcall(wkb_generator, globals->id_generate, 1, obj);
375
+ return rb_funcall(marshal_wkb_generator, rb_intern("generate"), 1, obj);
308
376
  }
309
377
  #endif
310
378
  wkb_writer = self_data->marshal_wkb_writer;
311
379
  if (!wkb_writer) {
312
- wkb_writer = GEOSWKBWriter_create_r(self_context);
380
+ wkb_writer = GEOSWKBWriter_create();
381
+ GEOSWKBWriter_setOutputDimension(wkb_writer, 2);
313
382
  if (has_3d) {
314
- GEOSWKBWriter_setOutputDimension_r(self_context, wkb_writer, 3);
383
+ GEOSWKBWriter_setOutputDimension(wkb_writer, 3);
315
384
  }
316
385
  self_data->marshal_wkb_writer = wkb_writer;
317
386
  }
@@ -319,52 +388,50 @@ static VALUE method_factory_write_for_marshal(VALUE self, VALUE obj)
319
388
  if (wkb_writer) {
320
389
  geom = rgeo_get_geos_geometry_safe(obj);
321
390
  if (geom) {
322
- str = (char*)GEOSWKBWriter_write_r(self_context, wkb_writer, geom, &size);
391
+ str = (char*)GEOSWKBWriter_write(wkb_writer, geom, &size);
323
392
  if (str) {
324
393
  result = rb_str_new(str, size);
325
- GEOSFree_r(self_context, str);
394
+ GEOSFree(str);
326
395
  }
327
396
  }
328
397
  }
329
398
  return result;
330
399
  }
331
400
 
401
+ #ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
402
+ static VALUE psych_wkt_generator;
403
+ #endif
332
404
 
333
- static VALUE method_factory_write_for_psych(VALUE self, VALUE obj)
405
+ static VALUE
406
+ method_factory_write_for_psych(VALUE self, VALUE obj)
334
407
  {
335
408
  RGeo_FactoryData* self_data;
336
- GEOSContextHandle_t self_context;
337
409
  GEOSWKTWriter* wkt_writer;
338
410
  const GEOSGeometry* geom;
339
411
  VALUE result;
340
412
  char* str;
341
413
  char has_3d;
342
- #ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
343
- RGeo_Globals* globals;
344
- VALUE wkt_generator;
345
- #endif
346
414
 
347
415
  self_data = RGEO_FACTORY_DATA_PTR(self);
348
- self_context = self_data->geos_context;
349
416
  has_3d = self_data->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M;
350
417
  #ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
351
418
  if (has_3d) {
352
- globals = self_data->globals;
353
- wkt_generator = globals->psych_wkt_generator;
354
- if (NIL_P(wkt_generator)) {
355
- wkt_generator = rb_funcall(
356
- rb_const_get_at(globals->geos_module, rb_intern("Utils")),
357
- rb_intern("psych_wkt_generator"), 0);
358
- globals->psych_wkt_generator = wkt_generator;
419
+ if (NIL_P(psych_wkt_generator)) {
420
+ psych_wkt_generator =
421
+ rb_funcall(rb_const_get_at(rgeo_geos_module, rb_intern("Utils")),
422
+ rb_intern("psych_wkt_generator"),
423
+ 0);
359
424
  }
360
- return rb_funcall(wkt_generator, globals->id_generate, 1, obj);
425
+ return rb_funcall(psych_wkt_generator, rb_intern("generate"), 1, obj);
361
426
  }
362
427
  #endif
363
428
  wkt_writer = self_data->psych_wkt_writer;
364
429
  if (!wkt_writer) {
365
- wkt_writer = GEOSWKTWriter_create_r(self_context);
430
+ wkt_writer = GEOSWKTWriter_create();
431
+ GEOSWKTWriter_setOutputDimension(wkt_writer, 2);
432
+ GEOSWKTWriter_setTrim(wkt_writer, 1);
366
433
  if (has_3d) {
367
- GEOSWKTWriter_setOutputDimension_r(self_context, wkt_writer, 3);
434
+ GEOSWKTWriter_setOutputDimension(wkt_writer, 3);
368
435
  }
369
436
  self_data->psych_wkt_writer = wkt_writer;
370
437
  }
@@ -372,24 +439,24 @@ static VALUE method_factory_write_for_psych(VALUE self, VALUE obj)
372
439
  if (wkt_writer) {
373
440
  geom = rgeo_get_geos_geometry_safe(obj);
374
441
  if (geom) {
375
- str = GEOSWKTWriter_write_r(self_context, wkt_writer, geom);
442
+ str = GEOSWKTWriter_write(wkt_writer, geom);
376
443
  if (str) {
377
444
  result = rb_str_new2(str);
378
- GEOSFree_r(self_context, str);
445
+ GEOSFree(str);
379
446
  }
380
447
  }
381
448
  }
382
449
  return result;
383
450
  }
384
451
 
385
-
386
- static VALUE cmethod_factory_geos_version(VALUE klass)
452
+ static VALUE
453
+ cmethod_factory_geos_version(VALUE klass)
387
454
  {
388
455
  return rb_str_new2(GEOS_VERSION);
389
456
  }
390
457
 
391
-
392
- static VALUE cmethod_factory_supports_unary_union(VALUE klass)
458
+ static VALUE
459
+ cmethod_factory_supports_unary_union(VALUE klass)
393
460
  {
394
461
  #ifdef RGEO_GEOS_SUPPORTS_UNARYUNION
395
462
  return Qtrue;
@@ -398,105 +465,97 @@ static VALUE cmethod_factory_supports_unary_union(VALUE klass)
398
465
  #endif
399
466
  }
400
467
 
401
- static VALUE cmethod_factory_create(VALUE klass, VALUE flags, VALUE srid, VALUE buffer_resolution,
402
- VALUE wkt_generator, VALUE wkb_generator, VALUE proj4_obj, VALUE coord_sys_obj)
468
+ static VALUE
469
+ cmethod_factory_create(VALUE klass,
470
+ VALUE flags,
471
+ VALUE srid,
472
+ VALUE buffer_resolution,
473
+ VALUE wkt_generator,
474
+ VALUE wkb_generator,
475
+ VALUE coord_sys_obj)
403
476
  {
404
477
  VALUE result;
405
478
  RGeo_FactoryData* data;
406
- GEOSContextHandle_t context;
407
- VALUE wrapped_globals;
408
479
 
409
480
  result = Qnil;
410
481
  data = ALLOC(RGeo_FactoryData);
411
482
  if (data) {
412
- context = initGEOS_r(message_handler, message_handler);
413
- if (context) {
414
- wrapped_globals = rb_const_get_at(klass, rb_intern("INTERNAL_CGLOBALS"));
415
- data->globals = (RGeo_Globals*)DATA_PTR(wrapped_globals);
416
- data->geos_context = context;
417
- data->flags = NUM2INT(flags);
418
- data->srid = NUM2INT(srid);
419
- data->buffer_resolution = NUM2INT(buffer_resolution);
420
- data->wkt_reader = NULL;
421
- data->wkb_reader = NULL;
422
- data->wkt_writer = NULL;
423
- data->wkb_writer = NULL;
424
- data->psych_wkt_reader = NULL;
425
- data->marshal_wkb_reader = NULL;
426
- data->psych_wkt_writer = NULL;
427
- data->marshal_wkb_writer = NULL;
428
- data->wkrep_wkt_generator = wkt_generator;
429
- data->wkrep_wkb_generator = wkb_generator;
430
- data->wkrep_wkt_parser = Qnil;
431
- data->wkrep_wkb_parser = Qnil;
432
- data->proj4_obj = proj4_obj;
433
- data->coord_sys_obj = coord_sys_obj;
434
- result = Data_Wrap_Struct(klass, mark_factory_func, destroy_factory_func, data);
435
- }
436
- else {
437
- free(data);
438
- }
483
+ data->flags = RB_NUM2INT(flags);
484
+ data->srid = RB_NUM2INT(srid);
485
+ data->buffer_resolution = RB_NUM2INT(buffer_resolution);
486
+ data->wkt_reader = NULL;
487
+ data->wkb_reader = NULL;
488
+ data->wkt_writer = NULL;
489
+ data->wkb_writer = NULL;
490
+ data->psych_wkt_reader = NULL;
491
+ data->marshal_wkb_reader = NULL;
492
+ data->psych_wkt_writer = NULL;
493
+ data->marshal_wkb_writer = NULL;
494
+ data->wkrep_wkt_generator = wkt_generator;
495
+ data->wkrep_wkb_generator = wkb_generator;
496
+ data->wkrep_wkt_parser = Qnil;
497
+ data->wkrep_wkb_parser = Qnil;
498
+ data->coord_sys_obj = coord_sys_obj;
499
+ result = TypedData_Wrap_Struct(klass, &rgeo_factory_type, data);
439
500
  }
440
501
  return result;
441
502
  }
442
503
 
443
-
444
- static VALUE alloc_factory(VALUE klass)
504
+ static VALUE
505
+ alloc_factory(VALUE klass)
445
506
  {
446
- return cmethod_factory_create(klass, INT2NUM(0), INT2NUM(0), INT2NUM(0), Qnil, Qnil, Qnil, Qnil);
507
+ return cmethod_factory_create(
508
+ klass, INT2NUM(0), INT2NUM(0), INT2NUM(0), Qnil, Qnil, Qnil);
447
509
  }
448
510
 
449
-
450
- static VALUE method_factory_initialize_copy(VALUE self, VALUE orig)
511
+ static VALUE
512
+ method_factory_initialize_copy(VALUE self, VALUE orig)
451
513
  {
452
514
  RGeo_FactoryData* self_data;
453
515
  RGeo_FactoryData* orig_data;
454
- GEOSContextHandle_t context;
455
516
 
456
517
  // Clear out existing data
457
518
  self_data = RGEO_FACTORY_DATA_PTR(self);
458
- context = self_data->geos_context;
459
519
  if (self_data->wkt_reader) {
460
- GEOSWKTReader_destroy_r(context, self_data->wkt_reader);
520
+ GEOSWKTReader_destroy(self_data->wkt_reader);
461
521
  self_data->wkt_reader = NULL;
462
522
  }
463
523
  if (self_data->wkb_reader) {
464
- GEOSWKBReader_destroy_r(context, self_data->wkb_reader);
524
+ GEOSWKBReader_destroy(self_data->wkb_reader);
465
525
  self_data->wkb_reader = NULL;
466
526
  }
467
527
  if (self_data->wkt_writer) {
468
- GEOSWKTWriter_destroy_r(context, self_data->wkt_writer);
528
+ GEOSWKTWriter_destroy(self_data->wkt_writer);
469
529
  self_data->wkt_writer = NULL;
470
530
  }
471
531
  if (self_data->wkb_writer) {
472
- GEOSWKBWriter_destroy_r(context, self_data->wkb_writer);
532
+ GEOSWKBWriter_destroy(self_data->wkb_writer);
473
533
  self_data->wkb_writer = NULL;
474
534
  }
475
535
  if (self_data->psych_wkt_reader) {
476
- GEOSWKTReader_destroy_r(context, self_data->psych_wkt_reader);
536
+ GEOSWKTReader_destroy(self_data->psych_wkt_reader);
477
537
  self_data->psych_wkt_reader = NULL;
478
538
  }
479
539
  if (self_data->marshal_wkb_reader) {
480
- GEOSWKBReader_destroy_r(context, self_data->marshal_wkb_reader);
540
+ GEOSWKBReader_destroy(self_data->marshal_wkb_reader);
481
541
  self_data->marshal_wkb_reader = NULL;
482
542
  }
483
543
  if (self_data->psych_wkt_writer) {
484
- GEOSWKTWriter_destroy_r(context, self_data->psych_wkt_writer);
544
+ GEOSWKTWriter_destroy(self_data->psych_wkt_writer);
485
545
  self_data->psych_wkt_writer = NULL;
486
546
  }
487
547
  if (self_data->marshal_wkb_writer) {
488
- GEOSWKBWriter_destroy_r(context, self_data->marshal_wkb_writer);
548
+ GEOSWKBWriter_destroy(self_data->marshal_wkb_writer);
489
549
  self_data->marshal_wkb_writer = NULL;
490
550
  }
491
551
  self_data->wkrep_wkt_generator = Qnil;
492
552
  self_data->wkrep_wkb_generator = Qnil;
493
553
  self_data->wkrep_wkt_parser = Qnil;
494
554
  self_data->wkrep_wkb_parser = Qnil;
495
- self_data->proj4_obj = Qnil;
496
555
  self_data->coord_sys_obj = Qnil;
497
556
 
498
557
  // Copy new data from original object
499
- if (TYPE(orig) == T_DATA && RDATA(orig)->dfree == (RUBY_DATA_FUNC)destroy_factory_func) {
558
+ if (RGEO_FACTORY_TYPEDDATA_P(orig)) {
500
559
  orig_data = RGEO_FACTORY_DATA_PTR(orig);
501
560
  self_data->flags = orig_data->flags;
502
561
  self_data->srid = orig_data->srid;
@@ -505,14 +564,13 @@ static VALUE method_factory_initialize_copy(VALUE self, VALUE orig)
505
564
  self_data->wkrep_wkb_generator = orig_data->wkrep_wkb_generator;
506
565
  self_data->wkrep_wkt_parser = orig_data->wkrep_wkt_parser;
507
566
  self_data->wkrep_wkb_parser = orig_data->wkrep_wkb_parser;
508
- self_data->proj4_obj = orig_data->proj4_obj;
509
567
  self_data->coord_sys_obj = orig_data->coord_sys_obj;
510
568
  }
511
569
  return self;
512
570
  }
513
571
 
514
-
515
- static VALUE method_set_wkrep_parsers(VALUE self, VALUE wkt_parser, VALUE wkb_parser)
572
+ static VALUE
573
+ method_set_wkrep_parsers(VALUE self, VALUE wkt_parser, VALUE wkb_parser)
516
574
  {
517
575
  RGeo_FactoryData* self_data;
518
576
 
@@ -523,157 +581,148 @@ static VALUE method_set_wkrep_parsers(VALUE self, VALUE wkt_parser, VALUE wkb_pa
523
581
  return self;
524
582
  }
525
583
 
526
-
527
- static VALUE method_get_proj4(VALUE self)
528
- {
529
- return RGEO_FACTORY_DATA_PTR(self)->proj4_obj;
530
- }
531
-
532
-
533
- static VALUE method_get_coord_sys(VALUE self)
584
+ static VALUE
585
+ method_get_coord_sys(VALUE self)
534
586
  {
535
587
  return RGEO_FACTORY_DATA_PTR(self)->coord_sys_obj;
536
588
  }
537
589
 
538
-
539
- static VALUE method_get_wkt_generator(VALUE self)
590
+ static VALUE
591
+ method_get_wkt_generator(VALUE self)
540
592
  {
541
593
  return RGEO_FACTORY_DATA_PTR(self)->wkrep_wkt_generator;
542
594
  }
543
595
 
544
-
545
- static VALUE method_get_wkb_generator(VALUE self)
596
+ static VALUE
597
+ method_get_wkb_generator(VALUE self)
546
598
  {
547
599
  return RGEO_FACTORY_DATA_PTR(self)->wkrep_wkb_generator;
548
600
  }
549
601
 
550
-
551
- static VALUE method_get_wkt_parser(VALUE self)
602
+ static VALUE
603
+ method_get_wkt_parser(VALUE self)
552
604
  {
553
605
  return RGEO_FACTORY_DATA_PTR(self)->wkrep_wkt_parser;
554
606
  }
555
607
 
556
-
557
- static VALUE method_get_wkb_parser(VALUE self)
608
+ static VALUE
609
+ method_get_wkb_parser(VALUE self)
558
610
  {
559
611
  return RGEO_FACTORY_DATA_PTR(self)->wkrep_wkb_parser;
560
612
  }
561
613
 
562
-
563
- static VALUE alloc_geometry(VALUE klass)
614
+ static VALUE
615
+ alloc_geometry(VALUE klass)
564
616
  {
565
617
  return rgeo_wrap_geos_geometry(Qnil, NULL, klass);
566
618
  }
567
619
 
568
-
569
620
  /**** INITIALIZATION FUNCTION ****/
570
621
 
571
-
572
- RGeo_Globals* rgeo_init_geos_factory()
622
+ void
623
+ rgeo_init_geos_factory()
573
624
  {
574
- RGeo_Globals* globals;
575
- VALUE rgeo_module;
576
625
  VALUE geos_factory_class;
577
- VALUE wrapped_globals;
578
- VALUE feature_module;
579
-
580
- rgeo_module = rb_define_module("RGeo");
581
-
582
- globals = ALLOC(RGeo_Globals);
583
-
584
- // Cache some modules so we don't have to look them up by name every time
585
- feature_module = rb_define_module_under(rgeo_module, "Feature");
586
- globals->feature_module = feature_module;
587
- globals->geos_module = rb_define_module_under(rgeo_module, "Geos");
588
- globals->feature_geometry = rb_const_get_at(feature_module, rb_intern("Geometry"));
589
- globals->feature_point = rb_const_get_at(feature_module, rb_intern("Point"));
590
- globals->feature_line_string = rb_const_get_at(feature_module, rb_intern("LineString"));
591
- globals->feature_linear_ring = rb_const_get_at(feature_module, rb_intern("LinearRing"));
592
- globals->feature_line = rb_const_get_at(feature_module, rb_intern("Line"));
593
- globals->feature_polygon = rb_const_get_at(feature_module, rb_intern("Polygon"));
594
- globals->feature_geometry_collection = rb_const_get_at(feature_module, rb_intern("GeometryCollection"));
595
- globals->feature_multi_point = rb_const_get_at(feature_module, rb_intern("MultiPoint"));
596
- globals->feature_multi_line_string = rb_const_get_at(feature_module, rb_intern("MultiLineString"));
597
- globals->feature_multi_polygon = rb_const_get_at(feature_module, rb_intern("MultiPolygon"));
598
-
599
- // Cache some commonly used names
600
- globals->id_cast = rb_intern("cast");
601
- globals->id_eql = rb_intern("eql?");
602
- globals->id_generate = rb_intern("generate");
603
- globals->id_enum_for = rb_intern("enum_for");
604
- globals->id_hash = rb_intern("hash");
605
- globals->sym_force_new = ID2SYM(rb_intern("force_new"));
606
- globals->sym_keep_subtype = ID2SYM(rb_intern("keep_subtype"));
626
+
607
627
  #ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
608
- globals->psych_wkt_generator = Qnil;
609
- globals->marshal_wkb_generator = Qnil;
628
+ /* We favor rb_gc_register_address over rb_gc_register_mark_object because
629
+ * the value changes at runtime */
630
+ psych_wkt_generator = Qnil;
631
+ rb_gc_register_address(&psych_wkt_generator);
632
+ marshal_wkb_generator = Qnil;
633
+ rb_gc_register_address(&marshal_wkb_generator);
610
634
  #endif
611
635
 
612
- // Add C methods to the factory.
613
- geos_factory_class = rb_define_class_under(globals->geos_module, "CAPIFactory", rb_cObject);
636
+ geos_factory_class =
637
+ rb_define_class_under(rgeo_geos_module, "CAPIFactory", rb_cObject);
614
638
  rb_define_alloc_func(geos_factory_class, alloc_factory);
615
- rb_define_method(geos_factory_class, "initialize_copy", method_factory_initialize_copy, 1);
616
- rb_define_method(geos_factory_class, "_parse_wkt_impl", method_factory_parse_wkt, 1);
617
- rb_define_method(geos_factory_class, "_parse_wkb_impl", method_factory_parse_wkb, 1);
639
+ // Add C constants to the factory.
640
+ rb_define_const(geos_factory_class,
641
+ "FLAG_SUPPORTS_Z",
642
+ INT2FIX(RGEO_FACTORYFLAGS_SUPPORTS_Z));
643
+ rb_define_const(geos_factory_class,
644
+ "FLAG_SUPPORTS_M",
645
+ INT2FIX(RGEO_FACTORYFLAGS_SUPPORTS_M));
646
+ rb_define_const(geos_factory_class,
647
+ "FLAG_SUPPORTS_Z_OR_M",
648
+ INT2FIX(RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M));
649
+ rb_define_const(geos_factory_class,
650
+ "FLAG_PREPARE_HEURISTIC",
651
+ INT2FIX(RGEO_FACTORYFLAGS_PREPARE_HEURISTIC));
652
+ // Add C methods to the factory.
653
+ rb_define_method(
654
+ geos_factory_class, "initialize_copy", method_factory_initialize_copy, 1);
655
+ rb_define_method(
656
+ geos_factory_class, "_parse_wkt_impl", method_factory_parse_wkt, 1);
657
+ rb_define_method(
658
+ geos_factory_class, "_parse_wkb_impl", method_factory_parse_wkb, 1);
618
659
  rb_define_method(geos_factory_class, "_srid", method_factory_srid, 0);
619
- rb_define_method(geos_factory_class, "_buffer_resolution", method_factory_buffer_resolution, 0);
660
+ rb_define_method(geos_factory_class,
661
+ "_buffer_resolution",
662
+ method_factory_buffer_resolution,
663
+ 0);
620
664
  rb_define_method(geos_factory_class, "_flags", method_factory_flags, 0);
621
- rb_define_method(geos_factory_class, "_set_wkrep_parsers", method_set_wkrep_parsers, 2);
622
- rb_define_method(geos_factory_class, "_proj4", method_get_proj4, 0);
665
+ rb_define_method(
666
+ geos_factory_class, "supports_z?", method_factory_supports_z_p, 0);
667
+ rb_define_method(
668
+ geos_factory_class, "supports_m?", method_factory_supports_m_p, 0);
669
+ rb_define_method(geos_factory_class,
670
+ "supports_z_or_m?",
671
+ method_factory_supports_z_or_m_p,
672
+ 0);
673
+ rb_define_method(geos_factory_class,
674
+ "prepare_heuristic?",
675
+ method_factory_prepare_heuristic_p,
676
+ 0);
677
+ rb_define_method(
678
+ geos_factory_class, "_set_wkrep_parsers", method_set_wkrep_parsers, 2);
623
679
  rb_define_method(geos_factory_class, "_coord_sys", method_get_coord_sys, 0);
624
- rb_define_method(geos_factory_class, "_wkt_generator", method_get_wkt_generator, 0);
625
- rb_define_method(geos_factory_class, "_wkb_generator", method_get_wkb_generator, 0);
680
+ rb_define_method(
681
+ geos_factory_class, "_wkt_generator", method_get_wkt_generator, 0);
682
+ rb_define_method(
683
+ geos_factory_class, "_wkb_generator", method_get_wkb_generator, 0);
626
684
  rb_define_method(geos_factory_class, "_wkt_parser", method_get_wkt_parser, 0);
627
685
  rb_define_method(geos_factory_class, "_wkb_parser", method_get_wkb_parser, 0);
628
- rb_define_method(geos_factory_class, "read_for_marshal", method_factory_read_for_marshal, 1);
629
- rb_define_method(geos_factory_class, "write_for_marshal", method_factory_write_for_marshal, 1);
630
- rb_define_method(geos_factory_class, "read_for_psych", method_factory_read_for_psych, 1);
631
- rb_define_method(geos_factory_class, "write_for_psych", method_factory_write_for_psych, 1);
632
- rb_define_module_function(geos_factory_class, "_create", cmethod_factory_create, 7);
633
- rb_define_module_function(geos_factory_class, "_geos_version", cmethod_factory_geos_version, 0);
634
- rb_define_module_function(geos_factory_class, "_supports_unary_union?", cmethod_factory_supports_unary_union, 0);
635
-
636
- // Pre-define implementation classes and set up allocation methods
637
- globals->geos_geometry = rb_define_class_under(globals->geos_module, "CAPIGeometryImpl", rb_cObject);
638
- rb_define_alloc_func(globals->geos_geometry, alloc_geometry);
639
- globals->geos_point = rb_define_class_under(globals->geos_module, "CAPIPointImpl", rb_cObject);
640
- rb_define_alloc_func(globals->geos_point, alloc_geometry);
641
- globals->geos_line_string = rb_define_class_under(globals->geos_module, "CAPILineStringImpl", rb_cObject);
642
- rb_define_alloc_func(globals->geos_line_string, alloc_geometry);
643
- globals->geos_linear_ring = rb_define_class_under(globals->geos_module, "CAPILinearRingImpl", rb_cObject);
644
- rb_define_alloc_func(globals->geos_linear_ring, alloc_geometry);
645
- globals->geos_line = rb_define_class_under(globals->geos_module, "CAPILineImpl", rb_cObject);
646
- rb_define_alloc_func(globals->geos_line, alloc_geometry);
647
- globals->geos_polygon = rb_define_class_under(globals->geos_module, "CAPIPolygonImpl", rb_cObject);
648
- rb_define_alloc_func(globals->geos_polygon, alloc_geometry);
649
- globals->geos_geometry_collection = rb_define_class_under(globals->geos_module, "CAPIGeometryCollectionImpl", rb_cObject);
650
- rb_define_alloc_func(globals->geos_geometry_collection, alloc_geometry);
651
- globals->geos_multi_point = rb_define_class_under(globals->geos_module, "CAPIMultiPointImpl", rb_cObject);
652
- rb_define_alloc_func(globals->geos_multi_point, alloc_geometry);
653
- globals->geos_multi_line_string = rb_define_class_under(globals->geos_module, "CAPIMultiLineStringImpl", rb_cObject);
654
- rb_define_alloc_func(globals->geos_multi_line_string, alloc_geometry);
655
- globals->geos_multi_polygon = rb_define_class_under(globals->geos_module, "CAPIMultiPolygonImpl", rb_cObject);
656
- rb_define_alloc_func(globals->geos_multi_polygon, alloc_geometry);
657
-
658
- // Wrap the globals in a Ruby object and store it off so we have access
659
- // to it later. Each factory instance will reference it internally.
660
- wrapped_globals = Data_Wrap_Struct(rb_cObject, mark_globals_func, destroy_globals_func, globals);
661
- rb_define_const(geos_factory_class, "INTERNAL_CGLOBALS", wrapped_globals);
662
-
663
- return globals;
686
+ rb_define_method(
687
+ geos_factory_class, "read_for_marshal", method_factory_read_for_marshal, 1);
688
+ rb_define_method(geos_factory_class,
689
+ "write_for_marshal",
690
+ method_factory_write_for_marshal,
691
+ 1);
692
+ rb_define_method(
693
+ geos_factory_class, "read_for_psych", method_factory_read_for_psych, 1);
694
+ rb_define_method(
695
+ geos_factory_class, "write_for_psych", method_factory_write_for_psych, 1);
696
+ rb_define_module_function(
697
+ geos_factory_class, "_create", cmethod_factory_create, 6);
698
+ rb_define_module_function(
699
+ geos_factory_class, "_geos_version", cmethod_factory_geos_version, 0);
700
+ rb_define_module_function(geos_factory_class,
701
+ "_supports_unary_union?",
702
+ cmethod_factory_supports_unary_union,
703
+ 0);
704
+
705
+ // Define allocation methods for global class types
706
+ rb_define_alloc_func(rgeo_geos_geometry_class, alloc_geometry);
707
+ rb_define_alloc_func(rgeo_geos_point_class, alloc_geometry);
708
+ rb_define_alloc_func(rgeo_geos_line_string_class, alloc_geometry);
709
+ rb_define_alloc_func(rgeo_geos_linear_ring_class, alloc_geometry);
710
+ rb_define_alloc_func(rgeo_geos_line_class, alloc_geometry);
711
+ rb_define_alloc_func(rgeo_geos_polygon_class, alloc_geometry);
712
+ rb_define_alloc_func(rgeo_geos_geometry_collection_class, alloc_geometry);
713
+ rb_define_alloc_func(rgeo_geos_multi_point_class, alloc_geometry);
714
+ rb_define_alloc_func(rgeo_geos_multi_line_string_class, alloc_geometry);
715
+ rb_define_alloc_func(rgeo_geos_multi_polygon_class, alloc_geometry);
664
716
  }
665
717
 
666
-
667
718
  /**** OTHER PUBLIC FUNCTIONS ****/
668
719
 
669
-
670
- VALUE rgeo_wrap_geos_geometry(VALUE factory, GEOSGeometry* geom, VALUE klass)
720
+ VALUE
721
+ rgeo_wrap_geos_geometry(VALUE factory, GEOSGeometry* geom, VALUE klass)
671
722
  {
672
723
  VALUE result;
673
724
  RGeo_FactoryData* factory_data;
674
- GEOSContextHandle_t factory_context;
675
725
  VALUE klasses;
676
- RGeo_Globals* globals;
677
726
  VALUE inferred_klass;
678
727
  char is_collection;
679
728
  RGeo_GeometryData* data;
@@ -681,16 +730,15 @@ VALUE rgeo_wrap_geos_geometry(VALUE factory, GEOSGeometry* geom, VALUE klass)
681
730
  result = Qnil;
682
731
  if (geom || !NIL_P(klass)) {
683
732
  factory_data = NIL_P(factory) ? NULL : RGEO_FACTORY_DATA_PTR(factory);
684
- factory_context = factory_data ? factory_data->geos_context : NULL;
685
- globals = factory_data ? factory_data->globals : NULL;
686
733
 
687
734
  // We don't allow "empty" points, so replace such objects with
688
735
  // an empty collection.
689
736
  if (geom && factory) {
690
- if (GEOSGeomTypeId_r(factory_context, geom) == GEOS_POINT && GEOSGetNumCoordinates_r(factory_context, geom) == 0) {
691
- GEOSGeom_destroy_r(factory_context, geom);
692
- geom = GEOSGeom_createCollection_r(factory_context, GEOS_GEOMETRYCOLLECTION, NULL, 0);
693
- klass = globals->geos_geometry_collection;
737
+ if (GEOSGeomTypeId(geom) == GEOS_POINT &&
738
+ GEOSGetNumCoordinates(geom) == 0) {
739
+ GEOSGeom_destroy(geom);
740
+ geom = GEOSGeom_createCollection(GEOS_GEOMETRYCOLLECTION, NULL, 0);
741
+ klass = rgeo_geos_geometry_collection_class;
694
742
  }
695
743
  }
696
744
 
@@ -698,38 +746,38 @@ VALUE rgeo_wrap_geos_geometry(VALUE factory, GEOSGeometry* geom, VALUE klass)
698
746
  if (TYPE(klass) != T_CLASS) {
699
747
  inferred_klass = Qnil;
700
748
  is_collection = 0;
701
- switch (GEOSGeomTypeId_r(factory_context, geom)) {
702
- case GEOS_POINT:
703
- inferred_klass = globals->geos_point;
704
- break;
705
- case GEOS_LINESTRING:
706
- inferred_klass = globals->geos_line_string;
707
- break;
708
- case GEOS_LINEARRING:
709
- inferred_klass = globals->geos_linear_ring;
710
- break;
711
- case GEOS_POLYGON:
712
- inferred_klass = globals->geos_polygon;
713
- break;
714
- case GEOS_MULTIPOINT:
715
- inferred_klass = globals->geos_multi_point;
716
- is_collection = 1;
717
- break;
718
- case GEOS_MULTILINESTRING:
719
- inferred_klass = globals->geos_multi_line_string;
720
- is_collection = 1;
721
- break;
722
- case GEOS_MULTIPOLYGON:
723
- inferred_klass = globals->geos_multi_polygon;
724
- is_collection = 1;
725
- break;
726
- case GEOS_GEOMETRYCOLLECTION:
727
- inferred_klass = globals->geos_geometry_collection;
728
- is_collection = 1;
729
- break;
730
- default:
731
- inferred_klass = globals->geos_geometry;
732
- break;
749
+ switch (GEOSGeomTypeId(geom)) {
750
+ case GEOS_POINT:
751
+ inferred_klass = rgeo_geos_point_class;
752
+ break;
753
+ case GEOS_LINESTRING:
754
+ inferred_klass = rgeo_geos_line_string_class;
755
+ break;
756
+ case GEOS_LINEARRING:
757
+ inferred_klass = rgeo_geos_linear_ring_class;
758
+ break;
759
+ case GEOS_POLYGON:
760
+ inferred_klass = rgeo_geos_polygon_class;
761
+ break;
762
+ case GEOS_MULTIPOINT:
763
+ inferred_klass = rgeo_geos_multi_point_class;
764
+ is_collection = 1;
765
+ break;
766
+ case GEOS_MULTILINESTRING:
767
+ inferred_klass = rgeo_geos_multi_line_string_class;
768
+ is_collection = 1;
769
+ break;
770
+ case GEOS_MULTIPOLYGON:
771
+ inferred_klass = rgeo_geos_multi_polygon_class;
772
+ is_collection = 1;
773
+ break;
774
+ case GEOS_GEOMETRYCOLLECTION:
775
+ inferred_klass = rgeo_geos_geometry_collection_class;
776
+ is_collection = 1;
777
+ break;
778
+ default:
779
+ inferred_klass = rgeo_geos_geometry_class;
780
+ break;
733
781
  }
734
782
  if (TYPE(klass) == T_ARRAY && is_collection) {
735
783
  klasses = klass;
@@ -739,29 +787,33 @@ VALUE rgeo_wrap_geos_geometry(VALUE factory, GEOSGeometry* geom, VALUE klass)
739
787
  data = ALLOC(RGeo_GeometryData);
740
788
  if (data) {
741
789
  if (geom) {
742
- GEOSSetSRID_r(factory_context, geom, factory_data->srid);
790
+ GEOSSetSRID(geom, factory_data->srid);
743
791
  }
744
- data->geos_context = factory_context;
745
792
  data->geom = geom;
746
- data->prep = factory_data && ((factory_data->flags & RGEO_FACTORYFLAGS_PREPARE_HEURISTIC) != 0) ?
747
- (GEOSPreparedGeometry*)1 : NULL;
793
+ data->prep =
794
+ factory_data &&
795
+ ((factory_data->flags & RGEO_FACTORYFLAGS_PREPARE_HEURISTIC) != 0)
796
+ ? (GEOSPreparedGeometry*)1
797
+ : NULL;
748
798
  data->factory = factory;
749
799
  data->klasses = klasses;
750
- result = Data_Wrap_Struct(klass, mark_geometry_func, destroy_geometry_func, data);
800
+ result = TypedData_Wrap_Struct(klass, &rgeo_geometry_type, data);
751
801
  }
752
802
  }
753
803
  return result;
754
804
  }
755
805
 
756
-
757
- VALUE rgeo_wrap_geos_geometry_clone(VALUE factory, const GEOSGeometry* geom, VALUE klass)
806
+ VALUE
807
+ rgeo_wrap_geos_geometry_clone(VALUE factory,
808
+ const GEOSGeometry* geom,
809
+ VALUE klass)
758
810
  {
759
811
  VALUE result;
760
812
  GEOSGeometry* clone_geom;
761
813
 
762
814
  result = Qnil;
763
815
  if (geom) {
764
- clone_geom = GEOSGeom_clone_r(RGEO_FACTORY_DATA_PTR(factory)->geos_context, geom);
816
+ clone_geom = GEOSGeom_clone(geom);
765
817
  if (clone_geom) {
766
818
  result = rgeo_wrap_geos_geometry(factory, clone_geom, klass);
767
819
  }
@@ -769,84 +821,136 @@ VALUE rgeo_wrap_geos_geometry_clone(VALUE factory, const GEOSGeometry* geom, VAL
769
821
  return result;
770
822
  }
771
823
 
772
-
773
- const GEOSGeometry* rgeo_convert_to_geos_geometry(VALUE factory, VALUE obj, VALUE type)
824
+ const GEOSGeometry*
825
+ rgeo_convert_to_geos_geometry(VALUE factory, VALUE obj, VALUE type, int* state)
774
826
  {
775
827
  VALUE object;
776
- RGeo_Globals* globals;
777
828
 
778
- if (NIL_P(type) && TYPE(obj) == T_DATA && RDATA(obj)->dfree == (RUBY_DATA_FUNC)destroy_geometry_func && RGEO_GEOMETRY_DATA_PTR(obj)->factory == factory) {
829
+ if (NIL_P(type) && RGEO_GEOMETRY_TYPEDDATA_P(obj) &&
830
+ RGEO_GEOMETRY_DATA_PTR(obj)->factory == factory) {
779
831
  object = obj;
832
+ } else {
833
+ object =
834
+ rb_funcall(rgeo_feature_module, rb_intern("cast"), 3, obj, factory, type);
780
835
  }
781
- else {
782
- globals = RGEO_FACTORY_DATA_PTR(factory)->globals;
783
- object = rb_funcall(globals->feature_module, globals->id_cast, 3, obj, factory, type);
836
+ if (NIL_P(object)) {
837
+ rb_protect(
838
+ rb_exc_raise_value,
839
+ rb_exc_new_cstr(rb_eRGeoInvalidGeometry,
840
+ "Unable to cast the geometry to the GEOS Factory"),
841
+ state);
784
842
  }
785
- if (NIL_P(object))
843
+
844
+ if (*state) {
786
845
  return NULL;
846
+ }
847
+
848
+ if (!rgeo_is_geos_object(object)) {
849
+ rb_protect(rb_exc_raise_value,
850
+ rb_exc_new_cstr(rb_eRGeoError, "Not a GEOS Geometry object."),
851
+ state);
852
+ }
853
+
854
+ if (*state) {
855
+ return NULL;
856
+ }
787
857
 
788
- Check_Type(object, T_DATA);
789
858
  return RGEO_GEOMETRY_DATA_PTR(object)->geom;
790
859
  }
791
860
 
792
-
793
- GEOSGeometry* rgeo_convert_to_detached_geos_geometry(VALUE obj, VALUE factory, VALUE type, VALUE* klasses)
861
+ GEOSGeometry*
862
+ rgeo_convert_to_detached_geos_geometry(VALUE obj,
863
+ VALUE factory,
864
+ VALUE type,
865
+ VALUE* klasses,
866
+ int* state)
794
867
  {
795
868
  VALUE object;
796
869
  GEOSGeometry* geom;
797
870
  RGeo_GeometryData* object_data;
798
871
  const GEOSPreparedGeometry* prep;
799
- RGeo_Globals* globals;
800
872
 
801
873
  if (klasses) {
802
874
  *klasses = Qnil;
803
875
  }
804
- globals = RGEO_FACTORY_DATA_PTR(factory)->globals;
805
- object = rb_funcall(globals->feature_module, globals->id_cast, 5, obj, factory, type, globals->sym_force_new, globals->sym_keep_subtype);
806
- geom = NULL;
807
- if (!NIL_P(object)) {
808
- object_data = RGEO_GEOMETRY_DATA_PTR(object);
809
- geom = object_data->geom;
810
- if (klasses) {
811
- *klasses = object_data->klasses;
812
- if (NIL_P(*klasses)) {
813
- *klasses = CLASS_OF(object);
814
- }
815
- }
816
- prep = object_data->prep;
817
- if (prep && prep != (GEOSPreparedGeometry*)1 && prep != (GEOSPreparedGeometry*)2) {
818
- GEOSPreparedGeom_destroy_r(object_data->geos_context, prep);
876
+
877
+ object = rb_protect_funcall(rgeo_feature_module,
878
+ rb_intern("cast"),
879
+ state,
880
+ 5,
881
+ obj,
882
+ factory,
883
+ type,
884
+ ID2SYM(rb_intern("force_new")),
885
+ ID2SYM(rb_intern("keep_subtype")));
886
+
887
+ if (NIL_P(object)) {
888
+ rb_protect(
889
+ rb_exc_raise_value,
890
+ rb_exc_new_cstr(rb_eRGeoInvalidGeometry,
891
+ "Unable to cast the geometry to the GEOS Factory"),
892
+ state);
893
+ }
894
+ if (*state) {
895
+ return NULL;
896
+ }
897
+
898
+ if (!rgeo_is_geos_object(object)) {
899
+ rb_protect(rb_exc_raise_value,
900
+ rb_exc_new_cstr(rb_eRGeoError, "Not a GEOS Geometry object."),
901
+ state);
902
+ }
903
+ if (*state) {
904
+ return NULL;
905
+ }
906
+
907
+ object_data = RGEO_GEOMETRY_DATA_PTR(object);
908
+ geom = object_data->geom;
909
+ if (klasses) {
910
+ *klasses = object_data->klasses;
911
+ if (NIL_P(*klasses)) {
912
+ *klasses = CLASS_OF(object);
819
913
  }
820
- object_data->geos_context = NULL;
821
- object_data->geom = NULL;
822
- object_data->prep = NULL;
823
- object_data->factory = Qnil;
824
- object_data->klasses = Qnil;
825
914
  }
915
+ prep = object_data->prep;
916
+ if (prep && prep != (GEOSPreparedGeometry*)1 &&
917
+ prep != (GEOSPreparedGeometry*)2) {
918
+ GEOSPreparedGeom_destroy(prep);
919
+ }
920
+ object_data->geom = NULL;
921
+ object_data->prep = NULL;
922
+ object_data->factory = Qnil;
923
+ object_data->klasses = Qnil;
924
+
826
925
  return geom;
827
926
  }
828
927
 
829
-
830
- char rgeo_is_geos_object(VALUE obj)
928
+ char
929
+ rgeo_is_geos_object(VALUE obj)
831
930
  {
832
- return (TYPE(obj) == T_DATA && RDATA(obj)->dfree == (RUBY_DATA_FUNC)destroy_geometry_func) ? 1 : 0;
931
+ return RGEO_GEOMETRY_TYPEDDATA_P(obj) ? 1 : 0;
833
932
  }
834
933
 
835
- void rgeo_check_geos_object(VALUE obj)
934
+ void
935
+ rgeo_check_geos_object(VALUE obj)
836
936
  {
837
937
  if (!rgeo_is_geos_object(obj)) {
838
- rb_raise(rgeo_error, "Not a GEOS Geometry object.");
938
+ rb_raise(rb_eRGeoError, "Not a GEOS Geometry object.");
839
939
  }
840
940
  }
841
941
 
842
-
843
- const GEOSGeometry* rgeo_get_geos_geometry_safe(VALUE obj)
942
+ const GEOSGeometry*
943
+ rgeo_get_geos_geometry_safe(VALUE obj)
844
944
  {
845
- return (TYPE(obj) == T_DATA && RDATA(obj)->dfree == (RUBY_DATA_FUNC)destroy_geometry_func) ? (const GEOSGeometry*)(RGEO_GEOMETRY_DATA_PTR(obj)->geom) : NULL;
945
+ return RGEO_GEOMETRY_TYPEDDATA_P(obj)
946
+ ? (const GEOSGeometry*)(RGEO_GEOMETRY_DATA_PTR(obj)->geom)
947
+ : NULL;
846
948
  }
847
949
 
848
-
849
- VALUE rgeo_geos_coordseqs_eql(GEOSContextHandle_t context, const GEOSGeometry* geom1, const GEOSGeometry* geom2, char check_z)
950
+ VALUE
951
+ rgeo_geos_coordseqs_eql(const GEOSGeometry* geom1,
952
+ const GEOSGeometry* geom2,
953
+ char check_z)
850
954
  {
851
955
  VALUE result;
852
956
  const GEOSCoordSequence* cs1;
@@ -858,27 +962,30 @@ VALUE rgeo_geos_coordseqs_eql(GEOSContextHandle_t context, const GEOSGeometry* g
858
962
 
859
963
  result = Qnil;
860
964
  if (geom1 && geom2) {
861
- cs1 = GEOSGeom_getCoordSeq_r(context, geom1);
862
- cs2 = GEOSGeom_getCoordSeq_r(context, geom2);
965
+ cs1 = GEOSGeom_getCoordSeq(geom1);
966
+ cs2 = GEOSGeom_getCoordSeq(geom2);
863
967
  if (cs1 && cs2) {
864
968
  len1 = 0;
865
969
  len2 = 0;
866
- if (GEOSCoordSeq_getSize_r(context, cs1, &len1) && GEOSCoordSeq_getSize_r(context, cs2, &len2)) {
970
+ if (GEOSCoordSeq_getSize(cs1, &len1) &&
971
+ GEOSCoordSeq_getSize(cs2, &len2)) {
867
972
  if (len1 == len2) {
868
973
  result = Qtrue;
869
- for (i=0; i<len1; ++i) {
870
- if (GEOSCoordSeq_getX_r(context, cs1, i, &val1) && GEOSCoordSeq_getX_r(context, cs2, i, &val2)) {
974
+ for (i = 0; i < len1; ++i) {
975
+ if (GEOSCoordSeq_getX(cs1, i, &val1) &&
976
+ GEOSCoordSeq_getX(cs2, i, &val2)) {
871
977
  if (val1 == val2) {
872
- if (GEOSCoordSeq_getY_r(context, cs1, i, &val1) && GEOSCoordSeq_getY_r(context, cs2, i, &val2)) {
978
+ if (GEOSCoordSeq_getY(cs1, i, &val1) &&
979
+ GEOSCoordSeq_getY(cs2, i, &val2)) {
873
980
  if (val1 == val2) {
874
981
  if (check_z) {
875
982
  val1 = 0;
876
- if (!GEOSCoordSeq_getZ_r(context, cs1, i, &val1)) {
983
+ if (!GEOSCoordSeq_getZ(cs1, i, &val1)) {
877
984
  result = Qnil;
878
985
  break;
879
986
  }
880
987
  val2 = 0;
881
- if (!GEOSCoordSeq_getZ_r(context, cs2, i, &val2)) {
988
+ if (!GEOSCoordSeq_getZ(cs2, i, &val2)) {
882
989
  result = Qnil;
883
990
  break;
884
991
  }
@@ -887,29 +994,24 @@ VALUE rgeo_geos_coordseqs_eql(GEOSContextHandle_t context, const GEOSGeometry* g
887
994
  break;
888
995
  }
889
996
  }
890
- }
891
- else { // Y coords are different
997
+ } else { // Y coords are different
892
998
  result = Qfalse;
893
999
  break;
894
1000
  }
895
- }
896
- else { // Failed to get Y coords
1001
+ } else { // Failed to get Y coords
897
1002
  result = Qnil;
898
1003
  break;
899
1004
  }
900
- }
901
- else { // X coords are different
1005
+ } else { // X coords are different
902
1006
  result = Qfalse;
903
1007
  break;
904
1008
  }
905
- }
906
- else { // Failed to get X coords
1009
+ } else { // Failed to get X coords
907
1010
  result = Qnil;
908
1011
  break;
909
1012
  }
910
- } // Iteration over coords
911
- }
912
- else { // Lengths are different
1013
+ } // Iteration over coords
1014
+ } else { // Lengths are different
913
1015
  result = Qfalse;
914
1016
  }
915
1017
  }
@@ -918,8 +1020,8 @@ VALUE rgeo_geos_coordseqs_eql(GEOSContextHandle_t context, const GEOSGeometry* g
918
1020
  return result;
919
1021
  }
920
1022
 
921
-
922
- VALUE rgeo_geos_klasses_and_factories_eql(VALUE obj1, VALUE obj2)
1023
+ VALUE
1024
+ rgeo_geos_klasses_and_factories_eql(VALUE obj1, VALUE obj2)
923
1025
  {
924
1026
  VALUE result;
925
1027
  VALUE factory;
@@ -927,23 +1029,25 @@ VALUE rgeo_geos_klasses_and_factories_eql(VALUE obj1, VALUE obj2)
927
1029
  result = Qnil;
928
1030
  if (rb_obj_class(obj1) != rb_obj_class(obj2)) {
929
1031
  result = Qfalse;
930
- }
931
- else {
1032
+ } else {
932
1033
  factory = RGEO_GEOMETRY_DATA_PTR(obj1)->factory;
933
- result = rb_funcall(factory, RGEO_FACTORY_DATA_PTR(factory)->globals->id_eql, 1, RGEO_GEOMETRY_DATA_PTR(obj2)->factory);
1034
+ /* No need to cache the internal here (https://ips.fastruby.io/4x) */
1035
+ result = rb_funcall(
1036
+ factory, rb_intern("eql?"), 1, RGEO_GEOMETRY_DATA_PTR(obj2)->factory);
934
1037
  }
935
1038
  return result;
936
1039
  }
937
1040
 
938
-
939
- typedef struct {
1041
+ typedef struct
1042
+ {
940
1043
  st_index_t seed_hash;
941
1044
  double x;
942
1045
  double y;
943
1046
  double z;
944
1047
  } RGeo_Coordseq_Hash_Struct;
945
1048
 
946
- st_index_t rgeo_geos_coordseq_hash(GEOSContextHandle_t context, const GEOSGeometry* geom, st_index_t hash)
1049
+ st_index_t
1050
+ rgeo_geos_coordseq_hash(const GEOSGeometry* geom, st_index_t hash)
947
1051
  {
948
1052
  const GEOSCoordSequence* cs;
949
1053
  unsigned int len;
@@ -951,17 +1055,18 @@ st_index_t rgeo_geos_coordseq_hash(GEOSContextHandle_t context, const GEOSGeomet
951
1055
  RGeo_Coordseq_Hash_Struct hash_struct;
952
1056
 
953
1057
  if (geom) {
954
- cs = GEOSGeom_getCoordSeq_r(context, geom);
1058
+ cs = GEOSGeom_getCoordSeq(geom);
955
1059
  if (cs) {
956
- if (GEOSCoordSeq_getSize_r(context, cs, &len)) {
957
- for (i=0; i<len; ++i) {
958
- if (GEOSCoordSeq_getX_r(context, cs, i, &hash_struct.x)) {
959
- if (GEOSCoordSeq_getY_r(context, cs, i, &hash_struct.y)) {
960
- if (!GEOSCoordSeq_getY_r(context, cs, i, &hash_struct.z)) {
1060
+ if (GEOSCoordSeq_getSize(cs, &len)) {
1061
+ for (i = 0; i < len; ++i) {
1062
+ if (GEOSCoordSeq_getX(cs, i, &hash_struct.x)) {
1063
+ if (GEOSCoordSeq_getY(cs, i, &hash_struct.y)) {
1064
+ if (!GEOSCoordSeq_getZ(cs, i, &hash_struct.z)) {
961
1065
  hash_struct.z = 0;
962
1066
  }
963
1067
  hash_struct.seed_hash = hash;
964
- hash = rb_memhash(&hash_struct, sizeof(RGeo_Coordseq_Hash_Struct));
1068
+ hash =
1069
+ rb_memhash(&hash_struct, sizeof(RGeo_Coordseq_Hash_Struct));
965
1070
  }
966
1071
  }
967
1072
  }
@@ -971,42 +1076,26 @@ st_index_t rgeo_geos_coordseq_hash(GEOSContextHandle_t context, const GEOSGeomet
971
1076
  return hash;
972
1077
  }
973
1078
 
974
-
975
- typedef struct {
1079
+ typedef struct
1080
+ {
976
1081
  st_index_t seed_hash;
977
1082
  st_index_t h1;
978
1083
  st_index_t h2;
979
1084
  } RGeo_Objbase_Hash_Struct;
980
1085
 
981
- st_index_t rgeo_geos_objbase_hash(VALUE factory, VALUE type_module, st_index_t hash)
1086
+ st_index_t
1087
+ rgeo_geos_objbase_hash(VALUE factory, VALUE type_module, st_index_t hash)
982
1088
  {
983
1089
  ID hash_method;
984
1090
  RGeo_Objbase_Hash_Struct hash_struct;
985
1091
 
986
- hash_method = RGEO_FACTORY_DATA_PTR(factory)->globals->id_hash;
1092
+ hash_method = rb_intern("hash");
987
1093
  hash_struct.seed_hash = hash;
988
1094
  hash_struct.h1 = FIX2LONG(rb_funcall(factory, hash_method, 0));
989
1095
  hash_struct.h2 = FIX2LONG(rb_funcall(type_module, hash_method, 0));
990
1096
  return rb_memhash(&hash_struct, sizeof(RGeo_Objbase_Hash_Struct));
991
1097
  }
992
1098
 
993
-
994
- st_index_t rgeo_internal_memhash(const void* ptr, long len)
995
- {
996
- const char* bytes;
997
- st_index_t hval;
998
- long i;
999
-
1000
- bytes = (const char*)ptr;
1001
- hval = 0x811c9dc5;
1002
- for (i=0; i<len; ++i) {
1003
- hval ^= (unsigned int)(*bytes++);
1004
- hval *= 0x01000193;
1005
- }
1006
- return hval;
1007
- }
1008
-
1009
-
1010
1099
  RGEO_END_C
1011
1100
 
1012
1101
  #endif