rgeo 0.5.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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