rgeo 0.1.13 → 0.1.14
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 +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
|
}
|