nayutaya-googlemaps-polyline 0.0.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.
@@ -0,0 +1,10 @@
1
+
2
+ # googlemaps-polyline
3
+
4
+ googlemaps-polylineは、Google Maps APIのエンコード化ポリラインを取り扱う
5
+ ためのライブラリです。
6
+ ポリラインのエンコード、デコードを行うことができます。
7
+
8
+ ## インストール
9
+
10
+ $ gem install nayutaya-googlemaps-polyline
@@ -0,0 +1,70 @@
1
+
2
+ require "rake/testtask"
3
+ require "lib/googlemaps_polyline/version"
4
+
5
+ PACKAGE_NAME = "nayutaya-googlemaps-polyline"
6
+ PACKAGE_VERSION = GoogleMapsPolyline::VERSION
7
+
8
+ task :default => :test
9
+
10
+ Rake::TestTask.new do |test|
11
+ test.libs << "test"
12
+ test.test_files = Dir.glob("test/**/*_test.rb")
13
+ test.verbose = true
14
+ end
15
+
16
+ namespace :version do
17
+ desc "show current version"
18
+ task :show do
19
+ puts(PACKAGE_VERSION)
20
+ end
21
+
22
+ desc "bump version"
23
+ task :bump do
24
+ cur_version = PACKAGE_VERSION
25
+ next_version = cur_version.succ
26
+ puts("#{cur_version} -> #{next_version}")
27
+
28
+ filename = File.join(File.dirname(__FILE__), "lib", "googlemaps_polyline", "version.rb")
29
+ File.open(filename, "wb") { |file|
30
+ file.puts(%|# coding: utf-8|)
31
+ file.puts(%||)
32
+ file.puts(%|module GoogleMapsPolyline|)
33
+ file.puts(%| VERSION = "#{next_version}"|)
34
+ file.puts(%|end|)
35
+ }
36
+ end
37
+ end
38
+
39
+ namespace :gem do
40
+ desc "generate gemspec"
41
+ task :spec do
42
+ require "erb"
43
+
44
+ src = File.open("#{PACKAGE_NAME}.gemspec.erb", "rb") { |file| file.read }
45
+ erb = ERB.new(src, nil, "-")
46
+
47
+ files = Dir.glob("**/*").
48
+ select { |s| File.file?(s) }.
49
+ reject { |s| /\.gem\z/ =~ s }.
50
+ reject { |s| /\Anbproject\// =~ s }
51
+
52
+ test_files = Dir.glob("test/**").
53
+ select { |s| File.file?(s) }
54
+
55
+ File.open("#{PACKAGE_NAME}.gemspec", "wb") { |file|
56
+ file.write(erb.result(binding))
57
+ }
58
+ end
59
+
60
+ desc "build gem"
61
+ task :build do
62
+ sh "gem build #{PACKAGE_NAME}.gemspec"
63
+ end
64
+
65
+ desc "push gem"
66
+ task :push do
67
+ target = "#{PACKAGE_NAME}-#{PACKAGE_VERSION}.gem"
68
+ sh "gem push #{target}"
69
+ end
70
+ end
@@ -0,0 +1,4 @@
1
+ # coding: utf-8
2
+
3
+ require "googlemaps_polyline/version"
4
+ require "googlemaps_polyline/core"
@@ -0,0 +1,39 @@
1
+ # coding: utf-8
2
+
3
+ require "googlemaps_polyline/encoder"
4
+ require "googlemaps_polyline/decoder"
5
+
6
+ module GoogleMapsPolyline
7
+ def self.encode_points_and_levels(points, levels)
8
+ encoded_points = Encoder.new(StringIO.new).encode_points(points).string
9
+ encoded_levels = Encoder.new(StringIO.new).encode_levels(levels).string
10
+ return encoded_points, encoded_levels
11
+ end
12
+
13
+ def self.encode_polyline_1e5(records)
14
+ points = records.map { |record| record[0..1] }
15
+ levels = records.map { |record| record[2] }
16
+ return self.encode_points_and_levels(points, levels)
17
+ end
18
+
19
+ def self.encode_polyline(records)
20
+ records_1e5 = records.map { |lat, lng, level| [(lat * 1e5).to_i, (lng * 1e5).to_i, level] }
21
+ return self.encode_polyline_1e5(records_1e5)
22
+ end
23
+
24
+ def self.decode_points_and_levels(points, levels)
25
+ decoded_points = Decoder.new(StringIO.new(points)).decode_points
26
+ decoded_levels = Decoder.new(StringIO.new(levels)).decode_levels
27
+ return decoded_points, decoded_levels
28
+ end
29
+
30
+ def self.decode_polyline_1e5(points, levels)
31
+ decoded_points, decoded_levels = self.decode_points_and_levels(points, levels)
32
+ return decoded_points.zip(decoded_levels).map { |a| a.flatten }
33
+ end
34
+
35
+ def self.decode_polyline(points, levels)
36
+ records = self.decode_polyline_1e5(points, levels)
37
+ return records.map { |lat, lng, level| [lat.to_f / 1e5, lng.to_f / 1e5, level] }
38
+ end
39
+ end
@@ -0,0 +1,73 @@
1
+ # coding: utf-8
2
+
3
+ module GoogleMapsPolyline
4
+ class Decoder
5
+ def initialize(io)
6
+ @io = io
7
+ end
8
+
9
+ attr_reader :io
10
+
11
+ def decode_points
12
+ points = []
13
+
14
+ until @io.eof?
15
+ lat = read_point(@io)
16
+ lng = read_point(@io)
17
+
18
+ unless points.empty?
19
+ lat += points.last[0]
20
+ lng += points.last[1]
21
+ end
22
+
23
+ points << [lat, lng]
24
+ end
25
+
26
+ return points
27
+ end
28
+
29
+ def decode_levels
30
+ levels = []
31
+
32
+ until @io.eof?
33
+ levels << read_level(@io)
34
+ end
35
+
36
+ return levels
37
+ end
38
+
39
+ private
40
+
41
+ def read_point(io)
42
+ codes = []
43
+
44
+ while (char = io.read(1))
45
+ code = char.unpack("C")[0] - 63
46
+ codes << (code & ~0x20)
47
+ break if code & 0x20 == 0
48
+ end
49
+
50
+ raise(ArgumentError) unless (1..6).include?(codes.size)
51
+
52
+ bin = codes.map { |c| '%05b' % c }.reverse.join("")
53
+
54
+ negative = (bin.slice!(-1, 1) == "1")
55
+
56
+ num = bin.to_i(2)
57
+ num *= -1 if negative
58
+ num += -1 if negative
59
+
60
+ return num
61
+ end
62
+
63
+ def read_level(io)
64
+ case io.read(1)
65
+ when "?" then return 0
66
+ when "@" then return 1
67
+ when "A" then return 2
68
+ when "B" then return 3
69
+ else raise(ArgumentError)
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,64 @@
1
+ # coding: utf-8
2
+
3
+ module GoogleMapsPolyline
4
+ class Encoder
5
+ def initialize(io)
6
+ @io = io
7
+ end
8
+
9
+ attr_reader :io
10
+
11
+ def encode_points(points)
12
+ plat, plng = 0, 0
13
+ points.each { |lat, lng|
14
+ @io.write(pack_point(lat - plat))
15
+ @io.write(pack_point(lng - plng))
16
+ plat, plng = lat, lng
17
+ }
18
+
19
+ return @io
20
+ end
21
+
22
+ def encode_levels(levels)
23
+ levels.each { |level|
24
+ @io.write(pack_level(level))
25
+ }
26
+
27
+ return @io
28
+ end
29
+
30
+ private
31
+
32
+ def pack_point(num)
33
+ negative = (num < 0)
34
+ if negative
35
+ num -= -1
36
+ num *= -1
37
+ end
38
+
39
+ num <<= 1
40
+ num |= 1 if negative
41
+
42
+ codes = []
43
+
44
+ begin
45
+ code = (num & 0b11111) + 63
46
+ num >>= 5
47
+ code += 0x20 if num > 0
48
+ codes << code
49
+ end while num > 0
50
+
51
+ return codes.pack("C*")
52
+ end
53
+
54
+ def pack_level(level)
55
+ case level
56
+ when 0 then return "?"
57
+ when 1 then return "@"
58
+ when 2 then return "A"
59
+ when 3 then return "B"
60
+ else raise(ArgumentError)
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,5 @@
1
+ # coding: utf-8
2
+
3
+ module GoogleMapsPolyline
4
+ VERSION = "0.0.1"
5
+ end
@@ -0,0 +1,44 @@
1
+
2
+ Gem::Specification.new do |s|
3
+ s.specification_version = 2
4
+ s.required_rubygems_version = Gem::Requirement.new(">= 0")
5
+ s.required_ruby_version = Gem::Requirement.new(">= 1.8.6")
6
+
7
+ s.name = "nayutaya-googlemaps-polyline"
8
+ s.version = "0.0.1"
9
+ s.date = "2010-03-23"
10
+
11
+ s.authors = ["Yuya Kato"]
12
+ s.email = "yuyakato@gmail.com"
13
+
14
+ s.summary = "Google Maps Polyline Utility"
15
+ s.description = "Polyline Encoder/Decoder for Google Maps API"
16
+ s.homepage = "http://github.com/nayutaya/googlemaps-polyline/"
17
+
18
+ s.rubyforge_project = nil
19
+ s.has_rdoc = false
20
+ s.require_paths = ["lib"]
21
+
22
+ s.files = [
23
+ "lib/googlemaps_polyline/core.rb",
24
+ "lib/googlemaps_polyline/decoder.rb",
25
+ "lib/googlemaps_polyline/encoder.rb",
26
+ "lib/googlemaps_polyline/version.rb",
27
+ "lib/googlemaps_polyline.rb",
28
+ "nayutaya-googlemaps-polyline.gemspec",
29
+ "nayutaya-googlemaps-polyline.gemspec.erb",
30
+ "Rakefile",
31
+ "README.md",
32
+ "test/core_test.rb",
33
+ "test/decoder_test.rb",
34
+ "test/encoder_test.rb",
35
+ "test/test_helper.rb",
36
+ ]
37
+ s.test_files = [
38
+ "test/core_test.rb",
39
+ "test/decoder_test.rb",
40
+ "test/encoder_test.rb",
41
+ "test/test_helper.rb",
42
+ ]
43
+ s.extra_rdoc_files = []
44
+ end
@@ -0,0 +1,33 @@
1
+
2
+ Gem::Specification.new do |s|
3
+ s.specification_version = 2
4
+ s.required_rubygems_version = Gem::Requirement.new(">= 0")
5
+ s.required_ruby_version = Gem::Requirement.new(">= 1.8.6")
6
+
7
+ s.name = <%= PACKAGE_NAME.dump %>
8
+ s.version = <%= PACKAGE_VERSION.dump %>
9
+ s.date = <%= Time.now.strftime("%Y-%m-%d").dump %>
10
+
11
+ s.authors = ["Yuya Kato"]
12
+ s.email = "yuyakato@gmail.com"
13
+
14
+ s.summary = "Google Maps Polyline Utility"
15
+ s.description = "Polyline Encoder/Decoder for Google Maps API"
16
+ s.homepage = "http://github.com/nayutaya/googlemaps-polyline/"
17
+
18
+ s.rubyforge_project = nil
19
+ s.has_rdoc = false
20
+ s.require_paths = ["lib"]
21
+
22
+ s.files = [
23
+ <%- files.each { |path| -%>
24
+ <%= path.dump %>,
25
+ <%- } -%>
26
+ ]
27
+ s.test_files = [
28
+ <%- test_files.each { |path| -%>
29
+ <%= path.dump %>,
30
+ <%- } -%>
31
+ ]
32
+ s.extra_rdoc_files = []
33
+ end
@@ -0,0 +1,76 @@
1
+ # coding: utf-8
2
+
3
+ require "test_helper"
4
+ require "googlemaps_polyline/core"
5
+
6
+ class CoreTest < Test::Unit::TestCase
7
+ def setup
8
+ @mod = GoogleMapsPolyline
9
+ end
10
+
11
+ def test_encode_points_and_levels
12
+ points, levels = @mod.encode_points_and_levels([[0, 0]], [3])
13
+ assert_equal("??", points)
14
+ assert_equal("B", levels)
15
+ end
16
+
17
+ def test_encode_polyline_1e5__1
18
+ points, levels = @mod.encode_polyline_1e5([[0, 0, 3]])
19
+ assert_equal("??", points)
20
+ assert_equal("B", levels)
21
+ end
22
+
23
+ def test_encode_polyline_1e5__1
24
+ points, levels = @mod.encode_polyline_1e5(
25
+ [[1, 2, 3], [2, 4, 2], [3, 8, 1], [4, 16, 0], [5, 32, 3]])
26
+ assert_equal("ACACAGAOA_@", points)
27
+ assert_equal("BA@?B", levels)
28
+ end
29
+
30
+ def test_encode_polyline
31
+ points, levels = @mod.encode_polyline(
32
+ [[34.69025, 135.19501, 3], [34.69363, 135.50192, 3]])
33
+ assert_equal("amvrEygdxXcTe}z@", points)
34
+ assert_equal("BB", levels)
35
+ end
36
+
37
+ def test_decode_points_and_levels
38
+ expected = [[[0, 0]], [3]]
39
+ assert_equal(
40
+ expected,
41
+ @mod.decode_points_and_levels("??", "B"))
42
+ end
43
+
44
+ def test_decode_polyline_1e5__1
45
+ expected = [[0, 0, 3]]
46
+ assert_equal(
47
+ expected,
48
+ @mod.decode_polyline_1e5("??", "B"))
49
+ end
50
+
51
+ def test_decode_polyline_1e5__2
52
+ expected = [[1, 2, 3], [2, 4, 2], [3, 8, 1], [4, 16, 0], [5, 32, 3]]
53
+ assert_equal(
54
+ expected,
55
+ @mod.decode_polyline_1e5("ACACAGAOA_@", "BA@?B"))
56
+ end
57
+
58
+ def test_decode_polyline
59
+ expected = [[34.69025, 135.19501, 3], [34.69363, 135.50192, 3]]
60
+ assert_equal(
61
+ expected,
62
+ @mod.decode_polyline("amvrEygdxXcTe}z@", "BB"))
63
+ end
64
+
65
+ def test_encode_and_decode
66
+ srand(0)
67
+ points1 = 20.times.map { [rand(180 * 1e5) - 90 * 1e5, rand(360 * 1e5) - 180 * 1e5] }.map { |lat, lng| [lat.to_i, lng.to_i] }
68
+ levels1 = [3] + 18.times.map { rand(4) } + [3]
69
+
70
+ points2, levels2 = @mod.encode_points_and_levels(points1, levels1)
71
+ points3, levels3 = @mod.decode_points_and_levels(points2, levels2)
72
+
73
+ assert_equal(points1, points3)
74
+ assert_equal(levels1, levels3)
75
+ end
76
+ end
@@ -0,0 +1,88 @@
1
+ # coding: utf-8
2
+
3
+ require "test_helper"
4
+ require "googlemaps_polyline/decoder"
5
+ require "stringio"
6
+
7
+ class DecoderTest < Test::Unit::TestCase
8
+ def setup
9
+ @klass = GoogleMapsPolyline::Decoder
10
+ end
11
+
12
+ def test_initialize
13
+ io = sio
14
+ encoder = @klass.new(io)
15
+ assert_same(io, encoder.io)
16
+ end
17
+
18
+ def test_decode_points__1
19
+ assert_equal(
20
+ [[0, 0]],
21
+ @klass.new(sio("??")).decode_points)
22
+ end
23
+
24
+ def test_decode_points__2
25
+ assert_equal(
26
+ [[0, 0], [0, 0]],
27
+ @klass.new(sio("????")).decode_points)
28
+ end
29
+
30
+ def test_decode_points__3
31
+ assert_equal(
32
+ [[1, 0]],
33
+ @klass.new(sio("A?")).decode_points)
34
+ end
35
+
36
+ def test_decode_points__4
37
+ assert_equal(
38
+ [[0, 1]],
39
+ @klass.new(sio("?A")).decode_points)
40
+ end
41
+
42
+ def test_decode_points__5
43
+ assert_equal(
44
+ [[1, 1], [1, 1]],
45
+ @klass.new(sio("AA??")).decode_points)
46
+ end
47
+
48
+ def test_decode_points__6
49
+ assert_equal(
50
+ [[1, 2], [2, 4], [3, 8], [4, 16], [5, 32]],
51
+ @klass.new(sio("ACACAGAOA_@")).decode_points)
52
+ end
53
+
54
+ def test_decode_levels
55
+ assert_equal(
56
+ [0, 1, 2, 3],
57
+ @klass.new(sio("?@AB")).decode_levels)
58
+ end
59
+
60
+ def test_read_point
61
+ decoder = @klass.new(sio)
62
+ read_point = proc { |io| decoder.instance_eval { read_point(io) } }
63
+ assert_equal( 0, read_point[sio("?")])
64
+ assert_equal( 1, read_point[sio("A")])
65
+ assert_equal( -1, read_point[sio("@")])
66
+ assert_equal( 12345678, read_point[sio("{sopV")])
67
+ assert_equal(-12345678, read_point[sio("zsopV")])
68
+ assert_equal( 18000000, read_point[sio("_gsia@")])
69
+ assert_equal(-18000000, read_point[sio("~fsia@")])
70
+ assert_raise(ArgumentError) { read_point[sio("")] }
71
+ end
72
+
73
+ def test_read_level
74
+ decoder = @klass.new(sio)
75
+ read_level = proc { |io| decoder.instance_eval { read_level(io) } }
76
+ assert_equal(0, read_level[sio("?")])
77
+ assert_equal(1, read_level[sio("@")])
78
+ assert_equal(2, read_level[sio("A")])
79
+ assert_equal(3, read_level[sio("B")])
80
+ assert_raise(ArgumentError) { read_level[sio("")] }
81
+ end
82
+
83
+ private
84
+
85
+ def sio(string = nil)
86
+ return StringIO.new(string || "")
87
+ end
88
+ end
@@ -0,0 +1,97 @@
1
+ # coding: utf-8
2
+
3
+ require "test_helper"
4
+ require "googlemaps_polyline/encoder"
5
+ require "stringio"
6
+
7
+ class EncoderTest < Test::Unit::TestCase
8
+ def setup
9
+ @klass = GoogleMapsPolyline::Encoder
10
+ @encoder = @klass.new(sio)
11
+ end
12
+
13
+ def test_initialize
14
+ io = sio
15
+ encoder = @klass.new(io)
16
+ assert_same(io, encoder.io)
17
+ end
18
+
19
+ def test_encode_points__1
20
+ assert_equal(
21
+ "",
22
+ @encoder.encode_points([]).string)
23
+ end
24
+
25
+ def test_encode_points__2
26
+ assert_equal(
27
+ "??",
28
+ @encoder.encode_points([[0, 0]]).string)
29
+ end
30
+
31
+ def test_encode_points__3
32
+ assert_equal(
33
+ "????",
34
+ @encoder.encode_points([[0, 0], [0, 0]]).string)
35
+ end
36
+
37
+ def test_encode_points__4
38
+ assert_equal(
39
+ "A?",
40
+ @encoder.encode_points([[1, 0]]).string)
41
+ end
42
+
43
+ def test_encode_points__5
44
+ assert_equal(
45
+ "?A",
46
+ @encoder.encode_points([[0, 1]]).string)
47
+ end
48
+
49
+ def test_encode_points__6
50
+ assert_equal(
51
+ "AA??",
52
+ @encoder.encode_points([[1, 1], [1, 1]]).string)
53
+ end
54
+
55
+ def test_encode_points__7
56
+ assert_equal(
57
+ "ACACAGAOA_@",
58
+ @encoder.encode_points([[1, 2], [2, 4], [3, 8], [4, 16], [5, 32]]).string)
59
+ end
60
+
61
+ def test_encode_levels
62
+ assert_equal(
63
+ "?@AB",
64
+ @encoder.encode_levels([0, 1, 2, 3]).string)
65
+ end
66
+
67
+ def test_pack_point
68
+ pack_point = proc { |num| @encoder.instance_eval { pack_point(num) } }
69
+ assert_equal("?" , pack_point[ 0])
70
+ assert_equal("A" , pack_point[ 1])
71
+ assert_equal("@" , pack_point[ -1])
72
+ assert_equal("{sopV" , pack_point[ 12345678])
73
+ assert_equal("zsopV" , pack_point[-12345678])
74
+ assert_equal("_gsia@", pack_point[ 18000000])
75
+ assert_equal("~fsia@", pack_point[-18000000])
76
+ end
77
+
78
+ def test_pack_level
79
+ pack_level = proc { |level| @encoder.instance_eval { pack_level(level) } }
80
+ assert_equal("?", pack_level[0])
81
+ assert_equal("@", pack_level[1])
82
+ assert_equal("A", pack_level[2])
83
+ assert_equal("B", pack_level[3])
84
+ end
85
+
86
+ def test_pack_level__invalid
87
+ assert_raise(ArgumentError) {
88
+ @encoder.instance_eval { pack_level(-1) }
89
+ }
90
+ end
91
+
92
+ private
93
+
94
+ def sio(string = nil)
95
+ return StringIO.new(string || "")
96
+ end
97
+ end
@@ -0,0 +1,13 @@
1
+ # coding: utf-8
2
+
3
+ $:.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
4
+
5
+ require "test/unit"
6
+
7
+ begin
8
+ require "rubygems"
9
+ require "redgreen"
10
+ require "win32console" if /win32/ =~ RUBY_PLATFORM
11
+ rescue LoadError
12
+ # nop
13
+ end
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nayutaya-googlemaps-polyline
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Yuya Kato
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-03-23 00:00:00 +09:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Polyline Encoder/Decoder for Google Maps API
17
+ email: yuyakato@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - lib/googlemaps_polyline/core.rb
26
+ - lib/googlemaps_polyline/decoder.rb
27
+ - lib/googlemaps_polyline/encoder.rb
28
+ - lib/googlemaps_polyline/version.rb
29
+ - lib/googlemaps_polyline.rb
30
+ - nayutaya-googlemaps-polyline.gemspec
31
+ - nayutaya-googlemaps-polyline.gemspec.erb
32
+ - Rakefile
33
+ - README.md
34
+ - test/core_test.rb
35
+ - test/decoder_test.rb
36
+ - test/encoder_test.rb
37
+ - test/test_helper.rb
38
+ has_rdoc: true
39
+ homepage: http://github.com/nayutaya/googlemaps-polyline/
40
+ licenses: []
41
+
42
+ post_install_message:
43
+ rdoc_options: []
44
+
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: 1.8.6
52
+ version:
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ version:
59
+ requirements: []
60
+
61
+ rubyforge_project:
62
+ rubygems_version: 1.3.5
63
+ signing_key:
64
+ specification_version: 2
65
+ summary: Google Maps Polyline Utility
66
+ test_files:
67
+ - test/core_test.rb
68
+ - test/decoder_test.rb
69
+ - test/encoder_test.rb
70
+ - test/test_helper.rb