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