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,206 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Core calculations on the sphere
|
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 Geographic
|
40
|
+
|
41
|
+
module SphericalMath # :nodoc:
|
42
|
+
|
43
|
+
|
44
|
+
RADIUS = 6378137.0
|
45
|
+
|
46
|
+
|
47
|
+
# Represents a point on the unit sphere in (x,y,z) coordinates
|
48
|
+
# instead of lat-lon. This form is often faster, more convenient,
|
49
|
+
# and more numerically stable for certain computations.
|
50
|
+
#
|
51
|
+
# The coordinate system is a right-handed system where the z-axis
|
52
|
+
# goes through the north pole, the x-axis goes through the prime
|
53
|
+
# meridian, and the y-axis goes through +90 degrees longitude.
|
54
|
+
#
|
55
|
+
# This object is also used to represent a great circle, as its axis
|
56
|
+
# of rotation.
|
57
|
+
|
58
|
+
class PointXYZ # :nodoc:
|
59
|
+
|
60
|
+
def initialize(x_, y_, z_)
|
61
|
+
r_ = ::Math.sqrt(x_ * x_ + y_ * y_ + z_ * z_)
|
62
|
+
@x = x_ / r_
|
63
|
+
@y = y_ / r_
|
64
|
+
@z = z_ / r_
|
65
|
+
raise "Not a number" if @x.nan? || @y.nan? || @z.nan?
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
def to_s
|
70
|
+
"(#{@x}, #{@y}, #{@z})"
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
attr_reader :x
|
75
|
+
attr_reader :y
|
76
|
+
attr_reader :z
|
77
|
+
|
78
|
+
|
79
|
+
def eql?(rhs_)
|
80
|
+
rhs_.kind_of?(PointXYZ) && @x == rhs_.x && @y == rhs_.y && @z == rhs_.z
|
81
|
+
end
|
82
|
+
alias_method :==, :eql?
|
83
|
+
|
84
|
+
|
85
|
+
def latlon
|
86
|
+
lat_rad_ = ::Math.asin(@z)
|
87
|
+
lon_rad_ = ::Math.atan2(@y, @x) rescue 0.0
|
88
|
+
rpd_ = ImplHelper::Math::RADIANS_PER_DEGREE
|
89
|
+
[lat_rad_ / rpd_, lon_rad_ / rpd_]
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
def *(rhs_)
|
94
|
+
val_ = @x * rhs_.x + @y * rhs_.y + @z * rhs_.z
|
95
|
+
val_ = 1.0 if val_ > 1.0
|
96
|
+
val_ = -1.0 if val_ < -1.0
|
97
|
+
val_
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
def %(rhs_)
|
102
|
+
rx_ = rhs_.x
|
103
|
+
ry_ = rhs_.y
|
104
|
+
rz_ = rhs_.z
|
105
|
+
PointXYZ.new(@y*rz_-@z*ry_, @z*rx_-@x*rz_, @x*ry_-@y*rx_) rescue nil
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
def dist_to_point(rhs_)
|
110
|
+
rx_ = rhs_.x
|
111
|
+
ry_ = rhs_.y
|
112
|
+
rz_ = rhs_.z
|
113
|
+
x_ = @y*rz_-@z*ry_
|
114
|
+
y_ = @z*rx_-@x*rz_
|
115
|
+
z_ = @x*ry_-@y*rx_
|
116
|
+
r_ = ::Math.sqrt(x_*x_ + y_*y_ + z_*z_)
|
117
|
+
r_ = 1.0 if r_ > 1.0
|
118
|
+
::Math.asin(r_)
|
119
|
+
end
|
120
|
+
|
121
|
+
|
122
|
+
def self.from_latlon(lat_, lon_)
|
123
|
+
rpd_ = ImplHelper::Math::RADIANS_PER_DEGREE
|
124
|
+
lat_rad_ = rpd_ * lat_
|
125
|
+
lon_rad_ = rpd_ * lon_
|
126
|
+
z_ = ::Math.sin(lat_rad_)
|
127
|
+
r_ = ::Math.cos(lat_rad_)
|
128
|
+
x_ = ::Math.cos(lon_rad_) * r_
|
129
|
+
y_ = ::Math.sin(lon_rad_) * r_
|
130
|
+
new(x_, y_, z_)
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
|
136
|
+
# Represents a finite arc on the sphere.
|
137
|
+
|
138
|
+
class ArcXYZ # :nodoc:
|
139
|
+
|
140
|
+
def initialize(start_, end_)
|
141
|
+
@s = start_
|
142
|
+
@e = end_
|
143
|
+
@axis = false
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
attr_reader :s
|
148
|
+
attr_reader :e
|
149
|
+
|
150
|
+
|
151
|
+
def to_s
|
152
|
+
"#{@s} - #{@e}"
|
153
|
+
end
|
154
|
+
|
155
|
+
|
156
|
+
def eql?(rhs_)
|
157
|
+
rhs_.kind_of?(ArcXYZ) && @s == rhs_.s && @e == rhs_.e
|
158
|
+
end
|
159
|
+
alias_method :==, :eql?
|
160
|
+
|
161
|
+
|
162
|
+
def degenerate?
|
163
|
+
axis_ = axis
|
164
|
+
axis_.x == 0 && axis_.y == 0 && axis_.z == 0
|
165
|
+
end
|
166
|
+
|
167
|
+
|
168
|
+
def axis
|
169
|
+
if @axis == false
|
170
|
+
@axis = @s % @e
|
171
|
+
end
|
172
|
+
@axis
|
173
|
+
end
|
174
|
+
|
175
|
+
|
176
|
+
def contains_point?(obj_)
|
177
|
+
axis_ = axis
|
178
|
+
saxis_ = ArcXYZ.new(@s, obj_).axis
|
179
|
+
eaxis_ = ArcXYZ.new(obj_, @e).axis
|
180
|
+
!saxis_ || !eaxis_ || obj_ * axis_ == 0.0 && saxis_ * axis_ > 0 && eaxis_ * axis_ > 0
|
181
|
+
end
|
182
|
+
|
183
|
+
|
184
|
+
def intersects_arc?(obj_)
|
185
|
+
my_axis_ = axis
|
186
|
+
dot1_ = my_axis_ * obj_.s
|
187
|
+
dot2_ = my_axis_ * obj_.e
|
188
|
+
if dot1_ >= 0.0 && dot2_ <= 0.0 || dot1_ <= 0.0 && dot2_ >= 0.0
|
189
|
+
ob_axis_ = obj_.axis
|
190
|
+
dot1_ = ob_axis_ * @s
|
191
|
+
dot2_ = ob_axis_ * @e
|
192
|
+
dot1_ >= 0.0 && dot2_ <= 0.0 || dot1_ <= 0.0 && dot2_ >= 0.0
|
193
|
+
else
|
194
|
+
false
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
|
199
|
+
end
|
200
|
+
|
201
|
+
|
202
|
+
end
|
203
|
+
|
204
|
+
end
|
205
|
+
|
206
|
+
end
|
data/lib/rgeo/geos.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# GEOS 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
|
+
|
40
|
+
# The Geos module provides general tools for creating and manipulating
|
41
|
+
# a GEOS-backed implementation of the SFS. This is a full implementation
|
42
|
+
# of the SFS using a Cartesian coordinate system. It uses the GEOS C++
|
43
|
+
# library to perform most operations, and hence is available only if
|
44
|
+
# GEOS version 3.2 or later is installed and accessible when the rgeo
|
45
|
+
# gem is installed. RGeo feature calls are translated into appropriate
|
46
|
+
# GEOS calls and directed to the library's C api. RGeo also corrects a
|
47
|
+
# few cases of missing or non-standard behavior in GEOS.
|
48
|
+
#
|
49
|
+
# This module also provides a namespace for the implementation classes
|
50
|
+
# themselves; however, those classes are meant to be opaque and are
|
51
|
+
# therefore not documented.
|
52
|
+
#
|
53
|
+
# To use the Geos implementation, first obtain a factory using the
|
54
|
+
# ::RGeo::Geos::factory method. You may then call any of the standard
|
55
|
+
# factory methods on the resulting object.
|
56
|
+
|
57
|
+
module Geos
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
# Implementation files
|
65
|
+
require 'rgeo/geos/factory'
|
66
|
+
require 'rgeo/geos/interface'
|
67
|
+
begin
|
68
|
+
require 'rgeo/geos/geos_c_impl'
|
69
|
+
rescue ::LoadError; end
|
70
|
+
require 'rgeo/geos/impl_additions'
|
71
|
+
require 'rgeo/geos/zm_factory'
|
72
|
+
require 'rgeo/geos/zm_impl'
|
@@ -0,0 +1,301 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# GEOS factory implementation
|
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 Geos
|
40
|
+
|
41
|
+
|
42
|
+
# This the GEOS implementation of ::RGeo::Feature::Factory.
|
43
|
+
|
44
|
+
class Factory
|
45
|
+
|
46
|
+
|
47
|
+
include Feature::Factory::Instance
|
48
|
+
|
49
|
+
|
50
|
+
class << self
|
51
|
+
|
52
|
+
|
53
|
+
# Create a new factory. Returns nil if the GEOS implementation is
|
54
|
+
# not supported.
|
55
|
+
#
|
56
|
+
# See ::RGeo::Geos::factory for a list of supported options.
|
57
|
+
|
58
|
+
def create(opts_={})
|
59
|
+
return nil unless respond_to?(:_create)
|
60
|
+
flags_ = 0
|
61
|
+
flags_ |= 1 if opts_[:lenient_multi_polygon_assertions]
|
62
|
+
flags_ |= 2 if opts_[:has_z_coordinate]
|
63
|
+
flags_ |= 4 if opts_[:has_m_coordinate]
|
64
|
+
if flags_ & 6 == 6
|
65
|
+
raise Error::UnsupportedOperation, "GEOS cannot support both Z and M coordinates at the same time."
|
66
|
+
end
|
67
|
+
buffer_resolution_ = opts_[:buffer_resolution].to_i
|
68
|
+
buffer_resolution_ = 1 if buffer_resolution_ < 1
|
69
|
+
srid_ = opts_[:srid]
|
70
|
+
proj4_ = opts_[:proj4]
|
71
|
+
if CoordSys::Proj4.supported?
|
72
|
+
if proj4_.kind_of?(::String) || proj4_.kind_of?(::Hash)
|
73
|
+
proj4_ = CoordSys::Proj4.create(proj4_)
|
74
|
+
end
|
75
|
+
else
|
76
|
+
proj4_ = nil
|
77
|
+
end
|
78
|
+
coord_sys_ = opts_[:coord_sys]
|
79
|
+
if coord_sys_.kind_of?(::String)
|
80
|
+
coord_sys_ = CoordSys::CS.create_from_wkt(coord_sys_) rescue nil
|
81
|
+
end
|
82
|
+
if (!proj4_ || !coord_sys_) && srid_ && (db_ = opts_[:srs_database])
|
83
|
+
entry_ = db_.get(srid_.to_i)
|
84
|
+
if entry_
|
85
|
+
proj4_ ||= entry_.proj4
|
86
|
+
coord_sys_ ||= entry_.coord_sys
|
87
|
+
end
|
88
|
+
end
|
89
|
+
srid_ ||= coord_sys_.authority_code if coord_sys_
|
90
|
+
result_ = _create(flags_, srid_.to_i, buffer_resolution_)
|
91
|
+
result_.instance_variable_set(:@proj4, proj4_)
|
92
|
+
result_.instance_variable_set(:@coord_sys, coord_sys_)
|
93
|
+
result_
|
94
|
+
end
|
95
|
+
alias_method :new, :create
|
96
|
+
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
def inspect # :nodoc:
|
102
|
+
"#<#{self.class}:0x#{object_id.to_s(16)} srid=#{_srid} bufres=#{_buffer_resolution} flags=#{_flags}>"
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
# Factory equivalence test.
|
107
|
+
|
108
|
+
def eql?(rhs_)
|
109
|
+
rhs_.is_a?(Factory) && rhs_.srid == _srid && rhs_._buffer_resolution == _buffer_resolution && rhs_._flags == _flags && rhs_.proj4 == @proj4
|
110
|
+
end
|
111
|
+
alias_method :==, :eql?
|
112
|
+
|
113
|
+
|
114
|
+
# Returns the SRID of geometries created by this factory.
|
115
|
+
|
116
|
+
def srid
|
117
|
+
_srid
|
118
|
+
end
|
119
|
+
|
120
|
+
|
121
|
+
# Returns the resolution used by buffer calculations on geometries
|
122
|
+
# created by this factory
|
123
|
+
|
124
|
+
def buffer_resolution
|
125
|
+
_buffer_resolution
|
126
|
+
end
|
127
|
+
|
128
|
+
|
129
|
+
# Returns true if this factory is lenient with MultiPolygon assertions
|
130
|
+
|
131
|
+
def lenient_multi_polygon_assertions?
|
132
|
+
_flags & 0x1 != 0
|
133
|
+
end
|
134
|
+
|
135
|
+
|
136
|
+
# See ::RGeo::Feature::Factory#property
|
137
|
+
|
138
|
+
def property(name_)
|
139
|
+
case name_
|
140
|
+
when :has_z_coordinate
|
141
|
+
_flags & 0x2 != 0
|
142
|
+
when :has_m_coordinate
|
143
|
+
_flags & 0x4 != 0
|
144
|
+
when :is_cartesian
|
145
|
+
true
|
146
|
+
else
|
147
|
+
nil
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
|
152
|
+
# See ::RGeo::Feature::Factory#parse_wkt
|
153
|
+
|
154
|
+
def parse_wkt(str_)
|
155
|
+
_parse_wkt_impl(str_)
|
156
|
+
end
|
157
|
+
|
158
|
+
|
159
|
+
# See ::RGeo::Feature::Factory#parse_wkb
|
160
|
+
|
161
|
+
def parse_wkb(str_)
|
162
|
+
_parse_wkb_impl(str_)
|
163
|
+
end
|
164
|
+
|
165
|
+
|
166
|
+
# See ::RGeo::Feature::Factory#point
|
167
|
+
|
168
|
+
def point(x_, y_, *extra_)
|
169
|
+
if extra_.length > (_flags & 6 == 0 ? 0 : 1)
|
170
|
+
nil
|
171
|
+
else
|
172
|
+
PointImpl.create(self, x_, y_, extra_[0].to_f) rescue nil
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
|
177
|
+
# See ::RGeo::Feature::Factory#line_string
|
178
|
+
|
179
|
+
def line_string(points_)
|
180
|
+
points_ = points_.to_a unless points_.kind_of?(::Array)
|
181
|
+
LineStringImpl.create(self, points_) rescue nil
|
182
|
+
end
|
183
|
+
|
184
|
+
|
185
|
+
# See ::RGeo::Feature::Factory#line
|
186
|
+
|
187
|
+
def line(start_, end_)
|
188
|
+
LineImpl.create(self, start_, end_) rescue nil
|
189
|
+
end
|
190
|
+
|
191
|
+
|
192
|
+
# See ::RGeo::Feature::Factory#linear_ring
|
193
|
+
|
194
|
+
def linear_ring(points_)
|
195
|
+
points_ = points_.to_a unless points_.kind_of?(::Array)
|
196
|
+
LinearRingImpl.create(self, points_) rescue nil
|
197
|
+
end
|
198
|
+
|
199
|
+
|
200
|
+
# See ::RGeo::Feature::Factory#polygon
|
201
|
+
|
202
|
+
def polygon(outer_ring_, inner_rings_=nil)
|
203
|
+
inner_rings_ = inner_rings_.to_a unless inner_rings_.kind_of?(::Array)
|
204
|
+
PolygonImpl.create(self, outer_ring_, inner_rings_) rescue nil
|
205
|
+
end
|
206
|
+
|
207
|
+
|
208
|
+
# See ::RGeo::Feature::Factory#collection
|
209
|
+
|
210
|
+
def collection(elems_)
|
211
|
+
elems_ = elems_.to_a unless elems_.kind_of?(::Array)
|
212
|
+
GeometryCollectionImpl.create(self, elems_) rescue nil
|
213
|
+
end
|
214
|
+
|
215
|
+
|
216
|
+
# See ::RGeo::Feature::Factory#multi_point
|
217
|
+
|
218
|
+
def multi_point(elems_)
|
219
|
+
elems_ = elems_.to_a unless elems_.kind_of?(::Array)
|
220
|
+
MultiPointImpl.create(self, elems_) rescue nil
|
221
|
+
end
|
222
|
+
|
223
|
+
|
224
|
+
# See ::RGeo::Feature::Factory#multi_line_string
|
225
|
+
|
226
|
+
def multi_line_string(elems_)
|
227
|
+
elems_ = elems_.to_a unless elems_.kind_of?(::Array)
|
228
|
+
MultiLineStringImpl.create(self, elems_) rescue nil
|
229
|
+
end
|
230
|
+
|
231
|
+
|
232
|
+
# See ::RGeo::Feature::Factory#multi_polygon
|
233
|
+
|
234
|
+
def multi_polygon(elems_)
|
235
|
+
elems_ = elems_.to_a unless elems_.kind_of?(::Array)
|
236
|
+
MultiPolygonImpl.create(self, elems_) rescue nil
|
237
|
+
end
|
238
|
+
|
239
|
+
|
240
|
+
# See ::RGeo::Feature::Factory#proj4
|
241
|
+
|
242
|
+
def proj4
|
243
|
+
@proj4
|
244
|
+
end
|
245
|
+
|
246
|
+
|
247
|
+
# See ::RGeo::Feature::Factory#coord_sys
|
248
|
+
|
249
|
+
def coord_sys
|
250
|
+
@coord_sys
|
251
|
+
end
|
252
|
+
|
253
|
+
|
254
|
+
# See ::RGeo::Feature::Factory#override_cast
|
255
|
+
|
256
|
+
def override_cast(original_, ntype_, flags_)
|
257
|
+
return nil unless Geos.supported?
|
258
|
+
keep_subtype_ = flags_[:keep_subtype]
|
259
|
+
force_new_ = flags_[:force_new]
|
260
|
+
project_ = flags_[:project]
|
261
|
+
type_ = original_.geometry_type
|
262
|
+
ntype_ = type_ if keep_subtype_ && type_.include?(ntype_)
|
263
|
+
case original_
|
264
|
+
when GeometryImpl
|
265
|
+
# Optimization if we're just changing factories, but the
|
266
|
+
# factories are zm-compatible and proj4-compatible.
|
267
|
+
if original_.factory != self && ntype_ == type_ &&
|
268
|
+
original_.factory._flags & 0x6 == _flags & 0x6 &&
|
269
|
+
(!project_ || original_.factory.proj4 == @proj4)
|
270
|
+
then
|
271
|
+
result_ = original_.dup
|
272
|
+
result_._set_factory(self)
|
273
|
+
return result_
|
274
|
+
end
|
275
|
+
# LineString conversion optimization.
|
276
|
+
if (original_.factory != self || ntype_ != type_) &&
|
277
|
+
original_.factory._flags & 0x6 == _flags & 0x6 &&
|
278
|
+
(!project_ || original_.factory.proj4 == @proj4) &&
|
279
|
+
type_.subtype_of?(Feature::LineString) && ntype_.subtype_of?(Feature::LineString)
|
280
|
+
then
|
281
|
+
return IMPL_CLASSES[ntype_]._copy_from(self, original_)
|
282
|
+
end
|
283
|
+
when ZMGeometryImpl
|
284
|
+
# Optimization for just removing a coordinate from an otherwise
|
285
|
+
# compatible factory
|
286
|
+
if _flags & 0x6 == 0x2 && self == original_.factory.z_factory
|
287
|
+
return Feature.cast(original_.z_geometry, ntype_, flags_)
|
288
|
+
elsif _flags & 0x6 == 0x4 && self == original_.factory.m_factory
|
289
|
+
return Feature.cast(original_.m_geometry, ntype_, flags_)
|
290
|
+
end
|
291
|
+
end
|
292
|
+
false
|
293
|
+
end
|
294
|
+
|
295
|
+
|
296
|
+
end
|
297
|
+
|
298
|
+
|
299
|
+
end
|
300
|
+
|
301
|
+
end
|