schleyfox-rgeo 0.2.5
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 +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
|