rgeo 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. data/History.rdoc +6 -0
  2. data/README.rdoc +10 -7
  3. data/Version +1 -1
  4. data/ext/geos_c_impl/extconf.rb +42 -34
  5. data/ext/geos_c_impl/factory.c +56 -39
  6. data/ext/geos_c_impl/factory.h +55 -45
  7. data/ext/geos_c_impl/geometry.c +137 -93
  8. data/ext/geos_c_impl/geometry_collection.c +67 -46
  9. data/ext/geos_c_impl/line_string.c +79 -54
  10. data/ext/geos_c_impl/point.c +37 -24
  11. data/ext/geos_c_impl/polygon.c +40 -25
  12. data/ext/proj4_c_impl/extconf.rb +44 -36
  13. data/lib/rgeo/coord_sys.rb +3 -1
  14. data/lib/rgeo/geos.rb +3 -1
  15. data/lib/rgeo/geos/impl_additions.rb +12 -10
  16. data/test/coord_sys/tc_proj4.rb +1 -1
  17. data/test/geos/tc_factory.rb +1 -1
  18. data/test/geos/tc_geometry_collection.rb +1 -1
  19. data/test/geos/tc_line_string.rb +1 -1
  20. data/test/geos/tc_misc.rb +1 -1
  21. data/test/geos/tc_multi_line_string.rb +1 -1
  22. data/test/geos/tc_multi_point.rb +1 -1
  23. data/test/geos/tc_multi_polygon.rb +1 -1
  24. data/test/geos/tc_point.rb +1 -1
  25. data/test/geos/tc_polygon.rb +1 -1
  26. data/test/geos/tc_zmfactory.rb +1 -1
  27. data/test/projected_geographic/tc_geometry_collection.rb +1 -1
  28. data/test/projected_geographic/tc_line_string.rb +1 -1
  29. data/test/projected_geographic/tc_multi_line_string.rb +1 -1
  30. data/test/projected_geographic/tc_multi_point.rb +1 -1
  31. data/test/projected_geographic/tc_multi_polygon.rb +1 -1
  32. data/test/projected_geographic/tc_point.rb +1 -1
  33. data/test/projected_geographic/tc_polygon.rb +1 -1
  34. data/test/simple_cartesian/tc_calculations.rb +1 -1
  35. data/test/tc_oneoff.rb +5 -5
  36. data/test/wkrep/tc_wkt_parser.rb +4 -4
  37. metadata +3 -3
@@ -64,19 +64,21 @@ static VALUE create_geometry_collection(VALUE module, int type, VALUE factory, V
64
64
  unsigned int len = (unsigned int)RARRAY_LEN(array);
65
65
  GEOSGeometry** geoms = ALLOC_N(GEOSGeometry*, len == 0 ? 1 : len);
66
66
  if (geoms) {
67
+ RGeo_FactoryData* factory_data = RGEO_FACTORY_DATA_PTR(factory);
68
+ GEOSContextHandle_t geos_context = factory_data->geos_context;
67
69
  VALUE klass;
68
70
  unsigned int i,j;
69
71
  VALUE klasses = Qnil;
70
72
  VALUE cast_type = Qnil;
71
73
  switch (type) {
72
74
  case GEOS_MULTIPOINT:
73
- cast_type = rb_const_get_at(RGEO_GLOBALS_FROM_FACTORY(factory)->features_module, rb_intern("Point"));
75
+ cast_type = factory_data->globals->feature_point;
74
76
  break;
75
77
  case GEOS_MULTILINESTRING:
76
- cast_type = rb_const_get_at(RGEO_GLOBALS_FROM_FACTORY(factory)->features_module, rb_intern("LineString"));
78
+ cast_type = factory_data->globals->feature_line_string;
77
79
  break;
78
80
  case GEOS_MULTIPOLYGON:
79
- cast_type = rb_const_get_at(RGEO_GLOBALS_FROM_FACTORY(factory)->features_module, rb_intern("Polygon"));
81
+ cast_type = factory_data->globals->feature_polygon;
80
82
  break;
81
83
  }
82
84
  for (i=0; i<len; ++i) {
@@ -97,24 +99,24 @@ static VALUE create_geometry_collection(VALUE module, int type, VALUE factory, V
97
99
  }
98
100
  if (i != len) {
99
101
  for (j=0; j<i; ++j) {
100
- GEOSGeom_destroy_r(RGEO_CONTEXT_FROM_FACTORY(factory), geoms[j]);
102
+ GEOSGeom_destroy_r(geos_context, geoms[j]);
101
103
  }
102
104
  }
103
105
  else {
104
- GEOSGeometry* collection = GEOSGeom_createCollection_r(RGEO_CONTEXT_FROM_FACTORY(factory), type, geoms, len);
106
+ GEOSGeometry* collection = GEOSGeom_createCollection_r(geos_context, type, geoms, len);
105
107
  // Due to a limitation of GEOS, the MultiPolygon assertions are not checked.
106
108
  // We do that manually here.
107
- if (collection && type == GEOS_MULTIPOLYGON && (RGEO_FACTORY_DATA_PTR(factory)->flags & 1) == 0) {
109
+ if (collection && type == GEOS_MULTIPOLYGON && (factory_data->flags & 1) == 0) {
108
110
  char problem = 0;
109
111
  for (i=1; i<len; ++i) {
110
112
  for (j=0; j<i; ++j) {
111
113
  GEOSGeometry* igeom = geoms[i];
112
114
  GEOSGeometry* jgeom = geoms[j];
113
- problem = GEOSRelatePattern_r(RGEO_CONTEXT_FROM_FACTORY(factory), igeom, jgeom, "2********");
115
+ problem = GEOSRelatePattern_r(geos_context, igeom, jgeom, "2********");
114
116
  if (problem) {
115
117
  break;
116
118
  }
117
- problem = GEOSRelatePattern_r(RGEO_CONTEXT_FROM_FACTORY(factory), igeom, jgeom, "****1****");
119
+ problem = GEOSRelatePattern_r(geos_context, igeom, jgeom, "****1****");
118
120
  if (problem) {
119
121
  break;
120
122
  }
@@ -124,7 +126,7 @@ static VALUE create_geometry_collection(VALUE module, int type, VALUE factory, V
124
126
  }
125
127
  }
126
128
  if (problem) {
127
- GEOSGeom_destroy_r(RGEO_CONTEXT_FROM_FACTORY(factory), collection);
129
+ GEOSGeom_destroy_r(geos_context, collection);
128
130
  collection = NULL;
129
131
  }
130
132
  }
@@ -151,7 +153,8 @@ static VALUE method_geometry_collection_eql(VALUE self, VALUE rhs)
151
153
  {
152
154
  VALUE result = rgeo_geos_klasses_and_factories_eql(self, rhs);
153
155
  if (RTEST(result)) {
154
- result = rgeo_geos_geometry_collections_eql(RGEO_CONTEXT_FROM_GEOMETRY(self), RGEO_GET_GEOS_GEOMETRY(self), RGEO_GET_GEOS_GEOMETRY(rhs), RGEO_FACTORY_DATA_FROM_GEOMETRY(self)->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M);
156
+ RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
157
+ result = rgeo_geos_geometry_collections_eql(self_data->geos_context, self_data->geom, RGEO_GEOMETRY_DATA_PTR(rhs)->geom, RGEO_FACTORY_DATA_PTR(self_data->factory)->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M);
155
158
  }
156
159
  return result;
157
160
  }
@@ -160,9 +163,9 @@ static VALUE method_geometry_collection_eql(VALUE self, VALUE rhs)
160
163
  static VALUE method_geometry_collection_geometry_type(VALUE self)
161
164
  {
162
165
  VALUE result = Qnil;
163
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
164
- if (self_geom) {
165
- result = rb_const_get_at(RGEO_GLOBALS_FROM_GEOMETRY(self)->features_module, rb_intern("GeometryCollection"));
166
+ RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
167
+ if (self_data->geom) {
168
+ result = RGEO_FACTORY_DATA_PTR(self_data->factory)->globals->feature_geometry_collection;
166
169
  }
167
170
  return result;
168
171
  }
@@ -171,9 +174,10 @@ static VALUE method_geometry_collection_geometry_type(VALUE self)
171
174
  static VALUE method_geometry_collection_num_geometries(VALUE self)
172
175
  {
173
176
  VALUE result = Qnil;
174
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
177
+ RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
178
+ const GEOSGeometry* self_geom = self_data->geom;
175
179
  if (self_geom) {
176
- result = INT2NUM(GEOSGetNumGeometries_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom));
180
+ result = INT2NUM(GEOSGetNumGeometries_r(self_data->geos_context, self_geom));
177
181
  }
178
182
  return result;
179
183
  }
@@ -182,12 +186,13 @@ static VALUE method_geometry_collection_num_geometries(VALUE self)
182
186
  static VALUE method_geometry_collection_geometry_n(VALUE self, VALUE n)
183
187
  {
184
188
  VALUE result = Qnil;
185
- 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;
186
191
  if (self_geom) {
187
- VALUE klasses = RGEO_KLASSES_FROM_GEOMETRY(self);
192
+ VALUE klasses = self_data->klasses;
188
193
  int i = NUM2INT(n);
189
- const GEOSGeometry* elem_geom = GEOSGetGeometryN_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom, i);
190
- result = rgeo_wrap_geos_geometry_clone(RGEO_FACTORY_FROM_GEOMETRY(self), elem_geom, NIL_P(klasses) ? Qnil : rb_ary_entry(klasses, i));
194
+ const GEOSGeometry* elem_geom = GEOSGetGeometryN_r(self_data->geos_context, self_geom, i);
195
+ result = rgeo_wrap_geos_geometry_clone(self_data->factory, elem_geom, NIL_P(klasses) ? Qnil : rb_ary_entry(klasses, i));
191
196
  }
192
197
  return result;
193
198
  }
@@ -195,16 +200,18 @@ static VALUE method_geometry_collection_geometry_n(VALUE self, VALUE n)
195
200
 
196
201
  static VALUE method_geometry_collection_each(VALUE self)
197
202
  {
198
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
203
+ RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
204
+ const GEOSGeometry* self_geom = self_data->geom;
199
205
  if (self_geom) {
200
- int len = GEOSGetNumGeometries_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom);
206
+ GEOSContextHandle_t self_context = self_data->geos_context;
207
+ int len = GEOSGetNumGeometries_r(self_context, self_geom);
201
208
  if (len > 0) {
202
- VALUE klasses = RGEO_KLASSES_FROM_GEOMETRY(self);
209
+ VALUE klasses = self_data->klasses;
203
210
  int i;
204
211
  for (i=0; i<len; ++i) {
205
212
  VALUE elem;
206
- const GEOSGeometry* elem_geom = GEOSGetGeometryN_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom, i);
207
- elem = rgeo_wrap_geos_geometry_clone(RGEO_FACTORY_FROM_GEOMETRY(self), elem_geom, NIL_P(klasses) ? Qnil : rb_ary_entry(klasses, i));
213
+ const GEOSGeometry* elem_geom = GEOSGetGeometryN_r(self_context, self_geom, i);
214
+ elem = rgeo_wrap_geos_geometry_clone(self_data->factory, elem_geom, NIL_P(klasses) ? Qnil : rb_ary_entry(klasses, i));
208
215
  if (!NIL_P(elem)) {
209
216
  rb_yield(elem);
210
217
  }
@@ -218,9 +225,9 @@ static VALUE method_geometry_collection_each(VALUE self)
218
225
  static VALUE method_multi_point_geometry_type(VALUE self)
219
226
  {
220
227
  VALUE result = Qnil;
221
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
222
- if (self_geom) {
223
- result = rb_const_get_at(RGEO_GLOBALS_FROM_GEOMETRY(self)->features_module, rb_intern("MultiPoint"));
228
+ RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
229
+ if (self_data->geom) {
230
+ result = RGEO_FACTORY_DATA_PTR(self_data->factory)->globals->feature_multi_point;
224
231
  }
225
232
  return result;
226
233
  }
@@ -229,9 +236,9 @@ static VALUE method_multi_point_geometry_type(VALUE self)
229
236
  static VALUE method_multi_line_string_geometry_type(VALUE self)
230
237
  {
231
238
  VALUE result = Qnil;
232
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
233
- if (self_geom) {
234
- result = rb_const_get_at(RGEO_GLOBALS_FROM_GEOMETRY(self)->features_module, rb_intern("MultiLineString"));
239
+ RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
240
+ if (self_data->geom) {
241
+ result = RGEO_FACTORY_DATA_PTR(self_data->factory)->globals->feature_multi_line_string;
235
242
  }
236
243
  return result;
237
244
  }
@@ -239,11 +246,12 @@ static VALUE method_multi_line_string_geometry_type(VALUE self)
239
246
 
240
247
  static VALUE method_multi_line_string_length(VALUE self)
241
248
  {
242
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
243
249
  VALUE result = Qnil;
250
+ RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
251
+ const GEOSGeometry* self_geom = self_data->geom;
244
252
  if (self_geom) {
245
253
  double len;
246
- if (GEOSLength_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom, &len)) {
254
+ if (GEOSLength_r(self_data->geos_context, self_geom, &len)) {
247
255
  result = rb_float_new(len);
248
256
  }
249
257
  }
@@ -253,17 +261,19 @@ static VALUE method_multi_line_string_length(VALUE self)
253
261
 
254
262
  static VALUE method_multi_line_string_is_closed(VALUE self)
255
263
  {
256
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
257
264
  VALUE result = Qnil;
265
+ RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
266
+ const GEOSGeometry* self_geom = self_data->geom;
258
267
  if (self_geom) {
268
+ GEOSContextHandle_t self_context = self_data->geos_context;
259
269
  result = Qtrue;
260
- int len = GEOSGetNumGeometries_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom);
270
+ int len = GEOSGetNumGeometries_r(self_context, self_geom);
261
271
  if (len > 0) {
262
272
  int i;
263
273
  for (i=0; i<len; ++i) {
264
- const GEOSGeometry* geom = GEOSGetGeometryN_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom, i);
274
+ const GEOSGeometry* geom = GEOSGetGeometryN_r(self_context, self_geom, i);
265
275
  if (geom) {
266
- result = rgeo_is_geos_line_string_closed(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom);
276
+ result = rgeo_is_geos_line_string_closed(self_context, self_geom);
267
277
  if (result != Qtrue) {
268
278
  break;
269
279
  }
@@ -278,9 +288,9 @@ static VALUE method_multi_line_string_is_closed(VALUE self)
278
288
  static VALUE method_multi_polygon_geometry_type(VALUE self)
279
289
  {
280
290
  VALUE result = Qnil;
281
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
282
- if (self_geom) {
283
- result = rb_const_get_at(RGEO_GLOBALS_FROM_GEOMETRY(self)->features_module, rb_intern("MultiPolygon"));
291
+ RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
292
+ if (self_data->geom) {
293
+ result = RGEO_FACTORY_DATA_PTR(self_data->factory)->globals->feature_multi_polygon;
284
294
  }
285
295
  return result;
286
296
  }
@@ -289,10 +299,11 @@ static VALUE method_multi_polygon_geometry_type(VALUE self)
289
299
  static VALUE method_multi_polygon_area(VALUE self)
290
300
  {
291
301
  VALUE result = Qnil;
292
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
302
+ RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
303
+ const GEOSGeometry* self_geom = self_data->geom;
293
304
  if (self_geom) {
294
305
  double area;
295
- if (GEOSArea_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom, &area)) {
306
+ if (GEOSArea_r(self_data->geos_context, self_geom, &area)) {
296
307
  result = rb_float_new(area);
297
308
  }
298
309
  }
@@ -303,9 +314,10 @@ static VALUE method_multi_polygon_area(VALUE self)
303
314
  static VALUE method_multi_polygon_centroid(VALUE self)
304
315
  {
305
316
  VALUE result = Qnil;
306
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
317
+ RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
318
+ const GEOSGeometry* self_geom = self_data->geom;
307
319
  if (self_geom) {
308
- result = rgeo_wrap_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), GEOSGetCentroid_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom), Qnil);
320
+ result = rgeo_wrap_geos_geometry(self_data->factory, GEOSGetCentroid_r(self_data->geos_context, self_geom), Qnil);
309
321
  }
310
322
  return result;
311
323
  }
@@ -314,9 +326,10 @@ static VALUE method_multi_polygon_centroid(VALUE self)
314
326
  static VALUE method_multi_polygon_point_on_surface(VALUE self)
315
327
  {
316
328
  VALUE result = Qnil;
317
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
329
+ RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
330
+ const GEOSGeometry* self_geom = self_data->geom;
318
331
  if (self_geom) {
319
- result = rgeo_wrap_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), GEOSPointOnSurface_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom), Qnil);
332
+ result = rgeo_wrap_geos_geometry(self_data->factory, GEOSPointOnSurface_r(self_data->geos_context, self_geom), Qnil);
320
333
  }
321
334
  return result;
322
335
  }
@@ -352,10 +365,18 @@ static VALUE cmethod_multi_polygon_create(VALUE module, VALUE factory, VALUE arr
352
365
  void rgeo_init_geos_geometry_collection(RGeo_Globals* globals)
353
366
  {
354
367
  // Create implementation classes
355
- VALUE geos_geometry_collection_class = rb_define_class_under(globals->geos_module, "GeometryCollectionImpl", rb_const_get_at(globals->geos_module, rb_intern("GeometryImpl")));
368
+ VALUE geos_geometry_collection_class = rb_define_class_under(globals->geos_module, "GeometryCollectionImpl", globals->geos_geometry);
369
+ globals->geos_geometry_collection = geos_geometry_collection_class;
370
+ globals->feature_geometry_collection = rb_const_get_at(globals->feature_module, rb_intern("GeometryCollection"));
356
371
  VALUE geos_multi_point_class = rb_define_class_under(globals->geos_module, "MultiPointImpl", geos_geometry_collection_class);
372
+ globals->geos_multi_point = geos_multi_point_class;
373
+ globals->feature_multi_point = rb_const_get_at(globals->feature_module, rb_intern("MultiPoint"));
357
374
  VALUE geos_multi_line_string_class = rb_define_class_under(globals->geos_module, "MultiLineStringImpl", geos_geometry_collection_class);
375
+ globals->geos_multi_line_string = geos_multi_line_string_class;
376
+ globals->feature_multi_line_string = rb_const_get_at(globals->feature_module, rb_intern("MultiLineString"));
358
377
  VALUE geos_multi_polygon_class = rb_define_class_under(globals->geos_module, "MultiPolygonImpl", geos_geometry_collection_class);
378
+ globals->geos_multi_polygon = geos_multi_polygon_class;
379
+ globals->feature_multi_polygon = rb_const_get_at(globals->feature_module, rb_intern("MultiPolygon"));
359
380
 
360
381
  // Methods for GeometryCollectionImpl
361
382
  rb_define_module_function(geos_geometry_collection_class, "create", cmethod_geometry_collection_create, 2);
@@ -54,9 +54,9 @@ RGEO_BEGIN_C
54
54
  static VALUE method_line_string_geometry_type(VALUE self)
55
55
  {
56
56
  VALUE result = Qnil;
57
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
58
- if (self_geom) {
59
- result = rb_const_get_at(RGEO_GLOBALS_FROM_GEOMETRY(self)->features_module, rb_intern("LineString"));
57
+ RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
58
+ if (self_data->geom) {
59
+ result = RGEO_FACTORY_DATA_PTR(self_data->factory)->globals->feature_line_string;
60
60
  }
61
61
  return result;
62
62
  }
@@ -65,9 +65,9 @@ static VALUE method_line_string_geometry_type(VALUE self)
65
65
  static VALUE method_linear_ring_geometry_type(VALUE self)
66
66
  {
67
67
  VALUE result = Qnil;
68
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
69
- if (self_geom) {
70
- result = rb_const_get_at(RGEO_GLOBALS_FROM_GEOMETRY(self)->features_module, rb_intern("LinearRing"));
68
+ RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
69
+ if (self_data->geom) {
70
+ result = RGEO_FACTORY_DATA_PTR(self_data->factory)->globals->feature_linear_ring;
71
71
  }
72
72
  return result;
73
73
  }
@@ -76,9 +76,9 @@ static VALUE method_linear_ring_geometry_type(VALUE self)
76
76
  static VALUE method_line_geometry_type(VALUE self)
77
77
  {
78
78
  VALUE result = Qnil;
79
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
80
- if (self_geom) {
81
- result = rb_const_get_at(RGEO_GLOBALS_FROM_GEOMETRY(self)->features_module, rb_intern("Line"));
79
+ RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
80
+ if (self_data->geom) {
81
+ result = RGEO_FACTORY_DATA_PTR(self_data->factory)->globals->feature_line;
82
82
  }
83
83
  return result;
84
84
  }
@@ -87,10 +87,11 @@ static VALUE method_line_geometry_type(VALUE self)
87
87
  static VALUE method_line_string_length(VALUE self)
88
88
  {
89
89
  VALUE result = Qnil;
90
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
90
+ RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
91
+ const GEOSGeometry* self_geom = self_data->geom;
91
92
  if (self_geom) {
92
93
  double len;
93
- if (GEOSLength_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom, &len)) {
94
+ if (GEOSLength_r(self_data->geos_context, self_geom, &len)) {
94
95
  result = rb_float_new(len);
95
96
  }
96
97
  }
@@ -101,9 +102,10 @@ static VALUE method_line_string_length(VALUE self)
101
102
  static VALUE method_line_string_num_points(VALUE self)
102
103
  {
103
104
  VALUE result = Qnil;
104
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
105
+ RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
106
+ const GEOSGeometry* self_geom = self_data->geom;
105
107
  if (self_geom) {
106
- result = INT2NUM(GEOSGetNumCoordinates_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom));
108
+ result = INT2NUM(GEOSGetNumCoordinates_r(self_data->geos_context, self_geom));
107
109
  }
108
110
  return result;
109
111
  }
@@ -113,17 +115,19 @@ static VALUE get_point_from_coordseq(VALUE self, const GEOSCoordSequence* coord_
113
115
  {
114
116
  VALUE result = Qnil;
115
117
  double x, y, z;
116
- if (GEOSCoordSeq_getX_r(RGEO_CONTEXT_FROM_GEOMETRY(self), coord_seq, i, &x)) {
117
- if (GEOSCoordSeq_getY_r(RGEO_CONTEXT_FROM_GEOMETRY(self), coord_seq, i, &y)) {
118
+ RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
119
+ GEOSContextHandle_t self_context = self_data->geos_context;
120
+ if (GEOSCoordSeq_getX_r(self_context, coord_seq, i, &x)) {
121
+ if (GEOSCoordSeq_getY_r(self_context, coord_seq, i, &y)) {
118
122
  if (has_z) {
119
- if (!GEOSCoordSeq_getZ_r(RGEO_CONTEXT_FROM_GEOMETRY(self), coord_seq, i, &z)) {
123
+ if (!GEOSCoordSeq_getZ_r(self_context, coord_seq, i, &z)) {
120
124
  z = 0.0;
121
125
  }
122
126
  }
123
127
  else {
124
128
  z = 0.0;
125
129
  }
126
- result = rgeo_create_geos_point(RGEO_FACTORY_FROM_GEOMETRY(self), x, y, z);
130
+ result = rgeo_create_geos_point(self_data->factory, x, y, z);
127
131
  }
128
132
  }
129
133
  return result;
@@ -133,16 +137,18 @@ static VALUE get_point_from_coordseq(VALUE self, const GEOSCoordSequence* coord_
133
137
  static VALUE method_line_string_point_n(VALUE self, VALUE n)
134
138
  {
135
139
  VALUE result = Qnil;
136
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
140
+ RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
141
+ const GEOSGeometry* self_geom = self_data->geom;
137
142
  if (self_geom) {
138
- const GEOSCoordSequence* coord_seq = GEOSGeom_getCoordSeq_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom);
143
+ GEOSContextHandle_t self_context = self_data->geos_context;
144
+ const GEOSCoordSequence* coord_seq = GEOSGeom_getCoordSeq_r(self_context, self_geom);
139
145
  if (coord_seq) {
140
- char has_z = (char)(RGEO_FACTORY_DATA_FROM_GEOMETRY(self)->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M);
146
+ char has_z = (char)(RGEO_FACTORY_DATA_PTR(self_data->factory)->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M);
141
147
  int si = NUM2INT(n);
142
148
  if (si >= 0) {
143
149
  unsigned int i = si;
144
150
  unsigned int size;
145
- if (GEOSCoordSeq_getSize_r(RGEO_CONTEXT_FROM_GEOMETRY(self), coord_seq, &size)) {
151
+ if (GEOSCoordSeq_getSize_r(self_context, coord_seq, &size)) {
146
152
  if (i < size) {
147
153
  unsigned int dims;
148
154
  result = get_point_from_coordseq(self, coord_seq, i, has_z);
@@ -158,13 +164,15 @@ static VALUE method_line_string_point_n(VALUE self, VALUE n)
158
164
  static VALUE method_line_string_points(VALUE self)
159
165
  {
160
166
  VALUE result = Qnil;
161
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
167
+ RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
168
+ const GEOSGeometry* self_geom = self_data->geom;
162
169
  if (self_geom) {
163
- const GEOSCoordSequence* coord_seq = GEOSGeom_getCoordSeq_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom);
170
+ GEOSContextHandle_t self_context = self_data->geos_context;
171
+ const GEOSCoordSequence* coord_seq = GEOSGeom_getCoordSeq_r(self_context, self_geom);
164
172
  if (coord_seq) {
165
- char has_z = (char)(RGEO_FACTORY_DATA_FROM_GEOMETRY(self)->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M);
173
+ char has_z = (char)(RGEO_FACTORY_DATA_PTR(self_data->factory)->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M);
166
174
  unsigned int size;
167
- if (GEOSCoordSeq_getSize_r(RGEO_CONTEXT_FROM_GEOMETRY(self), coord_seq, &size)) {
175
+ if (GEOSCoordSeq_getSize_r(self_context, coord_seq, &size)) {
168
176
  result = rb_ary_new2(size);
169
177
  double x, y, z;
170
178
  unsigned int i;
@@ -190,9 +198,10 @@ static VALUE method_line_string_start_point(VALUE self)
190
198
  static VALUE method_line_string_end_point(VALUE self)
191
199
  {
192
200
  VALUE result = Qnil;
193
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
201
+ RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
202
+ const GEOSGeometry* self_geom = self_data->geom;
194
203
  if (self_geom) {
195
- unsigned int n = GEOSGetNumCoordinates_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom);
204
+ unsigned int n = GEOSGetNumCoordinates_r(self_data->geos_context, self_geom);
196
205
  if (n > 0) {
197
206
  result = method_line_string_point_n(self, INT2NUM(n-1));
198
207
  }
@@ -204,9 +213,10 @@ static VALUE method_line_string_end_point(VALUE self)
204
213
  static VALUE method_line_string_is_closed(VALUE self)
205
214
  {
206
215
  VALUE result = Qnil;
207
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
216
+ RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
217
+ const GEOSGeometry* self_geom = self_data->geom;
208
218
  if (self_geom) {
209
- result = rgeo_is_geos_line_string_closed(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom);
219
+ result = rgeo_is_geos_line_string_closed(self_data->geos_context, self_geom);
210
220
  }
211
221
  return result;
212
222
  }
@@ -215,9 +225,10 @@ static VALUE method_line_string_is_closed(VALUE self)
215
225
  static VALUE method_line_string_is_ring(VALUE self)
216
226
  {
217
227
  VALUE result = Qnil;
218
- const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
228
+ RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
229
+ const GEOSGeometry* self_geom = self_data->geom;
219
230
  if (self_geom) {
220
- char val = GEOSisRing_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom);
231
+ char val = GEOSisRing_r(self_data->geos_context, self_geom);
221
232
  if (val == 0) {
222
233
  result = Qfalse;
223
234
  }
@@ -233,7 +244,8 @@ static VALUE method_line_string_eql(VALUE self, VALUE rhs)
233
244
  {
234
245
  VALUE result = rgeo_geos_klasses_and_factories_eql(self, rhs);
235
246
  if (RTEST(result)) {
236
- result = rgeo_geos_coordseqs_eql(RGEO_CONTEXT_FROM_GEOMETRY(self), RGEO_GET_GEOS_GEOMETRY(self), RGEO_GET_GEOS_GEOMETRY(rhs), RGEO_FACTORY_DATA_FROM_GEOMETRY(self)->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M);
247
+ RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
248
+ result = rgeo_geos_coordseqs_eql(self_data->geos_context, self_data->geom, RGEO_GEOMETRY_DATA_PTR(rhs)->geom, RGEO_FACTORY_DATA_PTR(self_data->factory)->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M);
237
249
  }
238
250
  return result;
239
251
  }
@@ -242,7 +254,8 @@ static VALUE method_line_string_eql(VALUE self, VALUE rhs)
242
254
  static GEOSCoordSequence* coord_seq_from_array(VALUE factory, VALUE array, char close)
243
255
  {
244
256
  Check_Type(array, T_ARRAY);
245
- VALUE point_type = rb_const_get_at(RGEO_GLOBALS_FROM_FACTORY(factory)->features_module, rb_intern("Point"));
257
+ RGeo_FactoryData* factory_data = RGEO_FACTORY_DATA_PTR(factory);
258
+ VALUE point_type = factory_data->globals->feature_point;
246
259
  unsigned int len = (unsigned int)RARRAY_LEN(array);
247
260
  char has_z = (char)(RGEO_FACTORY_DATA_PTR(factory)->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M);
248
261
  unsigned int dims = has_z ? 3 : 2;
@@ -250,7 +263,7 @@ static GEOSCoordSequence* coord_seq_from_array(VALUE factory, VALUE array, char
250
263
  if (!coords) {
251
264
  return NULL;
252
265
  }
253
- GEOSContextHandle_t context = RGEO_CONTEXT_FROM_FACTORY(factory);
266
+ GEOSContextHandle_t context = factory_data->geos_context;
254
267
  unsigned int i;
255
268
  for (i=0; i<len; ++i) {
256
269
  char good = 0;
@@ -312,9 +325,10 @@ static VALUE cmethod_create_line_string(VALUE module, VALUE factory, VALUE array
312
325
  VALUE result = Qnil;
313
326
  GEOSCoordSequence* coord_seq = coord_seq_from_array(factory, array, 0);
314
327
  if (coord_seq) {
315
- GEOSGeometry* geom = GEOSGeom_createLineString_r(RGEO_CONTEXT_FROM_FACTORY(factory), coord_seq);
328
+ RGeo_FactoryData* factory_data = RGEO_FACTORY_DATA_PTR(factory);
329
+ GEOSGeometry* geom = GEOSGeom_createLineString_r(factory_data->geos_context, coord_seq);
316
330
  if (geom) {
317
- result = rgeo_wrap_geos_geometry(factory, geom, rb_const_get_at(RGEO_GLOBALS_FROM_FACTORY(factory)->geos_module, rb_intern("LineStringImpl")));
331
+ result = rgeo_wrap_geos_geometry(factory, geom, factory_data->globals->geos_line_string);
318
332
  }
319
333
  }
320
334
  return result;
@@ -326,9 +340,10 @@ static VALUE cmethod_create_linear_ring(VALUE module, VALUE factory, VALUE array
326
340
  VALUE result = Qnil;
327
341
  GEOSCoordSequence* coord_seq = coord_seq_from_array(factory, array, 1);
328
342
  if (coord_seq) {
329
- GEOSGeometry* geom = GEOSGeom_createLinearRing_r(RGEO_CONTEXT_FROM_FACTORY(factory), coord_seq);
343
+ RGeo_FactoryData* factory_data = RGEO_FACTORY_DATA_PTR(factory);
344
+ GEOSGeometry* geom = GEOSGeom_createLinearRing_r(factory_data->geos_context, coord_seq);
330
345
  if (geom) {
331
- result = rgeo_wrap_geos_geometry(factory, geom, rb_const_get_at(RGEO_GLOBALS_FROM_FACTORY(factory)->geos_module, rb_intern("LinearRingImpl")));
346
+ result = rgeo_wrap_geos_geometry(factory, geom, factory_data->globals->geos_linear_ring);
332
347
  }
333
348
  }
334
349
  return result;
@@ -359,9 +374,10 @@ static void populate_geom_into_coord_seq(GEOSContextHandle_t context, const GEOS
359
374
  static VALUE cmethod_create_line(VALUE module, VALUE factory, VALUE start, VALUE end)
360
375
  {
361
376
  VALUE result = Qnil;
362
- char has_z = (char)(RGEO_FACTORY_DATA_PTR(factory)->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M);
363
- VALUE point_type = rb_const_get_at(RGEO_GLOBALS_FROM_FACTORY(factory)->features_module, rb_intern("Point"));
364
- GEOSContextHandle_t context = RGEO_CONTEXT_FROM_FACTORY(factory);
377
+ RGeo_FactoryData* factory_data = RGEO_FACTORY_DATA_PTR(factory);
378
+ char has_z = (char)(factory_data->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M);
379
+ VALUE point_type = factory_data->globals->feature_point;
380
+ GEOSContextHandle_t context = factory_data->geos_context;
365
381
 
366
382
  const GEOSGeometry* start_geom = rgeo_convert_to_geos_geometry(factory, start, point_type);
367
383
  if (start_geom) {
@@ -373,7 +389,7 @@ static VALUE cmethod_create_line(VALUE module, VALUE factory, VALUE start, VALUE
373
389
  populate_geom_into_coord_seq(context, end_geom, coord_seq, 1, has_z);
374
390
  GEOSGeometry* geom = GEOSGeom_createLineString_r(context, coord_seq);
375
391
  if (geom) {
376
- result = rgeo_wrap_geos_geometry(factory, geom, rb_const_get_at(RGEO_GLOBALS_FROM_FACTORY(factory)->geos_module, rb_intern("LineImpl")));
392
+ result = rgeo_wrap_geos_geometry(factory, geom, factory_data->globals->geos_line);
377
393
  }
378
394
  }
379
395
  }
@@ -386,18 +402,21 @@ static VALUE cmethod_create_line(VALUE module, VALUE factory, VALUE start, VALUE
386
402
  static VALUE impl_copy_from(VALUE klass, VALUE factory, VALUE original, char subtype)
387
403
  {
388
404
  VALUE result = Qnil;
389
- const GEOSGeometry* original_geom = RGEO_GET_GEOS_GEOMETRY(original);
390
- if (original_geom && subtype == 1 && GEOSGetNumCoordinates_r(RGEO_CONTEXT_FROM_FACTORY(factory), original_geom) != 2) {
391
- original_geom = NULL;
392
- }
405
+ const GEOSGeometry* original_geom = RGEO_GEOMETRY_DATA_PTR(original)->geom;
393
406
  if (original_geom) {
394
- const GEOSCoordSequence* original_coord_seq = GEOSGeom_getCoordSeq_r(RGEO_CONTEXT_FROM_FACTORY(factory), original_geom);
395
- if (original_coord_seq) {
396
- GEOSCoordSequence* coord_seq = GEOSCoordSeq_clone_r(RGEO_CONTEXT_FROM_FACTORY(factory), original_coord_seq);
397
- if (coord_seq) {
398
- GEOSGeometry* geom = subtype == 2 ? GEOSGeom_createLinearRing_r(RGEO_CONTEXT_FROM_FACTORY(factory), coord_seq) : GEOSGeom_createLineString_r(RGEO_CONTEXT_FROM_FACTORY(factory), coord_seq);
399
- if (geom) {
400
- result = rgeo_wrap_geos_geometry(factory, geom, klass);
407
+ GEOSContextHandle_t context = RGEO_FACTORY_DATA_PTR(factory)->geos_context;
408
+ if (subtype == 1 && GEOSGetNumCoordinates_r(context, original_geom) != 2) {
409
+ original_geom = NULL;
410
+ }
411
+ if (original_geom) {
412
+ const GEOSCoordSequence* original_coord_seq = GEOSGeom_getCoordSeq_r(context, original_geom);
413
+ if (original_coord_seq) {
414
+ GEOSCoordSequence* coord_seq = GEOSCoordSeq_clone_r(context, original_coord_seq);
415
+ if (coord_seq) {
416
+ GEOSGeometry* geom = subtype == 2 ? GEOSGeom_createLinearRing_r(context, coord_seq) : GEOSGeom_createLineString_r(context, coord_seq);
417
+ if (geom) {
418
+ result = rgeo_wrap_geos_geometry(factory, geom, klass);
419
+ }
401
420
  }
402
421
  }
403
422
  }
@@ -426,9 +445,15 @@ static VALUE cmethod_linear_ring_copy_from(VALUE klass, VALUE factory, VALUE ori
426
445
 
427
446
  void rgeo_init_geos_line_string(RGeo_Globals* globals)
428
447
  {
429
- VALUE geos_line_string_class = rb_define_class_under(globals->geos_module, "LineStringImpl", rb_const_get_at(globals->geos_module, rb_intern("GeometryImpl")));
448
+ VALUE geos_line_string_class = rb_define_class_under(globals->geos_module, "LineStringImpl", globals->geos_geometry);
449
+ globals->geos_line_string = geos_line_string_class;
450
+ globals->feature_line_string = rb_const_get_at(globals->feature_module, rb_intern("LineString"));
430
451
  VALUE geos_linear_ring_class = rb_define_class_under(globals->geos_module, "LinearRingImpl", geos_line_string_class);
452
+ globals->geos_linear_ring = geos_linear_ring_class;
453
+ globals->feature_linear_ring = rb_const_get_at(globals->feature_module, rb_intern("LinearRing"));
431
454
  VALUE geos_line_class = rb_define_class_under(globals->geos_module, "LineImpl", geos_line_string_class);
455
+ globals->geos_line = geos_line_class;
456
+ globals->feature_line = rb_const_get_at(globals->feature_module, rb_intern("Line"));
432
457
 
433
458
  rb_define_module_function(geos_line_string_class, "create", cmethod_create_line_string, 2);
434
459
  rb_define_module_function(geos_line_string_class, "_copy_from", cmethod_line_string_copy_from, 2);