rgeo 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. data/History.rdoc +6 -0
  2. data/README.rdoc +10 -7
  3. data/Version +1 -1
  4. data/ext/geos_c_impl/extconf.rb +42 -34
  5. data/ext/geos_c_impl/factory.c +56 -39
  6. data/ext/geos_c_impl/factory.h +55 -45
  7. data/ext/geos_c_impl/geometry.c +137 -93
  8. data/ext/geos_c_impl/geometry_collection.c +67 -46
  9. data/ext/geos_c_impl/line_string.c +79 -54
  10. data/ext/geos_c_impl/point.c +37 -24
  11. data/ext/geos_c_impl/polygon.c +40 -25
  12. data/ext/proj4_c_impl/extconf.rb +44 -36
  13. data/lib/rgeo/coord_sys.rb +3 -1
  14. data/lib/rgeo/geos.rb +3 -1
  15. data/lib/rgeo/geos/impl_additions.rb +12 -10
  16. data/test/coord_sys/tc_proj4.rb +1 -1
  17. data/test/geos/tc_factory.rb +1 -1
  18. data/test/geos/tc_geometry_collection.rb +1 -1
  19. data/test/geos/tc_line_string.rb +1 -1
  20. data/test/geos/tc_misc.rb +1 -1
  21. data/test/geos/tc_multi_line_string.rb +1 -1
  22. data/test/geos/tc_multi_point.rb +1 -1
  23. data/test/geos/tc_multi_polygon.rb +1 -1
  24. data/test/geos/tc_point.rb +1 -1
  25. data/test/geos/tc_polygon.rb +1 -1
  26. data/test/geos/tc_zmfactory.rb +1 -1
  27. data/test/projected_geographic/tc_geometry_collection.rb +1 -1
  28. data/test/projected_geographic/tc_line_string.rb +1 -1
  29. data/test/projected_geographic/tc_multi_line_string.rb +1 -1
  30. data/test/projected_geographic/tc_multi_point.rb +1 -1
  31. data/test/projected_geographic/tc_multi_polygon.rb +1 -1
  32. data/test/projected_geographic/tc_point.rb +1 -1
  33. data/test/projected_geographic/tc_polygon.rb +1 -1
  34. data/test/simple_cartesian/tc_calculations.rb +1 -1
  35. data/test/tc_oneoff.rb +5 -5
  36. data/test/wkrep/tc_wkt_parser.rb +4 -4
  37. metadata +3 -3
@@ -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);