rgeo 0.1.10

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.
Files changed (82) hide show
  1. data/History.rdoc +22 -0
  2. data/README.rdoc +124 -0
  3. data/Version +1 -0
  4. data/ext/geos_c_impl/extconf.rb +72 -0
  5. data/ext/geos_c_impl/factory.c +468 -0
  6. data/ext/geos_c_impl/factory.h +217 -0
  7. data/ext/geos_c_impl/geometry.c +644 -0
  8. data/ext/geos_c_impl/geometry.h +65 -0
  9. data/ext/geos_c_impl/geometry_collection.c +580 -0
  10. data/ext/geos_c_impl/geometry_collection.h +79 -0
  11. data/ext/geos_c_impl/globals.h +58 -0
  12. data/ext/geos_c_impl/line_string.c +468 -0
  13. data/ext/geos_c_impl/line_string.h +74 -0
  14. data/ext/geos_c_impl/main.c +65 -0
  15. data/ext/geos_c_impl/point.c +201 -0
  16. data/ext/geos_c_impl/point.h +77 -0
  17. data/ext/geos_c_impl/polygon.c +259 -0
  18. data/ext/geos_c_impl/polygon.h +76 -0
  19. data/ext/geos_c_impl/preface.h +42 -0
  20. data/lib/rgeo.rb +68 -0
  21. data/lib/rgeo/errors.rb +59 -0
  22. data/lib/rgeo/features.rb +89 -0
  23. data/lib/rgeo/features/curve.rb +155 -0
  24. data/lib/rgeo/features/factory.rb +191 -0
  25. data/lib/rgeo/features/geometry.rb +560 -0
  26. data/lib/rgeo/features/geometry_collection.rb +118 -0
  27. data/lib/rgeo/features/line.rb +65 -0
  28. data/lib/rgeo/features/line_string.rb +101 -0
  29. data/lib/rgeo/features/linear_ring.rb +65 -0
  30. data/lib/rgeo/features/multi_curve.rb +112 -0
  31. data/lib/rgeo/features/multi_line_string.rb +65 -0
  32. data/lib/rgeo/features/multi_point.rb +72 -0
  33. data/lib/rgeo/features/multi_polygon.rb +96 -0
  34. data/lib/rgeo/features/multi_surface.rb +115 -0
  35. data/lib/rgeo/features/point.rb +97 -0
  36. data/lib/rgeo/features/polygon.rb +141 -0
  37. data/lib/rgeo/features/surface.rb +121 -0
  38. data/lib/rgeo/geo_json.rb +58 -0
  39. data/lib/rgeo/geo_json/coder.rb +305 -0
  40. data/lib/rgeo/geo_json/entities.rb +284 -0
  41. data/lib/rgeo/geo_json/interface.rb +95 -0
  42. data/lib/rgeo/geography.rb +75 -0
  43. data/lib/rgeo/geography/common/geometry_collection_methods.rb +206 -0
  44. data/lib/rgeo/geography/common/geometry_methods.rb +92 -0
  45. data/lib/rgeo/geography/common/helper.rb +102 -0
  46. data/lib/rgeo/geography/common/line_string_methods.rb +187 -0
  47. data/lib/rgeo/geography/common/point_methods.rb +149 -0
  48. data/lib/rgeo/geography/common/polygon_methods.rb +122 -0
  49. data/lib/rgeo/geography/factories.rb +136 -0
  50. data/lib/rgeo/geography/factory.rb +246 -0
  51. data/lib/rgeo/geography/projected_window.rb +467 -0
  52. data/lib/rgeo/geography/simple_mercator/feature_classes.rb +320 -0
  53. data/lib/rgeo/geography/simple_mercator/feature_methods.rb +291 -0
  54. data/lib/rgeo/geography/simple_mercator/projector.rb +116 -0
  55. data/lib/rgeo/geography/simple_spherical/calculations.rb +70 -0
  56. data/lib/rgeo/geography/simple_spherical/geometry_collection_impl.rb +66 -0
  57. data/lib/rgeo/geography/simple_spherical/geometry_methods.rb +59 -0
  58. data/lib/rgeo/geography/simple_spherical/line_string_impl.rb +104 -0
  59. data/lib/rgeo/geography/simple_spherical/multi_line_string_impl.rb +67 -0
  60. data/lib/rgeo/geography/simple_spherical/multi_point_impl.rb +67 -0
  61. data/lib/rgeo/geography/simple_spherical/multi_polygon_impl.rb +67 -0
  62. data/lib/rgeo/geography/simple_spherical/point_impl.rb +85 -0
  63. data/lib/rgeo/geography/simple_spherical/polygon_impl.rb +66 -0
  64. data/lib/rgeo/geos.rb +72 -0
  65. data/lib/rgeo/geos/factory.rb +260 -0
  66. data/lib/rgeo/geos/impl_additions.rb +57 -0
  67. data/lib/rgeo/geos/interface.rb +74 -0
  68. data/lib/rgeo/version.rb +52 -0
  69. data/tests/geos/tc_factory.rb +91 -0
  70. data/tests/geos/tc_geometry_collection.rb +226 -0
  71. data/tests/geos/tc_line_string.rb +310 -0
  72. data/tests/geos/tc_misc.rb +72 -0
  73. data/tests/geos/tc_multi_line_string.rb +211 -0
  74. data/tests/geos/tc_multi_point.rb +202 -0
  75. data/tests/geos/tc_multi_polygon.rb +210 -0
  76. data/tests/geos/tc_point.rb +305 -0
  77. data/tests/geos/tc_polygon.rb +240 -0
  78. data/tests/simple_mercator/tc_point.rb +303 -0
  79. data/tests/simple_mercator/tc_window.rb +219 -0
  80. data/tests/tc_geojson.rb +230 -0
  81. data/tests/tc_oneoff.rb +61 -0
  82. metadata +162 -0
@@ -0,0 +1,149 @@
1
+ # -----------------------------------------------------------------------------
2
+ #
3
+ # Common methods for Point geography features
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 Geography
40
+
41
+ module Common
42
+
43
+
44
+ module PointMethods
45
+
46
+
47
+ def _setup(x_, y_)
48
+ @x = x_.to_f
49
+ @y = y_.to_f
50
+ _validate_geometry
51
+ end
52
+
53
+
54
+ def x
55
+ @x
56
+ end
57
+
58
+
59
+ def y
60
+ @y
61
+ end
62
+
63
+
64
+ def eql?(rhs_)
65
+ rhs_.is_a?(self.class) && @x == rhs_.x && @y == rhs_.y
66
+ end
67
+ alias_method :==, :eql?
68
+
69
+
70
+ def cast(type_)
71
+ case type_
72
+ when Features::Point
73
+ self
74
+ when Features::GeometryCollection
75
+ factory.collection([self]) rescue nil
76
+ when Features::MultiPoint
77
+ factory.multi_point([self]) rescue nil
78
+ else
79
+ super
80
+ end
81
+ end
82
+
83
+
84
+ def dimension
85
+ 0
86
+ end
87
+
88
+
89
+ def geometry_type
90
+ Features::Point
91
+ end
92
+
93
+
94
+ def is_empty?
95
+ false
96
+ end
97
+
98
+
99
+ def is_simple?
100
+ true
101
+ end
102
+
103
+
104
+ def envelope
105
+ self
106
+ end
107
+
108
+
109
+ def boundary
110
+ factory.collection([])
111
+ end
112
+
113
+
114
+ def equals?(rhs_)
115
+ return false unless rhs_.factory.is_a?(Factory)
116
+ rhs_ = factory.convert(rhs_)
117
+ case rhs_
118
+ when Features::Point
119
+ if @y == 90
120
+ rhs_.y == 90
121
+ elsif @y == -90
122
+ rhs_.y == -90
123
+ else
124
+ rhs_.x == @x && rhs_.y == @y
125
+ end
126
+ when Features::LineString
127
+ rhs_.num_points > 0 && rhs_.points.all?{ |elem_| equals?(elem_) }
128
+ when Features::GeometryCollection
129
+ rhs_.num_geometries > 0 && rhs_.all?{ |elem_| equals?(elem_) }
130
+ else
131
+ false
132
+ end
133
+ end
134
+
135
+
136
+ alias_method :longitude, :x
137
+ alias_method :lon, :x
138
+ alias_method :latitude, :y
139
+ alias_method :lat, :y
140
+
141
+
142
+ end
143
+
144
+
145
+ end
146
+
147
+ end
148
+
149
+ end
@@ -0,0 +1,122 @@
1
+ # -----------------------------------------------------------------------------
2
+ #
3
+ # Common methods for Polygon geography features
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 Geography
40
+
41
+ module Common
42
+
43
+
44
+ module PolygonMethods
45
+
46
+
47
+ def _setup(exterior_ring_, interior_rings_)
48
+ @exterior_ring = exterior_ring_
49
+ @interior_rings = (interior_rings_ || []).map{ |elem_| factory.convert(elem_) }
50
+ unless Features::LinearRing.check_type(@exterior_ring)
51
+ raise Errors::InvalidGeometry, 'Exterior ring must be a LinearRing'
52
+ end
53
+ @interior_rings.each do |ring_|
54
+ unless Features::LinearRing.check_type(ring_)
55
+ raise Errors::InvalidGeometry, 'Interior ring must be a LinearRing'
56
+ end
57
+ end
58
+ _validate_geometry
59
+ end
60
+
61
+
62
+ def cast(type_)
63
+ case type_
64
+ when Features::Polygon
65
+ self
66
+ when Features::LinearRing
67
+ @exterior_ring
68
+ when Features::LineString
69
+ @exterior_ring.cast(type_)
70
+ when Features::GeometryCollection
71
+ factory.collection([self]) rescue nil
72
+ when Features::MultiPolygon
73
+ factory.multi_polygon([self]) rescue nil
74
+ else
75
+ super
76
+ end
77
+ end
78
+
79
+
80
+ def exterior_ring
81
+ @exterior_ring
82
+ end
83
+
84
+
85
+ def num_interior_rings
86
+ @interior_rings.size
87
+ end
88
+
89
+
90
+ def interior_ring_n(n_)
91
+ @interior_rings[n_]
92
+ end
93
+
94
+
95
+ def interior_rings
96
+ @interior_rings.dup
97
+ end
98
+
99
+
100
+ def dimension
101
+ 2
102
+ end
103
+
104
+
105
+ def geometry_type
106
+ Features::Polygon
107
+ end
108
+
109
+
110
+ def is_empty?
111
+ @exterior_ring.is_empty?
112
+ end
113
+
114
+
115
+ end
116
+
117
+
118
+ end
119
+
120
+ end
121
+
122
+ end
@@ -0,0 +1,136 @@
1
+ # -----------------------------------------------------------------------------
2
+ #
3
+ # Access to geographic data factories
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 Geography
40
+
41
+ @simple_spherical = nil
42
+ @simple_mercator = nil
43
+
44
+ class << self
45
+
46
+
47
+ # Geographic features provided by this factory perform calculations
48
+ # assuming a spherical earth. In other words, geodesics are treated
49
+ # as great circle arcs, and size and geometric calculations are
50
+ # treated accordingly. Distance and area calculations report results
51
+ # in meters. This makes this implementation ideal for everyday
52
+ # calculations on the globe where accuracy within about 0.5 percent
53
+ # is sufficient.
54
+ #
55
+ # Currently, this implementation is incomplete. Basic input/output
56
+ # and a few geodesic functions are implemented, but many return nil.
57
+ #
58
+ # Simple_spherical features report SRID=4326, indicating EPSG 4326
59
+ # (i.e. the WGS84 spheroid and the lat/lon system commonly used by
60
+ # most GIS systems).
61
+ # This is technically not correct, for two reasons:
62
+ #
63
+ # * We are running calculations on a spherical approximation of the
64
+ # WGS84 spheroid rather than the ellipsoidal shape itself.
65
+ # * While most functions use the EPSG 4326 unit of degrees longitude
66
+ # and latitude, a few (specifically, distance and area calculations)
67
+ # return their results in meters.
68
+ #
69
+ # We, however, hereby punt on this issue for this particular factory,
70
+ # on the theory that, for "most applications" that we expect will
71
+ # want to use this library, these behaviors are sufficient, and the
72
+ # SRID imprecision isn't crucial.
73
+ # Note, however, that this means features created with this factory
74
+ # may generate slightly different results from geodesic calculations
75
+ # than those generated by, e.g., PostGIS (unless you direct PostGIS
76
+ # to use spherical geodesics).
77
+
78
+ def simple_spherical(opts_={}) # :nodoc:
79
+ @simple_spherical ||= Geography::Factory.new(Geography::SimpleSpherical)
80
+ end
81
+
82
+
83
+ # Geographic features provided by this factory perform calculations
84
+ # on the simple mercator projection currently used by Google and
85
+ # Bing maps. This makes this implementation ideal for representing
86
+ # and performing calculations on features to be visualized using
87
+ # those technologies. Note, however, that significant discrepancies
88
+ # may occur for large features between the "mapping visualization"
89
+ # sizes and shapes, and the actual sizes and shapes on the globe,
90
+ # because the mercator projection, like all projections of a
91
+ # non-flat earth onto a flat coordinate system, does introduce
92
+ # distortions (especially near the poles.)
93
+ #
94
+ # Distance and area computations return results in meters, whereas
95
+ # all coordinates are represented in degrees latitude and longitude.
96
+ #
97
+ # This is not a true projected spatial reference: point coordinates
98
+ # are still represented in degrees latitude and longitude. However,
99
+ # computations are done in the projected spatial reference. (That
100
+ # spatial reference is EPSG 3857, for the interested.) This means,
101
+ # for example, that a line segment whose endpoints fall on a line of
102
+ # latitude away from the equator will follow the line of latitude
103
+ # rather than the actual geodesic (which will curve away from the
104
+ # equator in the projected coordinate system). It also means that
105
+ # latitudes very near the poles are excluded. Specifically,
106
+ # latitudes are restricted to the range (-85.05112877980659,
107
+ # 85.05112877980659), which conveniently results in a square
108
+ # projected domain.
109
+ #
110
+ # In general, this implementation is designed specifically for
111
+ # mapping applications using Google and Bing maps, and any others
112
+ # that use the same projection.
113
+ #
114
+ # Simple_mercator features report SRID=4326, indicating EPSG 4326
115
+ # (i.e. the WGS84 spheroid and the lat/lon system commonly used by
116
+ # most GIS systems).
117
+ # This is actualy grossly inaccurate for a number of reasons, chief
118
+ # among them being that calculations are being done on a projection,
119
+ # whereas EPSG 4326 calculations are supposed to be done on the
120
+ # spheroid. However, we continue to report SRID=4326 because the x
121
+ # and y coordinates represent latitude and longitude rather than
122
+ # projected coordinates. There is no EPSG spatial reference that
123
+ # describes the <i>actual</i> behavior of the common map
124
+ # visualization APIs, so we've decided to fudge on this in the
125
+ # interest of being true to our expected application use cases.
126
+
127
+ def simple_mercator(opts_={})
128
+ @simple_mercator ||= Geography::Factory.new(Geography::SimpleMercator, :buffer_resolution => opts_[:buffer_resolution])
129
+ end
130
+
131
+
132
+ end
133
+
134
+ end
135
+
136
+ end
@@ -0,0 +1,246 @@
1
+ # -----------------------------------------------------------------------------
2
+ #
3
+ # Geographic data 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 Geography
40
+
41
+
42
+ # This class implements the various factories for geography features.
43
+ # See methods of the RGeo::Geography module for the API for creating
44
+ # geography factories.
45
+
46
+ class Factory
47
+
48
+ include Features::Factory
49
+
50
+
51
+ def initialize(namespace_, opts_={}) # :nodoc:
52
+ @namespace = namespace_
53
+ @opts = opts_.dup
54
+ @projector = @namespace.const_get(:Projector).new(self, opts_) rescue nil
55
+ end
56
+
57
+
58
+ # Equivalence test.
59
+
60
+ def eql?(rhs_)
61
+ rhs_.is_a?(self.class) && @namespace == rhs_.instance_variable_get(:@namespace) &&
62
+ @opts == rhs_.instance_variable_get(:@opts)
63
+ end
64
+ alias_method :==, :eql?
65
+
66
+
67
+ # Returns true if this factory supports a projection.
68
+
69
+ def has_projection?
70
+ !@projector.nil?
71
+ end
72
+
73
+
74
+ # Returns the factory for the projected coordinate space,
75
+ # or nil if this factory does not support a projection.
76
+
77
+ def projection_factory
78
+ @projector ? @projector.projection_factory : nil
79
+ end
80
+
81
+
82
+ # Projects the given geometry into the projected coordinate space,
83
+ # and returns the projected geometry.
84
+ # Returns nil if this factory does not support a projection.
85
+ # Raises Errors::IllegalGeometry if the given geometry is not of
86
+ # this factory.
87
+
88
+ def project(geometry_)
89
+ return nil unless @projector
90
+ unless geometry_.factory == self
91
+ raise Errors::IllegalGeometry, 'Wrong geometry type'
92
+ end
93
+ @projector.project(geometry_)
94
+ end
95
+
96
+
97
+ # Reverse-projects the given geometry from the projected coordinate
98
+ # space into lat-long space.
99
+ # Raises Errors::IllegalGeometry if the given geometry is not of
100
+ # the projection defined by this factory.
101
+
102
+ def unproject(geometry_)
103
+ unless @projector && @projector.projection_factory == geometry_.factory
104
+ raise Errors::IllegalGeometry, 'You can unproject only features that are in the projected coordinate space.'
105
+ end
106
+ @projector.unproject(geometry_)
107
+ end
108
+
109
+
110
+ # Returns true if this factory supports a projection and the
111
+ # projection wraps its x (easting) direction. For example, a
112
+ # Mercator projection wraps, but a local projection that is valid
113
+ # only for a small area does not wrap.
114
+
115
+ def projection_wraps?
116
+ @projector ? @projector.wraps? : nil
117
+ end
118
+
119
+
120
+ # Returns a ProjectedWindow specifying the limits of the domain of
121
+ # the projection space.
122
+ # Returns nil if this factory does not support a projection.
123
+
124
+ def projection_limits_window
125
+ @projector ? (@projection_limits_window ||= @projector.limits_window) : nil
126
+ end
127
+
128
+
129
+ # See ::RGeo::Features::Factory#parse_wkt
130
+
131
+ def parse_wkt(str_)
132
+ Common::Helper.parse_wkt(str_, self)
133
+ end
134
+
135
+
136
+ # See ::RGeo::Features::Factory#parse_wkb
137
+
138
+ def parse_wkb(str_)
139
+ Common::Helper.parse_wkb(str_, self)
140
+ end
141
+
142
+
143
+ # See ::RGeo::Features::Factory#point
144
+
145
+ def point(x_, y_)
146
+ @namespace.const_get(:PointImpl).new(self, x_, y_) rescue nil
147
+ end
148
+
149
+
150
+ # See ::RGeo::Features::Factory#line_string
151
+
152
+ def line_string(points_)
153
+ @namespace.const_get(:LineStringImpl).new(self, points_) rescue nil
154
+ end
155
+
156
+
157
+ # See ::RGeo::Features::Factory#line
158
+
159
+ def line(start_, end_)
160
+ @namespace.const_get(:LineImpl).new(self, start_, end_) rescue nil
161
+ end
162
+
163
+
164
+ # See ::RGeo::Features::Factory#linear_ring
165
+
166
+ def linear_ring(points_)
167
+ if points_.size > 1 && points_.first != points_.last
168
+ points_ << points_.first
169
+ end
170
+ @namespace.const_get(:LinearRingImpl).new(self, points_) rescue nil
171
+ end
172
+
173
+
174
+ # See ::RGeo::Features::Factory#polygon
175
+
176
+ def polygon(outer_ring_, inner_rings_=nil)
177
+ inner_rings_ = inner_rings_.to_a unless inner_rings_.kind_of?(::Array)
178
+ @namespace.const_get(:PolygonImpl).new(self, outer_ring_, inner_rings_) rescue nil
179
+ end
180
+
181
+
182
+ # See ::RGeo::Features::Factory#collection
183
+
184
+ def collection(elems_)
185
+ @namespace.const_get(:GeometryCollectionImpl).new(self, elems_) rescue nil
186
+ end
187
+
188
+
189
+ # See ::RGeo::Features::Factory#multi_point
190
+
191
+ def multi_point(elems_)
192
+ @namespace.const_get(:MultiPointImpl).new(self, elems_) rescue nil
193
+ end
194
+
195
+
196
+ # See ::RGeo::Features::Factory#multi_line_string
197
+
198
+ def multi_line_string(elems_)
199
+ @namespace.const_get(:MultiLineStringImpl).new(self, elems_) rescue nil
200
+ end
201
+
202
+
203
+ # See ::RGeo::Features::Factory#multi_polygon
204
+
205
+ def multi_polygon(elems_)
206
+ @namespace.const_get(:MultiPolygonImpl).new(self, elems_) rescue nil
207
+ end
208
+
209
+
210
+ # See ::RGeo::Features::Factory#convert
211
+
212
+ def convert(original_, force_new_=false)
213
+ if self == original_.factory
214
+ force_new_ ? original_.dup : original_
215
+ else
216
+ case original_
217
+ when Features::Point
218
+ @namespace.const_get(:PointImpl).new(self, original_.x, original_.y) rescue nil
219
+ when Features::Line
220
+ @namespace.const_get(:LineImpl).new(self, original_.start_point, original_.end_point) rescue nil
221
+ when Features::LinearRing
222
+ @namespace.const_get(:LinearRingImpl).new(self, original_.points) rescue nil
223
+ when Features::LineString
224
+ @namespace.const_get(:LineStringImpl).new(self, original_.points) rescue nil
225
+ when Features::Polygon
226
+ @namespace.const_get(:PolygonImpl).new(self, original_.exterior_ring, original_.interior_rings) rescue nil
227
+ when Features::MultiPoint
228
+ @namespace.const_get(:MultiPointImpl).new(self, original_.to_a) rescue nil
229
+ when Features::MultiLineString
230
+ @namespace.const_get(:MultiLineStringImpl).new(self, original_.to_a) rescue nil
231
+ when Features::MultiPolygon
232
+ @namespace.const_get(:MultiPolygonImpl).new(self, original_.to_a) rescue nil
233
+ when Features::GeometryCollection
234
+ @namespace.const_get(:GeometryCollectionImpl).new(self, original_.to_a) rescue nil
235
+ else
236
+ nil
237
+ end
238
+ end
239
+ end
240
+
241
+
242
+ end
243
+
244
+ end
245
+
246
+ end