georuby 2.3.0 → 2.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +16 -9
  3. data/Rakefile +13 -14
  4. data/lib/geo_ruby/ewk.rb +2 -0
  5. data/lib/geo_ruby/{simple_features → ewk}/ewkb_parser.rb +206 -218
  6. data/lib/geo_ruby/ewk/ewkt_parser.rb +321 -0
  7. data/lib/geo_ruby/geojson.rb +27 -32
  8. data/lib/geo_ruby/georss.rb +88 -66
  9. data/lib/geo_ruby/gpx.rb +113 -1
  10. data/lib/geo_ruby/kml.rb +43 -31
  11. data/lib/geo_ruby/shp.rb +1 -0
  12. data/lib/geo_ruby/shp4r/dbf.rb +7 -3
  13. data/lib/geo_ruby/shp4r/shp.rb +297 -284
  14. data/lib/geo_ruby/simple_features.rb +2 -6
  15. data/lib/geo_ruby/simple_features/circle.rb +15 -13
  16. data/lib/geo_ruby/simple_features/envelope.rb +84 -77
  17. data/lib/geo_ruby/simple_features/geometry.rb +89 -69
  18. data/lib/geo_ruby/simple_features/geometry_collection.rb +46 -43
  19. data/lib/geo_ruby/simple_features/geometry_factory.rb +50 -47
  20. data/lib/geo_ruby/simple_features/helper.rb +14 -14
  21. data/lib/geo_ruby/simple_features/line_string.rb +94 -97
  22. data/lib/geo_ruby/simple_features/linear_ring.rb +4 -9
  23. data/lib/geo_ruby/simple_features/multi_line_string.rb +18 -21
  24. data/lib/geo_ruby/simple_features/multi_point.rb +18 -20
  25. data/lib/geo_ruby/simple_features/multi_polygon.rb +19 -25
  26. data/lib/geo_ruby/simple_features/point.rb +134 -128
  27. data/lib/geo_ruby/simple_features/polygon.rb +60 -59
  28. data/lib/geo_ruby/version.rb +1 -1
  29. data/spec/data/geojson/feature.json +9 -0
  30. data/spec/data/geojson/feature_collection.json +3 -4
  31. data/spec/geo_ruby/{simple_features → ewk}/ewkb_parser_spec.rb +56 -57
  32. data/spec/geo_ruby/{simple_features → ewk}/ewkt_parser_spec.rb +62 -63
  33. data/spec/geo_ruby/geojson_spec.rb +34 -17
  34. data/spec/geo_ruby/georss_spec.rb +76 -64
  35. data/spec/geo_ruby/{gpx4r/gpx_spec.rb → gpx_spec.rb} +25 -25
  36. data/spec/geo_ruby/kml_spec.rb +40 -36
  37. data/spec/geo_ruby/shp4r/shp_spec.rb +51 -51
  38. data/spec/geo_ruby/simple_features/circle_spec.rb +2 -2
  39. data/spec/geo_ruby/simple_features/envelope_spec.rb +8 -8
  40. data/spec/geo_ruby/simple_features/geometry_collection_spec.rb +26 -26
  41. data/spec/geo_ruby/simple_features/geometry_factory_spec.rb +5 -5
  42. data/spec/geo_ruby/simple_features/geometry_spec.rb +8 -8
  43. data/spec/geo_ruby/simple_features/line_string_spec.rb +102 -102
  44. data/spec/geo_ruby/simple_features/linear_ring_spec.rb +7 -7
  45. data/spec/geo_ruby/simple_features/multi_line_string_spec.rb +20 -20
  46. data/spec/geo_ruby/simple_features/multi_point_spec.rb +16 -16
  47. data/spec/geo_ruby/simple_features/multi_polygon_spec.rb +19 -19
  48. data/spec/geo_ruby/simple_features/point_spec.rb +180 -174
  49. data/spec/geo_ruby/simple_features/polygon_spec.rb +55 -56
  50. data/spec/geo_ruby_spec.rb +4 -4
  51. data/spec/spec_helper.rb +19 -13
  52. metadata +10 -9
  53. data/lib/geo_ruby/gpx4r/gpx.rb +0 -118
  54. 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