polylines 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
@@ -0,0 +1,24 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ polylines (0.0.1)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.1.2)
10
+ rspec (2.4.0)
11
+ rspec-core (~> 2.4.0)
12
+ rspec-expectations (~> 2.4.0)
13
+ rspec-mocks (~> 2.4.0)
14
+ rspec-core (2.4.0)
15
+ rspec-expectations (2.4.0)
16
+ diff-lcs (~> 1.1.2)
17
+ rspec-mocks (2.4.0)
18
+
19
+ PLATFORMS
20
+ ruby
21
+
22
+ DEPENDENCIES
23
+ polylines!
24
+ rspec (= 2.4.0)
@@ -0,0 +1,12 @@
1
+ require "rake"
2
+ require "rake/tasklib"
3
+ require 'bundler'
4
+ Bundler::GemHelper.install_tasks
5
+
6
+ Bundler.require
7
+
8
+ require "rspec/core/rake_task"
9
+
10
+ RSpec::Core::RakeTask.new(:rspec)
11
+
12
+ task :default => [:rspec]
@@ -0,0 +1,5 @@
1
+ module Polylines
2
+ autoload :Base, "polylines/base"
3
+ autoload :Encoder, "polylines/encoder"
4
+ autoload :Decoder, "polylines/decoder"
5
+ end
@@ -0,0 +1,117 @@
1
+ module Polylines
2
+ class Base
3
+ attr_reader :current_value, :negative
4
+
5
+ def initialize(current_value)
6
+ @current_value = current_value
7
+ end
8
+
9
+ def step_2
10
+ @negative = current_value < 0 if encoding?
11
+
12
+ encode! { (current_value * 1e5).round }
13
+ decode! { current_value.to_f/1e5 }
14
+ end
15
+
16
+ def step_3
17
+ return unless negative
18
+ encode! { ~(current_value * -1) + 1 }
19
+ decode! { ~(current_value - 1) * -1 }
20
+ end
21
+
22
+ def step_4
23
+ encode! { current_value << 1 }
24
+ decode! { current_value >> 1 }
25
+ end
26
+
27
+ def step_5
28
+ return unless negative
29
+ encode! { ~current_value }
30
+ decode! { ~current_value }
31
+ end
32
+
33
+ def step_6
34
+ encode! do
35
+ [].tap do |numbers|
36
+ while current_value > 0 do
37
+ numbers.unshift(current_value & 0x1f)
38
+ @current_value >>= 5
39
+ end
40
+ end
41
+ end
42
+
43
+ decode! do
44
+ current_value.map {|chunk| "%05b" % chunk }.join.tap do |val|
45
+ @negative = val[-1, 1] == "1"
46
+ end.to_i(2)
47
+ end
48
+ end
49
+
50
+ def step_7
51
+ encode! { current_value.reverse }
52
+ decode! { current_value.reverse }
53
+ end
54
+
55
+ def step_8
56
+ encode! { current_value[0..-2].map {|item| item | 0x20 } << current_value.last }
57
+ decode! { current_value[0..-2].map {|item| item ^ 0x20 } << current_value.last }
58
+ end
59
+
60
+ def step_10
61
+ encode! { current_value.map {|value| value + 63 } }
62
+ decode! { current_value.map {|value| value - 63 } }
63
+ end
64
+
65
+ def step_11
66
+ encode! { current_value.map(&:chr).join }
67
+ decode! { current_value.split(//).map {|char| char.unpack("U").first } }
68
+ end
69
+
70
+ def encode!
71
+ if encoding?
72
+ @current_value = yield
73
+ end
74
+ end
75
+
76
+ def decode!
77
+ if decoding?
78
+ @current_value = yield
79
+ end
80
+ end
81
+
82
+ def encoding?
83
+ self.is_a?(Polylines::Encoder)
84
+ end
85
+
86
+ def decoding?
87
+ self.is_a?(Polylines::Decoder)
88
+ end
89
+
90
+ def self.transform_to_array_of_lat_lng_and_deltas(value)
91
+ if self == Polylines::Encoder
92
+ delta_latitude, delta_longitude = 0, 0
93
+
94
+ return value.inject([]) do |polyline, (latitude, longitude)|
95
+ polyline << latitude - delta_latitude
96
+ polyline << longitude - delta_longitude
97
+ delta_latitude, delta_longitude = latitude, longitude
98
+ polyline
99
+ end
100
+ end
101
+
102
+ if self == Polylines::Decoder
103
+ set = []
104
+ return value.split(//).inject([]) do |charset, char|
105
+ set << char
106
+
107
+ if ((char.unpack("U").first - 63) & 0x20).zero?
108
+ charset << set.join
109
+ set = []
110
+ end
111
+
112
+ charset
113
+ end.map {|charset| decode(charset) }
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,32 @@
1
+ module Polylines
2
+ class Decoder < Base
3
+ def self.decode_polyline(polyline)
4
+ points_with_deltas = transform_to_array_of_lat_lng_and_deltas(polyline)
5
+
6
+ [].tap do |points|
7
+ points << [points_with_deltas.shift, points_with_deltas.shift]
8
+
9
+ while points_with_deltas.any?
10
+ points << [
11
+ points.last[0] + points_with_deltas.shift,
12
+ points.last[1] + points_with_deltas.shift
13
+ ]
14
+ end
15
+ end
16
+ end
17
+
18
+ def self.decode(string)
19
+ self.new(string).tap do |decoding|
20
+ decoding.step_11
21
+ decoding.step_10
22
+ decoding.step_8
23
+ decoding.step_7
24
+ decoding.step_6
25
+ decoding.step_5
26
+ decoding.step_4
27
+ decoding.step_3
28
+ decoding.step_2
29
+ end.current_value
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,22 @@
1
+ module Polylines
2
+ class Encoder < Base
3
+ def self.encode_points(points)
4
+ points_with_deltas = transform_to_array_of_lat_lng_and_deltas(points)
5
+ points_with_deltas.map {|point| encode(point) }.join
6
+ end
7
+
8
+ def self.encode(number)
9
+ self.new(number).tap do |encoding|
10
+ encoding.step_2
11
+ encoding.step_3
12
+ encoding.step_4
13
+ encoding.step_5
14
+ encoding.step_6
15
+ encoding.step_7
16
+ encoding.step_8
17
+ encoding.step_10
18
+ encoding.step_11
19
+ end.current_value
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,3 @@
1
+ module Polylines
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "polylines/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "polylines"
7
+ s.version = Polylines::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Josh Clayton"]
10
+ s.email = ["joshua.clayton@gmail.com"]
11
+ s.homepage = ""
12
+ s.summary = %q{Easily handle Google polylines}
13
+
14
+ s.files = `git ls-files`.split("\n")
15
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
+ s.require_paths = ["lib"]
18
+
19
+ s.add_development_dependency("rspec", "2.4.0")
20
+ end
@@ -0,0 +1,16 @@
1
+ require "spec_helper"
2
+
3
+ describe Polylines::Decoder, ".decode" do
4
+ it "decodes a single point" do
5
+ Polylines::Decoder.decode("`~oia@").should be_within(0.00001).of(-179.9832104)
6
+ end
7
+ end
8
+
9
+ describe Polylines::Decoder, ".decode_polyline" do
10
+ let(:polyline) { "_p~iF~ps|U_ulLnnqC_mqNvxq`@" }
11
+ let(:points) { [[38.5, -120.2], [40.7, -120.95], [43.252, -126.453]] }
12
+
13
+ it "decodes a polyline correctly" do
14
+ Polylines::Decoder.decode_polyline(polyline).should == points
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ require "spec_helper"
2
+
3
+ describe Polylines::Encoder, ".encode" do
4
+ it "encodes a single point" do
5
+ Polylines::Encoder.encode(-179.9832104).should == "`~oia@"
6
+ end
7
+ end
8
+
9
+ describe Polylines::Encoder, ".encode_points" do
10
+ let(:polyline) { "_p~iF~ps|U_ulLnnqC_mqNvxq`@" }
11
+ let(:points) { [[38.5, -120.2], [40.7, -120.95], [43.252, -126.453]] }
12
+
13
+ it "encodes points correctly" do
14
+ Polylines::Encoder.encode_points(points).should == polyline
15
+ end
16
+ end
@@ -0,0 +1,7 @@
1
+ require "rubygems"
2
+ require "bundler/setup"
3
+
4
+ require "polylines"
5
+ #
6
+ # RSpec.configure do |config|
7
+ # end
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: polylines
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Josh Clayton
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-02-19 00:00:00 -05:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rspec
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - "="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 2
30
+ - 4
31
+ - 0
32
+ version: 2.4.0
33
+ type: :development
34
+ version_requirements: *id001
35
+ description:
36
+ email:
37
+ - joshua.clayton@gmail.com
38
+ executables: []
39
+
40
+ extensions: []
41
+
42
+ extra_rdoc_files: []
43
+
44
+ files:
45
+ - .gitignore
46
+ - Gemfile
47
+ - Gemfile.lock
48
+ - Rakefile
49
+ - lib/polylines.rb
50
+ - lib/polylines/base.rb
51
+ - lib/polylines/decoder.rb
52
+ - lib/polylines/encoder.rb
53
+ - lib/polylines/version.rb
54
+ - polylines.gemspec
55
+ - spec/polylines/decoder_spec.rb
56
+ - spec/polylines/encoder_spec.rb
57
+ - spec/spec_helper.rb
58
+ has_rdoc: true
59
+ homepage: ""
60
+ licenses: []
61
+
62
+ post_install_message:
63
+ rdoc_options: []
64
+
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ segments:
73
+ - 0
74
+ version: "0"
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ segments:
81
+ - 0
82
+ version: "0"
83
+ requirements: []
84
+
85
+ rubyforge_project:
86
+ rubygems_version: 1.3.7
87
+ signing_key:
88
+ specification_version: 3
89
+ summary: Easily handle Google polylines
90
+ test_files:
91
+ - spec/polylines/decoder_spec.rb
92
+ - spec/polylines/encoder_spec.rb
93
+ - spec/spec_helper.rb