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.
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