rgeo 0.1.12 → 0.1.13
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.
- data/History.rdoc +9 -7
- data/README.rdoc +7 -5
- data/Version +1 -1
- data/ext/geos_c_impl/factory.c +12 -19
- data/ext/geos_c_impl/factory.h +15 -21
- data/ext/geos_c_impl/geometry.c +19 -36
- data/ext/geos_c_impl/geometry.h +2 -12
- data/ext/geos_c_impl/geometry_collection.c +38 -157
- data/ext/geos_c_impl/geometry_collection.h +2 -12
- data/ext/geos_c_impl/line_string.c +83 -80
- data/ext/geos_c_impl/line_string.h +2 -12
- data/ext/geos_c_impl/main.c +5 -0
- data/ext/geos_c_impl/point.c +2 -12
- data/ext/geos_c_impl/point.h +2 -12
- data/ext/geos_c_impl/polygon.c +5 -14
- data/ext/geos_c_impl/polygon.h +2 -12
- data/ext/geos_c_impl/preface.h +8 -0
- data/lib/rgeo.rb +34 -16
- data/lib/rgeo/{geography/simple_spherical/geometry_collection_impl.rb → cartesian.rb} +19 -26
- data/lib/rgeo/cartesian/calculations.rb +129 -0
- data/lib/rgeo/cartesian/interface.rb +85 -0
- data/lib/rgeo/cartesian/simple_factory.rb +159 -0
- data/lib/rgeo/cartesian/simple_feature_classes.rb +187 -0
- data/lib/rgeo/cartesian/simple_feature_methods.rb +97 -0
- data/lib/rgeo/features.rb +1 -0
- data/lib/rgeo/features/curve.rb +3 -2
- data/lib/rgeo/features/factory.rb +62 -37
- data/lib/rgeo/features/geometry.rb +10 -32
- data/lib/rgeo/features/geometry_collection.rb +3 -2
- data/lib/rgeo/features/line.rb +3 -2
- data/lib/rgeo/features/line_string.rb +3 -2
- data/lib/rgeo/features/linear_ring.rb +3 -2
- data/lib/rgeo/features/multi_curve.rb +3 -2
- data/lib/rgeo/features/multi_line_string.rb +3 -2
- data/lib/rgeo/features/multi_point.rb +3 -2
- data/lib/rgeo/features/multi_polygon.rb +3 -2
- data/lib/rgeo/features/multi_surface.rb +3 -2
- data/lib/rgeo/features/point.rb +3 -2
- data/lib/rgeo/features/polygon.rb +3 -2
- data/lib/rgeo/features/surface.rb +3 -2
- data/lib/rgeo/features/types.rb +198 -0
- data/lib/rgeo/geography.rb +4 -14
- data/lib/rgeo/geography/factory.rb +7 -64
- data/lib/rgeo/geography/{simple_spherical/geometry_methods.rb → helper.rb} +4 -13
- data/lib/rgeo/geography/simple_mercator/feature_classes.rb +35 -89
- data/lib/rgeo/geography/simple_mercator/feature_methods.rb +22 -31
- data/lib/rgeo/geography/simple_mercator/projector.rb +4 -8
- data/lib/rgeo/geography/simple_spherical/calculations.rb +11 -9
- data/lib/rgeo/geography/simple_spherical/feature_classes.rb +189 -0
- data/lib/rgeo/geography/simple_spherical/{line_string_impl.rb → feature_methods.rb} +16 -64
- data/lib/rgeo/geos/factory.rb +26 -40
- data/lib/rgeo/geos/impl_additions.rb +3 -5
- data/lib/rgeo/{geography/simple_spherical/polygon_impl.rb → impl_helpers.rb} +16 -26
- data/lib/rgeo/impl_helpers/basic_geometry_collection_methods.rb +186 -0
- data/lib/rgeo/impl_helpers/basic_geometry_methods.rb +90 -0
- data/lib/rgeo/impl_helpers/basic_line_string_methods.rb +188 -0
- data/lib/rgeo/impl_helpers/basic_point_methods.rb +149 -0
- data/lib/rgeo/{geography/common/helper.rb → impl_helpers/basic_polygon_methods.rb} +62 -53
- data/lib/rgeo/{geography/common/polygon_methods.rb → impl_helpers/serialization.rb} +50 -42
- data/tests/common/geometry_collection_tests.rb +9 -7
- data/tests/common/multi_line_string_tests.rb +16 -13
- data/tests/common/multi_point_tests.rb +16 -13
- data/tests/common/multi_polygon_tests.rb +8 -6
- data/tests/common/point_tests.rb +1 -2
- data/tests/common/polygon_tests.rb +9 -9
- data/tests/geos/tc_multi_line_string.rb +2 -2
- data/tests/simple_cartesian/tc_calculations.rb +138 -0
- data/tests/simple_cartesian/tc_geometry_collection.rb +68 -0
- data/tests/simple_cartesian/tc_line_string.rb +70 -0
- data/{lib/rgeo/geography/simple_spherical/multi_line_string_impl.rb → tests/simple_cartesian/tc_multi_line_string.rb} +19 -19
- data/{lib/rgeo/geography/simple_spherical/multi_polygon_impl.rb → tests/simple_cartesian/tc_multi_point.rb} +19 -19
- data/{lib/rgeo/geography/common/geometry_methods.rb → tests/simple_cartesian/tc_multi_polygon.rb} +19 -41
- data/{lib/rgeo/geography/simple_spherical/point_impl.rb → tests/simple_cartesian/tc_point.rb} +33 -35
- data/tests/simple_cartesian/tc_polygon.rb +67 -0
- data/tests/simple_spherical/tc_geometry_collection.rb +68 -0
- data/tests/simple_spherical/tc_line_string.rb +10 -171
- data/tests/simple_spherical/tc_multi_line_string.rb +67 -0
- data/{lib/rgeo/geography/simple_spherical/multi_point_impl.rb → tests/simple_spherical/tc_multi_point.rb} +19 -19
- data/tests/simple_spherical/tc_multi_polygon.rb +70 -0
- data/tests/simple_spherical/tc_point.rb +17 -115
- data/tests/simple_spherical/tc_polygon.rb +67 -0
- metadata +46 -18
- data/ext/geos_c_impl/globals.h +0 -58
- data/lib/rgeo/geography/common/geometry_collection_methods.rb +0 -217
- data/lib/rgeo/geography/common/line_string_methods.rb +0 -201
- data/lib/rgeo/geography/common/point_methods.rb +0 -153
data/History.rdoc
CHANGED
@@ -1,8 +1,14 @@
|
|
1
|
-
=== 0.1.
|
1
|
+
=== 0.1.13 / 2010-10-26
|
2
2
|
|
3
|
-
|
3
|
+
* Reworked the way casting is done. Casting has two dimensions: factory casting and type casting, either or both of which can be done at once. Implemented a standard casting algorithm to handle these cases, and an override mechanism for factories that want to do some of their own casting. Removed Factory#cast and Geometry#cast, and implemented a global Features::cast entry point instead.
|
4
|
+
* All factory and relational methods now perform auto-casting on inputs.
|
5
|
+
* Removed the "auto-flattening" behavior of Factory#multi_point, Factory#multi_line_string, and Factory#multi_polygon because it seemed overkill for factory methods. These methods now just attempt to auto-cast the immediate objects.
|
6
|
+
* Filled out more test cases for SimpleSpherical.
|
7
|
+
* Provided SimpleCartesian as a fallback implementation in case Geos is not available. SimpleCartesian is like SimpleSpherical in that some operations are not provided, but it is pure ruby and doesn't depend on external libraries.
|
8
|
+
* Improved feature type checking facilities.
|
9
|
+
* Documentation updates.
|
4
10
|
|
5
|
-
|
11
|
+
=== 0.1.12 / 2010-10-23
|
6
12
|
|
7
13
|
* API CHANGE: Factory#coerce renamed to Factory#cast. I think this should be the final name for this function.
|
8
14
|
* Some new tests and a lot of fixes in SimpleMercator and SimpleSpherical.
|
@@ -12,10 +18,6 @@ Changes since 0.1.11:
|
|
12
18
|
|
13
19
|
=== 0.1.11 / 2010-10-21
|
14
20
|
|
15
|
-
Further development and fixing in the geographic coordinate systems.
|
16
|
-
|
17
|
-
Changes since 0.1.10:
|
18
|
-
|
19
21
|
* API CHANGE: Factory#convert renamed to Factory#coerce.
|
20
22
|
* Some implementations that inherit from RGeo::Features::Geometry (e.g. the Geography implementations) raised Unimplemented from operator implementations because they had aliased the wrong methods. Fixed.
|
21
23
|
* Geos coercer didn't properly coerce "contained" elements in a compound geometry. Fixed.
|
data/README.rdoc
CHANGED
@@ -42,7 +42,9 @@ Use RGeo to:
|
|
42
42
|
RGeo has the following prerequisites:
|
43
43
|
|
44
44
|
* Ruby 1.8.7 or later. Ruby 1.9.2 or later preferred.
|
45
|
-
|
45
|
+
Rubinius and JRuby are not yet supported.
|
46
|
+
* GEOS 3.2 or later highly recommended. Some functions will not be
|
47
|
+
available without it. This C/C++ library may be available via your
|
46
48
|
operating system's package manager, or you can download it from
|
47
49
|
http://trac.osgeo.org/geos/
|
48
50
|
|
@@ -71,12 +73,12 @@ For example:
|
|
71
73
|
RGeo is currently under development and several planned features are not
|
72
74
|
yet complete. These include:
|
73
75
|
|
74
|
-
*
|
75
|
-
* The spherical geometry data objects.
|
76
|
+
* Some operations on SimpleCartesian and SimpleSpherical.
|
76
77
|
* Rails (ActiveRecord or ActiveModel) integration.
|
77
78
|
* Other third-party integration, including possibly SimpleGeo.
|
78
|
-
*
|
79
|
-
*
|
79
|
+
* Support for additional formats such as ESRI shapefiles.
|
80
|
+
* JRuby support via JTS integration.
|
81
|
+
* Rubinius support for Geos integration.
|
80
82
|
|
81
83
|
Additionally, not all implemented features are well-tested yet. In
|
82
84
|
general, we currently consider this library to be "pre-alpha" quality,
|
data/Version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.13
|
data/ext/geos_c_impl/factory.c
CHANGED
@@ -49,12 +49,7 @@
|
|
49
49
|
#include "polygon.h"
|
50
50
|
#include "geometry_collection.h"
|
51
51
|
|
52
|
-
|
53
|
-
extern "C" {
|
54
|
-
#if 0
|
55
|
-
}
|
56
|
-
#endif
|
57
|
-
#endif
|
52
|
+
RGEO_BEGIN_C
|
58
53
|
|
59
54
|
|
60
55
|
/**** RUBY AND GEOS CALLBACKS ****/
|
@@ -330,9 +325,9 @@ VALUE rgeo_wrap_geos_geometry_clone(VALUE factory, const GEOSGeometry* geom, VAL
|
|
330
325
|
}
|
331
326
|
|
332
327
|
|
333
|
-
const GEOSGeometry* rgeo_convert_to_geos_geometry(VALUE factory, VALUE obj)
|
328
|
+
const GEOSGeometry* rgeo_convert_to_geos_geometry(VALUE factory, VALUE obj, VALUE type)
|
334
329
|
{
|
335
|
-
VALUE object = rb_funcall(factory, rb_intern("cast"),
|
330
|
+
VALUE object = rb_funcall(RGEO_GLOBALS_FROM_FACTORY(factory)->features_module, rb_intern("cast"), 3, obj, factory, type);
|
336
331
|
const GEOSGeometry* geom = NULL;
|
337
332
|
if (!NIL_P(object)) {
|
338
333
|
geom = RGEO_GET_GEOS_GEOMETRY(object);
|
@@ -341,21 +336,24 @@ const GEOSGeometry* rgeo_convert_to_geos_geometry(VALUE factory, VALUE obj)
|
|
341
336
|
}
|
342
337
|
|
343
338
|
|
344
|
-
GEOSGeometry* rgeo_convert_to_detached_geos_geometry(RGeo_Globals* globals, VALUE obj, VALUE* klasses)
|
339
|
+
GEOSGeometry* rgeo_convert_to_detached_geos_geometry(RGeo_Globals* globals, VALUE obj, VALUE type, VALUE* klasses)
|
345
340
|
{
|
346
341
|
if (klasses) {
|
347
342
|
*klasses = Qnil;
|
348
343
|
}
|
349
|
-
VALUE object = rb_funcall(globals->
|
344
|
+
VALUE object = rb_funcall(globals->features_module, rb_intern("cast"), 5, obj, globals->default_factory, type, ID2SYM(rb_intern("force_new")), ID2SYM(rb_intern("keep_subtype")));
|
350
345
|
GEOSGeometry* geom = NULL;
|
351
346
|
if (!NIL_P(object)) {
|
352
347
|
geom = RGEO_GEOMETRY_DATA_PTR(object)->geom;
|
348
|
+
if (klasses) {
|
349
|
+
*klasses = RGEO_KLASSES_FROM_GEOMETRY(object);
|
350
|
+
if (NIL_P(*klasses)) {
|
351
|
+
*klasses = CLASS_OF(object);
|
352
|
+
}
|
353
|
+
}
|
353
354
|
RGEO_GEOMETRY_DATA_PTR(object)->geom = NULL;
|
354
355
|
RGEO_GEOMETRY_DATA_PTR(object)->factory = Qnil;
|
355
356
|
RGEO_GEOMETRY_DATA_PTR(object)->klasses = Qnil;
|
356
|
-
if (klasses) {
|
357
|
-
*klasses = rgeo_is_geos_object(obj) ? RGEO_KLASSES_FROM_GEOMETRY(obj) : Qnil;
|
358
|
-
}
|
359
357
|
}
|
360
358
|
return geom;
|
361
359
|
}
|
@@ -458,11 +456,6 @@ VALUE rgeo_geos_klasses_and_factories_eql(VALUE obj1, VALUE obj2)
|
|
458
456
|
}
|
459
457
|
|
460
458
|
|
461
|
-
|
462
|
-
#if 0
|
463
|
-
{
|
464
|
-
#endif
|
465
|
-
}
|
466
|
-
#endif
|
459
|
+
RGEO_END_C
|
467
460
|
|
468
461
|
#endif
|
data/ext/geos_c_impl/factory.h
CHANGED
@@ -41,12 +41,7 @@
|
|
41
41
|
#include <ruby.h>
|
42
42
|
#include <geos_c.h>
|
43
43
|
|
44
|
-
|
45
|
-
extern "C" {
|
46
|
-
#if 0
|
47
|
-
}
|
48
|
-
#endif
|
49
|
-
#endif
|
44
|
+
RGEO_BEGIN_C
|
50
45
|
|
51
46
|
|
52
47
|
// Per-interpreter globals
|
@@ -158,25 +153,29 @@ VALUE rgeo_wrap_geos_geometry_clone(VALUE factory, const GEOSGeometry* geom, VAL
|
|
158
153
|
/*
|
159
154
|
Gets the GEOS geometry for a given ruby Geometry object. If the given
|
160
155
|
ruby object is not a GEOS geometry implementation, it is converted to a
|
161
|
-
GEOS implementation first.
|
156
|
+
GEOS implementation first. You may also optionally cast it to a type,
|
157
|
+
specified by an appropriate feature module. Passing Qnil for the type
|
158
|
+
disables this auto-cast. The returned GEOS geometry is owned by rgeo,
|
162
159
|
and you should not dispose it or take ownership of it yourself.
|
163
160
|
*/
|
164
|
-
const GEOSGeometry* rgeo_convert_to_geos_geometry(VALUE factory, VALUE obj);
|
161
|
+
const GEOSGeometry* rgeo_convert_to_geos_geometry(VALUE factory, VALUE obj, VALUE type);
|
165
162
|
|
166
163
|
/*
|
167
164
|
Gets a GEOS geometry for a given ruby Geometry object. If the given
|
168
165
|
ruby object is not a GEOS geometry implementation, it is converted to a
|
169
|
-
GEOS implementation first.
|
166
|
+
GEOS implementation first. You may also optionally cast it to a type,
|
167
|
+
specified by an appropriate feature module. Passing Qnil for the type
|
168
|
+
disables this auto-cast. The returned GEOS geometry is owned by the
|
170
169
|
caller-- that is, if the original ruby object is a GEOS implementation,
|
171
170
|
the returned GEOS geometry is a clone of the original.
|
172
171
|
If the klasses parameters is not NULL, its referent is set to the
|
173
|
-
klasses saved in the original ruby Geometry object (if any), or to
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
172
|
+
klasses saved in the original ruby Geometry object (if any), or else to
|
173
|
+
the class of the converted GEOS object. This is so that you can use the
|
174
|
+
result of this function to build a GEOS-backed clone of the original
|
175
|
+
geometry, or to include the given geometry in a collection while keeping
|
176
|
+
the klasses intact.
|
178
177
|
*/
|
179
|
-
GEOSGeometry* rgeo_convert_to_detached_geos_geometry(RGeo_Globals* globals, VALUE obj, VALUE* klasses);
|
178
|
+
GEOSGeometry* rgeo_convert_to_detached_geos_geometry(RGeo_Globals* globals, VALUE obj, VALUE type, VALUE* klasses);
|
180
179
|
|
181
180
|
/*
|
182
181
|
Returns 1 if the given ruby object is a GEOS Geometry implementation,
|
@@ -207,11 +206,6 @@ VALUE rgeo_geos_coordseqs_eql(GEOSContextHandle_t context, const GEOSGeometry* g
|
|
207
206
|
VALUE rgeo_geos_klasses_and_factories_eql(VALUE obj1, VALUE obj2);
|
208
207
|
|
209
208
|
|
210
|
-
|
211
|
-
#if 0
|
212
|
-
{
|
213
|
-
#endif
|
214
|
-
}
|
215
|
-
#endif
|
209
|
+
RGEO_END_C
|
216
210
|
|
217
211
|
#endif
|
data/ext/geos_c_impl/geometry.c
CHANGED
@@ -46,12 +46,7 @@
|
|
46
46
|
#include "factory.h"
|
47
47
|
#include "geometry.h"
|
48
48
|
|
49
|
-
|
50
|
-
extern "C" {
|
51
|
-
#if 0
|
52
|
-
}
|
53
|
-
#endif
|
54
|
-
#endif
|
49
|
+
RGEO_BEGIN_C
|
55
50
|
|
56
51
|
|
57
52
|
/**** INTERNAL UTILITY FUNCTIONS ****/
|
@@ -121,17 +116,10 @@ static VALUE method_geometry_factory(VALUE self)
|
|
121
116
|
}
|
122
117
|
|
123
118
|
|
124
|
-
static VALUE
|
119
|
+
static VALUE method_geometry_set_factory(VALUE self, VALUE factory)
|
125
120
|
{
|
126
|
-
|
127
|
-
|
128
|
-
if (self_geom) {
|
129
|
-
char* my_type_str = GEOSGeomType_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom);
|
130
|
-
VALUE type_name = rb_funcall(type, rb_intern("name"), 0);
|
131
|
-
result = strcmp(my_type_str, StringValuePtr(type_name)) ? Qnil : self;
|
132
|
-
free(my_type_str);
|
133
|
-
}
|
134
|
-
return result;
|
121
|
+
RGEO_GEOMETRY_DATA_PTR(self)->factory = factory;
|
122
|
+
return factory;
|
135
123
|
}
|
136
124
|
|
137
125
|
|
@@ -305,7 +293,7 @@ static VALUE method_geometry_disjoint(VALUE self, VALUE rhs)
|
|
305
293
|
VALUE result = Qnil;
|
306
294
|
const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
|
307
295
|
if (self_geom) {
|
308
|
-
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), rhs);
|
296
|
+
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), rhs, Qnil);
|
309
297
|
if (rhs_geom) {
|
310
298
|
char val = GEOSDisjoint_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom, rhs_geom);
|
311
299
|
if (val == 0) {
|
@@ -325,7 +313,7 @@ static VALUE method_geometry_intersects(VALUE self, VALUE rhs)
|
|
325
313
|
VALUE result = Qnil;
|
326
314
|
const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
|
327
315
|
if (self_geom) {
|
328
|
-
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), rhs);
|
316
|
+
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), rhs, Qnil);
|
329
317
|
if (rhs_geom) {
|
330
318
|
char val = GEOSIntersects_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom, rhs_geom);
|
331
319
|
if (val == 0) {
|
@@ -345,7 +333,7 @@ static VALUE method_geometry_touches(VALUE self, VALUE rhs)
|
|
345
333
|
VALUE result = Qnil;
|
346
334
|
const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
|
347
335
|
if (self_geom) {
|
348
|
-
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), rhs);
|
336
|
+
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), rhs, Qnil);
|
349
337
|
if (rhs_geom) {
|
350
338
|
char val = GEOSTouches_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom, rhs_geom);
|
351
339
|
if (val == 0) {
|
@@ -365,7 +353,7 @@ static VALUE method_geometry_crosses(VALUE self, VALUE rhs)
|
|
365
353
|
VALUE result = Qnil;
|
366
354
|
const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
|
367
355
|
if (self_geom) {
|
368
|
-
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), rhs);
|
356
|
+
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), rhs, Qnil);
|
369
357
|
if (rhs_geom) {
|
370
358
|
char val = GEOSCrosses_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom, rhs_geom);
|
371
359
|
if (val == 0) {
|
@@ -385,7 +373,7 @@ static VALUE method_geometry_within(VALUE self, VALUE rhs)
|
|
385
373
|
VALUE result = Qnil;
|
386
374
|
const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
|
387
375
|
if (self_geom) {
|
388
|
-
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), rhs);
|
376
|
+
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), rhs, Qnil);
|
389
377
|
if (rhs_geom) {
|
390
378
|
char val = GEOSWithin_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom, rhs_geom);
|
391
379
|
if (val == 0) {
|
@@ -405,7 +393,7 @@ static VALUE method_geometry_contains(VALUE self, VALUE rhs)
|
|
405
393
|
VALUE result = Qnil;
|
406
394
|
const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
|
407
395
|
if (self_geom) {
|
408
|
-
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), rhs);
|
396
|
+
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), rhs, Qnil);
|
409
397
|
if (rhs_geom) {
|
410
398
|
char val = GEOSContains_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom, rhs_geom);
|
411
399
|
if (val == 0) {
|
@@ -425,7 +413,7 @@ static VALUE method_geometry_overlaps(VALUE self, VALUE rhs)
|
|
425
413
|
VALUE result = Qnil;
|
426
414
|
const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
|
427
415
|
if (self_geom) {
|
428
|
-
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), rhs);
|
416
|
+
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), rhs, Qnil);
|
429
417
|
if (rhs_geom) {
|
430
418
|
char val = GEOSOverlaps_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom, rhs_geom);
|
431
419
|
if (val == 0) {
|
@@ -445,7 +433,7 @@ static VALUE method_geometry_relate(VALUE self, VALUE rhs, VALUE pattern)
|
|
445
433
|
VALUE result = Qnil;
|
446
434
|
const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
|
447
435
|
if (self_geom) {
|
448
|
-
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), rhs);
|
436
|
+
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), rhs, Qnil);
|
449
437
|
if (rhs_geom) {
|
450
438
|
char val = GEOSRelatePattern_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom, rhs_geom, StringValuePtr(pattern));
|
451
439
|
if (val == 0) {
|
@@ -465,7 +453,7 @@ static VALUE method_geometry_distance(VALUE self, VALUE rhs)
|
|
465
453
|
VALUE result = Qnil;
|
466
454
|
const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
|
467
455
|
if (self_geom) {
|
468
|
-
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), rhs);
|
456
|
+
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), rhs, Qnil);
|
469
457
|
if (rhs_geom) {
|
470
458
|
double dist;
|
471
459
|
if (GEOSDistance_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom, rhs_geom, &dist)) {
|
@@ -505,7 +493,7 @@ static VALUE method_geometry_intersection(VALUE self, VALUE rhs)
|
|
505
493
|
VALUE result = Qnil;
|
506
494
|
const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
|
507
495
|
if (self_geom) {
|
508
|
-
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), rhs);
|
496
|
+
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), rhs, Qnil);
|
509
497
|
if (rhs_geom) {
|
510
498
|
result = rgeo_wrap_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), GEOSIntersection_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom, rhs_geom), Qnil);
|
511
499
|
}
|
@@ -519,7 +507,7 @@ static VALUE method_geometry_union(VALUE self, VALUE rhs)
|
|
519
507
|
VALUE result = Qnil;
|
520
508
|
const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
|
521
509
|
if (self_geom) {
|
522
|
-
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), rhs);
|
510
|
+
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), rhs, Qnil);
|
523
511
|
if (rhs_geom) {
|
524
512
|
result = rgeo_wrap_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), GEOSUnion_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom, rhs_geom), Qnil);
|
525
513
|
}
|
@@ -533,7 +521,7 @@ static VALUE method_geometry_difference(VALUE self, VALUE rhs)
|
|
533
521
|
VALUE result = Qnil;
|
534
522
|
const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
|
535
523
|
if (self_geom) {
|
536
|
-
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), rhs);
|
524
|
+
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), rhs, Qnil);
|
537
525
|
if (rhs_geom) {
|
538
526
|
result = rgeo_wrap_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), GEOSDifference_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom, rhs_geom), Qnil);
|
539
527
|
}
|
@@ -547,7 +535,7 @@ static VALUE method_geometry_sym_difference(VALUE self, VALUE rhs)
|
|
547
535
|
VALUE result = Qnil;
|
548
536
|
const GEOSGeometry* self_geom = RGEO_GET_GEOS_GEOMETRY(self);
|
549
537
|
if (self_geom) {
|
550
|
-
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), rhs);
|
538
|
+
const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), rhs, Qnil);
|
551
539
|
if (rhs_geom) {
|
552
540
|
result = rgeo_wrap_geos_geometry(RGEO_FACTORY_FROM_GEOMETRY(self), GEOSSymDifference_r(RGEO_CONTEXT_FROM_GEOMETRY(self), self_geom, rhs_geom), Qnil);
|
553
541
|
}
|
@@ -596,10 +584,10 @@ void rgeo_init_geos_geometry(RGeo_Globals* globals)
|
|
596
584
|
VALUE geos_geometry_class = rb_define_class_under(globals->geos_module, "GeometryImpl", rb_cObject);
|
597
585
|
|
598
586
|
rb_define_alloc_func(geos_geometry_class, alloc_geometry);
|
587
|
+
rb_define_method(geos_geometry_class, "_set_factory", method_geometry_set_factory, 1);
|
599
588
|
rb_define_method(geos_geometry_class, "initialize_copy", method_geometry_initialize_copy, 1);
|
600
589
|
rb_define_method(geos_geometry_class, "initialized?", method_geometry_initialized_p, 0);
|
601
590
|
rb_define_method(geos_geometry_class, "factory", method_geometry_factory, 0);
|
602
|
-
rb_define_method(geos_geometry_class, "cast", method_geometry_cast, 1);
|
603
591
|
rb_define_method(geos_geometry_class, "dimension", method_geometry_dimension, 0);
|
604
592
|
rb_define_method(geos_geometry_class, "geometry_type", method_geometry_geometry_type, 0);
|
605
593
|
rb_define_method(geos_geometry_class, "srid", method_geometry_srid, 0);
|
@@ -634,11 +622,6 @@ void rgeo_init_geos_geometry(RGeo_Globals* globals)
|
|
634
622
|
}
|
635
623
|
|
636
624
|
|
637
|
-
|
638
|
-
#if 0
|
639
|
-
{
|
640
|
-
#endif
|
641
|
-
}
|
642
|
-
#endif
|
625
|
+
RGEO_END_C
|
643
626
|
|
644
627
|
#endif
|
data/ext/geos_c_impl/geometry.h
CHANGED
@@ -40,12 +40,7 @@
|
|
40
40
|
|
41
41
|
#include "factory.h"
|
42
42
|
|
43
|
-
|
44
|
-
extern "C" {
|
45
|
-
#if 0
|
46
|
-
}
|
47
|
-
#endif
|
48
|
-
#endif
|
43
|
+
RGEO_BEGIN_C
|
49
44
|
|
50
45
|
|
51
46
|
/*
|
@@ -55,11 +50,6 @@ extern "C" {
|
|
55
50
|
void rgeo_init_geos_geometry(RGeo_Globals* globals);
|
56
51
|
|
57
52
|
|
58
|
-
|
59
|
-
#if 0
|
60
|
-
{
|
61
|
-
#endif
|
62
|
-
}
|
63
|
-
#endif
|
53
|
+
RGEO_END_C
|
64
54
|
|
65
55
|
#endif
|
@@ -48,179 +48,64 @@
|
|
48
48
|
#include "polygon.h"
|
49
49
|
#include "geometry_collection.h"
|
50
50
|
|
51
|
-
|
52
|
-
extern "C" {
|
53
|
-
#if 0
|
54
|
-
}
|
55
|
-
#endif
|
56
|
-
#endif
|
51
|
+
RGEO_BEGIN_C
|
57
52
|
|
58
53
|
|
59
54
|
/**** INTERNAL IMPLEMENTATION OF CREATE ****/
|
60
55
|
|
61
56
|
|
62
|
-
|
63
|
-
|
64
|
-
char good = 1;
|
65
|
-
int geom_type = GEOSGeomTypeId_r(RGEO_CONTEXT_FROM_FACTORY(factory), geom);
|
66
|
-
if (type == GEOS_MULTIPOINT && geom_type == GEOS_POINT ||
|
67
|
-
type == GEOS_MULTILINESTRING && (geom_type == GEOS_LINESTRING || geom_type == GEOS_LINEARRING) ||
|
68
|
-
type == GEOS_MULTIPOLYGON && geom_type == GEOS_POLYGON) {
|
69
|
-
rb_ary_push(out_klasses, in_klass);
|
70
|
-
}
|
71
|
-
else if (geom_type == GEOS_GEOMETRYCOLLECTION || type == geom_type) {
|
72
|
-
int len = GEOSGetNumGeometries_r(RGEO_CONTEXT_FROM_FACTORY(factory), geom);
|
73
|
-
int i;
|
74
|
-
for (i=0; i<len; ++i) {
|
75
|
-
const GEOSGeometry* sub_geom = GEOSGetGeometryN_r(RGEO_CONTEXT_FROM_FACTORY(factory), geom, i);
|
76
|
-
if (sub_geom) {
|
77
|
-
VALUE sub_klass = (TYPE(in_klass) == T_ARRAY) ? rb_ary_entry(in_klass, i) : Qnil;
|
78
|
-
good = compute_collection_klasses_internal(type, factory, sub_geom, sub_klass, out_klasses);
|
79
|
-
if (!good) {
|
80
|
-
break;
|
81
|
-
}
|
82
|
-
}
|
83
|
-
else {
|
84
|
-
good = 0;
|
85
|
-
break;
|
86
|
-
}
|
87
|
-
}
|
88
|
-
}
|
89
|
-
else {
|
90
|
-
good = 0;
|
91
|
-
}
|
92
|
-
return good;
|
93
|
-
}
|
94
|
-
|
95
|
-
|
96
|
-
// This walks through an array of geometry objects, and determines the
|
97
|
-
// size of the collection that should be built. For straight
|
98
|
-
// GeometryCollection objects, the size is the same as the length of
|
99
|
-
// the array. For MultiPoint, MultiLineString, and MultiPolygon, we do
|
100
|
-
// recursive gathering of any sub-geometries, so the resulting collection
|
101
|
-
// may have a different length.
|
102
|
-
// We also build an array of the klasses for the geometries gathered.
|
103
|
-
// The array is returned. If a problem occurs-- usually a type mismatch
|
104
|
-
// such as trying to add a LineString to a MultiPoint-- we return Qnil.
|
57
|
+
// Main implementation of the "create" class method for geometry collections.
|
58
|
+
// You must pass in the correct GEOS geometry type ID.
|
105
59
|
|
106
|
-
static VALUE
|
60
|
+
static VALUE create_geometry_collection(VALUE module, int type, VALUE factory, VALUE array)
|
107
61
|
{
|
62
|
+
VALUE result = Qnil;
|
63
|
+
Check_Type(array, T_ARRAY);
|
108
64
|
unsigned int len = (unsigned int)RARRAY_LEN(array);
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
65
|
+
GEOSGeometry** geoms = ALLOC_N(GEOSGeometry*, len == 0 ? 1 : len);
|
66
|
+
if (geoms) {
|
67
|
+
VALUE klass;
|
68
|
+
unsigned int i,j;
|
69
|
+
VALUE klasses = Qnil;
|
70
|
+
VALUE cast_type = Qnil;
|
71
|
+
switch (type) {
|
72
|
+
case GEOS_MULTIPOINT:
|
73
|
+
cast_type = rb_const_get_at(RGEO_GLOBALS_FROM_FACTORY(factory)->features_module, rb_intern("Point"));
|
74
|
+
break;
|
75
|
+
case GEOS_MULTILINESTRING:
|
76
|
+
cast_type = rb_const_get_at(RGEO_GLOBALS_FROM_FACTORY(factory)->features_module, rb_intern("LineString"));
|
77
|
+
break;
|
78
|
+
case GEOS_MULTIPOLYGON:
|
79
|
+
cast_type = rb_const_get_at(RGEO_GLOBALS_FROM_FACTORY(factory)->features_module, rb_intern("Polygon"));
|
116
80
|
break;
|
117
81
|
}
|
118
|
-
VALUE klass = RGEO_KLASSES_FROM_GEOMETRY(entry);
|
119
|
-
if (NIL_P(klass)) {
|
120
|
-
klass = CLASS_OF(entry);
|
121
|
-
}
|
122
|
-
if (type == GEOS_GEOMETRYCOLLECTION) {
|
123
|
-
rb_ary_push(result, klass);
|
124
|
-
}
|
125
|
-
else {
|
126
|
-
char good = compute_collection_klasses_internal(type, factory, geom, klass, result);
|
127
|
-
if (!good) {
|
128
|
-
result = Qnil;
|
129
|
-
break;
|
130
|
-
}
|
131
|
-
}
|
132
|
-
}
|
133
|
-
return result;
|
134
|
-
}
|
135
|
-
|
136
|
-
|
137
|
-
static char gather_geometry_collection_internal(int type, VALUE factory, GEOSGeometry** geoms, unsigned int* ci, const GEOSGeometry* geom, char geom_mine)
|
138
|
-
{
|
139
|
-
char good = 1;
|
140
|
-
int geom_type = GEOSGeomTypeId_r(RGEO_CONTEXT_FROM_FACTORY(factory), geom);
|
141
|
-
if (type != GEOS_GEOMETRYCOLLECTION && (geom_type == GEOS_GEOMETRYCOLLECTION || geom_type == type)) {
|
142
|
-
int len = GEOSGetNumGeometries_r(RGEO_CONTEXT_FROM_FACTORY(factory), geom);
|
143
|
-
int i;
|
144
82
|
for (i=0; i<len; ++i) {
|
145
|
-
|
146
|
-
if (
|
147
|
-
good = gather_geometry_collection_internal(type, factory, geoms, ci, sub_geom, 0);
|
148
|
-
if (!good) {
|
149
|
-
break;
|
150
|
-
}
|
151
|
-
}
|
152
|
-
else {
|
153
|
-
good = 0;
|
83
|
+
GEOSGeometry* geom = rgeo_convert_to_detached_geos_geometry(RGEO_GLOBALS_FROM_FACTORY(factory), rb_ary_entry(array, i), cast_type, &klass);
|
84
|
+
if (!geom) {
|
154
85
|
break;
|
155
86
|
}
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
return good;
|
162
|
-
}
|
163
|
-
|
164
|
-
|
165
|
-
// This walks through the array of geometries and builds a C array of the
|
166
|
-
// geometries to add to the collection we're building. If we're building
|
167
|
-
// a simple GeometryCollection, we just gather the geometries as they are.
|
168
|
-
// If we're building a MultiPoint, MultiLineString, or MultiPolygon, we
|
169
|
-
// recursively gather the contents of any collections we encounter.
|
170
|
-
|
171
|
-
static GEOSGeometry** gather_geometry_collection(int type, VALUE factory, VALUE array, unsigned int len)
|
172
|
-
{
|
173
|
-
GEOSGeometry** geoms = ALLOC_N(GEOSGeometry*, len == 0 ? 1 : len);
|
174
|
-
unsigned int ci = 0;
|
175
|
-
if (geoms) {
|
176
|
-
unsigned int array_len = (unsigned int)RARRAY_LEN(array);
|
177
|
-
unsigned int ai;
|
178
|
-
for (ai=0; ai<array_len; ++ai) {
|
179
|
-
GEOSGeometry* geom = rgeo_convert_to_detached_geos_geometry(RGEO_GLOBALS_FROM_FACTORY(factory), rb_ary_entry(array, ai), NULL);
|
180
|
-
if (geom) {
|
181
|
-
if (!gather_geometry_collection_internal(type, factory, geoms, &ci, geom, 1)) {
|
182
|
-
break;
|
87
|
+
geoms[i] = geom;
|
88
|
+
if (!NIL_P(klass) && NIL_P(klasses)) {
|
89
|
+
klasses = rb_ary_new2(len);
|
90
|
+
for (j=0; j<i; ++j) {
|
91
|
+
rb_ary_push(klasses, Qnil);
|
183
92
|
}
|
184
93
|
}
|
185
|
-
|
186
|
-
|
94
|
+
if (!NIL_P(klasses)) {
|
95
|
+
rb_ary_push(klasses, klass);
|
187
96
|
}
|
188
97
|
}
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
GEOSGeom_destroy_r(RGEO_CONTEXT_FROM_FACTORY(factory), geoms[i]);
|
98
|
+
if (i != len) {
|
99
|
+
for (j=0; j<i; ++j) {
|
100
|
+
GEOSGeom_destroy_r(RGEO_CONTEXT_FROM_FACTORY(factory), geoms[j]);
|
101
|
+
}
|
194
102
|
}
|
195
|
-
|
196
|
-
geoms = NULL;
|
197
|
-
}
|
198
|
-
return geoms;
|
199
|
-
}
|
200
|
-
|
201
|
-
|
202
|
-
// Main implementation of the "create" class method for geometry collections.
|
203
|
-
// You must pass in the correct GEOS geometry type ID.
|
204
|
-
|
205
|
-
static VALUE create_geometry_collection(VALUE module, int type, VALUE factory, VALUE array)
|
206
|
-
{
|
207
|
-
VALUE result = Qnil;
|
208
|
-
Check_Type(array, T_ARRAY);
|
209
|
-
// First pass: we determine the size of the collection to create, and
|
210
|
-
// build the klasses array.
|
211
|
-
VALUE klasses = compute_collection_klasses(type, factory, array);
|
212
|
-
if (!NIL_P(klasses)) {
|
213
|
-
unsigned int len = (unsigned int)RARRAY_LEN(klasses);
|
214
|
-
// Second pass: we gather the actual geometries into a C array
|
215
|
-
GEOSGeometry** geoms = gather_geometry_collection(type, factory, array, len);
|
216
|
-
if (geoms) {
|
217
|
-
// Create the collection itself.
|
103
|
+
else {
|
218
104
|
GEOSGeometry* collection = GEOSGeom_createCollection_r(RGEO_CONTEXT_FROM_FACTORY(factory), type, geoms, len);
|
219
105
|
// Due to a limitation of GEOS, the MultiPolygon assertions are not checked.
|
220
106
|
// We do that manually here.
|
221
107
|
if (collection && type == GEOS_MULTIPOLYGON && (RGEO_FACTORY_DATA_PTR(factory)->flags & 1) == 0) {
|
222
108
|
char problem = 0;
|
223
|
-
unsigned int i, j;
|
224
109
|
for (i=1; i<len; ++i) {
|
225
110
|
for (j=0; j<i; ++j) {
|
226
111
|
GEOSGeometry* igeom = geoms[i];
|
@@ -251,9 +136,10 @@ static VALUE create_geometry_collection(VALUE module, int type, VALUE factory, V
|
|
251
136
|
// element geometries if it fails to create the collection, so we
|
252
137
|
// are not doing that ourselves. If that turns out not to be the
|
253
138
|
// case, this will be a memory leak.
|
254
|
-
free(geoms);
|
255
139
|
}
|
140
|
+
free(geoms);
|
256
141
|
}
|
142
|
+
|
257
143
|
return result;
|
258
144
|
}
|
259
145
|
|
@@ -570,11 +456,6 @@ VALUE rgeo_geos_geometry_collections_eql(GEOSContextHandle_t context, const GEOS
|
|
570
456
|
}
|
571
457
|
|
572
458
|
|
573
|
-
|
574
|
-
#if 0
|
575
|
-
{
|
576
|
-
#endif
|
577
|
-
}
|
578
|
-
#endif
|
459
|
+
RGEO_END_C
|
579
460
|
|
580
461
|
#endif
|