rgeo 2.1.1 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +160 -0
- data/ext/geos_c_impl/analysis.c +80 -0
- data/ext/geos_c_impl/analysis.h +40 -0
- data/ext/geos_c_impl/errors.c +35 -0
- data/ext/geos_c_impl/errors.h +22 -0
- data/ext/geos_c_impl/extconf.rb +2 -0
- data/ext/geos_c_impl/factory.c +179 -174
- data/ext/geos_c_impl/factory.h +20 -49
- data/ext/geos_c_impl/geometry.c +17 -16
- data/ext/geos_c_impl/geometry.h +1 -3
- data/ext/geos_c_impl/geometry_collection.c +39 -44
- data/ext/geos_c_impl/geometry_collection.h +1 -3
- data/ext/geos_c_impl/globals.c +91 -0
- data/ext/geos_c_impl/globals.h +45 -0
- data/ext/geos_c_impl/line_string.c +27 -28
- data/ext/geos_c_impl/line_string.h +1 -3
- data/ext/geos_c_impl/main.c +14 -10
- data/ext/geos_c_impl/point.c +8 -7
- data/ext/geos_c_impl/point.h +1 -3
- data/ext/geos_c_impl/polygon.c +14 -14
- data/ext/geos_c_impl/polygon.h +1 -3
- data/ext/geos_c_impl/preface.h +8 -0
- data/lib/rgeo/cartesian/analysis.rb +22 -0
- data/lib/rgeo/cartesian/feature_methods.rb +6 -1
- data/lib/rgeo/cartesian.rb +7 -7
- data/lib/rgeo/coord_sys.rb +6 -6
- data/lib/rgeo/error.rb +4 -0
- data/lib/rgeo/feature/curve.rb +12 -2
- data/lib/rgeo/feature/geometry.rb +12 -2
- data/lib/rgeo/feature/linear_ring.rb +10 -0
- data/lib/rgeo/feature/multi_curve.rb +6 -1
- data/lib/rgeo/feature.rb +17 -17
- data/lib/rgeo/geographic/interface.rb +2 -1
- data/lib/rgeo/geographic/projected_feature_methods.rb +12 -2
- data/lib/rgeo/geographic/spherical_feature_classes.rb +1 -0
- data/lib/rgeo/geographic/spherical_feature_methods.rb +29 -1
- data/lib/rgeo/geographic.rb +10 -10
- data/lib/rgeo/geos/capi_factory.rb +3 -3
- data/lib/rgeo/geos/capi_feature_classes.rb +33 -0
- data/lib/rgeo/geos/ffi_feature_methods.rb +34 -5
- data/lib/rgeo/geos/interface.rb +18 -4
- data/lib/rgeo/geos/zm_feature_methods.rb +30 -5
- data/lib/rgeo/geos.rb +11 -11
- data/lib/rgeo/impl_helper/basic_geometry_collection_methods.rb +33 -5
- data/lib/rgeo/impl_helper/basic_line_string_methods.rb +62 -8
- data/lib/rgeo/impl_helper/basic_point_methods.rb +12 -2
- data/lib/rgeo/impl_helper/basic_polygon_methods.rb +44 -2
- data/lib/rgeo/impl_helper.rb +7 -7
- data/lib/rgeo/version.rb +1 -1
- data/lib/rgeo/wkrep/wkb_generator.rb +1 -1
- data/lib/rgeo/wkrep/wkt_generator.rb +6 -6
- data/lib/rgeo/wkrep.rb +4 -4
- data/lib/rgeo.rb +9 -9
- metadata +26 -14
data/ext/geos_c_impl/factory.c
CHANGED
@@ -10,12 +10,15 @@
|
|
10
10
|
#include <ruby.h>
|
11
11
|
#include <geos_c.h>
|
12
12
|
|
13
|
+
#include "globals.h"
|
14
|
+
|
13
15
|
#include "factory.h"
|
14
16
|
#include "geometry.h"
|
15
17
|
#include "point.h"
|
16
18
|
#include "line_string.h"
|
17
19
|
#include "polygon.h"
|
18
20
|
#include "geometry_collection.h"
|
21
|
+
#include "errors.h"
|
19
22
|
|
20
23
|
RGEO_BEGIN_C
|
21
24
|
|
@@ -35,82 +38,89 @@ static void message_handler(const char* fmt, ...)
|
|
35
38
|
// objects that have been created for the factory, and then destroy
|
36
39
|
// the GEOS context, before freeing the factory data itself.
|
37
40
|
|
38
|
-
static void destroy_factory_func(
|
41
|
+
static void destroy_factory_func(void* data)
|
39
42
|
{
|
43
|
+
RGeo_FactoryData* factory_data;
|
40
44
|
GEOSContextHandle_t context;
|
41
45
|
|
42
|
-
|
43
|
-
|
44
|
-
|
46
|
+
factory_data = (RGeo_FactoryData*)data;
|
47
|
+
context = factory_data->geos_context;
|
48
|
+
if (factory_data->wkt_reader) {
|
49
|
+
GEOSWKTReader_destroy_r(context, factory_data->wkt_reader);
|
45
50
|
}
|
46
|
-
if (
|
47
|
-
GEOSWKBReader_destroy_r(context,
|
51
|
+
if (factory_data->wkb_reader) {
|
52
|
+
GEOSWKBReader_destroy_r(context, factory_data->wkb_reader);
|
48
53
|
}
|
49
|
-
if (
|
50
|
-
GEOSWKTWriter_destroy_r(context,
|
54
|
+
if (factory_data->wkt_writer) {
|
55
|
+
GEOSWKTWriter_destroy_r(context, factory_data->wkt_writer);
|
51
56
|
}
|
52
|
-
if (
|
53
|
-
GEOSWKBWriter_destroy_r(context,
|
57
|
+
if (factory_data->wkb_writer) {
|
58
|
+
GEOSWKBWriter_destroy_r(context, factory_data->wkb_writer);
|
54
59
|
}
|
55
|
-
if (
|
56
|
-
GEOSWKTReader_destroy_r(context,
|
60
|
+
if (factory_data->psych_wkt_reader) {
|
61
|
+
GEOSWKTReader_destroy_r(context, factory_data->psych_wkt_reader);
|
57
62
|
}
|
58
|
-
if (
|
59
|
-
GEOSWKBReader_destroy_r(context,
|
63
|
+
if (factory_data->marshal_wkb_reader) {
|
64
|
+
GEOSWKBReader_destroy_r(context, factory_data->marshal_wkb_reader);
|
60
65
|
}
|
61
|
-
if (
|
62
|
-
GEOSWKTWriter_destroy_r(context,
|
66
|
+
if (factory_data->psych_wkt_writer) {
|
67
|
+
GEOSWKTWriter_destroy_r(context, factory_data->psych_wkt_writer);
|
63
68
|
}
|
64
|
-
if (
|
65
|
-
GEOSWKBWriter_destroy_r(context,
|
69
|
+
if (factory_data->marshal_wkb_writer) {
|
70
|
+
GEOSWKBWriter_destroy_r(context, factory_data->marshal_wkb_writer);
|
66
71
|
}
|
67
72
|
finishGEOS_r(context);
|
68
|
-
free(
|
73
|
+
free(factory_data);
|
69
74
|
}
|
70
75
|
|
71
76
|
|
72
77
|
// Destroy function for geometry data. We destroy the internal
|
73
78
|
// GEOS geometry (if present) before freeing the data itself.
|
74
79
|
|
75
|
-
static void destroy_geometry_func(
|
80
|
+
static void destroy_geometry_func(void* data)
|
76
81
|
{
|
82
|
+
RGeo_GeometryData* geometry_data;
|
77
83
|
const GEOSPreparedGeometry* prep;
|
78
84
|
|
79
|
-
|
80
|
-
|
85
|
+
geometry_data = (RGeo_GeometryData*)data;
|
86
|
+
if (geometry_data->geom) {
|
87
|
+
GEOSGeom_destroy_r(geometry_data->geos_context, geometry_data->geom);
|
81
88
|
}
|
82
|
-
prep =
|
89
|
+
prep = geometry_data->prep;
|
83
90
|
if (prep && prep != (const GEOSPreparedGeometry*)1 && prep != (const GEOSPreparedGeometry*)2 &&
|
84
91
|
prep != (const GEOSPreparedGeometry*)3)
|
85
92
|
{
|
86
|
-
GEOSPreparedGeom_destroy_r(
|
93
|
+
GEOSPreparedGeom_destroy_r(geometry_data->geos_context, prep);
|
87
94
|
}
|
88
|
-
free(
|
95
|
+
free(geometry_data);
|
89
96
|
}
|
90
97
|
|
91
98
|
|
92
99
|
// Mark function for factory data. This marks the wkt and wkb generator
|
93
100
|
// handles so they don't get collected.
|
94
101
|
|
95
|
-
static void mark_factory_func(
|
102
|
+
static void mark_factory_func(void* data)
|
96
103
|
{
|
97
|
-
|
98
|
-
|
104
|
+
RGeo_FactoryData* factory_data;
|
105
|
+
|
106
|
+
factory_data = (RGeo_FactoryData*)data;
|
107
|
+
if (!NIL_P(factory_data->wkrep_wkt_generator)) {
|
108
|
+
mark(factory_data->wkrep_wkt_generator);
|
99
109
|
}
|
100
|
-
if (!NIL_P(
|
101
|
-
|
110
|
+
if (!NIL_P(factory_data->wkrep_wkb_generator)) {
|
111
|
+
mark(factory_data->wkrep_wkb_generator);
|
102
112
|
}
|
103
|
-
if (!NIL_P(
|
104
|
-
|
113
|
+
if (!NIL_P(factory_data->wkrep_wkt_parser)) {
|
114
|
+
mark(factory_data->wkrep_wkt_parser);
|
105
115
|
}
|
106
|
-
if (!NIL_P(
|
107
|
-
|
116
|
+
if (!NIL_P(factory_data->wkrep_wkb_parser)) {
|
117
|
+
mark(factory_data->wkrep_wkb_parser);
|
108
118
|
}
|
109
|
-
if (!NIL_P(
|
110
|
-
|
119
|
+
if (!NIL_P(factory_data->proj4_obj)) {
|
120
|
+
mark(factory_data->proj4_obj);
|
111
121
|
}
|
112
|
-
if (!NIL_P(
|
113
|
-
|
122
|
+
if (!NIL_P(factory_data->coord_sys_obj)) {
|
123
|
+
mark(factory_data->coord_sys_obj);
|
114
124
|
}
|
115
125
|
}
|
116
126
|
|
@@ -118,32 +128,83 @@ static void mark_factory_func(RGeo_FactoryData* data)
|
|
118
128
|
// Mark function for geometry data. This marks the factory and klasses
|
119
129
|
// held by the geometry so those don't get collected.
|
120
130
|
|
121
|
-
static void mark_geometry_func(
|
131
|
+
static void mark_geometry_func(void* data)
|
122
132
|
{
|
123
|
-
|
124
|
-
|
133
|
+
RGeo_GeometryData* geometry_data;
|
134
|
+
|
135
|
+
geometry_data = (RGeo_GeometryData*)data;
|
136
|
+
if (!NIL_P(geometry_data->factory)) {
|
137
|
+
mark(geometry_data->factory);
|
125
138
|
}
|
126
|
-
if (!NIL_P(
|
127
|
-
|
139
|
+
if (!NIL_P(geometry_data->klasses)) {
|
140
|
+
mark(geometry_data->klasses);
|
128
141
|
}
|
129
142
|
}
|
130
143
|
|
131
144
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
static void destroy_globals_func(RGeo_Globals* data)
|
145
|
+
#ifdef HAVE_RB_GC_MARK_MOVABLE
|
146
|
+
static void compact_factory_func(void* data)
|
136
147
|
{
|
137
|
-
|
138
|
-
}
|
148
|
+
RGeo_FactoryData* factory_data;
|
139
149
|
|
150
|
+
factory_data = (RGeo_FactoryData*)data;
|
151
|
+
if (!NIL_P(factory_data->wkrep_wkt_generator)) {
|
152
|
+
factory_data->wkrep_wkt_generator = rb_gc_location(factory_data->wkrep_wkt_generator);
|
153
|
+
}
|
154
|
+
if (!NIL_P(factory_data->wkrep_wkb_generator)) {
|
155
|
+
factory_data->wkrep_wkb_generator = rb_gc_location(factory_data->wkrep_wkb_generator);
|
156
|
+
}
|
157
|
+
if (!NIL_P(factory_data->wkrep_wkt_parser)) {
|
158
|
+
factory_data->wkrep_wkt_parser = rb_gc_location(factory_data->wkrep_wkt_parser);
|
159
|
+
}
|
160
|
+
if (!NIL_P(factory_data->wkrep_wkb_parser)) {
|
161
|
+
factory_data->wkrep_wkb_parser = rb_gc_location(factory_data->wkrep_wkb_parser);
|
162
|
+
}
|
163
|
+
if (!NIL_P(factory_data->proj4_obj)) {
|
164
|
+
factory_data->proj4_obj = rb_gc_location(factory_data->proj4_obj);
|
165
|
+
}
|
166
|
+
if (!NIL_P(factory_data->coord_sys_obj)) {
|
167
|
+
factory_data->coord_sys_obj = rb_gc_location(factory_data->coord_sys_obj);
|
168
|
+
}
|
169
|
+
}
|
140
170
|
|
141
|
-
// Mark function for globals data. This should mark any globals that
|
142
|
-
// need to be held through garbage collection (none at the moment.)
|
143
171
|
|
144
|
-
static void
|
172
|
+
static void compact_geometry_func(void* data)
|
145
173
|
{
|
174
|
+
RGeo_GeometryData* geometry_data;
|
175
|
+
|
176
|
+
geometry_data = (RGeo_GeometryData*)data;
|
177
|
+
if (!NIL_P(geometry_data->factory)) {
|
178
|
+
geometry_data->factory = rb_gc_location(geometry_data->factory);
|
179
|
+
}
|
180
|
+
if (!NIL_P(geometry_data->klasses)) {
|
181
|
+
geometry_data->klasses = rb_gc_location(geometry_data->klasses);
|
182
|
+
}
|
146
183
|
}
|
184
|
+
#endif
|
185
|
+
|
186
|
+
|
187
|
+
const rb_data_type_t rgeo_factory_type = {
|
188
|
+
.wrap_struct_name = "RGeo/Factory",
|
189
|
+
.function = {
|
190
|
+
.dmark = mark_factory_func,
|
191
|
+
.dfree = destroy_factory_func,
|
192
|
+
#ifdef HAVE_RB_GC_MARK_MOVABLE
|
193
|
+
.dcompact = compact_factory_func,
|
194
|
+
#endif
|
195
|
+
}
|
196
|
+
};
|
197
|
+
|
198
|
+
const rb_data_type_t rgeo_geometry_type = {
|
199
|
+
.wrap_struct_name = "RGeo/Geometry",
|
200
|
+
.function = {
|
201
|
+
.dmark = mark_geometry_func,
|
202
|
+
.dfree = destroy_geometry_func,
|
203
|
+
#ifdef HAVE_RB_GC_MARK_MOVABLE
|
204
|
+
.dcompact = compact_geometry_func,
|
205
|
+
#endif
|
206
|
+
}
|
207
|
+
};
|
147
208
|
|
148
209
|
|
149
210
|
/**** RUBY METHOD DEFINITIONS ****/
|
@@ -247,7 +308,6 @@ static VALUE method_factory_read_for_marshal(VALUE self, VALUE str)
|
|
247
308
|
return result;
|
248
309
|
}
|
249
310
|
|
250
|
-
|
251
311
|
static VALUE method_factory_read_for_psych(VALUE self, VALUE str)
|
252
312
|
{
|
253
313
|
RGeo_FactoryData* self_data;
|
@@ -274,6 +334,9 @@ static VALUE method_factory_read_for_psych(VALUE self, VALUE str)
|
|
274
334
|
return result;
|
275
335
|
}
|
276
336
|
|
337
|
+
#ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
|
338
|
+
static VALUE marshal_wkb_generator;
|
339
|
+
#endif
|
277
340
|
|
278
341
|
static VALUE method_factory_write_for_marshal(VALUE self, VALUE obj)
|
279
342
|
{
|
@@ -285,25 +348,18 @@ static VALUE method_factory_write_for_marshal(VALUE self, VALUE obj)
|
|
285
348
|
char* str;
|
286
349
|
size_t size;
|
287
350
|
char has_3d;
|
288
|
-
#ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
|
289
|
-
RGeo_Globals* globals;
|
290
|
-
VALUE wkb_generator;
|
291
|
-
#endif
|
292
351
|
|
293
352
|
self_data = RGEO_FACTORY_DATA_PTR(self);
|
294
353
|
self_context = self_data->geos_context;
|
295
354
|
has_3d = self_data->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M;
|
296
355
|
#ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
|
297
356
|
if (has_3d) {
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
wkb_generator = rb_funcall(
|
302
|
-
rb_const_get_at(globals->geos_module, rb_intern("Utils")),
|
357
|
+
if (NIL_P(marshal_wkb_generator)) {
|
358
|
+
marshal_wkb_generator = rb_funcall(
|
359
|
+
rb_const_get_at(rgeo_geos_module, rb_intern("Utils")),
|
303
360
|
rb_intern("marshal_wkb_generator"), 0);
|
304
|
-
globals->marshal_wkb_generator = wkb_generator;
|
305
361
|
}
|
306
|
-
return rb_funcall(
|
362
|
+
return rb_funcall(marshal_wkb_generator, rb_intern("generate"), 1, obj);
|
307
363
|
}
|
308
364
|
#endif
|
309
365
|
wkb_writer = self_data->marshal_wkb_writer;
|
@@ -328,6 +384,9 @@ static VALUE method_factory_write_for_marshal(VALUE self, VALUE obj)
|
|
328
384
|
return result;
|
329
385
|
}
|
330
386
|
|
387
|
+
#ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
|
388
|
+
static VALUE psych_wkt_generator;
|
389
|
+
#endif
|
331
390
|
|
332
391
|
static VALUE method_factory_write_for_psych(VALUE self, VALUE obj)
|
333
392
|
{
|
@@ -338,25 +397,18 @@ static VALUE method_factory_write_for_psych(VALUE self, VALUE obj)
|
|
338
397
|
VALUE result;
|
339
398
|
char* str;
|
340
399
|
char has_3d;
|
341
|
-
#ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
|
342
|
-
RGeo_Globals* globals;
|
343
|
-
VALUE wkt_generator;
|
344
|
-
#endif
|
345
400
|
|
346
401
|
self_data = RGEO_FACTORY_DATA_PTR(self);
|
347
402
|
self_context = self_data->geos_context;
|
348
403
|
has_3d = self_data->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M;
|
349
404
|
#ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
|
350
405
|
if (has_3d) {
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
wkt_generator = rb_funcall(
|
355
|
-
rb_const_get_at(globals->geos_module, rb_intern("Utils")),
|
406
|
+
if (NIL_P(psych_wkt_generator)) {
|
407
|
+
psych_wkt_generator = rb_funcall(
|
408
|
+
rb_const_get_at(rgeo_geos_module, rb_intern("Utils")),
|
356
409
|
rb_intern("psych_wkt_generator"), 0);
|
357
|
-
globals->psych_wkt_generator = wkt_generator;
|
358
410
|
}
|
359
|
-
return rb_funcall(
|
411
|
+
return rb_funcall(psych_wkt_generator, rb_intern("generate"), 1, obj);
|
360
412
|
}
|
361
413
|
#endif
|
362
414
|
wkt_writer = self_data->psych_wkt_writer;
|
@@ -403,15 +455,12 @@ static VALUE cmethod_factory_create(VALUE klass, VALUE flags, VALUE srid, VALUE
|
|
403
455
|
VALUE result;
|
404
456
|
RGeo_FactoryData* data;
|
405
457
|
GEOSContextHandle_t context;
|
406
|
-
VALUE wrapped_globals;
|
407
458
|
|
408
459
|
result = Qnil;
|
409
460
|
data = ALLOC(RGeo_FactoryData);
|
410
461
|
if (data) {
|
411
462
|
context = initGEOS_r(message_handler, message_handler);
|
412
463
|
if (context) {
|
413
|
-
wrapped_globals = rb_const_get_at(klass, rb_intern("INTERNAL_CGLOBALS"));
|
414
|
-
data->globals = (RGeo_Globals*)DATA_PTR(wrapped_globals);
|
415
464
|
data->geos_context = context;
|
416
465
|
data->flags = NUM2INT(flags);
|
417
466
|
data->srid = NUM2INT(srid);
|
@@ -430,7 +479,7 @@ static VALUE cmethod_factory_create(VALUE klass, VALUE flags, VALUE srid, VALUE
|
|
430
479
|
data->wkrep_wkb_parser = Qnil;
|
431
480
|
data->proj4_obj = proj4_obj;
|
432
481
|
data->coord_sys_obj = coord_sys_obj;
|
433
|
-
result =
|
482
|
+
result = TypedData_Wrap_Struct(klass, &rgeo_factory_type, data);
|
434
483
|
}
|
435
484
|
else {
|
436
485
|
free(data);
|
@@ -495,7 +544,7 @@ static VALUE method_factory_initialize_copy(VALUE self, VALUE orig)
|
|
495
544
|
self_data->coord_sys_obj = Qnil;
|
496
545
|
|
497
546
|
// Copy new data from original object
|
498
|
-
if (
|
547
|
+
if (RGEO_FACTORY_TYPEDDATA_P(orig)) {
|
499
548
|
orig_data = RGEO_FACTORY_DATA_PTR(orig);
|
500
549
|
self_data->flags = orig_data->flags;
|
501
550
|
self_data->srid = orig_data->srid;
|
@@ -568,47 +617,20 @@ static VALUE alloc_geometry(VALUE klass)
|
|
568
617
|
/**** INITIALIZATION FUNCTION ****/
|
569
618
|
|
570
619
|
|
571
|
-
|
620
|
+
void rgeo_init_geos_factory()
|
572
621
|
{
|
573
|
-
RGeo_Globals* globals;
|
574
|
-
VALUE rgeo_module;
|
575
622
|
VALUE geos_factory_class;
|
576
|
-
|
577
|
-
VALUE feature_module;
|
578
|
-
|
579
|
-
globals = ALLOC(RGeo_Globals);
|
580
|
-
|
581
|
-
// Cache some modules so we don't have to look them up by name every time
|
582
|
-
rgeo_module = rb_define_module("RGeo");
|
583
|
-
feature_module = rb_define_module_under(rgeo_module, "Feature");
|
584
|
-
globals->feature_module = feature_module;
|
585
|
-
globals->geos_module = rb_define_module_under(rgeo_module, "Geos");
|
586
|
-
globals->feature_geometry = rb_const_get_at(feature_module, rb_intern("Geometry"));
|
587
|
-
globals->feature_point = rb_const_get_at(feature_module, rb_intern("Point"));
|
588
|
-
globals->feature_line_string = rb_const_get_at(feature_module, rb_intern("LineString"));
|
589
|
-
globals->feature_linear_ring = rb_const_get_at(feature_module, rb_intern("LinearRing"));
|
590
|
-
globals->feature_line = rb_const_get_at(feature_module, rb_intern("Line"));
|
591
|
-
globals->feature_polygon = rb_const_get_at(feature_module, rb_intern("Polygon"));
|
592
|
-
globals->feature_geometry_collection = rb_const_get_at(feature_module, rb_intern("GeometryCollection"));
|
593
|
-
globals->feature_multi_point = rb_const_get_at(feature_module, rb_intern("MultiPoint"));
|
594
|
-
globals->feature_multi_line_string = rb_const_get_at(feature_module, rb_intern("MultiLineString"));
|
595
|
-
globals->feature_multi_polygon = rb_const_get_at(feature_module, rb_intern("MultiPolygon"));
|
596
|
-
|
597
|
-
// Cache some commonly used names
|
598
|
-
globals->id_cast = rb_intern("cast");
|
599
|
-
globals->id_eql = rb_intern("eql?");
|
600
|
-
globals->id_generate = rb_intern("generate");
|
601
|
-
globals->id_enum_for = rb_intern("enum_for");
|
602
|
-
globals->id_hash = rb_intern("hash");
|
603
|
-
globals->sym_force_new = ID2SYM(rb_intern("force_new"));
|
604
|
-
globals->sym_keep_subtype = ID2SYM(rb_intern("keep_subtype"));
|
623
|
+
|
605
624
|
#ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
|
606
|
-
|
607
|
-
|
625
|
+
/* We favor rb_gc_register_address over rb_gc_register_mark_object because the value changes at runtime */
|
626
|
+
psych_wkt_generator = Qnil;
|
627
|
+
rb_gc_register_address(&psych_wkt_generator);
|
628
|
+
marshal_wkb_generator = Qnil;
|
629
|
+
rb_gc_register_address(&marshal_wkb_generator);
|
608
630
|
#endif
|
609
631
|
|
610
632
|
// Add C methods to the factory.
|
611
|
-
geos_factory_class = rb_define_class_under(
|
633
|
+
geos_factory_class = rb_define_class_under(rgeo_geos_module, "CAPIFactory", rb_cObject);
|
612
634
|
rb_define_alloc_func(geos_factory_class, alloc_factory);
|
613
635
|
rb_define_method(geos_factory_class, "initialize_copy", method_factory_initialize_copy, 1);
|
614
636
|
rb_define_method(geos_factory_class, "_parse_wkt_impl", method_factory_parse_wkt, 1);
|
@@ -631,34 +653,17 @@ RGeo_Globals* rgeo_init_geos_factory()
|
|
631
653
|
rb_define_module_function(geos_factory_class, "_geos_version", cmethod_factory_geos_version, 0);
|
632
654
|
rb_define_module_function(geos_factory_class, "_supports_unary_union?", cmethod_factory_supports_unary_union, 0);
|
633
655
|
|
634
|
-
//
|
635
|
-
|
636
|
-
rb_define_alloc_func(
|
637
|
-
|
638
|
-
rb_define_alloc_func(
|
639
|
-
|
640
|
-
rb_define_alloc_func(
|
641
|
-
|
642
|
-
rb_define_alloc_func(
|
643
|
-
|
644
|
-
rb_define_alloc_func(
|
645
|
-
globals->geos_polygon = rb_define_class_under(globals->geos_module, "CAPIPolygonImpl", rb_cObject);
|
646
|
-
rb_define_alloc_func(globals->geos_polygon, alloc_geometry);
|
647
|
-
globals->geos_geometry_collection = rb_define_class_under(globals->geos_module, "CAPIGeometryCollectionImpl", rb_cObject);
|
648
|
-
rb_define_alloc_func(globals->geos_geometry_collection, alloc_geometry);
|
649
|
-
globals->geos_multi_point = rb_define_class_under(globals->geos_module, "CAPIMultiPointImpl", rb_cObject);
|
650
|
-
rb_define_alloc_func(globals->geos_multi_point, alloc_geometry);
|
651
|
-
globals->geos_multi_line_string = rb_define_class_under(globals->geos_module, "CAPIMultiLineStringImpl", rb_cObject);
|
652
|
-
rb_define_alloc_func(globals->geos_multi_line_string, alloc_geometry);
|
653
|
-
globals->geos_multi_polygon = rb_define_class_under(globals->geos_module, "CAPIMultiPolygonImpl", rb_cObject);
|
654
|
-
rb_define_alloc_func(globals->geos_multi_polygon, alloc_geometry);
|
655
|
-
|
656
|
-
// Wrap the globals in a Ruby object and store it off so we have access
|
657
|
-
// to it later. Each factory instance will reference it internally.
|
658
|
-
wrapped_globals = Data_Wrap_Struct(rb_cObject, mark_globals_func, destroy_globals_func, globals);
|
659
|
-
rb_define_const(geos_factory_class, "INTERNAL_CGLOBALS", wrapped_globals);
|
660
|
-
|
661
|
-
return globals;
|
656
|
+
// Define allocation methods for global class types
|
657
|
+
rb_define_alloc_func(rgeo_geos_geometry_class, alloc_geometry);
|
658
|
+
rb_define_alloc_func(rgeo_geos_point_class, alloc_geometry);
|
659
|
+
rb_define_alloc_func(rgeo_geos_line_string_class, alloc_geometry);
|
660
|
+
rb_define_alloc_func(rgeo_geos_linear_ring_class, alloc_geometry);
|
661
|
+
rb_define_alloc_func(rgeo_geos_line_class, alloc_geometry);
|
662
|
+
rb_define_alloc_func(rgeo_geos_polygon_class, alloc_geometry);
|
663
|
+
rb_define_alloc_func(rgeo_geos_geometry_collection_class, alloc_geometry);
|
664
|
+
rb_define_alloc_func(rgeo_geos_multi_point_class, alloc_geometry);
|
665
|
+
rb_define_alloc_func(rgeo_geos_multi_line_string_class, alloc_geometry);
|
666
|
+
rb_define_alloc_func(rgeo_geos_multi_polygon_class, alloc_geometry);
|
662
667
|
}
|
663
668
|
|
664
669
|
|
@@ -671,7 +676,6 @@ VALUE rgeo_wrap_geos_geometry(VALUE factory, GEOSGeometry* geom, VALUE klass)
|
|
671
676
|
RGeo_FactoryData* factory_data;
|
672
677
|
GEOSContextHandle_t factory_context;
|
673
678
|
VALUE klasses;
|
674
|
-
RGeo_Globals* globals;
|
675
679
|
VALUE inferred_klass;
|
676
680
|
char is_collection;
|
677
681
|
RGeo_GeometryData* data;
|
@@ -680,7 +684,6 @@ VALUE rgeo_wrap_geos_geometry(VALUE factory, GEOSGeometry* geom, VALUE klass)
|
|
680
684
|
if (geom || !NIL_P(klass)) {
|
681
685
|
factory_data = NIL_P(factory) ? NULL : RGEO_FACTORY_DATA_PTR(factory);
|
682
686
|
factory_context = factory_data ? factory_data->geos_context : NULL;
|
683
|
-
globals = factory_data ? factory_data->globals : NULL;
|
684
687
|
|
685
688
|
// We don't allow "empty" points, so replace such objects with
|
686
689
|
// an empty collection.
|
@@ -688,7 +691,7 @@ VALUE rgeo_wrap_geos_geometry(VALUE factory, GEOSGeometry* geom, VALUE klass)
|
|
688
691
|
if (GEOSGeomTypeId_r(factory_context, geom) == GEOS_POINT && GEOSGetNumCoordinates_r(factory_context, geom) == 0) {
|
689
692
|
GEOSGeom_destroy_r(factory_context, geom);
|
690
693
|
geom = GEOSGeom_createCollection_r(factory_context, GEOS_GEOMETRYCOLLECTION, NULL, 0);
|
691
|
-
klass =
|
694
|
+
klass = rgeo_geos_geometry_collection_class;
|
692
695
|
}
|
693
696
|
}
|
694
697
|
|
@@ -698,35 +701,35 @@ VALUE rgeo_wrap_geos_geometry(VALUE factory, GEOSGeometry* geom, VALUE klass)
|
|
698
701
|
is_collection = 0;
|
699
702
|
switch (GEOSGeomTypeId_r(factory_context, geom)) {
|
700
703
|
case GEOS_POINT:
|
701
|
-
inferred_klass =
|
704
|
+
inferred_klass = rgeo_geos_point_class;
|
702
705
|
break;
|
703
706
|
case GEOS_LINESTRING:
|
704
|
-
inferred_klass =
|
707
|
+
inferred_klass = rgeo_geos_line_string_class;
|
705
708
|
break;
|
706
709
|
case GEOS_LINEARRING:
|
707
|
-
inferred_klass =
|
710
|
+
inferred_klass = rgeo_geos_linear_ring_class;
|
708
711
|
break;
|
709
712
|
case GEOS_POLYGON:
|
710
|
-
inferred_klass =
|
713
|
+
inferred_klass = rgeo_geos_polygon_class;
|
711
714
|
break;
|
712
715
|
case GEOS_MULTIPOINT:
|
713
|
-
inferred_klass =
|
716
|
+
inferred_klass = rgeo_geos_multi_point_class;
|
714
717
|
is_collection = 1;
|
715
718
|
break;
|
716
719
|
case GEOS_MULTILINESTRING:
|
717
|
-
inferred_klass =
|
720
|
+
inferred_klass = rgeo_geos_multi_line_string_class;
|
718
721
|
is_collection = 1;
|
719
722
|
break;
|
720
723
|
case GEOS_MULTIPOLYGON:
|
721
|
-
inferred_klass =
|
724
|
+
inferred_klass = rgeo_geos_multi_polygon_class;
|
722
725
|
is_collection = 1;
|
723
726
|
break;
|
724
727
|
case GEOS_GEOMETRYCOLLECTION:
|
725
|
-
inferred_klass =
|
728
|
+
inferred_klass = rgeo_geos_geometry_collection_class;
|
726
729
|
is_collection = 1;
|
727
730
|
break;
|
728
731
|
default:
|
729
|
-
inferred_klass =
|
732
|
+
inferred_klass = rgeo_geos_geometry_class;
|
730
733
|
break;
|
731
734
|
}
|
732
735
|
if (TYPE(klass) == T_ARRAY && is_collection) {
|
@@ -745,13 +748,12 @@ VALUE rgeo_wrap_geos_geometry(VALUE factory, GEOSGeometry* geom, VALUE klass)
|
|
745
748
|
(GEOSPreparedGeometry*)1 : NULL;
|
746
749
|
data->factory = factory;
|
747
750
|
data->klasses = klasses;
|
748
|
-
result =
|
751
|
+
result = TypedData_Wrap_Struct(klass, &rgeo_geometry_type, data);
|
749
752
|
}
|
750
753
|
}
|
751
754
|
return result;
|
752
755
|
}
|
753
756
|
|
754
|
-
|
755
757
|
VALUE rgeo_wrap_geos_geometry_clone(VALUE factory, const GEOSGeometry* geom, VALUE klass)
|
756
758
|
{
|
757
759
|
VALUE result;
|
@@ -771,21 +773,18 @@ VALUE rgeo_wrap_geos_geometry_clone(VALUE factory, const GEOSGeometry* geom, VAL
|
|
771
773
|
const GEOSGeometry* rgeo_convert_to_geos_geometry(VALUE factory, VALUE obj, VALUE type)
|
772
774
|
{
|
773
775
|
VALUE object;
|
774
|
-
const GEOSGeometry* geom;
|
775
|
-
RGeo_Globals* globals;
|
776
776
|
|
777
|
-
if (NIL_P(type) &&
|
777
|
+
if (NIL_P(type) && RGEO_GEOMETRY_TYPEDDATA_P(obj) && RGEO_GEOMETRY_DATA_PTR(obj)->factory == factory) {
|
778
778
|
object = obj;
|
779
779
|
}
|
780
780
|
else {
|
781
|
-
|
782
|
-
object = rb_funcall(globals->feature_module, globals->id_cast, 3, obj, factory, type);
|
783
|
-
}
|
784
|
-
geom = NULL;
|
785
|
-
if (!NIL_P(object)) {
|
786
|
-
geom = RGEO_GEOMETRY_DATA_PTR(object)->geom;
|
781
|
+
object = rb_funcall(rgeo_feature_module, rb_intern("cast"), 3, obj, factory, type);
|
787
782
|
}
|
788
|
-
|
783
|
+
if (NIL_P(object))
|
784
|
+
return NULL;
|
785
|
+
|
786
|
+
Check_TypedStruct(object, &rgeo_geometry_type);
|
787
|
+
return RGEO_GEOMETRY_DATA_PTR(object)->geom;
|
789
788
|
}
|
790
789
|
|
791
790
|
|
@@ -795,13 +794,11 @@ GEOSGeometry* rgeo_convert_to_detached_geos_geometry(VALUE obj, VALUE factory, V
|
|
795
794
|
GEOSGeometry* geom;
|
796
795
|
RGeo_GeometryData* object_data;
|
797
796
|
const GEOSPreparedGeometry* prep;
|
798
|
-
RGeo_Globals* globals;
|
799
797
|
|
800
798
|
if (klasses) {
|
801
799
|
*klasses = Qnil;
|
802
800
|
}
|
803
|
-
|
804
|
-
object = rb_funcall(globals->feature_module, globals->id_cast, 5, obj, factory, type, globals->sym_force_new, globals->sym_keep_subtype);
|
801
|
+
object = rb_funcall(rgeo_feature_module, rb_intern("cast"), 5, obj, factory, type, ID2SYM(rb_intern("force_new")), ID2SYM(rb_intern("keep_subtype")));
|
805
802
|
geom = NULL;
|
806
803
|
if (!NIL_P(object)) {
|
807
804
|
object_data = RGEO_GEOMETRY_DATA_PTR(object);
|
@@ -828,13 +825,20 @@ GEOSGeometry* rgeo_convert_to_detached_geos_geometry(VALUE obj, VALUE factory, V
|
|
828
825
|
|
829
826
|
char rgeo_is_geos_object(VALUE obj)
|
830
827
|
{
|
831
|
-
return (
|
828
|
+
return RGEO_GEOMETRY_TYPEDDATA_P(obj) ? 1 : 0;
|
829
|
+
}
|
830
|
+
|
831
|
+
void rgeo_check_geos_object(VALUE obj)
|
832
|
+
{
|
833
|
+
if (!rgeo_is_geos_object(obj)) {
|
834
|
+
rb_raise(rgeo_error, "Not a GEOS Geometry object.");
|
835
|
+
}
|
832
836
|
}
|
833
837
|
|
834
838
|
|
835
839
|
const GEOSGeometry* rgeo_get_geos_geometry_safe(VALUE obj)
|
836
840
|
{
|
837
|
-
return (
|
841
|
+
return RGEO_GEOMETRY_TYPEDDATA_P(obj) ? (const GEOSGeometry*)(RGEO_GEOMETRY_DATA_PTR(obj)->geom) : NULL;
|
838
842
|
}
|
839
843
|
|
840
844
|
|
@@ -922,7 +926,8 @@ VALUE rgeo_geos_klasses_and_factories_eql(VALUE obj1, VALUE obj2)
|
|
922
926
|
}
|
923
927
|
else {
|
924
928
|
factory = RGEO_GEOMETRY_DATA_PTR(obj1)->factory;
|
925
|
-
|
929
|
+
/* No need to cache the internal here (https://ips.fastruby.io/4x) */
|
930
|
+
result = rb_funcall(factory, rb_intern("eql?"), 1, RGEO_GEOMETRY_DATA_PTR(obj2)->factory);
|
926
931
|
}
|
927
932
|
return result;
|
928
933
|
}
|
@@ -975,7 +980,7 @@ st_index_t rgeo_geos_objbase_hash(VALUE factory, VALUE type_module, st_index_t h
|
|
975
980
|
ID hash_method;
|
976
981
|
RGeo_Objbase_Hash_Struct hash_struct;
|
977
982
|
|
978
|
-
hash_method =
|
983
|
+
hash_method = rb_intern("hash");
|
979
984
|
hash_struct.seed_hash = hash;
|
980
985
|
hash_struct.h1 = FIX2LONG(rb_funcall(factory, hash_method, 0));
|
981
986
|
hash_struct.h2 = FIX2LONG(rb_funcall(type_module, hash_method, 0));
|