GeoRuby 1.3.2 → 1.3.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,335 +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
- module Io
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
- end
333
- end
334
- end
335
- end
@@ -1,65 +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
-
11
- module GeoRuby
12
- module SimpleFeatures
13
- module Io
14
- #Creates a new geometry according to constructions received from a parser, for example EWKBParser.
15
- class GeometryFactory
16
- #the built geometry
17
- attr_reader :geometry
18
-
19
- def initialize
20
- @geometry_stack = []
21
- end
22
- #resets the factory
23
- def reset
24
- @geometry_stack = []
25
- end
26
- #add a 2D point to the current geometry
27
- def add_point_x_y(x,y)
28
- @geometry_stack.last.set_x_y(x,y)
29
- end
30
- #add a 3D point to the current geometry
31
- def add_point_x_y_z(x,y,z)
32
- @geometry_stack.last.set_x_y_z(x,y,z)
33
- end
34
- #add a 2D point with M to the current geometry
35
- def add_point_x_y_m(x,y,m)
36
- @geometry_stack.last.set_x_y(x,y)
37
- @geometry_stack.last.m=m
38
- end
39
- #add a 3D point with M to the current geometry
40
- def add_point_x_y_z_m(x,y,z,m)
41
- @geometry_stack.last.set_x_y_z(x,y,z)
42
- @geometry_stack.last.m=m
43
- end
44
- #begin a geometry of type +geometry_type+
45
- def begin_geometry(geometry_type,srid=DEFAULT_SRID)
46
- geometry= geometry_type::new(srid)
47
- @geometry= geometry if @geometry.nil?
48
- @geometry_stack << geometry
49
- end
50
- #terminates the current geometry
51
- def end_geometry(with_z=false,with_m=false)
52
- @geometry=@geometry_stack.pop
53
- @geometry.with_z=with_z
54
- @geometry.with_m=with_m
55
- #add the newly defined geometry to its parent if there is one
56
- @geometry_stack.last << geometry if !@geometry_stack.empty?
57
- end
58
- #abort a geometry
59
- def abort_geometry
60
- reset
61
- end
62
- end
63
- end
64
- end
65
- end