rgeo 0.1.13 → 0.1.14
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 +11 -0
- data/Version +1 -1
- data/ext/geos_c_impl/factory.c +35 -40
- data/ext/geos_c_impl/factory.h +4 -1
- data/ext/geos_c_impl/geometry_collection.c +5 -5
- data/ext/geos_c_impl/geometry_collection.h +1 -1
- data/ext/geos_c_impl/line_string.c +129 -116
- data/ext/geos_c_impl/point.c +22 -33
- data/ext/geos_c_impl/point.h +1 -6
- data/ext/geos_c_impl/polygon.c +4 -4
- data/ext/geos_c_impl/polygon.h +1 -1
- data/lib/rgeo.rb +1 -0
- data/lib/rgeo/cartesian/simple_factory.rb +20 -4
- data/lib/rgeo/errors.rb +8 -0
- data/lib/rgeo/features/factory.rb +35 -1
- data/lib/rgeo/features/point.rb +22 -0
- data/lib/rgeo/features/polygon.rb +1 -2
- data/lib/rgeo/features/types.rb +70 -16
- data/lib/rgeo/geography/factories.rb +40 -3
- data/lib/rgeo/geography/factory.rb +25 -5
- data/lib/rgeo/geography/simple_mercator/feature_methods.rb +2 -6
- data/lib/rgeo/geography/simple_mercator/projector.rb +1 -1
- data/lib/rgeo/geos/factory.rb +40 -46
- data/lib/rgeo/geos/interface.rb +10 -0
- data/lib/rgeo/impl_helpers.rb +0 -1
- data/lib/rgeo/impl_helpers/basic_geometry_methods.rb +2 -2
- data/lib/rgeo/impl_helpers/basic_point_methods.rb +12 -14
- data/lib/rgeo/wkrep.rb +59 -0
- data/lib/rgeo/wkrep/wkb_generator.rb +181 -0
- data/lib/rgeo/wkrep/wkb_parser.rb +205 -0
- data/lib/rgeo/wkrep/wkt_generator.rb +187 -0
- data/lib/rgeo/wkrep/wkt_parser.rb +321 -0
- data/tests/common/line_string_tests.rb +26 -2
- data/tests/common/point_tests.rb +26 -0
- data/tests/geos/tc_point.rb +1 -20
- data/tests/simple_cartesian/tc_point.rb +1 -0
- data/tests/simple_mercator/tc_point.rb +1 -0
- data/tests/simple_spherical/tc_point.rb +1 -0
- data/tests/tc_oneoff.rb +3 -2
- metadata +8 -4
- data/lib/rgeo/impl_helpers/serialization.rb +0 -130
@@ -71,9 +71,36 @@ module RGeo
|
|
71
71
|
# may generate slightly different results from geodesic calculations
|
72
72
|
# than those generated by, e.g., PostGIS (unless you direct PostGIS
|
73
73
|
# to use spherical geodesics).
|
74
|
+
#
|
75
|
+
# Options include:
|
76
|
+
#
|
77
|
+
# <tt>:lenient_multi_polygon_assertions</tt>::
|
78
|
+
# If set to true, assertion checking on MultiPolygon is disabled.
|
79
|
+
# This may speed up creation of MultiPolygon objects, at the
|
80
|
+
# expense of not doing the proper checking for OGC MultiPolygon
|
81
|
+
# compliance. See RGeo::Features::MultiPolygon for details on
|
82
|
+
# the MultiPolygon assertions. Default is false.
|
83
|
+
# <tt>:buffer_resolution</tt>::
|
84
|
+
# The resolution of buffers around geometries created by this
|
85
|
+
# factory. This controls the number of line segments used to
|
86
|
+
# approximate curves. The default is 1, which causes, for
|
87
|
+
# example, the buffer around a point to be approximated by a
|
88
|
+
# 4-sided polygon. A resolution of 2 would cause that buffer
|
89
|
+
# to be approximated by an 8-sided polygon. The exact behavior
|
90
|
+
# for different kinds of buffers is defined by GEOS.
|
91
|
+
# <tt>:support_z_coordinate</tt>::
|
92
|
+
# Support <tt>z_coordinate</tt>. Default is false.
|
93
|
+
# Note that simple_mercator factories cannot support both
|
94
|
+
# <tt>z_coordinate</tt> and <tt>m_coordinate</tt>. They may at
|
95
|
+
# most support one or the other.
|
96
|
+
# <tt>:support_m_coordinate</tt>::
|
97
|
+
# Support <tt>m_coordinate</tt>. Default is false.
|
98
|
+
# Note that simple_mercator factories cannot support both
|
99
|
+
# <tt>z_coordinate</tt> and <tt>m_coordinate</tt>. They may at
|
100
|
+
# most support one or the other.
|
74
101
|
|
75
102
|
def simple_spherical(opts_={})
|
76
|
-
Geography::Factory.new(Geography::SimpleSpherical)
|
103
|
+
Geography::Factory.new(Geography::SimpleSpherical, :support_z_coordinate => opts_[:support_z_coordinate], :support_m_coordinate => opts_[:support_m_coordinate])
|
77
104
|
end
|
78
105
|
|
79
106
|
|
@@ -121,7 +148,7 @@ module RGeo
|
|
121
148
|
# visualization APIs, so we've decided to fudge on this in the
|
122
149
|
# interest of being true to our expected application use cases.
|
123
150
|
#
|
124
|
-
#
|
151
|
+
# Options include:
|
125
152
|
#
|
126
153
|
# <tt>:lenient_multi_polygon_assertions</tt>::
|
127
154
|
# If set to true, assertion checking on MultiPolygon is disabled.
|
@@ -137,9 +164,19 @@ module RGeo
|
|
137
164
|
# 4-sided polygon. A resolution of 2 would cause that buffer
|
138
165
|
# to be approximated by an 8-sided polygon. The exact behavior
|
139
166
|
# for different kinds of buffers is defined by GEOS.
|
167
|
+
# <tt>:support_z_coordinate</tt>::
|
168
|
+
# Support <tt>z_coordinate</tt>. Default is false.
|
169
|
+
# Note that simple_mercator factories cannot support both
|
170
|
+
# <tt>z_coordinate</tt> and <tt>m_coordinate</tt>. They may at
|
171
|
+
# most support one or the other.
|
172
|
+
# <tt>:support_m_coordinate</tt>::
|
173
|
+
# Support <tt>m_coordinate</tt>. Default is false.
|
174
|
+
# Note that simple_mercator factories cannot support both
|
175
|
+
# <tt>z_coordinate</tt> and <tt>m_coordinate</tt>. They may at
|
176
|
+
# most support one or the other.
|
140
177
|
|
141
178
|
def simple_mercator(opts_={})
|
142
|
-
Geography::Factory.new(Geography::SimpleMercator, :buffer_resolution => opts_[:buffer_resolution], :lenient_multi_polygon_assertions => opts_[:lenient_multi_polygon_assertions])
|
179
|
+
Geography::Factory.new(Geography::SimpleMercator, :buffer_resolution => opts_[:buffer_resolution], :lenient_multi_polygon_assertions => opts_[:lenient_multi_polygon_assertions], :support_z_coordinate => opts_[:support_z_coordinate], :support_m_coordinate => opts_[:support_m_coordinate])
|
143
180
|
end
|
144
181
|
|
145
182
|
|
@@ -51,7 +51,13 @@ module RGeo
|
|
51
51
|
def initialize(namespace_, opts_={}) # :nodoc:
|
52
52
|
@namespace = namespace_
|
53
53
|
@opts = opts_.dup
|
54
|
-
|
54
|
+
if @namespace.const_defined?(:Projector)
|
55
|
+
@projector = @namespace.const_get(:Projector).new(self, opts_)
|
56
|
+
else
|
57
|
+
@projector = nil
|
58
|
+
end
|
59
|
+
@support_z = opts_[:support_z_coordinate] ? true : false
|
60
|
+
@support_m = opts_[:support_m_coordinate] ? true : false
|
55
61
|
end
|
56
62
|
|
57
63
|
|
@@ -126,24 +132,38 @@ module RGeo
|
|
126
132
|
end
|
127
133
|
|
128
134
|
|
135
|
+
# See ::RGeo::Features::Factory#has_capability?
|
136
|
+
|
137
|
+
def has_capability?(name_)
|
138
|
+
case name_
|
139
|
+
when :z_coordinate
|
140
|
+
@support_z
|
141
|
+
when :m_coordinate
|
142
|
+
@support_m
|
143
|
+
else
|
144
|
+
nil
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
|
129
149
|
# See ::RGeo::Features::Factory#parse_wkt
|
130
150
|
|
131
151
|
def parse_wkt(str_)
|
132
|
-
|
152
|
+
WKRep::WKTParser.new(self, :support_higher_dimensions => true).parse(str_)
|
133
153
|
end
|
134
154
|
|
135
155
|
|
136
156
|
# See ::RGeo::Features::Factory#parse_wkb
|
137
157
|
|
138
158
|
def parse_wkb(str_)
|
139
|
-
|
159
|
+
WKRep::WKBParser.new(self).parse(str_)
|
140
160
|
end
|
141
161
|
|
142
162
|
|
143
163
|
# See ::RGeo::Features::Factory#point
|
144
164
|
|
145
|
-
def point(x_, y_)
|
146
|
-
@namespace.const_get(:PointImpl).new(self, x_, y_) rescue nil
|
165
|
+
def point(x_, y_, *extra_)
|
166
|
+
@namespace.const_get(:PointImpl).new(self, x_, y_, *extra_) rescue nil
|
147
167
|
end
|
148
168
|
|
149
169
|
|
@@ -50,13 +50,9 @@ module RGeo
|
|
50
50
|
|
51
51
|
|
52
52
|
def projection
|
53
|
-
|
53
|
+
if @projection.nil?
|
54
54
|
projection_factory_ = @factory.projection_factory
|
55
|
-
|
56
|
-
@projection = _make_projection(projection_factory_)
|
57
|
-
else
|
58
|
-
@projection = nil
|
59
|
-
end
|
55
|
+
@projection = projection_factory_ ? _make_projection(projection_factory_) : nil
|
60
56
|
@projection = false unless @projection
|
61
57
|
end
|
62
58
|
@projection ? @projection : nil
|
@@ -48,7 +48,7 @@ module RGeo
|
|
48
48
|
|
49
49
|
def initialize(geography_factory_, opts_={})
|
50
50
|
@geography_factory = geography_factory_
|
51
|
-
@projection_factory = Cartesian.preferred_factory(:srid => 3857, :buffer_resolution => opts_[:buffer_resolution], :lenient_multi_polygon_assertions => opts_[:lenient_multi_polygon_assertions])
|
51
|
+
@projection_factory = Cartesian.preferred_factory(:srid => 3857, :buffer_resolution => opts_[:buffer_resolution], :lenient_multi_polygon_assertions => opts_[:lenient_multi_polygon_assertions], :support_z_coordinate => opts_[:support_z_coordinate], :support_m_coordinate => opts_[:support_m_coordinate])
|
52
52
|
end
|
53
53
|
|
54
54
|
|
data/lib/rgeo/geos/factory.rb
CHANGED
@@ -52,30 +52,17 @@ module RGeo
|
|
52
52
|
# Create a new factory. Returns nil if the GEOS implementation is
|
53
53
|
# not supported.
|
54
54
|
#
|
55
|
-
#
|
56
|
-
#
|
57
|
-
# <tt>:lenient_multi_polygon_assertions</tt>::
|
58
|
-
# If set to true, assertion checking on MultiPolygon is disabled.
|
59
|
-
# This may speed up creation of MultiPolygon objects, at the
|
60
|
-
# expense of not doing the proper checking for OGC MultiPolygon
|
61
|
-
# compliance. See RGeo::Features::MultiPolygon for details on
|
62
|
-
# the MultiPolygon assertions. Default is false.
|
63
|
-
# <tt>:buffer_resolution</tt>::
|
64
|
-
# The resolution of buffers around geometries created by this
|
65
|
-
# factory. This controls the number of line segments used to
|
66
|
-
# approximate curves. The default is 1, which causes, for
|
67
|
-
# example, the buffer around a point to be approximated by a
|
68
|
-
# 4-sided polygon. A resolution of 2 would cause that buffer
|
69
|
-
# to be approximated by an 8-sided polygon. The exact behavior
|
70
|
-
# for different kinds of buffers is defined by GEOS.
|
71
|
-
# <tt>:srid</tt>::
|
72
|
-
# Set the SRID returned by geometries created by this factory.
|
73
|
-
# Default is 0.
|
55
|
+
# See ::RGeo::Geos::factory for a list of supported options.
|
74
56
|
|
75
57
|
def create(opts_={})
|
76
58
|
return nil unless respond_to?(:_create)
|
77
59
|
flags_ = 0
|
78
60
|
flags_ |= 1 if opts_[:lenient_multi_polygon_assertions]
|
61
|
+
flags_ |= 2 if opts_[:support_z_coordinate]
|
62
|
+
flags_ |= 4 if opts_[:support_m_coordinate]
|
63
|
+
if flags_ & 6 == 6
|
64
|
+
raise Errors::UnsupportedCapability, "GEOS cannot support both Z and M coordinates at the same time."
|
65
|
+
end
|
79
66
|
buffer_resolution_ = opts_[:buffer_resolution].to_i
|
80
67
|
buffer_resolution_ = 1 if buffer_resolution_ < 1
|
81
68
|
_create(flags_, opts_[:srid].to_i, buffer_resolution_)
|
@@ -116,6 +103,20 @@ module RGeo
|
|
116
103
|
alias_method :==, :eql?
|
117
104
|
|
118
105
|
|
106
|
+
# See ::RGeo::Features::Factory#has_capability?
|
107
|
+
|
108
|
+
def has_capability?(name_)
|
109
|
+
case name_
|
110
|
+
when :z_coordinate
|
111
|
+
_flags & 0x2 != 0
|
112
|
+
when :m_coordinate
|
113
|
+
_flags & 0x4 != 0
|
114
|
+
else
|
115
|
+
nil
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
|
119
120
|
# See ::RGeo::Features::Factory#parse_wkt
|
120
121
|
|
121
122
|
def parse_wkt(str_)
|
@@ -132,8 +133,12 @@ module RGeo
|
|
132
133
|
|
133
134
|
# See ::RGeo::Features::Factory#point
|
134
135
|
|
135
|
-
def point(x_, y_)
|
136
|
-
|
136
|
+
def point(x_, y_, *extra_)
|
137
|
+
if extra_.length > (_flags & 6 == 0 ? 0 : 1)
|
138
|
+
nil
|
139
|
+
else
|
140
|
+
PointImpl.create(self, x_, y_, extra_[0].to_f) rescue nil
|
141
|
+
end
|
137
142
|
end
|
138
143
|
|
139
144
|
|
@@ -204,41 +209,30 @@ module RGeo
|
|
204
209
|
|
205
210
|
def override_cast(original_, ntype_, keep_subtype_, force_new_)
|
206
211
|
return nil unless Geos.supported?
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
if
|
212
|
+
if GeometryImpl === original_
|
213
|
+
type_ = original_.geometry_type
|
214
|
+
ntype_ = type_ if keep_subtype_ && type_.include?(ntype_)
|
215
|
+
if original_.factory != self && ntype_ == type_
|
211
216
|
result_ = original_.dup
|
212
217
|
result_._set_factory(self)
|
213
218
|
return result_
|
214
219
|
end
|
215
|
-
if
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
elsif ntype_ == Features::Line
|
226
|
-
return LineImpl._copy_from(self, original_)
|
227
|
-
elsif ntype_ == Features::LinearRing
|
228
|
-
return LinearRingImpl._copy_from(self, original_)
|
220
|
+
if (original_.factory != self || ntype_ != type_) &&
|
221
|
+
(type_ == Features::LineString || type_.include?(Features::LineString))
|
222
|
+
then
|
223
|
+
if ntype_ == Features::LineString
|
224
|
+
return LineStringImpl._copy_from(self, original_)
|
225
|
+
elsif ntype_ == Features::Line
|
226
|
+
return LineImpl._copy_from(self, original_)
|
227
|
+
elsif ntype_ == Features::LinearRing
|
228
|
+
return LinearRingImpl._copy_from(self, original_)
|
229
|
+
end
|
229
230
|
end
|
230
231
|
end
|
231
232
|
false
|
232
233
|
end
|
233
234
|
|
234
235
|
|
235
|
-
# A GEOS extension that creates a 3-D point with a Z coordinate.
|
236
|
-
|
237
|
-
def point3d(x_, y_, z_)
|
238
|
-
PointImpl.create3d(self, x_, y_, z_) rescue nil
|
239
|
-
end
|
240
|
-
|
241
|
-
|
242
236
|
end
|
243
237
|
|
244
238
|
|
data/lib/rgeo/geos/interface.rb
CHANGED
@@ -81,6 +81,16 @@ module RGeo
|
|
81
81
|
# <tt>:srid</tt>::
|
82
82
|
# Set the SRID returned by geometries created by this factory.
|
83
83
|
# Default is 0.
|
84
|
+
# <tt>:support_z_coordinate</tt>::
|
85
|
+
# Support <tt>z_coordinate</tt>. Default is false.
|
86
|
+
# Note that GEOS factories cannot support both
|
87
|
+
# <tt>z_coordinate</tt> and <tt>m_coordinate</tt>. They may at
|
88
|
+
# most support one or the other.
|
89
|
+
# <tt>:support_m_coordinate</tt>::
|
90
|
+
# Support <tt>m_coordinate</tt>. Default is false.
|
91
|
+
# Note that GEOS factories cannot support both
|
92
|
+
# <tt>z_coordinate</tt> and <tt>m_coordinate</tt>. They may at
|
93
|
+
# most support one or the other.
|
84
94
|
|
85
95
|
def factory(opts_={})
|
86
96
|
supported? ? Factory.create(opts_) : nil
|
data/lib/rgeo/impl_helpers.rb
CHANGED
@@ -42,10 +42,12 @@ module RGeo
|
|
42
42
|
module BasicPointMethods # :nodoc:
|
43
43
|
|
44
44
|
|
45
|
-
def initialize(factory_, x_, y_)
|
45
|
+
def initialize(factory_, x_, y_, *extra_)
|
46
46
|
_set_factory(factory_)
|
47
47
|
@x = x_.to_f
|
48
48
|
@y = y_.to_f
|
49
|
+
@z = factory_.has_capability?(:z_coordinate) ? extra_.shift.to_f : nil
|
50
|
+
@m = factory_.has_capability?(:m_coordinate) ? extra_.shift.to_f : nil
|
49
51
|
_validate_geometry
|
50
52
|
end
|
51
53
|
|
@@ -60,22 +62,18 @@ module RGeo
|
|
60
62
|
end
|
61
63
|
|
62
64
|
|
63
|
-
def
|
64
|
-
|
65
|
+
def z
|
66
|
+
@z
|
65
67
|
end
|
66
68
|
|
67
69
|
|
68
|
-
def
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
factory.multi_point([self]) rescue nil
|
76
|
-
else
|
77
|
-
super
|
78
|
-
end
|
70
|
+
def m
|
71
|
+
@m
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
def eql?(rhs_)
|
76
|
+
rhs_.is_a?(self.class) && rhs_.factory.eql?(@factory) && @x == rhs_.x && @y == rhs_.y && @z == rhs_.z && @m == rhs_.m
|
79
77
|
end
|
80
78
|
|
81
79
|
|
data/lib/rgeo/wkrep.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Well-known representation for RGeo
|
4
|
+
#
|
5
|
+
# -----------------------------------------------------------------------------
|
6
|
+
# Copyright 2010 Daniel Azuma
|
7
|
+
#
|
8
|
+
# All rights reserved.
|
9
|
+
#
|
10
|
+
# Redistribution and use in source and binary forms, with or without
|
11
|
+
# modification, are permitted provided that the following conditions are met:
|
12
|
+
#
|
13
|
+
# * Redistributions of source code must retain the above copyright notice,
|
14
|
+
# this list of conditions and the following disclaimer.
|
15
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
16
|
+
# this list of conditions and the following disclaimer in the documentation
|
17
|
+
# and/or other materials provided with the distribution.
|
18
|
+
# * Neither the name of the copyright holder, nor the names of any other
|
19
|
+
# contributors to this software, may be used to endorse or promote products
|
20
|
+
# derived from this software without specific prior written permission.
|
21
|
+
#
|
22
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
23
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
24
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
25
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
26
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
27
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
28
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
29
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
30
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
31
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
32
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
33
|
+
# -----------------------------------------------------------------------------
|
34
|
+
;
|
35
|
+
|
36
|
+
|
37
|
+
module RGeo
|
38
|
+
|
39
|
+
|
40
|
+
# Implementations of the OpenGIS well-known representation
|
41
|
+
# (i.e. the WKT/WKB) and its variants (e.g. the EWKT/EWKB used by
|
42
|
+
# PostGIS). Provides generation and parsing facilities.
|
43
|
+
|
44
|
+
module WKRep
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
# Dependency source files.
|
52
|
+
paths_ = [
|
53
|
+
'features',
|
54
|
+
'wkrep/wkt_parser',
|
55
|
+
'wkrep/wkt_generator',
|
56
|
+
'wkrep/wkb_parser',
|
57
|
+
'wkrep/wkb_generator',
|
58
|
+
]
|
59
|
+
paths_.each{ |path_| require "rgeo/#{path_}" }
|
@@ -0,0 +1,181 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Well-known binary generator for RGeo
|
4
|
+
#
|
5
|
+
# -----------------------------------------------------------------------------
|
6
|
+
# Copyright 2010 Daniel Azuma
|
7
|
+
#
|
8
|
+
# All rights reserved.
|
9
|
+
#
|
10
|
+
# Redistribution and use in source and binary forms, with or without
|
11
|
+
# modification, are permitted provided that the following conditions are met:
|
12
|
+
#
|
13
|
+
# * Redistributions of source code must retain the above copyright notice,
|
14
|
+
# this list of conditions and the following disclaimer.
|
15
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
16
|
+
# this list of conditions and the following disclaimer in the documentation
|
17
|
+
# and/or other materials provided with the distribution.
|
18
|
+
# * Neither the name of the copyright holder, nor the names of any other
|
19
|
+
# contributors to this software, may be used to endorse or promote products
|
20
|
+
# derived from this software without specific prior written permission.
|
21
|
+
#
|
22
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
23
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
24
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
25
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
26
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
27
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
28
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
29
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
30
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
31
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
32
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
33
|
+
# -----------------------------------------------------------------------------
|
34
|
+
;
|
35
|
+
|
36
|
+
|
37
|
+
module RGeo
|
38
|
+
|
39
|
+
module WKRep
|
40
|
+
|
41
|
+
|
42
|
+
class WKBGenerator
|
43
|
+
|
44
|
+
|
45
|
+
TYPE_CODES = {
|
46
|
+
Features::Point => 1,
|
47
|
+
Features::LineString => 2,
|
48
|
+
Features::LinearRing => 2,
|
49
|
+
Features::Line => 2,
|
50
|
+
Features::Polygon => 3,
|
51
|
+
Features::MultiPoint => 4,
|
52
|
+
Features::MultiLineString => 5,
|
53
|
+
Features::MultiPolygon => 6,
|
54
|
+
Features::GeometryCollection => 7,
|
55
|
+
}
|
56
|
+
|
57
|
+
|
58
|
+
def initialize(opts_={})
|
59
|
+
@type_format = opts_[:type_format]
|
60
|
+
@emit_ewkb_srid = opts_[:emit_ewkb_srid] if @type_format == :ewkb
|
61
|
+
@hex_format = opts_[:hex_format]
|
62
|
+
@little_endian = opts_[:little_endian]
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
def generate(obj_)
|
67
|
+
factory_ = obj_.factory
|
68
|
+
if @type_format == :ewkb || @type_format == :wkb12
|
69
|
+
@cur_has_z = factory_.has_capability?(:z_coordinate)
|
70
|
+
@cur_has_m = factory_.has_capability?(:m_coordinate)
|
71
|
+
else
|
72
|
+
@cur_has_z = nil
|
73
|
+
@cur_has_m = nil
|
74
|
+
end
|
75
|
+
@cur_dims = 2 + (@cur_has_z ? 1 : 0) + (@cur_has_m ? 1 : 0)
|
76
|
+
_start_emitter
|
77
|
+
_generate_feature(obj_, true)
|
78
|
+
_finish_emitter
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
def _generate_feature(obj_, toplevel_=false) # :nodoc:
|
83
|
+
_emit_byte(@little_endian ? 1 : 0)
|
84
|
+
type_ = obj_.geometry_type
|
85
|
+
type_code_ = TYPE_CODES[type_]
|
86
|
+
unless type_code_
|
87
|
+
raise Errors::ParseError, "Unrecognized Geometry Type: #{type_}"
|
88
|
+
end
|
89
|
+
emit_srid_ = false
|
90
|
+
if @emit_ewkb_srid && toplevel_
|
91
|
+
type_code |= 0x20000000
|
92
|
+
emit_srid_ = true
|
93
|
+
end
|
94
|
+
if @type_format == :ewkb
|
95
|
+
type_code_ |= 0x80000000 if @cur_has_z
|
96
|
+
type_code_ |= 0x40000000 if @cur_has_m
|
97
|
+
elsif @type_format == :wkb12
|
98
|
+
type_code_ += 1000 if @cur_has_z
|
99
|
+
type_code_ += 2000 if @cur_has_m
|
100
|
+
end
|
101
|
+
_emit_integer(type_code_)
|
102
|
+
_emit_integer(obj_.srid) if emit_srid_
|
103
|
+
if type_ == Features::Point
|
104
|
+
_emit_doubles(_point_coords(obj_))
|
105
|
+
elsif type_.subtype_of?(Features::LineString)
|
106
|
+
_emit_line_string_coords(obj_)
|
107
|
+
elsif type_ == Features::Polygon
|
108
|
+
exterior_ring_ = obj_.exterior_ring
|
109
|
+
if exterior_ring_.is_empty?
|
110
|
+
_emit_integer(0)
|
111
|
+
else
|
112
|
+
_emit_integer(1 + obj_.num_interior_rings)
|
113
|
+
_emit_line_string_coords(exterior_ring_)
|
114
|
+
obj_.interior_rings.each{ |r_| _emit_line_string_coords(r_) }
|
115
|
+
end
|
116
|
+
elsif type_ == Features::GeometryCollection
|
117
|
+
_emit_integer(obj_.num_geometries)
|
118
|
+
obj_.each{ |g_| _generate_feature(g_) }
|
119
|
+
elsif type_ == Features::MultiPoint
|
120
|
+
_emit_integer(obj_.num_geometries)
|
121
|
+
obj_.each{ |g_| _generate_feature(g_) }
|
122
|
+
elsif type_ == Features::MultiLineString
|
123
|
+
_emit_integer(obj_.num_geometries)
|
124
|
+
obj_.each{ |g_| _generate_feature(g_) }
|
125
|
+
elsif type_ == Features::MultiPolygon
|
126
|
+
_emit_integer(obj_.num_geometries)
|
127
|
+
obj_.each{ |g_| _generate_feature(g_) }
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
|
132
|
+
def _point_coords(obj_, array_=[]) # :nodoc:
|
133
|
+
array_ << obj_.x
|
134
|
+
array_ << obj_.y
|
135
|
+
array_ << obj_.z if @cur_has_z
|
136
|
+
array_ << obj_.m if @cur_has_m
|
137
|
+
array_
|
138
|
+
end
|
139
|
+
|
140
|
+
|
141
|
+
def _emit_line_string_coords(obj_) # :nodoc:
|
142
|
+
array_ = []
|
143
|
+
obj_.points.each{ |p_| _point_coords(p_, array_) }
|
144
|
+
_emit_integer(obj_.num_points)
|
145
|
+
_emit_doubles(array_)
|
146
|
+
end
|
147
|
+
|
148
|
+
|
149
|
+
def _start_emitter # :nodoc:
|
150
|
+
@cur_array = []
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
def _emit_byte(value_) # :nodoc:
|
155
|
+
@cur_array << [value_].pack("C")
|
156
|
+
end
|
157
|
+
|
158
|
+
|
159
|
+
def _emit_integer(value_) # :nodoc:
|
160
|
+
@cur_array << [value_].pack(@little_endian ? 'V' : 'N')
|
161
|
+
end
|
162
|
+
|
163
|
+
|
164
|
+
def _emit_doubles(array_) # :nodoc:
|
165
|
+
@cur_array << array_.pack(@little_endian ? 'E*' : 'G*')
|
166
|
+
end
|
167
|
+
|
168
|
+
|
169
|
+
def _finish_emitter # :nodoc:
|
170
|
+
str_ = @cur_array.join
|
171
|
+
@cur_array = nil
|
172
|
+
str_
|
173
|
+
end
|
174
|
+
|
175
|
+
|
176
|
+
end
|
177
|
+
|
178
|
+
|
179
|
+
end
|
180
|
+
|
181
|
+
end
|