rgeo 2.3.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/ext/geos_c_impl/analysis.c +4 -2
- data/ext/geos_c_impl/analysis.h +1 -3
- data/ext/geos_c_impl/errors.c +2 -2
- data/ext/geos_c_impl/extconf.rb +1 -0
- data/ext/geos_c_impl/factory.c +167 -170
- data/ext/geos_c_impl/factory.h +15 -48
- data/ext/geos_c_impl/geometry.c +8 -8
- data/ext/geos_c_impl/geometry.h +1 -3
- data/ext/geos_c_impl/geometry_collection.c +38 -43
- 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 +25 -26
- data/ext/geos_c_impl/line_string.h +1 -3
- data/ext/geos_c_impl/main.c +10 -9
- 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 +5 -0
- data/lib/rgeo/version.rb +1 -1
- metadata +8 -6
data/ext/geos_c_impl/factory.c
CHANGED
@@ -10,6 +10,8 @@
|
|
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"
|
@@ -36,82 +38,89 @@ static void message_handler(const char* fmt, ...)
|
|
36
38
|
// objects that have been created for the factory, and then destroy
|
37
39
|
// the GEOS context, before freeing the factory data itself.
|
38
40
|
|
39
|
-
static void destroy_factory_func(
|
41
|
+
static void destroy_factory_func(void* data)
|
40
42
|
{
|
43
|
+
RGeo_FactoryData* factory_data;
|
41
44
|
GEOSContextHandle_t context;
|
42
45
|
|
43
|
-
|
44
|
-
|
45
|
-
|
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);
|
46
50
|
}
|
47
|
-
if (
|
48
|
-
GEOSWKBReader_destroy_r(context,
|
51
|
+
if (factory_data->wkb_reader) {
|
52
|
+
GEOSWKBReader_destroy_r(context, factory_data->wkb_reader);
|
49
53
|
}
|
50
|
-
if (
|
51
|
-
GEOSWKTWriter_destroy_r(context,
|
54
|
+
if (factory_data->wkt_writer) {
|
55
|
+
GEOSWKTWriter_destroy_r(context, factory_data->wkt_writer);
|
52
56
|
}
|
53
|
-
if (
|
54
|
-
GEOSWKBWriter_destroy_r(context,
|
57
|
+
if (factory_data->wkb_writer) {
|
58
|
+
GEOSWKBWriter_destroy_r(context, factory_data->wkb_writer);
|
55
59
|
}
|
56
|
-
if (
|
57
|
-
GEOSWKTReader_destroy_r(context,
|
60
|
+
if (factory_data->psych_wkt_reader) {
|
61
|
+
GEOSWKTReader_destroy_r(context, factory_data->psych_wkt_reader);
|
58
62
|
}
|
59
|
-
if (
|
60
|
-
GEOSWKBReader_destroy_r(context,
|
63
|
+
if (factory_data->marshal_wkb_reader) {
|
64
|
+
GEOSWKBReader_destroy_r(context, factory_data->marshal_wkb_reader);
|
61
65
|
}
|
62
|
-
if (
|
63
|
-
GEOSWKTWriter_destroy_r(context,
|
66
|
+
if (factory_data->psych_wkt_writer) {
|
67
|
+
GEOSWKTWriter_destroy_r(context, factory_data->psych_wkt_writer);
|
64
68
|
}
|
65
|
-
if (
|
66
|
-
GEOSWKBWriter_destroy_r(context,
|
69
|
+
if (factory_data->marshal_wkb_writer) {
|
70
|
+
GEOSWKBWriter_destroy_r(context, factory_data->marshal_wkb_writer);
|
67
71
|
}
|
68
72
|
finishGEOS_r(context);
|
69
|
-
free(
|
73
|
+
free(factory_data);
|
70
74
|
}
|
71
75
|
|
72
76
|
|
73
77
|
// Destroy function for geometry data. We destroy the internal
|
74
78
|
// GEOS geometry (if present) before freeing the data itself.
|
75
79
|
|
76
|
-
static void destroy_geometry_func(
|
80
|
+
static void destroy_geometry_func(void* data)
|
77
81
|
{
|
82
|
+
RGeo_GeometryData* geometry_data;
|
78
83
|
const GEOSPreparedGeometry* prep;
|
79
84
|
|
80
|
-
|
81
|
-
|
85
|
+
geometry_data = (RGeo_GeometryData*)data;
|
86
|
+
if (geometry_data->geom) {
|
87
|
+
GEOSGeom_destroy_r(geometry_data->geos_context, geometry_data->geom);
|
82
88
|
}
|
83
|
-
prep =
|
89
|
+
prep = geometry_data->prep;
|
84
90
|
if (prep && prep != (const GEOSPreparedGeometry*)1 && prep != (const GEOSPreparedGeometry*)2 &&
|
85
91
|
prep != (const GEOSPreparedGeometry*)3)
|
86
92
|
{
|
87
|
-
GEOSPreparedGeom_destroy_r(
|
93
|
+
GEOSPreparedGeom_destroy_r(geometry_data->geos_context, prep);
|
88
94
|
}
|
89
|
-
free(
|
95
|
+
free(geometry_data);
|
90
96
|
}
|
91
97
|
|
92
98
|
|
93
99
|
// Mark function for factory data. This marks the wkt and wkb generator
|
94
100
|
// handles so they don't get collected.
|
95
101
|
|
96
|
-
static void mark_factory_func(
|
102
|
+
static void mark_factory_func(void* data)
|
97
103
|
{
|
98
|
-
|
99
|
-
|
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);
|
100
109
|
}
|
101
|
-
if (!NIL_P(
|
102
|
-
|
110
|
+
if (!NIL_P(factory_data->wkrep_wkb_generator)) {
|
111
|
+
mark(factory_data->wkrep_wkb_generator);
|
103
112
|
}
|
104
|
-
if (!NIL_P(
|
105
|
-
|
113
|
+
if (!NIL_P(factory_data->wkrep_wkt_parser)) {
|
114
|
+
mark(factory_data->wkrep_wkt_parser);
|
106
115
|
}
|
107
|
-
if (!NIL_P(
|
108
|
-
|
116
|
+
if (!NIL_P(factory_data->wkrep_wkb_parser)) {
|
117
|
+
mark(factory_data->wkrep_wkb_parser);
|
109
118
|
}
|
110
|
-
if (!NIL_P(
|
111
|
-
|
119
|
+
if (!NIL_P(factory_data->proj4_obj)) {
|
120
|
+
mark(factory_data->proj4_obj);
|
112
121
|
}
|
113
|
-
if (!NIL_P(
|
114
|
-
|
122
|
+
if (!NIL_P(factory_data->coord_sys_obj)) {
|
123
|
+
mark(factory_data->coord_sys_obj);
|
115
124
|
}
|
116
125
|
}
|
117
126
|
|
@@ -119,32 +128,83 @@ static void mark_factory_func(RGeo_FactoryData* data)
|
|
119
128
|
// Mark function for geometry data. This marks the factory and klasses
|
120
129
|
// held by the geometry so those don't get collected.
|
121
130
|
|
122
|
-
static void mark_geometry_func(
|
131
|
+
static void mark_geometry_func(void* data)
|
123
132
|
{
|
124
|
-
|
125
|
-
|
133
|
+
RGeo_GeometryData* geometry_data;
|
134
|
+
|
135
|
+
geometry_data = (RGeo_GeometryData*)data;
|
136
|
+
if (!NIL_P(geometry_data->factory)) {
|
137
|
+
mark(geometry_data->factory);
|
126
138
|
}
|
127
|
-
if (!NIL_P(
|
128
|
-
|
139
|
+
if (!NIL_P(geometry_data->klasses)) {
|
140
|
+
mark(geometry_data->klasses);
|
129
141
|
}
|
130
142
|
}
|
131
143
|
|
132
144
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
static void destroy_globals_func(RGeo_Globals* data)
|
145
|
+
#ifdef HAVE_RB_GC_MARK_MOVABLE
|
146
|
+
static void compact_factory_func(void* data)
|
137
147
|
{
|
138
|
-
|
139
|
-
}
|
148
|
+
RGeo_FactoryData* factory_data;
|
140
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
|
+
}
|
141
170
|
|
142
|
-
// Mark function for globals data. This should mark any globals that
|
143
|
-
// need to be held through garbage collection (none at the moment.)
|
144
171
|
|
145
|
-
static void
|
172
|
+
static void compact_geometry_func(void* data)
|
146
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
|
+
}
|
147
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
|
+
};
|
148
208
|
|
149
209
|
|
150
210
|
/**** RUBY METHOD DEFINITIONS ****/
|
@@ -248,7 +308,6 @@ static VALUE method_factory_read_for_marshal(VALUE self, VALUE str)
|
|
248
308
|
return result;
|
249
309
|
}
|
250
310
|
|
251
|
-
|
252
311
|
static VALUE method_factory_read_for_psych(VALUE self, VALUE str)
|
253
312
|
{
|
254
313
|
RGeo_FactoryData* self_data;
|
@@ -275,6 +334,9 @@ static VALUE method_factory_read_for_psych(VALUE self, VALUE str)
|
|
275
334
|
return result;
|
276
335
|
}
|
277
336
|
|
337
|
+
#ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
|
338
|
+
static VALUE marshal_wkb_generator;
|
339
|
+
#endif
|
278
340
|
|
279
341
|
static VALUE method_factory_write_for_marshal(VALUE self, VALUE obj)
|
280
342
|
{
|
@@ -286,25 +348,18 @@ static VALUE method_factory_write_for_marshal(VALUE self, VALUE obj)
|
|
286
348
|
char* str;
|
287
349
|
size_t size;
|
288
350
|
char has_3d;
|
289
|
-
#ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
|
290
|
-
RGeo_Globals* globals;
|
291
|
-
VALUE wkb_generator;
|
292
|
-
#endif
|
293
351
|
|
294
352
|
self_data = RGEO_FACTORY_DATA_PTR(self);
|
295
353
|
self_context = self_data->geos_context;
|
296
354
|
has_3d = self_data->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M;
|
297
355
|
#ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
|
298
356
|
if (has_3d) {
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
wkb_generator = rb_funcall(
|
303
|
-
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")),
|
304
360
|
rb_intern("marshal_wkb_generator"), 0);
|
305
|
-
globals->marshal_wkb_generator = wkb_generator;
|
306
361
|
}
|
307
|
-
return rb_funcall(
|
362
|
+
return rb_funcall(marshal_wkb_generator, rb_intern("generate"), 1, obj);
|
308
363
|
}
|
309
364
|
#endif
|
310
365
|
wkb_writer = self_data->marshal_wkb_writer;
|
@@ -329,6 +384,9 @@ static VALUE method_factory_write_for_marshal(VALUE self, VALUE obj)
|
|
329
384
|
return result;
|
330
385
|
}
|
331
386
|
|
387
|
+
#ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
|
388
|
+
static VALUE psych_wkt_generator;
|
389
|
+
#endif
|
332
390
|
|
333
391
|
static VALUE method_factory_write_for_psych(VALUE self, VALUE obj)
|
334
392
|
{
|
@@ -339,25 +397,18 @@ static VALUE method_factory_write_for_psych(VALUE self, VALUE obj)
|
|
339
397
|
VALUE result;
|
340
398
|
char* str;
|
341
399
|
char has_3d;
|
342
|
-
#ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
|
343
|
-
RGeo_Globals* globals;
|
344
|
-
VALUE wkt_generator;
|
345
|
-
#endif
|
346
400
|
|
347
401
|
self_data = RGEO_FACTORY_DATA_PTR(self);
|
348
402
|
self_context = self_data->geos_context;
|
349
403
|
has_3d = self_data->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M;
|
350
404
|
#ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
|
351
405
|
if (has_3d) {
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
wkt_generator = rb_funcall(
|
356
|
-
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")),
|
357
409
|
rb_intern("psych_wkt_generator"), 0);
|
358
|
-
globals->psych_wkt_generator = wkt_generator;
|
359
410
|
}
|
360
|
-
return rb_funcall(
|
411
|
+
return rb_funcall(psych_wkt_generator, rb_intern("generate"), 1, obj);
|
361
412
|
}
|
362
413
|
#endif
|
363
414
|
wkt_writer = self_data->psych_wkt_writer;
|
@@ -404,15 +455,12 @@ static VALUE cmethod_factory_create(VALUE klass, VALUE flags, VALUE srid, VALUE
|
|
404
455
|
VALUE result;
|
405
456
|
RGeo_FactoryData* data;
|
406
457
|
GEOSContextHandle_t context;
|
407
|
-
VALUE wrapped_globals;
|
408
458
|
|
409
459
|
result = Qnil;
|
410
460
|
data = ALLOC(RGeo_FactoryData);
|
411
461
|
if (data) {
|
412
462
|
context = initGEOS_r(message_handler, message_handler);
|
413
463
|
if (context) {
|
414
|
-
wrapped_globals = rb_const_get_at(klass, rb_intern("INTERNAL_CGLOBALS"));
|
415
|
-
data->globals = (RGeo_Globals*)DATA_PTR(wrapped_globals);
|
416
464
|
data->geos_context = context;
|
417
465
|
data->flags = NUM2INT(flags);
|
418
466
|
data->srid = NUM2INT(srid);
|
@@ -431,7 +479,7 @@ static VALUE cmethod_factory_create(VALUE klass, VALUE flags, VALUE srid, VALUE
|
|
431
479
|
data->wkrep_wkb_parser = Qnil;
|
432
480
|
data->proj4_obj = proj4_obj;
|
433
481
|
data->coord_sys_obj = coord_sys_obj;
|
434
|
-
result =
|
482
|
+
result = TypedData_Wrap_Struct(klass, &rgeo_factory_type, data);
|
435
483
|
}
|
436
484
|
else {
|
437
485
|
free(data);
|
@@ -496,7 +544,7 @@ static VALUE method_factory_initialize_copy(VALUE self, VALUE orig)
|
|
496
544
|
self_data->coord_sys_obj = Qnil;
|
497
545
|
|
498
546
|
// Copy new data from original object
|
499
|
-
if (
|
547
|
+
if (RGEO_FACTORY_TYPEDDATA_P(orig)) {
|
500
548
|
orig_data = RGEO_FACTORY_DATA_PTR(orig);
|
501
549
|
self_data->flags = orig_data->flags;
|
502
550
|
self_data->srid = orig_data->srid;
|
@@ -569,48 +617,20 @@ static VALUE alloc_geometry(VALUE klass)
|
|
569
617
|
/**** INITIALIZATION FUNCTION ****/
|
570
618
|
|
571
619
|
|
572
|
-
|
620
|
+
void rgeo_init_geos_factory()
|
573
621
|
{
|
574
|
-
RGeo_Globals* globals;
|
575
|
-
VALUE rgeo_module;
|
576
622
|
VALUE geos_factory_class;
|
577
|
-
|
578
|
-
VALUE feature_module;
|
579
|
-
|
580
|
-
rgeo_module = rb_define_module("RGeo");
|
581
|
-
|
582
|
-
globals = ALLOC(RGeo_Globals);
|
583
|
-
|
584
|
-
// Cache some modules so we don't have to look them up by name every time
|
585
|
-
feature_module = rb_define_module_under(rgeo_module, "Feature");
|
586
|
-
globals->feature_module = feature_module;
|
587
|
-
globals->geos_module = rb_define_module_under(rgeo_module, "Geos");
|
588
|
-
globals->feature_geometry = rb_const_get_at(feature_module, rb_intern("Geometry"));
|
589
|
-
globals->feature_point = rb_const_get_at(feature_module, rb_intern("Point"));
|
590
|
-
globals->feature_line_string = rb_const_get_at(feature_module, rb_intern("LineString"));
|
591
|
-
globals->feature_linear_ring = rb_const_get_at(feature_module, rb_intern("LinearRing"));
|
592
|
-
globals->feature_line = rb_const_get_at(feature_module, rb_intern("Line"));
|
593
|
-
globals->feature_polygon = rb_const_get_at(feature_module, rb_intern("Polygon"));
|
594
|
-
globals->feature_geometry_collection = rb_const_get_at(feature_module, rb_intern("GeometryCollection"));
|
595
|
-
globals->feature_multi_point = rb_const_get_at(feature_module, rb_intern("MultiPoint"));
|
596
|
-
globals->feature_multi_line_string = rb_const_get_at(feature_module, rb_intern("MultiLineString"));
|
597
|
-
globals->feature_multi_polygon = rb_const_get_at(feature_module, rb_intern("MultiPolygon"));
|
598
|
-
|
599
|
-
// Cache some commonly used names
|
600
|
-
globals->id_cast = rb_intern("cast");
|
601
|
-
globals->id_eql = rb_intern("eql?");
|
602
|
-
globals->id_generate = rb_intern("generate");
|
603
|
-
globals->id_enum_for = rb_intern("enum_for");
|
604
|
-
globals->id_hash = rb_intern("hash");
|
605
|
-
globals->sym_force_new = ID2SYM(rb_intern("force_new"));
|
606
|
-
globals->sym_keep_subtype = ID2SYM(rb_intern("keep_subtype"));
|
623
|
+
|
607
624
|
#ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
|
608
|
-
|
609
|
-
|
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);
|
610
630
|
#endif
|
611
631
|
|
612
632
|
// Add C methods to the factory.
|
613
|
-
geos_factory_class = rb_define_class_under(
|
633
|
+
geos_factory_class = rb_define_class_under(rgeo_geos_module, "CAPIFactory", rb_cObject);
|
614
634
|
rb_define_alloc_func(geos_factory_class, alloc_factory);
|
615
635
|
rb_define_method(geos_factory_class, "initialize_copy", method_factory_initialize_copy, 1);
|
616
636
|
rb_define_method(geos_factory_class, "_parse_wkt_impl", method_factory_parse_wkt, 1);
|
@@ -633,34 +653,17 @@ RGeo_Globals* rgeo_init_geos_factory()
|
|
633
653
|
rb_define_module_function(geos_factory_class, "_geos_version", cmethod_factory_geos_version, 0);
|
634
654
|
rb_define_module_function(geos_factory_class, "_supports_unary_union?", cmethod_factory_supports_unary_union, 0);
|
635
655
|
|
636
|
-
//
|
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
|
-
|
646
|
-
rb_define_alloc_func(
|
647
|
-
globals->geos_polygon = rb_define_class_under(globals->geos_module, "CAPIPolygonImpl", rb_cObject);
|
648
|
-
rb_define_alloc_func(globals->geos_polygon, alloc_geometry);
|
649
|
-
globals->geos_geometry_collection = rb_define_class_under(globals->geos_module, "CAPIGeometryCollectionImpl", rb_cObject);
|
650
|
-
rb_define_alloc_func(globals->geos_geometry_collection, alloc_geometry);
|
651
|
-
globals->geos_multi_point = rb_define_class_under(globals->geos_module, "CAPIMultiPointImpl", rb_cObject);
|
652
|
-
rb_define_alloc_func(globals->geos_multi_point, alloc_geometry);
|
653
|
-
globals->geos_multi_line_string = rb_define_class_under(globals->geos_module, "CAPIMultiLineStringImpl", rb_cObject);
|
654
|
-
rb_define_alloc_func(globals->geos_multi_line_string, alloc_geometry);
|
655
|
-
globals->geos_multi_polygon = rb_define_class_under(globals->geos_module, "CAPIMultiPolygonImpl", rb_cObject);
|
656
|
-
rb_define_alloc_func(globals->geos_multi_polygon, alloc_geometry);
|
657
|
-
|
658
|
-
// Wrap the globals in a Ruby object and store it off so we have access
|
659
|
-
// to it later. Each factory instance will reference it internally.
|
660
|
-
wrapped_globals = Data_Wrap_Struct(rb_cObject, mark_globals_func, destroy_globals_func, globals);
|
661
|
-
rb_define_const(geos_factory_class, "INTERNAL_CGLOBALS", wrapped_globals);
|
662
|
-
|
663
|
-
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);
|
664
667
|
}
|
665
668
|
|
666
669
|
|
@@ -673,7 +676,6 @@ VALUE rgeo_wrap_geos_geometry(VALUE factory, GEOSGeometry* geom, VALUE klass)
|
|
673
676
|
RGeo_FactoryData* factory_data;
|
674
677
|
GEOSContextHandle_t factory_context;
|
675
678
|
VALUE klasses;
|
676
|
-
RGeo_Globals* globals;
|
677
679
|
VALUE inferred_klass;
|
678
680
|
char is_collection;
|
679
681
|
RGeo_GeometryData* data;
|
@@ -682,7 +684,6 @@ VALUE rgeo_wrap_geos_geometry(VALUE factory, GEOSGeometry* geom, VALUE klass)
|
|
682
684
|
if (geom || !NIL_P(klass)) {
|
683
685
|
factory_data = NIL_P(factory) ? NULL : RGEO_FACTORY_DATA_PTR(factory);
|
684
686
|
factory_context = factory_data ? factory_data->geos_context : NULL;
|
685
|
-
globals = factory_data ? factory_data->globals : NULL;
|
686
687
|
|
687
688
|
// We don't allow "empty" points, so replace such objects with
|
688
689
|
// an empty collection.
|
@@ -690,7 +691,7 @@ VALUE rgeo_wrap_geos_geometry(VALUE factory, GEOSGeometry* geom, VALUE klass)
|
|
690
691
|
if (GEOSGeomTypeId_r(factory_context, geom) == GEOS_POINT && GEOSGetNumCoordinates_r(factory_context, geom) == 0) {
|
691
692
|
GEOSGeom_destroy_r(factory_context, geom);
|
692
693
|
geom = GEOSGeom_createCollection_r(factory_context, GEOS_GEOMETRYCOLLECTION, NULL, 0);
|
693
|
-
klass =
|
694
|
+
klass = rgeo_geos_geometry_collection_class;
|
694
695
|
}
|
695
696
|
}
|
696
697
|
|
@@ -700,35 +701,35 @@ VALUE rgeo_wrap_geos_geometry(VALUE factory, GEOSGeometry* geom, VALUE klass)
|
|
700
701
|
is_collection = 0;
|
701
702
|
switch (GEOSGeomTypeId_r(factory_context, geom)) {
|
702
703
|
case GEOS_POINT:
|
703
|
-
inferred_klass =
|
704
|
+
inferred_klass = rgeo_geos_point_class;
|
704
705
|
break;
|
705
706
|
case GEOS_LINESTRING:
|
706
|
-
inferred_klass =
|
707
|
+
inferred_klass = rgeo_geos_line_string_class;
|
707
708
|
break;
|
708
709
|
case GEOS_LINEARRING:
|
709
|
-
inferred_klass =
|
710
|
+
inferred_klass = rgeo_geos_linear_ring_class;
|
710
711
|
break;
|
711
712
|
case GEOS_POLYGON:
|
712
|
-
inferred_klass =
|
713
|
+
inferred_klass = rgeo_geos_polygon_class;
|
713
714
|
break;
|
714
715
|
case GEOS_MULTIPOINT:
|
715
|
-
inferred_klass =
|
716
|
+
inferred_klass = rgeo_geos_multi_point_class;
|
716
717
|
is_collection = 1;
|
717
718
|
break;
|
718
719
|
case GEOS_MULTILINESTRING:
|
719
|
-
inferred_klass =
|
720
|
+
inferred_klass = rgeo_geos_multi_line_string_class;
|
720
721
|
is_collection = 1;
|
721
722
|
break;
|
722
723
|
case GEOS_MULTIPOLYGON:
|
723
|
-
inferred_klass =
|
724
|
+
inferred_klass = rgeo_geos_multi_polygon_class;
|
724
725
|
is_collection = 1;
|
725
726
|
break;
|
726
727
|
case GEOS_GEOMETRYCOLLECTION:
|
727
|
-
inferred_klass =
|
728
|
+
inferred_klass = rgeo_geos_geometry_collection_class;
|
728
729
|
is_collection = 1;
|
729
730
|
break;
|
730
731
|
default:
|
731
|
-
inferred_klass =
|
732
|
+
inferred_klass = rgeo_geos_geometry_class;
|
732
733
|
break;
|
733
734
|
}
|
734
735
|
if (TYPE(klass) == T_ARRAY && is_collection) {
|
@@ -747,13 +748,12 @@ VALUE rgeo_wrap_geos_geometry(VALUE factory, GEOSGeometry* geom, VALUE klass)
|
|
747
748
|
(GEOSPreparedGeometry*)1 : NULL;
|
748
749
|
data->factory = factory;
|
749
750
|
data->klasses = klasses;
|
750
|
-
result =
|
751
|
+
result = TypedData_Wrap_Struct(klass, &rgeo_geometry_type, data);
|
751
752
|
}
|
752
753
|
}
|
753
754
|
return result;
|
754
755
|
}
|
755
756
|
|
756
|
-
|
757
757
|
VALUE rgeo_wrap_geos_geometry_clone(VALUE factory, const GEOSGeometry* geom, VALUE klass)
|
758
758
|
{
|
759
759
|
VALUE result;
|
@@ -773,19 +773,17 @@ VALUE rgeo_wrap_geos_geometry_clone(VALUE factory, const GEOSGeometry* geom, VAL
|
|
773
773
|
const GEOSGeometry* rgeo_convert_to_geos_geometry(VALUE factory, VALUE obj, VALUE type)
|
774
774
|
{
|
775
775
|
VALUE object;
|
776
|
-
RGeo_Globals* globals;
|
777
776
|
|
778
|
-
if (NIL_P(type) &&
|
777
|
+
if (NIL_P(type) && RGEO_GEOMETRY_TYPEDDATA_P(obj) && RGEO_GEOMETRY_DATA_PTR(obj)->factory == factory) {
|
779
778
|
object = obj;
|
780
779
|
}
|
781
780
|
else {
|
782
|
-
|
783
|
-
object = rb_funcall(globals->feature_module, globals->id_cast, 3, obj, factory, type);
|
781
|
+
object = rb_funcall(rgeo_feature_module, rb_intern("cast"), 3, obj, factory, type);
|
784
782
|
}
|
785
783
|
if (NIL_P(object))
|
786
784
|
return NULL;
|
787
785
|
|
788
|
-
|
786
|
+
Check_TypedStruct(object, &rgeo_geometry_type);
|
789
787
|
return RGEO_GEOMETRY_DATA_PTR(object)->geom;
|
790
788
|
}
|
791
789
|
|
@@ -796,13 +794,11 @@ GEOSGeometry* rgeo_convert_to_detached_geos_geometry(VALUE obj, VALUE factory, V
|
|
796
794
|
GEOSGeometry* geom;
|
797
795
|
RGeo_GeometryData* object_data;
|
798
796
|
const GEOSPreparedGeometry* prep;
|
799
|
-
RGeo_Globals* globals;
|
800
797
|
|
801
798
|
if (klasses) {
|
802
799
|
*klasses = Qnil;
|
803
800
|
}
|
804
|
-
|
805
|
-
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")));
|
806
802
|
geom = NULL;
|
807
803
|
if (!NIL_P(object)) {
|
808
804
|
object_data = RGEO_GEOMETRY_DATA_PTR(object);
|
@@ -829,7 +825,7 @@ GEOSGeometry* rgeo_convert_to_detached_geos_geometry(VALUE obj, VALUE factory, V
|
|
829
825
|
|
830
826
|
char rgeo_is_geos_object(VALUE obj)
|
831
827
|
{
|
832
|
-
return (
|
828
|
+
return RGEO_GEOMETRY_TYPEDDATA_P(obj) ? 1 : 0;
|
833
829
|
}
|
834
830
|
|
835
831
|
void rgeo_check_geos_object(VALUE obj)
|
@@ -842,7 +838,7 @@ void rgeo_check_geos_object(VALUE obj)
|
|
842
838
|
|
843
839
|
const GEOSGeometry* rgeo_get_geos_geometry_safe(VALUE obj)
|
844
840
|
{
|
845
|
-
return (
|
841
|
+
return RGEO_GEOMETRY_TYPEDDATA_P(obj) ? (const GEOSGeometry*)(RGEO_GEOMETRY_DATA_PTR(obj)->geom) : NULL;
|
846
842
|
}
|
847
843
|
|
848
844
|
|
@@ -930,7 +926,8 @@ VALUE rgeo_geos_klasses_and_factories_eql(VALUE obj1, VALUE obj2)
|
|
930
926
|
}
|
931
927
|
else {
|
932
928
|
factory = RGEO_GEOMETRY_DATA_PTR(obj1)->factory;
|
933
|
-
|
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);
|
934
931
|
}
|
935
932
|
return result;
|
936
933
|
}
|
@@ -983,7 +980,7 @@ st_index_t rgeo_geos_objbase_hash(VALUE factory, VALUE type_module, st_index_t h
|
|
983
980
|
ID hash_method;
|
984
981
|
RGeo_Objbase_Hash_Struct hash_struct;
|
985
982
|
|
986
|
-
hash_method =
|
983
|
+
hash_method = rb_intern("hash");
|
987
984
|
hash_struct.seed_hash = hash;
|
988
985
|
hash_struct.h1 = FIX2LONG(rb_funcall(factory, hash_method, 0));
|
989
986
|
hash_struct.h2 = FIX2LONG(rb_funcall(type_module, hash_method, 0));
|