rgeo 2.4.0 → 3.1.0

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