kmlbo 0.0.1 → 0.0.2
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.
- data/bin/kmlbo +8 -2
- data/lib/kmlbo/g_polyline.rb +78 -0
- data/lib/kmlbo/kml.rb +13 -6
- data/lib/kmlbo/pointlist.rb +4 -1
- data/lib/kmlbo.rb +9 -0
- data/test/g_polyline_test.rb +18 -0
- data/test/pointlist_test.rb +2 -3
- data/test/test_helper.rb +3 -0
- metadata +11 -6
data/bin/kmlbo
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
require 'optparse'
|
3
|
-
require 'kmlbo
|
4
|
-
require 'kmlbo/pointlist'
|
3
|
+
require 'kmlbo'
|
5
4
|
|
6
5
|
options = {}
|
7
6
|
option_parser = OptionParser.new do |opts|
|
@@ -16,6 +15,9 @@ option_parser = OptionParser.new do |opts|
|
|
16
15
|
opts.on("-k", "--kml", "Emit kml instead of ruby") do |kml|
|
17
16
|
options[:kml] = true
|
18
17
|
end
|
18
|
+
opts.on("-e", "--encoded", "Output an encoded path suitable for use in Google Maps v3 API") do |encoded|
|
19
|
+
options[:encoded] = true
|
20
|
+
end
|
19
21
|
end
|
20
22
|
|
21
23
|
option_parser.parse!
|
@@ -39,6 +41,10 @@ if options[:kml]
|
|
39
41
|
File.open(output_file, "w+") do |file|
|
40
42
|
file.write(coordinates.to_kml)
|
41
43
|
end
|
44
|
+
elsif options[:encoded]
|
45
|
+
File.open(output_file, "w+") do |file|
|
46
|
+
file.write(coordinates.to_encoded.inspect)
|
47
|
+
end
|
42
48
|
else
|
43
49
|
File.open(output_file, "w+") do |file|
|
44
50
|
file.write("PATH_COORDINATES = #{coordinates.to_a.to_s}")
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# GPolyline is a module that implements the Google Polyline Algorithm Format.
|
2
|
+
# https://developers.google.com/maps/documentation/utilities/polylinealgorithm
|
3
|
+
#
|
4
|
+
# Author:: Josh Cronemeyer
|
5
|
+
# Copyright:: Copyright (c) 2008-2011
|
6
|
+
# License:: MIT License (http://www.opensource.org/licenses/mit-license.php)
|
7
|
+
#
|
8
|
+
# Include this module into a class that has an instance variable called
|
9
|
+
# @tuple_array, where @tuple_array contains a list of geocoordinates of the
|
10
|
+
# form [[lng, lat, elev], ..., [lng, lat, elev]]. It will override to_s
|
11
|
+
# and output an encoded path suitable for use in Google Maps v3 API
|
12
|
+
#
|
13
|
+
# require "kmlbo/g_polyline"
|
14
|
+
# class Polyline
|
15
|
+
# include GPolyline
|
16
|
+
# ...
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# path = Polyline.new
|
20
|
+
# path.to_s
|
21
|
+
# # => "svzmFdgi_QdA?nCA"
|
22
|
+
#
|
23
|
+
# Ideas for this implementation of the google polyline algorithm format
|
24
|
+
# come from the following sources:
|
25
|
+
# * http://facstaff.unca.edu/mcmcclur/GoogleMaps/
|
26
|
+
# * https://github.com/joshuaclayton/polylines/
|
27
|
+
#
|
28
|
+
# This implementation is tested against results from the Google API to
|
29
|
+
# ensure compatability. See unit tests for more information.
|
30
|
+
|
31
|
+
module GPolyline
|
32
|
+
# Output an encoded path String suitable for use in Google Maps v3 API
|
33
|
+
def to_s
|
34
|
+
encode_polyline_algorithm
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
def encode_polyline_algorithm
|
39
|
+
deltas.map {|point| encode_signed_decimal(point) }.join
|
40
|
+
end
|
41
|
+
|
42
|
+
def round_decimal(decimal)
|
43
|
+
(decimal * 1e5).round
|
44
|
+
end
|
45
|
+
|
46
|
+
def encode_signed_decimal(num)
|
47
|
+
sgn_num = num << 1
|
48
|
+
sgn_num = ~sgn_num if num < 0
|
49
|
+
return encode_number(sgn_num)
|
50
|
+
end
|
51
|
+
|
52
|
+
def to_e5
|
53
|
+
@tuple_array.map do |tuple|
|
54
|
+
tuple.map{|coordinate| round_decimal(coordinate)}
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def deltas
|
59
|
+
delta_latitude, delta_longitude = 0, 0
|
60
|
+
|
61
|
+
return to_e5.inject([]) do |polyline, (longitude, latitude)|
|
62
|
+
polyline << latitude - delta_latitude
|
63
|
+
polyline << longitude - delta_longitude
|
64
|
+
delta_latitude, delta_longitude = latitude, longitude
|
65
|
+
polyline
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def encode_number(num)
|
70
|
+
encoded = ""
|
71
|
+
while (num >= 0x20) do
|
72
|
+
encoded << ((0x20 | (num & 0x1f)) + 63).chr
|
73
|
+
num = num >> 5
|
74
|
+
end
|
75
|
+
encoded << (num + 63).chr
|
76
|
+
return encoded
|
77
|
+
end
|
78
|
+
end
|
data/lib/kmlbo/kml.rb
CHANGED
@@ -2,8 +2,8 @@ require 'erb'
|
|
2
2
|
|
3
3
|
class KML
|
4
4
|
def initialize(kml_file)
|
5
|
-
@coordinates = []
|
6
5
|
@file_data = ""
|
6
|
+
@point_list = PointList.new([])
|
7
7
|
File.open(kml_file, "r") do |file|
|
8
8
|
@file_data = file.read
|
9
9
|
parse_coordinates
|
@@ -11,13 +11,17 @@ class KML
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def to_a
|
14
|
-
@
|
14
|
+
@point_list.tuple_array
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_encoded
|
18
|
+
@point_list.to_s
|
15
19
|
end
|
16
20
|
|
17
21
|
def simplify!(epsilon=nil, passes=nil)
|
18
|
-
original_number_of_coords = @
|
19
|
-
@
|
20
|
-
puts "Simplified path from #{original_number_of_coords} to #{@
|
22
|
+
original_number_of_coords = @point_list.size
|
23
|
+
@point_list = PointList.new(@point_list.tuple_array, epsilon, passes).simplify
|
24
|
+
puts "Simplified path from #{original_number_of_coords} to #{@point_list.size} points"
|
21
25
|
self
|
22
26
|
end
|
23
27
|
|
@@ -34,7 +38,10 @@ class KML
|
|
34
38
|
private
|
35
39
|
def parse_coordinates
|
36
40
|
coordinate_string = get_data_between_coordinates_markup
|
37
|
-
|
41
|
+
if coordinate_string != ""
|
42
|
+
array_data = convert_string_data_to_array_data(coordinate_string)
|
43
|
+
@point_list = PointList.new(array_data)
|
44
|
+
end
|
38
45
|
end
|
39
46
|
|
40
47
|
def get_data_between_coordinates_markup
|
data/lib/kmlbo/pointlist.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
class PointList
|
2
|
-
|
2
|
+
include GPolyline
|
3
3
|
attr_accessor :tuple_array
|
4
4
|
attr_accessor :epsilon
|
5
5
|
attr_accessor :passes
|
@@ -20,6 +20,9 @@ class PointList
|
|
20
20
|
@tuple_array == other.tuple_array
|
21
21
|
end
|
22
22
|
|
23
|
+
def size
|
24
|
+
@tuple_array.size
|
25
|
+
end
|
23
26
|
private
|
24
27
|
def douglas_peucker(point_list, epsilon)
|
25
28
|
#http://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm
|
data/lib/kmlbo.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
# kmlbo is a library and utility for working with KML, Ruby and the Google Maps API
|
2
|
+
# See https://github.com/joshuacronemeyer/kmlbo for info.
|
3
|
+
#
|
4
|
+
# Author:: Josh Cronemeyer
|
5
|
+
# Copyright:: Copyright (c) 2008-2011
|
6
|
+
# License:: MIT License (http://www.opensource.org/licenses/mit-license.php)
|
7
|
+
require 'kmlbo/g_polyline.rb'
|
8
|
+
require 'kmlbo/pointlist'
|
9
|
+
require 'kmlbo/kml'
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
# all expected values for these tests were computed using google's API
|
3
|
+
# https://developers.google.com/maps/documentation/utilities/polylineutility
|
4
|
+
class GPolylineTest < MiniTest::Unit::TestCase
|
5
|
+
describe "polyline module" do
|
6
|
+
it "must correctly convert a one element polyline" do
|
7
|
+
pointlist = PointList.new([[-122.674693498207,45.5474112205939,0]])
|
8
|
+
pointlist.to_s.must_equal "i~~tGx{vkV"
|
9
|
+
end
|
10
|
+
|
11
|
+
it "must convert a multipart line" do
|
12
|
+
path = [ [-94.42434787909789,39.13594499803094,0], [-94.42434713169446,39.1355875721549,0], [-94.424343522331,39.13486866498771,0] ]
|
13
|
+
expected = "svzmFdgi_QdA?nCA"
|
14
|
+
pointlist = PointList.new(path)
|
15
|
+
pointlist.to_s.must_equal expected
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/test/pointlist_test.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
|
-
require '
|
2
|
-
|
3
|
-
require_relative 'data.rb'
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
4
3
|
class PointlistTest < MiniTest::Unit::TestCase
|
5
4
|
describe "simplify module" do
|
6
5
|
it "must do nothing when asked to simplify a one point path" do
|
data/test/test_helper.rb
ADDED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kmlbo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ date: 2012-11-13 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
16
|
-
requirement: &
|
16
|
+
requirement: &70183536448300 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70183536448300
|
25
25
|
description: A Gem for converting kml path data to ruby arrays, and applying douglas
|
26
26
|
peucker path simplification.
|
27
27
|
email: joshuacronemeyer@gmail.com
|
@@ -33,12 +33,16 @@ files:
|
|
33
33
|
- Rakefile
|
34
34
|
- README.md
|
35
35
|
- bin/kmlbo
|
36
|
+
- lib/kmlbo.rb
|
36
37
|
- lib/kmlbo/kml.rb
|
37
|
-
- lib/kmlbo/
|
38
|
+
- lib/kmlbo/g_polyline.rb
|
38
39
|
- lib/kmlbo/pointlist.rb
|
40
|
+
- lib/kmlbo/output.kml.erb
|
39
41
|
- test/data.rb
|
40
42
|
- test/pointlist_test.rb
|
43
|
+
- test/g_polyline_test.rb
|
41
44
|
- test/sample.kml
|
45
|
+
- test/test_helper.rb
|
42
46
|
homepage: https://github.com/joshuacronemeyer/kmlbo
|
43
47
|
licenses: []
|
44
48
|
post_install_message:
|
@@ -62,9 +66,10 @@ rubyforge_project:
|
|
62
66
|
rubygems_version: 1.8.10
|
63
67
|
signing_key:
|
64
68
|
specification_version: 3
|
65
|
-
summary: A
|
66
|
-
path simplification.
|
69
|
+
summary: A library and utility for working with KML, Ruby and the Google Maps API.
|
67
70
|
test_files:
|
68
71
|
- test/data.rb
|
69
72
|
- test/pointlist_test.rb
|
73
|
+
- test/g_polyline_test.rb
|
70
74
|
- test/sample.kml
|
75
|
+
- test/test_helper.rb
|