rgeo 1.1.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/geos_c_impl/extconf.rb +5 -3
- data/ext/geos_c_impl/factory.c +4 -4
- data/ext/geos_c_impl/geometry.c +1 -1
- data/lib/rgeo.rb +2 -4
- data/lib/rgeo/cartesian.rb +6 -16
- data/lib/rgeo/cartesian/analysis.rb +22 -20
- data/lib/rgeo/cartesian/bounding_box.rb +83 -79
- data/lib/rgeo/cartesian/calculations.rb +40 -38
- data/lib/rgeo/cartesian/factory.rb +134 -169
- data/lib/rgeo/cartesian/feature_classes.rb +2 -18
- data/lib/rgeo/cartesian/feature_methods.rb +37 -39
- data/lib/rgeo/cartesian/interface.rb +11 -9
- data/lib/rgeo/coord_sys.rb +9 -8
- data/lib/rgeo/coord_sys/cs/entities.rb +345 -303
- data/lib/rgeo/coord_sys/cs/factories.rb +30 -28
- data/lib/rgeo/coord_sys/cs/wkt_parser.rb +128 -126
- data/lib/rgeo/coord_sys/srs_database/{interface.rb → entry.rb} +26 -32
- data/lib/rgeo/coord_sys/srs_database/sr_org.rb +19 -17
- data/lib/rgeo/coord_sys/srs_database/url_reader.rb +21 -19
- data/lib/rgeo/error.rb +3 -1
- data/lib/rgeo/feature.rb +23 -34
- data/lib/rgeo/feature/curve.rb +2 -0
- data/lib/rgeo/feature/factory.rb +15 -13
- data/lib/rgeo/feature/factory_generator.rb +7 -5
- data/lib/rgeo/feature/geometry.rb +31 -29
- data/lib/rgeo/feature/geometry_collection.rb +6 -4
- data/lib/rgeo/feature/line.rb +2 -0
- data/lib/rgeo/feature/line_string.rb +3 -1
- data/lib/rgeo/feature/linear_ring.rb +2 -0
- data/lib/rgeo/feature/multi_curve.rb +2 -0
- data/lib/rgeo/feature/multi_line_string.rb +2 -0
- data/lib/rgeo/feature/multi_point.rb +2 -0
- data/lib/rgeo/feature/multi_polygon.rb +2 -0
- data/lib/rgeo/feature/multi_surface.rb +2 -0
- data/lib/rgeo/feature/point.rb +2 -0
- data/lib/rgeo/feature/polygon.rb +3 -1
- data/lib/rgeo/feature/surface.rb +2 -0
- data/lib/rgeo/feature/types.rb +107 -103
- data/lib/rgeo/geographic.rb +17 -27
- data/lib/rgeo/geographic/factory.rb +154 -199
- data/lib/rgeo/geographic/interface.rb +141 -137
- data/lib/rgeo/geographic/proj4_projector.rb +28 -23
- data/lib/rgeo/geographic/projected_feature_classes.rb +2 -18
- data/lib/rgeo/geographic/projected_feature_methods.rb +59 -49
- data/lib/rgeo/geographic/projected_window.rb +4 -2
- data/lib/rgeo/geographic/simple_mercator_projector.rb +41 -39
- data/lib/rgeo/geographic/spherical_feature_classes.rb +2 -18
- data/lib/rgeo/geographic/spherical_feature_methods.rb +67 -67
- data/lib/rgeo/geographic/spherical_math.rb +81 -87
- data/lib/rgeo/geos.rb +23 -34
- data/lib/rgeo/geos/capi_factory.rb +106 -135
- data/lib/rgeo/geos/capi_feature_classes.rb +19 -37
- data/lib/rgeo/geos/ffi_factory.rb +276 -297
- data/lib/rgeo/geos/ffi_feature_classes.rb +2 -20
- data/lib/rgeo/geos/ffi_feature_methods.rb +170 -166
- data/lib/rgeo/geos/interface.rb +25 -23
- data/lib/rgeo/geos/utils.rb +47 -39
- data/lib/rgeo/geos/zm_factory.rb +171 -185
- data/lib/rgeo/geos/zm_feature_classes.rb +2 -20
- data/lib/rgeo/geos/zm_feature_methods.rb +76 -72
- data/lib/rgeo/impl_helper.rb +1 -11
- data/lib/rgeo/impl_helper/basic_geometry_collection_methods.rb +72 -75
- data/lib/rgeo/impl_helper/basic_geometry_methods.rb +21 -23
- data/lib/rgeo/impl_helper/basic_line_string_methods.rb +57 -49
- data/lib/rgeo/impl_helper/basic_point_methods.rb +29 -25
- data/lib/rgeo/impl_helper/basic_polygon_methods.rb +31 -27
- data/lib/rgeo/impl_helper/math.rb +2 -0
- data/lib/rgeo/impl_helper/utils.rb +9 -15
- data/lib/rgeo/version.rb +3 -1
- data/lib/rgeo/wkrep.rb +20 -30
- data/lib/rgeo/wkrep/wkb_generator.rb +87 -84
- data/lib/rgeo/wkrep/wkb_parser.rb +93 -93
- data/lib/rgeo/wkrep/wkt_generator.rb +67 -63
- data/lib/rgeo/wkrep/wkt_parser.rb +172 -168
- metadata +17 -32
- data/lib/rgeo/feature/mixins.rb +0 -143
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# -----------------------------------------------------------------------------
|
2
4
|
#
|
3
5
|
# Core calculations on the sphere
|
@@ -21,11 +23,11 @@ module RGeo
|
|
21
23
|
# of rotation.
|
22
24
|
|
23
25
|
class PointXYZ # :nodoc:
|
24
|
-
def initialize(
|
25
|
-
|
26
|
-
@x = (
|
27
|
-
@y = (
|
28
|
-
@z = (
|
26
|
+
def initialize(x, y, z)
|
27
|
+
r = Math.sqrt(x * x + y * y + z * z)
|
28
|
+
@x = (x / r).to_f
|
29
|
+
@y = (y / r).to_f
|
30
|
+
@z = (z / r).to_f
|
29
31
|
raise "Not a number" if @x.nan? || @y.nan? || @z.nan?
|
30
32
|
end
|
31
33
|
|
@@ -37,90 +39,82 @@ module RGeo
|
|
37
39
|
attr_reader :y
|
38
40
|
attr_reader :z
|
39
41
|
|
40
|
-
def eql?(
|
41
|
-
|
42
|
+
def eql?(rhs)
|
43
|
+
rhs.is_a?(PointXYZ) && @x == rhs.x && @y == rhs.y && @z == rhs.z
|
42
44
|
end
|
43
45
|
alias == eql?
|
44
46
|
|
45
47
|
def latlon
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
0.0
|
51
|
-
end
|
52
|
-
rpd_ = ImplHelper::Math::RADIANS_PER_DEGREE
|
53
|
-
[lat_rad_ / rpd_, lon_rad_ / rpd_]
|
48
|
+
lat_rad = Math.asin(@z)
|
49
|
+
lon_rad = Math.atan2(@y, @x)
|
50
|
+
rpd = ImplHelper::Math::RADIANS_PER_DEGREE
|
51
|
+
[lat_rad / rpd, lon_rad / rpd]
|
54
52
|
end
|
55
53
|
|
56
54
|
def lonlat
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
def %(rhs_)
|
75
|
-
rx_ = rhs_.x
|
76
|
-
ry_ = rhs_.y
|
77
|
-
rz_ = rhs_.z
|
55
|
+
lat_rad = Math.asin(@z)
|
56
|
+
lon_rad = Math.atan2(@y, @x)
|
57
|
+
rpd = ImplHelper::Math::RADIANS_PER_DEGREE
|
58
|
+
[lon_rad / rpd, lat_rad / rpd]
|
59
|
+
end
|
60
|
+
|
61
|
+
def *(rhs)
|
62
|
+
val = @x * rhs.x + @y * rhs.y + @z * rhs.z
|
63
|
+
val = 1.0 if val > 1.0
|
64
|
+
val = -1.0 if val < -1.0
|
65
|
+
val
|
66
|
+
end
|
67
|
+
|
68
|
+
def %(rhs)
|
69
|
+
rx = rhs.x
|
70
|
+
ry = rhs.y
|
71
|
+
rz = rhs.z
|
78
72
|
begin
|
79
|
-
PointXYZ.new(@y *
|
80
|
-
rescue
|
73
|
+
PointXYZ.new(@y * rz - @z * ry, @z * rx - @x * rz, @x * ry - @y * rx)
|
74
|
+
rescue StandardError
|
81
75
|
nil
|
82
76
|
end
|
83
77
|
end
|
84
78
|
|
85
|
-
def dist_to_point(
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
if
|
91
|
-
|
79
|
+
def dist_to_point(rhs)
|
80
|
+
rx = rhs.x
|
81
|
+
ry = rhs.y
|
82
|
+
rz = rhs.z
|
83
|
+
dot = @x * rx + @y * ry + @z * rz
|
84
|
+
if dot > -0.8 && dot < 0.8
|
85
|
+
Math.acos(dot)
|
92
86
|
else
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
87
|
+
x = @y * rz - @z * ry
|
88
|
+
y = @z * rx - @x * rz
|
89
|
+
z = @x * ry - @y * rx
|
90
|
+
as = Math.asin(Math.sqrt(x * x + y * y + z * z))
|
91
|
+
dot > 0.0 ? as : Math::PI - as
|
98
92
|
end
|
99
93
|
end
|
100
94
|
|
101
95
|
# Creates some point that is perpendicular to this point
|
102
96
|
|
103
97
|
def create_perpendicular
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
98
|
+
p1dot = self * P1
|
99
|
+
p2dot = self * P2
|
100
|
+
p1dot = -p1dot if p1dot < 0
|
101
|
+
p2dot = -p2dot if p2dot < 0
|
102
|
+
p1dot < p2dot ? (self % P1) : (self % P2)
|
109
103
|
end
|
110
104
|
|
111
|
-
def self.from_latlon(
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
new(
|
105
|
+
def self.from_latlon(lat, lon)
|
106
|
+
rpd = ImplHelper::Math::RADIANS_PER_DEGREE
|
107
|
+
lat_rad = rpd * lat
|
108
|
+
lon_rad = rpd * lon
|
109
|
+
z = Math.sin(lat_rad)
|
110
|
+
r = Math.cos(lat_rad)
|
111
|
+
x = Math.cos(lon_rad) * r
|
112
|
+
y = Math.sin(lon_rad) * r
|
113
|
+
new(x, y, z)
|
120
114
|
end
|
121
115
|
|
122
|
-
def self.weighted_combination(
|
123
|
-
new(
|
116
|
+
def self.weighted_combination(p1, w1, p2, w2)
|
117
|
+
new(p1.x * w1 + p2.x * w2, p1.y * w1 + p2.y * w2, p1.z * w1 + p2.z * w2)
|
124
118
|
end
|
125
119
|
|
126
120
|
P1 = new(1, 0, 0)
|
@@ -130,9 +124,9 @@ module RGeo
|
|
130
124
|
# Represents a finite arc on the sphere.
|
131
125
|
|
132
126
|
class ArcXYZ # :nodoc:
|
133
|
-
def initialize(
|
134
|
-
@s =
|
135
|
-
@e =
|
127
|
+
def initialize(start, stop)
|
128
|
+
@s = start
|
129
|
+
@e = stop
|
136
130
|
@axis = false
|
137
131
|
end
|
138
132
|
|
@@ -143,14 +137,14 @@ module RGeo
|
|
143
137
|
"#{@s} - #{@e}"
|
144
138
|
end
|
145
139
|
|
146
|
-
def eql?(
|
147
|
-
|
140
|
+
def eql?(rhs)
|
141
|
+
rhs.is_a?(ArcXYZ) && @s == rhs.s && @e == rhs.e
|
148
142
|
end
|
149
143
|
alias == eql?
|
150
144
|
|
151
145
|
def degenerate?
|
152
|
-
|
153
|
-
|
146
|
+
my_axis = axis
|
147
|
+
my_axis.x == 0 && my_axis.y == 0 && my_axis.z == 0
|
154
148
|
end
|
155
149
|
|
156
150
|
def axis
|
@@ -158,22 +152,22 @@ module RGeo
|
|
158
152
|
@axis
|
159
153
|
end
|
160
154
|
|
161
|
-
def contains_point?(
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
!
|
155
|
+
def contains_point?(obj)
|
156
|
+
my_axis = axis
|
157
|
+
s_axis = ArcXYZ.new(@s, obj).axis
|
158
|
+
e_axis = ArcXYZ.new(obj, @e).axis
|
159
|
+
!s_axis || !e_axis || obj * my_axis == 0.0 && s_axis * my_axis > 0 && e_axis * my_axis > 0
|
166
160
|
end
|
167
161
|
|
168
|
-
def intersects_arc?(
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
if
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
162
|
+
def intersects_arc?(obj)
|
163
|
+
my_axis = axis
|
164
|
+
dot1 = my_axis * obj.s
|
165
|
+
dot2 = my_axis * obj.e
|
166
|
+
if dot1 >= 0.0 && dot2 <= 0.0 || dot1 <= 0.0 && dot2 >= 0.0
|
167
|
+
ob_axis = obj.axis
|
168
|
+
dot1 = ob_axis * @s
|
169
|
+
dot2 = ob_axis * @e
|
170
|
+
dot1 >= 0.0 && dot2 <= 0.0 || dot1 <= 0.0 && dot2 >= 0.0
|
177
171
|
else
|
178
172
|
false
|
179
173
|
end
|
data/lib/rgeo/geos.rb
CHANGED
@@ -1,41 +1,33 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# The Geos module provides general tools for creating and manipulating
|
4
|
+
# a GEOS-backed implementation of the SFS. This is a full implementation
|
5
|
+
# of the SFS using a Cartesian coordinate system. It uses the GEOS C++
|
6
|
+
# library to perform most operations, and hence is available only if
|
7
|
+
# GEOS version 3.2 or later is installed and accessible when the rgeo
|
8
|
+
# gem is installed. RGeo feature calls are translated into appropriate
|
9
|
+
# GEOS calls and directed to the library's C api. RGeo also corrects a
|
10
|
+
# few cases of missing or non-standard behavior in GEOS.
|
2
11
|
#
|
3
|
-
#
|
12
|
+
# This module also provides a namespace for the implementation classes
|
13
|
+
# themselves; however, those classes are meant to be opaque and are
|
14
|
+
# therefore not documented.
|
4
15
|
#
|
5
|
-
#
|
6
|
-
|
7
|
-
|
8
|
-
# The Geos module provides general tools for creating and manipulating
|
9
|
-
# a GEOS-backed implementation of the SFS. This is a full implementation
|
10
|
-
# of the SFS using a Cartesian coordinate system. It uses the GEOS C++
|
11
|
-
# library to perform most operations, and hence is available only if
|
12
|
-
# GEOS version 3.2 or later is installed and accessible when the rgeo
|
13
|
-
# gem is installed. RGeo feature calls are translated into appropriate
|
14
|
-
# GEOS calls and directed to the library's C api. RGeo also corrects a
|
15
|
-
# few cases of missing or non-standard behavior in GEOS.
|
16
|
-
#
|
17
|
-
# This module also provides a namespace for the implementation classes
|
18
|
-
# themselves; however, those classes are meant to be opaque and are
|
19
|
-
# therefore not documented.
|
20
|
-
#
|
21
|
-
# To use the Geos implementation, first obtain a factory using the
|
22
|
-
# RGeo::Geos.factory method. You may then call any of the standard
|
23
|
-
# factory methods on the resulting object.
|
24
|
-
|
25
|
-
module Geos
|
26
|
-
end
|
27
|
-
end
|
16
|
+
# To use the Geos implementation, first obtain a factory using the
|
17
|
+
# RGeo::Geos.factory method. You may then call any of the standard
|
18
|
+
# factory methods on the resulting object.
|
28
19
|
|
29
20
|
# :stopdoc:
|
30
21
|
|
31
22
|
module RGeo
|
32
23
|
module Geos
|
33
|
-
# Implementation files
|
34
24
|
require "rgeo/geos/utils"
|
35
25
|
require "rgeo/geos/interface"
|
36
26
|
begin
|
37
27
|
require "rgeo/geos/geos_c_impl"
|
38
|
-
rescue
|
28
|
+
rescue LoadError
|
29
|
+
# continue
|
30
|
+
end
|
39
31
|
CAPI_SUPPORTED = RGeo::Geos.const_defined?(:CAPIGeometryMethods)
|
40
32
|
if CAPI_SUPPORTED
|
41
33
|
require "rgeo/geos/capi_feature_classes"
|
@@ -56,12 +48,12 @@ module RGeo
|
|
56
48
|
raise "Problem loading FFI" unless ::FFI::AutoPointer
|
57
49
|
FFI_SUPPORTED = true
|
58
50
|
FFI_SUPPORT_EXCEPTION = nil
|
59
|
-
rescue
|
51
|
+
rescue LoadError => ex
|
60
52
|
FFI_SUPPORTED = false
|
61
|
-
FFI_SUPPORT_EXCEPTION =
|
62
|
-
rescue =>
|
53
|
+
FFI_SUPPORT_EXCEPTION = ex
|
54
|
+
rescue StandardError => ex
|
63
55
|
FFI_SUPPORTED = false
|
64
|
-
FFI_SUPPORT_EXCEPTION =
|
56
|
+
FFI_SUPPORT_EXCEPTION = ex
|
65
57
|
end
|
66
58
|
|
67
59
|
# Default preferred native interface
|
@@ -80,9 +72,6 @@ module RGeo
|
|
80
72
|
JOIN_ROUND = 0
|
81
73
|
JOIN_MITRE = 1
|
82
74
|
JOIN_BEVEL = 2
|
83
|
-
|
84
|
-
# Init internal utilities
|
85
|
-
Utils._init
|
86
75
|
end
|
87
76
|
end
|
88
77
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# -----------------------------------------------------------------------------
|
2
4
|
#
|
3
5
|
# GEOS factory implementation
|
@@ -10,6 +12,7 @@ module RGeo
|
|
10
12
|
|
11
13
|
class CAPIFactory
|
12
14
|
include Feature::Factory::Instance
|
15
|
+
include ImplHelper::Utils
|
13
16
|
|
14
17
|
class << self
|
15
18
|
# Create a new factory. Returns nil if the GEOS CAPI implementation
|
@@ -19,17 +22,17 @@ module RGeo
|
|
19
22
|
|
20
23
|
def create(opts_ = {})
|
21
24
|
# Make sure GEOS is available
|
22
|
-
return
|
25
|
+
return unless respond_to?(:_create)
|
23
26
|
|
24
27
|
# Get flags to pass to the C extension
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
if
|
28
|
+
flags = 0
|
29
|
+
flags |= 1 if opts_[:uses_lenient_assertions] || opts_[:lenient_multi_polygon_assertions] || opts_[:uses_lenient_multi_polygon_assertions]
|
30
|
+
flags |= 2 if opts_[:has_z_coordinate]
|
31
|
+
flags |= 4 if opts_[:has_m_coordinate]
|
32
|
+
if flags & 6 == 6
|
30
33
|
raise Error::UnsupportedOperation, "GEOS cannot support both Z and M coordinates at the same time."
|
31
34
|
end
|
32
|
-
|
35
|
+
flags |= 8 unless opts_[:auto_prepare] == :disabled
|
33
36
|
|
34
37
|
# Buffer resolution
|
35
38
|
buffer_resolution_ = opts_[:buffer_resolution].to_i
|
@@ -40,7 +43,7 @@ module RGeo
|
|
40
43
|
case wkt_generator_
|
41
44
|
when :geos
|
42
45
|
wkt_generator_ = nil
|
43
|
-
when
|
46
|
+
when Hash
|
44
47
|
wkt_generator_ = WKRep::WKTGenerator.new(wkt_generator_)
|
45
48
|
else
|
46
49
|
wkt_generator_ = WKRep::WKTGenerator.new(convert_case: :upper)
|
@@ -49,7 +52,7 @@ module RGeo
|
|
49
52
|
case wkb_generator_
|
50
53
|
when :geos
|
51
54
|
wkb_generator_ = nil
|
52
|
-
when
|
55
|
+
when Hash
|
53
56
|
wkb_generator_ = WKRep::WKBGenerator.new(wkb_generator_)
|
54
57
|
else
|
55
58
|
wkb_generator_ = WKRep::WKBGenerator.new
|
@@ -59,19 +62,15 @@ module RGeo
|
|
59
62
|
srid_ = opts_[:srid]
|
60
63
|
proj4_ = opts_[:proj4]
|
61
64
|
if proj4_ && CoordSys.check!(:proj4)
|
62
|
-
if proj4_.is_a?(
|
65
|
+
if proj4_.is_a?(String) || proj4_.is_a?(Hash)
|
63
66
|
proj4_ = CoordSys::Proj4.create(proj4_)
|
64
67
|
end
|
65
68
|
else
|
66
69
|
proj4_ = nil
|
67
70
|
end
|
68
71
|
coord_sys_ = opts_[:coord_sys]
|
69
|
-
if coord_sys_.is_a?(
|
70
|
-
coord_sys_ =
|
71
|
-
CoordSys::CS.create_from_wkt(coord_sys_)
|
72
|
-
rescue
|
73
|
-
nil
|
74
|
-
end
|
72
|
+
if coord_sys_.is_a?(String)
|
73
|
+
coord_sys_ = CoordSys::CS.create_from_wkt(coord_sys_)
|
75
74
|
end
|
76
75
|
if (!proj4_ || !coord_sys_) && srid_ && (db_ = opts_[:srs_database])
|
77
76
|
entry_ = db_.get(srid_.to_i)
|
@@ -83,7 +82,7 @@ module RGeo
|
|
83
82
|
srid_ ||= coord_sys_.authority_code if coord_sys_
|
84
83
|
|
85
84
|
# Create the factory and set instance variables
|
86
|
-
|
85
|
+
result = _create(flags, srid_.to_i, buffer_resolution_,
|
87
86
|
wkt_generator_, wkb_generator_, proj4_, coord_sys_)
|
88
87
|
|
89
88
|
# Interpret parser options
|
@@ -91,24 +90,24 @@ module RGeo
|
|
91
90
|
case wkt_parser_
|
92
91
|
when :geos
|
93
92
|
wkt_parser_ = nil
|
94
|
-
when
|
95
|
-
wkt_parser_ = WKRep::WKTParser.new(
|
93
|
+
when Hash
|
94
|
+
wkt_parser_ = WKRep::WKTParser.new(result, wkt_parser_)
|
96
95
|
else
|
97
|
-
wkt_parser_ = WKRep::WKTParser.new(
|
96
|
+
wkt_parser_ = WKRep::WKTParser.new(result)
|
98
97
|
end
|
99
98
|
wkb_parser_ = opts_[:wkb_parser]
|
100
99
|
case wkb_parser_
|
101
100
|
when :geos
|
102
101
|
wkb_parser_ = nil
|
103
|
-
when
|
104
|
-
wkb_parser_ = WKRep::WKBParser.new(
|
102
|
+
when Hash
|
103
|
+
wkb_parser_ = WKRep::WKBParser.new(result, wkb_parser_)
|
105
104
|
else
|
106
|
-
wkb_parser_ = WKRep::WKBParser.new(
|
105
|
+
wkb_parser_ = WKRep::WKBParser.new(result)
|
107
106
|
end
|
108
|
-
|
107
|
+
result._set_wkrep_parsers(wkt_parser_, wkb_parser_)
|
109
108
|
|
110
109
|
# Return the result
|
111
|
-
|
110
|
+
result
|
112
111
|
end
|
113
112
|
alias new create
|
114
113
|
end
|
@@ -142,10 +141,10 @@ module RGeo
|
|
142
141
|
"hasm" => (_flags & 0x4 != 0),
|
143
142
|
"srid" => _srid,
|
144
143
|
"bufr" => _buffer_resolution,
|
145
|
-
"wktg" => _wkt_generator ? _wkt_generator.
|
146
|
-
"wkbg" => _wkb_generator ? _wkb_generator.
|
147
|
-
"wktp" => _wkt_parser ? _wkt_parser.
|
148
|
-
"wkbp" => _wkb_parser ? _wkb_parser.
|
144
|
+
"wktg" => _wkt_generator ? _wkt_generator.properties : {},
|
145
|
+
"wkbg" => _wkb_generator ? _wkb_generator.properties : {},
|
146
|
+
"wktp" => _wkt_parser ? _wkt_parser.properties : {},
|
147
|
+
"wkbp" => _wkb_parser ? _wkb_parser.properties : {},
|
149
148
|
"lmpa" => (_flags & 0x1 != 0),
|
150
149
|
"apre" => ((_flags & 0x8) >> 3)
|
151
150
|
}
|
@@ -170,20 +169,22 @@ module RGeo
|
|
170
169
|
else
|
171
170
|
coord_sys_ = nil
|
172
171
|
end
|
173
|
-
initialize_copy(
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
172
|
+
initialize_copy(
|
173
|
+
CAPIFactory.create(
|
174
|
+
has_z_coordinate: data_["hasz"],
|
175
|
+
has_m_coordinate: data_["hasm"],
|
176
|
+
srid: data_["srid"],
|
177
|
+
buffer_resolution: data_["bufr"],
|
178
|
+
wkt_generator: symbolize_hash(data_["wktg"]),
|
179
|
+
wkb_generator: symbolize_hash(data_["wkbg"]),
|
180
|
+
wkt_parser: symbolize_hash(data_["wktp"]),
|
181
|
+
wkb_parser: symbolize_hash(data_["wkbp"]),
|
182
|
+
uses_lenient_multi_polygon_assertions: data_["lmpa"],
|
183
|
+
auto_prepare: (data_["apre"] == 0 ? :disabled : :simple),
|
184
|
+
proj4: proj4_,
|
185
|
+
coord_sys: coord_sys_
|
186
|
+
)
|
187
|
+
)
|
187
188
|
end
|
188
189
|
|
189
190
|
# Psych support
|
@@ -194,10 +195,10 @@ module RGeo
|
|
194
195
|
coder_["srid"] = _srid
|
195
196
|
coder_["buffer_resolution"] = _buffer_resolution
|
196
197
|
coder_["lenient_multi_polygon_assertions"] = (_flags & 0x1 != 0)
|
197
|
-
coder_["wkt_generator"] = _wkt_generator ? _wkt_generator.
|
198
|
-
coder_["wkb_generator"] = _wkb_generator ? _wkb_generator.
|
199
|
-
coder_["wkt_parser"] = _wkt_parser ? _wkt_parser.
|
200
|
-
coder_["wkb_parser"] = _wkb_parser ? _wkb_parser.
|
198
|
+
coder_["wkt_generator"] = _wkt_generator ? _wkt_generator.properties : {}
|
199
|
+
coder_["wkb_generator"] = _wkb_generator ? _wkb_generator.properties : {}
|
200
|
+
coder_["wkt_parser"] = _wkt_parser ? _wkt_parser.properties : {}
|
201
|
+
coder_["wkb_parser"] = _wkb_parser ? _wkb_parser.properties : {}
|
201
202
|
coder_["auto_prepare"] = ((_flags & 0x8) == 0 ? "disabled" : "simple")
|
202
203
|
if (proj4_ = _proj4)
|
203
204
|
str_ = proj4_.original_str || proj4_.canonical_str
|
@@ -211,7 +212,7 @@ module RGeo
|
|
211
212
|
def init_with(coder_) # :nodoc:
|
212
213
|
if (proj4_data_ = coder_["proj4"])
|
213
214
|
CoordSys.check!(:proj4)
|
214
|
-
if proj4_data_.is_a?(
|
215
|
+
if proj4_data_.is_a?(Hash)
|
215
216
|
proj4_ = CoordSys::Proj4.create(proj4_data_["proj4"], radians: proj4_data_["radians"])
|
216
217
|
else
|
217
218
|
proj4_ = CoordSys::Proj4.create(proj4_data_.to_s)
|
@@ -224,20 +225,22 @@ module RGeo
|
|
224
225
|
else
|
225
226
|
coord_sys_ = nil
|
226
227
|
end
|
227
|
-
initialize_copy(
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
228
|
+
initialize_copy(
|
229
|
+
CAPIFactory.create(
|
230
|
+
has_z_coordinate: coder_["has_z_coordinate"],
|
231
|
+
has_m_coordinate: coder_["has_m_coordinate"],
|
232
|
+
srid: coder_["srid"],
|
233
|
+
buffer_resolution: coder_["buffer_resolution"],
|
234
|
+
wkt_generator: symbolize_hash(coder_["wkt_generator"]),
|
235
|
+
wkb_generator: symbolize_hash(coder_["wkb_generator"]),
|
236
|
+
wkt_parser: symbolize_hash(coder_["wkt_parser"]),
|
237
|
+
wkb_parser: symbolize_hash(coder_["wkb_parser"]),
|
238
|
+
auto_prepare: coder_["auto_prepare"] == "disabled" ? :disabled : :simple,
|
239
|
+
uses_lenient_multi_polygon_assertions: coder_["lenient_multi_polygon_assertions"],
|
240
|
+
proj4: proj4_,
|
241
|
+
coord_sys: coord_sys_
|
242
|
+
)
|
243
|
+
)
|
241
244
|
end
|
242
245
|
|
243
246
|
# Returns the SRID of geometries created by this factory.
|
@@ -302,99 +305,67 @@ module RGeo
|
|
302
305
|
|
303
306
|
def point(x_, y_, *extra_)
|
304
307
|
if extra_.length > (_flags & 6 == 0 ? 0 : 1)
|
305
|
-
|
308
|
+
raise(RGeo::Error::InvalidGeometry, "Parse error")
|
306
309
|
else
|
307
|
-
|
308
|
-
CAPIPointImpl.create(self, x_, y_, extra_[0].to_f)
|
309
|
-
rescue
|
310
|
-
nil
|
311
|
-
end
|
310
|
+
CAPIPointImpl.create(self, x_, y_, extra_[0].to_f)
|
312
311
|
end
|
313
312
|
end
|
314
313
|
|
315
314
|
# See RGeo::Feature::Factory#line_string
|
316
315
|
|
317
316
|
def line_string(points_)
|
318
|
-
points_ = points_.to_a unless points_.is_a?(
|
319
|
-
|
320
|
-
|
321
|
-
rescue
|
322
|
-
nil
|
323
|
-
end
|
317
|
+
points_ = points_.to_a unless points_.is_a?(Array)
|
318
|
+
CAPILineStringImpl.create(self, points_) ||
|
319
|
+
raise(RGeo::Error::InvalidGeometry, "Parse error")
|
324
320
|
end
|
325
321
|
|
326
322
|
# See RGeo::Feature::Factory#line
|
327
323
|
|
328
324
|
def line(start_, end_)
|
329
325
|
CAPILineImpl.create(self, start_, end_)
|
330
|
-
rescue
|
331
|
-
nil
|
332
326
|
end
|
333
327
|
|
334
328
|
# See RGeo::Feature::Factory#linear_ring
|
335
329
|
|
336
330
|
def linear_ring(points_)
|
337
|
-
points_ = points_.to_a unless points_.is_a?(
|
338
|
-
|
339
|
-
CAPILinearRingImpl.create(self, points_)
|
340
|
-
rescue
|
341
|
-
nil
|
342
|
-
end
|
331
|
+
points_ = points_.to_a unless points_.is_a?(Array)
|
332
|
+
CAPILinearRingImpl.create(self, points_)
|
343
333
|
end
|
344
334
|
|
345
335
|
# See RGeo::Feature::Factory#polygon
|
346
336
|
|
347
337
|
def polygon(outer_ring_, inner_rings_ = nil)
|
348
|
-
inner_rings_ = inner_rings_.to_a unless inner_rings_.is_a?(
|
349
|
-
|
350
|
-
CAPIPolygonImpl.create(self, outer_ring_, inner_rings_)
|
351
|
-
rescue
|
352
|
-
nil
|
353
|
-
end
|
338
|
+
inner_rings_ = inner_rings_.to_a unless inner_rings_.is_a?(Array)
|
339
|
+
CAPIPolygonImpl.create(self, outer_ring_, inner_rings_)
|
354
340
|
end
|
355
341
|
|
356
342
|
# See RGeo::Feature::Factory#collection
|
357
343
|
|
358
344
|
def collection(elems_)
|
359
|
-
elems_ = elems_.to_a unless elems_.is_a?(
|
360
|
-
|
361
|
-
CAPIGeometryCollectionImpl.create(self, elems_)
|
362
|
-
rescue
|
363
|
-
nil
|
364
|
-
end
|
345
|
+
elems_ = elems_.to_a unless elems_.is_a?(Array)
|
346
|
+
CAPIGeometryCollectionImpl.create(self, elems_)
|
365
347
|
end
|
366
348
|
|
367
349
|
# See RGeo::Feature::Factory#multi_point
|
368
350
|
|
369
351
|
def multi_point(elems_)
|
370
|
-
elems_ = elems_.to_a unless elems_.is_a?(
|
371
|
-
|
372
|
-
CAPIMultiPointImpl.create(self, elems_)
|
373
|
-
rescue
|
374
|
-
nil
|
375
|
-
end
|
352
|
+
elems_ = elems_.to_a unless elems_.is_a?(Array)
|
353
|
+
CAPIMultiPointImpl.create(self, elems_)
|
376
354
|
end
|
377
355
|
|
378
356
|
# See RGeo::Feature::Factory#multi_line_string
|
379
357
|
|
380
358
|
def multi_line_string(elems_)
|
381
|
-
elems_ = elems_.to_a unless elems_.is_a?(
|
382
|
-
|
383
|
-
CAPIMultiLineStringImpl.create(self, elems_)
|
384
|
-
rescue
|
385
|
-
nil
|
386
|
-
end
|
359
|
+
elems_ = elems_.to_a unless elems_.is_a?(Array)
|
360
|
+
CAPIMultiLineStringImpl.create(self, elems_)
|
387
361
|
end
|
388
362
|
|
389
363
|
# See RGeo::Feature::Factory#multi_polygon
|
390
364
|
|
391
365
|
def multi_polygon(elems_)
|
392
|
-
elems_ = elems_.to_a unless elems_.is_a?(
|
393
|
-
|
394
|
-
|
395
|
-
rescue
|
396
|
-
nil
|
397
|
-
end
|
366
|
+
elems_ = elems_.to_a unless elems_.is_a?(Array)
|
367
|
+
CAPIMultiPolygonImpl.create(self, elems_) ||
|
368
|
+
raise(RGeo::Error::InvalidGeometry, "Parse error")
|
398
369
|
end
|
399
370
|
|
400
371
|
# See RGeo::Feature::Factory#proj4
|
@@ -411,38 +382,38 @@ module RGeo
|
|
411
382
|
|
412
383
|
# See RGeo::Feature::Factory#override_cast
|
413
384
|
|
414
|
-
def override_cast(
|
415
|
-
return
|
416
|
-
|
417
|
-
# force_new_ =
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
case
|
385
|
+
def override_cast(original, ntype, flags)
|
386
|
+
return unless Geos.supported?
|
387
|
+
keep_subtype = flags[:keep_subtype]
|
388
|
+
# force_new_ = flags[:force_new]
|
389
|
+
project = flags[:project]
|
390
|
+
type = original.geometry_type
|
391
|
+
ntype = type if keep_subtype && type.include?(ntype)
|
392
|
+
case original
|
422
393
|
when CAPIGeometryMethods
|
423
394
|
# Optimization if we're just changing factories, but the
|
424
395
|
# factories are zm-compatible and proj4-compatible.
|
425
|
-
if
|
426
|
-
|
427
|
-
(!
|
428
|
-
|
429
|
-
|
430
|
-
return
|
396
|
+
if original.factory != self && ntype == type &&
|
397
|
+
original.factory._flags & 0x6 == _flags & 0x6 &&
|
398
|
+
(!project || original.factory.proj4 == _proj4)
|
399
|
+
result = original.dup
|
400
|
+
result.factory = self
|
401
|
+
return result
|
431
402
|
end
|
432
403
|
# LineString conversion optimization.
|
433
|
-
if (
|
434
|
-
|
435
|
-
(!
|
436
|
-
|
437
|
-
return IMPL_CLASSES[
|
404
|
+
if (original.factory != self || ntype != type) &&
|
405
|
+
original.factory._flags & 0x6 == _flags & 0x6 &&
|
406
|
+
(!project || original.factory.proj4 == _proj4) &&
|
407
|
+
type.subtype_of?(Feature::LineString) && ntype.subtype_of?(Feature::LineString)
|
408
|
+
return IMPL_CLASSES[ntype]._copy_from(self, original)
|
438
409
|
end
|
439
410
|
when ZMGeometryMethods
|
440
411
|
# Optimization for just removing a coordinate from an otherwise
|
441
412
|
# compatible factory
|
442
|
-
if _flags & 0x6 == 0x2 && self ==
|
443
|
-
return Feature.cast(
|
444
|
-
elsif _flags & 0x6 == 0x4 && self ==
|
445
|
-
return Feature.cast(
|
413
|
+
if _flags & 0x6 == 0x2 && self == original.factory.z_factory
|
414
|
+
return Feature.cast(original.z_geometry, ntype, flags)
|
415
|
+
elsif _flags & 0x6 == 0x4 && self == original.factory.m_factory
|
416
|
+
return Feature.cast(original.m_geometry, ntype, flags)
|
446
417
|
end
|
447
418
|
end
|
448
419
|
false
|