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