georuby 2.3.0 → 2.5.1
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.
- checksums.yaml +4 -4
- data/README.md +16 -9
- data/Rakefile +13 -14
- data/lib/geo_ruby/ewk.rb +2 -0
- data/lib/geo_ruby/{simple_features → ewk}/ewkb_parser.rb +206 -218
- data/lib/geo_ruby/ewk/ewkt_parser.rb +321 -0
- data/lib/geo_ruby/geojson.rb +27 -32
- data/lib/geo_ruby/georss.rb +88 -66
- data/lib/geo_ruby/gpx.rb +113 -1
- data/lib/geo_ruby/kml.rb +43 -31
- data/lib/geo_ruby/shp.rb +1 -0
- data/lib/geo_ruby/shp4r/dbf.rb +7 -3
- data/lib/geo_ruby/shp4r/shp.rb +297 -284
- data/lib/geo_ruby/simple_features.rb +2 -6
- data/lib/geo_ruby/simple_features/circle.rb +15 -13
- data/lib/geo_ruby/simple_features/envelope.rb +84 -77
- data/lib/geo_ruby/simple_features/geometry.rb +89 -69
- data/lib/geo_ruby/simple_features/geometry_collection.rb +46 -43
- data/lib/geo_ruby/simple_features/geometry_factory.rb +50 -47
- data/lib/geo_ruby/simple_features/helper.rb +14 -14
- data/lib/geo_ruby/simple_features/line_string.rb +94 -97
- data/lib/geo_ruby/simple_features/linear_ring.rb +4 -9
- data/lib/geo_ruby/simple_features/multi_line_string.rb +18 -21
- data/lib/geo_ruby/simple_features/multi_point.rb +18 -20
- data/lib/geo_ruby/simple_features/multi_polygon.rb +19 -25
- data/lib/geo_ruby/simple_features/point.rb +134 -128
- data/lib/geo_ruby/simple_features/polygon.rb +60 -59
- data/lib/geo_ruby/version.rb +1 -1
- data/spec/data/geojson/feature.json +9 -0
- data/spec/data/geojson/feature_collection.json +3 -4
- data/spec/geo_ruby/{simple_features → ewk}/ewkb_parser_spec.rb +56 -57
- data/spec/geo_ruby/{simple_features → ewk}/ewkt_parser_spec.rb +62 -63
- data/spec/geo_ruby/geojson_spec.rb +34 -17
- data/spec/geo_ruby/georss_spec.rb +76 -64
- data/spec/geo_ruby/{gpx4r/gpx_spec.rb → gpx_spec.rb} +25 -25
- data/spec/geo_ruby/kml_spec.rb +40 -36
- data/spec/geo_ruby/shp4r/shp_spec.rb +51 -51
- data/spec/geo_ruby/simple_features/circle_spec.rb +2 -2
- data/spec/geo_ruby/simple_features/envelope_spec.rb +8 -8
- data/spec/geo_ruby/simple_features/geometry_collection_spec.rb +26 -26
- data/spec/geo_ruby/simple_features/geometry_factory_spec.rb +5 -5
- data/spec/geo_ruby/simple_features/geometry_spec.rb +8 -8
- data/spec/geo_ruby/simple_features/line_string_spec.rb +102 -102
- data/spec/geo_ruby/simple_features/linear_ring_spec.rb +7 -7
- data/spec/geo_ruby/simple_features/multi_line_string_spec.rb +20 -20
- data/spec/geo_ruby/simple_features/multi_point_spec.rb +16 -16
- data/spec/geo_ruby/simple_features/multi_polygon_spec.rb +19 -19
- data/spec/geo_ruby/simple_features/point_spec.rb +180 -174
- data/spec/geo_ruby/simple_features/polygon_spec.rb +55 -56
- data/spec/geo_ruby_spec.rb +4 -4
- data/spec/spec_helper.rb +19 -13
- metadata +10 -9
- data/lib/geo_ruby/gpx4r/gpx.rb +0 -118
- data/lib/geo_ruby/simple_features/ewkt_parser.rb +0 -336
@@ -1,336 +0,0 @@
|
|
1
|
-
require 'geo_ruby/simple_features/point'
|
2
|
-
require 'geo_ruby/simple_features/line_string'
|
3
|
-
require 'geo_ruby/simple_features/linear_ring'
|
4
|
-
require 'geo_ruby/simple_features/polygon'
|
5
|
-
require 'geo_ruby/simple_features/multi_point'
|
6
|
-
require 'geo_ruby/simple_features/multi_line_string'
|
7
|
-
require 'geo_ruby/simple_features/multi_polygon'
|
8
|
-
require 'geo_ruby/simple_features/geometry_collection'
|
9
|
-
|
10
|
-
require 'strscan'
|
11
|
-
|
12
|
-
module GeoRuby
|
13
|
-
module SimpleFeatures
|
14
|
-
|
15
|
-
#Raised when an error in the EWKT string is detected
|
16
|
-
class EWKTFormatError < StandardError
|
17
|
-
end
|
18
|
-
|
19
|
-
#Parses EWKT strings and notifies of events (such as the beginning of the definition of geometry, the value of the SRID...) the factory passed as argument to the constructor.
|
20
|
-
#
|
21
|
-
#=Example
|
22
|
-
# factory = GeometryFactory::new
|
23
|
-
# ewkt_parser = EWKTParser::new(factory)
|
24
|
-
# ewkt_parser.parse(<EWKT String>)
|
25
|
-
# geometry = @factory.geometry
|
26
|
-
#
|
27
|
-
#You can also use directly the static method Geometry.from_ewkt
|
28
|
-
class EWKTParser
|
29
|
-
|
30
|
-
def initialize(factory)
|
31
|
-
@factory = factory
|
32
|
-
@parse_options ={
|
33
|
-
"POINT" => method(:parse_point),
|
34
|
-
"LINESTRING" => method(:parse_line_string),
|
35
|
-
"POLYGON" => method(:parse_polygon),
|
36
|
-
"MULTIPOINT" => method(:parse_multi_point),
|
37
|
-
"MULTILINESTRING" => method(:parse_multi_line_string),
|
38
|
-
"MULTIPOLYGON" => method(:parse_multi_polygon),
|
39
|
-
"GEOMETRYCOLLECTION" => method(:parse_geometry_collection)
|
40
|
-
}
|
41
|
-
end
|
42
|
-
|
43
|
-
#Parses the ewkt string passed as argument and notifies the factory of events
|
44
|
-
def parse(ewkt)
|
45
|
-
@factory.reset
|
46
|
-
@tokenizer_structure = TokenizerStructure.new(ewkt)
|
47
|
-
@with_z=false
|
48
|
-
@with_m=false
|
49
|
-
@is_3dm = false
|
50
|
-
parse_geometry(true)
|
51
|
-
@srid=nil
|
52
|
-
end
|
53
|
-
|
54
|
-
private
|
55
|
-
def parse_geometry(srid_allowed)
|
56
|
-
|
57
|
-
token = @tokenizer_structure.get_next_token
|
58
|
-
if token == 'SRID'
|
59
|
-
#SRID present
|
60
|
-
raise EWKTFormatError.new("SRID not allowed at this position") if(!srid_allowed)
|
61
|
-
if @tokenizer_structure.get_next_token != '='
|
62
|
-
raise EWKTFormatError.new("Invalid SRID expression")
|
63
|
-
else
|
64
|
-
@srid = @tokenizer_structure.get_next_token.to_i
|
65
|
-
raise EWKTFormatError.new("Invalid SRID separator") if @tokenizer_structure.get_next_token != ';'
|
66
|
-
geom_type = @tokenizer_structure.get_next_token
|
67
|
-
end
|
68
|
-
|
69
|
-
else
|
70
|
-
#to manage multi geometries : the srid is not present in sub_geometries, therefore we take the srid of the parent ; if it is the root, we take the default srid
|
71
|
-
@srid= @srid || DEFAULT_SRID
|
72
|
-
geom_type = token
|
73
|
-
end
|
74
|
-
|
75
|
-
if geom_type[-1] == ?M
|
76
|
-
@is_3dm=true
|
77
|
-
@with_m=true
|
78
|
-
geom_type.chop! #remove the M
|
79
|
-
end
|
80
|
-
|
81
|
-
if @parse_options.has_key?(geom_type)
|
82
|
-
@parse_options[geom_type].call
|
83
|
-
else
|
84
|
-
raise EWKTFormatError.new("Urecognized geometry type: #{geom_type}")
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
def parse_geometry_collection
|
89
|
-
if @tokenizer_structure.get_next_token !='('
|
90
|
-
raise EWKTFormatError.new('Invalid GeometryCollection')
|
91
|
-
end
|
92
|
-
|
93
|
-
@factory.begin_geometry(GeometryCollection,@srid)
|
94
|
-
|
95
|
-
token = ''
|
96
|
-
while token != ')'
|
97
|
-
parse_geometry(false)
|
98
|
-
token = @tokenizer_structure.get_next_token
|
99
|
-
if token.nil?
|
100
|
-
raise EWKTFormatError.new("EWKT string not correctly terminated")
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
@factory.end_geometry(@with_z,@with_m)
|
105
|
-
end
|
106
|
-
|
107
|
-
def parse_multi_polygon
|
108
|
-
if @tokenizer_structure.get_next_token !='('
|
109
|
-
raise EWKTFormatError.new('Invalid MultiLineString')
|
110
|
-
end
|
111
|
-
|
112
|
-
@factory.begin_geometry(MultiPolygon,@srid)
|
113
|
-
token = ''
|
114
|
-
while token != ')'
|
115
|
-
parse_polygon
|
116
|
-
token = @tokenizer_structure.get_next_token
|
117
|
-
if token.nil?
|
118
|
-
raise EWKTFormatError.new("EWKT string not correctly terminated")
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
@factory.end_geometry(@with_z,@with_m)
|
123
|
-
end
|
124
|
-
|
125
|
-
def parse_multi_line_string
|
126
|
-
if @tokenizer_structure.get_next_token !='('
|
127
|
-
raise EWKTFormatError.new('Invalid MultiLineString')
|
128
|
-
end
|
129
|
-
|
130
|
-
@factory.begin_geometry(MultiLineString,@srid)
|
131
|
-
|
132
|
-
token = ''
|
133
|
-
while token != ')'
|
134
|
-
parse_line_string
|
135
|
-
token = @tokenizer_structure.get_next_token
|
136
|
-
if token.nil?
|
137
|
-
raise EWKTFormatError.new("EWKT string not correctly terminated")
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
@factory.end_geometry(@with_z,@with_m)
|
142
|
-
end
|
143
|
-
|
144
|
-
def parse_polygon
|
145
|
-
if @tokenizer_structure.get_next_token !='('
|
146
|
-
raise EWKTFormatError.new('Invalid Polygon')
|
147
|
-
end
|
148
|
-
|
149
|
-
@factory.begin_geometry(Polygon,@srid)
|
150
|
-
|
151
|
-
token = ''
|
152
|
-
while token != ')'
|
153
|
-
parse_linear_ring
|
154
|
-
token = @tokenizer_structure.get_next_token
|
155
|
-
if token.nil?
|
156
|
-
raise EWKTFormatError.new("EWKT string not correctly terminated")
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
160
|
-
@factory.end_geometry(@with_z,@with_m)
|
161
|
-
end
|
162
|
-
|
163
|
-
#must support the PostGIS form and the one in the specification
|
164
|
-
def parse_multi_point
|
165
|
-
if @tokenizer_structure.get_next_token !='('
|
166
|
-
raise EWKTFormatError.new('Invalid MultiPoint')
|
167
|
-
end
|
168
|
-
|
169
|
-
token = @tokenizer_structure.check_next_token
|
170
|
-
if token == '('
|
171
|
-
#specification
|
172
|
-
@factory.begin_geometry(MultiPoint,@srid)
|
173
|
-
|
174
|
-
token = ''
|
175
|
-
while token != ')'
|
176
|
-
parse_point
|
177
|
-
token = @tokenizer_structure.get_next_token
|
178
|
-
if token.nil?
|
179
|
-
raise EWKTFormatError.new("EWKT string not correctly terminated")
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
@factory.end_geometry(@with_z,@with_m)
|
184
|
-
else
|
185
|
-
#postgis
|
186
|
-
parse_point_list(MultiPoint)
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
|
-
def parse_linear_ring
|
191
|
-
if @tokenizer_structure.get_next_token !='('
|
192
|
-
raise EWKTFormatError.new('Invalid Linear ring')
|
193
|
-
end
|
194
|
-
|
195
|
-
parse_point_list(LinearRing)
|
196
|
-
end
|
197
|
-
|
198
|
-
def parse_line_string
|
199
|
-
if @tokenizer_structure.get_next_token !='('
|
200
|
-
raise EWKTFormatError.new('Invalid Line string')
|
201
|
-
end
|
202
|
-
|
203
|
-
parse_point_list(LineString)
|
204
|
-
end
|
205
|
-
|
206
|
-
#used to parse line_strings and linear_rings and the PostGIS form of multi_points
|
207
|
-
def parse_point_list(geometry_type)
|
208
|
-
@factory.begin_geometry(geometry_type,@srid)
|
209
|
-
|
210
|
-
token = ''
|
211
|
-
while token != ')'
|
212
|
-
@factory.begin_geometry(Point,@srid)
|
213
|
-
token = parse_coords
|
214
|
-
if token.nil?
|
215
|
-
raise EWKTFormatError.new("EWKT string not correctly terminated")
|
216
|
-
end
|
217
|
-
@factory.end_geometry(@with_z,@with_m)
|
218
|
-
end
|
219
|
-
|
220
|
-
@factory.end_geometry(@with_z,@with_m)
|
221
|
-
end
|
222
|
-
|
223
|
-
def parse_point
|
224
|
-
if @tokenizer_structure.get_next_token !='('
|
225
|
-
raise EWKTFormatError.new('Invalid Point')
|
226
|
-
end
|
227
|
-
|
228
|
-
@factory.begin_geometry(Point,@srid)
|
229
|
-
|
230
|
-
token = parse_coords
|
231
|
-
|
232
|
-
if token != ')'
|
233
|
-
raise EWKTFormatError.new("EWKT string not correctly terminated")
|
234
|
-
end
|
235
|
-
|
236
|
-
@factory.end_geometry(@with_z,@with_m)
|
237
|
-
end
|
238
|
-
|
239
|
-
def parse_coords
|
240
|
-
coords = Array.new
|
241
|
-
x = @tokenizer_structure.get_next_token
|
242
|
-
y = @tokenizer_structure.get_next_token
|
243
|
-
|
244
|
-
if x.nil? or y.nil?
|
245
|
-
raise EWKTFormatError.new("Bad Point format")
|
246
|
-
end
|
247
|
-
|
248
|
-
if @is_3dm
|
249
|
-
m = @tokenizer_structure.get_next_token
|
250
|
-
|
251
|
-
if m.nil? or m == ',' or m == ')'
|
252
|
-
raise EWKTFormatError.new("No M dimension found")
|
253
|
-
else
|
254
|
-
@factory.add_point_x_y_m(x.to_f,y.to_f,m.to_f)
|
255
|
-
@tokenizer_structure.get_next_token
|
256
|
-
end
|
257
|
-
else
|
258
|
-
z = @tokenizer_structure.get_next_token
|
259
|
-
|
260
|
-
if z.nil?
|
261
|
-
raise EWKTFormatError.new("EWKT string not correctly terminated")
|
262
|
-
end
|
263
|
-
|
264
|
-
if z == ',' or z == ')'
|
265
|
-
#2D : no z no m
|
266
|
-
@factory.add_point_x_y(x.to_f,y.to_f)
|
267
|
-
z
|
268
|
-
else
|
269
|
-
m = @tokenizer_structure.get_next_token
|
270
|
-
if m.nil?
|
271
|
-
raise EWKTFormatError.new("EWKT string not correctly terminated")
|
272
|
-
end
|
273
|
-
|
274
|
-
if m == ',' or m ==')'
|
275
|
-
#3Dz : no m
|
276
|
-
@with_z = true
|
277
|
-
@factory.add_point_x_y_z(x.to_f,y.to_f,z.to_f)
|
278
|
-
m
|
279
|
-
else
|
280
|
-
#4D
|
281
|
-
@with_z = true
|
282
|
-
@with_m = true
|
283
|
-
@factory.add_point_x_y_z_m(x.to_f,y.to_f,z.to_f,m.to_f)
|
284
|
-
@tokenizer_structure.get_next_token
|
285
|
-
end
|
286
|
-
end
|
287
|
-
end
|
288
|
-
end
|
289
|
-
end
|
290
|
-
|
291
|
-
class TokenizerStructure
|
292
|
-
|
293
|
-
def initialize(ewkt)
|
294
|
-
@ewkt = ewkt
|
295
|
-
@scanner = StringScanner.new(ewkt)
|
296
|
-
@regex = /\s*([\w.-]+)s*/
|
297
|
-
end
|
298
|
-
|
299
|
-
def get_next_token
|
300
|
-
if @scanner.scan(@regex).nil?
|
301
|
-
if @scanner.eos?
|
302
|
-
nil
|
303
|
-
else
|
304
|
-
ch = @scanner.getch
|
305
|
-
while ch == ' '
|
306
|
-
ch = @scanner.getch
|
307
|
-
end
|
308
|
-
ch
|
309
|
-
end
|
310
|
-
else
|
311
|
-
@scanner[1]
|
312
|
-
end
|
313
|
-
end
|
314
|
-
|
315
|
-
|
316
|
-
def check_next_token
|
317
|
-
check = @scanner.check(@regex)
|
318
|
-
if check.nil?
|
319
|
-
if @scanner.eos?
|
320
|
-
nil
|
321
|
-
else
|
322
|
-
pos = @scanner.pos
|
323
|
-
while @ewkt[pos].chr == ' '
|
324
|
-
pos+=1
|
325
|
-
end
|
326
|
-
@ewkt[pos].chr
|
327
|
-
end
|
328
|
-
else
|
329
|
-
check
|
330
|
-
end
|
331
|
-
end
|
332
|
-
|
333
|
-
end
|
334
|
-
|
335
|
-
end
|
336
|
-
end
|