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.
Files changed (150) hide show
  1. data/History.rdoc +199 -0
  2. data/README.rdoc +172 -0
  3. data/Spatial_Programming_With_RGeo.rdoc +440 -0
  4. data/Version +1 -0
  5. data/ext/geos_c_impl/extconf.rb +84 -0
  6. data/ext/geos_c_impl/factory.c +468 -0
  7. data/ext/geos_c_impl/factory.h +224 -0
  8. data/ext/geos_c_impl/geometry.c +705 -0
  9. data/ext/geos_c_impl/geometry.h +55 -0
  10. data/ext/geos_c_impl/geometry_collection.c +482 -0
  11. data/ext/geos_c_impl/geometry_collection.h +69 -0
  12. data/ext/geos_c_impl/line_string.c +509 -0
  13. data/ext/geos_c_impl/line_string.h +64 -0
  14. data/ext/geos_c_impl/main.c +70 -0
  15. data/ext/geos_c_impl/point.c +193 -0
  16. data/ext/geos_c_impl/point.h +62 -0
  17. data/ext/geos_c_impl/polygon.c +265 -0
  18. data/ext/geos_c_impl/polygon.h +66 -0
  19. data/ext/geos_c_impl/preface.h +50 -0
  20. data/ext/proj4_c_impl/extconf.rb +88 -0
  21. data/ext/proj4_c_impl/main.c +271 -0
  22. data/lib/rgeo.rb +124 -0
  23. data/lib/rgeo/cartesian.rb +60 -0
  24. data/lib/rgeo/cartesian/analysis.rb +118 -0
  25. data/lib/rgeo/cartesian/bounding_box.rb +337 -0
  26. data/lib/rgeo/cartesian/calculations.rb +161 -0
  27. data/lib/rgeo/cartesian/factory.rb +209 -0
  28. data/lib/rgeo/cartesian/feature_classes.rb +173 -0
  29. data/lib/rgeo/cartesian/feature_methods.rb +106 -0
  30. data/lib/rgeo/cartesian/interface.rb +150 -0
  31. data/lib/rgeo/coord_sys.rb +79 -0
  32. data/lib/rgeo/coord_sys/cs/entities.rb +1524 -0
  33. data/lib/rgeo/coord_sys/cs/factories.rb +208 -0
  34. data/lib/rgeo/coord_sys/cs/wkt_parser.rb +308 -0
  35. data/lib/rgeo/coord_sys/proj4.rb +312 -0
  36. data/lib/rgeo/coord_sys/srs_database/active_record_table.rb +194 -0
  37. data/lib/rgeo/coord_sys/srs_database/interface.rb +165 -0
  38. data/lib/rgeo/coord_sys/srs_database/proj4_data.rb +188 -0
  39. data/lib/rgeo/coord_sys/srs_database/sr_org.rb +108 -0
  40. data/lib/rgeo/coord_sys/srs_database/url_reader.rb +108 -0
  41. data/lib/rgeo/error.rb +63 -0
  42. data/lib/rgeo/feature.rb +88 -0
  43. data/lib/rgeo/feature/curve.rb +156 -0
  44. data/lib/rgeo/feature/factory.rb +332 -0
  45. data/lib/rgeo/feature/factory_generator.rb +138 -0
  46. data/lib/rgeo/feature/geometry.rb +614 -0
  47. data/lib/rgeo/feature/geometry_collection.rb +129 -0
  48. data/lib/rgeo/feature/line.rb +66 -0
  49. data/lib/rgeo/feature/line_string.rb +102 -0
  50. data/lib/rgeo/feature/linear_ring.rb +66 -0
  51. data/lib/rgeo/feature/multi_curve.rb +113 -0
  52. data/lib/rgeo/feature/multi_line_string.rb +66 -0
  53. data/lib/rgeo/feature/multi_point.rb +73 -0
  54. data/lib/rgeo/feature/multi_polygon.rb +97 -0
  55. data/lib/rgeo/feature/multi_surface.rb +116 -0
  56. data/lib/rgeo/feature/point.rb +120 -0
  57. data/lib/rgeo/feature/polygon.rb +141 -0
  58. data/lib/rgeo/feature/surface.rb +122 -0
  59. data/lib/rgeo/feature/types.rb +305 -0
  60. data/lib/rgeo/geographic.rb +75 -0
  61. data/lib/rgeo/geographic/factory.rb +287 -0
  62. data/lib/rgeo/geographic/interface.rb +410 -0
  63. data/lib/rgeo/geographic/proj4_projector.rb +98 -0
  64. data/lib/rgeo/geographic/projected_feature_classes.rb +213 -0
  65. data/lib/rgeo/geographic/projected_feature_methods.rb +228 -0
  66. data/lib/rgeo/geographic/projected_window.rb +467 -0
  67. data/lib/rgeo/geographic/simple_mercator_projector.rb +157 -0
  68. data/lib/rgeo/geographic/spherical_feature_classes.rb +212 -0
  69. data/lib/rgeo/geographic/spherical_feature_methods.rb +97 -0
  70. data/lib/rgeo/geographic/spherical_math.rb +206 -0
  71. data/lib/rgeo/geos.rb +72 -0
  72. data/lib/rgeo/geos/factory.rb +301 -0
  73. data/lib/rgeo/geos/impl_additions.rb +76 -0
  74. data/lib/rgeo/geos/interface.rb +139 -0
  75. data/lib/rgeo/geos/zm_factory.rb +275 -0
  76. data/lib/rgeo/geos/zm_impl.rb +432 -0
  77. data/lib/rgeo/impl_helper.rb +53 -0
  78. data/lib/rgeo/impl_helper/basic_geometry_collection_methods.rb +235 -0
  79. data/lib/rgeo/impl_helper/basic_geometry_methods.rb +85 -0
  80. data/lib/rgeo/impl_helper/basic_line_string_methods.rb +197 -0
  81. data/lib/rgeo/impl_helper/basic_point_methods.rb +138 -0
  82. data/lib/rgeo/impl_helper/basic_polygon_methods.rb +121 -0
  83. data/lib/rgeo/impl_helper/math.rb +50 -0
  84. data/lib/rgeo/version.rb +52 -0
  85. data/lib/rgeo/wkrep.rb +72 -0
  86. data/lib/rgeo/wkrep/wkb_generator.rb +267 -0
  87. data/lib/rgeo/wkrep/wkb_parser.rb +315 -0
  88. data/lib/rgeo/wkrep/wkt_generator.rb +275 -0
  89. data/lib/rgeo/wkrep/wkt_parser.rb +496 -0
  90. data/test/common/geometry_collection_tests.rb +238 -0
  91. data/test/common/line_string_tests.rb +324 -0
  92. data/test/common/multi_line_string_tests.rb +209 -0
  93. data/test/common/multi_point_tests.rb +201 -0
  94. data/test/common/multi_polygon_tests.rb +208 -0
  95. data/test/common/point_tests.rb +331 -0
  96. data/test/common/polygon_tests.rb +232 -0
  97. data/test/coord_sys/tc_active_record_table.rb +102 -0
  98. data/test/coord_sys/tc_ogc_cs.rb +356 -0
  99. data/test/coord_sys/tc_proj4.rb +138 -0
  100. data/test/coord_sys/tc_proj4_srs_data.rb +76 -0
  101. data/test/coord_sys/tc_sr_org.rb +70 -0
  102. data/test/coord_sys/tc_url_reader.rb +82 -0
  103. data/test/geos/tc_factory.rb +91 -0
  104. data/test/geos/tc_geometry_collection.rb +62 -0
  105. data/test/geos/tc_line_string.rb +62 -0
  106. data/test/geos/tc_misc.rb +72 -0
  107. data/test/geos/tc_multi_line_string.rb +62 -0
  108. data/test/geos/tc_multi_point.rb +62 -0
  109. data/test/geos/tc_multi_polygon.rb +63 -0
  110. data/test/geos/tc_point.rb +86 -0
  111. data/test/geos/tc_polygon.rb +86 -0
  112. data/test/geos/tc_zmfactory.rb +85 -0
  113. data/test/projected_geographic/tc_geometry_collection.rb +62 -0
  114. data/test/projected_geographic/tc_line_string.rb +62 -0
  115. data/test/projected_geographic/tc_multi_line_string.rb +62 -0
  116. data/test/projected_geographic/tc_multi_point.rb +62 -0
  117. data/test/projected_geographic/tc_multi_polygon.rb +63 -0
  118. data/test/projected_geographic/tc_point.rb +93 -0
  119. data/test/projected_geographic/tc_polygon.rb +62 -0
  120. data/test/simple_cartesian/tc_calculations.rb +145 -0
  121. data/test/simple_cartesian/tc_geometry_collection.rb +69 -0
  122. data/test/simple_cartesian/tc_line_string.rb +70 -0
  123. data/test/simple_cartesian/tc_multi_line_string.rb +67 -0
  124. data/test/simple_cartesian/tc_multi_point.rb +67 -0
  125. data/test/simple_cartesian/tc_multi_polygon.rb +70 -0
  126. data/test/simple_cartesian/tc_point.rb +91 -0
  127. data/test/simple_cartesian/tc_polygon.rb +67 -0
  128. data/test/simple_mercator/tc_geometry_collection.rb +62 -0
  129. data/test/simple_mercator/tc_line_string.rb +62 -0
  130. data/test/simple_mercator/tc_multi_line_string.rb +62 -0
  131. data/test/simple_mercator/tc_multi_point.rb +62 -0
  132. data/test/simple_mercator/tc_multi_polygon.rb +63 -0
  133. data/test/simple_mercator/tc_point.rb +93 -0
  134. data/test/simple_mercator/tc_polygon.rb +62 -0
  135. data/test/simple_mercator/tc_window.rb +219 -0
  136. data/test/spherical_geographic/tc_calculations.rb +203 -0
  137. data/test/spherical_geographic/tc_geometry_collection.rb +70 -0
  138. data/test/spherical_geographic/tc_line_string.rb +70 -0
  139. data/test/spherical_geographic/tc_multi_line_string.rb +67 -0
  140. data/test/spherical_geographic/tc_multi_point.rb +67 -0
  141. data/test/spherical_geographic/tc_multi_polygon.rb +70 -0
  142. data/test/spherical_geographic/tc_point.rb +100 -0
  143. data/test/spherical_geographic/tc_polygon.rb +67 -0
  144. data/test/tc_cartesian_analysis.rb +107 -0
  145. data/test/tc_oneoff.rb +63 -0
  146. data/test/wkrep/tc_wkb_generator.rb +249 -0
  147. data/test/wkrep/tc_wkb_parser.rb +353 -0
  148. data/test/wkrep/tc_wkt_generator.rb +362 -0
  149. data/test/wkrep/tc_wkt_parser.rb +480 -0
  150. metadata +267 -0
@@ -0,0 +1,208 @@
1
+ # -----------------------------------------------------------------------------
2
+ #
3
+ # OGC CS factory 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 module contains an implementation of the CS (coordinate
43
+ # systems) package of the OGC Coordinate Transform spec. It provides
44
+ # classes for representing ellipsoids, datums, coordinate systems,
45
+ # and other related concepts, as well as a parser for the WKT format
46
+ # for specifying coordinate systems.
47
+ #
48
+ # Generally, the easiest way to create coordinate system objects is
49
+ # to use RGeo::CoordSys::CS.create_from_wkt, which parses the WKT
50
+ # format. You can also use the create methods available for each
51
+ # object class.
52
+ #
53
+ # Most but not all of the spec is implemented here.
54
+ # Currently missing are:
55
+ #
56
+ # * XML format is not implemented. We're assuming that WKT is the
57
+ # preferred format.
58
+ # * The PT and CT packages are not implemented.
59
+ # * FittedCoordinateSystem is not implemented.
60
+ # * The defaultEnvelope attribute of CS_CoordinateSystem is not
61
+ # implemented.
62
+
63
+ module CS
64
+
65
+
66
+ # A class implementing the CS_CoordinateSystemFactory interface.
67
+ # It provides methods for building up complex objects from simpler
68
+ # objects or values.
69
+ #
70
+ # Note that the methods of CS_CoordinateSystemFactory do not provide
71
+ # facilities for setting the authority. If you need to set authority
72
+ # values, use the create methods for the object classes themselves.
73
+
74
+ class CoordinateSystemFactory
75
+
76
+
77
+ # Create a CompoundCoordinateSystem from a name, and two
78
+ # constituent coordinate systems.
79
+
80
+ def create_compound_coordinate_system(name_, head_, tail_)
81
+ CompoundCoordinateSystem.create(name_, head_, tail_)
82
+ end
83
+
84
+
85
+ # Create an Ellipsoid from a name, semi-major axis, and semi-minor
86
+ # axis. You can also provide a LinearUnit, but this is optional
87
+ # and may be set to nil.
88
+
89
+ def create_ellipsoid(name_, semi_major_axis_, semi_minor_axis_, linear_unit_)
90
+ Ellipsoid.create_ellipsoid(name_, semi_major_axis_, semi_minor_axis_, linear_unit_)
91
+ end
92
+
93
+
94
+ # Create an Ellipsoid from a name, semi-major axis, and an inverse
95
+ # flattening factor. You can also provide a LinearUnit, but this
96
+ # is optional and may be set to nil.
97
+
98
+ def create_flattened_sphere(name_, semi_major_axis_, inverse_flattening_, linear_unit_)
99
+ Ellipsoid.create_flattened_sphere(name_, semi_major_axis_, inverse_flattening_, linear_unit_)
100
+ end
101
+
102
+
103
+ # Create any object given the OGC WKT format. Raises
104
+ # Error::ParseError if a syntax error is encounterred.
105
+
106
+ def create_from_wkt(str_)
107
+ WKTParser.new(str_).parse
108
+ end
109
+
110
+
111
+ # Create a GeographicCoordinateSystem, given a name, an
112
+ # AngularUnit, a HorizontalDatum, a PrimeMeridian, and two
113
+ # AxisInfo objects. The AxisInfo objects are optional and may be
114
+ # set to nil.
115
+
116
+ def create_geographic_coordinate_system(name_, angular_unit_, horizontal_datum_, prime_meridian_, axis0_, axis1_)
117
+ GeographicCoordinateSystem.create(name_, angular_unit_, horizontal_datum_, prime_meridian_, axis0_, axis1_)
118
+ end
119
+
120
+
121
+ # Create a HorizontalDatum given a name, a horizontal datum type
122
+ # code, an Ellipsoid, and a WGS84ConversionInfo. The
123
+ # WGS84ConversionInfo is optional and may be set to nil.
124
+
125
+ def create_horizontal_datum(name_, horizontal_datum_type_, ellipsoid_, to_wgs84_)
126
+ HorizontalDatum.create(name_, horizontal_datum_type_, ellipsoid_, to_wgs84_)
127
+ end
128
+
129
+
130
+ # Create a LocalCoordinateSystem given a name, a LocalDatum, a
131
+ # Unit, and an array of at least one AxisInfo.
132
+
133
+ def create_local_coordinate_system(name_, datum_, unit_, axes_)
134
+ LocalCoordinateSystem.create(name_, datum_, unit_, axes_)
135
+ end
136
+
137
+
138
+ # Create a LocalDatum given a name and a local datum type code.
139
+
140
+ def create_local_datum(name_, local_datum_type_)
141
+ LocalDatum.create(name, local_datum_type_)
142
+ end
143
+
144
+
145
+ # Create a PrimeMeridian given a name, an AngularUnit, and a
146
+ # longitude offset.
147
+
148
+ def create_prime_meridian(name_, angular_unit_, longitude_)
149
+ PrimeMeridian.create(name, angular_unit_, longitude_)
150
+ end
151
+
152
+
153
+ # Create a ProjectedCoordinateSystem given a name, a
154
+ # GeographicCoordinateSystem, and Projection, a LinearUnit, and
155
+ # two AxisInfo objects. The AxisInfo objects are optional and may
156
+ # be set to nil.
157
+
158
+ def create_projected_coordinate_system(name_, gcs_, projection_, linear_unit_, axis0_, axis1_)
159
+ ProjectedCoordinateSystem.create(name_, gcs_, projection_, linear_unit_, axis0_, axis1_)
160
+ end
161
+
162
+
163
+ # Create a Projection given a name, a projection class, and an
164
+ # array of ProjectionParameter.
165
+
166
+ def create_projection(name_, wkt_projection_class_, parameters_)
167
+ Projection.create(name_, wkt_projection_class_, parameters_)
168
+ end
169
+
170
+
171
+ # Create a VerticalCoordinateSystem given a name, a VerticalDatum,
172
+ # a VerticalUnit, and an AxisInfo. The AxisInfo is optional and
173
+ # may be nil.
174
+
175
+ def create_vertical_coordinate_system(name_, vertical_datum_, vertical_unit_, axis_)
176
+ VerticalCoordinateSystem.create(name_, vertical_datum_, vertical_unit_, axis_)
177
+ end
178
+
179
+
180
+ # Create a VerticalDatum given a name ane a datum type code.
181
+
182
+ def create_vertical_datum(name_, vertical_datum_type_)
183
+ VerticalDatum.create(name_, vertical_datum_type_)
184
+ end
185
+
186
+
187
+ end
188
+
189
+
190
+ class << self
191
+
192
+
193
+ # Parsees OGC WKT format and returns the object created. Raises
194
+ # Error::ParseError if a syntax error is encounterred.
195
+
196
+ def create_from_wkt(str_)
197
+ WKTParser.new(str_).parse
198
+ end
199
+
200
+
201
+ end
202
+
203
+
204
+ end
205
+
206
+ end
207
+
208
+ end
@@ -0,0 +1,308 @@
1
+ # -----------------------------------------------------------------------------
2
+ #
3
+ # OGC CS wkt parser 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
+ module CS
43
+
44
+
45
+ class WKTParser # :nodoc:
46
+
47
+ def initialize(str_)
48
+ @scanner = ::StringScanner.new(str_)
49
+ next_token
50
+ end
51
+
52
+
53
+ def parse(containing_type_=nil)
54
+ if @cur_token.kind_of?(QuotedString) ||
55
+ @cur_token.kind_of?(::Numeric) ||
56
+ (containing_type_ == 'AXIS' && @cur_token.kind_of?(TypeString))
57
+ value_ = @cur_token
58
+ next_token
59
+ return value_
60
+ end
61
+ unless @cur_token.kind_of?(TypeString)
62
+ raise Error::ParseError("Found token #{@cur_token} when we expected a value")
63
+ end
64
+ type_ = @cur_token
65
+ next_token
66
+ consume_token_type(:begin)
67
+ args_ = ArgumentList.new
68
+ args_ << parse(type_)
69
+ loop do
70
+ break unless @cur_token == :comma
71
+ next_token
72
+ args_ << parse(type_)
73
+ end
74
+ consume_token_type(:end)
75
+ obj_ = nil
76
+ case type_
77
+ when 'AUTHORITY'
78
+ obj_ = AuthorityClause.new(args_.shift(QuotedString), args_.shift(QuotedString))
79
+ when 'AXIS'
80
+ obj_ = AxisInfo.create(args_.shift(QuotedString), args_.shift(TypeString))
81
+ when 'TOWGS84'
82
+ bursa_wolf_params_ = args_.find_all(::Numeric)
83
+ unless bursa_wolf_params_.size == 7
84
+ raise Error::ParseError("Expected 7 Bursa Wolf parameters but found #{bursa_wolf_params_.size}")
85
+ end
86
+ obj_ = WGS84ConversionInfo.create(*bursa_wolf_params_)
87
+ when 'UNIT'
88
+ case containing_type_
89
+ when 'GEOCCS', 'VERT_CS', 'PROJCS', 'SPHEROID'
90
+ klass_ = LinearUnit
91
+ when 'GEOGCS'
92
+ klass_ = AngularUnit
93
+ else
94
+ klass_ = Unit
95
+ end
96
+ obj_ = klass_.create(args_.shift(QuotedString), args_.shift(::Numeric), *args_.find_first(AuthorityClause).to_a)
97
+ when 'PARAMETER'
98
+ obj_ = ProjectionParameter.create(args_.shift(QuotedString), args_.shift(::Numeric))
99
+ when 'PRIMEM'
100
+ obj_ = PrimeMeridian.create(args_.shift(QuotedString), nil, args_.shift(::Numeric), *args_.find_first(AuthorityClause).to_a)
101
+ when 'SPHEROID'
102
+ obj_ = Ellipsoid.create_flattened_sphere(args_.shift(QuotedString), args_.shift(::Numeric), args_.shift(::Numeric), args_.find_first(LinearUnit), *args_.find_first(AuthorityClause).to_a)
103
+ when 'PROJECTION'
104
+ name_ = args_.shift(QuotedString)
105
+ obj_ = Projection.create(name_, name_, args_.find_all(ProjectionParameter), *args_.find_first(AuthorityClause).to_a)
106
+ when 'DATUM'
107
+ name_ = args_.shift(QuotedString)
108
+ ellipsoid_ = args_.find_first(Ellipsoid)
109
+ to_wgs84_ = args_.find_first(WGS84ConversionInfo)
110
+ obj_ = HorizontalDatum.create(name_, HD_GEOCENTRIC, ellipsoid_, to_wgs84_, *args_.find_first(AuthorityClause).to_a)
111
+ when 'VERT_DATUM'
112
+ obj_ = VerticalDatum.create(args_.shift(QuotedString), args_.shift(::Numeric), *args_.find_first(AuthorityClause).to_a)
113
+ when 'LOCAL_DATUM'
114
+ obj_ = LocalDatum.create(args_.shift(QuotedString), args_.shift(::Numeric), *args_.find_first(AuthorityClause).to_a)
115
+ when 'COMPD_CS'
116
+ obj_ = CompoundCoordinateSystem.create(args_.shift(QuotedString), args_.shift(CoordinateSystem), args_.shift(CoordinateSystem), *args_.find_first(AuthorityClause).to_a)
117
+ when 'LOCAL_CS'
118
+ name_ = args_.shift(QuotedString)
119
+ local_datum_ = args_.find_first(LocalDatum)
120
+ unit_ = args_.find_first(Unit)
121
+ axes_ = args_.find_all(AxisInfo)
122
+ unless axes_.size > 0
123
+ raise Error::ParseError("Expected at least one AXIS in a LOCAL_CS")
124
+ end
125
+ obj_ = LocalCoordinateSystem.create(name_, local_datum_, unit_, axes_, *args_.find_first(AuthorityClause).to_a)
126
+ when 'GEOCCS'
127
+ name_ = args_.shift(QuotedString)
128
+ horizontal_datum_ = args_.find_first(HorizontalDatum)
129
+ prime_meridian_ = args_.find_first(PrimeMeridian)
130
+ linear_unit_ = args_.find_first(LinearUnit)
131
+ axes_ = args_.find_all(AxisInfo)
132
+ unless axes_.size == 0 || axes_.size == 3
133
+ raise Error::ParseError("GEOCCS must contain either 0 or 3 AXIS parameters")
134
+ end
135
+ obj_ = GeocentricCoordinateSystem.create(name_, horizontal_datum_, prime_meridian_, linear_unit_, axes_[0], axes_[1], axes_[2], *args_.find_first(AuthorityClause).to_a)
136
+ when 'VERT_CS'
137
+ name_ = args_.shift(QuotedString)
138
+ vertical_datum_ = args_.find_first(VerticalDatum)
139
+ linear_unit_ = args_.find_first(LinearUnit)
140
+ axis_ = args_.find_first(AxisInfo)
141
+ obj_ = VerticalCoordinateSystem.create(name_, vertical_datum_, linear_unit_, axis_, *args_.find_first(AuthorityClause).to_a)
142
+ when 'GEOGCS'
143
+ name_ = args_.shift(QuotedString)
144
+ horizontal_datum_ = args_.find_first(HorizontalDatum)
145
+ prime_meridian_ = args_.find_first(PrimeMeridian)
146
+ angular_unit_ = args_.find_first(AngularUnit)
147
+ axes_ = args_.find_all(AxisInfo)
148
+ unless axes_.size == 0 || axes_.size == 2
149
+ raise Error::ParseError("GEOGCS must contain either 0 or 2 AXIS parameters")
150
+ end
151
+ obj_ = GeographicCoordinateSystem.create(name_, angular_unit_, horizontal_datum_, prime_meridian_, axes_[0], axes_[1], *args_.find_first(AuthorityClause).to_a)
152
+ when 'PROJCS'
153
+ name_ = args_.shift(QuotedString)
154
+ geographic_coordinate_system_ = args_.find_first(GeographicCoordinateSystem)
155
+ projection_ = args_.find_first(Projection)
156
+ parameters_ = args_.find_all(ProjectionParameter)
157
+ projection_.instance_variable_get(:@parameters).concat(parameters_)
158
+ linear_unit_ = args_.find_first(LinearUnit)
159
+ axes_ = args_.find_all(AxisInfo)
160
+ unless axes_.size == 0 || axes_.size == 2
161
+ raise Error::ParseError("PROJCS must contain either 0 or 2 AXIS parameters")
162
+ end
163
+ obj_ = ProjectedCoordinateSystem.create(name_, geographic_coordinate_system_, projection_, linear_unit_, axes_[0], axes_[1], *args_.find_first(AuthorityClause).to_a)
164
+ else
165
+ raise Error::ParseError, "Unrecognized type: #{type_}"
166
+ end
167
+ args_.assert_empty
168
+ obj_
169
+ end
170
+
171
+
172
+ def consume_token_type(type_) # :nodoc:
173
+ expect_token_type(type_)
174
+ tok_ = @cur_token
175
+ next_token
176
+ tok_
177
+ end
178
+
179
+ def expect_token_type(type_) # :nodoc:
180
+ unless type_ === @cur_token
181
+ raise Error::ParseError, "#{type_.inspect} expected but #{@cur_token.inspect} found."
182
+ end
183
+ end
184
+
185
+ def next_token # :nodoc:
186
+ @scanner.skip(/\s+/)
187
+ case @scanner.peek(1)
188
+ when '"'
189
+ @scanner.getch
190
+ @cur_token = QuotedString.new(@scanner.scan(/[^"]*/))
191
+ @scanner.getch
192
+ when ','
193
+ @scanner.getch
194
+ @cur_token = :comma
195
+ when '(','['
196
+ @scanner.getch
197
+ @cur_token = :begin
198
+ when ']',')'
199
+ @scanner.getch
200
+ @cur_token = :end
201
+ when /[a-zA-Z]/
202
+ @cur_token = TypeString.new(@scanner.scan(/[a-zA-Z]\w*/))
203
+ when '', nil
204
+ @cur_token = nil
205
+ else
206
+ @scanner.scan_until(/[^\s\(\)\[\],"]+/)
207
+ token_ = @scanner.matched
208
+ if token_ =~ /^[-+]?(\d+(\.\d*)?|\.\d+)(e[-+]?\d+)?$/
209
+ @cur_token = token_.to_f
210
+ else
211
+ raise Error::ParseError, "Bad token: #{token_.inspect}"
212
+ end
213
+ end
214
+ @cur_token
215
+ end
216
+
217
+ def cur_token # :nodoc:
218
+ @cur_token
219
+ end
220
+
221
+
222
+ class QuotedString < ::String # :nodoc:
223
+ end
224
+
225
+ class TypeString < ::String # :nodoc:
226
+ end
227
+
228
+
229
+ class AuthorityClause # :nodoc:
230
+
231
+ def initialize(name_, code_)
232
+ @name = name_
233
+ @code = code_
234
+ end
235
+
236
+ def to_a
237
+ [@name, @code]
238
+ end
239
+
240
+ end
241
+
242
+
243
+ class ArgumentList # :nodoc:
244
+
245
+ def initialize
246
+ @values = []
247
+ end
248
+
249
+ def <<(value_)
250
+ @values << value_
251
+ end
252
+
253
+ def assert_empty
254
+ if @values.size > 0
255
+ names_ = @values.map do |val_|
256
+ val_.kind_of?(Base) ? val_._wkt_typename : val_.inspect
257
+ end
258
+ raise Error::ParseError, "#{@remaining} unexpected arguments: #{names_.join(', ')}"
259
+ end
260
+ end
261
+
262
+ def find_first(klass_)
263
+ @values.each_with_index do |val_, index_|
264
+ if val_.kind_of?(klass_)
265
+ @values.slice!(index_)
266
+ return val_
267
+ end
268
+ end
269
+ nil
270
+ end
271
+
272
+ def find_all(klass_)
273
+ results_ = []
274
+ nvalues_ = []
275
+ @values.each do |val_|
276
+ if val_.kind_of?(klass_)
277
+ results_ << val_
278
+ else
279
+ nvalues_ << val_
280
+ end
281
+ end
282
+ @values = nvalues_
283
+ results_
284
+ end
285
+
286
+ def shift(klass_=nil)
287
+ val_ = @values.shift
288
+ unless val_
289
+ raise Error::ParseError, "No arguments left... expected #{klass_}"
290
+ end
291
+ if klass_ && !val_.kind_of?(klass_)
292
+ raise Error::ParseError, "Expected #{klass_} but got #{val_.class}"
293
+ end
294
+ val_
295
+ end
296
+
297
+ end
298
+
299
+
300
+ end
301
+
302
+
303
+ end
304
+
305
+
306
+ end
307
+
308
+ end