georuby 2.3.0 → 2.5.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
data/lib/geo_ruby/georss.rb
CHANGED
@@ -1,132 +1,154 @@
|
|
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
|
-
# require 'geo_ruby/simple_features/envelope'
|
10
|
-
|
11
1
|
module GeoRuby
|
12
|
-
|
13
|
-
#Raised when an error in the GeoRSS string is detected
|
2
|
+
# Raised when an error in the GeoRSS string is detected
|
14
3
|
class GeorssFormatError < StandardError
|
15
4
|
end
|
16
5
|
|
17
|
-
#Contains tags possibly found on GeoRss Simple geometries
|
18
|
-
class GeorssTags < Struct.new(:featuretypetag
|
6
|
+
# Contains tags possibly found on GeoRss Simple geometries
|
7
|
+
class GeorssTags < Struct.new(:featuretypetag, :relationshiptag,
|
8
|
+
:elev, :floor, :radius)
|
19
9
|
end
|
20
10
|
|
21
|
-
#Parses GeoRSS strings
|
22
|
-
#You can also use directly the static method Geometry.from_georss
|
11
|
+
# Parses GeoRSS strings
|
12
|
+
# You can also use directly the static method Geometry.from_georss
|
23
13
|
class GeorssParser
|
24
14
|
include GeoRuby::SimpleFeatures
|
25
15
|
attr_reader :georss_tags, :geometry
|
26
16
|
|
27
|
-
|
28
|
-
|
29
|
-
|
17
|
+
GEORSS_REGEX = /=['"]([^"']*)['"]/
|
18
|
+
|
19
|
+
# Parses the georss geometry passed as argument and notifies
|
20
|
+
# the factory of events the parser assumes
|
21
|
+
def parse(georss, with_tags = false)
|
30
22
|
@geometry = nil
|
31
23
|
@georss_tags = GeorssTags.new
|
32
|
-
parse_geometry(georss,with_tags)
|
24
|
+
parse_geometry(georss, with_tags)
|
33
25
|
end
|
34
26
|
|
35
27
|
private
|
36
|
-
|
28
|
+
|
29
|
+
def parse_geometry(georss, with_tags)
|
37
30
|
georss.strip!
|
38
|
-
#check for W3CGeo first
|
31
|
+
# check for W3CGeo first
|
39
32
|
if georss =~ /<[^:>]*:lat\s*>([^<]*)</
|
40
|
-
#if valid, it is W3CGeo
|
41
|
-
lat =
|
33
|
+
# if valid, it is W3CGeo
|
34
|
+
lat = Regexp.last_match[1].to_f
|
42
35
|
if georss =~ /<[^:>]*:long\s*>([^<]*)</
|
43
|
-
lon =
|
44
|
-
@geometry = Point.from_x_y(lon,lat)
|
36
|
+
lon = Regexp.last_match[1].to_f
|
37
|
+
@geometry = Point.from_x_y(lon, lat)
|
45
38
|
else
|
46
|
-
|
39
|
+
fail GeorssFormatError, 'Bad W3CGeo GeoRSS format'
|
47
40
|
end
|
48
41
|
elsif georss =~ /^<\s*[^:>]*:where\s*>/
|
49
|
-
#GML format found
|
42
|
+
# GML format found
|
50
43
|
gml = $'.strip
|
51
44
|
if gml =~ /^<\s*[^:>]*:Point\s*>/
|
52
|
-
#gml point
|
45
|
+
# gml point
|
53
46
|
if gml =~ /<\s*[^:>]*:pos\s*>([^<]*)/
|
54
|
-
point =
|
55
|
-
#lat comes first
|
56
|
-
@geometry = Point.from_x_y(point[1].to_f,point[0].to_f)
|
47
|
+
point = Regexp.last_match[1].split(' ')
|
48
|
+
# lat comes first
|
49
|
+
@geometry = Point.from_x_y(point[1].to_f, point[0].to_f)
|
57
50
|
else
|
58
|
-
|
51
|
+
fail GeorssFormatError, 'Bad GML GeoRSS: Malformed Point'
|
59
52
|
end
|
60
53
|
elsif gml =~ /^<\s*[^:>]*:LineString\s*>/
|
61
54
|
if gml =~ /<\s*[^:>]*:posList\s*>([^<]*)/
|
62
|
-
xy =
|
55
|
+
xy = Regexp.last_match[1].split(' ')
|
63
56
|
@geometry = LineString.new
|
64
|
-
0.upto(xy.size/2 - 1)
|
57
|
+
0.upto(xy.size / 2 - 1) do |index|
|
58
|
+
@geometry << Point.from_x_y(xy[index * 2 + 1].to_f,
|
59
|
+
xy[index * 2].to_f)
|
60
|
+
end
|
65
61
|
else
|
66
|
-
|
62
|
+
fail GeorssFormatError, 'Bad GML GeoRSS: Malformed LineString'
|
67
63
|
end
|
68
64
|
elsif gml =~ /^<\s*[^:>]*:Polygon\s*>/
|
69
65
|
if gml =~ /<\s*[^:>]*:posList\s*>([^<]*)/
|
70
|
-
xy =
|
66
|
+
xy = Regexp.last_match[1].split(' ')
|
71
67
|
@geometry = Polygon.new
|
72
68
|
linear_ring = LinearRing.new
|
73
69
|
@geometry << linear_ring
|
74
|
-
xy =
|
75
|
-
0.upto(xy.size/2 - 1)
|
70
|
+
xy = Regexp.last_match[1].split(' ')
|
71
|
+
0.upto(xy.size / 2 - 1) do |index|
|
72
|
+
linear_ring << Point.from_x_y(xy[index * 2 + 1].to_f,
|
73
|
+
xy[index * 2].to_f)
|
74
|
+
end
|
76
75
|
else
|
77
|
-
|
76
|
+
fail GeorssFormatError, 'Bad GML GeoRSS: Malformed Polygon'
|
78
77
|
end
|
79
78
|
elsif gml =~ /^<\s*[^:>]*:Envelope\s*>/
|
80
79
|
if gml =~ /<\s*[^:>]*:lowerCorner\s*>([^<]*)</
|
81
|
-
lc =
|
80
|
+
lc = Regexp.last_match[1].split(' ').collect(&:to_f).reverse
|
82
81
|
if gml =~ /<\s*[^:>]*:upperCorner\s*>([^<]*)</
|
83
|
-
uc =
|
84
|
-
@geometry = Envelope.from_coordinates([lc,uc])
|
82
|
+
uc = Regexp.last_match[1].split(' ').collect(&:to_f).reverse
|
83
|
+
@geometry = Envelope.from_coordinates([lc, uc])
|
85
84
|
else
|
86
|
-
|
85
|
+
fail GeorssFormatError, 'Bad GML GeoRSS: Malformed Envelope'
|
87
86
|
end
|
88
87
|
else
|
89
|
-
|
88
|
+
fail GeorssFormatError, 'Bad GML GeoRSS: Malformed Envelope'
|
90
89
|
end
|
91
90
|
else
|
92
|
-
|
91
|
+
fail GeorssFormatError, 'Bad GML GeoRSS: Unknown geometry type'
|
93
92
|
end
|
94
93
|
else
|
95
|
-
#must be simple format
|
94
|
+
# must be simple format
|
96
95
|
if georss =~ /^<\s*[^>:]*:point([^>]*)>(.*)</m
|
97
|
-
tags =
|
98
|
-
point =
|
99
|
-
@geometry = Point.from_x_y(point[1].to_f,point[0].to_f)
|
96
|
+
tags = Regexp.last_match[1]
|
97
|
+
point = Regexp.last_match[2].gsub(',', ' ').split(' ')
|
98
|
+
@geometry = Point.from_x_y(point[1].to_f, point[0].to_f)
|
100
99
|
elsif georss =~ /^<\s*[^>:]*:line([^>]*)>(.*)</m
|
101
|
-
tags =
|
100
|
+
tags = Regexp.last_match[1]
|
102
101
|
@geometry = LineString.new
|
103
|
-
xy =
|
104
|
-
0.upto(xy.size/2 - 1)
|
102
|
+
xy = Regexp.last_match[2].gsub(',', ' ').split(' ')
|
103
|
+
0.upto(xy.size / 2 - 1) do |index|
|
104
|
+
@geometry << Point.from_x_y(xy[index * 2 + 1].to_f,
|
105
|
+
xy[index * 2].to_f)
|
106
|
+
end
|
105
107
|
elsif georss =~ /^<\s*[^>:]*:polygon([^>]*)>(.*)</m
|
106
|
-
tags =
|
108
|
+
tags = Regexp.last_match[1]
|
107
109
|
@geometry = Polygon.new
|
108
110
|
linear_ring = LinearRing.new
|
109
111
|
@geometry << linear_ring
|
110
|
-
xy =
|
111
|
-
0.upto(xy.size/2 - 1)
|
112
|
+
xy = Regexp.last_match[2].gsub(',', ' ').split(' ')
|
113
|
+
0.upto(xy.size / 2 - 1) do |index|
|
114
|
+
linear_ring << Point.from_x_y(xy[index * 2 + 1].to_f,
|
115
|
+
xy[index * 2].to_f)
|
116
|
+
end
|
112
117
|
elsif georss =~ /^<\s*[^>:]*:box([^>]*)>(.*)</m
|
113
|
-
tags =
|
118
|
+
tags = Regexp.last_match[1]
|
114
119
|
corners = []
|
115
|
-
xy =
|
116
|
-
0.upto(xy.size/2 - 1)
|
120
|
+
xy = Regexp.last_match[2].gsub(',', ' ').split(' ')
|
121
|
+
0.upto(xy.size / 2 - 1) do |index|
|
122
|
+
corners << Point.from_x_y(xy[index * 2 + 1].to_f,
|
123
|
+
xy[index * 2].to_f)
|
124
|
+
end
|
117
125
|
@geometry = Envelope.from_points(corners)
|
118
126
|
else
|
119
|
-
|
127
|
+
fail GeorssFormatError, 'Bad Simple GeoRSS format: ' \
|
128
|
+
'Unknown geometry type'
|
120
129
|
end
|
121
130
|
|
122
|
-
#geometry found: parse tags
|
131
|
+
# geometry found: parse tags
|
123
132
|
return unless with_tags
|
133
|
+
if tags =~ /featuretypetag#{GEORSS_REGEX}/
|
134
|
+
@georss_tags.featuretypetag = Regexp.last_match[1]
|
135
|
+
end
|
136
|
+
|
137
|
+
if tags =~ /relationshiptag#{GEORSS_REGEX}/
|
138
|
+
@georss_tags.relationshiptag = Regexp.last_match[1]
|
139
|
+
end
|
140
|
+
|
141
|
+
if tags =~ /elev#{GEORSS_REGEX}/
|
142
|
+
@georss_tags.elev = Regexp.last_match[1].to_f
|
143
|
+
end
|
144
|
+
|
145
|
+
if tags =~ /floor#{GEORSS_REGEX}/
|
146
|
+
@georss_tags.floor = Regexp.last_match[1].to_i
|
147
|
+
end
|
124
148
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
@georss_tags.floor = $1.to_i if tags =~ /floor=['"]([^'"]*)['"]/
|
129
|
-
@georss_tags.radius = $1.to_f if tags =~ /radius=['"]([^'"]*)['"]/
|
149
|
+
if tags =~ /radius#{GEORSS_REGEX}/
|
150
|
+
@georss_tags.radius = Regexp.last_match[1].to_f
|
151
|
+
end
|
130
152
|
|
131
153
|
end
|
132
154
|
end
|
data/lib/geo_ruby/gpx.rb
CHANGED
@@ -1 +1,113 @@
|
|
1
|
-
require '
|
1
|
+
require 'nokogiri'
|
2
|
+
|
3
|
+
module GeoRuby
|
4
|
+
module Gpx4r
|
5
|
+
# An interface to GPX files
|
6
|
+
class GpxFile
|
7
|
+
attr_reader :record_count, :file_root #:xmin, :ymin, :xmax, :ymax, :zmin, :zmax, :mmin, :mmax, :file_length
|
8
|
+
|
9
|
+
include Enumerable
|
10
|
+
|
11
|
+
# Opens a GPX file. Both "abc.shp" and "abc" are accepted.
|
12
|
+
def initialize(file, *opts) # with_z = true, with_m = true)
|
13
|
+
@file_root = file.gsub(/\.gpx$/i, '')
|
14
|
+
fail MalformedGpxException.new('Missing GPX File') unless
|
15
|
+
File.exist? @file_root + '.gpx'
|
16
|
+
@points, @envelope = [], nil
|
17
|
+
@gpx = File.open(@file_root + '.gpx', 'rb')
|
18
|
+
opt = opts.reduce({}) { |a, e| e.merge(a) }
|
19
|
+
parse_file(opt[:with_z], opt[:with_m])
|
20
|
+
end
|
21
|
+
|
22
|
+
# force the reopening of the files compsing the shp. Close before calling this.
|
23
|
+
def reload!
|
24
|
+
initialize(@file_root)
|
25
|
+
end
|
26
|
+
|
27
|
+
# opens a GPX "file". If a block is given, the GpxFile object is yielded to it and is closed upon return. Else a call to <tt>open</tt> is equivalent to <tt>GpxFile.new(...)</tt>.
|
28
|
+
def self.open(file, *opts)
|
29
|
+
gpxfile = GpxFile.new(file, *opts)
|
30
|
+
if block_given?
|
31
|
+
yield gpxfile
|
32
|
+
# gpxfile.close
|
33
|
+
else
|
34
|
+
gpxfile
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Closes a gpxfile
|
39
|
+
def close
|
40
|
+
@gpx.close
|
41
|
+
end
|
42
|
+
|
43
|
+
# Tests if the file has no record
|
44
|
+
def empty?
|
45
|
+
record_count == 0
|
46
|
+
end
|
47
|
+
|
48
|
+
# Goes through each record
|
49
|
+
def each
|
50
|
+
(0...record_count).each do |i|
|
51
|
+
yield get_record(i)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
alias_method :each_record, :each
|
55
|
+
|
56
|
+
# Returns record +i+
|
57
|
+
def [](i)
|
58
|
+
get_record(i)
|
59
|
+
end
|
60
|
+
|
61
|
+
# Returns all the records
|
62
|
+
def records
|
63
|
+
@points
|
64
|
+
end
|
65
|
+
|
66
|
+
# Return the GPX file as LineString
|
67
|
+
def as_line_string
|
68
|
+
GeoRuby::SimpleFeatures::LineString.from_points(@points)
|
69
|
+
end
|
70
|
+
alias_method :as_polyline, :as_line_string
|
71
|
+
|
72
|
+
# Return the GPX file as a Polygon
|
73
|
+
# If the GPX isn't closed, a line from the first
|
74
|
+
# to the last point will be created to close it.
|
75
|
+
def as_polygon
|
76
|
+
GeoRuby::SimpleFeatures::Polygon.from_points([@points[0] == @points[-1] ? @points : @points.push(@points[0].clone)])
|
77
|
+
end
|
78
|
+
|
79
|
+
# Return GPX Envelope
|
80
|
+
def envelope
|
81
|
+
@envelope ||= as_polygon.envelope
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def get_record(i)
|
87
|
+
@points[i]
|
88
|
+
end
|
89
|
+
|
90
|
+
# wpt => waypoint => TODO?
|
91
|
+
# rte(pt) => route
|
92
|
+
# trk(pt) => track /
|
93
|
+
def parse_file(with_z, with_m)
|
94
|
+
data = @gpx.read
|
95
|
+
@file_mode = data =~ /trkpt/ ? '//trkpt' : (data =~ /wpt/ ? '//wpt' : '//rtept')
|
96
|
+
Nokogiri.HTML(data).search(@file_mode).each do |tp|
|
97
|
+
z = z.inner_text.to_f if with_z && z = tp.at('ele')
|
98
|
+
m = m.inner_text if with_m && m = tp.at('time')
|
99
|
+
@points << GeoRuby::SimpleFeatures::Point.from_coordinates([tp['lon'].to_f, tp['lat'].to_f, z, m], 4326, with_z, with_m)
|
100
|
+
end
|
101
|
+
close
|
102
|
+
@record_count = @points.length
|
103
|
+
envelope
|
104
|
+
rescue => e
|
105
|
+
raise MalformedGpxException.new("Bad GPX. Error: #{e}")
|
106
|
+
# trackpoint.at("gpxdata:hr").nil? # heartrate
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
class MalformedGpxException < StandardError
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
data/lib/geo_ruby/kml.rb
CHANGED
@@ -3,16 +3,18 @@ module GeoRuby
|
|
3
3
|
class KmlParser
|
4
4
|
ELEMENT_MAP = {
|
5
5
|
# "Point" => SimpleFeatures::Point, # we don't need to map points. they are done automatically by the coordinate parsing
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
'LineString' => SimpleFeatures::LineString,
|
7
|
+
'LinearRing' => SimpleFeatures::LinearRing,
|
8
|
+
'Polygon' => SimpleFeatures::Polygon,
|
9
|
+
'MultiGeometry' => SimpleFeatures::GeometryCollection
|
10
10
|
}
|
11
|
+
|
11
12
|
def initialize(factory)
|
12
13
|
@factory = factory
|
13
|
-
@buffer =
|
14
|
+
@buffer = ''
|
14
15
|
@with_z = false
|
15
16
|
end
|
17
|
+
|
16
18
|
# argument should be a valid kml geometry fragment ie. <Point> .... </Point>
|
17
19
|
# returns the GeoRuby geometry object back
|
18
20
|
def parse(kml)
|
@@ -22,24 +24,24 @@ module GeoRuby
|
|
22
24
|
while @parser.has_next?
|
23
25
|
e = @parser.pull
|
24
26
|
if e.start_element?
|
25
|
-
if(type = ELEMENT_MAP[e[0]])
|
27
|
+
if (type = ELEMENT_MAP[e[0]])
|
26
28
|
@factory.begin_geometry(type)
|
27
29
|
else
|
28
|
-
@buffer =
|
30
|
+
@buffer = '' if (e[0] == 'coordinates') # clear the buffer
|
29
31
|
accumulate_start(e)
|
30
32
|
end
|
31
33
|
elsif e.end_element?
|
32
|
-
if
|
34
|
+
if ELEMENT_MAP[e[0]]
|
33
35
|
@factory.end_geometry(@with_z)
|
34
|
-
@buffer =
|
36
|
+
@buffer = '' # clear the buffer
|
35
37
|
else
|
36
38
|
accumulate_end(e)
|
37
|
-
if(e[0] ==
|
39
|
+
if (e[0] == 'coordinates')
|
38
40
|
parse_coordinates(@buffer)
|
39
|
-
@buffer =
|
41
|
+
@buffer = '' # clear the buffer
|
40
42
|
end
|
41
43
|
end
|
42
|
-
elsif e.text?
|
44
|
+
elsif e.text?
|
43
45
|
accumulate_text(e)
|
44
46
|
elsif e.cdata?
|
45
47
|
accumulate_cdata(e)
|
@@ -47,38 +49,48 @@ module GeoRuby
|
|
47
49
|
end
|
48
50
|
@factory.geometry.dup
|
49
51
|
end
|
50
|
-
|
51
|
-
private
|
52
|
-
|
53
|
-
def
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def accumulate_text(e)
|
56
|
+
@buffer << e[0]
|
57
|
+
end
|
58
|
+
|
59
|
+
def accumulate_cdata(e)
|
60
|
+
@buffer << "<![CDATA[#{e[0]}]]>"
|
61
|
+
end
|
62
|
+
|
54
63
|
def accumulate_start(e)
|
55
64
|
@buffer << "<#{e[0]}"
|
56
|
-
if(e[1].class == Hash)
|
57
|
-
e[1].each_pair {|k,v| @buffer << " #{k}='#{v}'" }
|
65
|
+
if (e[1].class == Hash)
|
66
|
+
e[1].each_pair { |k, v| @buffer << " #{k}='#{v}'" }
|
58
67
|
end
|
59
|
-
@buffer <<
|
68
|
+
@buffer << '>'
|
69
|
+
end
|
70
|
+
|
71
|
+
def accumulate_end(e)
|
72
|
+
@buffer << "</#{e[0]}>"
|
60
73
|
end
|
61
|
-
|
62
|
-
|
74
|
+
|
63
75
|
def parse_coordinates(buffer)
|
64
|
-
if
|
65
|
-
|
66
|
-
x,y,z = coord.split(',')
|
67
|
-
if
|
68
|
-
|
76
|
+
if buffer =~ /<coordinates>(.+)<\/coordinates>/m
|
77
|
+
Regexp.last_match[1].gsub(/\n/, ' ').strip.split(/\s+/).each do |coord|
|
78
|
+
x, y, z = coord.split(',')
|
79
|
+
if x.nil? || y.nil?
|
80
|
+
fail StandardError, 'coordinates must have at least x and y elements'
|
69
81
|
end
|
70
82
|
@factory.begin_geometry(SimpleFeatures::Point)
|
71
|
-
if
|
72
|
-
@factory.add_point_x_y(x,y)
|
83
|
+
if z.nil?
|
84
|
+
@factory.add_point_x_y(x, y)
|
73
85
|
else
|
74
|
-
@factory.add_point_x_y_z(x,y,z)
|
86
|
+
@factory.add_point_x_y_z(x, y, z)
|
75
87
|
@with_z = true unless @with_z # is the conditional even necessary
|
76
88
|
end
|
77
89
|
@factory.end_geometry(@with_z)
|
78
90
|
end
|
79
91
|
end
|
80
92
|
rescue
|
81
|
-
raise StandardError,
|
93
|
+
raise StandardError, 'error parsing coordinates: check your kml for errors'
|
82
94
|
end
|
83
95
|
end
|
84
|
-
end
|
96
|
+
end
|