rgeo 2.4.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +6 -0
  3. data/README.md +21 -11
  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 +41 -29
  11. data/ext/geos_c_impl/factory.c +441 -351
  12. data/ext/geos_c_impl/factory.h +98 -55
  13. data/ext/geos_c_impl/geometry.c +563 -384
  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 +99 -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 +62 -65
  23. data/ext/geos_c_impl/point.h +4 -5
  24. data/ext/geos_c_impl/polygon.c +134 -132
  25. data/ext/geos_c_impl/polygon.h +11 -9
  26. data/ext/geos_c_impl/preface.h +10 -12
  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 +57 -102
  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 +299 -99
  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 +73 -83
  58. data/lib/rgeo/geographic/factory.rb +98 -125
  59. data/lib/rgeo/geographic/interface.rb +66 -163
  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 +24 -23
  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 +95 -165
  72. data/lib/rgeo/geos/ffi_feature_classes.rb +34 -10
  73. data/lib/rgeo/geos/ffi_feature_methods.rb +105 -126
  74. data/lib/rgeo/geos/interface.rb +20 -59
  75. data/lib/rgeo/geos/utils.rb +3 -3
  76. data/lib/rgeo/geos/zm_factory.rb +53 -95
  77. data/lib/rgeo/geos/zm_feature_methods.rb +30 -32
  78. data/lib/rgeo/geos.rb +8 -8
  79. data/lib/rgeo/impl_helper/basic_geometry_collection_methods.rb +9 -22
  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 +51 -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,186 @@ 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
 
231
-
232
- static VALUE cmethod_create(VALUE module, VALUE factory, VALUE exterior, VALUE interior_array)
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
- factory_data = RGEO_FACTORY_DATA_PTR(factory);
247
252
  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);
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
- for (i=0; i<actual_len; ++i) {
269
- GEOSGeom_destroy_r(context, interior_geoms[i]);
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
- GEOSGeom_destroy_r(context, exterior_geom);
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
- void rgeo_init_geos_polygon()
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(rgeo_geos_polygon_class, "create", cmethod_create, 3);
308
+ rb_define_module_function(
309
+ rgeo_geos_polygon_class, "create", cmethod_create, 3);
285
310
 
286
311
  // CAPIPolygonMethods module
287
- geos_polygon_methods = rb_define_module_under(rgeo_geos_module, "CAPIPolygonMethods");
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(geos_polygon_methods, "geometry_type", method_polygon_geometry_type, 0);
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(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;
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);
335
338
  }
336
339
 
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(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);
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
@@ -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,26 +23,25 @@
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
29
- #endif
30
26
  #ifdef HAVE_RB_GC_MARK_MOVABLE
31
27
  #define mark rb_gc_mark_movable
32
28
  #else
33
29
  #define mark rb_gc_mark
34
30
  #endif
35
31
 
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
32
  #ifdef __cplusplus
44
- #define RGEO_BEGIN_C extern "C" {
33
+ #define RGEO_BEGIN_C \
34
+ extern "C" \
35
+ {
45
36
  #define RGEO_END_C }
46
37
  #else
47
38
  #define RGEO_BEGIN_C
48
39
  #define RGEO_END_C
49
40
  #endif
41
+
42
+ // https://ozlabs.org/~rusty/index.cgi/tech/2008-04-01.html
43
+ #define streq(a, b) (!strcmp((a), (b)))
44
+
45
+ // When using ruby ALLOC* macros, we are using ruby_xmalloc, which counterpart
46
+ // is ruby_xfree. This macro helps enforcing that by showing us the way.
47
+ #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 && (sin > 0.0 || sin == 0.0 && direction == -1) || y < 0.0 && (sin < 0.0 || sin == 0.0 && direction == 1)
83
- if y != 0.0
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)