rgeo 2.3.0 → 3.0.0.pre.rc.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 +1 -0
- data/ext/geos_c_impl/analysis.c +8 -6
- data/ext/geos_c_impl/analysis.h +1 -3
- data/ext/geos_c_impl/errors.c +10 -8
- data/ext/geos_c_impl/errors.h +7 -3
- data/ext/geos_c_impl/extconf.rb +3 -0
- data/ext/geos_c_impl/factory.c +251 -182
- data/ext/geos_c_impl/factory.h +43 -62
- data/ext/geos_c_impl/geometry.c +56 -24
- data/ext/geos_c_impl/geometry.h +8 -3
- data/ext/geos_c_impl/geometry_collection.c +41 -148
- data/ext/geos_c_impl/geometry_collection.h +1 -14
- 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 +28 -29
- 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 +9 -8
- data/ext/geos_c_impl/point.h +1 -3
- data/ext/geos_c_impl/polygon.c +15 -51
- data/ext/geos_c_impl/polygon.h +1 -3
- data/ext/geos_c_impl/preface.h +8 -0
- data/lib/rgeo/cartesian/analysis.rb +2 -2
- data/lib/rgeo/cartesian/calculations.rb +54 -17
- data/lib/rgeo/cartesian/factory.rb +0 -7
- data/lib/rgeo/cartesian/feature_classes.rb +66 -46
- data/lib/rgeo/cartesian/feature_methods.rb +56 -20
- data/lib/rgeo/cartesian/interface.rb +0 -6
- data/lib/rgeo/cartesian/planar_graph.rb +379 -0
- data/lib/rgeo/cartesian/sweepline_intersector.rb +149 -0
- data/lib/rgeo/cartesian/valid_op.rb +71 -0
- data/lib/rgeo/cartesian.rb +3 -0
- data/lib/rgeo/coord_sys/cs/wkt_parser.rb +6 -6
- data/lib/rgeo/error.rb +15 -0
- data/lib/rgeo/feature/curve.rb +12 -2
- data/lib/rgeo/feature/geometry.rb +38 -28
- data/lib/rgeo/feature/geometry_collection.rb +13 -5
- data/lib/rgeo/feature/line_string.rb +3 -3
- data/lib/rgeo/feature/multi_curve.rb +6 -1
- data/lib/rgeo/feature/multi_surface.rb +3 -3
- data/lib/rgeo/feature/point.rb +4 -4
- data/lib/rgeo/feature/surface.rb +3 -3
- data/lib/rgeo/geographic/factory.rb +0 -7
- data/lib/rgeo/geographic/interface.rb +4 -18
- data/lib/rgeo/geographic/proj4_projector.rb +0 -2
- data/lib/rgeo/geographic/projected_feature_classes.rb +21 -9
- data/lib/rgeo/geographic/projected_feature_methods.rb +63 -30
- data/lib/rgeo/geographic/simple_mercator_projector.rb +0 -2
- data/lib/rgeo/geographic/spherical_feature_classes.rb +29 -9
- data/lib/rgeo/geographic/spherical_feature_methods.rb +68 -2
- data/lib/rgeo/geos/capi_factory.rb +21 -31
- data/lib/rgeo/geos/capi_feature_classes.rb +64 -11
- data/lib/rgeo/geos/ffi_factory.rb +0 -28
- data/lib/rgeo/geos/ffi_feature_classes.rb +34 -10
- data/lib/rgeo/geos/ffi_feature_methods.rb +53 -10
- data/lib/rgeo/geos/interface.rb +18 -10
- data/lib/rgeo/geos/zm_factory.rb +0 -12
- data/lib/rgeo/geos/zm_feature_methods.rb +30 -5
- data/lib/rgeo/impl_helper/basic_geometry_collection_methods.rb +18 -8
- data/lib/rgeo/impl_helper/basic_geometry_methods.rb +1 -1
- data/lib/rgeo/impl_helper/basic_line_string_methods.rb +37 -26
- data/lib/rgeo/impl_helper/basic_point_methods.rb +13 -3
- data/lib/rgeo/impl_helper/basic_polygon_methods.rb +8 -3
- data/lib/rgeo/impl_helper/valid_op.rb +354 -0
- data/lib/rgeo/impl_helper/validity_check.rb +138 -0
- data/lib/rgeo/impl_helper.rb +1 -0
- data/lib/rgeo/version.rb +1 -1
- data/lib/rgeo/wkrep/wkb_generator.rb +1 -1
- data/lib/rgeo/wkrep/wkt_generator.rb +6 -6
- metadata +30 -7
data/ext/geos_c_impl/factory.h
CHANGED
@@ -10,58 +10,13 @@
|
|
10
10
|
|
11
11
|
RGEO_BEGIN_C
|
12
12
|
|
13
|
-
/*
|
14
|
-
Per-interpreter globals.
|
15
|
-
Most of these are cached references to commonly used classes, modules,
|
16
|
-
and symbols so we don't have to do a lot of constant lookups and calls
|
17
|
-
to rb_intern.
|
18
|
-
*/
|
19
|
-
typedef struct {
|
20
|
-
VALUE feature_module;
|
21
|
-
VALUE feature_geometry;
|
22
|
-
VALUE feature_point;
|
23
|
-
VALUE feature_line_string;
|
24
|
-
VALUE feature_linear_ring;
|
25
|
-
VALUE feature_line;
|
26
|
-
VALUE feature_polygon;
|
27
|
-
VALUE feature_geometry_collection;
|
28
|
-
VALUE feature_multi_point;
|
29
|
-
VALUE feature_multi_line_string;
|
30
|
-
VALUE feature_multi_polygon;
|
31
|
-
VALUE geos_module;
|
32
|
-
VALUE geos_geometry;
|
33
|
-
VALUE geos_point;
|
34
|
-
VALUE geos_line_string;
|
35
|
-
VALUE geos_linear_ring;
|
36
|
-
VALUE geos_line;
|
37
|
-
VALUE geos_polygon;
|
38
|
-
VALUE geos_geometry_collection;
|
39
|
-
VALUE geos_multi_point;
|
40
|
-
VALUE geos_multi_line_string;
|
41
|
-
VALUE geos_multi_polygon;
|
42
|
-
ID id_cast;
|
43
|
-
ID id_eql;
|
44
|
-
ID id_generate;
|
45
|
-
ID id_enum_for;
|
46
|
-
ID id_hash;
|
47
|
-
VALUE sym_force_new;
|
48
|
-
VALUE sym_keep_subtype;
|
49
|
-
#ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
|
50
|
-
VALUE psych_wkt_generator;
|
51
|
-
VALUE marshal_wkb_generator;
|
52
|
-
#endif
|
53
|
-
} RGeo_Globals;
|
54
|
-
|
55
|
-
|
56
13
|
/*
|
57
14
|
Wrapped structure for Factory objects.
|
58
15
|
A factory encapsulates the GEOS context, and GEOS serializer settings.
|
59
16
|
It also stores the SRID for all geometries created by this factory,
|
60
17
|
and the resolution for buffers created for this factory's geometries.
|
61
|
-
Finally, it provides easy access to the globals.
|
62
18
|
*/
|
63
19
|
typedef struct {
|
64
|
-
RGeo_Globals* globals;
|
65
20
|
GEOSContextHandle_t geos_context;
|
66
21
|
GEOSWKTReader* wkt_reader;
|
67
22
|
GEOSWKBReader* wkb_reader;
|
@@ -82,12 +37,35 @@ typedef struct {
|
|
82
37
|
int buffer_resolution;
|
83
38
|
} RGeo_FactoryData;
|
84
39
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
40
|
+
/*
|
41
|
+
Flags that are used to pass options when creating a factory.
|
42
|
+
They are available in ruby under RGeo::Geos::CAPIFactory::FLAG_name
|
43
|
+
where name is the name below without the RGEO_FACTORYFLAGS_ prefix.
|
44
|
+
*/
|
45
|
+
#define RGEO_FACTORYFLAGS_SUPPORTS_Z 0b0010
|
46
|
+
#define RGEO_FACTORYFLAGS_SUPPORTS_M 0b0100
|
47
|
+
#define RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M (RGEO_FACTORYFLAGS_SUPPORTS_Z | RGEO_FACTORYFLAGS_SUPPORTS_M)
|
48
|
+
#define RGEO_FACTORYFLAGS_PREPARE_HEURISTIC 0b1000
|
49
|
+
|
50
|
+
/* call-seq:
|
51
|
+
* RGeo::Geos::CAPIFactory.supports_z? -> true or false
|
52
|
+
*/
|
53
|
+
VALUE method_factory_supports_z_p(VALUE self);
|
54
|
+
|
55
|
+
/* call-seq:
|
56
|
+
* RGeo::Geos::CAPIFactory.supports_m? -> true or false
|
57
|
+
*/
|
58
|
+
VALUE method_factory_supports_m_p(VALUE self);
|
90
59
|
|
60
|
+
/* call-seq:
|
61
|
+
* RGeo::Geos::CAPIFactory.supports_z_or_m? -> true or false
|
62
|
+
*/
|
63
|
+
VALUE method_factory_supports_z_or_m_p(VALUE self);
|
64
|
+
|
65
|
+
/* call-seq:
|
66
|
+
* RGeo::Geos::CAPIFactory.prepare_heuristic? -> true or false
|
67
|
+
*/
|
68
|
+
VALUE method_factory_prepare_heuristic_p(VALUE self);
|
91
69
|
|
92
70
|
/*
|
93
71
|
Wrapped structure for Geometry objects.
|
@@ -119,18 +97,30 @@ typedef struct {
|
|
119
97
|
} RGeo_GeometryData;
|
120
98
|
|
121
99
|
|
100
|
+
// Data types which indicate how RGeo types should be managed by Ruby.
|
101
|
+
extern const rb_data_type_t rgeo_factory_type;
|
102
|
+
|
103
|
+
extern const rb_data_type_t rgeo_geometry_type;
|
104
|
+
|
105
|
+
|
106
|
+
// Convenient macros for checking the type of data from Ruby
|
107
|
+
#define RGEO_FACTORY_TYPEDDATA_P(object) (_RGEO_TYPEDDATA_P(object, &rgeo_factory_type))
|
108
|
+
#define RGEO_GEOMETRY_TYPEDDATA_P(object) (_RGEO_TYPEDDATA_P(object, &rgeo_geometry_type))
|
109
|
+
|
110
|
+
#define _RGEO_TYPEDDATA_P(object, data_type) (TYPE(object) == T_DATA && RTYPEDDATA(object)->typed_flag == 1 && RTYPEDDATA(object)->type == data_type)
|
111
|
+
|
122
112
|
// Returns the RGeo_FactoryData* given a ruby Factory object
|
123
|
-
#define RGEO_FACTORY_DATA_PTR(factory) ((RGeo_FactoryData*)
|
113
|
+
#define RGEO_FACTORY_DATA_PTR(factory) ((RGeo_FactoryData*)RTYPEDDATA_DATA(factory))
|
124
114
|
|
125
115
|
// Returns the RGeo_GeometryData* given a ruby Geometry object
|
126
|
-
#define RGEO_GEOMETRY_DATA_PTR(geometry) ((RGeo_GeometryData*)
|
116
|
+
#define RGEO_GEOMETRY_DATA_PTR(geometry) ((RGeo_GeometryData*)RTYPEDDATA_DATA(geometry))
|
127
117
|
|
128
118
|
|
129
119
|
/*
|
130
120
|
Initializes the factory module. This should be called first in the
|
131
121
|
initialization process.
|
132
122
|
*/
|
133
|
-
|
123
|
+
void rgeo_init_geos_factory();
|
134
124
|
|
135
125
|
/*
|
136
126
|
Given a GEOS geometry handle, wraps it in a ruby Geometry object of the
|
@@ -197,15 +187,6 @@ void rgeo_check_geos_object(VALUE obj);
|
|
197
187
|
*/
|
198
188
|
const GEOSGeometry* rgeo_get_geos_geometry_safe(VALUE obj);
|
199
189
|
|
200
|
-
/*
|
201
|
-
Compares the coordinate sequences for two given GEOS geometries.
|
202
|
-
The two given geometries MUST be of types backed directly by
|
203
|
-
coordinate sequences-- i.e. points or line strings.
|
204
|
-
Returns Qtrue if the two coordinate sequences are equal, Qfalse
|
205
|
-
if they are inequal, or Qnil if an error occurs.
|
206
|
-
*/
|
207
|
-
VALUE rgeo_geos_coordseqs_eql(GEOSContextHandle_t context, const GEOSGeometry* geom1, const GEOSGeometry* geom2, char check_z);
|
208
|
-
|
209
190
|
/*
|
210
191
|
Compares the ruby classes and geometry factories of the two given ruby
|
211
192
|
objects. Returns Qtrue if everything is equal (that is, the two objects
|
data/ext/geos_c_impl/geometry.c
CHANGED
@@ -11,6 +11,9 @@
|
|
11
11
|
#include <ruby.h>
|
12
12
|
#include <geos_c.h>
|
13
13
|
|
14
|
+
#include "globals.h"
|
15
|
+
|
16
|
+
#include "errors.h"
|
14
17
|
#include "factory.h"
|
15
18
|
#include "geometry.h"
|
16
19
|
|
@@ -180,13 +183,11 @@ static VALUE method_geometry_geometry_type(VALUE self)
|
|
180
183
|
{
|
181
184
|
VALUE result;
|
182
185
|
RGeo_GeometryData* self_data;
|
183
|
-
const GEOSGeometry* self_geom;
|
184
186
|
|
185
187
|
result = Qnil;
|
186
188
|
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
187
|
-
|
188
|
-
|
189
|
-
result = RGEO_FACTORY_DATA_PTR(self_data->factory)->globals->feature_geometry;
|
189
|
+
if (self_data->geom) {
|
190
|
+
result = rgeo_feature_geometry_module;
|
190
191
|
}
|
191
192
|
return result;
|
192
193
|
}
|
@@ -271,7 +272,7 @@ static VALUE method_geometry_as_text(VALUE self)
|
|
271
272
|
factory_data = RGEO_FACTORY_DATA_PTR(self_data->factory);
|
272
273
|
wkt_generator = factory_data->wkrep_wkt_generator;
|
273
274
|
if (!NIL_P(wkt_generator)) {
|
274
|
-
result = rb_funcall(wkt_generator,
|
275
|
+
result = rb_funcall(wkt_generator, rb_intern("generate"), 1, self);
|
275
276
|
}
|
276
277
|
else {
|
277
278
|
wkt_writer = factory_data->wkt_writer;
|
@@ -310,7 +311,7 @@ static VALUE method_geometry_as_binary(VALUE self)
|
|
310
311
|
factory_data = RGEO_FACTORY_DATA_PTR(self_data->factory);
|
311
312
|
wkb_generator = factory_data->wkrep_wkb_generator;
|
312
313
|
if (!NIL_P(wkb_generator)) {
|
313
|
-
result = rb_funcall(wkb_generator,
|
314
|
+
result = rb_funcall(wkb_generator, rb_intern("generate"), 1, self);
|
314
315
|
}
|
315
316
|
else {
|
316
317
|
wkb_writer = factory_data->wkb_writer;
|
@@ -863,24 +864,21 @@ static VALUE method_geometry_union(VALUE self, VALUE rhs)
|
|
863
864
|
|
864
865
|
static VALUE method_geometry_unary_union(VALUE self)
|
865
866
|
{
|
866
|
-
|
867
|
+
#ifdef RGEO_GEOS_SUPPORTS_UNARYUNION
|
867
868
|
RGeo_GeometryData* self_data;
|
868
869
|
const GEOSGeometry* self_geom;
|
869
870
|
|
870
|
-
result = Qnil;
|
871
|
-
|
872
|
-
#ifdef RGEO_GEOS_SUPPORTS_UNARYUNION
|
873
871
|
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
874
872
|
self_geom = self_data->geom;
|
875
873
|
if (self_geom) {
|
876
874
|
GEOSContextHandle_t self_context = self_data->geos_context;
|
877
|
-
|
875
|
+
return rgeo_wrap_geos_geometry(self_data->factory,
|
878
876
|
GEOSUnaryUnion_r(self_context, self_geom),
|
879
877
|
Qnil);
|
880
878
|
}
|
881
879
|
#endif
|
882
880
|
|
883
|
-
return
|
881
|
+
return Qnil;
|
884
882
|
}
|
885
883
|
|
886
884
|
|
@@ -1044,18 +1042,39 @@ static VALUE method_geometry_invalid_reason(VALUE self)
|
|
1044
1042
|
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
1045
1043
|
self_geom = self_data->geom;
|
1046
1044
|
if (self_geom) {
|
1047
|
-
|
1048
|
-
|
1049
|
-
|
1050
|
-
|
1051
|
-
|
1052
|
-
|
1053
|
-
|
1054
|
-
|
1045
|
+
// We use NULL there to tell GEOS that we don't care about the position.
|
1046
|
+
switch(GEOSisValidDetail_r(self_data->geos_context, self_geom, 0, &str, NULL)) {
|
1047
|
+
case 0: // invalid
|
1048
|
+
result = rb_utf8_str_new_cstr(str);
|
1049
|
+
case 1: // valid
|
1050
|
+
break;
|
1051
|
+
case 2: // exception
|
1052
|
+
default:
|
1053
|
+
result = rb_utf8_str_new_cstr("Exception");
|
1054
|
+
break;
|
1055
|
+
};
|
1056
|
+
if (str) GEOSFree_r(self_data->geos_context, str);
|
1055
1057
|
}
|
1056
1058
|
return result;
|
1057
1059
|
}
|
1058
1060
|
|
1061
|
+
static VALUE method_geometry_make_valid(VALUE self)
|
1062
|
+
{
|
1063
|
+
RGeo_GeometryData* self_data;
|
1064
|
+
const GEOSGeometry* self_geom;
|
1065
|
+
GEOSGeometry* valid_geom;
|
1066
|
+
self_data = RGEO_GEOMETRY_DATA_PTR(self);
|
1067
|
+
self_geom = self_data->geom;
|
1068
|
+
if (!self_geom) return Qnil;
|
1069
|
+
|
1070
|
+
// According to GEOS implementation, MakeValid always returns.
|
1071
|
+
valid_geom = GEOSMakeValid_r(self_data->geos_context, self_geom);
|
1072
|
+
if (!valid_geom) {
|
1073
|
+
rb_raise(rb_eRGeoInvalidGeometry, "%"PRIsVALUE, method_geometry_invalid_reason(self));
|
1074
|
+
}
|
1075
|
+
return rgeo_wrap_geos_geometry(self_data->factory, valid_geom, Qnil);
|
1076
|
+
}
|
1077
|
+
|
1059
1078
|
static VALUE method_geometry_point_on_surface(VALUE self)
|
1060
1079
|
{
|
1061
1080
|
VALUE result;
|
@@ -1071,15 +1090,27 @@ static VALUE method_geometry_point_on_surface(VALUE self)
|
|
1071
1090
|
return result;
|
1072
1091
|
}
|
1073
1092
|
|
1093
|
+
VALUE rgeo_geos_geometries_strict_eql(GEOSContextHandle_t context, const GEOSGeometry* geom1, const GEOSGeometry* geom2)
|
1094
|
+
{
|
1095
|
+
switch (GEOSEqualsExact_r(context, geom1, geom2, 0.0)) {
|
1096
|
+
case 0:
|
1097
|
+
return Qfalse;
|
1098
|
+
case 1:
|
1099
|
+
return Qtrue;
|
1100
|
+
case 2:
|
1101
|
+
default:
|
1102
|
+
rb_raise(rb_eGeosError, "Cannot test equality.");
|
1103
|
+
}
|
1104
|
+
}
|
1074
1105
|
|
1075
1106
|
/**** INITIALIZATION FUNCTION ****/
|
1076
1107
|
|
1077
1108
|
|
1078
|
-
void rgeo_init_geos_geometry(
|
1109
|
+
void rgeo_init_geos_geometry()
|
1079
1110
|
{
|
1080
1111
|
VALUE geos_geometry_methods;
|
1081
1112
|
|
1082
|
-
geos_geometry_methods = rb_define_module_under(
|
1113
|
+
geos_geometry_methods = rb_define_module_under(rgeo_geos_module, "CAPIGeometryMethods");
|
1083
1114
|
|
1084
1115
|
rb_define_method(geos_geometry_methods, "factory=", method_geometry_set_factory, 1);
|
1085
1116
|
rb_define_method(geos_geometry_methods, "initialize_copy", method_geometry_initialize_copy, 1);
|
@@ -1095,8 +1126,8 @@ void rgeo_init_geos_geometry(RGeo_Globals* globals)
|
|
1095
1126
|
rb_define_method(geos_geometry_methods, "boundary", method_geometry_boundary, 0);
|
1096
1127
|
rb_define_method(geos_geometry_methods, "_as_text", method_geometry_as_text, 0);
|
1097
1128
|
rb_define_method(geos_geometry_methods, "as_binary", method_geometry_as_binary, 0);
|
1098
|
-
rb_define_method(geos_geometry_methods, "
|
1099
|
-
rb_define_method(geos_geometry_methods, "
|
1129
|
+
rb_define_method(geos_geometry_methods, "empty?", method_geometry_is_empty, 0);
|
1130
|
+
rb_define_method(geos_geometry_methods, "simple?", method_geometry_is_simple, 0);
|
1100
1131
|
rb_define_method(geos_geometry_methods, "equals?", method_geometry_equals, 1);
|
1101
1132
|
rb_define_method(geos_geometry_methods, "==", method_geometry_equals, 1);
|
1102
1133
|
rb_define_method(geos_geometry_methods, "rep_equals?", method_geometry_eql, 1);
|
@@ -1126,6 +1157,7 @@ void rgeo_init_geos_geometry(RGeo_Globals* globals)
|
|
1126
1157
|
rb_define_method(geos_geometry_methods, "valid?", method_geometry_is_valid, 0);
|
1127
1158
|
rb_define_method(geos_geometry_methods, "invalid_reason", method_geometry_invalid_reason, 0);
|
1128
1159
|
rb_define_method(geos_geometry_methods, "point_on_surface", method_geometry_point_on_surface, 0);
|
1160
|
+
rb_define_method(geos_geometry_methods, "make_valid", method_geometry_make_valid, 0);
|
1129
1161
|
}
|
1130
1162
|
|
1131
1163
|
|
data/ext/geos_c_impl/geometry.h
CHANGED
@@ -6,8 +6,6 @@
|
|
6
6
|
#ifndef RGEO_GEOS_GEOMETRY_INCLUDED
|
7
7
|
#define RGEO_GEOS_GEOMETRY_INCLUDED
|
8
8
|
|
9
|
-
#include "factory.h"
|
10
|
-
|
11
9
|
RGEO_BEGIN_C
|
12
10
|
|
13
11
|
|
@@ -15,8 +13,15 @@ RGEO_BEGIN_C
|
|
15
13
|
Initializes the geometry module. This should be called after the factory
|
16
14
|
module is initialized, but before any of the other modules.
|
17
15
|
*/
|
18
|
-
void rgeo_init_geos_geometry(
|
16
|
+
void rgeo_init_geos_geometry();
|
17
|
+
|
19
18
|
|
19
|
+
/*
|
20
|
+
Compares two geometries using strict GEOS comparison. return Qtrue
|
21
|
+
if they are equal, Qfalse otherwise.
|
22
|
+
May raise a `RGeo::Error::GeosError`.
|
23
|
+
*/
|
24
|
+
VALUE rgeo_geos_geometries_strict_eql(GEOSContextHandle_t context, const GEOSGeometry* geom1, const GEOSGeometry* geom2);
|
20
25
|
|
21
26
|
RGEO_END_C
|
22
27
|
|