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
@@ -6,19 +6,30 @@
|
|
6
6
|
#
|
7
7
|
# -----------------------------------------------------------------------------
|
8
8
|
|
9
|
+
require_relative "../impl_helper/validity_check"
|
10
|
+
|
9
11
|
module RGeo
|
10
12
|
module Geos
|
11
|
-
module CAPIGeometryMethods
|
13
|
+
module CAPIGeometryMethods
|
12
14
|
include Feature::Instance
|
13
15
|
|
14
|
-
def
|
15
|
-
|
16
|
-
|
16
|
+
def coordinate_dimension
|
17
|
+
dim = 2
|
18
|
+
dim += 1 if factory.supports_z?
|
19
|
+
dim += 1 if factory.supports_m?
|
20
|
+
dim
|
21
|
+
end
|
22
|
+
|
23
|
+
def spatial_dimension
|
24
|
+
factory.supports_z? ? 3 : 2
|
17
25
|
end
|
18
26
|
|
19
|
-
def
|
20
|
-
|
21
|
-
|
27
|
+
def is_3d?
|
28
|
+
factory.supports_z?
|
29
|
+
end
|
30
|
+
|
31
|
+
def measured?
|
32
|
+
factory.supports_m?
|
22
33
|
end
|
23
34
|
|
24
35
|
def inspect
|
@@ -60,44 +71,33 @@ module RGeo
|
|
60
71
|
alias to_s as_text
|
61
72
|
end
|
62
73
|
|
63
|
-
module CAPIMultiLineStringMethods # :nodoc:
|
64
|
-
def is_closed? # rubocop:disable Naming/PredicateName
|
65
|
-
warn "The is_closed? method is deprecated, please use the closed? counterpart, will be removed in v3" unless ENV["RGEO_SILENCE_DEPRECATION"]
|
66
|
-
closed?
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
module CAPILineStringMethods # :nodoc:
|
71
|
-
def is_closed? # rubocop:disable Naming/PredicateName
|
72
|
-
warn "The is_closed? method is deprecated, please use the closed? counterpart, will be removed in v3" unless ENV["RGEO_SILENCE_DEPRECATION"]
|
73
|
-
closed?
|
74
|
-
end
|
75
|
-
|
76
|
-
def is_ring? # rubocop:disable Naming/PredicateName
|
77
|
-
warn "The is_ring? method is deprecated, please use the ring? counterpart, will be removed in v3" unless ENV["RGEO_SILENCE_DEPRECATION"]
|
78
|
-
ring?
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
74
|
module CAPIGeometryCollectionMethods # :nodoc:
|
83
75
|
include Enumerable
|
84
76
|
end
|
85
77
|
|
86
|
-
class CAPIGeometryImpl
|
78
|
+
class CAPIGeometryImpl
|
79
|
+
include Feature::Geometry
|
80
|
+
include ImplHelper::ValidityCheck
|
87
81
|
include CAPIGeometryMethods
|
88
82
|
end
|
89
83
|
|
90
|
-
class CAPIPointImpl
|
84
|
+
class CAPIPointImpl
|
85
|
+
include Feature::Point
|
86
|
+
include ImplHelper::ValidityCheck
|
91
87
|
include CAPIGeometryMethods
|
92
88
|
include CAPIPointMethods
|
93
89
|
end
|
94
90
|
|
95
|
-
class CAPILineStringImpl
|
91
|
+
class CAPILineStringImpl
|
92
|
+
include Feature::LineString
|
93
|
+
include ImplHelper::ValidityCheck
|
96
94
|
include CAPIGeometryMethods
|
97
95
|
include CAPILineStringMethods
|
98
96
|
end
|
99
97
|
|
100
|
-
class CAPILinearRingImpl
|
98
|
+
class CAPILinearRingImpl
|
99
|
+
include Feature::LinearRing
|
100
|
+
include ImplHelper::ValidityCheck
|
101
101
|
include CAPIGeometryMethods
|
102
102
|
include CAPILineStringMethods
|
103
103
|
include CAPILinearRingMethods
|
@@ -107,38 +107,52 @@ module RGeo
|
|
107
107
|
end
|
108
108
|
end
|
109
109
|
|
110
|
-
class CAPILineImpl
|
110
|
+
class CAPILineImpl
|
111
|
+
include Feature::Line
|
112
|
+
include ImplHelper::ValidityCheck
|
111
113
|
include CAPIGeometryMethods
|
112
114
|
include CAPILineStringMethods
|
113
115
|
include CAPILineMethods
|
114
116
|
end
|
115
117
|
|
116
|
-
class CAPIPolygonImpl
|
118
|
+
class CAPIPolygonImpl
|
119
|
+
include Feature::Polygon
|
120
|
+
include ImplHelper::ValidityCheck
|
117
121
|
include CAPIGeometryMethods
|
118
122
|
include CAPIPolygonMethods
|
119
123
|
end
|
120
124
|
|
121
|
-
class CAPIGeometryCollectionImpl
|
125
|
+
class CAPIGeometryCollectionImpl
|
126
|
+
include Feature::GeometryCollection
|
127
|
+
include ImplHelper::ValidityCheck
|
122
128
|
include CAPIGeometryMethods
|
123
129
|
include CAPIGeometryCollectionMethods
|
124
130
|
end
|
125
131
|
|
126
|
-
class CAPIMultiPointImpl
|
132
|
+
class CAPIMultiPointImpl
|
133
|
+
include Feature::MultiPoint
|
134
|
+
include ImplHelper::ValidityCheck
|
127
135
|
include CAPIGeometryMethods
|
128
136
|
include CAPIGeometryCollectionMethods
|
129
137
|
include CAPIMultiPointMethods
|
130
138
|
end
|
131
139
|
|
132
|
-
class CAPIMultiLineStringImpl
|
140
|
+
class CAPIMultiLineStringImpl
|
141
|
+
include Feature::MultiLineString
|
142
|
+
include ImplHelper::ValidityCheck
|
133
143
|
include CAPIGeometryMethods
|
134
144
|
include CAPIGeometryCollectionMethods
|
135
145
|
include CAPIMultiLineStringMethods
|
136
146
|
end
|
137
147
|
|
138
|
-
class CAPIMultiPolygonImpl
|
148
|
+
class CAPIMultiPolygonImpl
|
149
|
+
include Feature::MultiPolygon
|
150
|
+
include ImplHelper::ValidityCheck
|
139
151
|
include CAPIGeometryMethods
|
140
152
|
include CAPIGeometryCollectionMethods
|
141
153
|
include CAPIMultiPolygonMethods
|
142
154
|
end
|
155
|
+
|
156
|
+
ImplHelper::ValidityCheck.override_classes
|
143
157
|
end
|
144
158
|
end
|
@@ -9,104 +9,91 @@
|
|
9
9
|
module RGeo
|
10
10
|
module Geos
|
11
11
|
# This the FFI-GEOS implementation of RGeo::Feature::Factory.
|
12
|
-
|
13
12
|
class FFIFactory
|
14
13
|
include Feature::Factory::Instance
|
15
14
|
include ImplHelper::Utils
|
16
15
|
|
16
|
+
attr_reader :coordinate_dimension, :spatial_dimension, :_has_3d, :_auto_prepare
|
17
|
+
|
18
|
+
# Returns the SRID of geometries created by this factory.
|
19
|
+
attr_reader :srid
|
20
|
+
|
21
|
+
# Returns the resolution used by buffer calculations on geometries
|
22
|
+
# created by this factory
|
23
|
+
attr_reader :buffer_resolution
|
24
|
+
|
25
|
+
# See RGeo::Feature::Factory#coord_sys
|
26
|
+
attr_reader :coord_sys
|
27
|
+
|
17
28
|
# Create a new factory. Returns nil if the FFI-GEOS implementation
|
18
29
|
# is not supported.
|
19
30
|
#
|
20
31
|
# See RGeo::Geos.factory for a list of supported options.
|
21
32
|
|
22
33
|
def initialize(opts = {})
|
23
|
-
# Main flags
|
24
|
-
@uses_lenient_multi_polygon_assertions = opts[:uses_lenient_assertions] ||
|
25
|
-
opts[:lenient_multi_polygon_assertions] || opts[:uses_lenient_multi_polygon_assertions]
|
26
34
|
@has_z = opts[:has_z_coordinate] ? true : false
|
27
35
|
@has_m = opts[:has_m_coordinate] ? true : false
|
36
|
+
|
28
37
|
if @has_z && @has_m
|
29
38
|
raise Error::UnsupportedOperation, "GEOS cannot support both Z and M coordinates at the same time."
|
30
39
|
end
|
40
|
+
|
41
|
+
@coordinate_dimension = 2
|
42
|
+
@coordinate_dimension += 1 if @has_z
|
43
|
+
@coordinate_dimension += 1 if @has_m
|
44
|
+
@spatial_dimension = @has_z ? 3 : 2
|
45
|
+
|
31
46
|
@_has_3d = @has_z || @has_m
|
32
47
|
@buffer_resolution = opts[:buffer_resolution].to_i
|
33
48
|
@buffer_resolution = 1 if @buffer_resolution < 1
|
34
|
-
@_auto_prepare = opts[:auto_prepare]
|
49
|
+
@_auto_prepare = opts[:auto_prepare] != :disabled
|
35
50
|
|
36
51
|
# Interpret the generator options
|
37
|
-
|
38
|
-
case
|
39
|
-
when :geos
|
40
|
-
@wkt_writer = ::Geos::WktWriter.new
|
41
|
-
@wkt_generator = nil
|
52
|
+
wkt_generator = opts[:wkt_generator]
|
53
|
+
case wkt_generator
|
42
54
|
when Hash
|
43
|
-
@wkt_generator = WKRep::WKTGenerator.new(
|
55
|
+
@wkt_generator = WKRep::WKTGenerator.new(wkt_generator)
|
44
56
|
@wkt_writer = nil
|
45
57
|
else
|
46
|
-
@
|
47
|
-
@wkt_writer =
|
58
|
+
@wkt_writer = ::Geos::WktWriter.new
|
59
|
+
@wkt_writer.output_dimensions = 2
|
60
|
+
@wkt_writer.trim = true
|
61
|
+
@wkt_generator = nil
|
48
62
|
end
|
49
|
-
|
50
|
-
case
|
51
|
-
when :geos
|
52
|
-
@wkb_writer = ::Geos::WkbWriter.new
|
53
|
-
@wkb_generator = nil
|
63
|
+
wkb_generator = opts[:wkb_generator]
|
64
|
+
case wkb_generator
|
54
65
|
when Hash
|
55
|
-
@wkb_generator = WKRep::WKBGenerator.new(
|
66
|
+
@wkb_generator = WKRep::WKBGenerator.new(wkb_generator)
|
56
67
|
@wkb_writer = nil
|
57
68
|
else
|
58
|
-
@
|
59
|
-
@wkb_writer =
|
69
|
+
@wkb_writer = ::Geos::WkbWriter.new
|
70
|
+
@wkb_writer.output_dimensions = 2
|
71
|
+
@wkb_generator = nil
|
60
72
|
end
|
61
73
|
|
62
|
-
# Coordinate system (srid
|
63
|
-
|
64
|
-
@
|
65
|
-
|
66
|
-
if @proj4.is_a?(String) || @proj4.is_a?(Hash)
|
67
|
-
@proj4 = CoordSys::Proj4.create(@proj4)
|
68
|
-
end
|
69
|
-
else
|
70
|
-
@proj4 = nil
|
71
|
-
end
|
72
|
-
@coord_sys = opts[:coord_sys]
|
73
|
-
if @coord_sys.is_a?(String)
|
74
|
-
@coord_sys = CoordSys::CS.create_from_wkt(@coord_sys)
|
75
|
-
end
|
76
|
-
if (!@proj4 || !@coord_sys) && @srid && (db = opts[:srs_database])
|
77
|
-
entry = db.get(@srid.to_i)
|
78
|
-
if entry
|
79
|
-
@proj4 ||= entry.proj4
|
80
|
-
@coord_sys ||= entry.coord_sys
|
81
|
-
end
|
82
|
-
end
|
83
|
-
@srid ||= @coord_sys.authority_code if @coord_sys
|
84
|
-
@srid = @srid.to_i
|
74
|
+
# Coordinate system (srid and coord_sys)
|
75
|
+
coord_sys_info = ImplHelper::Utils.setup_coord_sys(opts[:srid], opts[:coord_sys], opts[:coord_sys_class])
|
76
|
+
@srid = coord_sys_info[:srid]
|
77
|
+
@coord_sys = coord_sys_info[:coord_sys]
|
85
78
|
|
86
79
|
# Interpret parser options
|
87
80
|
wkt_parser = opts[:wkt_parser]
|
88
81
|
case wkt_parser
|
89
|
-
when :geos
|
90
|
-
@wkt_reader = ::Geos::WktReader.new
|
91
|
-
@wkt_parser = nil
|
92
82
|
when Hash
|
93
83
|
@wkt_parser = WKRep::WKTParser.new(self, wkt_parser)
|
94
84
|
@wkt_reader = nil
|
95
85
|
else
|
96
|
-
@
|
97
|
-
@
|
86
|
+
@wkt_reader = ::Geos::WktReader.new
|
87
|
+
@wkt_parser = nil
|
98
88
|
end
|
99
89
|
wkb_parser = opts[:wkb_parser]
|
100
90
|
case wkb_parser
|
101
|
-
when :geos
|
102
|
-
@wkb_reader = ::Geos::WkbReader.new
|
103
|
-
@wkb_parser = nil
|
104
91
|
when Hash
|
105
92
|
@wkb_parser = WKRep::WKBParser.new(self, wkb_parser)
|
106
93
|
@wkb_reader = nil
|
107
94
|
else
|
108
|
-
@
|
109
|
-
@
|
95
|
+
@wkb_reader = ::Geos::WkbReader.new
|
96
|
+
@wkb_parser = nil
|
110
97
|
end
|
111
98
|
end
|
112
99
|
|
@@ -118,19 +105,19 @@ module RGeo
|
|
118
105
|
|
119
106
|
# Factory equivalence test.
|
120
107
|
|
121
|
-
def eql?(
|
122
|
-
|
123
|
-
@has_z ==
|
124
|
-
@has_m ==
|
125
|
-
@buffer_resolution ==
|
126
|
-
@
|
108
|
+
def eql?(other)
|
109
|
+
other.is_a?(self.class) && @srid == other.srid &&
|
110
|
+
@has_z == other.property(:has_z_coordinate) &&
|
111
|
+
@has_m == other.property(:has_m_coordinate) &&
|
112
|
+
@buffer_resolution == other.property(:buffer_resolution) &&
|
113
|
+
@coord_sys.eql?(other.coord_sys)
|
127
114
|
end
|
128
115
|
alias == eql?
|
129
116
|
|
130
117
|
# Standard hash code
|
131
118
|
|
132
119
|
def hash
|
133
|
-
@hash ||= [@srid, @has_z, @has_m, @buffer_resolution, @
|
120
|
+
@hash ||= [@srid, @has_z, @has_m, @buffer_resolution, @coord_sys].hash
|
134
121
|
end
|
135
122
|
|
136
123
|
# Marshal support
|
@@ -141,42 +128,30 @@ module RGeo
|
|
141
128
|
"hasm" => @has_m,
|
142
129
|
"srid" => @srid,
|
143
130
|
"bufr" => @buffer_resolution,
|
144
|
-
"wktg" => @wkt_generator
|
145
|
-
"wkbg" => @wkb_generator
|
146
|
-
"wktp" => @wkt_parser
|
147
|
-
"wkbp" => @wkb_parser
|
148
|
-
"lmpa" => @uses_lenient_multi_polygon_assertions,
|
131
|
+
"wktg" => @wkt_generator&.properties,
|
132
|
+
"wkbg" => @wkb_generator&.properties,
|
133
|
+
"wktp" => @wkt_parser&.properties,
|
134
|
+
"wkbp" => @wkb_parser&.properties,
|
149
135
|
"apre" => @_auto_prepare
|
150
136
|
}
|
151
|
-
hash["proj4"] = @proj4.marshal_dump if @proj4
|
152
137
|
hash["cs"] = @coord_sys.to_wkt if @coord_sys
|
153
138
|
hash
|
154
139
|
end
|
155
140
|
|
156
141
|
def marshal_load(data) # :nodoc:
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
else
|
161
|
-
proj4 = nil
|
162
|
-
end
|
163
|
-
if (coord_sys_data = data["cs"])
|
164
|
-
coord_sys = CoordSys::CS.create_from_wkt(coord_sys_data)
|
165
|
-
else
|
166
|
-
coord_sys = nil
|
167
|
-
end
|
142
|
+
cs_class = CoordSys::CONFIG.default_coord_sys_class
|
143
|
+
coord_sys = data["cs"]&.then { |cs| cs_class.create_from_wkt(cs) }
|
144
|
+
|
168
145
|
initialize(
|
169
146
|
has_z_coordinate: data["hasz"],
|
170
147
|
has_m_coordinate: data["hasm"],
|
171
148
|
srid: data["srid"],
|
172
149
|
buffer_resolution: data["bufr"],
|
173
|
-
wkt_generator: symbolize_hash(data["wktg"]),
|
174
|
-
wkb_generator: symbolize_hash(data["wkbg"]),
|
175
|
-
wkt_parser: symbolize_hash(data["wktp"]),
|
176
|
-
wkb_parser: symbolize_hash(data["wkbp"]),
|
177
|
-
uses_lenient_multi_polygon_assertions: data["lmpa"],
|
150
|
+
wkt_generator: data["wktg"] && symbolize_hash(data["wktg"]),
|
151
|
+
wkb_generator: data["wkbg"] && symbolize_hash(data["wkbg"]),
|
152
|
+
wkt_parser: data["wktp"] && symbolize_hash(data["wktp"]),
|
153
|
+
wkb_parser: data["wkbp"] && symbolize_hash(data["wkbp"]),
|
178
154
|
auto_prepare: (data["apre"] ? :simple : :disabled),
|
179
|
-
proj4: proj4,
|
180
155
|
coord_sys: coord_sys
|
181
156
|
)
|
182
157
|
end
|
@@ -188,68 +163,33 @@ module RGeo
|
|
188
163
|
coder["has_m_coordinate"] = @has_m
|
189
164
|
coder["srid"] = @srid
|
190
165
|
coder["buffer_resolution"] = @buffer_resolution
|
191
|
-
coder["
|
192
|
-
coder["
|
193
|
-
coder["
|
194
|
-
coder["
|
195
|
-
coder["wkb_parser"] = @wkb_parser.properties
|
166
|
+
coder["wkt_generator"] = @wkt_generator&.properties
|
167
|
+
coder["wkb_generator"] = @wkb_generator&.properties
|
168
|
+
coder["wkt_parser"] = @wkt_parser&.properties
|
169
|
+
coder["wkb_parser"] = @wkb_parser&.properties
|
196
170
|
coder["auto_prepare"] = @_auto_prepare ? "simple" : "disabled"
|
197
|
-
if @proj4
|
198
|
-
str = @proj4.original_str || @proj4.canonical_str
|
199
|
-
coder["proj4"] = @proj4.radians? ? { "proj4" => str, "radians" => true } : str
|
200
|
-
end
|
201
171
|
coder["coord_sys"] = @coord_sys.to_wkt if @coord_sys
|
202
172
|
end
|
203
173
|
|
204
174
|
def init_with(coder) # :nodoc:
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
proj4 = CoordSys::Proj4.create(proj4_data["proj4"], radians: proj4_data["radians"])
|
209
|
-
else
|
210
|
-
proj4 = CoordSys::Proj4.create(proj4_data.to_s)
|
211
|
-
end
|
212
|
-
else
|
213
|
-
proj4 = nil
|
214
|
-
end
|
215
|
-
if (coord_sys_data = coder["cs"])
|
216
|
-
coord_sys = CoordSys::CS.create_from_wkt(coord_sys_data.to_s)
|
217
|
-
else
|
218
|
-
coord_sys = nil
|
219
|
-
end
|
175
|
+
cs_class = CoordSys::CONFIG.default_coord_sys_class
|
176
|
+
coord_sys = coder["cs"]&.then { |cs| cs_class.create_from_wkt(cs) }
|
177
|
+
|
220
178
|
initialize(
|
221
179
|
has_z_coordinate: coder["has_z_coordinate"],
|
222
180
|
has_m_coordinate: coder["has_m_coordinate"],
|
223
181
|
srid: coder["srid"],
|
224
182
|
buffer_resolution: coder["buffer_resolution"],
|
225
|
-
wkt_generator: symbolize_hash(coder["wkt_generator"]),
|
226
|
-
wkb_generator: symbolize_hash(coder["wkb_generator"]),
|
227
|
-
wkt_parser: symbolize_hash(coder["wkt_parser"]),
|
228
|
-
wkb_parser: symbolize_hash(coder["wkb_parser"]),
|
183
|
+
wkt_generator: coder["wkt_generator"] && symbolize_hash(coder["wkt_generator"]),
|
184
|
+
wkb_generator: coder["wkb_generator"] && symbolize_hash(coder["wkb_generator"]),
|
185
|
+
wkt_parser: coder["wkt_parser"] && symbolize_hash(coder["wkt_parser"]),
|
186
|
+
wkb_parser: coder["wkb_parser"] && symbolize_hash(coder["wkb_parser"]),
|
229
187
|
auto_prepare: coder["auto_prepare"] == "disabled" ? :disabled : :simple,
|
230
|
-
uses_lenient_multi_polygon_assertions: coder["lenient_multi_polygon_assertions"],
|
231
|
-
proj4: proj4,
|
232
188
|
coord_sys: coord_sys
|
233
189
|
)
|
234
190
|
end
|
235
191
|
|
236
|
-
# Returns the SRID of geometries created by this factory.
|
237
|
-
|
238
|
-
attr_reader :srid
|
239
|
-
|
240
|
-
# Returns the resolution used by buffer calculations on geometries
|
241
|
-
# created by this factory
|
242
|
-
|
243
|
-
attr_reader :buffer_resolution
|
244
|
-
|
245
|
-
# Returns true if this factory is lenient with MultiPolygon assertions
|
246
|
-
|
247
|
-
def lenient_multi_polygon_assertions?
|
248
|
-
@uses_lenient_multi_polygon_assertions
|
249
|
-
end
|
250
|
-
|
251
192
|
# See RGeo::Feature::Factory#property
|
252
|
-
|
253
193
|
def property(name_)
|
254
194
|
case name_
|
255
195
|
when :has_z_coordinate
|
@@ -260,18 +200,19 @@ module RGeo
|
|
260
200
|
true
|
261
201
|
when :buffer_resolution
|
262
202
|
@buffer_resolution
|
263
|
-
when :uses_lenient_multi_polygon_assertions
|
264
|
-
@uses_lenient_multi_polygon_assertions
|
265
203
|
when :auto_prepare
|
266
204
|
@_auto_prepare ? :simple : :disabled
|
267
205
|
end
|
268
206
|
end
|
269
207
|
|
270
208
|
# See RGeo::Feature::Factory#parse_wkt
|
271
|
-
|
272
209
|
def parse_wkt(str)
|
273
210
|
if @wkt_reader
|
274
|
-
|
211
|
+
begin
|
212
|
+
wrap_fg_geom(@wkt_reader.read(str), nil)
|
213
|
+
rescue ::Geos::WktReader::ParseError => e
|
214
|
+
raise RGeo::Error::ParseError, e.message.partition(":").last
|
215
|
+
end
|
275
216
|
else
|
276
217
|
@wkt_parser.parse(str)
|
277
218
|
end
|
@@ -281,7 +222,12 @@ module RGeo
|
|
281
222
|
|
282
223
|
def parse_wkb(str)
|
283
224
|
if @wkb_reader
|
284
|
-
|
225
|
+
begin
|
226
|
+
meth = str[0].match?(/[0-9a-fA-F]/) ? :read_hex : :read
|
227
|
+
wrap_fg_geom(@wkb_reader.public_send(meth, str), nil)
|
228
|
+
rescue ::Geos::WkbReader::ParseError => e
|
229
|
+
raise RGeo::Error::ParseError, e.message.partition(":").last
|
230
|
+
end
|
285
231
|
else
|
286
232
|
@wkb_parser.parse(str)
|
287
233
|
end
|
@@ -351,10 +297,8 @@ module RGeo
|
|
351
297
|
inner_rings = inner_rings.to_a unless inner_rings.is_a?(Array)
|
352
298
|
return unless RGeo::Feature::LineString.check_type(outer_ring)
|
353
299
|
outer_ring = create_fg_linear_ring(outer_ring.points)
|
354
|
-
|
355
|
-
|
356
|
-
create_fg_linear_ring(r.points)
|
357
|
-
end
|
300
|
+
return unless inner_rings.all? { |r| RGeo::Feature::LineString.check_type(r) }
|
301
|
+
inner_rings = inner_rings.map { |r| create_fg_linear_ring(r.points) }
|
358
302
|
inner_rings.compact!
|
359
303
|
fg_geom = ::Geos::Utils.create_polygon(outer_ring, *inner_rings)
|
360
304
|
FFIPolygonImpl.new(self, fg_geom, nil)
|
@@ -383,11 +327,16 @@ module RGeo
|
|
383
327
|
def multi_point(elems)
|
384
328
|
elems = elems.to_a unless elems.is_a?(Array)
|
385
329
|
elems = elems.map do |elem|
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
330
|
+
RGeo::Feature.cast(
|
331
|
+
elem,
|
332
|
+
self,
|
333
|
+
RGeo::Feature::Point,
|
334
|
+
:force_new,
|
335
|
+
:keep_subtype
|
336
|
+
)
|
337
|
+
end
|
338
|
+
return unless elems.all?
|
339
|
+
elems = elems.map(&:detach_fg_geom)
|
391
340
|
klasses = Array.new(elems.size, FFIPointImpl)
|
392
341
|
fg_geom = ::Geos::Utils.create_collection(::Geos::GeomTypes::GEOS_MULTIPOINT, elems)
|
393
342
|
FFIMultiPointImpl.new(self, fg_geom, klasses)
|
@@ -417,33 +366,14 @@ module RGeo
|
|
417
366
|
raise(RGeo::Error::InvalidGeometry, "Could not cast to polygon: #{elem}") unless elem
|
418
367
|
elem.detach_fg_geom
|
419
368
|
end
|
420
|
-
unless @uses_lenient_multi_polygon_assertions
|
421
|
-
(1...elems.size).each do |i|
|
422
|
-
(0...i).each do |j|
|
423
|
-
igeom = elems[i]
|
424
|
-
jgeom = elems[j]
|
425
|
-
if igeom.relate_pattern(jgeom, "2********") || igeom.relate_pattern(jgeom, "****1****")
|
426
|
-
raise(RGeo::Error::InvalidGeometry, "Invalid relate pattern: #{jgeom}")
|
427
|
-
end
|
428
|
-
end
|
429
|
-
end
|
430
|
-
end
|
431
369
|
klasses = Array.new(elems.size, FFIPolygonImpl)
|
432
370
|
fg_geom = ::Geos::Utils.create_collection(::Geos::GeomTypes::GEOS_MULTIPOLYGON, elems)
|
433
371
|
FFIMultiPolygonImpl.new(self, fg_geom, klasses)
|
434
372
|
end
|
435
373
|
|
436
|
-
# See RGeo::Feature::Factory#proj4
|
437
|
-
|
438
|
-
attr_reader :proj4
|
439
|
-
|
440
|
-
# See RGeo::Feature::Factory#coord_sys
|
441
|
-
|
442
|
-
attr_reader :coord_sys
|
443
|
-
|
444
374
|
# See RGeo::Feature::Factory#override_cast
|
445
375
|
|
446
|
-
def override_cast(
|
376
|
+
def override_cast(_original, _ntype, _flags)
|
447
377
|
false
|
448
378
|
# TODO
|
449
379
|
end
|
@@ -491,14 +421,13 @@ module RGeo
|
|
491
421
|
klass.new(self, fg_geom, klasses)
|
492
422
|
end
|
493
423
|
|
494
|
-
attr_reader :_has_3d # :nodoc:
|
495
|
-
attr_reader :_auto_prepare # :nodoc:
|
496
|
-
|
497
424
|
def convert_to_fg_geometry(obj, type = nil)
|
498
|
-
if type && obj.factory != self
|
499
|
-
|
500
|
-
|
501
|
-
|
425
|
+
obj = Feature.cast(obj, self, type) if type && obj.factory != self
|
426
|
+
|
427
|
+
geom = obj&.fg_geom
|
428
|
+
raise RGeo::Error::InvalidGeometry, "Unable to cast the geometry to the FFI Factory" if geom.nil?
|
429
|
+
|
430
|
+
geom
|
502
431
|
end
|
503
432
|
|
504
433
|
def generate_wkt(geom)
|
@@ -520,6 +449,7 @@ module RGeo
|
|
520
449
|
def write_for_marshal(geom)
|
521
450
|
if Utils.ffi_supports_set_output_dimension || !@_has_3d
|
522
451
|
wkb_writer = ::Geos::WkbWriter.new
|
452
|
+
wkb_writer.output_dimensions = 2
|
523
453
|
wkb_writer.output_dimensions = 3 if @_has_3d
|
524
454
|
wkb_writer.write(geom.fg_geom)
|
525
455
|
else
|
@@ -534,6 +464,8 @@ module RGeo
|
|
534
464
|
def write_for_psych(geom)
|
535
465
|
if Utils.ffi_supports_set_output_dimension || !@_has_3d
|
536
466
|
wkt_writer = ::Geos::WktWriter.new
|
467
|
+
wkt_writer.output_dimensions = 2
|
468
|
+
wkt_writer.trim = true
|
537
469
|
wkt_writer.output_dimensions = 3 if @_has_3d
|
538
470
|
wkt_writer.write(geom.fg_geom)
|
539
471
|
else
|
@@ -549,14 +481,14 @@ module RGeo
|
|
549
481
|
|
550
482
|
def create_fg_linear_ring(points)
|
551
483
|
size = points.size
|
552
|
-
return if size
|
484
|
+
return if size.between?(1, 2)
|
553
485
|
if size > 0 && points.first != points.last
|
554
486
|
points += [points.first]
|
555
487
|
size += 1
|
556
488
|
end
|
557
489
|
cs = ::Geos::CoordinateSequence.new(size, 3)
|
490
|
+
return unless points.all? { |p| RGeo::Feature::Point.check_type(p) }
|
558
491
|
points.each_with_index do |p, i|
|
559
|
-
return unless RGeo::Feature::Point.check_type(p)
|
560
492
|
cs.set_x(i, p.x)
|
561
493
|
cs.set_y(i, p.y)
|
562
494
|
if @has_z
|