rgeo 2.3.1 → 3.0.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.
- checksums.yaml +4 -4
- data/.yardopts +6 -0
- data/README.md +23 -14
- data/ext/geos_c_impl/analysis.c +30 -25
- data/ext/geos_c_impl/analysis.h +8 -7
- data/ext/geos_c_impl/coordinates.c +27 -21
- data/ext/geos_c_impl/coordinates.h +5 -2
- data/ext/geos_c_impl/errors.c +19 -10
- data/ext/geos_c_impl/errors.h +11 -4
- data/ext/geos_c_impl/extconf.rb +42 -28
- data/ext/geos_c_impl/factory.c +540 -451
- data/ext/geos_c_impl/factory.h +105 -95
- data/ext/geos_c_impl/geometry.c +593 -387
- data/ext/geos_c_impl/geometry.h +10 -5
- data/ext/geos_c_impl/geometry_collection.c +306 -339
- data/ext/geos_c_impl/geometry_collection.h +6 -20
- data/ext/geos_c_impl/globals.c +169 -0
- data/ext/geos_c_impl/globals.h +46 -0
- data/ext/geos_c_impl/line_string.c +271 -231
- data/ext/geos_c_impl/line_string.h +5 -8
- data/ext/geos_c_impl/main.c +16 -16
- data/ext/geos_c_impl/point.c +65 -67
- data/ext/geos_c_impl/point.h +4 -7
- data/ext/geos_c_impl/polygon.c +137 -135
- data/ext/geos_c_impl/polygon.h +11 -11
- data/ext/geos_c_impl/preface.h +16 -10
- data/ext/geos_c_impl/ruby_more.c +67 -0
- data/ext/geos_c_impl/ruby_more.h +25 -0
- data/lib/rgeo/cartesian/analysis.rb +5 -3
- data/lib/rgeo/cartesian/bounding_box.rb +74 -79
- data/lib/rgeo/cartesian/calculations.rb +64 -33
- data/lib/rgeo/cartesian/factory.rb +57 -102
- data/lib/rgeo/cartesian/feature_classes.rb +68 -46
- data/lib/rgeo/cartesian/feature_methods.rb +67 -25
- data/lib/rgeo/cartesian/interface.rb +6 -41
- data/lib/rgeo/cartesian/planar_graph.rb +373 -0
- data/lib/rgeo/cartesian/sweepline_intersector.rb +147 -0
- data/lib/rgeo/cartesian/valid_op.rb +69 -0
- data/lib/rgeo/cartesian.rb +3 -0
- data/lib/rgeo/coord_sys/cs/entities.rb +303 -99
- data/lib/rgeo/coord_sys/cs/factories.rb +0 -2
- data/lib/rgeo/coord_sys/cs/wkt_parser.rb +90 -42
- data/lib/rgeo/coord_sys.rb +1 -20
- data/lib/rgeo/error.rb +15 -0
- data/lib/rgeo/feature/curve.rb +0 -11
- data/lib/rgeo/feature/factory.rb +26 -36
- data/lib/rgeo/feature/factory_generator.rb +6 -14
- data/lib/rgeo/feature/geometry.rb +146 -66
- data/lib/rgeo/feature/geometry_collection.rb +16 -9
- data/lib/rgeo/feature/line_string.rb +4 -5
- data/lib/rgeo/feature/linear_ring.rb +0 -1
- data/lib/rgeo/feature/multi_curve.rb +0 -6
- data/lib/rgeo/feature/multi_surface.rb +3 -4
- data/lib/rgeo/feature/point.rb +4 -5
- data/lib/rgeo/feature/polygon.rb +1 -2
- data/lib/rgeo/feature/surface.rb +3 -4
- data/lib/rgeo/feature/types.rb +69 -85
- data/lib/rgeo/geographic/factory.rb +98 -125
- data/lib/rgeo/geographic/interface.rb +69 -166
- data/lib/rgeo/geographic/projected_feature_classes.rb +21 -9
- data/lib/rgeo/geographic/projected_feature_methods.rb +67 -42
- data/lib/rgeo/geographic/projected_window.rb +36 -22
- data/lib/rgeo/geographic/{proj4_projector.rb → projector.rb} +3 -5
- data/lib/rgeo/geographic/simple_mercator_projector.rb +26 -25
- data/lib/rgeo/geographic/spherical_feature_classes.rb +29 -9
- data/lib/rgeo/geographic/spherical_feature_methods.rb +86 -9
- data/lib/rgeo/geographic/spherical_math.rb +17 -20
- data/lib/rgeo/geographic.rb +1 -1
- data/lib/rgeo/geos/capi_factory.rb +87 -158
- data/lib/rgeo/geos/capi_feature_classes.rb +50 -36
- data/lib/rgeo/geos/ffi_factory.rb +105 -173
- data/lib/rgeo/geos/ffi_feature_classes.rb +34 -10
- data/lib/rgeo/geos/ffi_feature_methods.rb +105 -127
- data/lib/rgeo/geos/interface.rb +20 -59
- data/lib/rgeo/geos/utils.rb +5 -5
- data/lib/rgeo/geos/zm_factory.rb +53 -95
- data/lib/rgeo/geos/zm_feature_methods.rb +30 -33
- data/lib/rgeo/geos.rb +8 -8
- data/lib/rgeo/impl_helper/basic_geometry_collection_methods.rb +9 -22
- data/lib/rgeo/impl_helper/basic_geometry_methods.rb +1 -2
- data/lib/rgeo/impl_helper/basic_line_string_methods.rb +28 -56
- data/lib/rgeo/impl_helper/basic_point_methods.rb +2 -14
- data/lib/rgeo/impl_helper/basic_polygon_methods.rb +17 -26
- data/lib/rgeo/impl_helper/utils.rb +21 -0
- data/lib/rgeo/impl_helper/valid_op.rb +350 -0
- data/lib/rgeo/impl_helper/validity_check.rb +139 -0
- data/lib/rgeo/impl_helper.rb +1 -0
- data/lib/rgeo/version.rb +1 -1
- data/lib/rgeo/wkrep/wkb_generator.rb +73 -63
- data/lib/rgeo/wkrep/wkb_parser.rb +33 -31
- data/lib/rgeo/wkrep/wkt_generator.rb +52 -45
- data/lib/rgeo/wkrep/wkt_parser.rb +48 -35
- data/lib/rgeo.rb +1 -3
- metadata +50 -13
- data/lib/rgeo/coord_sys/srs_database/entry.rb +0 -107
- data/lib/rgeo/coord_sys/srs_database/sr_org.rb +0 -64
- data/lib/rgeo/coord_sys/srs_database/url_reader.rb +0 -65
data/ext/geos_c_impl/factory.c
CHANGED
@@ -2,191 +2,261 @@
|
|
2
2
|
Factory and utility functions for GEOS wrapper
|
3
3
|
*/
|
4
4
|
|
5
|
-
|
6
5
|
#include "preface.h"
|
7
6
|
|
8
7
|
#ifdef RGEO_GEOS_SUPPORTED
|
9
8
|
|
10
|
-
#include <ruby.h>
|
11
9
|
#include <geos_c.h>
|
10
|
+
#include <ruby.h>
|
12
11
|
|
12
|
+
#include "errors.h"
|
13
13
|
#include "factory.h"
|
14
14
|
#include "geometry.h"
|
15
|
-
#include "
|
15
|
+
#include "geometry_collection.h"
|
16
|
+
#include "globals.h"
|
16
17
|
#include "line_string.h"
|
18
|
+
#include "point.h"
|
17
19
|
#include "polygon.h"
|
18
|
-
#include "
|
19
|
-
#include "errors.h"
|
20
|
+
#include "ruby_more.h"
|
20
21
|
|
21
22
|
RGEO_BEGIN_C
|
22
23
|
|
23
|
-
|
24
24
|
/**** RUBY AND GEOS CALLBACKS ****/
|
25
25
|
|
26
|
-
|
27
|
-
// NOP message handler. GEOS requires that a message handler be set
|
28
|
-
// for every context handle.
|
29
|
-
|
30
|
-
static void message_handler(const char* fmt, ...)
|
31
|
-
{
|
32
|
-
}
|
33
|
-
|
34
|
-
|
35
26
|
// Destroy function for factory data. We destroy any serialization
|
36
|
-
// objects that have been created for the factory
|
37
|
-
// the
|
27
|
+
// objects that have been created for the factory before freeing
|
28
|
+
// the factory data itself.
|
38
29
|
|
39
|
-
static void
|
30
|
+
static void
|
31
|
+
destroy_factory_func(void* data)
|
40
32
|
{
|
41
|
-
|
33
|
+
RGeo_FactoryData* factory_data;
|
42
34
|
|
43
|
-
|
44
|
-
if (
|
45
|
-
|
35
|
+
factory_data = (RGeo_FactoryData*)data;
|
36
|
+
if (factory_data->wkt_reader) {
|
37
|
+
GEOSWKTReader_destroy(factory_data->wkt_reader);
|
46
38
|
}
|
47
|
-
if (
|
48
|
-
|
39
|
+
if (factory_data->wkb_reader) {
|
40
|
+
GEOSWKBReader_destroy(factory_data->wkb_reader);
|
49
41
|
}
|
50
|
-
if (
|
51
|
-
|
42
|
+
if (factory_data->wkt_writer) {
|
43
|
+
GEOSWKTWriter_destroy(factory_data->wkt_writer);
|
52
44
|
}
|
53
|
-
if (
|
54
|
-
|
45
|
+
if (factory_data->wkb_writer) {
|
46
|
+
GEOSWKBWriter_destroy(factory_data->wkb_writer);
|
55
47
|
}
|
56
|
-
if (
|
57
|
-
|
48
|
+
if (factory_data->psych_wkt_reader) {
|
49
|
+
GEOSWKTReader_destroy(factory_data->psych_wkt_reader);
|
58
50
|
}
|
59
|
-
if (
|
60
|
-
|
51
|
+
if (factory_data->marshal_wkb_reader) {
|
52
|
+
GEOSWKBReader_destroy(factory_data->marshal_wkb_reader);
|
61
53
|
}
|
62
|
-
if (
|
63
|
-
|
54
|
+
if (factory_data->psych_wkt_writer) {
|
55
|
+
GEOSWKTWriter_destroy(factory_data->psych_wkt_writer);
|
64
56
|
}
|
65
|
-
if (
|
66
|
-
|
57
|
+
if (factory_data->marshal_wkb_writer) {
|
58
|
+
GEOSWKBWriter_destroy(factory_data->marshal_wkb_writer);
|
67
59
|
}
|
68
|
-
|
69
|
-
free(data);
|
60
|
+
FREE(factory_data);
|
70
61
|
}
|
71
62
|
|
72
|
-
|
73
63
|
// Destroy function for geometry data. We destroy the internal
|
74
64
|
// GEOS geometry (if present) before freeing the data itself.
|
75
65
|
|
76
|
-
static void
|
66
|
+
static void
|
67
|
+
destroy_geometry_func(void* data)
|
77
68
|
{
|
69
|
+
RGeo_GeometryData* geometry_data;
|
78
70
|
const GEOSPreparedGeometry* prep;
|
79
71
|
|
80
|
-
|
81
|
-
|
72
|
+
geometry_data = (RGeo_GeometryData*)data;
|
73
|
+
if (geometry_data->geom) {
|
74
|
+
GEOSGeom_destroy(geometry_data->geom);
|
82
75
|
}
|
83
|
-
prep =
|
84
|
-
if (prep && prep != (const GEOSPreparedGeometry*)1 &&
|
85
|
-
|
86
|
-
|
87
|
-
|
76
|
+
prep = geometry_data->prep;
|
77
|
+
if (prep && prep != (const GEOSPreparedGeometry*)1 &&
|
78
|
+
prep != (const GEOSPreparedGeometry*)2 &&
|
79
|
+
prep != (const GEOSPreparedGeometry*)3) {
|
80
|
+
GEOSPreparedGeom_destroy(prep);
|
88
81
|
}
|
89
|
-
|
82
|
+
FREE(geometry_data);
|
90
83
|
}
|
91
84
|
|
92
|
-
|
93
85
|
// Mark function for factory data. This marks the wkt and wkb generator
|
94
86
|
// handles so they don't get collected.
|
95
87
|
|
96
|
-
static void
|
88
|
+
static void
|
89
|
+
mark_factory_func(void* data)
|
97
90
|
{
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
if (!NIL_P(
|
102
|
-
|
91
|
+
RGeo_FactoryData* factory_data;
|
92
|
+
|
93
|
+
factory_data = (RGeo_FactoryData*)data;
|
94
|
+
if (!NIL_P(factory_data->wkrep_wkt_generator)) {
|
95
|
+
mark(factory_data->wkrep_wkt_generator);
|
103
96
|
}
|
104
|
-
if (!NIL_P(
|
105
|
-
|
97
|
+
if (!NIL_P(factory_data->wkrep_wkb_generator)) {
|
98
|
+
mark(factory_data->wkrep_wkb_generator);
|
106
99
|
}
|
107
|
-
if (!NIL_P(
|
108
|
-
|
100
|
+
if (!NIL_P(factory_data->wkrep_wkt_parser)) {
|
101
|
+
mark(factory_data->wkrep_wkt_parser);
|
109
102
|
}
|
110
|
-
if (!NIL_P(
|
111
|
-
|
103
|
+
if (!NIL_P(factory_data->wkrep_wkb_parser)) {
|
104
|
+
mark(factory_data->wkrep_wkb_parser);
|
112
105
|
}
|
113
|
-
if (!NIL_P(
|
114
|
-
|
106
|
+
if (!NIL_P(factory_data->coord_sys_obj)) {
|
107
|
+
mark(factory_data->coord_sys_obj);
|
115
108
|
}
|
116
109
|
}
|
117
110
|
|
118
|
-
|
119
111
|
// Mark function for geometry data. This marks the factory and klasses
|
120
112
|
// held by the geometry so those don't get collected.
|
121
113
|
|
122
|
-
static void
|
114
|
+
static void
|
115
|
+
mark_geometry_func(void* data)
|
123
116
|
{
|
124
|
-
|
125
|
-
|
117
|
+
RGeo_GeometryData* geometry_data;
|
118
|
+
|
119
|
+
geometry_data = (RGeo_GeometryData*)data;
|
120
|
+
if (!NIL_P(geometry_data->factory)) {
|
121
|
+
mark(geometry_data->factory);
|
126
122
|
}
|
127
|
-
if (!NIL_P(
|
128
|
-
|
123
|
+
if (!NIL_P(geometry_data->klasses)) {
|
124
|
+
mark(geometry_data->klasses);
|
129
125
|
}
|
130
126
|
}
|
131
127
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
static void destroy_globals_func(RGeo_Globals* data)
|
128
|
+
#ifdef HAVE_RB_GC_MARK_MOVABLE
|
129
|
+
static void
|
130
|
+
compact_factory_func(void* data)
|
137
131
|
{
|
138
|
-
|
139
|
-
}
|
140
|
-
|
132
|
+
RGeo_FactoryData* factory_data;
|
141
133
|
|
142
|
-
|
143
|
-
|
134
|
+
factory_data = (RGeo_FactoryData*)data;
|
135
|
+
if (!NIL_P(factory_data->wkrep_wkt_generator)) {
|
136
|
+
factory_data->wkrep_wkt_generator =
|
137
|
+
rb_gc_location(factory_data->wkrep_wkt_generator);
|
138
|
+
}
|
139
|
+
if (!NIL_P(factory_data->wkrep_wkb_generator)) {
|
140
|
+
factory_data->wkrep_wkb_generator =
|
141
|
+
rb_gc_location(factory_data->wkrep_wkb_generator);
|
142
|
+
}
|
143
|
+
if (!NIL_P(factory_data->wkrep_wkt_parser)) {
|
144
|
+
factory_data->wkrep_wkt_parser =
|
145
|
+
rb_gc_location(factory_data->wkrep_wkt_parser);
|
146
|
+
}
|
147
|
+
if (!NIL_P(factory_data->wkrep_wkb_parser)) {
|
148
|
+
factory_data->wkrep_wkb_parser =
|
149
|
+
rb_gc_location(factory_data->wkrep_wkb_parser);
|
150
|
+
}
|
151
|
+
if (!NIL_P(factory_data->coord_sys_obj)) {
|
152
|
+
factory_data->coord_sys_obj = rb_gc_location(factory_data->coord_sys_obj);
|
153
|
+
}
|
154
|
+
}
|
144
155
|
|
145
|
-
static void
|
156
|
+
static void
|
157
|
+
compact_geometry_func(void* data)
|
146
158
|
{
|
159
|
+
RGeo_GeometryData* geometry_data;
|
160
|
+
|
161
|
+
geometry_data = (RGeo_GeometryData*)data;
|
162
|
+
if (!NIL_P(geometry_data->factory)) {
|
163
|
+
geometry_data->factory = rb_gc_location(geometry_data->factory);
|
164
|
+
}
|
165
|
+
if (!NIL_P(geometry_data->klasses)) {
|
166
|
+
geometry_data->klasses = rb_gc_location(geometry_data->klasses);
|
167
|
+
}
|
147
168
|
}
|
169
|
+
#endif
|
148
170
|
|
171
|
+
const rb_data_type_t rgeo_factory_type = { .wrap_struct_name = "RGeo/Factory",
|
172
|
+
.function = {
|
173
|
+
.dmark = mark_factory_func,
|
174
|
+
.dfree = destroy_factory_func,
|
175
|
+
#ifdef HAVE_RB_GC_MARK_MOVABLE
|
176
|
+
.dcompact = compact_factory_func,
|
177
|
+
#endif
|
178
|
+
} };
|
179
|
+
|
180
|
+
const rb_data_type_t rgeo_geometry_type = { .wrap_struct_name = "RGeo/Geometry",
|
181
|
+
.function = {
|
182
|
+
.dmark = mark_geometry_func,
|
183
|
+
.dfree = destroy_geometry_func,
|
184
|
+
#ifdef HAVE_RB_GC_MARK_MOVABLE
|
185
|
+
.dcompact = compact_geometry_func,
|
186
|
+
#endif
|
187
|
+
} };
|
149
188
|
|
150
189
|
/**** RUBY METHOD DEFINITIONS ****/
|
151
190
|
|
152
|
-
|
153
|
-
|
191
|
+
static VALUE
|
192
|
+
method_factory_srid(VALUE self)
|
154
193
|
{
|
155
194
|
return INT2NUM(RGEO_FACTORY_DATA_PTR(self)->srid);
|
156
195
|
}
|
157
196
|
|
158
|
-
|
159
|
-
|
197
|
+
static VALUE
|
198
|
+
method_factory_buffer_resolution(VALUE self)
|
160
199
|
{
|
161
200
|
return INT2NUM(RGEO_FACTORY_DATA_PTR(self)->buffer_resolution);
|
162
201
|
}
|
163
202
|
|
164
|
-
|
165
|
-
|
203
|
+
static VALUE
|
204
|
+
method_factory_flags(VALUE self)
|
166
205
|
{
|
167
206
|
return INT2NUM(RGEO_FACTORY_DATA_PTR(self)->flags);
|
168
207
|
}
|
169
208
|
|
209
|
+
VALUE
|
210
|
+
method_factory_supports_z_p(VALUE self)
|
211
|
+
{
|
212
|
+
return RGEO_FACTORY_DATA_PTR(self)->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z
|
213
|
+
? Qtrue
|
214
|
+
: Qfalse;
|
215
|
+
}
|
216
|
+
|
217
|
+
VALUE
|
218
|
+
method_factory_supports_m_p(VALUE self)
|
219
|
+
{
|
220
|
+
return RGEO_FACTORY_DATA_PTR(self)->flags & RGEO_FACTORYFLAGS_SUPPORTS_M
|
221
|
+
? Qtrue
|
222
|
+
: Qfalse;
|
223
|
+
}
|
224
|
+
|
225
|
+
VALUE
|
226
|
+
method_factory_supports_z_or_m_p(VALUE self)
|
227
|
+
{
|
228
|
+
return RGEO_FACTORY_DATA_PTR(self)->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M
|
229
|
+
? Qtrue
|
230
|
+
: Qfalse;
|
231
|
+
}
|
232
|
+
|
233
|
+
VALUE
|
234
|
+
method_factory_prepare_heuristic_p(VALUE self)
|
235
|
+
{
|
236
|
+
return RGEO_FACTORY_DATA_PTR(self)->flags &
|
237
|
+
RGEO_FACTORYFLAGS_PREPARE_HEURISTIC
|
238
|
+
? Qtrue
|
239
|
+
: Qfalse;
|
240
|
+
}
|
170
241
|
|
171
|
-
static VALUE
|
242
|
+
static VALUE
|
243
|
+
method_factory_parse_wkt(VALUE self, VALUE str)
|
172
244
|
{
|
173
245
|
RGeo_FactoryData* self_data;
|
174
|
-
GEOSContextHandle_t self_context;
|
175
246
|
GEOSWKTReader* wkt_reader;
|
176
247
|
VALUE result;
|
177
248
|
GEOSGeometry* geom;
|
178
249
|
|
179
250
|
Check_Type(str, T_STRING);
|
180
251
|
self_data = RGEO_FACTORY_DATA_PTR(self);
|
181
|
-
self_context = self_data->geos_context;
|
182
252
|
wkt_reader = self_data->wkt_reader;
|
183
253
|
if (!wkt_reader) {
|
184
|
-
wkt_reader =
|
254
|
+
wkt_reader = GEOSWKTReader_create();
|
185
255
|
self_data->wkt_reader = wkt_reader;
|
186
256
|
}
|
187
257
|
result = Qnil;
|
188
258
|
if (wkt_reader) {
|
189
|
-
geom =
|
259
|
+
geom = GEOSWKTReader_read(wkt_reader, RSTRING_PTR(str));
|
190
260
|
if (geom) {
|
191
261
|
result = rgeo_wrap_geos_geometry(self, geom, Qnil);
|
192
262
|
}
|
@@ -194,26 +264,31 @@ static VALUE method_factory_parse_wkt(VALUE self, VALUE str)
|
|
194
264
|
return result;
|
195
265
|
}
|
196
266
|
|
197
|
-
|
198
|
-
|
267
|
+
static VALUE
|
268
|
+
method_factory_parse_wkb(VALUE self, VALUE str)
|
199
269
|
{
|
200
270
|
RGeo_FactoryData* self_data;
|
201
|
-
GEOSContextHandle_t self_context;
|
202
271
|
GEOSWKBReader* wkb_reader;
|
203
272
|
VALUE result;
|
204
273
|
GEOSGeometry* geom;
|
274
|
+
char* c_str;
|
205
275
|
|
206
276
|
Check_Type(str, T_STRING);
|
207
277
|
self_data = RGEO_FACTORY_DATA_PTR(self);
|
208
|
-
self_context = self_data->geos_context;
|
209
278
|
wkb_reader = self_data->wkb_reader;
|
210
279
|
if (!wkb_reader) {
|
211
|
-
wkb_reader =
|
280
|
+
wkb_reader = GEOSWKBReader_create();
|
212
281
|
self_data->wkb_reader = wkb_reader;
|
213
282
|
}
|
214
283
|
result = Qnil;
|
215
284
|
if (wkb_reader) {
|
216
|
-
|
285
|
+
c_str = RSTRING_PTR(str);
|
286
|
+
if (c_str[0] == '\x00' || c_str[0] == '\x01')
|
287
|
+
geom = GEOSWKBReader_read(
|
288
|
+
wkb_reader, (unsigned char*)c_str, (size_t)RSTRING_LEN(str));
|
289
|
+
else
|
290
|
+
geom = GEOSWKBReader_readHEX(
|
291
|
+
wkb_reader, (unsigned char*)c_str, (size_t)RSTRING_LEN(str));
|
217
292
|
if (geom) {
|
218
293
|
result = rgeo_wrap_geos_geometry(self, geom, Qnil);
|
219
294
|
}
|
@@ -221,26 +296,25 @@ static VALUE method_factory_parse_wkb(VALUE self, VALUE str)
|
|
221
296
|
return result;
|
222
297
|
}
|
223
298
|
|
224
|
-
|
225
|
-
|
299
|
+
static VALUE
|
300
|
+
method_factory_read_for_marshal(VALUE self, VALUE str)
|
226
301
|
{
|
227
302
|
RGeo_FactoryData* self_data;
|
228
|
-
GEOSContextHandle_t self_context;
|
229
303
|
GEOSWKBReader* wkb_reader;
|
230
304
|
VALUE result;
|
231
305
|
GEOSGeometry* geom;
|
232
306
|
|
233
307
|
Check_Type(str, T_STRING);
|
234
308
|
self_data = RGEO_FACTORY_DATA_PTR(self);
|
235
|
-
self_context = self_data->geos_context;
|
236
309
|
wkb_reader = self_data->marshal_wkb_reader;
|
237
310
|
if (!wkb_reader) {
|
238
|
-
wkb_reader =
|
311
|
+
wkb_reader = GEOSWKBReader_create();
|
239
312
|
self_data->marshal_wkb_reader = wkb_reader;
|
240
313
|
}
|
241
314
|
result = Qnil;
|
242
315
|
if (wkb_reader) {
|
243
|
-
geom =
|
316
|
+
geom = GEOSWKBReader_read(
|
317
|
+
wkb_reader, (unsigned char*)RSTRING_PTR(str), (size_t)RSTRING_LEN(str));
|
244
318
|
if (geom) {
|
245
319
|
result = rgeo_wrap_geos_geometry(self, geom, Qnil);
|
246
320
|
}
|
@@ -248,26 +322,24 @@ static VALUE method_factory_read_for_marshal(VALUE self, VALUE str)
|
|
248
322
|
return result;
|
249
323
|
}
|
250
324
|
|
251
|
-
|
252
|
-
|
325
|
+
static VALUE
|
326
|
+
method_factory_read_for_psych(VALUE self, VALUE str)
|
253
327
|
{
|
254
328
|
RGeo_FactoryData* self_data;
|
255
|
-
GEOSContextHandle_t self_context;
|
256
329
|
GEOSWKTReader* wkt_reader;
|
257
330
|
VALUE result;
|
258
331
|
GEOSGeometry* geom;
|
259
332
|
|
260
333
|
Check_Type(str, T_STRING);
|
261
334
|
self_data = RGEO_FACTORY_DATA_PTR(self);
|
262
|
-
self_context = self_data->geos_context;
|
263
335
|
wkt_reader = self_data->psych_wkt_reader;
|
264
336
|
if (!wkt_reader) {
|
265
|
-
wkt_reader =
|
337
|
+
wkt_reader = GEOSWKTReader_create();
|
266
338
|
self_data->psych_wkt_reader = wkt_reader;
|
267
339
|
}
|
268
340
|
result = Qnil;
|
269
341
|
if (wkt_reader) {
|
270
|
-
geom =
|
342
|
+
geom = GEOSWKTReader_read(wkt_reader, RSTRING_PTR(str));
|
271
343
|
if (geom) {
|
272
344
|
result = rgeo_wrap_geos_geometry(self, geom, Qnil);
|
273
345
|
}
|
@@ -275,43 +347,40 @@ static VALUE method_factory_read_for_psych(VALUE self, VALUE str)
|
|
275
347
|
return result;
|
276
348
|
}
|
277
349
|
|
350
|
+
#ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
|
351
|
+
static VALUE marshal_wkb_generator;
|
352
|
+
#endif
|
278
353
|
|
279
|
-
static VALUE
|
354
|
+
static VALUE
|
355
|
+
method_factory_write_for_marshal(VALUE self, VALUE obj)
|
280
356
|
{
|
281
357
|
RGeo_FactoryData* self_data;
|
282
|
-
GEOSContextHandle_t self_context;
|
283
358
|
GEOSWKBWriter* wkb_writer;
|
284
359
|
const GEOSGeometry* geom;
|
285
360
|
VALUE result;
|
286
361
|
char* str;
|
287
362
|
size_t size;
|
288
363
|
char has_3d;
|
289
|
-
#ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
|
290
|
-
RGeo_Globals* globals;
|
291
|
-
VALUE wkb_generator;
|
292
|
-
#endif
|
293
364
|
|
294
365
|
self_data = RGEO_FACTORY_DATA_PTR(self);
|
295
|
-
self_context = self_data->geos_context;
|
296
366
|
has_3d = self_data->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M;
|
297
367
|
#ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
|
298
368
|
if (has_3d) {
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
rb_intern("marshal_wkb_generator"), 0);
|
305
|
-
globals->marshal_wkb_generator = wkb_generator;
|
369
|
+
if (NIL_P(marshal_wkb_generator)) {
|
370
|
+
marshal_wkb_generator =
|
371
|
+
rb_funcall(rb_const_get_at(rgeo_geos_module, rb_intern("Utils")),
|
372
|
+
rb_intern("marshal_wkb_generator"),
|
373
|
+
0);
|
306
374
|
}
|
307
|
-
return rb_funcall(
|
375
|
+
return rb_funcall(marshal_wkb_generator, rb_intern("generate"), 1, obj);
|
308
376
|
}
|
309
377
|
#endif
|
310
378
|
wkb_writer = self_data->marshal_wkb_writer;
|
311
379
|
if (!wkb_writer) {
|
312
|
-
wkb_writer =
|
380
|
+
wkb_writer = GEOSWKBWriter_create();
|
381
|
+
GEOSWKBWriter_setOutputDimension(wkb_writer, 2);
|
313
382
|
if (has_3d) {
|
314
|
-
|
383
|
+
GEOSWKBWriter_setOutputDimension(wkb_writer, 3);
|
315
384
|
}
|
316
385
|
self_data->marshal_wkb_writer = wkb_writer;
|
317
386
|
}
|
@@ -319,52 +388,50 @@ static VALUE method_factory_write_for_marshal(VALUE self, VALUE obj)
|
|
319
388
|
if (wkb_writer) {
|
320
389
|
geom = rgeo_get_geos_geometry_safe(obj);
|
321
390
|
if (geom) {
|
322
|
-
str = (char*)
|
391
|
+
str = (char*)GEOSWKBWriter_write(wkb_writer, geom, &size);
|
323
392
|
if (str) {
|
324
393
|
result = rb_str_new(str, size);
|
325
|
-
|
394
|
+
GEOSFree(str);
|
326
395
|
}
|
327
396
|
}
|
328
397
|
}
|
329
398
|
return result;
|
330
399
|
}
|
331
400
|
|
401
|
+
#ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
|
402
|
+
static VALUE psych_wkt_generator;
|
403
|
+
#endif
|
332
404
|
|
333
|
-
static VALUE
|
405
|
+
static VALUE
|
406
|
+
method_factory_write_for_psych(VALUE self, VALUE obj)
|
334
407
|
{
|
335
408
|
RGeo_FactoryData* self_data;
|
336
|
-
GEOSContextHandle_t self_context;
|
337
409
|
GEOSWKTWriter* wkt_writer;
|
338
410
|
const GEOSGeometry* geom;
|
339
411
|
VALUE result;
|
340
412
|
char* str;
|
341
413
|
char has_3d;
|
342
|
-
#ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
|
343
|
-
RGeo_Globals* globals;
|
344
|
-
VALUE wkt_generator;
|
345
|
-
#endif
|
346
414
|
|
347
415
|
self_data = RGEO_FACTORY_DATA_PTR(self);
|
348
|
-
self_context = self_data->geos_context;
|
349
416
|
has_3d = self_data->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M;
|
350
417
|
#ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
|
351
418
|
if (has_3d) {
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
rb_intern("psych_wkt_generator"), 0);
|
358
|
-
globals->psych_wkt_generator = wkt_generator;
|
419
|
+
if (NIL_P(psych_wkt_generator)) {
|
420
|
+
psych_wkt_generator =
|
421
|
+
rb_funcall(rb_const_get_at(rgeo_geos_module, rb_intern("Utils")),
|
422
|
+
rb_intern("psych_wkt_generator"),
|
423
|
+
0);
|
359
424
|
}
|
360
|
-
return rb_funcall(
|
425
|
+
return rb_funcall(psych_wkt_generator, rb_intern("generate"), 1, obj);
|
361
426
|
}
|
362
427
|
#endif
|
363
428
|
wkt_writer = self_data->psych_wkt_writer;
|
364
429
|
if (!wkt_writer) {
|
365
|
-
wkt_writer =
|
430
|
+
wkt_writer = GEOSWKTWriter_create();
|
431
|
+
GEOSWKTWriter_setOutputDimension(wkt_writer, 2);
|
432
|
+
GEOSWKTWriter_setTrim(wkt_writer, 1);
|
366
433
|
if (has_3d) {
|
367
|
-
|
434
|
+
GEOSWKTWriter_setOutputDimension(wkt_writer, 3);
|
368
435
|
}
|
369
436
|
self_data->psych_wkt_writer = wkt_writer;
|
370
437
|
}
|
@@ -372,24 +439,24 @@ static VALUE method_factory_write_for_psych(VALUE self, VALUE obj)
|
|
372
439
|
if (wkt_writer) {
|
373
440
|
geom = rgeo_get_geos_geometry_safe(obj);
|
374
441
|
if (geom) {
|
375
|
-
str =
|
442
|
+
str = GEOSWKTWriter_write(wkt_writer, geom);
|
376
443
|
if (str) {
|
377
444
|
result = rb_str_new2(str);
|
378
|
-
|
445
|
+
GEOSFree(str);
|
379
446
|
}
|
380
447
|
}
|
381
448
|
}
|
382
449
|
return result;
|
383
450
|
}
|
384
451
|
|
385
|
-
|
386
|
-
|
452
|
+
static VALUE
|
453
|
+
cmethod_factory_geos_version(VALUE klass)
|
387
454
|
{
|
388
455
|
return rb_str_new2(GEOS_VERSION);
|
389
456
|
}
|
390
457
|
|
391
|
-
|
392
|
-
|
458
|
+
static VALUE
|
459
|
+
cmethod_factory_supports_unary_union(VALUE klass)
|
393
460
|
{
|
394
461
|
#ifdef RGEO_GEOS_SUPPORTS_UNARYUNION
|
395
462
|
return Qtrue;
|
@@ -398,105 +465,97 @@ static VALUE cmethod_factory_supports_unary_union(VALUE klass)
|
|
398
465
|
#endif
|
399
466
|
}
|
400
467
|
|
401
|
-
static VALUE
|
402
|
-
|
468
|
+
static VALUE
|
469
|
+
cmethod_factory_create(VALUE klass,
|
470
|
+
VALUE flags,
|
471
|
+
VALUE srid,
|
472
|
+
VALUE buffer_resolution,
|
473
|
+
VALUE wkt_generator,
|
474
|
+
VALUE wkb_generator,
|
475
|
+
VALUE coord_sys_obj)
|
403
476
|
{
|
404
477
|
VALUE result;
|
405
478
|
RGeo_FactoryData* data;
|
406
|
-
GEOSContextHandle_t context;
|
407
|
-
VALUE wrapped_globals;
|
408
479
|
|
409
480
|
result = Qnil;
|
410
481
|
data = ALLOC(RGeo_FactoryData);
|
411
482
|
if (data) {
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
data->wkrep_wkb_generator = wkb_generator;
|
430
|
-
data->wkrep_wkt_parser = Qnil;
|
431
|
-
data->wkrep_wkb_parser = Qnil;
|
432
|
-
data->proj4_obj = proj4_obj;
|
433
|
-
data->coord_sys_obj = coord_sys_obj;
|
434
|
-
result = Data_Wrap_Struct(klass, mark_factory_func, destroy_factory_func, data);
|
435
|
-
}
|
436
|
-
else {
|
437
|
-
free(data);
|
438
|
-
}
|
483
|
+
data->flags = RB_NUM2INT(flags);
|
484
|
+
data->srid = RB_NUM2INT(srid);
|
485
|
+
data->buffer_resolution = RB_NUM2INT(buffer_resolution);
|
486
|
+
data->wkt_reader = NULL;
|
487
|
+
data->wkb_reader = NULL;
|
488
|
+
data->wkt_writer = NULL;
|
489
|
+
data->wkb_writer = NULL;
|
490
|
+
data->psych_wkt_reader = NULL;
|
491
|
+
data->marshal_wkb_reader = NULL;
|
492
|
+
data->psych_wkt_writer = NULL;
|
493
|
+
data->marshal_wkb_writer = NULL;
|
494
|
+
data->wkrep_wkt_generator = wkt_generator;
|
495
|
+
data->wkrep_wkb_generator = wkb_generator;
|
496
|
+
data->wkrep_wkt_parser = Qnil;
|
497
|
+
data->wkrep_wkb_parser = Qnil;
|
498
|
+
data->coord_sys_obj = coord_sys_obj;
|
499
|
+
result = TypedData_Wrap_Struct(klass, &rgeo_factory_type, data);
|
439
500
|
}
|
440
501
|
return result;
|
441
502
|
}
|
442
503
|
|
443
|
-
|
444
|
-
|
504
|
+
static VALUE
|
505
|
+
alloc_factory(VALUE klass)
|
445
506
|
{
|
446
|
-
return cmethod_factory_create(
|
507
|
+
return cmethod_factory_create(
|
508
|
+
klass, INT2NUM(0), INT2NUM(0), INT2NUM(0), Qnil, Qnil, Qnil);
|
447
509
|
}
|
448
510
|
|
449
|
-
|
450
|
-
|
511
|
+
static VALUE
|
512
|
+
method_factory_initialize_copy(VALUE self, VALUE orig)
|
451
513
|
{
|
452
514
|
RGeo_FactoryData* self_data;
|
453
515
|
RGeo_FactoryData* orig_data;
|
454
|
-
GEOSContextHandle_t context;
|
455
516
|
|
456
517
|
// Clear out existing data
|
457
518
|
self_data = RGEO_FACTORY_DATA_PTR(self);
|
458
|
-
context = self_data->geos_context;
|
459
519
|
if (self_data->wkt_reader) {
|
460
|
-
|
520
|
+
GEOSWKTReader_destroy(self_data->wkt_reader);
|
461
521
|
self_data->wkt_reader = NULL;
|
462
522
|
}
|
463
523
|
if (self_data->wkb_reader) {
|
464
|
-
|
524
|
+
GEOSWKBReader_destroy(self_data->wkb_reader);
|
465
525
|
self_data->wkb_reader = NULL;
|
466
526
|
}
|
467
527
|
if (self_data->wkt_writer) {
|
468
|
-
|
528
|
+
GEOSWKTWriter_destroy(self_data->wkt_writer);
|
469
529
|
self_data->wkt_writer = NULL;
|
470
530
|
}
|
471
531
|
if (self_data->wkb_writer) {
|
472
|
-
|
532
|
+
GEOSWKBWriter_destroy(self_data->wkb_writer);
|
473
533
|
self_data->wkb_writer = NULL;
|
474
534
|
}
|
475
535
|
if (self_data->psych_wkt_reader) {
|
476
|
-
|
536
|
+
GEOSWKTReader_destroy(self_data->psych_wkt_reader);
|
477
537
|
self_data->psych_wkt_reader = NULL;
|
478
538
|
}
|
479
539
|
if (self_data->marshal_wkb_reader) {
|
480
|
-
|
540
|
+
GEOSWKBReader_destroy(self_data->marshal_wkb_reader);
|
481
541
|
self_data->marshal_wkb_reader = NULL;
|
482
542
|
}
|
483
543
|
if (self_data->psych_wkt_writer) {
|
484
|
-
|
544
|
+
GEOSWKTWriter_destroy(self_data->psych_wkt_writer);
|
485
545
|
self_data->psych_wkt_writer = NULL;
|
486
546
|
}
|
487
547
|
if (self_data->marshal_wkb_writer) {
|
488
|
-
|
548
|
+
GEOSWKBWriter_destroy(self_data->marshal_wkb_writer);
|
489
549
|
self_data->marshal_wkb_writer = NULL;
|
490
550
|
}
|
491
551
|
self_data->wkrep_wkt_generator = Qnil;
|
492
552
|
self_data->wkrep_wkb_generator = Qnil;
|
493
553
|
self_data->wkrep_wkt_parser = Qnil;
|
494
554
|
self_data->wkrep_wkb_parser = Qnil;
|
495
|
-
self_data->proj4_obj = Qnil;
|
496
555
|
self_data->coord_sys_obj = Qnil;
|
497
556
|
|
498
557
|
// Copy new data from original object
|
499
|
-
if (
|
558
|
+
if (RGEO_FACTORY_TYPEDDATA_P(orig)) {
|
500
559
|
orig_data = RGEO_FACTORY_DATA_PTR(orig);
|
501
560
|
self_data->flags = orig_data->flags;
|
502
561
|
self_data->srid = orig_data->srid;
|
@@ -505,14 +564,13 @@ static VALUE method_factory_initialize_copy(VALUE self, VALUE orig)
|
|
505
564
|
self_data->wkrep_wkb_generator = orig_data->wkrep_wkb_generator;
|
506
565
|
self_data->wkrep_wkt_parser = orig_data->wkrep_wkt_parser;
|
507
566
|
self_data->wkrep_wkb_parser = orig_data->wkrep_wkb_parser;
|
508
|
-
self_data->proj4_obj = orig_data->proj4_obj;
|
509
567
|
self_data->coord_sys_obj = orig_data->coord_sys_obj;
|
510
568
|
}
|
511
569
|
return self;
|
512
570
|
}
|
513
571
|
|
514
|
-
|
515
|
-
|
572
|
+
static VALUE
|
573
|
+
method_set_wkrep_parsers(VALUE self, VALUE wkt_parser, VALUE wkb_parser)
|
516
574
|
{
|
517
575
|
RGeo_FactoryData* self_data;
|
518
576
|
|
@@ -523,157 +581,148 @@ static VALUE method_set_wkrep_parsers(VALUE self, VALUE wkt_parser, VALUE wkb_pa
|
|
523
581
|
return self;
|
524
582
|
}
|
525
583
|
|
526
|
-
|
527
|
-
|
528
|
-
{
|
529
|
-
return RGEO_FACTORY_DATA_PTR(self)->proj4_obj;
|
530
|
-
}
|
531
|
-
|
532
|
-
|
533
|
-
static VALUE method_get_coord_sys(VALUE self)
|
584
|
+
static VALUE
|
585
|
+
method_get_coord_sys(VALUE self)
|
534
586
|
{
|
535
587
|
return RGEO_FACTORY_DATA_PTR(self)->coord_sys_obj;
|
536
588
|
}
|
537
589
|
|
538
|
-
|
539
|
-
|
590
|
+
static VALUE
|
591
|
+
method_get_wkt_generator(VALUE self)
|
540
592
|
{
|
541
593
|
return RGEO_FACTORY_DATA_PTR(self)->wkrep_wkt_generator;
|
542
594
|
}
|
543
595
|
|
544
|
-
|
545
|
-
|
596
|
+
static VALUE
|
597
|
+
method_get_wkb_generator(VALUE self)
|
546
598
|
{
|
547
599
|
return RGEO_FACTORY_DATA_PTR(self)->wkrep_wkb_generator;
|
548
600
|
}
|
549
601
|
|
550
|
-
|
551
|
-
|
602
|
+
static VALUE
|
603
|
+
method_get_wkt_parser(VALUE self)
|
552
604
|
{
|
553
605
|
return RGEO_FACTORY_DATA_PTR(self)->wkrep_wkt_parser;
|
554
606
|
}
|
555
607
|
|
556
|
-
|
557
|
-
|
608
|
+
static VALUE
|
609
|
+
method_get_wkb_parser(VALUE self)
|
558
610
|
{
|
559
611
|
return RGEO_FACTORY_DATA_PTR(self)->wkrep_wkb_parser;
|
560
612
|
}
|
561
613
|
|
562
|
-
|
563
|
-
|
614
|
+
static VALUE
|
615
|
+
alloc_geometry(VALUE klass)
|
564
616
|
{
|
565
617
|
return rgeo_wrap_geos_geometry(Qnil, NULL, klass);
|
566
618
|
}
|
567
619
|
|
568
|
-
|
569
620
|
/**** INITIALIZATION FUNCTION ****/
|
570
621
|
|
571
|
-
|
572
|
-
|
622
|
+
void
|
623
|
+
rgeo_init_geos_factory()
|
573
624
|
{
|
574
|
-
RGeo_Globals* globals;
|
575
|
-
VALUE rgeo_module;
|
576
625
|
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"));
|
626
|
+
|
607
627
|
#ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
|
608
|
-
|
609
|
-
|
628
|
+
/* We favor rb_gc_register_address over rb_gc_register_mark_object because
|
629
|
+
* the value changes at runtime */
|
630
|
+
psych_wkt_generator = Qnil;
|
631
|
+
rb_gc_register_address(&psych_wkt_generator);
|
632
|
+
marshal_wkb_generator = Qnil;
|
633
|
+
rb_gc_register_address(&marshal_wkb_generator);
|
610
634
|
#endif
|
611
635
|
|
612
|
-
|
613
|
-
|
636
|
+
geos_factory_class =
|
637
|
+
rb_define_class_under(rgeo_geos_module, "CAPIFactory", rb_cObject);
|
614
638
|
rb_define_alloc_func(geos_factory_class, alloc_factory);
|
615
|
-
|
616
|
-
|
617
|
-
|
639
|
+
// Add C constants to the factory.
|
640
|
+
rb_define_const(geos_factory_class,
|
641
|
+
"FLAG_SUPPORTS_Z",
|
642
|
+
INT2FIX(RGEO_FACTORYFLAGS_SUPPORTS_Z));
|
643
|
+
rb_define_const(geos_factory_class,
|
644
|
+
"FLAG_SUPPORTS_M",
|
645
|
+
INT2FIX(RGEO_FACTORYFLAGS_SUPPORTS_M));
|
646
|
+
rb_define_const(geos_factory_class,
|
647
|
+
"FLAG_SUPPORTS_Z_OR_M",
|
648
|
+
INT2FIX(RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M));
|
649
|
+
rb_define_const(geos_factory_class,
|
650
|
+
"FLAG_PREPARE_HEURISTIC",
|
651
|
+
INT2FIX(RGEO_FACTORYFLAGS_PREPARE_HEURISTIC));
|
652
|
+
// Add C methods to the factory.
|
653
|
+
rb_define_method(
|
654
|
+
geos_factory_class, "initialize_copy", method_factory_initialize_copy, 1);
|
655
|
+
rb_define_method(
|
656
|
+
geos_factory_class, "_parse_wkt_impl", method_factory_parse_wkt, 1);
|
657
|
+
rb_define_method(
|
658
|
+
geos_factory_class, "_parse_wkb_impl", method_factory_parse_wkb, 1);
|
618
659
|
rb_define_method(geos_factory_class, "_srid", method_factory_srid, 0);
|
619
|
-
rb_define_method(geos_factory_class,
|
660
|
+
rb_define_method(geos_factory_class,
|
661
|
+
"_buffer_resolution",
|
662
|
+
method_factory_buffer_resolution,
|
663
|
+
0);
|
620
664
|
rb_define_method(geos_factory_class, "_flags", method_factory_flags, 0);
|
621
|
-
rb_define_method(
|
622
|
-
|
665
|
+
rb_define_method(
|
666
|
+
geos_factory_class, "supports_z?", method_factory_supports_z_p, 0);
|
667
|
+
rb_define_method(
|
668
|
+
geos_factory_class, "supports_m?", method_factory_supports_m_p, 0);
|
669
|
+
rb_define_method(geos_factory_class,
|
670
|
+
"supports_z_or_m?",
|
671
|
+
method_factory_supports_z_or_m_p,
|
672
|
+
0);
|
673
|
+
rb_define_method(geos_factory_class,
|
674
|
+
"prepare_heuristic?",
|
675
|
+
method_factory_prepare_heuristic_p,
|
676
|
+
0);
|
677
|
+
rb_define_method(
|
678
|
+
geos_factory_class, "_set_wkrep_parsers", method_set_wkrep_parsers, 2);
|
623
679
|
rb_define_method(geos_factory_class, "_coord_sys", method_get_coord_sys, 0);
|
624
|
-
rb_define_method(
|
625
|
-
|
680
|
+
rb_define_method(
|
681
|
+
geos_factory_class, "_wkt_generator", method_get_wkt_generator, 0);
|
682
|
+
rb_define_method(
|
683
|
+
geos_factory_class, "_wkb_generator", method_get_wkb_generator, 0);
|
626
684
|
rb_define_method(geos_factory_class, "_wkt_parser", method_get_wkt_parser, 0);
|
627
685
|
rb_define_method(geos_factory_class, "_wkb_parser", method_get_wkb_parser, 0);
|
628
|
-
rb_define_method(
|
629
|
-
|
630
|
-
rb_define_method(geos_factory_class,
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
rb_define_alloc_func(
|
649
|
-
|
650
|
-
rb_define_alloc_func(
|
651
|
-
|
652
|
-
rb_define_alloc_func(
|
653
|
-
|
654
|
-
rb_define_alloc_func(
|
655
|
-
|
656
|
-
rb_define_alloc_func(
|
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;
|
686
|
+
rb_define_method(
|
687
|
+
geos_factory_class, "read_for_marshal", method_factory_read_for_marshal, 1);
|
688
|
+
rb_define_method(geos_factory_class,
|
689
|
+
"write_for_marshal",
|
690
|
+
method_factory_write_for_marshal,
|
691
|
+
1);
|
692
|
+
rb_define_method(
|
693
|
+
geos_factory_class, "read_for_psych", method_factory_read_for_psych, 1);
|
694
|
+
rb_define_method(
|
695
|
+
geos_factory_class, "write_for_psych", method_factory_write_for_psych, 1);
|
696
|
+
rb_define_module_function(
|
697
|
+
geos_factory_class, "_create", cmethod_factory_create, 6);
|
698
|
+
rb_define_module_function(
|
699
|
+
geos_factory_class, "_geos_version", cmethod_factory_geos_version, 0);
|
700
|
+
rb_define_module_function(geos_factory_class,
|
701
|
+
"_supports_unary_union?",
|
702
|
+
cmethod_factory_supports_unary_union,
|
703
|
+
0);
|
704
|
+
|
705
|
+
// Define allocation methods for global class types
|
706
|
+
rb_define_alloc_func(rgeo_geos_geometry_class, alloc_geometry);
|
707
|
+
rb_define_alloc_func(rgeo_geos_point_class, alloc_geometry);
|
708
|
+
rb_define_alloc_func(rgeo_geos_line_string_class, alloc_geometry);
|
709
|
+
rb_define_alloc_func(rgeo_geos_linear_ring_class, alloc_geometry);
|
710
|
+
rb_define_alloc_func(rgeo_geos_line_class, alloc_geometry);
|
711
|
+
rb_define_alloc_func(rgeo_geos_polygon_class, alloc_geometry);
|
712
|
+
rb_define_alloc_func(rgeo_geos_geometry_collection_class, alloc_geometry);
|
713
|
+
rb_define_alloc_func(rgeo_geos_multi_point_class, alloc_geometry);
|
714
|
+
rb_define_alloc_func(rgeo_geos_multi_line_string_class, alloc_geometry);
|
715
|
+
rb_define_alloc_func(rgeo_geos_multi_polygon_class, alloc_geometry);
|
664
716
|
}
|
665
717
|
|
666
|
-
|
667
718
|
/**** OTHER PUBLIC FUNCTIONS ****/
|
668
719
|
|
669
|
-
|
670
|
-
|
720
|
+
VALUE
|
721
|
+
rgeo_wrap_geos_geometry(VALUE factory, GEOSGeometry* geom, VALUE klass)
|
671
722
|
{
|
672
723
|
VALUE result;
|
673
724
|
RGeo_FactoryData* factory_data;
|
674
|
-
GEOSContextHandle_t factory_context;
|
675
725
|
VALUE klasses;
|
676
|
-
RGeo_Globals* globals;
|
677
726
|
VALUE inferred_klass;
|
678
727
|
char is_collection;
|
679
728
|
RGeo_GeometryData* data;
|
@@ -681,16 +730,15 @@ VALUE rgeo_wrap_geos_geometry(VALUE factory, GEOSGeometry* geom, VALUE klass)
|
|
681
730
|
result = Qnil;
|
682
731
|
if (geom || !NIL_P(klass)) {
|
683
732
|
factory_data = NIL_P(factory) ? NULL : RGEO_FACTORY_DATA_PTR(factory);
|
684
|
-
factory_context = factory_data ? factory_data->geos_context : NULL;
|
685
|
-
globals = factory_data ? factory_data->globals : NULL;
|
686
733
|
|
687
734
|
// We don't allow "empty" points, so replace such objects with
|
688
735
|
// an empty collection.
|
689
736
|
if (geom && factory) {
|
690
|
-
if (
|
691
|
-
|
692
|
-
geom
|
693
|
-
|
737
|
+
if (GEOSGeomTypeId(geom) == GEOS_POINT &&
|
738
|
+
GEOSGetNumCoordinates(geom) == 0) {
|
739
|
+
GEOSGeom_destroy(geom);
|
740
|
+
geom = GEOSGeom_createCollection(GEOS_GEOMETRYCOLLECTION, NULL, 0);
|
741
|
+
klass = rgeo_geos_geometry_collection_class;
|
694
742
|
}
|
695
743
|
}
|
696
744
|
|
@@ -698,38 +746,38 @@ VALUE rgeo_wrap_geos_geometry(VALUE factory, GEOSGeometry* geom, VALUE klass)
|
|
698
746
|
if (TYPE(klass) != T_CLASS) {
|
699
747
|
inferred_klass = Qnil;
|
700
748
|
is_collection = 0;
|
701
|
-
switch (
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
749
|
+
switch (GEOSGeomTypeId(geom)) {
|
750
|
+
case GEOS_POINT:
|
751
|
+
inferred_klass = rgeo_geos_point_class;
|
752
|
+
break;
|
753
|
+
case GEOS_LINESTRING:
|
754
|
+
inferred_klass = rgeo_geos_line_string_class;
|
755
|
+
break;
|
756
|
+
case GEOS_LINEARRING:
|
757
|
+
inferred_klass = rgeo_geos_linear_ring_class;
|
758
|
+
break;
|
759
|
+
case GEOS_POLYGON:
|
760
|
+
inferred_klass = rgeo_geos_polygon_class;
|
761
|
+
break;
|
762
|
+
case GEOS_MULTIPOINT:
|
763
|
+
inferred_klass = rgeo_geos_multi_point_class;
|
764
|
+
is_collection = 1;
|
765
|
+
break;
|
766
|
+
case GEOS_MULTILINESTRING:
|
767
|
+
inferred_klass = rgeo_geos_multi_line_string_class;
|
768
|
+
is_collection = 1;
|
769
|
+
break;
|
770
|
+
case GEOS_MULTIPOLYGON:
|
771
|
+
inferred_klass = rgeo_geos_multi_polygon_class;
|
772
|
+
is_collection = 1;
|
773
|
+
break;
|
774
|
+
case GEOS_GEOMETRYCOLLECTION:
|
775
|
+
inferred_klass = rgeo_geos_geometry_collection_class;
|
776
|
+
is_collection = 1;
|
777
|
+
break;
|
778
|
+
default:
|
779
|
+
inferred_klass = rgeo_geos_geometry_class;
|
780
|
+
break;
|
733
781
|
}
|
734
782
|
if (TYPE(klass) == T_ARRAY && is_collection) {
|
735
783
|
klasses = klass;
|
@@ -739,29 +787,33 @@ VALUE rgeo_wrap_geos_geometry(VALUE factory, GEOSGeometry* geom, VALUE klass)
|
|
739
787
|
data = ALLOC(RGeo_GeometryData);
|
740
788
|
if (data) {
|
741
789
|
if (geom) {
|
742
|
-
|
790
|
+
GEOSSetSRID(geom, factory_data->srid);
|
743
791
|
}
|
744
|
-
data->geos_context = factory_context;
|
745
792
|
data->geom = geom;
|
746
|
-
data->prep =
|
747
|
-
|
793
|
+
data->prep =
|
794
|
+
factory_data &&
|
795
|
+
((factory_data->flags & RGEO_FACTORYFLAGS_PREPARE_HEURISTIC) != 0)
|
796
|
+
? (GEOSPreparedGeometry*)1
|
797
|
+
: NULL;
|
748
798
|
data->factory = factory;
|
749
799
|
data->klasses = klasses;
|
750
|
-
result =
|
800
|
+
result = TypedData_Wrap_Struct(klass, &rgeo_geometry_type, data);
|
751
801
|
}
|
752
802
|
}
|
753
803
|
return result;
|
754
804
|
}
|
755
805
|
|
756
|
-
|
757
|
-
|
806
|
+
VALUE
|
807
|
+
rgeo_wrap_geos_geometry_clone(VALUE factory,
|
808
|
+
const GEOSGeometry* geom,
|
809
|
+
VALUE klass)
|
758
810
|
{
|
759
811
|
VALUE result;
|
760
812
|
GEOSGeometry* clone_geom;
|
761
813
|
|
762
814
|
result = Qnil;
|
763
815
|
if (geom) {
|
764
|
-
clone_geom =
|
816
|
+
clone_geom = GEOSGeom_clone(geom);
|
765
817
|
if (clone_geom) {
|
766
818
|
result = rgeo_wrap_geos_geometry(factory, clone_geom, klass);
|
767
819
|
}
|
@@ -769,84 +821,136 @@ VALUE rgeo_wrap_geos_geometry_clone(VALUE factory, const GEOSGeometry* geom, VAL
|
|
769
821
|
return result;
|
770
822
|
}
|
771
823
|
|
772
|
-
|
773
|
-
|
824
|
+
const GEOSGeometry*
|
825
|
+
rgeo_convert_to_geos_geometry(VALUE factory, VALUE obj, VALUE type, int* state)
|
774
826
|
{
|
775
827
|
VALUE object;
|
776
|
-
RGeo_Globals* globals;
|
777
828
|
|
778
|
-
if (NIL_P(type) &&
|
829
|
+
if (NIL_P(type) && RGEO_GEOMETRY_TYPEDDATA_P(obj) &&
|
830
|
+
RGEO_GEOMETRY_DATA_PTR(obj)->factory == factory) {
|
779
831
|
object = obj;
|
832
|
+
} else {
|
833
|
+
object =
|
834
|
+
rb_funcall(rgeo_feature_module, rb_intern("cast"), 3, obj, factory, type);
|
780
835
|
}
|
781
|
-
|
782
|
-
|
783
|
-
|
836
|
+
if (NIL_P(object)) {
|
837
|
+
rb_protect(
|
838
|
+
rb_exc_raise_value,
|
839
|
+
rb_exc_new_cstr(rb_eRGeoInvalidGeometry,
|
840
|
+
"Unable to cast the geometry to the GEOS Factory"),
|
841
|
+
state);
|
784
842
|
}
|
785
|
-
|
843
|
+
|
844
|
+
if (*state) {
|
786
845
|
return NULL;
|
846
|
+
}
|
847
|
+
|
848
|
+
if (!rgeo_is_geos_object(object)) {
|
849
|
+
rb_protect(rb_exc_raise_value,
|
850
|
+
rb_exc_new_cstr(rb_eRGeoError, "Not a GEOS Geometry object."),
|
851
|
+
state);
|
852
|
+
}
|
853
|
+
|
854
|
+
if (*state) {
|
855
|
+
return NULL;
|
856
|
+
}
|
787
857
|
|
788
|
-
Check_Type(object, T_DATA);
|
789
858
|
return RGEO_GEOMETRY_DATA_PTR(object)->geom;
|
790
859
|
}
|
791
860
|
|
792
|
-
|
793
|
-
|
861
|
+
GEOSGeometry*
|
862
|
+
rgeo_convert_to_detached_geos_geometry(VALUE obj,
|
863
|
+
VALUE factory,
|
864
|
+
VALUE type,
|
865
|
+
VALUE* klasses,
|
866
|
+
int* state)
|
794
867
|
{
|
795
868
|
VALUE object;
|
796
869
|
GEOSGeometry* geom;
|
797
870
|
RGeo_GeometryData* object_data;
|
798
871
|
const GEOSPreparedGeometry* prep;
|
799
|
-
RGeo_Globals* globals;
|
800
872
|
|
801
873
|
if (klasses) {
|
802
874
|
*klasses = Qnil;
|
803
875
|
}
|
804
|
-
|
805
|
-
object =
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
876
|
+
|
877
|
+
object = rb_protect_funcall(rgeo_feature_module,
|
878
|
+
rb_intern("cast"),
|
879
|
+
state,
|
880
|
+
5,
|
881
|
+
obj,
|
882
|
+
factory,
|
883
|
+
type,
|
884
|
+
ID2SYM(rb_intern("force_new")),
|
885
|
+
ID2SYM(rb_intern("keep_subtype")));
|
886
|
+
|
887
|
+
if (NIL_P(object)) {
|
888
|
+
rb_protect(
|
889
|
+
rb_exc_raise_value,
|
890
|
+
rb_exc_new_cstr(rb_eRGeoInvalidGeometry,
|
891
|
+
"Unable to cast the geometry to the GEOS Factory"),
|
892
|
+
state);
|
893
|
+
}
|
894
|
+
if (*state) {
|
895
|
+
return NULL;
|
896
|
+
}
|
897
|
+
|
898
|
+
if (!rgeo_is_geos_object(object)) {
|
899
|
+
rb_protect(rb_exc_raise_value,
|
900
|
+
rb_exc_new_cstr(rb_eRGeoError, "Not a GEOS Geometry object."),
|
901
|
+
state);
|
902
|
+
}
|
903
|
+
if (*state) {
|
904
|
+
return NULL;
|
905
|
+
}
|
906
|
+
|
907
|
+
object_data = RGEO_GEOMETRY_DATA_PTR(object);
|
908
|
+
geom = object_data->geom;
|
909
|
+
if (klasses) {
|
910
|
+
*klasses = object_data->klasses;
|
911
|
+
if (NIL_P(*klasses)) {
|
912
|
+
*klasses = CLASS_OF(object);
|
819
913
|
}
|
820
|
-
object_data->geos_context = NULL;
|
821
|
-
object_data->geom = NULL;
|
822
|
-
object_data->prep = NULL;
|
823
|
-
object_data->factory = Qnil;
|
824
|
-
object_data->klasses = Qnil;
|
825
914
|
}
|
915
|
+
prep = object_data->prep;
|
916
|
+
if (prep && prep != (GEOSPreparedGeometry*)1 &&
|
917
|
+
prep != (GEOSPreparedGeometry*)2) {
|
918
|
+
GEOSPreparedGeom_destroy(prep);
|
919
|
+
}
|
920
|
+
object_data->geom = NULL;
|
921
|
+
object_data->prep = NULL;
|
922
|
+
object_data->factory = Qnil;
|
923
|
+
object_data->klasses = Qnil;
|
924
|
+
|
826
925
|
return geom;
|
827
926
|
}
|
828
927
|
|
829
|
-
|
830
|
-
|
928
|
+
char
|
929
|
+
rgeo_is_geos_object(VALUE obj)
|
831
930
|
{
|
832
|
-
return (
|
931
|
+
return RGEO_GEOMETRY_TYPEDDATA_P(obj) ? 1 : 0;
|
833
932
|
}
|
834
933
|
|
835
|
-
void
|
934
|
+
void
|
935
|
+
rgeo_check_geos_object(VALUE obj)
|
836
936
|
{
|
837
937
|
if (!rgeo_is_geos_object(obj)) {
|
838
|
-
rb_raise(
|
938
|
+
rb_raise(rb_eRGeoError, "Not a GEOS Geometry object.");
|
839
939
|
}
|
840
940
|
}
|
841
941
|
|
842
|
-
|
843
|
-
|
942
|
+
const GEOSGeometry*
|
943
|
+
rgeo_get_geos_geometry_safe(VALUE obj)
|
844
944
|
{
|
845
|
-
return (
|
945
|
+
return RGEO_GEOMETRY_TYPEDDATA_P(obj)
|
946
|
+
? (const GEOSGeometry*)(RGEO_GEOMETRY_DATA_PTR(obj)->geom)
|
947
|
+
: NULL;
|
846
948
|
}
|
847
949
|
|
848
|
-
|
849
|
-
|
950
|
+
VALUE
|
951
|
+
rgeo_geos_coordseqs_eql(const GEOSGeometry* geom1,
|
952
|
+
const GEOSGeometry* geom2,
|
953
|
+
char check_z)
|
850
954
|
{
|
851
955
|
VALUE result;
|
852
956
|
const GEOSCoordSequence* cs1;
|
@@ -858,27 +962,30 @@ VALUE rgeo_geos_coordseqs_eql(GEOSContextHandle_t context, const GEOSGeometry* g
|
|
858
962
|
|
859
963
|
result = Qnil;
|
860
964
|
if (geom1 && geom2) {
|
861
|
-
cs1 =
|
862
|
-
cs2 =
|
965
|
+
cs1 = GEOSGeom_getCoordSeq(geom1);
|
966
|
+
cs2 = GEOSGeom_getCoordSeq(geom2);
|
863
967
|
if (cs1 && cs2) {
|
864
968
|
len1 = 0;
|
865
969
|
len2 = 0;
|
866
|
-
if (
|
970
|
+
if (GEOSCoordSeq_getSize(cs1, &len1) &&
|
971
|
+
GEOSCoordSeq_getSize(cs2, &len2)) {
|
867
972
|
if (len1 == len2) {
|
868
973
|
result = Qtrue;
|
869
|
-
for (i=0; i<len1; ++i) {
|
870
|
-
if (
|
974
|
+
for (i = 0; i < len1; ++i) {
|
975
|
+
if (GEOSCoordSeq_getX(cs1, i, &val1) &&
|
976
|
+
GEOSCoordSeq_getX(cs2, i, &val2)) {
|
871
977
|
if (val1 == val2) {
|
872
|
-
if (
|
978
|
+
if (GEOSCoordSeq_getY(cs1, i, &val1) &&
|
979
|
+
GEOSCoordSeq_getY(cs2, i, &val2)) {
|
873
980
|
if (val1 == val2) {
|
874
981
|
if (check_z) {
|
875
982
|
val1 = 0;
|
876
|
-
if (!
|
983
|
+
if (!GEOSCoordSeq_getZ(cs1, i, &val1)) {
|
877
984
|
result = Qnil;
|
878
985
|
break;
|
879
986
|
}
|
880
987
|
val2 = 0;
|
881
|
-
if (!
|
988
|
+
if (!GEOSCoordSeq_getZ(cs2, i, &val2)) {
|
882
989
|
result = Qnil;
|
883
990
|
break;
|
884
991
|
}
|
@@ -887,29 +994,24 @@ VALUE rgeo_geos_coordseqs_eql(GEOSContextHandle_t context, const GEOSGeometry* g
|
|
887
994
|
break;
|
888
995
|
}
|
889
996
|
}
|
890
|
-
}
|
891
|
-
else { // Y coords are different
|
997
|
+
} else { // Y coords are different
|
892
998
|
result = Qfalse;
|
893
999
|
break;
|
894
1000
|
}
|
895
|
-
}
|
896
|
-
else { // Failed to get Y coords
|
1001
|
+
} else { // Failed to get Y coords
|
897
1002
|
result = Qnil;
|
898
1003
|
break;
|
899
1004
|
}
|
900
|
-
}
|
901
|
-
else { // X coords are different
|
1005
|
+
} else { // X coords are different
|
902
1006
|
result = Qfalse;
|
903
1007
|
break;
|
904
1008
|
}
|
905
|
-
}
|
906
|
-
else { // Failed to get X coords
|
1009
|
+
} else { // Failed to get X coords
|
907
1010
|
result = Qnil;
|
908
1011
|
break;
|
909
1012
|
}
|
910
|
-
}
|
911
|
-
}
|
912
|
-
else { // Lengths are different
|
1013
|
+
} // Iteration over coords
|
1014
|
+
} else { // Lengths are different
|
913
1015
|
result = Qfalse;
|
914
1016
|
}
|
915
1017
|
}
|
@@ -918,8 +1020,8 @@ VALUE rgeo_geos_coordseqs_eql(GEOSContextHandle_t context, const GEOSGeometry* g
|
|
918
1020
|
return result;
|
919
1021
|
}
|
920
1022
|
|
921
|
-
|
922
|
-
|
1023
|
+
VALUE
|
1024
|
+
rgeo_geos_klasses_and_factories_eql(VALUE obj1, VALUE obj2)
|
923
1025
|
{
|
924
1026
|
VALUE result;
|
925
1027
|
VALUE factory;
|
@@ -927,23 +1029,25 @@ VALUE rgeo_geos_klasses_and_factories_eql(VALUE obj1, VALUE obj2)
|
|
927
1029
|
result = Qnil;
|
928
1030
|
if (rb_obj_class(obj1) != rb_obj_class(obj2)) {
|
929
1031
|
result = Qfalse;
|
930
|
-
}
|
931
|
-
else {
|
1032
|
+
} else {
|
932
1033
|
factory = RGEO_GEOMETRY_DATA_PTR(obj1)->factory;
|
933
|
-
|
1034
|
+
/* No need to cache the internal here (https://ips.fastruby.io/4x) */
|
1035
|
+
result = rb_funcall(
|
1036
|
+
factory, rb_intern("eql?"), 1, RGEO_GEOMETRY_DATA_PTR(obj2)->factory);
|
934
1037
|
}
|
935
1038
|
return result;
|
936
1039
|
}
|
937
1040
|
|
938
|
-
|
939
|
-
|
1041
|
+
typedef struct
|
1042
|
+
{
|
940
1043
|
st_index_t seed_hash;
|
941
1044
|
double x;
|
942
1045
|
double y;
|
943
1046
|
double z;
|
944
1047
|
} RGeo_Coordseq_Hash_Struct;
|
945
1048
|
|
946
|
-
st_index_t
|
1049
|
+
st_index_t
|
1050
|
+
rgeo_geos_coordseq_hash(const GEOSGeometry* geom, st_index_t hash)
|
947
1051
|
{
|
948
1052
|
const GEOSCoordSequence* cs;
|
949
1053
|
unsigned int len;
|
@@ -951,17 +1055,18 @@ st_index_t rgeo_geos_coordseq_hash(GEOSContextHandle_t context, const GEOSGeomet
|
|
951
1055
|
RGeo_Coordseq_Hash_Struct hash_struct;
|
952
1056
|
|
953
1057
|
if (geom) {
|
954
|
-
cs =
|
1058
|
+
cs = GEOSGeom_getCoordSeq(geom);
|
955
1059
|
if (cs) {
|
956
|
-
if (
|
957
|
-
for (i=0; i<len; ++i) {
|
958
|
-
if (
|
959
|
-
if (
|
960
|
-
if (!
|
1060
|
+
if (GEOSCoordSeq_getSize(cs, &len)) {
|
1061
|
+
for (i = 0; i < len; ++i) {
|
1062
|
+
if (GEOSCoordSeq_getX(cs, i, &hash_struct.x)) {
|
1063
|
+
if (GEOSCoordSeq_getY(cs, i, &hash_struct.y)) {
|
1064
|
+
if (!GEOSCoordSeq_getZ(cs, i, &hash_struct.z)) {
|
961
1065
|
hash_struct.z = 0;
|
962
1066
|
}
|
963
1067
|
hash_struct.seed_hash = hash;
|
964
|
-
hash =
|
1068
|
+
hash =
|
1069
|
+
rb_memhash(&hash_struct, sizeof(RGeo_Coordseq_Hash_Struct));
|
965
1070
|
}
|
966
1071
|
}
|
967
1072
|
}
|
@@ -971,42 +1076,26 @@ st_index_t rgeo_geos_coordseq_hash(GEOSContextHandle_t context, const GEOSGeomet
|
|
971
1076
|
return hash;
|
972
1077
|
}
|
973
1078
|
|
974
|
-
|
975
|
-
|
1079
|
+
typedef struct
|
1080
|
+
{
|
976
1081
|
st_index_t seed_hash;
|
977
1082
|
st_index_t h1;
|
978
1083
|
st_index_t h2;
|
979
1084
|
} RGeo_Objbase_Hash_Struct;
|
980
1085
|
|
981
|
-
st_index_t
|
1086
|
+
st_index_t
|
1087
|
+
rgeo_geos_objbase_hash(VALUE factory, VALUE type_module, st_index_t hash)
|
982
1088
|
{
|
983
1089
|
ID hash_method;
|
984
1090
|
RGeo_Objbase_Hash_Struct hash_struct;
|
985
1091
|
|
986
|
-
hash_method =
|
1092
|
+
hash_method = rb_intern("hash");
|
987
1093
|
hash_struct.seed_hash = hash;
|
988
1094
|
hash_struct.h1 = FIX2LONG(rb_funcall(factory, hash_method, 0));
|
989
1095
|
hash_struct.h2 = FIX2LONG(rb_funcall(type_module, hash_method, 0));
|
990
1096
|
return rb_memhash(&hash_struct, sizeof(RGeo_Objbase_Hash_Struct));
|
991
1097
|
}
|
992
1098
|
|
993
|
-
|
994
|
-
st_index_t rgeo_internal_memhash(const void* ptr, long len)
|
995
|
-
{
|
996
|
-
const char* bytes;
|
997
|
-
st_index_t hval;
|
998
|
-
long i;
|
999
|
-
|
1000
|
-
bytes = (const char*)ptr;
|
1001
|
-
hval = 0x811c9dc5;
|
1002
|
-
for (i=0; i<len; ++i) {
|
1003
|
-
hval ^= (unsigned int)(*bytes++);
|
1004
|
-
hval *= 0x01000193;
|
1005
|
-
}
|
1006
|
-
return hval;
|
1007
|
-
}
|
1008
|
-
|
1009
|
-
|
1010
1099
|
RGEO_END_C
|
1011
1100
|
|
1012
1101
|
#endif
|