schleyfox-rgeo 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
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