rgeo 0.1.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. data/History.rdoc +22 -0
  2. data/README.rdoc +124 -0
  3. data/Version +1 -0
  4. data/ext/geos_c_impl/extconf.rb +72 -0
  5. data/ext/geos_c_impl/factory.c +468 -0
  6. data/ext/geos_c_impl/factory.h +217 -0
  7. data/ext/geos_c_impl/geometry.c +644 -0
  8. data/ext/geos_c_impl/geometry.h +65 -0
  9. data/ext/geos_c_impl/geometry_collection.c +580 -0
  10. data/ext/geos_c_impl/geometry_collection.h +79 -0
  11. data/ext/geos_c_impl/globals.h +58 -0
  12. data/ext/geos_c_impl/line_string.c +468 -0
  13. data/ext/geos_c_impl/line_string.h +74 -0
  14. data/ext/geos_c_impl/main.c +65 -0
  15. data/ext/geos_c_impl/point.c +201 -0
  16. data/ext/geos_c_impl/point.h +77 -0
  17. data/ext/geos_c_impl/polygon.c +259 -0
  18. data/ext/geos_c_impl/polygon.h +76 -0
  19. data/ext/geos_c_impl/preface.h +42 -0
  20. data/lib/rgeo.rb +68 -0
  21. data/lib/rgeo/errors.rb +59 -0
  22. data/lib/rgeo/features.rb +89 -0
  23. data/lib/rgeo/features/curve.rb +155 -0
  24. data/lib/rgeo/features/factory.rb +191 -0
  25. data/lib/rgeo/features/geometry.rb +560 -0
  26. data/lib/rgeo/features/geometry_collection.rb +118 -0
  27. data/lib/rgeo/features/line.rb +65 -0
  28. data/lib/rgeo/features/line_string.rb +101 -0
  29. data/lib/rgeo/features/linear_ring.rb +65 -0
  30. data/lib/rgeo/features/multi_curve.rb +112 -0
  31. data/lib/rgeo/features/multi_line_string.rb +65 -0
  32. data/lib/rgeo/features/multi_point.rb +72 -0
  33. data/lib/rgeo/features/multi_polygon.rb +96 -0
  34. data/lib/rgeo/features/multi_surface.rb +115 -0
  35. data/lib/rgeo/features/point.rb +97 -0
  36. data/lib/rgeo/features/polygon.rb +141 -0
  37. data/lib/rgeo/features/surface.rb +121 -0
  38. data/lib/rgeo/geo_json.rb +58 -0
  39. data/lib/rgeo/geo_json/coder.rb +305 -0
  40. data/lib/rgeo/geo_json/entities.rb +284 -0
  41. data/lib/rgeo/geo_json/interface.rb +95 -0
  42. data/lib/rgeo/geography.rb +75 -0
  43. data/lib/rgeo/geography/common/geometry_collection_methods.rb +206 -0
  44. data/lib/rgeo/geography/common/geometry_methods.rb +92 -0
  45. data/lib/rgeo/geography/common/helper.rb +102 -0
  46. data/lib/rgeo/geography/common/line_string_methods.rb +187 -0
  47. data/lib/rgeo/geography/common/point_methods.rb +149 -0
  48. data/lib/rgeo/geography/common/polygon_methods.rb +122 -0
  49. data/lib/rgeo/geography/factories.rb +136 -0
  50. data/lib/rgeo/geography/factory.rb +246 -0
  51. data/lib/rgeo/geography/projected_window.rb +467 -0
  52. data/lib/rgeo/geography/simple_mercator/feature_classes.rb +320 -0
  53. data/lib/rgeo/geography/simple_mercator/feature_methods.rb +291 -0
  54. data/lib/rgeo/geography/simple_mercator/projector.rb +116 -0
  55. data/lib/rgeo/geography/simple_spherical/calculations.rb +70 -0
  56. data/lib/rgeo/geography/simple_spherical/geometry_collection_impl.rb +66 -0
  57. data/lib/rgeo/geography/simple_spherical/geometry_methods.rb +59 -0
  58. data/lib/rgeo/geography/simple_spherical/line_string_impl.rb +104 -0
  59. data/lib/rgeo/geography/simple_spherical/multi_line_string_impl.rb +67 -0
  60. data/lib/rgeo/geography/simple_spherical/multi_point_impl.rb +67 -0
  61. data/lib/rgeo/geography/simple_spherical/multi_polygon_impl.rb +67 -0
  62. data/lib/rgeo/geography/simple_spherical/point_impl.rb +85 -0
  63. data/lib/rgeo/geography/simple_spherical/polygon_impl.rb +66 -0
  64. data/lib/rgeo/geos.rb +72 -0
  65. data/lib/rgeo/geos/factory.rb +260 -0
  66. data/lib/rgeo/geos/impl_additions.rb +57 -0
  67. data/lib/rgeo/geos/interface.rb +74 -0
  68. data/lib/rgeo/version.rb +52 -0
  69. data/tests/geos/tc_factory.rb +91 -0
  70. data/tests/geos/tc_geometry_collection.rb +226 -0
  71. data/tests/geos/tc_line_string.rb +310 -0
  72. data/tests/geos/tc_misc.rb +72 -0
  73. data/tests/geos/tc_multi_line_string.rb +211 -0
  74. data/tests/geos/tc_multi_point.rb +202 -0
  75. data/tests/geos/tc_multi_polygon.rb +210 -0
  76. data/tests/geos/tc_point.rb +305 -0
  77. data/tests/geos/tc_polygon.rb +240 -0
  78. data/tests/simple_mercator/tc_point.rb +303 -0
  79. data/tests/simple_mercator/tc_window.rb +219 -0
  80. data/tests/tc_geojson.rb +230 -0
  81. data/tests/tc_oneoff.rb +61 -0
  82. metadata +162 -0
@@ -0,0 +1,79 @@
1
+ /*
2
+ -----------------------------------------------------------------------------
3
+
4
+ Geometry collection methods for GEOS wrapper
5
+
6
+ -----------------------------------------------------------------------------
7
+ Copyright 2010 Daniel Azuma
8
+
9
+ All rights reserved.
10
+
11
+ Redistribution and use in source and binary forms, with or without
12
+ modification, are permitted provided that the following conditions are met:
13
+
14
+ * Redistributions of source code must retain the above copyright notice,
15
+ this list of conditions and the following disclaimer.
16
+ * Redistributions in binary form must reproduce the above copyright notice,
17
+ this list of conditions and the following disclaimer in the documentation
18
+ and/or other materials provided with the distribution.
19
+ * Neither the name of the copyright holder, nor the names of any other
20
+ contributors to this software, may be used to endorse or promote products
21
+ derived from this software without specific prior written permission.
22
+
23
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33
+ POSSIBILITY OF SUCH DAMAGE.
34
+ -----------------------------------------------------------------------------
35
+ */
36
+
37
+
38
+ #ifndef RGEO_GEOS_GEOMETRY_COLLECTION_INCLUDED
39
+ #define RGEO_GEOS_GEOMETRY_COLLECTION_INCLUDED
40
+
41
+ #include <ruby.h>
42
+ #include <geos_c.h>
43
+
44
+ #include "factory.h"
45
+
46
+ #ifdef __cplusplus
47
+ extern "C" {
48
+ #if 0
49
+ }
50
+ #endif
51
+ #endif
52
+
53
+
54
+ /*
55
+ Initializes the geometry collection module. This should be called after
56
+ the geometry module is initialized.
57
+ */
58
+ void rgeo_init_geos_geometry_collection(RGeo_Globals* globals);
59
+
60
+ /*
61
+ Comopares the contents of two geometry collections. Does not test the
62
+ types of the collections themselves, but tests the types, values, and
63
+ contents of all the contents. The two given geometries MUST be
64
+ collection types-- i.e. GeometryCollection, MultiPoint, MultiLineString,
65
+ or MultiPolygon.
66
+ Returns Qtrue if the contents of the two geometry collections are equal,
67
+ Qfalse if they are inequal, or Qnil if an error occurs.
68
+ */
69
+ VALUE rgeo_geos_geometry_collections_eql(GEOSContextHandle_t context, const GEOSGeometry* geom1, const GEOSGeometry* geom2);
70
+
71
+
72
+ #ifdef __cplusplus
73
+ #if 0
74
+ {
75
+ #endif
76
+ }
77
+ #endif
78
+
79
+ #endif
@@ -0,0 +1,58 @@
1
+ /*
2
+ -----------------------------------------------------------------------------
3
+
4
+ Global data structure for GEOS wrapper
5
+
6
+ -----------------------------------------------------------------------------
7
+ Copyright 2010 Daniel Azuma
8
+
9
+ All rights reserved.
10
+
11
+ Redistribution and use in source and binary forms, with or without
12
+ modification, are permitted provided that the following conditions are met:
13
+
14
+ * Redistributions of source code must retain the above copyright notice,
15
+ this list of conditions and the following disclaimer.
16
+ * Redistributions in binary form must reproduce the above copyright notice,
17
+ this list of conditions and the following disclaimer in the documentation
18
+ and/or other materials provided with the distribution.
19
+ * Neither the name of the copyright holder, nor the names of any other
20
+ contributors to this software, may be used to endorse or promote products
21
+ derived from this software without specific prior written permission.
22
+
23
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33
+ POSSIBILITY OF SUCH DAMAGE.
34
+ -----------------------------------------------------------------------------
35
+ */
36
+
37
+
38
+ #ifndef RGEO_GEOS_GLOBALS_INCLUDED
39
+ #define RGEO_GEOS_GLOBALS_INCLUDED
40
+
41
+ #include <ruby.h>
42
+
43
+ #ifdef __cplusplus
44
+ extern "C" {
45
+ #if 0
46
+ }
47
+ #endif
48
+ #endif
49
+
50
+
51
+ #ifdef __cplusplus
52
+ #if 0
53
+ {
54
+ #endif
55
+ }
56
+ #endif
57
+
58
+ #endif
@@ -0,0 +1,468 @@
1
+ /*
2
+ -----------------------------------------------------------------------------
3
+
4
+ Line string methods for GEOS wrapper
5
+
6
+ -----------------------------------------------------------------------------
7
+ Copyright 2010 Daniel Azuma
8
+
9
+ All rights reserved.
10
+
11
+ Redistribution and use in source and binary forms, with or without
12
+ modification, are permitted provided that the following conditions are met:
13
+
14
+ * Redistributions of source code must retain the above copyright notice,
15
+ this list of conditions and the following disclaimer.
16
+ * Redistributions in binary form must reproduce the above copyright notice,
17
+ this list of conditions and the following disclaimer in the documentation
18
+ and/or other materials provided with the distribution.
19
+ * Neither the name of the copyright holder, nor the names of any other
20
+ contributors to this software, may be used to endorse or promote products
21
+ derived from this software without specific prior written permission.
22
+
23
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33
+ POSSIBILITY OF SUCH DAMAGE.
34
+ -----------------------------------------------------------------------------
35
+ */
36
+
37
+
38
+ #include "preface.h"
39
+
40
+ #ifdef RGEO_GEOS_SUPPORTED
41
+
42
+ #include <string.h>
43
+ #include <ruby.h>
44
+ #include <geos_c.h>
45
+
46
+ #include "factory.h"
47
+ #include "geometry.h"
48
+ #include "point.h"
49
+ #include "line_string.h"
50
+
51
+ #ifdef __cplusplus
52
+ extern "C" {
53
+ #if 0
54
+ }
55
+ #endif
56
+ #endif
57
+
58
+
59
+ static VALUE method_line_string_geometry_type(VALUE self)
60
+ {
61
+ VALUE result = Qnil;
62
+ const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
63
+ if (self_geom) {
64
+ result = rb_const_get_at(RGEO_GLOBALS_FROM_GEOMETRY(self)->features_module, rb_intern("LineString"));
65
+ }
66
+ return result;
67
+ }
68
+
69
+
70
+ static VALUE method_linear_ring_geometry_type(VALUE self)
71
+ {
72
+ VALUE result = Qnil;
73
+ const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
74
+ if (self_geom) {
75
+ result = rb_const_get_at(RGEO_GLOBALS_FROM_GEOMETRY(self)->features_module, rb_intern("LinearRing"));
76
+ }
77
+ return result;
78
+ }
79
+
80
+
81
+ static VALUE method_line_geometry_type(VALUE self)
82
+ {
83
+ VALUE result = Qnil;
84
+ const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
85
+ if (self_geom) {
86
+ result = rb_const_get_at(RGEO_GLOBALS_FROM_GEOMETRY(self)->features_module, rb_intern("Line"));
87
+ }
88
+ return result;
89
+ }
90
+
91
+
92
+ static VALUE method_line_string_cast(VALUE self, VALUE type)
93
+ {
94
+ VALUE result = Qnil;
95
+ const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
96
+ if (self_geom) {
97
+ VALUE type_name = rb_funcall(type, rb_intern("name"), 0);
98
+ char* new_type_str = StringValuePtr(type_name);
99
+ VALUE klass = Qnil;
100
+ char is_ring = 0;
101
+ if (strcmp(new_type_str, "Line") == 0) {
102
+ if (GEOSGetNumCoordinates_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom) == 2) {
103
+ klass = rb_const_get_at(RGEO_GLOBALS_FROM_GEOMETRY(self)->geos_module, rb_intern("LineImpl"));
104
+ }
105
+ }
106
+ else if (strcmp(new_type_str, "LinearRing") == 0) {
107
+ klass = rb_const_get_at(RGEO_GLOBALS_FROM_GEOMETRY(self)->geos_module, rb_intern("LinearRingImpl"));
108
+ is_ring = 1;
109
+ }
110
+ else if (strcmp(new_type_str, "LineString") == 0) {
111
+ klass = rb_const_get_at(RGEO_GLOBALS_FROM_GEOMETRY(self)->geos_module, rb_intern("LineStringImpl"));
112
+ }
113
+ if (!NIL_P(klass)) {
114
+ const GEOSCoordSequence* self_coord_seq = GEOSGeom_getCoordSeq_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom);
115
+ if (self_coord_seq) {
116
+ GEOSCoordSequence* coord_seq = GEOSCoordSeq_clone_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_coord_seq);
117
+ if (coord_seq) {
118
+ GEOSGeometry* geom = is_ring ? GEOSGeom_createLinearRing_r(RGEO_CONTEXT_FROM_GEOMETRY(self), coord_seq) : GEOSGeom_createLineString_r(RGEO_CONTEXT_FROM_GEOMETRY(self), coord_seq);
119
+ if (geom) {
120
+ result = rgeo_wrap_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), geom, klass);
121
+ }
122
+ }
123
+ }
124
+ }
125
+ if (NIL_P(result)) {
126
+ result = rb_call_super(1, &type);
127
+ }
128
+ }
129
+ return result;
130
+ }
131
+
132
+
133
+ static VALUE method_line_string_length(VALUE self)
134
+ {
135
+ VALUE result = Qnil;
136
+ const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
137
+ if (self_geom) {
138
+ double len;
139
+ if (GEOSLength_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom, &len)) {
140
+ result = rb_float_new(len);
141
+ }
142
+ }
143
+ return result;
144
+ }
145
+
146
+
147
+ static VALUE method_line_string_num_points(VALUE self)
148
+ {
149
+ VALUE result = Qnil;
150
+ const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
151
+ if (self_geom) {
152
+ result = INT2NUM(GEOSGetNumCoordinates_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom));
153
+ }
154
+ return result;
155
+ }
156
+
157
+
158
+ static VALUE method_line_string_point_n(VALUE self, VALUE n)
159
+ {
160
+ VALUE result = Qnil;
161
+ const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
162
+ if (self_geom) {
163
+ const GEOSCoordSequence* coord_seq = GEOSGeom_getCoordSeq_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom);
164
+ if (coord_seq) {
165
+ char has_z = GEOSHasZ_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom) == 1 ? 1 : 0;
166
+ unsigned int i = NUM2INT(n);
167
+ double x, y, z;
168
+ if (GEOSCoordSeq_getX_r(RGEO_CONTEXT_FROM_GEOMETRY(self), coord_seq, i, &x)) {
169
+ if (GEOSCoordSeq_getY_r(RGEO_CONTEXT_FROM_GEOMETRY(self), coord_seq, i, &y)) {
170
+ if (has_z) {
171
+ if (GEOSCoordSeq_getZ_r(RGEO_CONTEXT_FROM_GEOMETRY(self), coord_seq, i, &z)) {
172
+ result = rgeo_create_geos_point_3d(RGEO_FACTORY_FROM_GEOMETRY(self), x, y, z);
173
+ }
174
+ }
175
+ else {
176
+ result = rgeo_create_geos_point_2d(RGEO_FACTORY_FROM_GEOMETRY(self), x, y);
177
+ }
178
+ }
179
+ }
180
+ }
181
+ }
182
+ return result;
183
+ }
184
+
185
+
186
+ static VALUE method_line_string_points(VALUE self)
187
+ {
188
+ VALUE result = Qnil;
189
+ const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
190
+ if (self_geom) {
191
+ const GEOSCoordSequence* coord_seq = GEOSGeom_getCoordSeq_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom);
192
+ if (coord_seq) {
193
+ char has_z = GEOSHasZ_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom) == 1 ? 1 : 0;
194
+ int count = GEOSGetNumCoordinates_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom);
195
+ result = rb_ary_new2(count);
196
+ double x, y, z;
197
+ int i;
198
+ for (i=0; i<count; ++i) {
199
+ if (GEOSCoordSeq_getX_r(RGEO_CONTEXT_FROM_GEOMETRY(self), coord_seq, i, &x)) {
200
+ if (GEOSCoordSeq_getY_r(RGEO_CONTEXT_FROM_GEOMETRY(self), coord_seq, i, &y)) {
201
+ if (has_z) {
202
+ if (GEOSCoordSeq_getZ_r(RGEO_CONTEXT_FROM_GEOMETRY(self), coord_seq, i, &z)) {
203
+ rb_ary_store(result, i, rgeo_create_geos_point_3d(RGEO_FACTORY_FROM_GEOMETRY(self), x, y, z));
204
+ }
205
+ }
206
+ else {
207
+ rb_ary_store(result, i, rgeo_create_geos_point_2d(RGEO_FACTORY_FROM_GEOMETRY(self), x, y));
208
+ }
209
+ }
210
+ }
211
+ }
212
+ }
213
+ }
214
+ return result;
215
+ }
216
+
217
+
218
+ static VALUE method_line_string_start_point(VALUE self)
219
+ {
220
+ return method_line_string_point_n(self, 0);
221
+ }
222
+
223
+
224
+ static VALUE method_line_string_end_point(VALUE self)
225
+ {
226
+ VALUE result = Qnil;
227
+ const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
228
+ if (self_geom) {
229
+ unsigned int n = GEOSGetNumCoordinates_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom);
230
+ if (n > 0) {
231
+ result = method_line_string_point_n(self, n-1);
232
+ }
233
+ }
234
+ return result;
235
+ }
236
+
237
+
238
+ static VALUE method_line_string_is_closed(VALUE self)
239
+ {
240
+ VALUE result = Qnil;
241
+ const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
242
+ if (self_geom) {
243
+ result = rgeo_is_geos_line_string_closed(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom);
244
+ }
245
+ return result;
246
+ }
247
+
248
+
249
+ static VALUE method_line_string_is_ring(VALUE self)
250
+ {
251
+ VALUE result = Qnil;
252
+ const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
253
+ if (self_geom) {
254
+ char val = GEOSisRing_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom);
255
+ if (val == 0) {
256
+ result = Qfalse;
257
+ }
258
+ else if (val == 1) {
259
+ result = Qtrue;
260
+ }
261
+ }
262
+ return result;
263
+ }
264
+
265
+
266
+ static VALUE method_line_string_eql(VALUE self, VALUE rhs)
267
+ {
268
+ VALUE result = rgeo_geos_klasses_and_factories_eql(self, rhs);
269
+ if (RTEST(result)) {
270
+ result = rgeo_geos_coordseqs_eql(RGEO_CONTEXT_FROM_GEOMETRY(self), RGEO_GET_GEOS_GEOMETRY(self), RGEO_GET_GEOS_GEOMETRY(rhs));
271
+ }
272
+ return result;
273
+ }
274
+
275
+
276
+ static GEOSCoordSequence* coord_seq_from_array(GEOSContextHandle_t context, VALUE array)
277
+ {
278
+ Check_Type(array, T_ARRAY);
279
+ unsigned int len = (unsigned int)RARRAY_LEN(array);
280
+ char has_z = 0;
281
+ unsigned int i;
282
+ for (i=0; i<len; ++i) {
283
+ const GEOSGeometry* entry_geom = rgeo_get_geos_geometry_safe(rb_ary_entry(array, i));
284
+ if (!entry_geom || GEOSGeomTypeId_r(context, entry_geom) != GEOS_POINT) {
285
+ return NULL;
286
+ }
287
+ if (GEOSHasZ_r(context, entry_geom) == 1) {
288
+ has_z = 1;
289
+ i = len;
290
+ }
291
+ }
292
+ GEOSCoordSequence* coord_seq = GEOSCoordSeq_create_r(context, len, has_z ? 3 : 2);
293
+ if (coord_seq) {
294
+ for (i=0; i<len; ++i) {
295
+ const GEOSCoordSequence* cs = GEOSGeom_getCoordSeq_r(context, RGEO_GET_GEOS_GEOMETRY(rb_ary_entry(array, i)));
296
+ double x;
297
+ if (GEOSCoordSeq_getX_r(context, cs, 0, &x)) {
298
+ GEOSCoordSeq_setX_r(context, coord_seq, i, x);
299
+ }
300
+ if (GEOSCoordSeq_getY_r(context, cs, 0, &x)) {
301
+ GEOSCoordSeq_setY_r(context, coord_seq, i, x);
302
+ }
303
+ if (has_z && GEOSCoordSeq_getZ_r(context, cs, 0, &x)) {
304
+ GEOSCoordSeq_setZ_r(context, coord_seq, i, x);
305
+ }
306
+ }
307
+ }
308
+ return coord_seq;
309
+ }
310
+
311
+
312
+ static VALUE cmethod_create_line_string(VALUE module, VALUE factory, VALUE array)
313
+ {
314
+ VALUE result = Qnil;
315
+ GEOSCoordSequence* coord_seq = coord_seq_from_array(RGEO_CONTEXT_FROM_FACTORY(factory), array);
316
+ if (coord_seq) {
317
+ GEOSGeometry* geom = GEOSGeom_createLineString_r(RGEO_CONTEXT_FROM_FACTORY(factory), coord_seq);
318
+ if (geom) {
319
+ result = rgeo_wrap_geos_geometry(factory, geom, rb_const_get_at(RGEO_GLOBALS_FROM_FACTORY(factory)->geos_module, rb_intern("LineStringImpl")));
320
+ }
321
+ }
322
+ return result;
323
+ }
324
+
325
+
326
+ static VALUE cmethod_create_linear_ring(VALUE module, VALUE factory, VALUE array)
327
+ {
328
+ VALUE result = Qnil;
329
+ GEOSCoordSequence* coord_seq = coord_seq_from_array(RGEO_CONTEXT_FROM_FACTORY(factory), array);
330
+ if (coord_seq) {
331
+ GEOSGeometry* geom = GEOSGeom_createLinearRing_r(RGEO_CONTEXT_FROM_FACTORY(factory), coord_seq);
332
+ if (geom) {
333
+ result = rgeo_wrap_geos_geometry(factory, geom, rb_const_get_at(RGEO_GLOBALS_FROM_FACTORY(factory)->geos_module, rb_intern("LinearRingImpl")));
334
+ }
335
+ }
336
+ return result;
337
+ }
338
+
339
+
340
+ static VALUE cmethod_create_line(VALUE module, VALUE factory, VALUE start, VALUE end)
341
+ {
342
+ VALUE result = Qnil;
343
+ char has_z = 0;
344
+
345
+ const GEOSGeometry* entry_geom;
346
+ entry_geom = rgeo_get_geos_geometry_safe(start);
347
+ if (!entry_geom || GEOSGeomTypeId_r(RGEO_CONTEXT_FROM_FACTORY(factory), entry_geom) != GEOS_POINT) {
348
+ return Qnil;
349
+ }
350
+ if (GEOSHasZ_r(RGEO_CONTEXT_FROM_FACTORY(factory), entry_geom) == 1) {
351
+ has_z = 1;
352
+ }
353
+ entry_geom = rgeo_get_geos_geometry_safe(end);
354
+ if (!entry_geom || GEOSGeomTypeId_r(RGEO_CONTEXT_FROM_FACTORY(factory), entry_geom) != GEOS_POINT) {
355
+ return Qnil;
356
+ }
357
+ if (GEOSHasZ_r(RGEO_CONTEXT_FROM_FACTORY(factory), entry_geom) == 1) {
358
+ has_z = 1;
359
+ }
360
+
361
+ GEOSCoordSequence* coord_seq = GEOSCoordSeq_create_r(RGEO_CONTEXT_FROM_FACTORY(factory), 2, has_z ? 3 : 2);
362
+ if (coord_seq) {
363
+ const GEOSCoordSequence* cs;
364
+ double x;
365
+ cs = GEOSGeom_getCoordSeq_r(RGEO_CONTEXT_FROM_FACTORY(factory), RGEO_GET_GEOS_GEOMETRY(start));
366
+ if (GEOSCoordSeq_getX_r(RGEO_CONTEXT_FROM_FACTORY(factory), cs, 0, &x)) {
367
+ GEOSCoordSeq_setX_r(RGEO_CONTEXT_FROM_FACTORY(factory), coord_seq, 0, x);
368
+ }
369
+ if (GEOSCoordSeq_getY_r(RGEO_CONTEXT_FROM_FACTORY(factory), cs, 0, &x)) {
370
+ GEOSCoordSeq_setY_r(RGEO_CONTEXT_FROM_FACTORY(factory), coord_seq, 0, x);
371
+ }
372
+ if (has_z && GEOSCoordSeq_getZ_r(RGEO_CONTEXT_FROM_FACTORY(factory), cs, 0, &x)) {
373
+ GEOSCoordSeq_setZ_r(RGEO_CONTEXT_FROM_FACTORY(factory), coord_seq, 0, x);
374
+ }
375
+ cs = GEOSGeom_getCoordSeq_r(RGEO_CONTEXT_FROM_FACTORY(factory), RGEO_GET_GEOS_GEOMETRY(end));
376
+ if (GEOSCoordSeq_getX_r(RGEO_CONTEXT_FROM_FACTORY(factory), cs, 0, &x)) {
377
+ GEOSCoordSeq_setX_r(RGEO_CONTEXT_FROM_FACTORY(factory), coord_seq, 1, x);
378
+ }
379
+ if (GEOSCoordSeq_getY_r(RGEO_CONTEXT_FROM_FACTORY(factory), cs, 0, &x)) {
380
+ GEOSCoordSeq_setY_r(RGEO_CONTEXT_FROM_FACTORY(factory), coord_seq, 1, x);
381
+ }
382
+ if (has_z && GEOSCoordSeq_getZ_r(RGEO_CONTEXT_FROM_FACTORY(factory), cs, 0, &x)) {
383
+ GEOSCoordSeq_setZ_r(RGEO_CONTEXT_FROM_FACTORY(factory), coord_seq, 1, x);
384
+ }
385
+ GEOSGeometry* geom = GEOSGeom_createLineString_r(RGEO_CONTEXT_FROM_FACTORY(factory), coord_seq);
386
+ if (geom) {
387
+ result = rgeo_wrap_geos_geometry(factory, geom, rb_const_get_at(RGEO_GLOBALS_FROM_FACTORY(factory)->geos_module, rb_intern("LineImpl")));
388
+ }
389
+ }
390
+ return result;
391
+ }
392
+
393
+
394
+ void rgeo_init_geos_line_string(RGeo_Globals* globals)
395
+ {
396
+ VALUE geos_line_string_class = rb_define_class_under(globals->geos_module, "LineStringImpl", rb_const_get_at(globals->geos_module, rb_intern("GeometryImpl")));
397
+ VALUE geos_linear_ring_class = rb_define_class_under(globals->geos_module, "LinearRingImpl", geos_line_string_class);
398
+ VALUE geos_line_class = rb_define_class_under(globals->geos_module, "LineImpl", geos_line_string_class);
399
+
400
+ rb_define_module_function(geos_line_string_class, "create", cmethod_create_line_string, 2);
401
+ rb_define_method(geos_line_string_class, "eql?", method_line_string_eql, 1);
402
+ rb_define_method(geos_line_string_class, "geometry_type", method_line_string_geometry_type, 0);
403
+ rb_define_method(geos_line_string_class, "cast", method_line_string_cast, 1);
404
+ rb_define_method(geos_line_string_class, "length", method_line_string_length, 0);
405
+ rb_define_method(geos_line_string_class, "num_points", method_line_string_num_points, 0);
406
+ rb_define_method(geos_line_string_class, "point_n", method_line_string_point_n, 1);
407
+ rb_define_method(geos_line_string_class, "points", method_line_string_points, 0);
408
+ rb_define_method(geos_line_string_class, "start_point", method_line_string_start_point, 0);
409
+ rb_define_method(geos_line_string_class, "end_point", method_line_string_end_point, 0);
410
+ rb_define_method(geos_line_string_class, "is_closed?", method_line_string_is_closed, 0);
411
+ rb_define_method(geos_line_string_class, "is_ring?", method_line_string_is_ring, 0);
412
+
413
+ rb_define_module_function(geos_linear_ring_class, "create", cmethod_create_linear_ring, 2);
414
+ rb_define_method(geos_linear_ring_class, "geometry_type", method_linear_ring_geometry_type, 0);
415
+
416
+ rb_define_module_function(geos_line_class, "create", cmethod_create_line, 3);
417
+ rb_define_method(geos_line_class, "geometry_type", method_line_geometry_type, 0);
418
+ }
419
+
420
+
421
+ VALUE rgeo_is_geos_line_string_closed(GEOSContextHandle_t context, const GEOSGeometry* geom)
422
+ {
423
+ char result = Qnil;
424
+ unsigned int n = GEOSGetNumCoordinates_r(context, geom);
425
+ if (n > 0) {
426
+ double x1, x2, y1, y2, z1, z2;
427
+ const GEOSCoordSequence* coord_seq = GEOSGeom_getCoordSeq_r(context, geom);
428
+ if (GEOSCoordSeq_getX_r(context, coord_seq, 0, &x1)) {
429
+ if (GEOSCoordSeq_getX_r(context, coord_seq, n-1, &x2)) {
430
+ if (x1 == x2) {
431
+ if (GEOSCoordSeq_getY_r(context, coord_seq, 0, &y1)) {
432
+ if (GEOSCoordSeq_getY_r(context, coord_seq, n-2, &y2)) {
433
+ if (y1 == y2) {
434
+ if (GEOSHasZ_r(context, geom) == 1) {
435
+ if (GEOSCoordSeq_getZ_r(context, coord_seq, 0, &z1)) {
436
+ if (GEOSCoordSeq_getZ_r(context, coord_seq, 0, &z2)) {
437
+ result = z1 == z2 ? Qtrue : Qfalse;
438
+ }
439
+ }
440
+ }
441
+ else { // Doesn't have Z coordinate
442
+ result = Qtrue;
443
+ }
444
+ }
445
+ else { // Y coordinates are different
446
+ result = Qfalse;
447
+ }
448
+ }
449
+ }
450
+ }
451
+ else { // X coordinates are different
452
+ result = Qfalse;
453
+ }
454
+ }
455
+ }
456
+ }
457
+ return result;
458
+ }
459
+
460
+
461
+ #ifdef __cplusplus
462
+ #if 0
463
+ {
464
+ #endif
465
+ }
466
+ #endif
467
+
468
+ #endif