rgeo 0.3.2 → 0.3.3
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.
- data/History.rdoc +8 -0
- data/Version +1 -1
- data/ext/geos_c_impl/extconf.rb +2 -2
- data/ext/geos_c_impl/factory.c +93 -42
- data/ext/geos_c_impl/geometry.c +327 -146
- data/ext/geos_c_impl/geometry_collection.c +157 -75
- data/ext/geos_c_impl/line_string.c +200 -93
- data/ext/geos_c_impl/main.c +3 -1
- data/ext/geos_c_impl/point.c +60 -28
- data/ext/geos_c_impl/polygon.c +108 -50
- data/ext/proj4_c_impl/extconf.rb +2 -2
- data/ext/proj4_c_impl/main.c +68 -30
- data/lib/rgeo/cartesian/bounding_box.rb +1 -1
- data/lib/rgeo/feature/factory.rb +7 -6
- data/lib/rgeo/feature/geometry.rb +4 -3
- data/lib/rgeo/geographic/projected_feature_methods.rb +1 -1
- data/lib/rgeo/geos/interface.rb +1 -1
- data/lib/rgeo/wkrep/wkt_parser.rb +7 -1
- data/test/wkrep/tc_wkt_parser.rb +13 -0
- metadata +3 -3
@@ -59,17 +59,31 @@ RGEO_BEGIN_C
|
|
59
59
|
|
60
60
|
static VALUE create_geometry_collection(VALUE module, int type, VALUE factory, VALUE array)
|
61
61
|
{
|
62
|
-
VALUE result
|
62
|
+
VALUE result;
|
63
|
+
unsigned int len;
|
64
|
+
GEOSGeometry** geoms;
|
65
|
+
RGeo_FactoryData* factory_data;
|
66
|
+
GEOSContextHandle_t geos_context;
|
67
|
+
VALUE klass;
|
68
|
+
unsigned int i;
|
69
|
+
unsigned int j;
|
70
|
+
VALUE klasses;
|
71
|
+
VALUE cast_type;
|
72
|
+
GEOSGeometry* geom;
|
73
|
+
GEOSGeometry* collection;
|
74
|
+
char problem;
|
75
|
+
GEOSGeometry* igeom;
|
76
|
+
GEOSGeometry* jgeom;
|
77
|
+
|
78
|
+
result = Qnil;
|
63
79
|
Check_Type(array, T_ARRAY);
|
64
|
-
|
65
|
-
|
80
|
+
len = (unsigned int)RARRAY_LEN(array);
|
81
|
+
geoms = ALLOC_N(GEOSGeometry*, len == 0 ? 1 : len);
|
66
82
|
if (geoms) {
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
VALUE klasses = Qnil;
|
72
|
-
VALUE cast_type = Qnil;
|
83
|
+
factory_data = RGEO_FACTORY_DATA_PTR(factory);
|
84
|
+
geos_context = factory_data->geos_context;
|
85
|
+
klasses = Qnil;
|
86
|
+
cast_type = Qnil;
|
73
87
|
switch (type) {
|
74
88
|
case GEOS_MULTIPOINT:
|
75
89
|
cast_type = factory_data->globals->feature_point;
|
@@ -82,7 +96,7 @@ static VALUE create_geometry_collection(VALUE module, int type, VALUE factory, V
|
|
82
96
|
break;
|
83
97
|
}
|
84
98
|
for (i=0; i<len; ++i) {
|
85
|
-
|
99
|
+
geom = rgeo_convert_to_detached_geos_geometry(rb_ary_entry(array, i), factory, cast_type, &klass);
|
86
100
|
if (!geom) {
|
87
101
|
break;
|
88
102
|
}
|
@@ -103,15 +117,15 @@ static VALUE create_geometry_collection(VALUE module, int type, VALUE factory, V
|
|
103
117
|
}
|
104
118
|
}
|
105
119
|
else {
|
106
|
-
|
120
|
+
collection = GEOSGeom_createCollection_r(geos_context, type, geoms, len);
|
107
121
|
// Due to a limitation of GEOS, the MultiPolygon assertions are not checked.
|
108
122
|
// We do that manually here.
|
109
123
|
if (collection && type == GEOS_MULTIPOLYGON && (factory_data->flags & 1) == 0) {
|
110
|
-
|
124
|
+
problem = 0;
|
111
125
|
for (i=1; i<len; ++i) {
|
112
126
|
for (j=0; j<i; ++j) {
|
113
|
-
|
114
|
-
|
127
|
+
igeom = geoms[i];
|
128
|
+
jgeom = geoms[j];
|
115
129
|
problem = GEOSRelatePattern_r(geos_context, igeom, jgeom, "2********");
|
116
130
|
if (problem) {
|
117
131
|
break;
|
@@ -151,9 +165,12 @@ static VALUE create_geometry_collection(VALUE module, int type, VALUE factory, V
|
|
151
165
|
|
152
166
|
static VALUE method_geometry_collection_eql(VALUE self, VALUE rhs)
|
153
167
|
{
|
154
|
-
VALUE result
|
168
|
+
VALUE result;
|
169
|
+
RGeo_GeometryData* self_data;
|
170
|
+
|
171
|
+
result = rgeo_geos_klasses_and_factories_eql(self, rhs);
|
155
172
|
if (RTEST(result)) {
|
156
|
-
|
173
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
157
174
|
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);
|
158
175
|
}
|
159
176
|
return result;
|
@@ -162,8 +179,11 @@ static VALUE method_geometry_collection_eql(VALUE self, VALUE rhs)
|
|
162
179
|
|
163
180
|
static VALUE method_geometry_collection_geometry_type(VALUE self)
|
164
181
|
{
|
165
|
-
VALUE result
|
166
|
-
RGeo_GeometryData* self_data
|
182
|
+
VALUE result;
|
183
|
+
RGeo_GeometryData* self_data;
|
184
|
+
|
185
|
+
result = Qnil;
|
186
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
167
187
|
if (self_data->geom) {
|
168
188
|
result = RGEO_FACTORY_DATA_PTR(self_data->factory)->globals->feature_geometry_collection;
|
169
189
|
}
|
@@ -173,9 +193,13 @@ static VALUE method_geometry_collection_geometry_type(VALUE self)
|
|
173
193
|
|
174
194
|
static VALUE method_geometry_collection_num_geometries(VALUE self)
|
175
195
|
{
|
176
|
-
VALUE result
|
177
|
-
RGeo_GeometryData* self_data
|
178
|
-
const GEOSGeometry* self_geom
|
196
|
+
VALUE result;
|
197
|
+
RGeo_GeometryData* self_data;
|
198
|
+
const GEOSGeometry* self_geom;
|
199
|
+
|
200
|
+
result = Qnil;
|
201
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
202
|
+
self_geom = self_data->geom;
|
179
203
|
if (self_geom) {
|
180
204
|
result = INT2NUM(GEOSGetNumGeometries_r(self_data->geos_context, self_geom));
|
181
205
|
}
|
@@ -185,15 +209,22 @@ static VALUE method_geometry_collection_num_geometries(VALUE self)
|
|
185
209
|
|
186
210
|
static VALUE impl_geometry_n(VALUE self, VALUE n, char allow_negatives)
|
187
211
|
{
|
188
|
-
VALUE result
|
189
|
-
RGeo_GeometryData* self_data
|
190
|
-
const GEOSGeometry* self_geom
|
212
|
+
VALUE result;
|
213
|
+
RGeo_GeometryData* self_data;
|
214
|
+
const GEOSGeometry* self_geom;
|
215
|
+
VALUE klasses;
|
216
|
+
int i;
|
217
|
+
int len;
|
218
|
+
|
219
|
+
result = Qnil;
|
220
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
221
|
+
self_geom = self_data->geom;
|
191
222
|
if (self_geom) {
|
192
|
-
|
193
|
-
|
223
|
+
klasses = self_data->klasses;
|
224
|
+
i = NUM2INT(n);
|
194
225
|
if (allow_negatives || i >= 0) {
|
195
226
|
GEOSContextHandle_t self_context = self_data->geos_context;
|
196
|
-
|
227
|
+
len = GEOSGetNumGeometries_r(self_context, self_geom);
|
197
228
|
if (i < 0) {
|
198
229
|
i += len;
|
199
230
|
}
|
@@ -210,29 +241,35 @@ static VALUE impl_geometry_n(VALUE self, VALUE n, char allow_negatives)
|
|
210
241
|
|
211
242
|
static VALUE method_geometry_collection_geometry_n(VALUE self, VALUE n)
|
212
243
|
{
|
213
|
-
impl_geometry_n(self, n, 0);
|
244
|
+
return impl_geometry_n(self, n, 0);
|
214
245
|
}
|
215
246
|
|
216
247
|
|
217
248
|
static VALUE method_geometry_collection_brackets(VALUE self, VALUE n)
|
218
249
|
{
|
219
|
-
impl_geometry_n(self, n, 1);
|
250
|
+
return impl_geometry_n(self, n, 1);
|
220
251
|
}
|
221
252
|
|
222
253
|
|
223
254
|
static VALUE method_geometry_collection_each(VALUE self)
|
224
255
|
{
|
225
|
-
RGeo_GeometryData* self_data
|
226
|
-
const GEOSGeometry* self_geom
|
256
|
+
RGeo_GeometryData* self_data;
|
257
|
+
const GEOSGeometry* self_geom;
|
258
|
+
int len;
|
259
|
+
VALUE klasses;
|
260
|
+
int i;
|
261
|
+
VALUE elem;
|
262
|
+
const GEOSGeometry* elem_geom;
|
263
|
+
|
264
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
265
|
+
self_geom = self_data->geom;
|
227
266
|
if (self_geom) {
|
228
267
|
GEOSContextHandle_t self_context = self_data->geos_context;
|
229
|
-
|
268
|
+
len = GEOSGetNumGeometries_r(self_context, self_geom);
|
230
269
|
if (len > 0) {
|
231
|
-
|
232
|
-
int i;
|
270
|
+
klasses = self_data->klasses;
|
233
271
|
for (i=0; i<len; ++i) {
|
234
|
-
|
235
|
-
const GEOSGeometry* elem_geom = GEOSGetGeometryN_r(self_context, self_geom, i);
|
272
|
+
elem_geom = GEOSGetGeometryN_r(self_context, self_geom, i);
|
236
273
|
elem = rgeo_wrap_geos_geometry_clone(self_data->factory, elem_geom, NIL_P(klasses) ? Qnil : rb_ary_entry(klasses, i));
|
237
274
|
if (!NIL_P(elem)) {
|
238
275
|
rb_yield(elem);
|
@@ -246,8 +283,11 @@ static VALUE method_geometry_collection_each(VALUE self)
|
|
246
283
|
|
247
284
|
static VALUE method_multi_point_geometry_type(VALUE self)
|
248
285
|
{
|
249
|
-
VALUE result
|
250
|
-
RGeo_GeometryData* self_data
|
286
|
+
VALUE result;
|
287
|
+
RGeo_GeometryData* self_data;
|
288
|
+
|
289
|
+
result = Qnil;
|
290
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
251
291
|
if (self_data->geom) {
|
252
292
|
result = RGEO_FACTORY_DATA_PTR(self_data->factory)->globals->feature_multi_point;
|
253
293
|
}
|
@@ -257,8 +297,11 @@ static VALUE method_multi_point_geometry_type(VALUE self)
|
|
257
297
|
|
258
298
|
static VALUE method_multi_line_string_geometry_type(VALUE self)
|
259
299
|
{
|
260
|
-
VALUE result
|
261
|
-
RGeo_GeometryData* self_data
|
300
|
+
VALUE result;
|
301
|
+
RGeo_GeometryData* self_data;
|
302
|
+
|
303
|
+
result = Qnil;
|
304
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
262
305
|
if (self_data->geom) {
|
263
306
|
result = RGEO_FACTORY_DATA_PTR(self_data->factory)->globals->feature_multi_line_string;
|
264
307
|
}
|
@@ -268,11 +311,15 @@ static VALUE method_multi_line_string_geometry_type(VALUE self)
|
|
268
311
|
|
269
312
|
static VALUE method_multi_line_string_length(VALUE self)
|
270
313
|
{
|
271
|
-
VALUE result
|
272
|
-
RGeo_GeometryData* self_data
|
273
|
-
const GEOSGeometry* self_geom
|
314
|
+
VALUE result;
|
315
|
+
RGeo_GeometryData* self_data;
|
316
|
+
const GEOSGeometry* self_geom;
|
317
|
+
double len;
|
318
|
+
|
319
|
+
result = Qnil;
|
320
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
321
|
+
self_geom = self_data->geom;
|
274
322
|
if (self_geom) {
|
275
|
-
double len;
|
276
323
|
if (GEOSLength_r(self_data->geos_context, self_geom, &len)) {
|
277
324
|
result = rb_float_new(len);
|
278
325
|
}
|
@@ -283,17 +330,24 @@ static VALUE method_multi_line_string_length(VALUE self)
|
|
283
330
|
|
284
331
|
static VALUE method_multi_line_string_is_closed(VALUE self)
|
285
332
|
{
|
286
|
-
VALUE result
|
287
|
-
RGeo_GeometryData* self_data
|
288
|
-
const GEOSGeometry* self_geom
|
333
|
+
VALUE result;
|
334
|
+
RGeo_GeometryData* self_data;
|
335
|
+
const GEOSGeometry* self_geom;
|
336
|
+
GEOSContextHandle_t self_context;
|
337
|
+
int len;
|
338
|
+
int i;
|
339
|
+
const GEOSGeometry* geom;
|
340
|
+
|
341
|
+
result = Qnil;
|
342
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
343
|
+
self_geom = self_data->geom;
|
289
344
|
if (self_geom) {
|
290
|
-
|
345
|
+
self_context = self_data->geos_context;
|
291
346
|
result = Qtrue;
|
292
|
-
|
347
|
+
len = GEOSGetNumGeometries_r(self_context, self_geom);
|
293
348
|
if (len > 0) {
|
294
|
-
int i;
|
295
349
|
for (i=0; i<len; ++i) {
|
296
|
-
|
350
|
+
geom = GEOSGetGeometryN_r(self_context, self_geom, i);
|
297
351
|
if (geom) {
|
298
352
|
result = rgeo_is_geos_line_string_closed(self_context, self_geom);
|
299
353
|
if (result != Qtrue) {
|
@@ -309,8 +363,11 @@ static VALUE method_multi_line_string_is_closed(VALUE self)
|
|
309
363
|
|
310
364
|
static VALUE method_multi_polygon_geometry_type(VALUE self)
|
311
365
|
{
|
312
|
-
VALUE result
|
313
|
-
RGeo_GeometryData* self_data
|
366
|
+
VALUE result;
|
367
|
+
RGeo_GeometryData* self_data;
|
368
|
+
|
369
|
+
result = Qnil;
|
370
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
314
371
|
if (self_data->geom) {
|
315
372
|
result = RGEO_FACTORY_DATA_PTR(self_data->factory)->globals->feature_multi_polygon;
|
316
373
|
}
|
@@ -320,11 +377,15 @@ static VALUE method_multi_polygon_geometry_type(VALUE self)
|
|
320
377
|
|
321
378
|
static VALUE method_multi_polygon_area(VALUE self)
|
322
379
|
{
|
323
|
-
VALUE result
|
324
|
-
RGeo_GeometryData* self_data
|
325
|
-
const GEOSGeometry* self_geom
|
380
|
+
VALUE result;
|
381
|
+
RGeo_GeometryData* self_data;
|
382
|
+
const GEOSGeometry* self_geom;
|
383
|
+
double area;
|
384
|
+
|
385
|
+
result = Qnil;
|
386
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
387
|
+
self_geom = self_data->geom;
|
326
388
|
if (self_geom) {
|
327
|
-
double area;
|
328
389
|
if (GEOSArea_r(self_data->geos_context, self_geom, &area)) {
|
329
390
|
result = rb_float_new(area);
|
330
391
|
}
|
@@ -335,9 +396,13 @@ static VALUE method_multi_polygon_area(VALUE self)
|
|
335
396
|
|
336
397
|
static VALUE method_multi_polygon_centroid(VALUE self)
|
337
398
|
{
|
338
|
-
VALUE result
|
339
|
-
RGeo_GeometryData* self_data
|
340
|
-
const GEOSGeometry* self_geom
|
399
|
+
VALUE result;
|
400
|
+
RGeo_GeometryData* self_data;
|
401
|
+
const GEOSGeometry* self_geom;
|
402
|
+
|
403
|
+
result = Qnil;
|
404
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
405
|
+
self_geom = self_data->geom;
|
341
406
|
if (self_geom) {
|
342
407
|
result = rgeo_wrap_geos_geometry(self_data->factory, GEOSGetCentroid_r(self_data->geos_context, self_geom), Qnil);
|
343
408
|
}
|
@@ -347,9 +412,13 @@ static VALUE method_multi_polygon_centroid(VALUE self)
|
|
347
412
|
|
348
413
|
static VALUE method_multi_polygon_point_on_surface(VALUE self)
|
349
414
|
{
|
350
|
-
VALUE result
|
351
|
-
RGeo_GeometryData* self_data
|
352
|
-
const GEOSGeometry* self_geom
|
415
|
+
VALUE result;
|
416
|
+
RGeo_GeometryData* self_data;
|
417
|
+
const GEOSGeometry* self_geom;
|
418
|
+
|
419
|
+
result = Qnil;
|
420
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
421
|
+
self_geom = self_data->geom;
|
353
422
|
if (self_geom) {
|
354
423
|
result = rgeo_wrap_geos_geometry(self_data->factory, GEOSPointOnSurface_r(self_data->geos_context, self_geom), Qnil);
|
355
424
|
}
|
@@ -386,20 +455,25 @@ static VALUE cmethod_multi_polygon_create(VALUE module, VALUE factory, VALUE arr
|
|
386
455
|
|
387
456
|
void rgeo_init_geos_geometry_collection(RGeo_Globals* globals)
|
388
457
|
{
|
458
|
+
VALUE geos_geometry_collection_class;
|
459
|
+
VALUE geos_multi_point_class;
|
460
|
+
VALUE geos_multi_line_string_class;
|
461
|
+
VALUE geos_multi_polygon_class;
|
462
|
+
|
389
463
|
// Create implementation classes
|
390
|
-
|
464
|
+
geos_geometry_collection_class = rb_define_class_under(globals->geos_module, "GeometryCollectionImpl", globals->geos_geometry);
|
391
465
|
globals->geos_geometry_collection = geos_geometry_collection_class;
|
392
466
|
globals->feature_geometry_collection = rb_const_get_at(globals->feature_module, rb_intern("GeometryCollection"));
|
393
467
|
rb_funcall(globals->global_mixins, rb_intern("include_in_class"), 2,
|
394
468
|
globals->feature_geometry_collection, geos_geometry_collection_class);
|
395
469
|
|
396
|
-
|
470
|
+
geos_multi_point_class = rb_define_class_under(globals->geos_module, "MultiPointImpl", geos_geometry_collection_class);
|
397
471
|
globals->geos_multi_point = geos_multi_point_class;
|
398
472
|
globals->feature_multi_point = rb_const_get_at(globals->feature_module, rb_intern("MultiPoint"));
|
399
473
|
rb_funcall(globals->global_mixins, rb_intern("include_in_class"), 2,
|
400
474
|
globals->feature_multi_point, geos_multi_point_class);
|
401
475
|
|
402
|
-
|
476
|
+
geos_multi_line_string_class = rb_define_class_under(globals->geos_module, "MultiLineStringImpl", geos_geometry_collection_class);
|
403
477
|
globals->geos_multi_line_string = geos_multi_line_string_class;
|
404
478
|
globals->feature_multi_line_string = rb_const_get_at(globals->feature_module, rb_intern("MultiLineString"));
|
405
479
|
rb_funcall(globals->global_mixins, rb_intern("include_in_class"), 2,
|
@@ -407,7 +481,7 @@ void rgeo_init_geos_geometry_collection(RGeo_Globals* globals)
|
|
407
481
|
rb_funcall(globals->global_mixins, rb_intern("include_in_class"), 2,
|
408
482
|
globals->feature_multi_line_string, geos_multi_line_string_class);
|
409
483
|
|
410
|
-
|
484
|
+
geos_multi_polygon_class = rb_define_class_under(globals->geos_module, "MultiPolygonImpl", geos_geometry_collection_class);
|
411
485
|
globals->geos_multi_polygon = geos_multi_polygon_class;
|
412
486
|
globals->feature_multi_polygon = rb_const_get_at(globals->feature_module, rb_intern("MultiPolygon"));
|
413
487
|
rb_funcall(globals->global_mixins, rb_intern("include_in_class"), 2,
|
@@ -450,20 +524,28 @@ void rgeo_init_geos_geometry_collection(RGeo_Globals* globals)
|
|
450
524
|
|
451
525
|
VALUE rgeo_geos_geometry_collections_eql(GEOSContextHandle_t context, const GEOSGeometry* geom1, const GEOSGeometry* geom2, char check_z)
|
452
526
|
{
|
453
|
-
VALUE result
|
527
|
+
VALUE result;
|
528
|
+
int len1;
|
529
|
+
int len2;
|
530
|
+
int i;
|
531
|
+
const GEOSGeometry* sub_geom1;
|
532
|
+
const GEOSGeometry* sub_geom2;
|
533
|
+
int type1;
|
534
|
+
int type2;
|
535
|
+
|
536
|
+
result = Qnil;
|
454
537
|
if (geom1 && geom2) {
|
455
|
-
|
456
|
-
|
538
|
+
len1 = GEOSGetNumGeometries_r(context, geom1);
|
539
|
+
len2 = GEOSGetNumGeometries_r(context, geom2);
|
457
540
|
if (len1 >= 0 && len2 >= 0) {
|
458
541
|
if (len1 == len2) {
|
459
542
|
result = Qtrue;
|
460
|
-
int i;
|
461
543
|
for (i=0; i<len1; ++i) {
|
462
|
-
|
463
|
-
|
544
|
+
sub_geom1 = GEOSGetGeometryN_r(context, geom1, i);
|
545
|
+
sub_geom2 = GEOSGetGeometryN_r(context, geom2, i);
|
464
546
|
if (sub_geom1 && sub_geom2) {
|
465
|
-
|
466
|
-
|
547
|
+
type1 = GEOSGeomTypeId_r(context, sub_geom1);
|
548
|
+
type2 = GEOSGeomTypeId_r(context, sub_geom2);
|
467
549
|
if (type1 >= 0 && type2 >= 0) {
|
468
550
|
if (type1 == type2) {
|
469
551
|
switch (type1) {
|
@@ -53,8 +53,11 @@ RGEO_BEGIN_C
|
|
53
53
|
|
54
54
|
static VALUE method_line_string_geometry_type(VALUE self)
|
55
55
|
{
|
56
|
-
VALUE result
|
57
|
-
RGeo_GeometryData* self_data
|
56
|
+
VALUE result;
|
57
|
+
RGeo_GeometryData* self_data;
|
58
|
+
|
59
|
+
result = Qnil;
|
60
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
58
61
|
if (self_data->geom) {
|
59
62
|
result = RGEO_FACTORY_DATA_PTR(self_data->factory)->globals->feature_line_string;
|
60
63
|
}
|
@@ -64,8 +67,11 @@ static VALUE method_line_string_geometry_type(VALUE self)
|
|
64
67
|
|
65
68
|
static VALUE method_linear_ring_geometry_type(VALUE self)
|
66
69
|
{
|
67
|
-
VALUE result
|
68
|
-
RGeo_GeometryData* self_data
|
70
|
+
VALUE result;
|
71
|
+
RGeo_GeometryData* self_data;
|
72
|
+
|
73
|
+
result = Qnil;
|
74
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
69
75
|
if (self_data->geom) {
|
70
76
|
result = RGEO_FACTORY_DATA_PTR(self_data->factory)->globals->feature_linear_ring;
|
71
77
|
}
|
@@ -75,8 +81,11 @@ static VALUE method_linear_ring_geometry_type(VALUE self)
|
|
75
81
|
|
76
82
|
static VALUE method_line_geometry_type(VALUE self)
|
77
83
|
{
|
78
|
-
VALUE result
|
79
|
-
RGeo_GeometryData* self_data
|
84
|
+
VALUE result;
|
85
|
+
RGeo_GeometryData* self_data;
|
86
|
+
|
87
|
+
result = Qnil;
|
88
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
80
89
|
if (self_data->geom) {
|
81
90
|
result = RGEO_FACTORY_DATA_PTR(self_data->factory)->globals->feature_line;
|
82
91
|
}
|
@@ -86,11 +95,15 @@ static VALUE method_line_geometry_type(VALUE self)
|
|
86
95
|
|
87
96
|
static VALUE method_line_string_length(VALUE self)
|
88
97
|
{
|
89
|
-
VALUE result
|
90
|
-
RGeo_GeometryData* self_data
|
91
|
-
const GEOSGeometry* self_geom
|
98
|
+
VALUE result;
|
99
|
+
RGeo_GeometryData* self_data;
|
100
|
+
const GEOSGeometry* self_geom;
|
101
|
+
double len;
|
102
|
+
|
103
|
+
result = Qnil;
|
104
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
105
|
+
self_geom = self_data->geom;
|
92
106
|
if (self_geom) {
|
93
|
-
double len;
|
94
107
|
if (GEOSLength_r(self_data->geos_context, self_geom, &len)) {
|
95
108
|
result = rb_float_new(len);
|
96
109
|
}
|
@@ -101,9 +114,13 @@ static VALUE method_line_string_length(VALUE self)
|
|
101
114
|
|
102
115
|
static VALUE method_line_string_num_points(VALUE self)
|
103
116
|
{
|
104
|
-
VALUE result
|
105
|
-
RGeo_GeometryData* self_data
|
106
|
-
const GEOSGeometry* self_geom
|
117
|
+
VALUE result;
|
118
|
+
RGeo_GeometryData* self_data;
|
119
|
+
const GEOSGeometry* self_geom;
|
120
|
+
|
121
|
+
result = Qnil;
|
122
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
123
|
+
self_geom = self_data->geom;
|
107
124
|
if (self_geom) {
|
108
125
|
result = INT2NUM(GEOSGetNumCoordinates_r(self_data->geos_context, self_geom));
|
109
126
|
}
|
@@ -113,10 +130,14 @@ static VALUE method_line_string_num_points(VALUE self)
|
|
113
130
|
|
114
131
|
static VALUE get_point_from_coordseq(VALUE self, const GEOSCoordSequence* coord_seq, unsigned int i, char has_z)
|
115
132
|
{
|
116
|
-
VALUE result
|
133
|
+
VALUE result;
|
134
|
+
RGeo_GeometryData* self_data;
|
135
|
+
GEOSContextHandle_t self_context;
|
117
136
|
double x, y, z;
|
118
|
-
|
119
|
-
|
137
|
+
|
138
|
+
result = Qnil;
|
139
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
140
|
+
self_context = self_data->geos_context;
|
120
141
|
if (GEOSCoordSeq_getX_r(self_context, coord_seq, i, &x)) {
|
121
142
|
if (GEOSCoordSeq_getY_r(self_context, coord_seq, i, &y)) {
|
122
143
|
if (has_z) {
|
@@ -136,18 +157,27 @@ static VALUE get_point_from_coordseq(VALUE self, const GEOSCoordSequence* coord_
|
|
136
157
|
|
137
158
|
static VALUE method_line_string_point_n(VALUE self, VALUE n)
|
138
159
|
{
|
139
|
-
VALUE result
|
140
|
-
RGeo_GeometryData* self_data
|
141
|
-
const GEOSGeometry* self_geom
|
160
|
+
VALUE result;
|
161
|
+
RGeo_GeometryData* self_data;
|
162
|
+
const GEOSGeometry* self_geom;
|
163
|
+
GEOSContextHandle_t self_context;
|
164
|
+
const GEOSCoordSequence* coord_seq;
|
165
|
+
char has_z;
|
166
|
+
int si;
|
167
|
+
unsigned int i;
|
168
|
+
unsigned int size;
|
169
|
+
|
170
|
+
result = Qnil;
|
171
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
172
|
+
self_geom = self_data->geom;
|
142
173
|
if (self_geom) {
|
143
|
-
|
144
|
-
|
174
|
+
self_context = self_data->geos_context;
|
175
|
+
coord_seq = GEOSGeom_getCoordSeq_r(self_context, self_geom);
|
145
176
|
if (coord_seq) {
|
146
|
-
|
147
|
-
|
177
|
+
has_z = (char)(RGEO_FACTORY_DATA_PTR(self_data->factory)->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M);
|
178
|
+
si = NUM2INT(n);
|
148
179
|
if (si >= 0) {
|
149
|
-
|
150
|
-
unsigned int size;
|
180
|
+
i = si;
|
151
181
|
if (GEOSCoordSeq_getSize_r(self_context, coord_seq, &size)) {
|
152
182
|
if (i < size) {
|
153
183
|
result = get_point_from_coordseq(self, coord_seq, i, has_z);
|
@@ -162,21 +192,31 @@ static VALUE method_line_string_point_n(VALUE self, VALUE n)
|
|
162
192
|
|
163
193
|
static VALUE method_line_string_points(VALUE self)
|
164
194
|
{
|
165
|
-
VALUE result
|
166
|
-
RGeo_GeometryData* self_data
|
167
|
-
const GEOSGeometry* self_geom
|
195
|
+
VALUE result;
|
196
|
+
RGeo_GeometryData* self_data;
|
197
|
+
const GEOSGeometry* self_geom;
|
198
|
+
GEOSContextHandle_t self_context;
|
199
|
+
const GEOSCoordSequence* coord_seq;
|
200
|
+
char has_z;
|
201
|
+
unsigned int size;
|
202
|
+
double x;
|
203
|
+
double y;
|
204
|
+
double z;
|
205
|
+
unsigned int i;
|
206
|
+
VALUE point;
|
207
|
+
|
208
|
+
result = Qnil;
|
209
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
210
|
+
self_geom = self_data->geom;
|
168
211
|
if (self_geom) {
|
169
|
-
|
170
|
-
|
212
|
+
self_context = self_data->geos_context;
|
213
|
+
coord_seq = GEOSGeom_getCoordSeq_r(self_context, self_geom);
|
171
214
|
if (coord_seq) {
|
172
|
-
|
173
|
-
unsigned int size;
|
215
|
+
has_z = (char)(RGEO_FACTORY_DATA_PTR(self_data->factory)->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M);
|
174
216
|
if (GEOSCoordSeq_getSize_r(self_context, coord_seq, &size)) {
|
175
217
|
result = rb_ary_new2(size);
|
176
|
-
double x, y, z;
|
177
|
-
unsigned int i;
|
178
218
|
for (i=0; i<size; ++i) {
|
179
|
-
|
219
|
+
point = get_point_from_coordseq(self, coord_seq, i, has_z);
|
180
220
|
if (!NIL_P(point)) {
|
181
221
|
rb_ary_store(result, i, point);
|
182
222
|
}
|
@@ -196,11 +236,16 @@ static VALUE method_line_string_start_point(VALUE self)
|
|
196
236
|
|
197
237
|
static VALUE method_line_string_end_point(VALUE self)
|
198
238
|
{
|
199
|
-
VALUE result
|
200
|
-
RGeo_GeometryData* self_data
|
201
|
-
const GEOSGeometry* self_geom
|
239
|
+
VALUE result;
|
240
|
+
RGeo_GeometryData* self_data;
|
241
|
+
const GEOSGeometry* self_geom;
|
242
|
+
unsigned int n;
|
243
|
+
|
244
|
+
result = Qnil;
|
245
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
246
|
+
self_geom = self_data->geom;
|
202
247
|
if (self_geom) {
|
203
|
-
|
248
|
+
n = GEOSGetNumCoordinates_r(self_data->geos_context, self_geom);
|
204
249
|
if (n > 0) {
|
205
250
|
result = method_line_string_point_n(self, INT2NUM(n-1));
|
206
251
|
}
|
@@ -211,9 +256,13 @@ static VALUE method_line_string_end_point(VALUE self)
|
|
211
256
|
|
212
257
|
static VALUE method_line_string_is_closed(VALUE self)
|
213
258
|
{
|
214
|
-
VALUE result
|
215
|
-
RGeo_GeometryData* self_data
|
216
|
-
const GEOSGeometry* self_geom
|
259
|
+
VALUE result;
|
260
|
+
RGeo_GeometryData* self_data;
|
261
|
+
const GEOSGeometry* self_geom;
|
262
|
+
|
263
|
+
result = Qnil;
|
264
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
265
|
+
self_geom = self_data->geom;
|
217
266
|
if (self_geom) {
|
218
267
|
result = rgeo_is_geos_line_string_closed(self_data->geos_context, self_geom);
|
219
268
|
}
|
@@ -223,11 +272,16 @@ static VALUE method_line_string_is_closed(VALUE self)
|
|
223
272
|
|
224
273
|
static VALUE method_line_string_is_ring(VALUE self)
|
225
274
|
{
|
226
|
-
VALUE result
|
227
|
-
RGeo_GeometryData* self_data
|
228
|
-
const GEOSGeometry* self_geom
|
275
|
+
VALUE result;
|
276
|
+
RGeo_GeometryData* self_data;
|
277
|
+
const GEOSGeometry* self_geom;
|
278
|
+
char val;
|
279
|
+
|
280
|
+
result = Qnil;
|
281
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
282
|
+
self_geom = self_data->geom;
|
229
283
|
if (self_geom) {
|
230
|
-
|
284
|
+
val = GEOSisRing_r(self_data->geos_context, self_geom);
|
231
285
|
if (val == 0) {
|
232
286
|
result = Qfalse;
|
233
287
|
}
|
@@ -241,9 +295,12 @@ static VALUE method_line_string_is_ring(VALUE self)
|
|
241
295
|
|
242
296
|
static VALUE method_line_string_eql(VALUE self, VALUE rhs)
|
243
297
|
{
|
244
|
-
VALUE result
|
298
|
+
VALUE result;
|
299
|
+
RGeo_GeometryData* self_data;
|
300
|
+
|
301
|
+
result = rgeo_geos_klasses_and_factories_eql(self, rhs);
|
245
302
|
if (RTEST(result)) {
|
246
|
-
|
303
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
247
304
|
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);
|
248
305
|
}
|
249
306
|
return result;
|
@@ -252,25 +309,37 @@ static VALUE method_line_string_eql(VALUE self, VALUE rhs)
|
|
252
309
|
|
253
310
|
static GEOSCoordSequence* coord_seq_from_array(VALUE factory, VALUE array, char close)
|
254
311
|
{
|
312
|
+
RGeo_FactoryData* factory_data;
|
313
|
+
VALUE point_type;
|
314
|
+
unsigned int len;
|
315
|
+
char has_z;
|
316
|
+
unsigned int dims;
|
317
|
+
double* coords;
|
318
|
+
GEOSContextHandle_t context;
|
319
|
+
unsigned int i;
|
320
|
+
char good;
|
321
|
+
const GEOSGeometry* entry_geom;
|
322
|
+
const GEOSCoordSequence* entry_cs;
|
323
|
+
double x;
|
324
|
+
GEOSCoordSequence* coord_seq;
|
325
|
+
|
255
326
|
Check_Type(array, T_ARRAY);
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
327
|
+
factory_data = RGEO_FACTORY_DATA_PTR(factory);
|
328
|
+
point_type = factory_data->globals->feature_point;
|
329
|
+
len = (unsigned int)RARRAY_LEN(array);
|
330
|
+
has_z = (char)(RGEO_FACTORY_DATA_PTR(factory)->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M);
|
331
|
+
dims = has_z ? 3 : 2;
|
332
|
+
coords = ALLOC_N(double, len == 0 ? 1 : len * dims);
|
262
333
|
if (!coords) {
|
263
334
|
return NULL;
|
264
335
|
}
|
265
|
-
|
266
|
-
unsigned int i;
|
336
|
+
context = factory_data->geos_context;
|
267
337
|
for (i=0; i<len; ++i) {
|
268
|
-
|
269
|
-
|
338
|
+
good = 0;
|
339
|
+
entry_geom = rgeo_convert_to_geos_geometry(factory, rb_ary_entry(array, i), point_type);
|
270
340
|
if (entry_geom) {
|
271
|
-
|
341
|
+
entry_cs = GEOSGeom_getCoordSeq_r(context, entry_geom);
|
272
342
|
if (entry_cs) {
|
273
|
-
double x;
|
274
343
|
if (GEOSCoordSeq_getX_r(context, entry_cs, 0, &x)) {
|
275
344
|
coords[i*dims] = x;
|
276
345
|
if (GEOSCoordSeq_getY_r(context, entry_cs, 0, &x)) {
|
@@ -301,7 +370,7 @@ static GEOSCoordSequence* coord_seq_from_array(VALUE factory, VALUE array, char
|
|
301
370
|
else {
|
302
371
|
close = 0;
|
303
372
|
}
|
304
|
-
|
373
|
+
coord_seq = GEOSCoordSeq_create_r(context, len + close, 3);
|
305
374
|
if (coord_seq) {
|
306
375
|
for (i=0; i<len; ++i) {
|
307
376
|
GEOSCoordSeq_setX_r(context, coord_seq, i, coords[i*dims]);
|
@@ -321,11 +390,16 @@ static GEOSCoordSequence* coord_seq_from_array(VALUE factory, VALUE array, char
|
|
321
390
|
|
322
391
|
static VALUE cmethod_create_line_string(VALUE module, VALUE factory, VALUE array)
|
323
392
|
{
|
324
|
-
VALUE result
|
325
|
-
GEOSCoordSequence* coord_seq
|
393
|
+
VALUE result;
|
394
|
+
GEOSCoordSequence* coord_seq;
|
395
|
+
RGeo_FactoryData* factory_data;
|
396
|
+
GEOSGeometry* geom;
|
397
|
+
|
398
|
+
result = Qnil;
|
399
|
+
coord_seq = coord_seq_from_array(factory, array, 0);
|
326
400
|
if (coord_seq) {
|
327
|
-
|
328
|
-
|
401
|
+
factory_data = RGEO_FACTORY_DATA_PTR(factory);
|
402
|
+
geom = GEOSGeom_createLineString_r(factory_data->geos_context, coord_seq);
|
329
403
|
if (geom) {
|
330
404
|
result = rgeo_wrap_geos_geometry(factory, geom, factory_data->globals->geos_line_string);
|
331
405
|
}
|
@@ -336,11 +410,16 @@ static VALUE cmethod_create_line_string(VALUE module, VALUE factory, VALUE array
|
|
336
410
|
|
337
411
|
static VALUE cmethod_create_linear_ring(VALUE module, VALUE factory, VALUE array)
|
338
412
|
{
|
339
|
-
VALUE result
|
340
|
-
GEOSCoordSequence* coord_seq
|
413
|
+
VALUE result;
|
414
|
+
GEOSCoordSequence* coord_seq;
|
415
|
+
RGeo_FactoryData* factory_data;
|
416
|
+
GEOSGeometry* geom;
|
417
|
+
|
418
|
+
result = Qnil;
|
419
|
+
coord_seq = coord_seq_from_array(factory, array, 1);
|
341
420
|
if (coord_seq) {
|
342
|
-
|
343
|
-
|
421
|
+
factory_data = RGEO_FACTORY_DATA_PTR(factory);
|
422
|
+
geom = GEOSGeom_createLinearRing_r(factory_data->geos_context, coord_seq);
|
344
423
|
if (geom) {
|
345
424
|
result = rgeo_wrap_geos_geometry(factory, geom, factory_data->globals->geos_linear_ring);
|
346
425
|
}
|
@@ -351,8 +430,11 @@ static VALUE cmethod_create_linear_ring(VALUE module, VALUE factory, VALUE array
|
|
351
430
|
|
352
431
|
static void populate_geom_into_coord_seq(GEOSContextHandle_t context, const GEOSGeometry* geom, GEOSCoordSequence* coord_seq, unsigned int i, char has_z)
|
353
432
|
{
|
354
|
-
const GEOSCoordSequence* cs
|
355
|
-
double x
|
433
|
+
const GEOSCoordSequence* cs;
|
434
|
+
double x;
|
435
|
+
|
436
|
+
cs = GEOSGeom_getCoordSeq_r(context, geom);
|
437
|
+
x = 0;
|
356
438
|
if (cs) {
|
357
439
|
GEOSCoordSeq_getX_r(context, cs, 0, &x);
|
358
440
|
}
|
@@ -372,21 +454,31 @@ static void populate_geom_into_coord_seq(GEOSContextHandle_t context, const GEOS
|
|
372
454
|
|
373
455
|
static VALUE cmethod_create_line(VALUE module, VALUE factory, VALUE start, VALUE end)
|
374
456
|
{
|
375
|
-
VALUE result
|
376
|
-
RGeo_FactoryData* factory_data
|
377
|
-
char has_z
|
378
|
-
VALUE point_type
|
379
|
-
GEOSContextHandle_t context
|
457
|
+
VALUE result;
|
458
|
+
RGeo_FactoryData* factory_data;
|
459
|
+
char has_z;
|
460
|
+
VALUE point_type;
|
461
|
+
GEOSContextHandle_t context;
|
462
|
+
const GEOSGeometry* start_geom;
|
463
|
+
const GEOSGeometry* end_geom;
|
464
|
+
GEOSCoordSequence* coord_seq;
|
465
|
+
GEOSGeometry* geom;
|
466
|
+
|
467
|
+
result = Qnil;
|
468
|
+
factory_data = RGEO_FACTORY_DATA_PTR(factory);
|
469
|
+
has_z = (char)(factory_data->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M);
|
470
|
+
point_type = factory_data->globals->feature_point;
|
471
|
+
context = factory_data->geos_context;
|
380
472
|
|
381
|
-
|
473
|
+
start_geom = rgeo_convert_to_geos_geometry(factory, start, point_type);
|
382
474
|
if (start_geom) {
|
383
|
-
|
475
|
+
end_geom = rgeo_convert_to_geos_geometry(factory, end, point_type);
|
384
476
|
if (end_geom) {
|
385
|
-
|
477
|
+
coord_seq = GEOSCoordSeq_create_r(context, 2, 3);
|
386
478
|
if (coord_seq) {
|
387
479
|
populate_geom_into_coord_seq(context, start_geom, coord_seq, 0, has_z);
|
388
480
|
populate_geom_into_coord_seq(context, end_geom, coord_seq, 1, has_z);
|
389
|
-
|
481
|
+
geom = GEOSGeom_createLineString_r(context, coord_seq);
|
390
482
|
if (geom) {
|
391
483
|
result = rgeo_wrap_geos_geometry(factory, geom, factory_data->globals->geos_line);
|
392
484
|
}
|
@@ -400,19 +492,26 @@ static VALUE cmethod_create_line(VALUE module, VALUE factory, VALUE start, VALUE
|
|
400
492
|
|
401
493
|
static VALUE impl_copy_from(VALUE klass, VALUE factory, VALUE original, char subtype)
|
402
494
|
{
|
403
|
-
VALUE result
|
404
|
-
const GEOSGeometry* original_geom
|
495
|
+
VALUE result;
|
496
|
+
const GEOSGeometry* original_geom;
|
497
|
+
GEOSContextHandle_t context;
|
498
|
+
const GEOSCoordSequence* original_coord_seq;
|
499
|
+
GEOSCoordSequence* coord_seq;
|
500
|
+
GEOSGeometry* geom;
|
501
|
+
|
502
|
+
result = Qnil;
|
503
|
+
original_geom = RGEO_GEOMETRY_DATA_PTR(original)->geom;
|
405
504
|
if (original_geom) {
|
406
|
-
|
505
|
+
context = RGEO_FACTORY_DATA_PTR(factory)->geos_context;
|
407
506
|
if (subtype == 1 && GEOSGetNumCoordinates_r(context, original_geom) != 2) {
|
408
507
|
original_geom = NULL;
|
409
508
|
}
|
410
509
|
if (original_geom) {
|
411
|
-
|
510
|
+
original_coord_seq = GEOSGeom_getCoordSeq_r(context, original_geom);
|
412
511
|
if (original_coord_seq) {
|
413
|
-
|
512
|
+
coord_seq = GEOSCoordSeq_clone_r(context, original_coord_seq);
|
414
513
|
if (coord_seq) {
|
415
|
-
|
514
|
+
geom = subtype == 2 ? GEOSGeom_createLinearRing_r(context, coord_seq) : GEOSGeom_createLineString_r(context, coord_seq);
|
416
515
|
if (geom) {
|
417
516
|
result = rgeo_wrap_geos_geometry(factory, geom, klass);
|
418
517
|
}
|
@@ -444,7 +543,11 @@ static VALUE cmethod_linear_ring_copy_from(VALUE klass, VALUE factory, VALUE ori
|
|
444
543
|
|
445
544
|
void rgeo_init_geos_line_string(RGeo_Globals* globals)
|
446
545
|
{
|
447
|
-
VALUE geos_line_string_class
|
546
|
+
VALUE geos_line_string_class;
|
547
|
+
VALUE geos_linear_ring_class;
|
548
|
+
VALUE geos_line_class;
|
549
|
+
|
550
|
+
geos_line_string_class = rb_define_class_under(globals->geos_module, "LineStringImpl", globals->geos_geometry);
|
448
551
|
globals->geos_line_string = geos_line_string_class;
|
449
552
|
globals->feature_line_string = rb_const_get_at(globals->feature_module, rb_intern("LineString"));
|
450
553
|
rb_funcall(globals->global_mixins, rb_intern("include_in_class"), 2,
|
@@ -452,13 +555,13 @@ void rgeo_init_geos_line_string(RGeo_Globals* globals)
|
|
452
555
|
rb_funcall(globals->global_mixins, rb_intern("include_in_class"), 2,
|
453
556
|
globals->feature_line_string, geos_line_string_class);
|
454
557
|
|
455
|
-
|
558
|
+
geos_linear_ring_class = rb_define_class_under(globals->geos_module, "LinearRingImpl", geos_line_string_class);
|
456
559
|
globals->geos_linear_ring = geos_linear_ring_class;
|
457
560
|
globals->feature_linear_ring = rb_const_get_at(globals->feature_module, rb_intern("LinearRing"));
|
458
561
|
rb_funcall(globals->global_mixins, rb_intern("include_in_class"), 2,
|
459
562
|
globals->feature_linear_ring, geos_linear_ring_class);
|
460
563
|
|
461
|
-
|
564
|
+
geos_line_class = rb_define_class_under(globals->geos_module, "LineImpl", geos_line_string_class);
|
462
565
|
globals->geos_line = geos_line_class;
|
463
566
|
globals->feature_line = rb_const_get_at(globals->feature_module, rb_intern("Line"));
|
464
567
|
rb_funcall(globals->global_mixins, rb_intern("include_in_class"), 2,
|
@@ -489,11 +592,15 @@ void rgeo_init_geos_line_string(RGeo_Globals* globals)
|
|
489
592
|
|
490
593
|
VALUE rgeo_is_geos_line_string_closed(GEOSContextHandle_t context, const GEOSGeometry* geom)
|
491
594
|
{
|
492
|
-
|
493
|
-
unsigned int n
|
595
|
+
VALUE result;
|
596
|
+
unsigned int n;
|
597
|
+
double x1, x2, y1, y2, z1, z2;
|
598
|
+
const GEOSCoordSequence* coord_seq;
|
599
|
+
|
600
|
+
result = Qnil;
|
601
|
+
n = GEOSGetNumCoordinates_r(context, geom);
|
494
602
|
if (n > 0) {
|
495
|
-
|
496
|
-
const GEOSCoordSequence* coord_seq = GEOSGeom_getCoordSeq_r(context, geom);
|
603
|
+
coord_seq = GEOSGeom_getCoordSeq_r(context, geom);
|
497
604
|
if (GEOSCoordSeq_getX_r(context, coord_seq, 0, &x1)) {
|
498
605
|
if (GEOSCoordSeq_getX_r(context, coord_seq, n-1, &x2)) {
|
499
606
|
if (x1 == x2) {
|