rgeo 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,238 +0,0 @@
1
- /*
2
- Factory and utility functions for GEOS wrapper
3
- */
4
-
5
- #ifndef RGEO_GEOS_FACTORY_INCLUDED
6
- #define RGEO_GEOS_FACTORY_INCLUDED
7
-
8
- #include <ruby.h>
9
- #include <geos_c.h>
10
-
11
- RGEO_BEGIN_C
12
-
13
-
14
- /*
15
- Per-interpreter globals.
16
- Most of these are cached references to commonly used classes, modules,
17
- and symbols so we don't have to do a lot of constant lookups and calls
18
- to rb_intern.
19
- */
20
- typedef struct {
21
- VALUE feature_module;
22
- VALUE feature_geometry;
23
- VALUE feature_point;
24
- VALUE feature_line_string;
25
- VALUE feature_linear_ring;
26
- VALUE feature_line;
27
- VALUE feature_polygon;
28
- VALUE feature_geometry_collection;
29
- VALUE feature_multi_point;
30
- VALUE feature_multi_line_string;
31
- VALUE feature_multi_polygon;
32
- VALUE geos_module;
33
- VALUE geos_geometry;
34
- VALUE geos_point;
35
- VALUE geos_line_string;
36
- VALUE geos_linear_ring;
37
- VALUE geos_line;
38
- VALUE geos_polygon;
39
- VALUE geos_geometry_collection;
40
- VALUE geos_multi_point;
41
- VALUE geos_multi_line_string;
42
- VALUE geos_multi_polygon;
43
- ID id_cast;
44
- ID id_eql;
45
- ID id_generate;
46
- ID id_enum_for;
47
- ID id_hash;
48
- VALUE sym_force_new;
49
- VALUE sym_keep_subtype;
50
- #ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
51
- VALUE psych_wkt_generator;
52
- VALUE marshal_wkb_generator;
53
- #endif
54
- } RGeo_Globals;
55
-
56
-
57
- /*
58
- Wrapped structure for Factory objects.
59
- A factory encapsulates the GEOS context, and GEOS serializer settings.
60
- It also stores the SRID for all geometries created by this factory,
61
- and the resolution for buffers created for this factory's geometries.
62
- Finally, it provides easy access to the globals.
63
- */
64
- typedef struct {
65
- RGeo_Globals* globals;
66
- GEOSContextHandle_t geos_context;
67
- GEOSWKTReader* wkt_reader;
68
- GEOSWKBReader* wkb_reader;
69
- GEOSWKTWriter* wkt_writer;
70
- GEOSWKBWriter* wkb_writer;
71
- VALUE wkrep_wkt_generator;
72
- VALUE wkrep_wkb_generator;
73
- VALUE wkrep_wkt_parser;
74
- VALUE wkrep_wkb_parser;
75
- GEOSWKTReader* psych_wkt_reader;
76
- GEOSWKBReader* marshal_wkb_reader;
77
- GEOSWKTWriter* psych_wkt_writer;
78
- GEOSWKBWriter* marshal_wkb_writer;
79
- VALUE proj4_obj;
80
- VALUE coord_sys_obj;
81
- int flags;
82
- int srid;
83
- int buffer_resolution;
84
- } RGeo_FactoryData;
85
-
86
- #define RGEO_FACTORYFLAGS_LENIENT_MULTIPOLYGON 1
87
- #define RGEO_FACTORYFLAGS_SUPPORTS_Z 2
88
- #define RGEO_FACTORYFLAGS_SUPPORTS_M 4
89
- #define RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M 6
90
- #define RGEO_FACTORYFLAGS_PREPARE_HEURISTIC 8
91
-
92
-
93
- /*
94
- Wrapped structure for Geometry objects.
95
- Includes a handle to the underlying GEOS geometry itself (which could
96
- be null for an uninitialized geometry).
97
- It also provides a handle to the factory that created this geometry.
98
-
99
- The klasses object is used by geometry collections. Its value is
100
- generally an array of the ruby classes for the colletion's elements,
101
- so that we can reproduce the exact class for those elements in cases
102
- where the class cannot be inferred directly from the GEOS type (as
103
- in Line objects, which have no GEOS type). Any array element, or the
104
- array itself, could be Qnil, indicating fall back to the default
105
- inferred from the GEOS type.
106
-
107
- The GEOS context handle is also included here. Ideally, it would be
108
- available by following the factory reference and getting it from the
109
- factory data. However, one use case is in the destroy_geometry_func
110
- in factory.c, and Rubinius 1.1.1 seems to crash when you try to
111
- evaluate a DATA_PTR from that function, so we copy the context handle
112
- here so the destroy_geometry_func can get to it.
113
- */
114
- typedef struct {
115
- GEOSContextHandle_t geos_context;
116
- GEOSGeometry* geom;
117
- const GEOSPreparedGeometry* prep;
118
- VALUE factory;
119
- VALUE klasses;
120
- } RGeo_GeometryData;
121
-
122
-
123
- // Returns the RGeo_FactoryData* given a ruby Factory object
124
- #define RGEO_FACTORY_DATA_PTR(factory) ((RGeo_FactoryData*)DATA_PTR(factory))
125
-
126
- // Returns the RGeo_GeometryData* given a ruby Geometry object
127
- #define RGEO_GEOMETRY_DATA_PTR(geometry) ((RGeo_GeometryData*)DATA_PTR(geometry))
128
-
129
-
130
- /*
131
- Initializes the factory module. This should be called first in the
132
- initialization process.
133
- */
134
- RGeo_Globals* rgeo_init_geos_factory();
135
-
136
- /*
137
- Given a GEOS geometry handle, wraps it in a ruby Geometry object of the
138
- given klass. The geometry is then owned by the ruby object, so make sure
139
- you clone the GEOS object first if something else thinks it owns it.
140
- You may pass Qnil for the klass to have the klass auto-detected. (But
141
- note that it cannot auto-detect the Line type because GEOS doesn't
142
- explicitly represent that type-- it will come out as LineString.)
143
- You may also pass a ruby Array for the klass if the geometry is a
144
- collection of some sort. In this case, the array elements should be the
145
- classes for the elements of the collection.
146
- Returns Qnil if the wrapping failed for any reason.
147
- */
148
- VALUE rgeo_wrap_geos_geometry(VALUE factory, GEOSGeometry* geom, VALUE klass);
149
-
150
- /*
151
- Same as rgeo_wrap_geos_geometry except that it wraps a clone of the
152
- given geom, so the original geom doesn't change ownership.
153
- */
154
- VALUE rgeo_wrap_geos_geometry_clone(VALUE factory, const GEOSGeometry* geom, VALUE klass);
155
-
156
- /*
157
- Gets the GEOS geometry for a given ruby Geometry object. If the given
158
- ruby object is not a GEOS geometry implementation, it is converted to a
159
- GEOS implementation first. You may also optionally cast it to a type,
160
- specified by an appropriate feature module. Passing Qnil for the type
161
- disables this auto-cast. The returned GEOS geometry is owned by rgeo,
162
- and you should not dispose it or take ownership of it yourself.
163
- */
164
- const GEOSGeometry* rgeo_convert_to_geos_geometry(VALUE factory, VALUE obj, VALUE type);
165
-
166
- /*
167
- Gets a GEOS geometry for a given ruby Geometry object. You must provide
168
- a GEOS factory for the geometry; the object is cast to that factory if
169
- it is not already of it. You may also optionally cast it to a type,
170
- specified by an appropriate feature module. Passing Qnil for the type
171
- disables this auto-cast. The returned GEOS geometry is owned by the
172
- caller-- that is, if the original ruby object is already of the desired
173
- factory, the returned GEOS geometry is a clone of the original.
174
-
175
- If the klasses parameter is not NULL, its referent is set to the
176
- klasses saved in the original ruby Geometry object (if any), or else to
177
- the class of the converted GEOS object. This is so that you can use the
178
- result of this function to build a GEOS-backed clone of the original
179
- geometry, or to include the given geometry in a collection while keeping
180
- the klasses intact.
181
- */
182
- GEOSGeometry* rgeo_convert_to_detached_geos_geometry(VALUE obj, VALUE factory, VALUE type, VALUE* klasses);
183
-
184
- /*
185
- Returns 1 if the given ruby object is a GEOS Geometry implementation,
186
- or 0 if not.
187
- */
188
- char rgeo_is_geos_object(VALUE obj);
189
-
190
- /*
191
- Gets the underlying GEOS geometry for a given ruby object. Returns NULL
192
- if the given ruby object is not a GEOS geometry wrapper.
193
- */
194
- const GEOSGeometry* rgeo_get_geos_geometry_safe(VALUE obj);
195
-
196
- /*
197
- Compares the coordinate sequences for two given GEOS geometries.
198
- The two given geometries MUST be of types backed directly by
199
- coordinate sequences-- i.e. points or line strings.
200
- Returns Qtrue if the two coordinate sequences are equal, Qfalse
201
- if they are inequal, or Qnil if an error occurs.
202
- */
203
- VALUE rgeo_geos_coordseqs_eql(GEOSContextHandle_t context, const GEOSGeometry* geom1, const GEOSGeometry* geom2, char check_z);
204
-
205
- /*
206
- Compares the ruby classes and geometry factories of the two given ruby
207
- objects. Returns Qtrue if everything is equal (that is, the two objects
208
- are of the same type and factory), or Qfalse otherwise.
209
- */
210
- VALUE rgeo_geos_klasses_and_factories_eql(VALUE obj1, VALUE obj2);
211
-
212
- /*
213
- A tool for building up hash values.
214
- You must pass in the context, a geos geometry, and a seed hash.
215
- Returns an updated hash.
216
- This call is useful in sequence, and should be bracketed by calls to
217
- rb_hash_start and rb_hash_end.
218
- */
219
- st_index_t rgeo_geos_coordseq_hash(GEOSContextHandle_t context, const GEOSGeometry* geom, st_index_t hash);
220
-
221
- /*
222
- A tool for building up hash values.
223
- You must pass in a factory, a feature type module, and a seed hash.
224
- Returns an updated hash.
225
- This call is useful in sequence, and should be bracketed by calls to
226
- rb_hash_start and rb_hash_end.
227
- */
228
- st_index_t rgeo_geos_objbase_hash(VALUE factory, VALUE type_module, st_index_t hash);
229
-
230
- /*
231
- Internal tool for creating simple (FNV-1A 32 bit) hashes.
232
- */
233
- st_index_t rgeo_internal_memhash(const void* ptr, long len);
234
-
235
-
236
- RGEO_END_C
237
-
238
- #endif
@@ -1,1028 +0,0 @@
1
- /*
2
- Geometry base class methods for GEOS wrapper
3
- */
4
-
5
-
6
- #include "preface.h"
7
-
8
- #ifdef RGEO_GEOS_SUPPORTED
9
-
10
- #include <string.h>
11
- #include <ruby.h>
12
- #include <geos_c.h>
13
-
14
- #include "factory.h"
15
- #include "geometry.h"
16
-
17
- RGEO_BEGIN_C
18
-
19
-
20
- /**** INTERNAL UTILITY FUNCTIONS ****/
21
-
22
-
23
- // Determine the dimension of the given geometry. Empty collections have dimension -1.
24
- // Recursively checks collection elemenets.
25
-
26
- static int compute_dimension(GEOSContextHandle_t context, const GEOSGeometry* geom)
27
- {
28
- int result;
29
- int size;
30
- int i;
31
- int dim;
32
-
33
- result = -1;
34
- if (geom) {
35
- switch (GEOSGeomTypeId_r(context, geom)) {
36
- case GEOS_POINT:
37
- result = 0;
38
- break;
39
- case GEOS_MULTIPOINT:
40
- if (!GEOSisEmpty_r(context, geom)) {
41
- result = 0;
42
- }
43
- break;
44
- case GEOS_LINESTRING:
45
- case GEOS_LINEARRING:
46
- result = 1;
47
- break;
48
- case GEOS_MULTILINESTRING:
49
- if (!GEOSisEmpty_r(context, geom)) {
50
- result = 1;
51
- }
52
- break;
53
- case GEOS_POLYGON:
54
- result = 2;
55
- break;
56
- case GEOS_MULTIPOLYGON:
57
- if (!GEOSisEmpty_r(context, geom)) {
58
- result = 2;
59
- }
60
- break;
61
- case GEOS_GEOMETRYCOLLECTION:
62
- size = GEOSGetNumGeometries_r(context, geom);
63
- for (i=0; i<size; ++i) {
64
- dim = compute_dimension(context, GEOSGetGeometryN_r(context, geom, i));
65
- if (dim > result) {
66
- result = dim;
67
- }
68
- }
69
- break;
70
- }
71
- }
72
- return result;
73
- }
74
-
75
-
76
- // Returns a prepared geometry, honoring the preparation policy.
77
-
78
- static const GEOSPreparedGeometry* rgeo_request_prepared_geometry(RGeo_GeometryData* object_data)
79
- {
80
- const GEOSPreparedGeometry* prep;
81
-
82
- prep = object_data->prep;
83
- if (prep == (const GEOSPreparedGeometry*)1) {
84
- object_data->prep = (GEOSPreparedGeometry*)2;
85
- prep = NULL;
86
- }
87
- else if (prep == (const GEOSPreparedGeometry*)2) {
88
- if (object_data->geom) {
89
- prep = GEOSPrepare_r(object_data->geos_context, object_data->geom);
90
- }
91
- else {
92
- prep = NULL;
93
- }
94
- if (prep) {
95
- object_data->prep = prep;
96
- }
97
- else {
98
- object_data->prep = (const GEOSPreparedGeometry*)3;
99
- }
100
- }
101
- else if (prep == (const GEOSPreparedGeometry*)3) {
102
- prep = NULL;
103
- }
104
- return prep;
105
- }
106
-
107
-
108
- /**** RUBY METHOD DEFINITIONS ****/
109
-
110
-
111
- static VALUE method_geometry_initialized_p(VALUE self)
112
- {
113
- return RGEO_GEOMETRY_DATA_PTR(self)->geom ? Qtrue : Qfalse;
114
- }
115
-
116
-
117
- static VALUE method_geometry_factory(VALUE self)
118
- {
119
- return RGEO_GEOMETRY_DATA_PTR(self)->factory;
120
- }
121
-
122
-
123
- static VALUE method_geometry_set_factory(VALUE self, VALUE factory)
124
- {
125
- RGEO_GEOMETRY_DATA_PTR(self)->factory = factory;
126
- return factory;
127
- }
128
-
129
-
130
- static VALUE method_geometry_prepared_p(VALUE self)
131
- {
132
- const GEOSPreparedGeometry* prep;
133
-
134
- prep = RGEO_GEOMETRY_DATA_PTR(self)->prep;
135
- return (prep && prep != (const GEOSPreparedGeometry*)1 &&
136
- prep != (const GEOSPreparedGeometry*)2 &&
137
- prep != (GEOSPreparedGeometry*)3) ? Qtrue : Qfalse;
138
- }
139
-
140
-
141
- static VALUE method_geometry_prepare(VALUE self)
142
- {
143
- RGeo_GeometryData* self_data;
144
- const GEOSPreparedGeometry* prep;
145
-
146
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
147
- if (self_data->geom) {
148
- prep = self_data->prep;
149
- if (!prep || prep == (const GEOSPreparedGeometry*)1 || prep == (const GEOSPreparedGeometry*)2) {
150
- prep = GEOSPrepare_r(self_data->geos_context, self_data->geom);
151
- if (prep) {
152
- self_data->prep = prep;
153
- }
154
- else {
155
- self_data->prep = (const GEOSPreparedGeometry*)3;
156
- }
157
- }
158
- }
159
- return self;
160
- }
161
-
162
-
163
- static VALUE method_geometry_dimension(VALUE self)
164
- {
165
- VALUE result;
166
- RGeo_GeometryData* self_data;
167
- const GEOSGeometry* self_geom;
168
-
169
- result = Qnil;
170
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
171
- self_geom = self_data->geom;
172
- if (self_geom) {
173
- result = INT2NUM(compute_dimension(self_data->geos_context, self_geom));
174
- }
175
- return result;
176
- }
177
-
178
-
179
- static VALUE method_geometry_geometry_type(VALUE self)
180
- {
181
- VALUE result;
182
- RGeo_GeometryData* self_data;
183
- const GEOSGeometry* self_geom;
184
-
185
- result = Qnil;
186
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
187
- self_geom = self_data->geom;
188
- if (self_geom) {
189
- result = RGEO_FACTORY_DATA_PTR(self_data->factory)->globals->feature_geometry;
190
- }
191
- return result;
192
- }
193
-
194
-
195
- static VALUE method_geometry_srid(VALUE self)
196
- {
197
- VALUE result;
198
- RGeo_GeometryData* self_data;
199
- const GEOSGeometry* self_geom;
200
-
201
- result = Qnil;
202
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
203
- self_geom = self_data->geom;
204
- if (self_geom) {
205
- result = INT2NUM(GEOSGetSRID_r(self_data->geos_context, self_geom));
206
- }
207
- return result;
208
- }
209
-
210
-
211
- static VALUE method_geometry_envelope(VALUE self)
212
- {
213
- VALUE result;
214
- RGeo_GeometryData* self_data;
215
- const GEOSGeometry* self_geom;
216
- GEOSContextHandle_t geos_context;
217
- GEOSGeometry* envelope;
218
-
219
- result = Qnil;
220
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
221
- self_geom = self_data->geom;
222
- if (self_geom) {
223
- geos_context = self_data->geos_context;
224
- envelope = GEOSEnvelope_r(geos_context, self_geom);
225
- if (!envelope) {
226
- envelope = GEOSGeom_createCollection_r(geos_context, GEOS_GEOMETRYCOLLECTION, NULL, 0);
227
- }
228
- result = rgeo_wrap_geos_geometry(self_data->factory, envelope, Qnil);
229
- }
230
- return result;
231
- }
232
-
233
-
234
- static VALUE method_geometry_boundary(VALUE self)
235
- {
236
- VALUE result;
237
- RGeo_GeometryData* self_data;
238
- const GEOSGeometry* self_geom;
239
- GEOSContextHandle_t geos_context;
240
- GEOSGeometry* boundary;
241
-
242
- result = Qnil;
243
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
244
- self_geom = self_data->geom;
245
- if (self_geom) {
246
- geos_context = self_data->geos_context;
247
- boundary = GEOSBoundary_r(geos_context, self_geom);
248
- if (boundary) {
249
- result = rgeo_wrap_geos_geometry(self_data->factory, boundary, Qnil);
250
- }
251
- }
252
- return result;
253
- }
254
-
255
-
256
- static VALUE method_geometry_as_text(VALUE self)
257
- {
258
- VALUE result;
259
- RGeo_GeometryData* self_data;
260
- const GEOSGeometry* self_geom;
261
- RGeo_FactoryData* factory_data;
262
- VALUE wkt_generator;
263
- GEOSWKTWriter* wkt_writer;
264
- GEOSContextHandle_t geos_context;
265
- char* str;
266
-
267
- result = Qnil;
268
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
269
- self_geom = self_data->geom;
270
- if (self_geom) {
271
- factory_data = RGEO_FACTORY_DATA_PTR(self_data->factory);
272
- wkt_generator = factory_data->wkrep_wkt_generator;
273
- if (!NIL_P(wkt_generator)) {
274
- result = rb_funcall(wkt_generator, factory_data->globals->id_generate, 1, self);
275
- }
276
- else {
277
- wkt_writer = factory_data->wkt_writer;
278
- geos_context = self_data->geos_context;
279
- if (!wkt_writer) {
280
- wkt_writer = GEOSWKTWriter_create_r(geos_context);
281
- factory_data->wkt_writer = wkt_writer;
282
- }
283
- str = GEOSWKTWriter_write_r(geos_context, wkt_writer, self_geom);
284
- if (str) {
285
- result = rb_str_new2(str);
286
- GEOSFree_r(geos_context, str);
287
- }
288
- }
289
- }
290
- return result;
291
- }
292
-
293
-
294
- static VALUE method_geometry_as_binary(VALUE self)
295
- {
296
- VALUE result;
297
- RGeo_GeometryData* self_data;
298
- const GEOSGeometry* self_geom;
299
- RGeo_FactoryData* factory_data;
300
- VALUE wkb_generator;
301
- GEOSWKBWriter* wkb_writer;
302
- GEOSContextHandle_t geos_context;
303
- size_t size;
304
- char* str;
305
-
306
- result = Qnil;
307
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
308
- self_geom = self_data->geom;
309
- if (self_geom) {
310
- factory_data = RGEO_FACTORY_DATA_PTR(self_data->factory);
311
- wkb_generator = factory_data->wkrep_wkb_generator;
312
- if (!NIL_P(wkb_generator)) {
313
- result = rb_funcall(wkb_generator, factory_data->globals->id_generate, 1, self);
314
- }
315
- else {
316
- wkb_writer = factory_data->wkb_writer;
317
- geos_context = self_data->geos_context;
318
- if (!wkb_writer) {
319
- wkb_writer = GEOSWKBWriter_create_r(geos_context);
320
- factory_data->wkb_writer = wkb_writer;
321
- }
322
- str = (char*)GEOSWKBWriter_write_r(geos_context, wkb_writer, self_geom, &size);
323
- if (str) {
324
- result = rb_str_new(str, size);
325
- GEOSFree_r(geos_context, str);
326
- }
327
- }
328
- }
329
- return result;
330
- }
331
-
332
-
333
- static VALUE method_geometry_is_empty(VALUE self)
334
- {
335
- VALUE result;
336
- RGeo_GeometryData* self_data;
337
- const GEOSGeometry* self_geom;
338
- char val;
339
-
340
- result = Qnil;
341
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
342
- self_geom = self_data->geom;
343
- if (self_geom) {
344
- val = GEOSisEmpty_r(self_data->geos_context, self_geom);
345
- if (val == 0) {
346
- result = Qfalse;
347
- }
348
- else if (val == 1) {
349
- result = Qtrue;
350
- }
351
- }
352
- return result;
353
- }
354
-
355
-
356
- static VALUE method_geometry_is_simple(VALUE self)
357
- {
358
- VALUE result;
359
- RGeo_GeometryData* self_data;
360
- const GEOSGeometry* self_geom;
361
- char val;
362
-
363
- result = Qnil;
364
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
365
- self_geom = self_data->geom;
366
- if (self_geom) {
367
- val = GEOSisSimple_r(self_data->geos_context, self_geom);
368
- if (val == 0) {
369
- result = Qfalse;
370
- }
371
- else if (val == 1) {
372
- result = Qtrue;
373
- }
374
- }
375
- return result;
376
- }
377
-
378
-
379
- static VALUE method_geometry_equals(VALUE self, VALUE rhs)
380
- {
381
- VALUE result;
382
- RGeo_GeometryData* self_data;
383
- const GEOSGeometry* self_geom;
384
- const GEOSGeometry* rhs_geom;
385
- GEOSContextHandle_t self_context;
386
- char val;
387
-
388
- result = Qnil;
389
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
390
- self_geom = self_data->geom;
391
- if (self_geom) {
392
- rhs_geom = rgeo_get_geos_geometry_safe(rhs);
393
- if (rhs_geom) {
394
- self_context = self_data->geos_context;
395
- // GEOS has a bug where empty geometries are not spatially equal
396
- // to each other. Work around this case first.
397
- if (GEOSisEmpty_r(self_context, self_geom) == 1 &&
398
- GEOSisEmpty_r(RGEO_GEOMETRY_DATA_PTR(rhs)->geos_context, rhs_geom) == 1) {
399
- result = Qtrue;
400
- }
401
- else {
402
- val = GEOSEquals_r(self_context, self_geom, rhs_geom);
403
- if (val == 0) {
404
- result = Qfalse;
405
- }
406
- else if (val == 1) {
407
- result = Qtrue;
408
- }
409
- }
410
- }
411
- }
412
- return result;
413
- }
414
-
415
-
416
- static VALUE method_geometry_eql(VALUE self, VALUE rhs)
417
- {
418
- // This should be overridden by the subclass.
419
- return self == rhs ? Qtrue : Qfalse;
420
- }
421
-
422
-
423
- static VALUE method_geometry_disjoint(VALUE self, VALUE rhs)
424
- {
425
- VALUE result;
426
- RGeo_GeometryData* self_data;
427
- const GEOSGeometry* self_geom;
428
- const GEOSGeometry* rhs_geom;
429
- char val;
430
- #ifdef RGEO_GEOS_SUPPORTS_PREPARED2
431
- const GEOSPreparedGeometry* prep;
432
- #endif
433
-
434
- result = Qnil;
435
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
436
- self_geom = self_data->geom;
437
- if (self_geom) {
438
- rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
439
- if (rhs_geom) {
440
- #ifdef RGEO_GEOS_SUPPORTS_PREPARED2
441
- prep = rgeo_request_prepared_geometry(self_data);
442
- if (prep)
443
- val = GEOSPreparedDisjoint_r(self_data->geos_context, prep, rhs_geom);
444
- else
445
- #endif
446
- val = GEOSDisjoint_r(self_data->geos_context, self_geom, rhs_geom);
447
- if (val == 0) {
448
- result = Qfalse;
449
- }
450
- else if (val == 1) {
451
- result = Qtrue;
452
- }
453
- }
454
- }
455
- return result;
456
- }
457
-
458
-
459
- static VALUE method_geometry_intersects(VALUE self, VALUE rhs)
460
- {
461
- VALUE result;
462
- RGeo_GeometryData* self_data;
463
- const GEOSGeometry* self_geom;
464
- const GEOSGeometry* rhs_geom;
465
- char val;
466
- #ifdef RGEO_GEOS_SUPPORTS_PREPARED1
467
- const GEOSPreparedGeometry* prep;
468
- #endif
469
-
470
- result = Qnil;
471
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
472
- self_geom = self_data->geom;
473
- if (self_geom) {
474
- rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
475
- if (rhs_geom) {
476
- #ifdef RGEO_GEOS_SUPPORTS_PREPARED1
477
- prep = rgeo_request_prepared_geometry(self_data);
478
- if (prep)
479
- val = GEOSPreparedIntersects_r(self_data->geos_context, prep, rhs_geom);
480
- else
481
- #endif
482
- val = GEOSIntersects_r(self_data->geos_context, self_geom, rhs_geom);
483
- if (val == 0) {
484
- result = Qfalse;
485
- }
486
- else if (val == 1) {
487
- result = Qtrue;
488
- }
489
- }
490
- }
491
- return result;
492
- }
493
-
494
-
495
- static VALUE method_geometry_touches(VALUE self, VALUE rhs)
496
- {
497
- VALUE result;
498
- RGeo_GeometryData* self_data;
499
- const GEOSGeometry* self_geom;
500
- const GEOSGeometry* rhs_geom;
501
- char val;
502
- #ifdef RGEO_GEOS_SUPPORTS_PREPARED2
503
- const GEOSPreparedGeometry* prep;
504
- #endif
505
-
506
- result = Qnil;
507
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
508
- self_geom = self_data->geom;
509
- if (self_geom) {
510
- rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
511
- if (rhs_geom) {
512
- #ifdef RGEO_GEOS_SUPPORTS_PREPARED2
513
- prep = rgeo_request_prepared_geometry(self_data);
514
- if (prep)
515
- val = GEOSPreparedTouches_r(self_data->geos_context, prep, rhs_geom);
516
- else
517
- #endif
518
- val = GEOSTouches_r(self_data->geos_context, self_geom, rhs_geom);
519
- if (val == 0) {
520
- result = Qfalse;
521
- }
522
- else if (val == 1) {
523
- result = Qtrue;
524
- }
525
- }
526
- }
527
- return result;
528
- }
529
-
530
-
531
- static VALUE method_geometry_crosses(VALUE self, VALUE rhs)
532
- {
533
- VALUE result;
534
- RGeo_GeometryData* self_data;
535
- const GEOSGeometry* self_geom;
536
- const GEOSGeometry* rhs_geom;
537
- char val;
538
- #ifdef RGEO_GEOS_SUPPORTS_PREPARED2
539
- const GEOSPreparedGeometry* prep;
540
- #endif
541
-
542
- result = Qnil;
543
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
544
- self_geom = self_data->geom;
545
- if (self_geom) {
546
- rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
547
- if (rhs_geom) {
548
- #ifdef RGEO_GEOS_SUPPORTS_PREPARED2
549
- prep = rgeo_request_prepared_geometry(self_data);
550
- if (prep)
551
- val = GEOSPreparedCrosses_r(self_data->geos_context, prep, rhs_geom);
552
- else
553
- #endif
554
- val = GEOSCrosses_r(self_data->geos_context, self_geom, rhs_geom);
555
- if (val == 0) {
556
- result = Qfalse;
557
- }
558
- else if (val == 1) {
559
- result = Qtrue;
560
- }
561
- }
562
- }
563
- return result;
564
- }
565
-
566
-
567
- static VALUE method_geometry_within(VALUE self, VALUE rhs)
568
- {
569
- VALUE result;
570
- RGeo_GeometryData* self_data;
571
- const GEOSGeometry* self_geom;
572
- const GEOSGeometry* rhs_geom;
573
- char val;
574
- #ifdef RGEO_GEOS_SUPPORTS_PREPARED2
575
- const GEOSPreparedGeometry* prep;
576
- #endif
577
-
578
- result = Qnil;
579
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
580
- self_geom = self_data->geom;
581
- if (self_geom) {
582
- rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
583
- if (rhs_geom) {
584
- #ifdef RGEO_GEOS_SUPPORTS_PREPARED2
585
- prep = rgeo_request_prepared_geometry(self_data);
586
- if (prep)
587
- val = GEOSPreparedWithin_r(self_data->geos_context, prep, rhs_geom);
588
- else
589
- #endif
590
- val = GEOSWithin_r(self_data->geos_context, self_geom, rhs_geom);
591
- if (val == 0) {
592
- result = Qfalse;
593
- }
594
- else if (val == 1) {
595
- result = Qtrue;
596
- }
597
- }
598
- }
599
- return result;
600
- }
601
-
602
-
603
- static VALUE method_geometry_contains(VALUE self, VALUE rhs)
604
- {
605
- VALUE result;
606
- RGeo_GeometryData* self_data;
607
- const GEOSGeometry* self_geom;
608
- const GEOSGeometry* rhs_geom;
609
- char val;
610
- #ifdef RGEO_GEOS_SUPPORTS_PREPARED1
611
- const GEOSPreparedGeometry* prep;
612
- #endif
613
-
614
- result = Qnil;
615
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
616
- self_geom = self_data->geom;
617
- if (self_geom) {
618
- rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
619
- if (rhs_geom) {
620
- #ifdef RGEO_GEOS_SUPPORTS_PREPARED1
621
- prep = rgeo_request_prepared_geometry(self_data);
622
- if (prep)
623
- val = GEOSPreparedContains_r(self_data->geos_context, prep, rhs_geom);
624
- else
625
- #endif
626
- val = GEOSContains_r(self_data->geos_context, self_geom, rhs_geom);
627
- if (val == 0) {
628
- result = Qfalse;
629
- }
630
- else if (val == 1) {
631
- result = Qtrue;
632
- }
633
- }
634
- }
635
- return result;
636
- }
637
-
638
-
639
- static VALUE method_geometry_overlaps(VALUE self, VALUE rhs)
640
- {
641
- VALUE result;
642
- RGeo_GeometryData* self_data;
643
- const GEOSGeometry* self_geom;
644
- const GEOSGeometry* rhs_geom;
645
- char val;
646
- #ifdef RGEO_GEOS_SUPPORTS_PREPARED2
647
- const GEOSPreparedGeometry* prep;
648
- #endif
649
-
650
- result = Qnil;
651
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
652
- self_geom = self_data->geom;
653
- if (self_geom) {
654
- rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
655
- if (rhs_geom) {
656
- #ifdef RGEO_GEOS_SUPPORTS_PREPARED2
657
- prep = rgeo_request_prepared_geometry(self_data);
658
- if (prep)
659
- val = GEOSPreparedOverlaps_r(self_data->geos_context, prep, rhs_geom);
660
- else
661
- #endif
662
- val = GEOSOverlaps_r(self_data->geos_context, self_geom, rhs_geom);
663
- if (val == 0) {
664
- result = Qfalse;
665
- }
666
- else if (val == 1) {
667
- result = Qtrue;
668
- }
669
- }
670
- }
671
- return result;
672
- }
673
-
674
-
675
- static VALUE method_geometry_relate(VALUE self, VALUE rhs, VALUE pattern)
676
- {
677
- VALUE result;
678
- RGeo_GeometryData* self_data;
679
- const GEOSGeometry* self_geom;
680
- const GEOSGeometry* rhs_geom;
681
- char val;
682
-
683
- result = Qnil;
684
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
685
- self_geom = self_data->geom;
686
- if (self_geom) {
687
- rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
688
- if (rhs_geom) {
689
- val = GEOSRelatePattern_r(self_data->geos_context, self_geom, rhs_geom, StringValuePtr(pattern));
690
- if (val == 0) {
691
- result = Qfalse;
692
- }
693
- else if (val == 1) {
694
- result = Qtrue;
695
- }
696
- }
697
- }
698
- return result;
699
- }
700
-
701
-
702
- static VALUE method_geometry_distance(VALUE self, VALUE rhs)
703
- {
704
- VALUE result;
705
- RGeo_GeometryData* self_data;
706
- const GEOSGeometry* self_geom;
707
- const GEOSGeometry* rhs_geom;
708
- double dist;
709
-
710
- result = Qnil;
711
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
712
- self_geom = self_data->geom;
713
- if (self_geom) {
714
- rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
715
- if (rhs_geom) {
716
- if (GEOSDistance_r(self_data->geos_context, self_geom, rhs_geom, &dist)) {
717
- result = rb_float_new(dist);
718
- }
719
- }
720
- }
721
- return result;
722
- }
723
-
724
-
725
- static VALUE method_geometry_buffer(VALUE self, VALUE distance)
726
- {
727
- VALUE result;
728
- RGeo_GeometryData* self_data;
729
- const GEOSGeometry* self_geom;
730
- VALUE factory;
731
- int resolution;
732
-
733
- result = Qnil;
734
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
735
- self_geom = self_data->geom;
736
- if (self_geom) {
737
- factory = self_data->factory;
738
- result = rgeo_wrap_geos_geometry(factory, GEOSBuffer_r(self_data->geos_context, self_geom,
739
- rb_num2dbl(distance), RGEO_FACTORY_DATA_PTR(factory)->buffer_resolution), Qnil);
740
- }
741
- return result;
742
- }
743
-
744
- static VALUE method_geometry_buffer_with_style(VALUE self, VALUE distance, VALUE endCapStyle, VALUE joinStyle, VALUE mitreLimit)
745
- {
746
- VALUE result;
747
- RGeo_GeometryData* self_data;
748
- const GEOSGeometry* self_geom;
749
- VALUE factory;
750
- int resolution;
751
-
752
- result = Qnil;
753
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
754
- self_geom = self_data->geom;
755
- if (self_geom) {
756
- factory = self_data->factory;
757
- result = rgeo_wrap_geos_geometry(factory,
758
- GEOSBufferWithStyle_r(self_data->geos_context, self_geom,
759
- rb_num2dbl(distance),
760
- RGEO_FACTORY_DATA_PTR(factory)->buffer_resolution,
761
- endCapStyle, joinStyle, mitreLimit),
762
- Qnil);
763
- }
764
- return result;
765
- }
766
-
767
- static VALUE method_geometry_simplify(VALUE self, VALUE tolerance)
768
- {
769
- VALUE result;
770
- RGeo_GeometryData* self_data;
771
- const GEOSGeometry* self_geom;
772
- VALUE factory;
773
-
774
- result = Qnil;
775
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
776
- self_geom = self_data->geom;
777
- if (self_geom) {
778
- factory = self_data->factory;
779
- result = rgeo_wrap_geos_geometry(factory, GEOSSimplify_r(self_data->geos_context, self_geom,
780
- rb_num2dbl(tolerance)), Qnil);
781
- }
782
- return result;
783
- }
784
-
785
-
786
- static VALUE method_geometry_convex_hull(VALUE self)
787
- {
788
- VALUE result;
789
- RGeo_GeometryData* self_data;
790
- const GEOSGeometry* self_geom;
791
-
792
- result = Qnil;
793
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
794
- self_geom = self_data->geom;
795
- if (self_geom) {
796
- result = rgeo_wrap_geos_geometry(self_data->factory, GEOSConvexHull_r(self_data->geos_context, self_geom), Qnil);
797
- }
798
- return result;
799
- }
800
-
801
-
802
- static VALUE method_geometry_intersection(VALUE self, VALUE rhs)
803
- {
804
- VALUE result;
805
- RGeo_GeometryData* self_data;
806
- const GEOSGeometry* self_geom;
807
- VALUE factory;
808
- const GEOSGeometry* rhs_geom;
809
-
810
- result = Qnil;
811
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
812
- self_geom = self_data->geom;
813
- if (self_geom) {
814
- factory = self_data->factory;
815
- rhs_geom = rgeo_convert_to_geos_geometry(factory, rhs, Qnil);
816
- if (rhs_geom) {
817
- result = rgeo_wrap_geos_geometry(factory, GEOSIntersection_r(self_data->geos_context, self_geom, rhs_geom), Qnil);
818
- }
819
- }
820
- return result;
821
- }
822
-
823
-
824
- static VALUE method_geometry_union(VALUE self, VALUE rhs)
825
- {
826
- VALUE result;
827
- RGeo_GeometryData* self_data;
828
- const GEOSGeometry* self_geom;
829
- VALUE factory;
830
- const GEOSGeometry* rhs_geom;
831
-
832
- result = Qnil;
833
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
834
- self_geom = self_data->geom;
835
- if (self_geom) {
836
- factory = self_data->factory;
837
- rhs_geom = rgeo_convert_to_geos_geometry(factory, rhs, Qnil);
838
- if (rhs_geom) {
839
- result = rgeo_wrap_geos_geometry(factory, GEOSUnion_r(self_data->geos_context, self_geom, rhs_geom), Qnil);
840
- }
841
- }
842
- return result;
843
- }
844
-
845
-
846
- static VALUE method_geometry_difference(VALUE self, VALUE rhs)
847
- {
848
- VALUE result;
849
- RGeo_GeometryData* self_data;
850
- const GEOSGeometry* self_geom;
851
- VALUE factory;
852
- const GEOSGeometry* rhs_geom;
853
-
854
- result = Qnil;
855
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
856
- self_geom = self_data->geom;
857
- if (self_geom) {
858
- factory = self_data->factory;
859
- rhs_geom = rgeo_convert_to_geos_geometry(factory, rhs, Qnil);
860
- if (rhs_geom) {
861
- result = rgeo_wrap_geos_geometry(factory, GEOSDifference_r(self_data->geos_context, self_geom, rhs_geom), Qnil);
862
- }
863
- }
864
- return result;
865
- }
866
-
867
-
868
- static VALUE method_geometry_sym_difference(VALUE self, VALUE rhs)
869
- {
870
- VALUE result;
871
- RGeo_GeometryData* self_data;
872
- const GEOSGeometry* self_geom;
873
- VALUE factory;
874
- const GEOSGeometry* rhs_geom;
875
-
876
- result = Qnil;
877
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
878
- self_geom = self_data->geom;
879
- if (self_geom) {
880
- factory = self_data->factory;
881
- rhs_geom = rgeo_convert_to_geos_geometry(factory, rhs, Qnil);
882
- if (rhs_geom) {
883
- result = rgeo_wrap_geos_geometry(factory, GEOSSymDifference_r(self_data->geos_context, self_geom, rhs_geom), Qnil);
884
- }
885
- }
886
- return result;
887
- }
888
-
889
-
890
- static VALUE method_geometry_initialize_copy(VALUE self, VALUE orig)
891
- {
892
- RGeo_GeometryData* self_data;
893
- const GEOSPreparedGeometry* prep;
894
- const GEOSGeometry* geom;
895
- RGeo_GeometryData* orig_data;
896
- GEOSContextHandle_t orig_context;
897
- GEOSGeometry* clone_geom;
898
- RGeo_FactoryData* factory_data;
899
-
900
- // Clear out any existing value
901
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
902
- if (self_data->geom) {
903
- GEOSGeom_destroy_r(self_data->geos_context, self_data->geom);
904
- self_data->geom = NULL;
905
- }
906
- prep = self_data->prep;
907
- if (prep && prep != (GEOSPreparedGeometry*)1 && prep != (GEOSPreparedGeometry*)2) {
908
- GEOSPreparedGeom_destroy_r(self_data->geos_context, prep);
909
- }
910
- self_data->prep = NULL;
911
- self_data->geos_context = NULL;
912
- self_data->factory = Qnil;
913
- self_data->klasses = Qnil;
914
-
915
- // Copy value from orig
916
- geom = rgeo_get_geos_geometry_safe(orig);
917
- if (geom) {
918
- orig_data = RGEO_GEOMETRY_DATA_PTR(orig);
919
- orig_context = orig_data->geos_context;
920
- clone_geom = GEOSGeom_clone_r(orig_context, geom);
921
- if (clone_geom) {
922
- factory_data = RGEO_FACTORY_DATA_PTR(orig_data->factory);
923
- GEOSSetSRID_r(orig_context, clone_geom, GEOSGetSRID_r(orig_context, geom));
924
- self_data->geom = clone_geom;
925
- self_data->geos_context = orig_context;
926
- self_data->prep = factory_data && ((factory_data->flags & RGEO_FACTORYFLAGS_PREPARE_HEURISTIC) != 0) ?
927
- (GEOSPreparedGeometry*)1 : NULL;
928
- self_data->factory = orig_data->factory;
929
- self_data->klasses = orig_data->klasses;
930
- }
931
- }
932
- return self;
933
- }
934
-
935
-
936
- static VALUE method_geometry_steal(VALUE self, VALUE orig)
937
- {
938
- RGeo_GeometryData* self_data;
939
- const GEOSPreparedGeometry* prep;
940
- const GEOSGeometry* geom;
941
- RGeo_GeometryData* orig_data;
942
-
943
- geom = rgeo_get_geos_geometry_safe(orig);
944
- if (geom) {
945
- // Clear out any existing value
946
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
947
- if (self_data->geom) {
948
- GEOSGeom_destroy_r(self_data->geos_context, self_data->geom);
949
- }
950
- prep = self_data->prep;
951
- if (prep && prep != (GEOSPreparedGeometry*)1 && prep != (GEOSPreparedGeometry*)2) {
952
- GEOSPreparedGeom_destroy_r(self_data->geos_context, prep);
953
- }
954
-
955
- // Steal value from orig
956
- orig_data = RGEO_GEOMETRY_DATA_PTR(orig);
957
- self_data->geom = orig_data->geom;
958
- self_data->prep = orig_data->prep;
959
- self_data->geos_context = orig_data->geos_context;
960
- self_data->factory = orig_data->factory;
961
- self_data->klasses = orig_data->klasses;
962
-
963
- // Clear out orig
964
- orig_data->geom = NULL;
965
- orig_data->prep = NULL;
966
- orig_data->geos_context = NULL;
967
- orig_data->factory = Qnil;
968
- orig_data->klasses = Qnil;
969
- }
970
- return self;
971
- }
972
-
973
-
974
- /**** INITIALIZATION FUNCTION ****/
975
-
976
-
977
- void rgeo_init_geos_geometry(RGeo_Globals* globals)
978
- {
979
- VALUE geos_geometry_methods;
980
-
981
- geos_geometry_methods = rb_define_module_under(globals->geos_module, "CAPIGeometryMethods");
982
-
983
- rb_define_method(geos_geometry_methods, "_set_factory", method_geometry_set_factory, 1);
984
- rb_define_method(geos_geometry_methods, "initialize_copy", method_geometry_initialize_copy, 1);
985
- rb_define_method(geos_geometry_methods, "_steal", method_geometry_steal, 1);
986
- rb_define_method(geos_geometry_methods, "initialized?", method_geometry_initialized_p, 0);
987
- rb_define_method(geos_geometry_methods, "factory", method_geometry_factory, 0);
988
- rb_define_method(geos_geometry_methods, "prepared?", method_geometry_prepared_p, 0);
989
- rb_define_method(geos_geometry_methods, "prepare!", method_geometry_prepare, 0);
990
- rb_define_method(geos_geometry_methods, "dimension", method_geometry_dimension, 0);
991
- rb_define_method(geos_geometry_methods, "geometry_type", method_geometry_geometry_type, 0);
992
- rb_define_method(geos_geometry_methods, "srid", method_geometry_srid, 0);
993
- rb_define_method(geos_geometry_methods, "envelope", method_geometry_envelope, 0);
994
- rb_define_method(geos_geometry_methods, "boundary", method_geometry_boundary, 0);
995
- rb_define_method(geos_geometry_methods, "_as_text", method_geometry_as_text, 0);
996
- rb_define_method(geos_geometry_methods, "as_binary", method_geometry_as_binary, 0);
997
- rb_define_method(geos_geometry_methods, "is_empty?", method_geometry_is_empty, 0);
998
- rb_define_method(geos_geometry_methods, "is_simple?", method_geometry_is_simple, 0);
999
- rb_define_method(geos_geometry_methods, "equals?", method_geometry_equals, 1);
1000
- rb_define_method(geos_geometry_methods, "==", method_geometry_equals, 1);
1001
- rb_define_method(geos_geometry_methods, "rep_equals?", method_geometry_eql, 1);
1002
- rb_define_method(geos_geometry_methods, "eql?", method_geometry_eql, 1);
1003
- rb_define_method(geos_geometry_methods, "disjoint?", method_geometry_disjoint, 1);
1004
- rb_define_method(geos_geometry_methods, "intersects?", method_geometry_intersects, 1);
1005
- rb_define_method(geos_geometry_methods, "touches?", method_geometry_touches, 1);
1006
- rb_define_method(geos_geometry_methods, "crosses?", method_geometry_crosses, 1);
1007
- rb_define_method(geos_geometry_methods, "within?", method_geometry_within, 1);
1008
- rb_define_method(geos_geometry_methods, "contains?", method_geometry_contains, 1);
1009
- rb_define_method(geos_geometry_methods, "overlaps?", method_geometry_overlaps, 1);
1010
- rb_define_method(geos_geometry_methods, "relate?", method_geometry_relate, 2);
1011
- rb_define_method(geos_geometry_methods, "distance", method_geometry_distance, 1);
1012
- rb_define_method(geos_geometry_methods, "buffer", method_geometry_buffer, 1);
1013
- rb_define_method(geos_geometry_methods, "buffer_with_style", method_geometry_buffer_with_style, 4);
1014
- rb_define_method(geos_geometry_methods, "simplify", method_geometry_simplify, 1);
1015
- rb_define_method(geos_geometry_methods, "convex_hull", method_geometry_convex_hull, 0);
1016
- rb_define_method(geos_geometry_methods, "intersection", method_geometry_intersection, 1);
1017
- rb_define_method(geos_geometry_methods, "*", method_geometry_intersection, 1);
1018
- rb_define_method(geos_geometry_methods, "union", method_geometry_union, 1);
1019
- rb_define_method(geos_geometry_methods, "+", method_geometry_union, 1);
1020
- rb_define_method(geos_geometry_methods, "difference", method_geometry_difference, 1);
1021
- rb_define_method(geos_geometry_methods, "-", method_geometry_difference, 1);
1022
- rb_define_method(geos_geometry_methods, "sym_difference", method_geometry_sym_difference, 1);
1023
- }
1024
-
1025
-
1026
- RGEO_END_C
1027
-
1028
- #endif