rgeo 0.1.13 → 0.1.14
Sign up to get free protection for your applications and to get access to all the features.
- data/History.rdoc +11 -0
- data/Version +1 -1
- data/ext/geos_c_impl/factory.c +35 -40
- data/ext/geos_c_impl/factory.h +4 -1
- data/ext/geos_c_impl/geometry_collection.c +5 -5
- data/ext/geos_c_impl/geometry_collection.h +1 -1
- data/ext/geos_c_impl/line_string.c +129 -116
- data/ext/geos_c_impl/point.c +22 -33
- data/ext/geos_c_impl/point.h +1 -6
- data/ext/geos_c_impl/polygon.c +4 -4
- data/ext/geos_c_impl/polygon.h +1 -1
- data/lib/rgeo.rb +1 -0
- data/lib/rgeo/cartesian/simple_factory.rb +20 -4
- data/lib/rgeo/errors.rb +8 -0
- data/lib/rgeo/features/factory.rb +35 -1
- data/lib/rgeo/features/point.rb +22 -0
- data/lib/rgeo/features/polygon.rb +1 -2
- data/lib/rgeo/features/types.rb +70 -16
- data/lib/rgeo/geography/factories.rb +40 -3
- data/lib/rgeo/geography/factory.rb +25 -5
- data/lib/rgeo/geography/simple_mercator/feature_methods.rb +2 -6
- data/lib/rgeo/geography/simple_mercator/projector.rb +1 -1
- data/lib/rgeo/geos/factory.rb +40 -46
- data/lib/rgeo/geos/interface.rb +10 -0
- data/lib/rgeo/impl_helpers.rb +0 -1
- data/lib/rgeo/impl_helpers/basic_geometry_methods.rb +2 -2
- data/lib/rgeo/impl_helpers/basic_point_methods.rb +12 -14
- data/lib/rgeo/wkrep.rb +59 -0
- data/lib/rgeo/wkrep/wkb_generator.rb +181 -0
- data/lib/rgeo/wkrep/wkb_parser.rb +205 -0
- data/lib/rgeo/wkrep/wkt_generator.rb +187 -0
- data/lib/rgeo/wkrep/wkt_parser.rb +321 -0
- data/tests/common/line_string_tests.rb +26 -2
- data/tests/common/point_tests.rb +26 -0
- data/tests/geos/tc_point.rb +1 -20
- data/tests/simple_cartesian/tc_point.rb +1 -0
- data/tests/simple_mercator/tc_point.rb +1 -0
- data/tests/simple_spherical/tc_point.rb +1 -0
- data/tests/tc_oneoff.rb +3 -2
- metadata +8 -4
- data/lib/rgeo/impl_helpers/serialization.rb +0 -130
data/History.rdoc
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
=== 0.1.14 / 2010-11-04
|
2
|
+
|
3
|
+
* Introduced capability checking API.
|
4
|
+
* Standardized API and semantics for handling of points with Z and/or M coordinates.
|
5
|
+
* Fixed several problems with Z coordinates in GEOS.
|
6
|
+
* Fixed exceptions and wrong values returned from GEOS LineString#start_point and LineString#end_point.
|
7
|
+
* Fixed crash in GEOS LineString#point_n when the index was out of bounds.
|
8
|
+
* Fixed GEOS line string closed test.
|
9
|
+
* Implemented support for Z and M coordinates in GEOS, SimpleCartesian, SimpleMercator, and SimpleSpherical. GEOS and SimpleMercator support Z or M but not both at once, because the underlying GEOS library supports only 3 dimensions. SimpleCartesian and SimpleSpherical can support both at once.
|
10
|
+
* Implemented parsers and generators for WKT/WKB and EWKT/EWKB in Ruby, providing full support for all generally used cases including 3 and 4 dimensional data and embedded SRIDs. This implementation is used by default by all feature implementations except GEOS, which continues to use its own internal WKT/WKB implementation unless the Ruby implementation is invoked explicitly.
|
11
|
+
|
1
12
|
=== 0.1.13 / 2010-10-26
|
2
13
|
|
3
14
|
* Reworked the way casting is done. Casting has two dimensions: factory casting and type casting, either or both of which can be done at once. Implemented a standard casting algorithm to handle these cases, and an override mechanism for factories that want to do some of their own casting. Removed Factory#cast and Geometry#cast, and implemented a global Features::cast entry point instead.
|
data/Version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.14
|
data/ext/geos_c_impl/factory.c
CHANGED
@@ -371,69 +371,64 @@ const GEOSGeometry* rgeo_get_geos_geometry_safe(VALUE obj)
|
|
371
371
|
}
|
372
372
|
|
373
373
|
|
374
|
-
VALUE rgeo_geos_coordseqs_eql(GEOSContextHandle_t context, const GEOSGeometry* geom1, const GEOSGeometry* geom2)
|
374
|
+
VALUE rgeo_geos_coordseqs_eql(GEOSContextHandle_t context, const GEOSGeometry* geom1, const GEOSGeometry* geom2, char check_z)
|
375
375
|
{
|
376
376
|
VALUE result = Qnil;
|
377
377
|
if (geom1 && geom2) {
|
378
378
|
const GEOSCoordSequence* cs1 = GEOSGeom_getCoordSeq_r(context, geom1);
|
379
379
|
const GEOSCoordSequence* cs2 = GEOSGeom_getCoordSeq_r(context, geom2);
|
380
380
|
if (cs1 && cs2) {
|
381
|
-
|
382
|
-
|
383
|
-
if (
|
384
|
-
if (
|
385
|
-
|
386
|
-
unsigned int
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
for (i=0; i<len1; ++i) {
|
393
|
-
if (GEOSCoordSeq_getX_r(context, cs1, i, &val1) && GEOSCoordSeq_getX_r(context, cs2, i, &val2)) {
|
381
|
+
unsigned int len1 = 0;
|
382
|
+
unsigned int len2 = 0;
|
383
|
+
if (GEOSCoordSeq_getSize_r(context, cs1, &len1) && GEOSCoordSeq_getSize_r(context, cs2, &len2)) {
|
384
|
+
if (len1 == len2) {
|
385
|
+
result = Qtrue;
|
386
|
+
unsigned int i;
|
387
|
+
double val1, val2;
|
388
|
+
for (i=0; i<len1; ++i) {
|
389
|
+
if (GEOSCoordSeq_getX_r(context, cs1, i, &val1) && GEOSCoordSeq_getX_r(context, cs2, i, &val2)) {
|
390
|
+
if (val1 == val2) {
|
391
|
+
if (GEOSCoordSeq_getY_r(context, cs1, i, &val1) && GEOSCoordSeq_getY_r(context, cs2, i, &val2)) {
|
394
392
|
if (val1 == val2) {
|
395
|
-
if (
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
result = Qnil;
|
406
|
-
break;
|
407
|
-
}
|
408
|
-
}
|
393
|
+
if (check_z) {
|
394
|
+
val1 = 0;
|
395
|
+
if (!GEOSCoordSeq_getZ_r(context, cs1, i, &val1)) {
|
396
|
+
result = Qnil;
|
397
|
+
break;
|
398
|
+
}
|
399
|
+
val2 = 0;
|
400
|
+
if (!GEOSCoordSeq_getZ_r(context, cs2, i, &val2)) {
|
401
|
+
result = Qnil;
|
402
|
+
break;
|
409
403
|
}
|
410
|
-
|
404
|
+
if (val1 != val2) {
|
411
405
|
result = Qfalse;
|
412
406
|
break;
|
413
407
|
}
|
414
408
|
}
|
415
|
-
else { // Failed to get Y coords
|
416
|
-
result = Qnil;
|
417
|
-
break;
|
418
|
-
}
|
419
409
|
}
|
420
|
-
else { //
|
410
|
+
else { // Y coords are different
|
421
411
|
result = Qfalse;
|
422
412
|
break;
|
423
413
|
}
|
424
414
|
}
|
425
|
-
else { // Failed to get
|
415
|
+
else { // Failed to get Y coords
|
426
416
|
result = Qnil;
|
427
417
|
break;
|
428
418
|
}
|
429
|
-
}
|
419
|
+
}
|
420
|
+
else { // X coords are different
|
421
|
+
result = Qfalse;
|
422
|
+
break;
|
423
|
+
}
|
430
424
|
}
|
431
|
-
else { //
|
432
|
-
result =
|
425
|
+
else { // Failed to get X coords
|
426
|
+
result = Qnil;
|
427
|
+
break;
|
433
428
|
}
|
434
|
-
}
|
429
|
+
} // Iteration over coords
|
435
430
|
}
|
436
|
-
else { //
|
431
|
+
else { // Lengths are different
|
437
432
|
result = Qfalse;
|
438
433
|
}
|
439
434
|
}
|
data/ext/geos_c_impl/factory.h
CHANGED
@@ -72,6 +72,9 @@ typedef struct {
|
|
72
72
|
} RGeo_FactoryData;
|
73
73
|
|
74
74
|
#define RGEO_FACTORYFLAGS_LENIENT_MULTIPOLYGON 1
|
75
|
+
#define RGEO_FACTORYFLAGS_SUPPORTS_Z 2
|
76
|
+
#define RGEO_FACTORYFLAGS_SUPPORTS_M 4
|
77
|
+
#define RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M 6
|
75
78
|
|
76
79
|
|
77
80
|
// Wrapped structure for Geometry objects.
|
@@ -196,7 +199,7 @@ const GEOSGeometry* rgeo_get_geos_geometry_safe(VALUE obj);
|
|
196
199
|
Returns Qtrue if the two coordinate sequences are equal, Qfalse
|
197
200
|
if they are inequal, or Qnil if an error occurs.
|
198
201
|
*/
|
199
|
-
VALUE rgeo_geos_coordseqs_eql(GEOSContextHandle_t context, const GEOSGeometry* geom1, const GEOSGeometry* geom2);
|
202
|
+
VALUE rgeo_geos_coordseqs_eql(GEOSContextHandle_t context, const GEOSGeometry* geom1, const GEOSGeometry* geom2, char check_z);
|
200
203
|
|
201
204
|
/*
|
202
205
|
Compares the ruby classes and geometry factories of the two given ruby
|
@@ -151,7 +151,7 @@ static VALUE method_geometry_collection_eql(VALUE self, VALUE rhs)
|
|
151
151
|
{
|
152
152
|
VALUE result = rgeo_geos_klasses_and_factories_eql(self, rhs);
|
153
153
|
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));
|
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);
|
155
155
|
}
|
156
156
|
return result;
|
157
157
|
}
|
@@ -390,7 +390,7 @@ void rgeo_init_geos_geometry_collection(RGeo_Globals* globals)
|
|
390
390
|
/**** OTHER PUBLIC FUNCTIONS ****/
|
391
391
|
|
392
392
|
|
393
|
-
VALUE rgeo_geos_geometry_collections_eql(GEOSContextHandle_t context, const GEOSGeometry* geom1, const GEOSGeometry* geom2)
|
393
|
+
VALUE rgeo_geos_geometry_collections_eql(GEOSContextHandle_t context, const GEOSGeometry* geom1, const GEOSGeometry* geom2, char check_z)
|
394
394
|
{
|
395
395
|
VALUE result = Qnil;
|
396
396
|
if (geom1 && geom2) {
|
@@ -412,16 +412,16 @@ VALUE rgeo_geos_geometry_collections_eql(GEOSContextHandle_t context, const GEOS
|
|
412
412
|
case GEOS_POINT:
|
413
413
|
case GEOS_LINESTRING:
|
414
414
|
case GEOS_LINEARRING:
|
415
|
-
result = rgeo_geos_coordseqs_eql(context, sub_geom1, sub_geom2);
|
415
|
+
result = rgeo_geos_coordseqs_eql(context, sub_geom1, sub_geom2, check_z);
|
416
416
|
break;
|
417
417
|
case GEOS_POLYGON:
|
418
|
-
result = rgeo_geos_polygons_eql(context, sub_geom1, sub_geom2);
|
418
|
+
result = rgeo_geos_polygons_eql(context, sub_geom1, sub_geom2, check_z);
|
419
419
|
break;
|
420
420
|
case GEOS_GEOMETRYCOLLECTION:
|
421
421
|
case GEOS_MULTIPOINT:
|
422
422
|
case GEOS_MULTILINESTRING:
|
423
423
|
case GEOS_MULTIPOLYGON:
|
424
|
-
result = rgeo_geos_geometry_collections_eql(context, sub_geom1, sub_geom2);
|
424
|
+
result = rgeo_geos_geometry_collections_eql(context, sub_geom1, sub_geom2, check_z);
|
425
425
|
break;
|
426
426
|
default:
|
427
427
|
result = Qnil;
|
@@ -61,7 +61,7 @@ void rgeo_init_geos_geometry_collection(RGeo_Globals* globals);
|
|
61
61
|
Returns Qtrue if the contents of the two geometry collections are equal,
|
62
62
|
Qfalse if they are inequal, or Qnil if an error occurs.
|
63
63
|
*/
|
64
|
-
VALUE rgeo_geos_geometry_collections_eql(GEOSContextHandle_t context, const GEOSGeometry* geom1, const GEOSGeometry* geom2);
|
64
|
+
VALUE rgeo_geos_geometry_collections_eql(GEOSContextHandle_t context, const GEOSGeometry* geom1, const GEOSGeometry* geom2, char check_z);
|
65
65
|
|
66
66
|
|
67
67
|
RGEO_END_C
|
@@ -109,6 +109,27 @@ static VALUE method_line_string_num_points(VALUE self)
|
|
109
109
|
}
|
110
110
|
|
111
111
|
|
112
|
+
static VALUE get_point_from_coordseq(VALUE self, const GEOSCoordSequence* coord_seq, unsigned int i, char has_z)
|
113
|
+
{
|
114
|
+
VALUE result = Qnil;
|
115
|
+
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
|
+
if (has_z) {
|
119
|
+
if (!GEOSCoordSeq_getZ_r(RGEO_CONTEXT_FROM_GEOMETRY(self), coord_seq, i, &z)) {
|
120
|
+
z = 0.0;
|
121
|
+
}
|
122
|
+
}
|
123
|
+
else {
|
124
|
+
z = 0.0;
|
125
|
+
}
|
126
|
+
result = rgeo_create_geos_point(RGEO_FACTORY_FROM_GEOMETRY(self), x, y, z);
|
127
|
+
}
|
128
|
+
}
|
129
|
+
return result;
|
130
|
+
}
|
131
|
+
|
132
|
+
|
112
133
|
static VALUE method_line_string_point_n(VALUE self, VALUE n)
|
113
134
|
{
|
114
135
|
VALUE result = Qnil;
|
@@ -116,18 +137,15 @@ static VALUE method_line_string_point_n(VALUE self, VALUE n)
|
|
116
137
|
if (self_geom) {
|
117
138
|
const GEOSCoordSequence* coord_seq = GEOSGeom_getCoordSeq_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom);
|
118
139
|
if (coord_seq) {
|
119
|
-
char has_z =
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
}
|
129
|
-
else {
|
130
|
-
result = rgeo_create_geos_point_2d(RGEO_FACTORY_FROM_GEOMETRY(self), x, y);
|
140
|
+
char has_z = (char)(RGEO_FACTORY_DATA_FROM_GEOMETRY(self)->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M);
|
141
|
+
int si = NUM2INT(n);
|
142
|
+
if (si >= 0) {
|
143
|
+
unsigned int i = si;
|
144
|
+
unsigned int size;
|
145
|
+
if (GEOSCoordSeq_getSize_r(RGEO_CONTEXT_FROM_GEOMETRY(self), coord_seq, &size)) {
|
146
|
+
if (i < size) {
|
147
|
+
unsigned int dims;
|
148
|
+
result = get_point_from_coordseq(self, coord_seq, i, has_z);
|
131
149
|
}
|
132
150
|
}
|
133
151
|
}
|
@@ -144,22 +162,16 @@ static VALUE method_line_string_points(VALUE self)
|
|
144
162
|
if (self_geom) {
|
145
163
|
const GEOSCoordSequence* coord_seq = GEOSGeom_getCoordSeq_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom);
|
146
164
|
if (coord_seq) {
|
147
|
-
char has_z =
|
148
|
-
int
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
rb_ary_store(result, i, rgeo_create_geos_point_3d(RGEO_FACTORY_FROM_GEOMETRY(self), x, y, z));
|
158
|
-
}
|
159
|
-
}
|
160
|
-
else {
|
161
|
-
rb_ary_store(result, i, rgeo_create_geos_point_2d(RGEO_FACTORY_FROM_GEOMETRY(self), x, y));
|
162
|
-
}
|
165
|
+
char has_z = (char)(RGEO_FACTORY_DATA_FROM_GEOMETRY(self)->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M);
|
166
|
+
unsigned int size;
|
167
|
+
if (GEOSCoordSeq_getSize_r(RGEO_CONTEXT_FROM_GEOMETRY(self), coord_seq, &size)) {
|
168
|
+
result = rb_ary_new2(size);
|
169
|
+
double x, y, z;
|
170
|
+
unsigned int i;
|
171
|
+
for (i=0; i<size; ++i) {
|
172
|
+
VALUE point = get_point_from_coordseq(self, coord_seq, i, has_z);
|
173
|
+
if (!NIL_P(point)) {
|
174
|
+
rb_ary_store(result, i, point);
|
163
175
|
}
|
164
176
|
}
|
165
177
|
}
|
@@ -171,7 +183,7 @@ static VALUE method_line_string_points(VALUE self)
|
|
171
183
|
|
172
184
|
static VALUE method_line_string_start_point(VALUE self)
|
173
185
|
{
|
174
|
-
return method_line_string_point_n(self, 0);
|
186
|
+
return method_line_string_point_n(self, INT2NUM(0));
|
175
187
|
}
|
176
188
|
|
177
189
|
|
@@ -182,7 +194,7 @@ static VALUE method_line_string_end_point(VALUE self)
|
|
182
194
|
if (self_geom) {
|
183
195
|
unsigned int n = GEOSGetNumCoordinates_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom);
|
184
196
|
if (n > 0) {
|
185
|
-
result = method_line_string_point_n(self, n-1);
|
197
|
+
result = method_line_string_point_n(self, INT2NUM(n-1));
|
186
198
|
}
|
187
199
|
}
|
188
200
|
return result;
|
@@ -221,7 +233,7 @@ static VALUE method_line_string_eql(VALUE self, VALUE rhs)
|
|
221
233
|
{
|
222
234
|
VALUE result = rgeo_geos_klasses_and_factories_eql(self, rhs);
|
223
235
|
if (RTEST(result)) {
|
224
|
-
result = rgeo_geos_coordseqs_eql(RGEO_CONTEXT_FROM_GEOMETRY(self), RGEO_GET_GEOS_GEOMETRY(self), RGEO_GET_GEOS_GEOMETRY(rhs));
|
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);
|
225
237
|
}
|
226
238
|
return result;
|
227
239
|
}
|
@@ -231,45 +243,66 @@ static GEOSCoordSequence* coord_seq_from_array(VALUE factory, VALUE array, char
|
|
231
243
|
{
|
232
244
|
Check_Type(array, T_ARRAY);
|
233
245
|
VALUE point_type = rb_const_get_at(RGEO_GLOBALS_FROM_FACTORY(factory)->features_module, rb_intern("Point"));
|
234
|
-
unsigned int
|
235
|
-
|
236
|
-
|
246
|
+
unsigned int len = (unsigned int)RARRAY_LEN(array);
|
247
|
+
char has_z = (char)(RGEO_FACTORY_DATA_PTR(factory)->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M);
|
248
|
+
unsigned int dims = has_z ? 3 : 2;
|
249
|
+
double* coords = ALLOC_N(double, len == 0 ? 1 : len * dims);
|
250
|
+
if (!coords) {
|
237
251
|
return NULL;
|
238
252
|
}
|
239
|
-
|
253
|
+
GEOSContextHandle_t context = RGEO_CONTEXT_FROM_FACTORY(factory);
|
240
254
|
unsigned int i;
|
241
|
-
for (i=0; i<
|
255
|
+
for (i=0; i<len; ++i) {
|
256
|
+
char good = 0;
|
242
257
|
const GEOSGeometry* entry_geom = rgeo_convert_to_geos_geometry(factory, rb_ary_entry(array, i), point_type);
|
243
|
-
if (
|
244
|
-
|
258
|
+
if (entry_geom) {
|
259
|
+
const GEOSCoordSequence* entry_cs = GEOSGeom_getCoordSeq_r(context, entry_geom);
|
260
|
+
if (entry_cs) {
|
261
|
+
double x;
|
262
|
+
if (GEOSCoordSeq_getX_r(context, entry_cs, 0, &x)) {
|
263
|
+
coords[i*dims] = x;
|
264
|
+
if (GEOSCoordSeq_getY_r(context, entry_cs, 0, &x)) {
|
265
|
+
coords[i*dims+1] = x;
|
266
|
+
good = 1;
|
267
|
+
if (has_z) {
|
268
|
+
if (GEOSCoordSeq_getZ_r(context, entry_cs, 0, &x)) {
|
269
|
+
coords[i*dims+2] = x;
|
270
|
+
}
|
271
|
+
else {
|
272
|
+
good = 0;
|
273
|
+
}
|
274
|
+
}
|
275
|
+
}
|
276
|
+
}
|
277
|
+
}
|
278
|
+
}
|
279
|
+
if (!good) {
|
280
|
+
free(coords);
|
245
281
|
return NULL;
|
246
282
|
}
|
247
|
-
|
248
|
-
|
249
|
-
|
283
|
+
}
|
284
|
+
if (len > 0 && close) {
|
285
|
+
if (coords[0] == coords[(len-1)*dims] && coords[1] == coords[(len-1)*dims+1]) {
|
286
|
+
close = 0;
|
250
287
|
}
|
251
288
|
}
|
252
|
-
|
253
|
-
|
254
|
-
++len;
|
289
|
+
else {
|
290
|
+
close = 0;
|
255
291
|
}
|
256
|
-
GEOSCoordSequence* coord_seq = GEOSCoordSeq_create_r(
|
292
|
+
GEOSCoordSequence* coord_seq = GEOSCoordSeq_create_r(context, len + close, 3);
|
257
293
|
if (coord_seq) {
|
258
294
|
for (i=0; i<len; ++i) {
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
if (has_z && GEOSCoordSeq_getZ_r(RGEO_CONTEXT_FROM_FACTORY(factory), cs, 0, &x)) {
|
268
|
-
GEOSCoordSeq_setZ_r(RGEO_CONTEXT_FROM_FACTORY(factory), coord_seq, i, x);
|
269
|
-
}
|
295
|
+
GEOSCoordSeq_setX_r(context, coord_seq, i, coords[i*dims]);
|
296
|
+
GEOSCoordSeq_setY_r(context, coord_seq, i, coords[i*dims+1]);
|
297
|
+
GEOSCoordSeq_setZ_r(context, coord_seq, i, has_z ? coords[i*dims+2] : 0);
|
298
|
+
}
|
299
|
+
if (close) {
|
300
|
+
GEOSCoordSeq_setX_r(context, coord_seq, len, coords[0]);
|
301
|
+
GEOSCoordSeq_setY_r(context, coord_seq, len, coords[1]);
|
302
|
+
GEOSCoordSeq_setZ_r(context, coord_seq, len, has_z ? coords[2] : 0);
|
270
303
|
}
|
271
304
|
}
|
272
|
-
free(
|
305
|
+
free(coords);
|
273
306
|
return coord_seq;
|
274
307
|
}
|
275
308
|
|
@@ -302,56 +335,50 @@ static VALUE cmethod_create_linear_ring(VALUE module, VALUE factory, VALUE array
|
|
302
335
|
}
|
303
336
|
|
304
337
|
|
338
|
+
static void populate_geom_into_coord_seq(GEOSContextHandle_t context, const GEOSGeometry* geom, GEOSCoordSequence* coord_seq, unsigned int i, char has_z)
|
339
|
+
{
|
340
|
+
const GEOSCoordSequence* cs = GEOSGeom_getCoordSeq_r(context, geom);
|
341
|
+
double x = 0;
|
342
|
+
if (cs) {
|
343
|
+
GEOSCoordSeq_getX_r(context, cs, 0, &x);
|
344
|
+
}
|
345
|
+
GEOSCoordSeq_setX_r(context, coord_seq, i, x);
|
346
|
+
x = 0;
|
347
|
+
if (cs) {
|
348
|
+
GEOSCoordSeq_getY_r(context, cs, 0, &x);
|
349
|
+
}
|
350
|
+
GEOSCoordSeq_setY_r(context, coord_seq, i, x);
|
351
|
+
x = 0;
|
352
|
+
if (has_z && cs) {
|
353
|
+
GEOSCoordSeq_getZ_r(context, cs, 0, &x);
|
354
|
+
}
|
355
|
+
GEOSCoordSeq_setZ_r(context, coord_seq, i, x);
|
356
|
+
}
|
357
|
+
|
358
|
+
|
305
359
|
static VALUE cmethod_create_line(VALUE module, VALUE factory, VALUE start, VALUE end)
|
306
360
|
{
|
307
361
|
VALUE result = Qnil;
|
308
|
-
char has_z =
|
362
|
+
char has_z = (char)(RGEO_FACTORY_DATA_PTR(factory)->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M);
|
309
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);
|
310
365
|
|
311
366
|
const GEOSGeometry* start_geom = rgeo_convert_to_geos_geometry(factory, start, point_type);
|
312
|
-
if (
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
}
|
325
|
-
|
326
|
-
GEOSCoordSequence* coord_seq = GEOSCoordSeq_create_r(RGEO_CONTEXT_FROM_FACTORY(factory), 2, has_z ? 3 : 2);
|
327
|
-
if (coord_seq) {
|
328
|
-
const GEOSCoordSequence* cs;
|
329
|
-
double x;
|
330
|
-
cs = GEOSGeom_getCoordSeq_r(RGEO_CONTEXT_FROM_FACTORY(factory), start_geom);
|
331
|
-
if (GEOSCoordSeq_getX_r(RGEO_CONTEXT_FROM_FACTORY(factory), cs, 0, &x)) {
|
332
|
-
GEOSCoordSeq_setX_r(RGEO_CONTEXT_FROM_FACTORY(factory), coord_seq, 0, x);
|
333
|
-
}
|
334
|
-
if (GEOSCoordSeq_getY_r(RGEO_CONTEXT_FROM_FACTORY(factory), cs, 0, &x)) {
|
335
|
-
GEOSCoordSeq_setY_r(RGEO_CONTEXT_FROM_FACTORY(factory), coord_seq, 0, x);
|
336
|
-
}
|
337
|
-
if (has_z && GEOSCoordSeq_getZ_r(RGEO_CONTEXT_FROM_FACTORY(factory), cs, 0, &x)) {
|
338
|
-
GEOSCoordSeq_setZ_r(RGEO_CONTEXT_FROM_FACTORY(factory), coord_seq, 0, x);
|
339
|
-
}
|
340
|
-
cs = GEOSGeom_getCoordSeq_r(RGEO_CONTEXT_FROM_FACTORY(factory), end_geom);
|
341
|
-
if (GEOSCoordSeq_getX_r(RGEO_CONTEXT_FROM_FACTORY(factory), cs, 0, &x)) {
|
342
|
-
GEOSCoordSeq_setX_r(RGEO_CONTEXT_FROM_FACTORY(factory), coord_seq, 1, x);
|
343
|
-
}
|
344
|
-
if (GEOSCoordSeq_getY_r(RGEO_CONTEXT_FROM_FACTORY(factory), cs, 0, &x)) {
|
345
|
-
GEOSCoordSeq_setY_r(RGEO_CONTEXT_FROM_FACTORY(factory), coord_seq, 1, x);
|
346
|
-
}
|
347
|
-
if (has_z && GEOSCoordSeq_getZ_r(RGEO_CONTEXT_FROM_FACTORY(factory), cs, 0, &x)) {
|
348
|
-
GEOSCoordSeq_setZ_r(RGEO_CONTEXT_FROM_FACTORY(factory), coord_seq, 1, x);
|
349
|
-
}
|
350
|
-
GEOSGeometry* geom = GEOSGeom_createLineString_r(RGEO_CONTEXT_FROM_FACTORY(factory), coord_seq);
|
351
|
-
if (geom) {
|
352
|
-
result = rgeo_wrap_geos_geometry(factory, geom, rb_const_get_at(RGEO_GLOBALS_FROM_FACTORY(factory)->geos_module, rb_intern("LineImpl")));
|
367
|
+
if (start_geom) {
|
368
|
+
const GEOSGeometry* end_geom = rgeo_convert_to_geos_geometry(factory, end, point_type);
|
369
|
+
if (end_geom) {
|
370
|
+
GEOSCoordSequence* coord_seq = GEOSCoordSeq_create_r(context, 2, 3);
|
371
|
+
if (coord_seq) {
|
372
|
+
populate_geom_into_coord_seq(context, start_geom, coord_seq, 0, has_z);
|
373
|
+
populate_geom_into_coord_seq(context, end_geom, coord_seq, 1, has_z);
|
374
|
+
GEOSGeometry* geom = GEOSGeom_createLineString_r(context, coord_seq);
|
375
|
+
if (geom) {
|
376
|
+
result = rgeo_wrap_geos_geometry(factory, geom, rb_const_get_at(RGEO_GLOBALS_FROM_FACTORY(factory)->geos_module, rb_intern("LineImpl")));
|
377
|
+
}
|
378
|
+
}
|
353
379
|
}
|
354
380
|
}
|
381
|
+
|
355
382
|
return result;
|
356
383
|
}
|
357
384
|
|
@@ -437,26 +464,12 @@ VALUE rgeo_is_geos_line_string_closed(GEOSContextHandle_t context, const GEOSGeo
|
|
437
464
|
if (GEOSCoordSeq_getX_r(context, coord_seq, n-1, &x2)) {
|
438
465
|
if (x1 == x2) {
|
439
466
|
if (GEOSCoordSeq_getY_r(context, coord_seq, 0, &y1)) {
|
440
|
-
if (GEOSCoordSeq_getY_r(context, coord_seq, n-
|
441
|
-
|
442
|
-
if (GEOSHasZ_r(context, geom) == 1) {
|
443
|
-
if (GEOSCoordSeq_getZ_r(context, coord_seq, 0, &z1)) {
|
444
|
-
if (GEOSCoordSeq_getZ_r(context, coord_seq, 0, &z2)) {
|
445
|
-
result = z1 == z2 ? Qtrue : Qfalse;
|
446
|
-
}
|
447
|
-
}
|
448
|
-
}
|
449
|
-
else { // Doesn't have Z coordinate
|
450
|
-
result = Qtrue;
|
451
|
-
}
|
452
|
-
}
|
453
|
-
else { // Y coordinates are different
|
454
|
-
result = Qfalse;
|
455
|
-
}
|
467
|
+
if (GEOSCoordSeq_getY_r(context, coord_seq, n-1, &y2)) {
|
468
|
+
result = y1 == y2 ? Qtrue : Qfalse;
|
456
469
|
}
|
457
470
|
}
|
458
471
|
}
|
459
|
-
else {
|
472
|
+
else {
|
460
473
|
result = Qfalse;
|
461
474
|
}
|
462
475
|
}
|