rgeo 0.5.1 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,32 @@
1
+ /*
2
+ Line string methods for GEOS wrapper
3
+ */
4
+
5
+
6
+ #ifndef RGEO_GEOS_LINE_STRING_INCLUDED
7
+ #define RGEO_GEOS_LINE_STRING_INCLUDED
8
+
9
+ #include <ruby.h>
10
+ #include <geos_c.h>
11
+
12
+ #include "factory.h"
13
+
14
+ RGEO_BEGIN_C
15
+
16
+
17
+ /*
18
+ Initializes the line string module. This should be called after
19
+ the geometry module is initialized.
20
+ */
21
+ void rgeo_init_geos_line_string(RGeo_Globals* globals);
22
+
23
+ /*
24
+ Determines whether the given GEOS line string is closed.
25
+ Returns Qtrue if true, Qfalse if false, or Qnil on an error.
26
+ */
27
+ VALUE rgeo_is_geos_line_string_closed(GEOSContextHandle_t context, const GEOSGeometry* geom);
28
+
29
+
30
+ RGEO_END_C
31
+
32
+ #endif
@@ -0,0 +1,40 @@
1
+ /*
2
+ Main initializer for GEOS wrapper
3
+ */
4
+
5
+
6
+ #include "preface.h"
7
+
8
+ #ifdef RGEO_GEOS_SUPPORTED
9
+
10
+ #include <ruby.h>
11
+ #include <geos_c.h>
12
+
13
+ #include "factory.h"
14
+ #include "geometry.h"
15
+ #include "point.h"
16
+ #include "line_string.h"
17
+ #include "polygon.h"
18
+ #include "geometry_collection.h"
19
+
20
+ #endif
21
+
22
+ RGEO_BEGIN_C
23
+
24
+
25
+ void Init_geos_c_impl()
26
+ {
27
+ #ifdef RGEO_GEOS_SUPPORTED
28
+ RGeo_Globals* globals;
29
+
30
+ globals = rgeo_init_geos_factory();
31
+ rgeo_init_geos_geometry(globals);
32
+ rgeo_init_geos_point(globals);
33
+ rgeo_init_geos_line_string(globals);
34
+ rgeo_init_geos_polygon(globals);
35
+ rgeo_init_geos_geometry_collection(globals);
36
+ #endif
37
+ }
38
+
39
+
40
+ RGEO_END_C
@@ -0,0 +1,236 @@
1
+ /*
2
+ Point methods for GEOS wrapper
3
+ */
4
+
5
+ #include "preface.h"
6
+
7
+ #ifdef RGEO_GEOS_SUPPORTED
8
+
9
+ #include <ruby.h>
10
+ #include <geos_c.h>
11
+
12
+ #include "factory.h"
13
+ #include "geometry.h"
14
+ #include "point.h"
15
+
16
+ #include "coordinates.h"
17
+
18
+ RGEO_BEGIN_C
19
+
20
+
21
+ static VALUE method_point_geometry_type(VALUE self)
22
+ {
23
+ VALUE result;
24
+ RGeo_GeometryData* self_data;
25
+
26
+ result = Qnil;
27
+ self_data = RGEO_GEOMETRY_DATA_PTR(self);
28
+ if (self_data->geom) {
29
+ result = RGEO_FACTORY_DATA_PTR(self_data->factory)->globals->feature_point;
30
+ }
31
+ return result;
32
+ }
33
+
34
+
35
+ static VALUE method_point_coordinates(VALUE self)
36
+ {
37
+ VALUE result = Qnil;
38
+ RGeo_GeometryData* self_data;
39
+ const GEOSGeometry* self_geom;
40
+ GEOSContextHandle_t context;
41
+ const GEOSCoordSequence* coord_sequence;
42
+ int zCoordinate;
43
+
44
+ self_data = RGEO_GEOMETRY_DATA_PTR(self);
45
+ self_geom = self_data->geom;
46
+
47
+ if (self_geom) {
48
+ zCoordinate = RGEO_FACTORY_DATA_PTR(self_data->factory)->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M;
49
+ context = self_data->geos_context;
50
+ coord_sequence = GEOSGeom_getCoordSeq_r(context, self_geom);
51
+ if(coord_sequence) {
52
+ result = rb_ary_pop(extract_points_from_coordinate_sequence(context, coord_sequence, zCoordinate));
53
+ }
54
+ }
55
+ return result;
56
+ }
57
+
58
+
59
+ static VALUE method_point_x(VALUE self)
60
+ {
61
+ VALUE result;
62
+ RGeo_GeometryData* self_data;
63
+ const GEOSGeometry* self_geom;
64
+ GEOSContextHandle_t self_context;
65
+ const GEOSCoordSequence* coord_seq;
66
+ double val;
67
+
68
+ result = Qnil;
69
+ self_data = RGEO_GEOMETRY_DATA_PTR(self);
70
+ self_geom = self_data->geom;
71
+ if (self_geom) {
72
+ self_context = self_data->geos_context;
73
+ coord_seq = GEOSGeom_getCoordSeq_r(self_context, self_geom);
74
+ if (coord_seq) {
75
+ if (GEOSCoordSeq_getX_r(self_context, coord_seq, 0, &val)) {
76
+ result = rb_float_new(val);
77
+ }
78
+ }
79
+ }
80
+ return result;
81
+ }
82
+
83
+
84
+ static VALUE method_point_y(VALUE self)
85
+ {
86
+ VALUE result;
87
+ RGeo_GeometryData* self_data;
88
+ const GEOSGeometry* self_geom;
89
+ GEOSContextHandle_t self_context;
90
+ const GEOSCoordSequence* coord_seq;
91
+ double val;
92
+
93
+ result = Qnil;
94
+ self_data = RGEO_GEOMETRY_DATA_PTR(self);
95
+ self_geom = self_data->geom;
96
+ if (self_geom) {
97
+ self_context = self_data->geos_context;
98
+ coord_seq = GEOSGeom_getCoordSeq_r(self_context, self_geom);
99
+ if (coord_seq) {
100
+ if (GEOSCoordSeq_getY_r(self_context, coord_seq, 0, &val)) {
101
+ result = rb_float_new(val);
102
+ }
103
+ }
104
+ }
105
+ return result;
106
+ }
107
+
108
+
109
+ static VALUE get_3d_point(VALUE self, int flag)
110
+ {
111
+ VALUE result;
112
+ RGeo_GeometryData* self_data;
113
+ const GEOSGeometry* self_geom;
114
+ GEOSContextHandle_t self_context;
115
+ const GEOSCoordSequence* coord_seq;
116
+ double val;
117
+
118
+ result = Qnil;
119
+ self_data = RGEO_GEOMETRY_DATA_PTR(self);
120
+ self_geom = self_data->geom;
121
+ if (self_geom) {
122
+ if (RGEO_FACTORY_DATA_PTR(self_data->factory)->flags & flag) {
123
+ self_context = self_data->geos_context;
124
+ coord_seq = GEOSGeom_getCoordSeq_r(self_context, self_geom);
125
+ if (coord_seq) {
126
+ if (GEOSCoordSeq_getZ_r(self_context, coord_seq, 0, &val)) {
127
+ result = rb_float_new(val);
128
+ }
129
+ }
130
+ }
131
+ }
132
+ return result;
133
+ }
134
+
135
+
136
+ static VALUE method_point_z(VALUE self)
137
+ {
138
+ return get_3d_point(self, RGEO_FACTORYFLAGS_SUPPORTS_Z);
139
+ }
140
+
141
+
142
+ static VALUE method_point_m(VALUE self)
143
+ {
144
+ return get_3d_point(self, RGEO_FACTORYFLAGS_SUPPORTS_M);
145
+ }
146
+
147
+
148
+ static VALUE method_point_eql(VALUE self, VALUE rhs)
149
+ {
150
+ VALUE result;
151
+ RGeo_GeometryData* self_data;
152
+
153
+ result = rgeo_geos_klasses_and_factories_eql(self, rhs);
154
+ if (RTEST(result)) {
155
+ self_data = RGEO_GEOMETRY_DATA_PTR(self);
156
+ result = rgeo_geos_coordseqs_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);
157
+ }
158
+ return result;
159
+ }
160
+
161
+
162
+ static VALUE method_point_hash(VALUE self)
163
+ {
164
+ st_index_t hash;
165
+ RGeo_GeometryData* self_data;
166
+ VALUE factory;
167
+
168
+ self_data = RGEO_GEOMETRY_DATA_PTR(self);
169
+ factory = self_data->factory;
170
+ hash = rb_hash_start(0);
171
+ hash = rgeo_geos_objbase_hash(factory,
172
+ RGEO_FACTORY_DATA_PTR(factory)->globals->feature_point, hash);
173
+ hash = rgeo_geos_coordseq_hash(self_data->geos_context, self_data->geom, hash);
174
+ return LONG2FIX(rb_hash_end(hash));
175
+ }
176
+
177
+
178
+ static VALUE cmethod_create(VALUE module, VALUE factory, VALUE x, VALUE y, VALUE z)
179
+ {
180
+ return rgeo_create_geos_point(factory, rb_num2dbl(x), rb_num2dbl(y),
181
+ RGEO_FACTORY_DATA_PTR(factory)->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M ? rb_num2dbl(z) : 0);
182
+ }
183
+
184
+
185
+ void rgeo_init_geos_point(RGeo_Globals* globals)
186
+ {
187
+ VALUE geos_point_methods;
188
+
189
+ // Class methods for CAPIPointImpl
190
+ rb_define_module_function(globals->geos_point, "create", cmethod_create, 4);
191
+
192
+ // CAPIPointMethods module
193
+ geos_point_methods = rb_define_module_under(globals->geos_module, "CAPIPointMethods");
194
+ rb_define_method(geos_point_methods, "rep_equals?", method_point_eql, 1);
195
+ rb_define_method(geos_point_methods, "eql?", method_point_eql, 1);
196
+ rb_define_method(geos_point_methods, "hash", method_point_hash, 0);
197
+ rb_define_method(geos_point_methods, "geometry_type", method_point_geometry_type, 0);
198
+ rb_define_method(geos_point_methods, "x", method_point_x, 0);
199
+ rb_define_method(geos_point_methods, "y", method_point_y, 0);
200
+ rb_define_method(geos_point_methods, "z", method_point_z, 0);
201
+ rb_define_method(geos_point_methods, "m", method_point_m, 0);
202
+ rb_define_method(geos_point_methods, "coordinates", method_point_coordinates, 0);
203
+ }
204
+
205
+
206
+ VALUE rgeo_create_geos_point(VALUE factory, double x, double y, double z)
207
+ {
208
+ VALUE result;
209
+ RGeo_FactoryData* factory_data;
210
+ GEOSContextHandle_t context;
211
+ GEOSCoordSequence* coord_seq;
212
+ GEOSGeometry* geom;
213
+
214
+ result = Qnil;
215
+ factory_data = RGEO_FACTORY_DATA_PTR(factory);
216
+ context = factory_data->geos_context;
217
+ coord_seq = GEOSCoordSeq_create_r(context, 1, 3);
218
+ if (coord_seq) {
219
+ if (GEOSCoordSeq_setX_r(context, coord_seq, 0, x)) {
220
+ if (GEOSCoordSeq_setY_r(context, coord_seq, 0, y)) {
221
+ if (GEOSCoordSeq_setZ_r(context, coord_seq, 0, z)) {
222
+ geom = GEOSGeom_createPoint_r(context, coord_seq);
223
+ if (geom) {
224
+ result = rgeo_wrap_geos_geometry(factory, geom, factory_data->globals->geos_point);
225
+ }
226
+ }
227
+ }
228
+ }
229
+ }
230
+ return result;
231
+ }
232
+
233
+
234
+ RGEO_END_C
235
+
236
+ #endif
@@ -0,0 +1,30 @@
1
+ /*
2
+ Point methods for GEOS wrapper
3
+ */
4
+
5
+
6
+ #ifndef RGEO_GEOS_POINT_INCLUDED
7
+ #define RGEO_GEOS_POINT_INCLUDED
8
+
9
+ #include <ruby.h>
10
+
11
+ #include "factory.h"
12
+
13
+ RGEO_BEGIN_C
14
+
15
+
16
+ /*
17
+ Initializes the point module. This should be called after
18
+ the geometry module is initialized.
19
+ */
20
+ void rgeo_init_geos_point(RGeo_Globals* globals);
21
+
22
+ /*
23
+ Creates a 3d point and returns the ruby object.
24
+ */
25
+ VALUE rgeo_create_geos_point(VALUE factory, double x, double y, double z);
26
+
27
+
28
+ RGEO_END_C
29
+
30
+ #endif
@@ -0,0 +1,359 @@
1
+ /*
2
+ Polygon methods for GEOS wrapper
3
+ */
4
+
5
+
6
+ #include "preface.h"
7
+
8
+ #ifdef RGEO_GEOS_SUPPORTED
9
+
10
+ #include <ruby.h>
11
+ #include <geos_c.h>
12
+
13
+ #include "factory.h"
14
+ #include "geometry.h"
15
+ #include "line_string.h"
16
+ #include "polygon.h"
17
+
18
+ #include "coordinates.h"
19
+
20
+ RGEO_BEGIN_C
21
+
22
+
23
+ static VALUE method_polygon_eql(VALUE self, VALUE rhs)
24
+ {
25
+ VALUE result;
26
+ RGeo_GeometryData* self_data;
27
+
28
+ result = rgeo_geos_klasses_and_factories_eql(self, rhs);
29
+ if (RTEST(result)) {
30
+ self_data = RGEO_GEOMETRY_DATA_PTR(self);
31
+ 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);
32
+ }
33
+ return result;
34
+ }
35
+
36
+
37
+ static VALUE method_polygon_hash(VALUE self)
38
+ {
39
+ st_index_t hash;
40
+ RGeo_GeometryData* self_data;
41
+ VALUE factory;
42
+
43
+ self_data = RGEO_GEOMETRY_DATA_PTR(self);
44
+ factory = self_data->factory;
45
+ hash = rb_hash_start(0);
46
+ hash = rgeo_geos_objbase_hash(factory,
47
+ RGEO_FACTORY_DATA_PTR(factory)->globals->feature_polygon, hash);
48
+ hash = rgeo_geos_polygon_hash(self_data->geos_context, self_data->geom, hash);
49
+ return LONG2FIX(rb_hash_end(hash));
50
+ }
51
+
52
+
53
+ static VALUE method_polygon_geometry_type(VALUE self)
54
+ {
55
+ VALUE result;
56
+ RGeo_GeometryData* self_data;
57
+
58
+ result = Qnil;
59
+ self_data = RGEO_GEOMETRY_DATA_PTR(self);
60
+ if (self_data->geom) {
61
+ result = RGEO_FACTORY_DATA_PTR(self_data->factory)->globals->feature_polygon;
62
+ }
63
+ return result;
64
+ }
65
+
66
+
67
+ static VALUE method_polygon_area(VALUE self)
68
+ {
69
+ VALUE result;
70
+ RGeo_GeometryData* self_data;
71
+ const GEOSGeometry* self_geom;
72
+ double area;
73
+
74
+ result = Qnil;
75
+ self_data = RGEO_GEOMETRY_DATA_PTR(self);
76
+ self_geom = self_data->geom;
77
+ if (self_geom) {
78
+ if (GEOSArea_r(self_data->geos_context, self_geom, &area)) {
79
+ result = rb_float_new(area);
80
+ }
81
+ }
82
+ return result;
83
+ }
84
+
85
+
86
+ static VALUE method_polygon_centroid(VALUE self)
87
+ {
88
+ VALUE result;
89
+ RGeo_GeometryData* self_data;
90
+ const GEOSGeometry* self_geom;
91
+
92
+ result = Qnil;
93
+ self_data = RGEO_GEOMETRY_DATA_PTR(self);
94
+ self_geom = self_data->geom;
95
+ if (self_geom) {
96
+ result = rgeo_wrap_geos_geometry(self_data->factory, GEOSGetCentroid_r(self_data->geos_context, self_geom), RGEO_FACTORY_DATA_PTR(self_data->factory)->globals->geos_point);
97
+ }
98
+ return result;
99
+ }
100
+
101
+
102
+ static VALUE method_polygon_point_on_surface(VALUE self)
103
+ {
104
+ VALUE result;
105
+ RGeo_GeometryData* self_data;
106
+ const GEOSGeometry* self_geom;
107
+
108
+ result = Qnil;
109
+ self_data = RGEO_GEOMETRY_DATA_PTR(self);
110
+ self_geom = self_data->geom;
111
+ if (self_geom) {
112
+ result = rgeo_wrap_geos_geometry(self_data->factory, GEOSPointOnSurface_r(self_data->geos_context, self_geom), RGEO_FACTORY_DATA_PTR(self_data->factory)->globals->geos_point);
113
+ }
114
+ return result;
115
+ }
116
+
117
+
118
+ static VALUE method_polygon_coordinates(VALUE self)
119
+ {
120
+ VALUE result = Qnil;
121
+ RGeo_GeometryData* self_data;
122
+ const GEOSGeometry* self_geom;
123
+ GEOSContextHandle_t self_context;
124
+
125
+ GEOSGeometry* ring;
126
+ GEOSCoordSequence* coord_sequence;
127
+ unsigned int interior_ring_count;
128
+ int zCoordinate;
129
+
130
+ self_data = RGEO_GEOMETRY_DATA_PTR(self);
131
+ self_geom = self_data->geom;
132
+
133
+ if (self_geom) {
134
+ zCoordinate = RGEO_FACTORY_DATA_PTR(self_data->factory)->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M;
135
+ self_context = self_data->geos_context;
136
+ result = extract_points_from_polygon(self_context, self_geom, zCoordinate);
137
+ }
138
+ return result;
139
+ }
140
+
141
+ static VALUE method_polygon_exterior_ring(VALUE self)
142
+ {
143
+ VALUE result;
144
+ RGeo_GeometryData* self_data;
145
+ const GEOSGeometry* self_geom;
146
+
147
+ result = Qnil;
148
+ self_data = RGEO_GEOMETRY_DATA_PTR(self);
149
+ self_geom = self_data->geom;
150
+ if (self_geom) {
151
+ result = rgeo_wrap_geos_geometry_clone(self_data->factory, GEOSGetExteriorRing_r(self_data->geos_context, self_geom), RGEO_FACTORY_DATA_PTR(self_data->factory)->globals->geos_linear_ring);
152
+ }
153
+ return result;
154
+ }
155
+
156
+
157
+ static VALUE method_polygon_num_interior_rings(VALUE self)
158
+ {
159
+ VALUE result;
160
+ RGeo_GeometryData* self_data;
161
+ const GEOSGeometry* self_geom;
162
+ int num;
163
+
164
+ result = Qnil;
165
+ self_data = RGEO_GEOMETRY_DATA_PTR(self);
166
+ self_geom = self_data->geom;
167
+ if (self_geom) {
168
+ num = GEOSGetNumInteriorRings_r(self_data->geos_context, self_geom);
169
+ if (num >= 0) {
170
+ result = INT2NUM(num);
171
+ }
172
+ }
173
+ return result;
174
+ }
175
+
176
+
177
+ static VALUE method_polygon_interior_ring_n(VALUE self, VALUE n)
178
+ {
179
+ VALUE result;
180
+ RGeo_GeometryData* self_data;
181
+ const GEOSGeometry* self_geom;
182
+ int i;
183
+ GEOSContextHandle_t self_context;
184
+ int num;
185
+
186
+ result = Qnil;
187
+ self_data = RGEO_GEOMETRY_DATA_PTR(self);
188
+ self_geom = self_data->geom;
189
+ if (self_geom) {
190
+ i = NUM2INT(n);
191
+ if (i >= 0) {
192
+ self_context = self_data->geos_context;
193
+ num = GEOSGetNumInteriorRings_r(self_context, self_geom);
194
+ if (i < num) {
195
+ result = rgeo_wrap_geos_geometry_clone(self_data->factory,
196
+ GEOSGetInteriorRingN_r(self_context, self_geom, i),
197
+ RGEO_FACTORY_DATA_PTR(self_data->factory)->globals->geos_linear_ring);
198
+ }
199
+ }
200
+ }
201
+ return result;
202
+ }
203
+
204
+
205
+ static VALUE method_polygon_interior_rings(VALUE self)
206
+ {
207
+ VALUE result;
208
+ RGeo_GeometryData* self_data;
209
+ const GEOSGeometry* self_geom;
210
+ GEOSContextHandle_t self_context;
211
+ int count;
212
+ VALUE factory;
213
+ VALUE linear_ring_class;
214
+ int i;
215
+
216
+ result = Qnil;
217
+ self_data = RGEO_GEOMETRY_DATA_PTR(self);
218
+ self_geom = self_data->geom;
219
+ if (self_geom) {
220
+ self_context = self_data->geos_context;
221
+ count = GEOSGetNumInteriorRings_r(self_context, self_geom);
222
+ if (count >= 0) {
223
+ result = rb_ary_new2(count);
224
+ factory = self_data->factory;
225
+ linear_ring_class = RGEO_FACTORY_DATA_PTR(self_data->factory)->globals->geos_linear_ring;
226
+ for (i=0; i<count; ++i) {
227
+ rb_ary_store(result, i, rgeo_wrap_geos_geometry_clone(factory, GEOSGetInteriorRingN_r(self_context, self_geom, i), linear_ring_class));
228
+ }
229
+ }
230
+ }
231
+ return result;
232
+ }
233
+
234
+
235
+ static VALUE cmethod_create(VALUE module, VALUE factory, VALUE exterior, VALUE interior_array)
236
+ {
237
+ RGeo_FactoryData* factory_data;
238
+ VALUE linear_ring_type;
239
+ GEOSGeometry* exterior_geom;
240
+ GEOSContextHandle_t context;
241
+ unsigned int len;
242
+ GEOSGeometry** interior_geoms;
243
+ unsigned int actual_len;
244
+ unsigned int i;
245
+ GEOSGeometry* interior_geom;
246
+ GEOSGeometry* polygon;
247
+
248
+ Check_Type(interior_array, T_ARRAY);
249
+ factory_data = RGEO_FACTORY_DATA_PTR(factory);
250
+ linear_ring_type = factory_data->globals->feature_linear_ring;
251
+ exterior_geom = rgeo_convert_to_detached_geos_geometry(exterior, factory, linear_ring_type, NULL);
252
+ if (exterior_geom) {
253
+ context = factory_data->geos_context;
254
+ len = (unsigned int)RARRAY_LEN(interior_array);
255
+ interior_geoms = ALLOC_N(GEOSGeometry*, len == 0 ? 1 : len);
256
+ if (interior_geoms) {
257
+ actual_len = 0;
258
+ for (i=0; i<len; ++i) {
259
+ interior_geom = rgeo_convert_to_detached_geos_geometry(rb_ary_entry(interior_array, i), factory, linear_ring_type, NULL);
260
+ if (interior_geom) {
261
+ interior_geoms[actual_len++] = interior_geom;
262
+ }
263
+ }
264
+ if (len == actual_len) {
265
+ polygon = GEOSGeom_createPolygon_r(context, exterior_geom, interior_geoms, actual_len);
266
+ if (polygon) {
267
+ free(interior_geoms);
268
+ return rgeo_wrap_geos_geometry(factory, polygon, factory_data->globals->geos_polygon);
269
+ }
270
+ }
271
+ for (i=0; i<actual_len; ++i) {
272
+ GEOSGeom_destroy_r(context, interior_geoms[i]);
273
+ }
274
+ free(interior_geoms);
275
+ }
276
+ GEOSGeom_destroy_r(context, exterior_geom);
277
+ }
278
+ return Qnil;
279
+ }
280
+
281
+
282
+ void rgeo_init_geos_polygon(RGeo_Globals* globals)
283
+ {
284
+ VALUE geos_polygon_methods;
285
+
286
+ // Class methods for CAPIPolygonImpl
287
+ rb_define_module_function(globals->geos_polygon, "create", cmethod_create, 3);
288
+
289
+ // CAPIPolygonMethods module
290
+ geos_polygon_methods = rb_define_module_under(globals->geos_module, "CAPIPolygonMethods");
291
+ rb_define_method(geos_polygon_methods, "rep_equals?", method_polygon_eql, 1);
292
+ rb_define_method(geos_polygon_methods, "eql?", method_polygon_eql, 1);
293
+ rb_define_method(geos_polygon_methods, "hash", method_polygon_hash, 0);
294
+ rb_define_method(geos_polygon_methods, "geometry_type", method_polygon_geometry_type, 0);
295
+ rb_define_method(geos_polygon_methods, "area", method_polygon_area, 0);
296
+ rb_define_method(geos_polygon_methods, "centroid", method_polygon_centroid, 0);
297
+ rb_define_method(geos_polygon_methods, "point_on_surface", method_polygon_point_on_surface, 0);
298
+ rb_define_method(geos_polygon_methods, "exterior_ring", method_polygon_exterior_ring, 0);
299
+ rb_define_method(geos_polygon_methods, "num_interior_rings", method_polygon_num_interior_rings, 0);
300
+ rb_define_method(geos_polygon_methods, "interior_ring_n", method_polygon_interior_ring_n, 1);
301
+ rb_define_method(geos_polygon_methods, "interior_rings", method_polygon_interior_rings, 0);
302
+ rb_define_method(geos_polygon_methods, "coordinates", method_polygon_coordinates, 0);
303
+ }
304
+
305
+
306
+ VALUE rgeo_geos_polygons_eql(GEOSContextHandle_t context, const GEOSGeometry* geom1, const GEOSGeometry* geom2, char check_z)
307
+ {
308
+ VALUE result;
309
+ int len1;
310
+ int len2;
311
+ int i;
312
+
313
+ result = Qnil;
314
+ if (geom1 && geom2) {
315
+ result = rgeo_geos_coordseqs_eql(context, GEOSGetExteriorRing_r(context, geom1), GEOSGetExteriorRing_r(context, geom2), check_z);
316
+ if (RTEST(result)) {
317
+ len1 = GEOSGetNumInteriorRings_r(context, geom1);
318
+ len2 = GEOSGetNumInteriorRings_r(context, geom2);
319
+ if (len1 >= 0 && len2 >= 0) {
320
+ if (len1 == len2) {
321
+ for (i=0; i<len1; ++i) {
322
+ result = rgeo_geos_coordseqs_eql(context, GEOSGetInteriorRingN_r(context, geom1, i), GEOSGetInteriorRingN_r(context, geom2, i), check_z);
323
+ if (!RTEST(result)) {
324
+ break;
325
+ }
326
+ }
327
+ }
328
+ else {
329
+ result = Qfalse;
330
+ }
331
+ }
332
+ else {
333
+ result = Qnil;
334
+ }
335
+ }
336
+ }
337
+ return result;
338
+ }
339
+
340
+
341
+ st_index_t rgeo_geos_polygon_hash(GEOSContextHandle_t context, const GEOSGeometry* geom, st_index_t hash)
342
+ {
343
+ unsigned int len;
344
+ unsigned int i;
345
+
346
+ if (geom) {
347
+ hash = rgeo_geos_coordseq_hash(context, GEOSGetExteriorRing_r(context, geom), hash);
348
+ len = GEOSGetNumInteriorRings_r(context, geom);
349
+ for (i=0; i<len; ++i) {
350
+ hash = rgeo_geos_coordseq_hash(context, GEOSGetInteriorRingN_r(context, geom, i), hash);
351
+ }
352
+ }
353
+ return hash;
354
+ }
355
+
356
+
357
+ RGEO_END_C
358
+
359
+ #endif