rgeo 2.3.1 → 3.0.1
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.
- checksums.yaml +4 -4
- data/.yardopts +6 -0
- data/README.md +23 -14
- data/ext/geos_c_impl/analysis.c +30 -25
- data/ext/geos_c_impl/analysis.h +8 -7
- data/ext/geos_c_impl/coordinates.c +27 -21
- data/ext/geos_c_impl/coordinates.h +5 -2
- data/ext/geos_c_impl/errors.c +19 -10
- data/ext/geos_c_impl/errors.h +11 -4
- data/ext/geos_c_impl/extconf.rb +42 -28
- data/ext/geos_c_impl/factory.c +540 -451
- data/ext/geos_c_impl/factory.h +105 -95
- data/ext/geos_c_impl/geometry.c +593 -387
- data/ext/geos_c_impl/geometry.h +10 -5
- data/ext/geos_c_impl/geometry_collection.c +306 -339
- data/ext/geos_c_impl/geometry_collection.h +6 -20
- data/ext/geos_c_impl/globals.c +169 -0
- data/ext/geos_c_impl/globals.h +46 -0
- data/ext/geos_c_impl/line_string.c +271 -231
- data/ext/geos_c_impl/line_string.h +5 -8
- data/ext/geos_c_impl/main.c +16 -16
- data/ext/geos_c_impl/point.c +65 -67
- data/ext/geos_c_impl/point.h +4 -7
- data/ext/geos_c_impl/polygon.c +137 -135
- data/ext/geos_c_impl/polygon.h +11 -11
- data/ext/geos_c_impl/preface.h +16 -10
- data/ext/geos_c_impl/ruby_more.c +67 -0
- data/ext/geos_c_impl/ruby_more.h +25 -0
- data/lib/rgeo/cartesian/analysis.rb +5 -3
- data/lib/rgeo/cartesian/bounding_box.rb +74 -79
- data/lib/rgeo/cartesian/calculations.rb +64 -33
- data/lib/rgeo/cartesian/factory.rb +57 -102
- data/lib/rgeo/cartesian/feature_classes.rb +68 -46
- data/lib/rgeo/cartesian/feature_methods.rb +67 -25
- data/lib/rgeo/cartesian/interface.rb +6 -41
- data/lib/rgeo/cartesian/planar_graph.rb +373 -0
- data/lib/rgeo/cartesian/sweepline_intersector.rb +147 -0
- data/lib/rgeo/cartesian/valid_op.rb +69 -0
- data/lib/rgeo/cartesian.rb +3 -0
- data/lib/rgeo/coord_sys/cs/entities.rb +303 -99
- data/lib/rgeo/coord_sys/cs/factories.rb +0 -2
- data/lib/rgeo/coord_sys/cs/wkt_parser.rb +90 -42
- data/lib/rgeo/coord_sys.rb +1 -20
- data/lib/rgeo/error.rb +15 -0
- data/lib/rgeo/feature/curve.rb +0 -11
- data/lib/rgeo/feature/factory.rb +26 -36
- data/lib/rgeo/feature/factory_generator.rb +6 -14
- data/lib/rgeo/feature/geometry.rb +146 -66
- data/lib/rgeo/feature/geometry_collection.rb +16 -9
- data/lib/rgeo/feature/line_string.rb +4 -5
- data/lib/rgeo/feature/linear_ring.rb +0 -1
- data/lib/rgeo/feature/multi_curve.rb +0 -6
- data/lib/rgeo/feature/multi_surface.rb +3 -4
- data/lib/rgeo/feature/point.rb +4 -5
- data/lib/rgeo/feature/polygon.rb +1 -2
- data/lib/rgeo/feature/surface.rb +3 -4
- data/lib/rgeo/feature/types.rb +69 -85
- data/lib/rgeo/geographic/factory.rb +98 -125
- data/lib/rgeo/geographic/interface.rb +69 -166
- data/lib/rgeo/geographic/projected_feature_classes.rb +21 -9
- data/lib/rgeo/geographic/projected_feature_methods.rb +67 -42
- data/lib/rgeo/geographic/projected_window.rb +36 -22
- data/lib/rgeo/geographic/{proj4_projector.rb → projector.rb} +3 -5
- data/lib/rgeo/geographic/simple_mercator_projector.rb +26 -25
- data/lib/rgeo/geographic/spherical_feature_classes.rb +29 -9
- data/lib/rgeo/geographic/spherical_feature_methods.rb +86 -9
- data/lib/rgeo/geographic/spherical_math.rb +17 -20
- data/lib/rgeo/geographic.rb +1 -1
- data/lib/rgeo/geos/capi_factory.rb +87 -158
- data/lib/rgeo/geos/capi_feature_classes.rb +50 -36
- data/lib/rgeo/geos/ffi_factory.rb +105 -173
- data/lib/rgeo/geos/ffi_feature_classes.rb +34 -10
- data/lib/rgeo/geos/ffi_feature_methods.rb +105 -127
- data/lib/rgeo/geos/interface.rb +20 -59
- data/lib/rgeo/geos/utils.rb +5 -5
- data/lib/rgeo/geos/zm_factory.rb +53 -95
- data/lib/rgeo/geos/zm_feature_methods.rb +30 -33
- data/lib/rgeo/geos.rb +8 -8
- data/lib/rgeo/impl_helper/basic_geometry_collection_methods.rb +9 -22
- data/lib/rgeo/impl_helper/basic_geometry_methods.rb +1 -2
- data/lib/rgeo/impl_helper/basic_line_string_methods.rb +28 -56
- data/lib/rgeo/impl_helper/basic_point_methods.rb +2 -14
- data/lib/rgeo/impl_helper/basic_polygon_methods.rb +17 -26
- data/lib/rgeo/impl_helper/utils.rb +21 -0
- data/lib/rgeo/impl_helper/valid_op.rb +350 -0
- data/lib/rgeo/impl_helper/validity_check.rb +139 -0
- data/lib/rgeo/impl_helper.rb +1 -0
- data/lib/rgeo/version.rb +1 -1
- data/lib/rgeo/wkrep/wkb_generator.rb +73 -63
- data/lib/rgeo/wkrep/wkb_parser.rb +33 -31
- data/lib/rgeo/wkrep/wkt_generator.rb +52 -45
- data/lib/rgeo/wkrep/wkt_parser.rb +48 -35
- data/lib/rgeo.rb +1 -3
- metadata +50 -13
- data/lib/rgeo/coord_sys/srs_database/entry.rb +0 -107
- data/lib/rgeo/coord_sys/srs_database/sr_org.rb +0 -64
- data/lib/rgeo/coord_sys/srs_database/url_reader.rb +0 -65
data/ext/geos_c_impl/polygon.c
CHANGED
@@ -2,25 +2,24 @@
|
|
2
2
|
Polygon methods for GEOS wrapper
|
3
3
|
*/
|
4
4
|
|
5
|
-
|
6
5
|
#include "preface.h"
|
7
6
|
|
8
7
|
#ifdef RGEO_GEOS_SUPPORTED
|
9
8
|
|
10
|
-
#include <ruby.h>
|
11
9
|
#include <geos_c.h>
|
10
|
+
#include <ruby.h>
|
12
11
|
|
12
|
+
#include "coordinates.h"
|
13
13
|
#include "factory.h"
|
14
14
|
#include "geometry.h"
|
15
|
+
#include "globals.h"
|
15
16
|
#include "line_string.h"
|
16
17
|
#include "polygon.h"
|
17
18
|
|
18
|
-
#include "coordinates.h"
|
19
|
-
|
20
19
|
RGEO_BEGIN_C
|
21
20
|
|
22
|
-
|
23
|
-
|
21
|
+
static VALUE
|
22
|
+
method_polygon_eql(VALUE self, VALUE rhs)
|
24
23
|
{
|
25
24
|
VALUE result;
|
26
25
|
RGeo_GeometryData* self_data;
|
@@ -28,13 +27,14 @@ static VALUE method_polygon_eql(VALUE self, VALUE rhs)
|
|
28
27
|
result = rgeo_geos_klasses_and_factories_eql(self, rhs);
|
29
28
|
if (RTEST(result)) {
|
30
29
|
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
31
|
-
result =
|
30
|
+
result = rgeo_geos_geometries_strict_eql(self_data->geom,
|
31
|
+
RGEO_GEOMETRY_DATA_PTR(rhs)->geom);
|
32
32
|
}
|
33
33
|
return result;
|
34
34
|
}
|
35
35
|
|
36
|
-
|
37
|
-
|
36
|
+
static VALUE
|
37
|
+
method_polygon_hash(VALUE self)
|
38
38
|
{
|
39
39
|
st_index_t hash;
|
40
40
|
RGeo_GeometryData* self_data;
|
@@ -43,14 +43,13 @@ static VALUE method_polygon_hash(VALUE self)
|
|
43
43
|
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
44
44
|
factory = self_data->factory;
|
45
45
|
hash = rb_hash_start(0);
|
46
|
-
hash = rgeo_geos_objbase_hash(factory,
|
47
|
-
|
48
|
-
hash = rgeo_geos_polygon_hash(self_data->geos_context, self_data->geom, hash);
|
46
|
+
hash = rgeo_geos_objbase_hash(factory, rgeo_feature_polygon_module, hash);
|
47
|
+
hash = rgeo_geos_polygon_hash(self_data->geom, hash);
|
49
48
|
return LONG2FIX(rb_hash_end(hash));
|
50
49
|
}
|
51
50
|
|
52
|
-
|
53
|
-
|
51
|
+
static VALUE
|
52
|
+
method_polygon_geometry_type(VALUE self)
|
54
53
|
{
|
55
54
|
VALUE result;
|
56
55
|
RGeo_GeometryData* self_data;
|
@@ -58,13 +57,13 @@ static VALUE method_polygon_geometry_type(VALUE self)
|
|
58
57
|
result = Qnil;
|
59
58
|
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
60
59
|
if (self_data->geom) {
|
61
|
-
result =
|
60
|
+
result = rgeo_feature_polygon_module;
|
62
61
|
}
|
63
62
|
return result;
|
64
63
|
}
|
65
64
|
|
66
|
-
|
67
|
-
|
65
|
+
static VALUE
|
66
|
+
method_polygon_area(VALUE self)
|
68
67
|
{
|
69
68
|
VALUE result;
|
70
69
|
RGeo_GeometryData* self_data;
|
@@ -75,15 +74,15 @@ static VALUE method_polygon_area(VALUE self)
|
|
75
74
|
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
76
75
|
self_geom = self_data->geom;
|
77
76
|
if (self_geom) {
|
78
|
-
if (
|
77
|
+
if (GEOSArea(self_geom, &area)) {
|
79
78
|
result = rb_float_new(area);
|
80
79
|
}
|
81
80
|
}
|
82
81
|
return result;
|
83
82
|
}
|
84
83
|
|
85
|
-
|
86
|
-
|
84
|
+
static VALUE
|
85
|
+
method_polygon_centroid(VALUE self)
|
87
86
|
{
|
88
87
|
VALUE result;
|
89
88
|
RGeo_GeometryData* self_data;
|
@@ -93,13 +92,14 @@ static VALUE method_polygon_centroid(VALUE self)
|
|
93
92
|
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
94
93
|
self_geom = self_data->geom;
|
95
94
|
if (self_geom) {
|
96
|
-
result = rgeo_wrap_geos_geometry(
|
95
|
+
result = rgeo_wrap_geos_geometry(
|
96
|
+
self_data->factory, GEOSGetCentroid(self_geom), rgeo_geos_point_class);
|
97
97
|
}
|
98
98
|
return result;
|
99
99
|
}
|
100
100
|
|
101
|
-
|
102
|
-
|
101
|
+
static VALUE
|
102
|
+
method_polygon_point_on_surface(VALUE self)
|
103
103
|
{
|
104
104
|
VALUE result;
|
105
105
|
RGeo_GeometryData* self_data;
|
@@ -109,18 +109,18 @@ static VALUE method_polygon_point_on_surface(VALUE self)
|
|
109
109
|
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
110
110
|
self_geom = self_data->geom;
|
111
111
|
if (self_geom) {
|
112
|
-
result = rgeo_wrap_geos_geometry(
|
112
|
+
result = rgeo_wrap_geos_geometry(
|
113
|
+
self_data->factory, GEOSPointOnSurface(self_geom), rgeo_geos_point_class);
|
113
114
|
}
|
114
115
|
return result;
|
115
116
|
}
|
116
117
|
|
117
|
-
|
118
|
-
|
118
|
+
static VALUE
|
119
|
+
method_polygon_coordinates(VALUE self)
|
119
120
|
{
|
120
121
|
VALUE result = Qnil;
|
121
122
|
RGeo_GeometryData* self_data;
|
122
123
|
const GEOSGeometry* self_geom;
|
123
|
-
GEOSContextHandle_t self_context;
|
124
124
|
|
125
125
|
int zCoordinate;
|
126
126
|
|
@@ -128,14 +128,15 @@ static VALUE method_polygon_coordinates(VALUE self)
|
|
128
128
|
self_geom = self_data->geom;
|
129
129
|
|
130
130
|
if (self_geom) {
|
131
|
-
zCoordinate = RGEO_FACTORY_DATA_PTR(self_data->factory)->flags &
|
132
|
-
|
133
|
-
result = extract_points_from_polygon(
|
131
|
+
zCoordinate = RGEO_FACTORY_DATA_PTR(self_data->factory)->flags &
|
132
|
+
RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M;
|
133
|
+
result = extract_points_from_polygon(self_geom, zCoordinate);
|
134
134
|
}
|
135
135
|
return result;
|
136
136
|
}
|
137
137
|
|
138
|
-
static VALUE
|
138
|
+
static VALUE
|
139
|
+
method_polygon_exterior_ring(VALUE self)
|
139
140
|
{
|
140
141
|
VALUE result;
|
141
142
|
RGeo_GeometryData* self_data;
|
@@ -145,13 +146,15 @@ static VALUE method_polygon_exterior_ring(VALUE self)
|
|
145
146
|
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
146
147
|
self_geom = self_data->geom;
|
147
148
|
if (self_geom) {
|
148
|
-
result = rgeo_wrap_geos_geometry_clone(self_data->factory,
|
149
|
+
result = rgeo_wrap_geos_geometry_clone(self_data->factory,
|
150
|
+
GEOSGetExteriorRing(self_geom),
|
151
|
+
rgeo_geos_linear_ring_class);
|
149
152
|
}
|
150
153
|
return result;
|
151
154
|
}
|
152
155
|
|
153
|
-
|
154
|
-
|
156
|
+
static VALUE
|
157
|
+
method_polygon_num_interior_rings(VALUE self)
|
155
158
|
{
|
156
159
|
VALUE result;
|
157
160
|
RGeo_GeometryData* self_data;
|
@@ -162,7 +165,7 @@ static VALUE method_polygon_num_interior_rings(VALUE self)
|
|
162
165
|
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
163
166
|
self_geom = self_data->geom;
|
164
167
|
if (self_geom) {
|
165
|
-
num =
|
168
|
+
num = GEOSGetNumInteriorRings(self_geom);
|
166
169
|
if (num >= 0) {
|
167
170
|
result = INT2NUM(num);
|
168
171
|
}
|
@@ -170,187 +173,186 @@ static VALUE method_polygon_num_interior_rings(VALUE self)
|
|
170
173
|
return result;
|
171
174
|
}
|
172
175
|
|
173
|
-
|
174
|
-
|
176
|
+
static VALUE
|
177
|
+
method_polygon_interior_ring_n(VALUE self, VALUE n)
|
175
178
|
{
|
176
179
|
VALUE result;
|
177
180
|
RGeo_GeometryData* self_data;
|
178
181
|
const GEOSGeometry* self_geom;
|
179
182
|
int i;
|
180
|
-
GEOSContextHandle_t self_context;
|
181
183
|
int num;
|
182
184
|
|
183
185
|
result = Qnil;
|
184
186
|
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
185
187
|
self_geom = self_data->geom;
|
186
188
|
if (self_geom) {
|
187
|
-
i =
|
189
|
+
i = RB_NUM2INT(n);
|
188
190
|
if (i >= 0) {
|
189
|
-
|
190
|
-
num = GEOSGetNumInteriorRings_r(self_context, self_geom);
|
191
|
+
num = GEOSGetNumInteriorRings(self_geom);
|
191
192
|
if (i < num) {
|
192
|
-
result =
|
193
|
-
|
194
|
-
|
193
|
+
result =
|
194
|
+
rgeo_wrap_geos_geometry_clone(self_data->factory,
|
195
|
+
GEOSGetInteriorRingN(self_geom, i),
|
196
|
+
rgeo_geos_linear_ring_class);
|
195
197
|
}
|
196
198
|
}
|
197
199
|
}
|
198
200
|
return result;
|
199
201
|
}
|
200
202
|
|
201
|
-
|
202
|
-
|
203
|
+
static VALUE
|
204
|
+
method_polygon_interior_rings(VALUE self)
|
203
205
|
{
|
204
206
|
VALUE result;
|
205
207
|
RGeo_GeometryData* self_data;
|
206
208
|
const GEOSGeometry* self_geom;
|
207
|
-
GEOSContextHandle_t self_context;
|
208
209
|
int count;
|
209
210
|
VALUE factory;
|
210
|
-
VALUE linear_ring_class;
|
211
211
|
int i;
|
212
212
|
|
213
213
|
result = Qnil;
|
214
214
|
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
215
215
|
self_geom = self_data->geom;
|
216
216
|
if (self_geom) {
|
217
|
-
|
218
|
-
count = GEOSGetNumInteriorRings_r(self_context, self_geom);
|
217
|
+
count = GEOSGetNumInteriorRings(self_geom);
|
219
218
|
if (count >= 0) {
|
220
219
|
result = rb_ary_new2(count);
|
221
220
|
factory = self_data->factory;
|
222
|
-
|
223
|
-
|
224
|
-
|
221
|
+
for (i = 0; i < count; ++i) {
|
222
|
+
rb_ary_store(
|
223
|
+
result,
|
224
|
+
i,
|
225
|
+
rgeo_wrap_geos_geometry_clone(factory,
|
226
|
+
GEOSGetInteriorRingN(self_geom, i),
|
227
|
+
rgeo_geos_linear_ring_class));
|
225
228
|
}
|
226
229
|
}
|
227
230
|
}
|
228
231
|
return result;
|
229
232
|
}
|
230
233
|
|
231
|
-
|
232
|
-
|
234
|
+
static VALUE
|
235
|
+
cmethod_create(VALUE module,
|
236
|
+
VALUE factory,
|
237
|
+
VALUE exterior,
|
238
|
+
VALUE interior_array)
|
233
239
|
{
|
234
|
-
RGeo_FactoryData* factory_data;
|
235
240
|
VALUE linear_ring_type;
|
236
241
|
GEOSGeometry* exterior_geom;
|
237
|
-
GEOSContextHandle_t context;
|
238
242
|
unsigned int len;
|
239
243
|
GEOSGeometry** interior_geoms;
|
240
244
|
unsigned int actual_len;
|
241
245
|
unsigned int i;
|
246
|
+
unsigned int j;
|
242
247
|
GEOSGeometry* interior_geom;
|
243
248
|
GEOSGeometry* polygon;
|
249
|
+
int state = 0;
|
244
250
|
|
245
251
|
Check_Type(interior_array, T_ARRAY);
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
if (
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
252
|
+
linear_ring_type = rgeo_feature_linear_ring_module;
|
253
|
+
exterior_geom = rgeo_convert_to_detached_geos_geometry(
|
254
|
+
exterior, factory, linear_ring_type, NULL, &state);
|
255
|
+
if (state) {
|
256
|
+
rb_jump_tag(state);
|
257
|
+
}
|
258
|
+
|
259
|
+
len = (unsigned int)RARRAY_LEN(interior_array);
|
260
|
+
interior_geoms = ALLOC_N(GEOSGeometry*, len == 0 ? 1 : len);
|
261
|
+
if (interior_geoms) {
|
262
|
+
actual_len = 0;
|
263
|
+
for (i = 0; i < len; ++i) {
|
264
|
+
interior_geom =
|
265
|
+
rgeo_convert_to_detached_geos_geometry(rb_ary_entry(interior_array, i),
|
266
|
+
factory,
|
267
|
+
linear_ring_type,
|
268
|
+
NULL,
|
269
|
+
&state);
|
270
|
+
if (state) {
|
271
|
+
for (j = 0; j < i; j++) {
|
272
|
+
GEOSGeom_destroy(interior_geoms[j]);
|
266
273
|
}
|
274
|
+
GEOSGeom_destroy(exterior_geom);
|
275
|
+
FREE(interior_geoms);
|
276
|
+
rb_jump_tag(state);
|
267
277
|
}
|
268
|
-
|
269
|
-
|
278
|
+
interior_geoms[actual_len++] = interior_geom;
|
279
|
+
}
|
280
|
+
if (len == actual_len) {
|
281
|
+
polygon =
|
282
|
+
GEOSGeom_createPolygon(exterior_geom, interior_geoms, actual_len);
|
283
|
+
if (polygon) {
|
284
|
+
FREE(interior_geoms);
|
285
|
+
// NOTE: we can return safely here, state cannot be other than 0.
|
286
|
+
return rgeo_wrap_geos_geometry(
|
287
|
+
factory, polygon, rgeo_geos_polygon_class);
|
270
288
|
}
|
271
|
-
free(interior_geoms);
|
272
289
|
}
|
273
|
-
|
290
|
+
for (i = 0; i < actual_len; ++i) {
|
291
|
+
GEOSGeom_destroy(interior_geoms[i]);
|
292
|
+
}
|
293
|
+
FREE(interior_geoms);
|
294
|
+
}
|
295
|
+
GEOSGeom_destroy(exterior_geom);
|
296
|
+
if (state) {
|
297
|
+
rb_jump_tag(state);
|
274
298
|
}
|
275
299
|
return Qnil;
|
276
300
|
}
|
277
301
|
|
278
|
-
|
279
|
-
|
302
|
+
void
|
303
|
+
rgeo_init_geos_polygon()
|
280
304
|
{
|
281
305
|
VALUE geos_polygon_methods;
|
282
306
|
|
283
307
|
// Class methods for CAPIPolygonImpl
|
284
|
-
rb_define_module_function(
|
308
|
+
rb_define_module_function(
|
309
|
+
rgeo_geos_polygon_class, "create", cmethod_create, 3);
|
285
310
|
|
286
311
|
// CAPIPolygonMethods module
|
287
|
-
geos_polygon_methods =
|
312
|
+
geos_polygon_methods =
|
313
|
+
rb_define_module_under(rgeo_geos_module, "CAPIPolygonMethods");
|
288
314
|
rb_define_method(geos_polygon_methods, "rep_equals?", method_polygon_eql, 1);
|
289
315
|
rb_define_method(geos_polygon_methods, "eql?", method_polygon_eql, 1);
|
290
316
|
rb_define_method(geos_polygon_methods, "hash", method_polygon_hash, 0);
|
291
|
-
rb_define_method(
|
317
|
+
rb_define_method(
|
318
|
+
geos_polygon_methods, "geometry_type", method_polygon_geometry_type, 0);
|
292
319
|
rb_define_method(geos_polygon_methods, "area", method_polygon_area, 0);
|
293
|
-
rb_define_method(
|
294
|
-
|
295
|
-
rb_define_method(geos_polygon_methods,
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
rb_define_method(
|
320
|
+
rb_define_method(
|
321
|
+
geos_polygon_methods, "centroid", method_polygon_centroid, 0);
|
322
|
+
rb_define_method(geos_polygon_methods,
|
323
|
+
"point_on_surface",
|
324
|
+
method_polygon_point_on_surface,
|
325
|
+
0);
|
326
|
+
rb_define_method(
|
327
|
+
geos_polygon_methods, "exterior_ring", method_polygon_exterior_ring, 0);
|
328
|
+
rb_define_method(geos_polygon_methods,
|
329
|
+
"num_interior_rings",
|
330
|
+
method_polygon_num_interior_rings,
|
331
|
+
0);
|
332
|
+
rb_define_method(
|
333
|
+
geos_polygon_methods, "interior_ring_n", method_polygon_interior_ring_n, 1);
|
334
|
+
rb_define_method(
|
335
|
+
geos_polygon_methods, "interior_rings", method_polygon_interior_rings, 0);
|
336
|
+
rb_define_method(
|
337
|
+
geos_polygon_methods, "coordinates", method_polygon_coordinates, 0);
|
300
338
|
}
|
301
339
|
|
302
|
-
|
303
|
-
|
304
|
-
{
|
305
|
-
VALUE result;
|
306
|
-
int len1;
|
307
|
-
int len2;
|
308
|
-
int i;
|
309
|
-
|
310
|
-
result = Qnil;
|
311
|
-
if (geom1 && geom2) {
|
312
|
-
result = rgeo_geos_coordseqs_eql(context, GEOSGetExteriorRing_r(context, geom1), GEOSGetExteriorRing_r(context, geom2), check_z);
|
313
|
-
if (RTEST(result)) {
|
314
|
-
len1 = GEOSGetNumInteriorRings_r(context, geom1);
|
315
|
-
len2 = GEOSGetNumInteriorRings_r(context, geom2);
|
316
|
-
if (len1 >= 0 && len2 >= 0) {
|
317
|
-
if (len1 == len2) {
|
318
|
-
for (i=0; i<len1; ++i) {
|
319
|
-
result = rgeo_geos_coordseqs_eql(context, GEOSGetInteriorRingN_r(context, geom1, i), GEOSGetInteriorRingN_r(context, geom2, i), check_z);
|
320
|
-
if (!RTEST(result)) {
|
321
|
-
break;
|
322
|
-
}
|
323
|
-
}
|
324
|
-
}
|
325
|
-
else {
|
326
|
-
result = Qfalse;
|
327
|
-
}
|
328
|
-
}
|
329
|
-
else {
|
330
|
-
result = Qnil;
|
331
|
-
}
|
332
|
-
}
|
333
|
-
}
|
334
|
-
return result;
|
335
|
-
}
|
336
|
-
|
337
|
-
|
338
|
-
st_index_t rgeo_geos_polygon_hash(GEOSContextHandle_t context, const GEOSGeometry* geom, st_index_t hash)
|
340
|
+
st_index_t
|
341
|
+
rgeo_geos_polygon_hash(const GEOSGeometry* geom, st_index_t hash)
|
339
342
|
{
|
340
343
|
unsigned int len;
|
341
344
|
unsigned int i;
|
342
345
|
|
343
346
|
if (geom) {
|
344
|
-
hash = rgeo_geos_coordseq_hash(
|
345
|
-
len =
|
346
|
-
for (i=0; i<len; ++i) {
|
347
|
-
hash = rgeo_geos_coordseq_hash(
|
347
|
+
hash = rgeo_geos_coordseq_hash(GEOSGetExteriorRing(geom), hash);
|
348
|
+
len = GEOSGetNumInteriorRings(geom);
|
349
|
+
for (i = 0; i < len; ++i) {
|
350
|
+
hash = rgeo_geos_coordseq_hash(GEOSGetInteriorRingN(geom, i), hash);
|
348
351
|
}
|
349
352
|
}
|
350
353
|
return hash;
|
351
354
|
}
|
352
355
|
|
353
|
-
|
354
356
|
RGEO_END_C
|
355
357
|
|
356
358
|
#endif
|
data/ext/geos_c_impl/polygon.h
CHANGED
@@ -2,41 +2,41 @@
|
|
2
2
|
Polygon methods for GEOS wrapper
|
3
3
|
*/
|
4
4
|
|
5
|
-
|
6
5
|
#ifndef RGEO_GEOS_POLYGON_INCLUDED
|
7
6
|
#define RGEO_GEOS_POLYGON_INCLUDED
|
8
7
|
|
9
|
-
#include <ruby.h>
|
10
8
|
#include <geos_c.h>
|
11
|
-
|
12
|
-
#include "factory.h"
|
9
|
+
#include <ruby.h>
|
13
10
|
|
14
11
|
RGEO_BEGIN_C
|
15
12
|
|
16
|
-
|
17
13
|
/*
|
18
14
|
Initializes the polygon module. This should be called after
|
19
15
|
the geometry module is initialized.
|
20
16
|
*/
|
21
|
-
void
|
17
|
+
void
|
18
|
+
rgeo_init_geos_polygon();
|
22
19
|
|
23
20
|
/*
|
24
|
-
|
21
|
+
Compares the values of two GEOS polygons. The two given geometries MUST
|
25
22
|
be polygon types.
|
26
23
|
Returns Qtrue if the polygons are equal, Qfalse if they are inequal, or
|
27
24
|
Qnil if an error occurs.
|
28
25
|
*/
|
29
|
-
VALUE
|
26
|
+
VALUE
|
27
|
+
rgeo_geos_polygons_eql(const GEOSGeometry* geom1,
|
28
|
+
const GEOSGeometry* geom2,
|
29
|
+
char check_z);
|
30
30
|
|
31
31
|
/*
|
32
32
|
A tool for building up hash values.
|
33
|
-
You must pass in
|
33
|
+
You must pass in a geos geometry, and a seed hash.
|
34
34
|
Returns an updated hash.
|
35
35
|
This call is useful in sequence, and should be bracketed by calls to
|
36
36
|
rb_hash_start and rb_hash_end.
|
37
37
|
*/
|
38
|
-
st_index_t
|
39
|
-
|
38
|
+
st_index_t
|
39
|
+
rgeo_geos_polygon_hash(const GEOSGeometry* geom, st_index_t hash);
|
40
40
|
|
41
41
|
RGEO_END_C
|
42
42
|
|
data/ext/geos_c_impl/preface.h
CHANGED
@@ -2,7 +2,6 @@
|
|
2
2
|
Preface header for GEOS wrapper
|
3
3
|
*/
|
4
4
|
|
5
|
-
|
6
5
|
#ifdef HAVE_GEOS_C_H
|
7
6
|
#ifdef HAVE_GEOSSETSRID_R
|
8
7
|
#define RGEO_GEOS_SUPPORTED
|
@@ -24,21 +23,28 @@
|
|
24
23
|
#ifdef HAVE_GEOSCOORDSEQ_ISCCW_R
|
25
24
|
#define RGEO_GEOS_SUPPORTS_ISCCW
|
26
25
|
#endif
|
27
|
-
#ifdef
|
28
|
-
#define
|
26
|
+
#ifdef HAVE_GEOSDENSIFY
|
27
|
+
#define RGEO_GEOS_SUPPORTS_DENSIFY
|
29
28
|
#endif
|
30
|
-
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#define
|
34
|
-
#define rb_hash_start(x) ((st_index_t)(x ^ 0xdeadbeef))
|
35
|
-
#define rb_hash_end(x) ((st_index_t)(x ^ 0xbeefdead))
|
29
|
+
#ifdef HAVE_RB_GC_MARK_MOVABLE
|
30
|
+
#define mark rb_gc_mark_movable
|
31
|
+
#else
|
32
|
+
#define mark rb_gc_mark
|
36
33
|
#endif
|
37
34
|
|
38
35
|
#ifdef __cplusplus
|
39
|
-
#define RGEO_BEGIN_C
|
36
|
+
#define RGEO_BEGIN_C \
|
37
|
+
extern "C" \
|
38
|
+
{
|
40
39
|
#define RGEO_END_C }
|
41
40
|
#else
|
42
41
|
#define RGEO_BEGIN_C
|
43
42
|
#define RGEO_END_C
|
44
43
|
#endif
|
44
|
+
|
45
|
+
// https://ozlabs.org/~rusty/index.cgi/tech/2008-04-01.html
|
46
|
+
#define streq(a, b) (!strcmp((a), (b)))
|
47
|
+
|
48
|
+
// When using ruby ALLOC* macros, we are using ruby_xmalloc, which counterpart
|
49
|
+
// is ruby_xfree. This macro helps enforcing that by showing us the way.
|
50
|
+
#define FREE ruby_xfree
|
@@ -0,0 +1,67 @@
|
|
1
|
+
/*
|
2
|
+
Utilities for the ruby CAPI
|
3
|
+
*/
|
4
|
+
|
5
|
+
#ifndef RGEO_GEOS_RUBY_MORE_INCLUDED
|
6
|
+
#define RGEO_GEOS_RUBY_MORE_INCLUDED
|
7
|
+
|
8
|
+
#include "ruby_more.h"
|
9
|
+
|
10
|
+
#include <ruby.h>
|
11
|
+
|
12
|
+
#include "preface.h"
|
13
|
+
|
14
|
+
RGEO_BEGIN_C
|
15
|
+
|
16
|
+
struct funcall_args
|
17
|
+
{
|
18
|
+
VALUE recv;
|
19
|
+
ID mid;
|
20
|
+
int argc;
|
21
|
+
VALUE* argv;
|
22
|
+
};
|
23
|
+
|
24
|
+
static VALUE
|
25
|
+
inner_funcall(VALUE args_)
|
26
|
+
{
|
27
|
+
struct funcall_args* args = (struct funcall_args*)args_;
|
28
|
+
return rb_funcallv(args->recv, args->mid, args->argc, args->argv);
|
29
|
+
}
|
30
|
+
|
31
|
+
VALUE
|
32
|
+
rb_protect_funcall(VALUE recv, ID mid, int* state, int n, ...)
|
33
|
+
{
|
34
|
+
struct funcall_args args;
|
35
|
+
VALUE* argv;
|
36
|
+
va_list ar;
|
37
|
+
|
38
|
+
if (n > 0) {
|
39
|
+
long i;
|
40
|
+
va_start(ar, n);
|
41
|
+
argv = ALLOCA_N(VALUE, n);
|
42
|
+
for (i = 0; i < n; i++) {
|
43
|
+
argv[i] = va_arg(ar, VALUE);
|
44
|
+
}
|
45
|
+
va_end(ar);
|
46
|
+
} else {
|
47
|
+
argv = 0;
|
48
|
+
}
|
49
|
+
|
50
|
+
args.recv = recv;
|
51
|
+
args.mid = mid;
|
52
|
+
args.argc = n;
|
53
|
+
args.argv = argv;
|
54
|
+
|
55
|
+
return rb_protect(inner_funcall, (VALUE)&args, state);
|
56
|
+
}
|
57
|
+
|
58
|
+
VALUE
|
59
|
+
rb_exc_raise_value(VALUE exc)
|
60
|
+
{
|
61
|
+
rb_exc_raise(exc);
|
62
|
+
return Qnil;
|
63
|
+
}
|
64
|
+
|
65
|
+
RGEO_END_C
|
66
|
+
|
67
|
+
#endif
|
@@ -0,0 +1,25 @@
|
|
1
|
+
/*
|
2
|
+
Utilities for the ruby CAPI
|
3
|
+
*/
|
4
|
+
|
5
|
+
#ifndef RGEO_GEOS_RUBY_MORE_INCLUDED
|
6
|
+
#define RGEO_GEOS_RUBY_MORE_INCLUDED
|
7
|
+
|
8
|
+
#include <ruby.h>
|
9
|
+
|
10
|
+
RGEO_BEGIN_C
|
11
|
+
|
12
|
+
VALUE
|
13
|
+
rb_protect_funcall(VALUE recv, ID mid, int* state, int n, ...);
|
14
|
+
|
15
|
+
/*
|
16
|
+
Raises an error based on the exception passed in, but also returns
|
17
|
+
a VALUE rather than void. This is so we can pass it into rb_protect
|
18
|
+
without getting type mismatch warnings.
|
19
|
+
*/
|
20
|
+
VALUE
|
21
|
+
rb_exc_raise_value(VALUE exc);
|
22
|
+
|
23
|
+
RGEO_END_C
|
24
|
+
|
25
|
+
#endif
|
@@ -10,7 +10,6 @@ module RGeo
|
|
10
10
|
module Cartesian
|
11
11
|
# This provides includes some spatial analysis algorithms supporting
|
12
12
|
# Cartesian data.
|
13
|
-
|
14
13
|
module Analysis
|
15
14
|
class << self
|
16
15
|
# Check orientation of a ring, returns `true` if it is counter-clockwise
|
@@ -79,8 +78,11 @@ module RGeo
|
|
79
78
|
sin = 0.0
|
80
79
|
cos = 1.0
|
81
80
|
angs.each_slice(2) do |(x, y)|
|
82
|
-
ready = y > 0.0 &&
|
83
|
-
|
81
|
+
ready = y > 0.0 &&
|
82
|
+
(sin > 0.0 || sin == 0 && direction == -1) ||
|
83
|
+
y < 0.0 &&
|
84
|
+
(sin < 0.0 || sin == 0 && direction == 1)
|
85
|
+
unless y == 0
|
84
86
|
s = sin * x + cos * y
|
85
87
|
c = cos * x - sin * y
|
86
88
|
r = Math.sqrt(s * s + c * c)
|