schleyfox-rgeo 0.2.5
Sign up to get free protection for your applications and to get access to all the features.
- data/History.rdoc +199 -0
- data/README.rdoc +172 -0
- data/Spatial_Programming_With_RGeo.rdoc +440 -0
- data/Version +1 -0
- data/ext/geos_c_impl/extconf.rb +84 -0
- data/ext/geos_c_impl/factory.c +468 -0
- data/ext/geos_c_impl/factory.h +224 -0
- data/ext/geos_c_impl/geometry.c +705 -0
- data/ext/geos_c_impl/geometry.h +55 -0
- data/ext/geos_c_impl/geometry_collection.c +482 -0
- data/ext/geos_c_impl/geometry_collection.h +69 -0
- data/ext/geos_c_impl/line_string.c +509 -0
- data/ext/geos_c_impl/line_string.h +64 -0
- data/ext/geos_c_impl/main.c +70 -0
- data/ext/geos_c_impl/point.c +193 -0
- data/ext/geos_c_impl/point.h +62 -0
- data/ext/geos_c_impl/polygon.c +265 -0
- data/ext/geos_c_impl/polygon.h +66 -0
- data/ext/geos_c_impl/preface.h +50 -0
- data/ext/proj4_c_impl/extconf.rb +88 -0
- data/ext/proj4_c_impl/main.c +271 -0
- data/lib/rgeo.rb +124 -0
- data/lib/rgeo/cartesian.rb +60 -0
- data/lib/rgeo/cartesian/analysis.rb +118 -0
- data/lib/rgeo/cartesian/bounding_box.rb +337 -0
- data/lib/rgeo/cartesian/calculations.rb +161 -0
- data/lib/rgeo/cartesian/factory.rb +209 -0
- data/lib/rgeo/cartesian/feature_classes.rb +173 -0
- data/lib/rgeo/cartesian/feature_methods.rb +106 -0
- data/lib/rgeo/cartesian/interface.rb +150 -0
- data/lib/rgeo/coord_sys.rb +79 -0
- data/lib/rgeo/coord_sys/cs/entities.rb +1524 -0
- data/lib/rgeo/coord_sys/cs/factories.rb +208 -0
- data/lib/rgeo/coord_sys/cs/wkt_parser.rb +308 -0
- data/lib/rgeo/coord_sys/proj4.rb +312 -0
- data/lib/rgeo/coord_sys/srs_database/active_record_table.rb +194 -0
- data/lib/rgeo/coord_sys/srs_database/interface.rb +165 -0
- data/lib/rgeo/coord_sys/srs_database/proj4_data.rb +188 -0
- data/lib/rgeo/coord_sys/srs_database/sr_org.rb +108 -0
- data/lib/rgeo/coord_sys/srs_database/url_reader.rb +108 -0
- data/lib/rgeo/error.rb +63 -0
- data/lib/rgeo/feature.rb +88 -0
- data/lib/rgeo/feature/curve.rb +156 -0
- data/lib/rgeo/feature/factory.rb +332 -0
- data/lib/rgeo/feature/factory_generator.rb +138 -0
- data/lib/rgeo/feature/geometry.rb +614 -0
- data/lib/rgeo/feature/geometry_collection.rb +129 -0
- data/lib/rgeo/feature/line.rb +66 -0
- data/lib/rgeo/feature/line_string.rb +102 -0
- data/lib/rgeo/feature/linear_ring.rb +66 -0
- data/lib/rgeo/feature/multi_curve.rb +113 -0
- data/lib/rgeo/feature/multi_line_string.rb +66 -0
- data/lib/rgeo/feature/multi_point.rb +73 -0
- data/lib/rgeo/feature/multi_polygon.rb +97 -0
- data/lib/rgeo/feature/multi_surface.rb +116 -0
- data/lib/rgeo/feature/point.rb +120 -0
- data/lib/rgeo/feature/polygon.rb +141 -0
- data/lib/rgeo/feature/surface.rb +122 -0
- data/lib/rgeo/feature/types.rb +305 -0
- data/lib/rgeo/geographic.rb +75 -0
- data/lib/rgeo/geographic/factory.rb +287 -0
- data/lib/rgeo/geographic/interface.rb +410 -0
- data/lib/rgeo/geographic/proj4_projector.rb +98 -0
- data/lib/rgeo/geographic/projected_feature_classes.rb +213 -0
- data/lib/rgeo/geographic/projected_feature_methods.rb +228 -0
- data/lib/rgeo/geographic/projected_window.rb +467 -0
- data/lib/rgeo/geographic/simple_mercator_projector.rb +157 -0
- data/lib/rgeo/geographic/spherical_feature_classes.rb +212 -0
- data/lib/rgeo/geographic/spherical_feature_methods.rb +97 -0
- data/lib/rgeo/geographic/spherical_math.rb +206 -0
- data/lib/rgeo/geos.rb +72 -0
- data/lib/rgeo/geos/factory.rb +301 -0
- data/lib/rgeo/geos/impl_additions.rb +76 -0
- data/lib/rgeo/geos/interface.rb +139 -0
- data/lib/rgeo/geos/zm_factory.rb +275 -0
- data/lib/rgeo/geos/zm_impl.rb +432 -0
- data/lib/rgeo/impl_helper.rb +53 -0
- data/lib/rgeo/impl_helper/basic_geometry_collection_methods.rb +235 -0
- data/lib/rgeo/impl_helper/basic_geometry_methods.rb +85 -0
- data/lib/rgeo/impl_helper/basic_line_string_methods.rb +197 -0
- data/lib/rgeo/impl_helper/basic_point_methods.rb +138 -0
- data/lib/rgeo/impl_helper/basic_polygon_methods.rb +121 -0
- data/lib/rgeo/impl_helper/math.rb +50 -0
- data/lib/rgeo/version.rb +52 -0
- data/lib/rgeo/wkrep.rb +72 -0
- data/lib/rgeo/wkrep/wkb_generator.rb +267 -0
- data/lib/rgeo/wkrep/wkb_parser.rb +315 -0
- data/lib/rgeo/wkrep/wkt_generator.rb +275 -0
- data/lib/rgeo/wkrep/wkt_parser.rb +496 -0
- data/test/common/geometry_collection_tests.rb +238 -0
- data/test/common/line_string_tests.rb +324 -0
- data/test/common/multi_line_string_tests.rb +209 -0
- data/test/common/multi_point_tests.rb +201 -0
- data/test/common/multi_polygon_tests.rb +208 -0
- data/test/common/point_tests.rb +331 -0
- data/test/common/polygon_tests.rb +232 -0
- data/test/coord_sys/tc_active_record_table.rb +102 -0
- data/test/coord_sys/tc_ogc_cs.rb +356 -0
- data/test/coord_sys/tc_proj4.rb +138 -0
- data/test/coord_sys/tc_proj4_srs_data.rb +76 -0
- data/test/coord_sys/tc_sr_org.rb +70 -0
- data/test/coord_sys/tc_url_reader.rb +82 -0
- data/test/geos/tc_factory.rb +91 -0
- data/test/geos/tc_geometry_collection.rb +62 -0
- data/test/geos/tc_line_string.rb +62 -0
- data/test/geos/tc_misc.rb +72 -0
- data/test/geos/tc_multi_line_string.rb +62 -0
- data/test/geos/tc_multi_point.rb +62 -0
- data/test/geos/tc_multi_polygon.rb +63 -0
- data/test/geos/tc_point.rb +86 -0
- data/test/geos/tc_polygon.rb +86 -0
- data/test/geos/tc_zmfactory.rb +85 -0
- data/test/projected_geographic/tc_geometry_collection.rb +62 -0
- data/test/projected_geographic/tc_line_string.rb +62 -0
- data/test/projected_geographic/tc_multi_line_string.rb +62 -0
- data/test/projected_geographic/tc_multi_point.rb +62 -0
- data/test/projected_geographic/tc_multi_polygon.rb +63 -0
- data/test/projected_geographic/tc_point.rb +93 -0
- data/test/projected_geographic/tc_polygon.rb +62 -0
- data/test/simple_cartesian/tc_calculations.rb +145 -0
- data/test/simple_cartesian/tc_geometry_collection.rb +69 -0
- data/test/simple_cartesian/tc_line_string.rb +70 -0
- data/test/simple_cartesian/tc_multi_line_string.rb +67 -0
- data/test/simple_cartesian/tc_multi_point.rb +67 -0
- data/test/simple_cartesian/tc_multi_polygon.rb +70 -0
- data/test/simple_cartesian/tc_point.rb +91 -0
- data/test/simple_cartesian/tc_polygon.rb +67 -0
- data/test/simple_mercator/tc_geometry_collection.rb +62 -0
- data/test/simple_mercator/tc_line_string.rb +62 -0
- data/test/simple_mercator/tc_multi_line_string.rb +62 -0
- data/test/simple_mercator/tc_multi_point.rb +62 -0
- data/test/simple_mercator/tc_multi_polygon.rb +63 -0
- data/test/simple_mercator/tc_point.rb +93 -0
- data/test/simple_mercator/tc_polygon.rb +62 -0
- data/test/simple_mercator/tc_window.rb +219 -0
- data/test/spherical_geographic/tc_calculations.rb +203 -0
- data/test/spherical_geographic/tc_geometry_collection.rb +70 -0
- data/test/spherical_geographic/tc_line_string.rb +70 -0
- data/test/spherical_geographic/tc_multi_line_string.rb +67 -0
- data/test/spherical_geographic/tc_multi_point.rb +67 -0
- data/test/spherical_geographic/tc_multi_polygon.rb +70 -0
- data/test/spherical_geographic/tc_point.rb +100 -0
- data/test/spherical_geographic/tc_polygon.rb +67 -0
- data/test/tc_cartesian_analysis.rb +107 -0
- data/test/tc_oneoff.rb +63 -0
- data/test/wkrep/tc_wkb_generator.rb +249 -0
- data/test/wkrep/tc_wkb_parser.rb +353 -0
- data/test/wkrep/tc_wkt_generator.rb +362 -0
- data/test/wkrep/tc_wkt_parser.rb +480 -0
- metadata +267 -0
@@ -0,0 +1,312 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Proj4 wrapper 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 CoordSys
|
40
|
+
|
41
|
+
|
42
|
+
# This is a Ruby wrapper around a Proj4 coordinate system.
|
43
|
+
# It represents a single geographic coordinate system, which may be
|
44
|
+
# a flat projection, a geocentric (3-dimensional) coordinate system,
|
45
|
+
# or a geographic (latitude-longitude) coordinate system.
|
46
|
+
#
|
47
|
+
# Generally, these are used to define the projection for a
|
48
|
+
# Feature::Factory. You can then convert between coordinate systems
|
49
|
+
# by casting geometries between such factories using the :project
|
50
|
+
# option. You may also use this object directly to perform low-level
|
51
|
+
# coordinate transformations.
|
52
|
+
|
53
|
+
class Proj4
|
54
|
+
|
55
|
+
|
56
|
+
def inspect # :nodoc:
|
57
|
+
"#<#{self.class}:0x#{object_id.to_s(16)} #{canonical_str.inspect}>"
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
def to_s # :nodoc:
|
62
|
+
canonical_str
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
def hash # :nodoc:
|
67
|
+
canonical_hash.hash
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
# Returns true if this Proj4 is equivalent to the given Proj4.
|
72
|
+
#
|
73
|
+
# Note: this tests for equivalence by comparing only the hash
|
74
|
+
# definitions of the Proj4 objects, and returning true if those
|
75
|
+
# definitions are equivalent. In some cases, this may still return
|
76
|
+
# false even if the actual coordinate systems are identical, since
|
77
|
+
# there are sometimes multiple ways to express a given coordinate
|
78
|
+
# system.
|
79
|
+
|
80
|
+
def eql?(rhs_)
|
81
|
+
rhs_.class == self.class && rhs_.canonical_hash == canonical_hash && rhs_._radians? == _radians?
|
82
|
+
end
|
83
|
+
alias_method :==, :eql?
|
84
|
+
|
85
|
+
|
86
|
+
# Returns the "canonical" string definition for this coordinate
|
87
|
+
# system, as reported by Proj4. This may be slightly different
|
88
|
+
# from the definition used to construct this object.
|
89
|
+
|
90
|
+
def canonical_str
|
91
|
+
unless defined?(@canonical_str)
|
92
|
+
@canonical_str = _canonical_str
|
93
|
+
end
|
94
|
+
@canonical_str
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
# Returns the "canonical" hash definition for this coordinate
|
99
|
+
# system, as reported by Proj4. This may be slightly different
|
100
|
+
# from the definition used to construct this object.
|
101
|
+
|
102
|
+
def canonical_hash
|
103
|
+
unless defined?(@canonical_hash)
|
104
|
+
@canonical_hash = {}
|
105
|
+
canonical_str.strip.split(/\s+/).each do |elem_|
|
106
|
+
if elem_ =~ /^\+(\w+)(=(\S+))?$/
|
107
|
+
@canonical_hash[$1] = $3
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
@canonical_hash
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
# Returns the string definition originally used to construct this
|
116
|
+
# object. Returns nil if this object wasn't created by a string
|
117
|
+
# definition; i.e. if it was created using get_geographic.
|
118
|
+
|
119
|
+
def original_str
|
120
|
+
_original_str
|
121
|
+
end
|
122
|
+
|
123
|
+
|
124
|
+
# Returns true if this Proj4 object is a geographic (lat-long)
|
125
|
+
# coordinate system.
|
126
|
+
|
127
|
+
def geographic?
|
128
|
+
_geographic?
|
129
|
+
end
|
130
|
+
|
131
|
+
|
132
|
+
# Returns true if this Proj4 object is a geocentric (3dz)
|
133
|
+
# coordinate system.
|
134
|
+
|
135
|
+
def geocentric?
|
136
|
+
_geocentric?
|
137
|
+
end
|
138
|
+
|
139
|
+
|
140
|
+
# Returns true if this Proj4 object uses radians rather than degrees
|
141
|
+
# if it is a geographic coordinate system.
|
142
|
+
|
143
|
+
def radians?
|
144
|
+
_radians?
|
145
|
+
end
|
146
|
+
|
147
|
+
|
148
|
+
# Get the geographic (unprojected lat-long) coordinate system
|
149
|
+
# corresponding to this coordinate system; i.e. the one that uses
|
150
|
+
# the same ellipsoid and datum.
|
151
|
+
|
152
|
+
def get_geographic
|
153
|
+
_get_geographic
|
154
|
+
end
|
155
|
+
|
156
|
+
|
157
|
+
class << self
|
158
|
+
|
159
|
+
|
160
|
+
# Returns true if Proj4 is supported in this installation.
|
161
|
+
# If this returns false, the other methods such as create
|
162
|
+
# will not work.
|
163
|
+
|
164
|
+
def supported?
|
165
|
+
respond_to?(:_create)
|
166
|
+
end
|
167
|
+
|
168
|
+
|
169
|
+
# Create a new Proj4 object, given a definition, which may be
|
170
|
+
# either a string or a hash. Returns nil if the given definition
|
171
|
+
# is invalid or Proj4 is not supported.
|
172
|
+
#
|
173
|
+
# Recognized options include:
|
174
|
+
#
|
175
|
+
# [<tt>:radians</tt>]
|
176
|
+
# If set to true, then this proj4 will represent geographic
|
177
|
+
# (latitude/longitude) coordinates in radians rather than
|
178
|
+
# degrees. If this is a geographic coordinate system, then its
|
179
|
+
# units will be in radians. If this is a projected coordinate
|
180
|
+
# system, then its units will be unchanged, but any geographic
|
181
|
+
# coordinate system obtained using get_geographic will use
|
182
|
+
# radians as its units. If this is a geocentric or other type of
|
183
|
+
# coordinate system, this has no effect. Default is false.
|
184
|
+
# (That is all coordinates are in degrees by default.)
|
185
|
+
|
186
|
+
def create(defn_, opts_={})
|
187
|
+
result_ = nil
|
188
|
+
if supported?
|
189
|
+
if defn_.kind_of?(::Hash)
|
190
|
+
defn_ = defn_.map{ |k_, v_| v_ ? "+#{k_}=#{v_}" : "+#{k_}" }.join(' ')
|
191
|
+
end
|
192
|
+
unless defn_ =~ /^\s*\+/
|
193
|
+
defn_ = defn_.sub(/^(\s*)/, '\1+').gsub(/(\s+)([^+\s])/, '\1+\2')
|
194
|
+
end
|
195
|
+
result_ = _create(defn_, opts_[:radians])
|
196
|
+
result_ = nil unless result_._valid?
|
197
|
+
end
|
198
|
+
result_
|
199
|
+
end
|
200
|
+
|
201
|
+
|
202
|
+
# Create a new Proj4 object, given a definition, which may be
|
203
|
+
# either a string or a hash. Raises Error::UnsupportedOperation
|
204
|
+
# if the given definition is invalid or Proj4 is not supported.
|
205
|
+
|
206
|
+
def new(defn_, opts_={})
|
207
|
+
result_ = create(defn_, opts_)
|
208
|
+
unless result_
|
209
|
+
raise Error::UnsupportedOperation, "Proj4 not supported in this installation"
|
210
|
+
end
|
211
|
+
result_
|
212
|
+
end
|
213
|
+
|
214
|
+
|
215
|
+
# Low-level coordinate transform method.
|
216
|
+
# Transforms the given coordinate (x, y, [z]) from one proj4
|
217
|
+
# coordinate system to another. Returns an array with either two
|
218
|
+
# or three elements.
|
219
|
+
|
220
|
+
def transform_coords(from_proj_, to_proj_, x_, y_, z_=nil)
|
221
|
+
if !from_proj_._radians? && from_proj_._geographic?
|
222
|
+
x_ *= ImplHelper::Math::RADIANS_PER_DEGREE
|
223
|
+
y_ *= ImplHelper::Math::RADIANS_PER_DEGREE
|
224
|
+
end
|
225
|
+
result_ = _transform_coords(from_proj_, to_proj_, x_, y_, z_)
|
226
|
+
if result_ && !to_proj_._radians? && to_proj_._geographic?
|
227
|
+
result_[0] *= ImplHelper::Math::DEGREES_PER_RADIAN
|
228
|
+
result_[1] *= ImplHelper::Math::DEGREES_PER_RADIAN
|
229
|
+
end
|
230
|
+
result_
|
231
|
+
end
|
232
|
+
|
233
|
+
|
234
|
+
# Low-level geometry transform method.
|
235
|
+
# Transforms the given geometry between the given two projections.
|
236
|
+
# The resulting geometry is constructed using the to_factory.
|
237
|
+
# Any projections associated with the factories themselves are
|
238
|
+
# ignored.
|
239
|
+
|
240
|
+
def transform(from_proj_, from_geometry_, to_proj_, to_factory_)
|
241
|
+
case from_geometry_
|
242
|
+
when Feature::Point
|
243
|
+
_transform_point(from_proj_, from_geometry_, to_proj_, to_factory_)
|
244
|
+
when Feature::Line
|
245
|
+
to_factory_.line(from_geometry_.points.map{ |p_| _transform_point(from_proj_, p_, to_proj_, to_factory_) })
|
246
|
+
when Feature::LinearRing
|
247
|
+
_transform_linear_ring(from_proj_, from_geometry_, to_proj_, to_factory_)
|
248
|
+
when Feature::LineString
|
249
|
+
to_factory_.line_string(from_geometry_.points.map{ |p_| _transform_point(from_proj_, p_, to_proj_, to_factory_) })
|
250
|
+
when Feature::Polygon
|
251
|
+
_transform_polygon(from_proj_, from_geometry_, to_proj_, to_factory_)
|
252
|
+
when Feature::MultiPoint
|
253
|
+
to_factory_.multi_point(from_geometry_.map{ |p_| _transform_point(from_proj_, p_, to_proj_, to_factory_) })
|
254
|
+
when Feature::MultiLineString
|
255
|
+
to_factory_.multi_line_string(from_geometry_.map{ |g_| transform(from_proj_, g_, to_proj_, to_factory_) })
|
256
|
+
when Feature::MultiPolygon
|
257
|
+
to_factory_.multi_polygon(from_geometry_.map{ |p_| _transform_polygon(from_proj_, p_, to_proj_, to_factory_) })
|
258
|
+
when Feature::GeometryCollection
|
259
|
+
to_factory_.collection(from_geometry_.map{ |g_| transform(from_proj_, g_, to_proj_, to_factory_) })
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
|
264
|
+
def _transform_point(from_proj_, from_point_, to_proj_, to_factory_) # :nodoc:
|
265
|
+
from_factory_ = from_point_.factory
|
266
|
+
from_has_z_ = from_factory_.property(:has_z_coordinate)
|
267
|
+
from_has_m_ = from_factory_.property(:has_m_coordinate)
|
268
|
+
to_has_z_ = to_factory_.property(:has_z_coordinate)
|
269
|
+
to_has_m_ = to_factory_.property(:has_m_coordinate)
|
270
|
+
x_ = from_point_.x
|
271
|
+
y_ = from_point_.y
|
272
|
+
if !from_proj_._radians? && from_proj_._geographic?
|
273
|
+
x_ *= ImplHelper::Math::RADIANS_PER_DEGREE
|
274
|
+
y_ *= ImplHelper::Math::RADIANS_PER_DEGREE
|
275
|
+
end
|
276
|
+
coords_ = _transform_coords(from_proj_, to_proj_, x_, y_, from_has_z_ ? from_point_.z : nil)
|
277
|
+
if coords_
|
278
|
+
if !to_proj_._radians? && to_proj_._geographic?
|
279
|
+
coords_[0] *= ImplHelper::Math::DEGREES_PER_RADIAN
|
280
|
+
coords_[1] *= ImplHelper::Math::DEGREES_PER_RADIAN
|
281
|
+
end
|
282
|
+
extras_ = []
|
283
|
+
extras_ << coords_[2].to_f if to_has_z_
|
284
|
+
extras_ << from_has_m_ ? from_point_.m : 0.0 if to_has_m_
|
285
|
+
to_factory_.point(coords_[0], coords_[1], *extras_)
|
286
|
+
else
|
287
|
+
nil
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
|
292
|
+
def _transform_linear_ring(from_proj_, from_ring_, to_proj_, to_factory_) # :nodoc:
|
293
|
+
to_factory_.linear_ring(from_ring_.points[0..-2].map{ |p_| _transform_point(from_proj_, p_, to_proj_, to_factory_) })
|
294
|
+
end
|
295
|
+
|
296
|
+
|
297
|
+
def _transform_polygon(from_proj_, from_polygon_, to_proj_, to_factory_) # :nodoc:
|
298
|
+
ext_ = _transform_linear_ring(from_proj_, from_polygon_.exterior_ring, to_proj_, to_factory_)
|
299
|
+
int_ = from_polygon_.interior_rings.map{ |r_| _transform_linear_ring(from_proj_, r_, to_proj_, to_factory_) }
|
300
|
+
to_factory_.polygon(ext_, int_)
|
301
|
+
end
|
302
|
+
|
303
|
+
|
304
|
+
end
|
305
|
+
|
306
|
+
|
307
|
+
end
|
308
|
+
|
309
|
+
|
310
|
+
end
|
311
|
+
|
312
|
+
end
|
@@ -0,0 +1,194 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# SRS database interface
|
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 CoordSys
|
40
|
+
|
41
|
+
module SRSDatabase
|
42
|
+
|
43
|
+
|
44
|
+
# A spatial reference database implementation that uses ActiveRecord
|
45
|
+
# to access a spatial reference table provided by a spatial database
|
46
|
+
# implementation. You can use this class to obtain coordinate system
|
47
|
+
# information from your installation of, e.g. PostGIS.
|
48
|
+
|
49
|
+
class ActiveRecordTable
|
50
|
+
|
51
|
+
@@class_counter = 0
|
52
|
+
|
53
|
+
|
54
|
+
# Create a new ActiveRecord-backed database connection.
|
55
|
+
#
|
56
|
+
# Options include:
|
57
|
+
#
|
58
|
+
# [<tt>:ar_class</tt>]
|
59
|
+
# An ActiveRecord class to use. You may provide this if you
|
60
|
+
# already have an ActiveRecord class that accesses the table.
|
61
|
+
# If not provided, an ActiveRecord class will be generated
|
62
|
+
# for you, using the <tt>:ar_base_class</tt>,
|
63
|
+
# <tt>:database_config</tt>, and <tt>:table_name</tt> options.
|
64
|
+
# [<tt>:ar_base_class</tt>]
|
65
|
+
# Specify an ActiveRecord base class to use when generating an
|
66
|
+
# ActiveRecord class. Default is ::ActiveRecord::Base. You may
|
67
|
+
# want to use this if you have a base class already that
|
68
|
+
# specifies an existing database connection and/or other
|
69
|
+
# class-scope options.
|
70
|
+
# [<tt>:database_config</tt>]
|
71
|
+
# If provided, <tt>establish_connection</tt> will be called on
|
72
|
+
# the generated ActiveRecord class, with the given value.
|
73
|
+
# [<tt>:table_name</tt>]
|
74
|
+
# The table name for the new ActiveRecord class. Defaults to
|
75
|
+
# the value <tt>spatial_ref_sys</tt>, which is the OGC-specified
|
76
|
+
# name for this table.
|
77
|
+
# [<tt>:srid_column</tt>]
|
78
|
+
# The name of the SRID column. Defaults to "srid", which is the
|
79
|
+
# OGC-specified name for this column.
|
80
|
+
# [<tt>:auth_name_column</tt>]
|
81
|
+
# The name of the authority name column. On an OGC-compliant
|
82
|
+
# database, this column should be named "auth_name". However,
|
83
|
+
# the default is set to nil; you should set this option
|
84
|
+
# explicitly if you want to read the authority name.
|
85
|
+
# [<tt>:auth_srid_column</tt>]
|
86
|
+
# The name of the authority srid column. On an OGC-compliant
|
87
|
+
# database, this column should be named "auth_srid". However,
|
88
|
+
# the default is set to nil; you should set this option
|
89
|
+
# explicitly if you want to read the authority's srid.
|
90
|
+
# [<tt>:name_column</tt>]
|
91
|
+
# The name of the coordinate system name column. This column is
|
92
|
+
# not part of the OGC spec, but it is included in some spatial
|
93
|
+
# database implementations. Default is nil.
|
94
|
+
# [<tt>:description_column</tt>]
|
95
|
+
# The name of the coordinate system description column. This
|
96
|
+
# column is not part of the OGC spec, but may be included in
|
97
|
+
# some spatial database implementations. Default is nil.
|
98
|
+
# [<tt>:srtext_column</tt>]
|
99
|
+
# The name of the spatial reference WKT column. On an
|
100
|
+
# OGC-compliant database, this column should be named "srtext".
|
101
|
+
# However, not all databases include this column, so the default
|
102
|
+
# is set to nil; you should set this option explicitly if you
|
103
|
+
# want to read the OGC coordinate system specification.
|
104
|
+
# [<tt>:proj4text_column</tt>]
|
105
|
+
# The name of the Proj4 format projection spec column. This
|
106
|
+
# column is not part of the OGC spec, but may be included in
|
107
|
+
# some spatial database implementations. Default is nil.
|
108
|
+
# [<tt>:cache</tt>]
|
109
|
+
# If set to true, entries are cached when first retrieved, so
|
110
|
+
# subsequent requests do not have to make a database round trip.
|
111
|
+
# Default is false.
|
112
|
+
#
|
113
|
+
# Some option settings may be provided by the ActiveRecord
|
114
|
+
# connection adapter, if the ActiveRecord class's connection uses
|
115
|
+
# an adapter that is RGeo-savvy. The "postgis" and "spatialite"
|
116
|
+
# adapters are such adapters. They automatically provide the
|
117
|
+
# <tt>:table_name</tt> and all the relevant column settings for
|
118
|
+
# the database-provided spatial reference table as defaults.
|
119
|
+
# However, you can still override those settings if you want to
|
120
|
+
# use a custom table.
|
121
|
+
|
122
|
+
def initialize(opts_={})
|
123
|
+
@cache = opts_[:cache] ? {} : nil
|
124
|
+
@ar_class = opts_[:ar_class]
|
125
|
+
unless @ar_class
|
126
|
+
ar_base_class_ = opts_[:ar_base_class] || ::ActiveRecord::Base
|
127
|
+
@ar_class = ::Class.new(ar_base_class_)
|
128
|
+
self.class.const_set("Klass#{@@class_counter}", @ar_class)
|
129
|
+
@@class_counter += 1
|
130
|
+
@ar_class.class_eval do
|
131
|
+
establish_connection(opts_[:database_config]) if opts_[:database_config]
|
132
|
+
end
|
133
|
+
end
|
134
|
+
connection_ = @ar_class.connection
|
135
|
+
if connection_.respond_to?(:srs_database_columns)
|
136
|
+
opts_ = connection_.srs_database_columns.merge(opts_)
|
137
|
+
end
|
138
|
+
unless opts_[:ar_class]
|
139
|
+
@ar_class.class_eval do
|
140
|
+
set_table_name(opts_[:table_name] || 'spatial_ref_sys')
|
141
|
+
end
|
142
|
+
end
|
143
|
+
@srid_column = opts_[:srid_column] || 'srid'
|
144
|
+
@auth_name_column = opts_[:auth_name_column]
|
145
|
+
@auth_srid_column = opts_[:auth_srid_column]
|
146
|
+
@name_column = opts_[:name_column]
|
147
|
+
@description_column = opts_[:description_column]
|
148
|
+
@srtext_column = opts_[:srtext_column]
|
149
|
+
@proj4text_column = opts_[:proj4text_column]
|
150
|
+
end
|
151
|
+
|
152
|
+
|
153
|
+
# Retrieve an Entry given an integer SRID.
|
154
|
+
|
155
|
+
def get(ident_)
|
156
|
+
ident_ = ident_.to_i
|
157
|
+
return @cache[ident_] if @cache && @cache.include?(ident_)
|
158
|
+
obj_ = @ar_class.where(@srid_column => ident_).first
|
159
|
+
unless obj_
|
160
|
+
@cache[ident_] = nil if @cache
|
161
|
+
return nil
|
162
|
+
end
|
163
|
+
auth_name_ = @auth_name_column ? obj_[@auth_name_column] : nil
|
164
|
+
auth_srid_ = @auth_srid_column ? obj_[@auth_srid_column] : nil
|
165
|
+
name_ = @name_column ? obj_[@name_column] : nil
|
166
|
+
description_ = @description_column ? obj_[@description_column] : nil
|
167
|
+
coord_sys_ = proj4_ = nil
|
168
|
+
if @srtext_column
|
169
|
+
coord_sys_ = CS.create_from_wkt(obj_[@srtext_column]) rescue nil
|
170
|
+
end
|
171
|
+
if @proj4text_column && Proj4.supported?
|
172
|
+
proj4_ = Proj4.create(obj_[@proj4text_column].strip) rescue nil
|
173
|
+
end
|
174
|
+
result_ = Entry.new(ident_, :authority => auth_name_, :authority_code => auth_srid_, :name => name_, :description => description_, :coord_sys => coord_sys_, :proj4 => proj4_)
|
175
|
+
@cache[ident_] = result_ if @cache
|
176
|
+
result_
|
177
|
+
end
|
178
|
+
|
179
|
+
|
180
|
+
# Clears the cache if a cache is active.
|
181
|
+
|
182
|
+
def clear_cache
|
183
|
+
@cache.clear if @cache
|
184
|
+
end
|
185
|
+
|
186
|
+
|
187
|
+
end
|
188
|
+
|
189
|
+
|
190
|
+
end
|
191
|
+
|
192
|
+
end
|
193
|
+
|
194
|
+
end
|