polylines 0.0.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: da58528bb3a57978f8dc73763bcebd2dd09d64cac7f6c64f6dffc33cdcc9a1c1
4
+ data.tar.gz: a0869fe420b3721e367374e163c2b396655efbb47b1a6c50b8864943a162a191
5
+ SHA512:
6
+ metadata.gz: b8745bf6f073c0894590884508f587448fdda56a9e24e8c2a09649f7477cd2eab1602e85c2754eb43242e43bc7748d8eb703aa948d68c9959ac546f7363dbe42
7
+ data.tar.gz: 9dc0c56d23b52261c03443a6f0b9a1a6e96fcb2c7f5b20ff1246853e69370c0fea4d1a35614a95deaccdb6f5a125fc8f4bb165f459da55f4c41a2074b950ae70
@@ -1,24 +1,34 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- polylines (0.0.1)
4
+ polylines (0.4.0)
5
5
 
6
6
  GEM
7
7
  remote: http://rubygems.org/
8
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)
9
+ diff-lcs (1.4.4)
10
+ rake (10.0.2)
11
+ rspec (3.10.0)
12
+ rspec-core (~> 3.10.0)
13
+ rspec-expectations (~> 3.10.0)
14
+ rspec-mocks (~> 3.10.0)
15
+ rspec-core (3.10.0)
16
+ rspec-support (~> 3.10.0)
17
+ rspec-expectations (3.10.0)
18
+ diff-lcs (>= 1.2.0, < 2.0)
19
+ rspec-support (~> 3.10.0)
20
+ rspec-mocks (3.10.0)
21
+ diff-lcs (>= 1.2.0, < 2.0)
22
+ rspec-support (~> 3.10.0)
23
+ rspec-support (3.10.0)
18
24
 
19
25
  PLATFORMS
20
26
  ruby
21
27
 
22
28
  DEPENDENCIES
23
29
  polylines!
24
- rspec (= 2.4.0)
30
+ rake
31
+ rspec (= 3.10.0)
32
+
33
+ BUNDLED WITH
34
+ 2.1.4
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2011 Josh Clayton
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,31 @@
1
+ # Polylines
2
+
3
+ ## Easily handle Google polylines
4
+
5
+ ## Install
6
+
7
+ Install with Rubygems:
8
+
9
+ gem install polylines
10
+
11
+ ## Usage
12
+
13
+ To encode an array of latitude/longitude pairs:
14
+
15
+ >> Polylines::Encoder.encode_points([[38.5, -120.2], [40.7, -120.95], [43.252, -126.453]])
16
+ => "_p~iF~ps|U_ulLnnqC_mqNvxq`@"
17
+
18
+ To decode a polyline into an array of latitude/longitude pairs:
19
+
20
+ >> Polylines::Decoder.decode_polyline("_p~iF~ps|U_ulLnnqC_mqNvxq`@")
21
+ => [[38.5, -120.2], [40.7, -120.95], [43.252, -126.453]]
22
+
23
+ I wrote this to follow the steps outlined in http://code.google.com/apis/maps/documentation/utilities/polylinealgorithm.html.
24
+
25
+ ## License
26
+
27
+ Please see LICENSE
28
+
29
+ ## Author
30
+
31
+ Written by Josh Clayton
@@ -1,5 +1,6 @@
1
+ require "polylines/base"
2
+ require "polylines/encoder"
3
+ require "polylines/decoder"
4
+
1
5
  module Polylines
2
- autoload :Base, "polylines/base"
3
- autoload :Encoder, "polylines/encoder"
4
- autoload :Decoder, "polylines/decoder"
5
6
  end
@@ -6,11 +6,11 @@ module Polylines
6
6
  @current_value = current_value
7
7
  end
8
8
 
9
- def step_2
9
+ def step_2(precision = 1e5)
10
10
  @negative = current_value < 0 if encoding?
11
11
 
12
- encode! { (current_value * 1e5).round }
13
- decode! { current_value.to_f/1e5 }
12
+ encode! { (current_value * precision).round }
13
+ decode! { current_value.to_f/precision }
14
14
  end
15
15
 
16
16
  def step_3
@@ -37,6 +37,8 @@ module Polylines
37
37
  numbers.unshift(current_value & 0x1f)
38
38
  @current_value >>= 5
39
39
  end
40
+
41
+ numbers << 0 if numbers.empty?
40
42
  end
41
43
  end
42
44
 
@@ -87,16 +89,18 @@ module Polylines
87
89
  self.is_a?(Polylines::Decoder)
88
90
  end
89
91
 
90
- def self.transform_to_array_of_lat_lng_and_deltas(value)
92
+ def self.transform_to_array_of_lat_lng_and_deltas(value, precision = 1e5)
91
93
  if self == Polylines::Encoder
92
94
  delta_latitude, delta_longitude = 0, 0
93
95
 
94
- return value.inject([]) do |polyline, (latitude, longitude)|
96
+ shifted_values = value.map{|tuple| tuple.map{|val| (val * precision).round } }
97
+ deltas = shifted_values.inject([]) do |polyline, (latitude, longitude)|
95
98
  polyline << latitude - delta_latitude
96
99
  polyline << longitude - delta_longitude
97
100
  delta_latitude, delta_longitude = latitude, longitude
98
101
  polyline
99
102
  end
103
+ return deltas.map{|val| val.to_f/precision }
100
104
  end
101
105
 
102
106
  if self == Polylines::Decoder
@@ -110,7 +114,7 @@ module Polylines
110
114
  end
111
115
 
112
116
  charset
113
- end.map {|charset| decode(charset) }
117
+ end.map {|charset| decode(charset, precision) }
114
118
  end
115
119
  end
116
120
  end
@@ -1,12 +1,13 @@
1
1
  module Polylines
2
2
  class Decoder < Base
3
- def self.decode_polyline(polyline)
4
- points_with_deltas = transform_to_array_of_lat_lng_and_deltas(polyline)
3
+ def self.decode_polyline(polyline, precision = 1e5)
4
+ points_with_deltas = transform_to_array_of_lat_lng_and_deltas(polyline,
5
+ precision)
5
6
 
6
7
  [].tap do |points|
7
8
  points << [points_with_deltas.shift, points_with_deltas.shift]
8
9
 
9
- while points_with_deltas.any?
10
+ while points_with_deltas.size > 1
10
11
  points << [
11
12
  points.last[0] + points_with_deltas.shift,
12
13
  points.last[1] + points_with_deltas.shift
@@ -15,7 +16,7 @@ module Polylines
15
16
  end
16
17
  end
17
18
 
18
- def self.decode(string)
19
+ def self.decode(string, precision = 1e5)
19
20
  self.new(string).tap do |decoding|
20
21
  decoding.step_11
21
22
  decoding.step_10
@@ -25,7 +26,7 @@ module Polylines
25
26
  decoding.step_5
26
27
  decoding.step_4
27
28
  decoding.step_3
28
- decoding.step_2
29
+ decoding.step_2 precision
29
30
  end.current_value
30
31
  end
31
32
  end
@@ -1,13 +1,13 @@
1
1
  module Polylines
2
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
3
+ def self.encode_points(points, precision = 1e5)
4
+ points_with_deltas = transform_to_array_of_lat_lng_and_deltas(points, precision)
5
+ points_with_deltas.map {|point| encode(point, precision) }.join
6
6
  end
7
7
 
8
- def self.encode(number)
8
+ def self.encode(number, precision = 1e5)
9
9
  self.new(number).tap do |encoding|
10
- encoding.step_2
10
+ encoding.step_2 precision
11
11
  encoding.step_3
12
12
  encoding.step_4
13
13
  encoding.step_5
@@ -1,3 +1,3 @@
1
1
  module Polylines
2
- VERSION = "0.0.1"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -16,5 +16,6 @@ Gem::Specification.new do |s|
16
16
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
17
  s.require_paths = ["lib"]
18
18
 
19
- s.add_development_dependency("rspec", "2.4.0")
19
+ s.add_development_dependency("rspec", "3.10.0")
20
+ s.add_development_dependency("rake")
20
21
  end
@@ -2,15 +2,52 @@ require "spec_helper"
2
2
 
3
3
  describe Polylines::Decoder, ".decode" do
4
4
  it "decodes a single point" do
5
- Polylines::Decoder.decode("`~oia@").should be_within(0.00001).of(-179.9832104)
5
+ expect(Polylines::Decoder.decode("`~oia@")).to be_within(0.00001).of(-179.9832104)
6
+ end
7
+
8
+ it "decodes a single point with 1e6 precision" do
9
+ expect(Polylines::Decoder.decode("ruhhvI", 1e6)).to be_within(0.000001).of(-179.9832104)
6
10
  end
7
11
  end
8
12
 
9
13
  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]] }
14
+ let(:points) { [[38.5, -120.2], [40.7, -120.95], [43.252, -126.453]] }
15
+
16
+ context "with default precision" do
17
+ it "decodes a polyline correctly" do
18
+ polyline = "_p~iF~ps|U_ulLnnqC_mqNvxq`@"
19
+
20
+ expect(Polylines::Decoder.decode_polyline(polyline)).to eq points
21
+ end
22
+ end
23
+
24
+ context "with 1e6 precision" do
25
+ it "decodes a polyline correctly" do
26
+ polyline = "_izlhA~rlgdF_{geC~ywl@_kwzCn`{nI"
27
+
28
+ expect(Polylines::Decoder.decode_polyline(polyline, 1e6)).to eq points
29
+ end
30
+ end
31
+ end
12
32
 
33
+ describe Polylines::Decoder, ".decode_polyline with points that were close together" do
13
34
  it "decodes a polyline correctly" do
14
- Polylines::Decoder.decode_polyline(polyline).should == points
35
+ points = [[41.35222, -86.04563], [41.35222, -86.04544]]
36
+
37
+ expect(Polylines::Decoder.decode_polyline("krk{FdxdlO?e@")).to eq points
38
+ end
39
+
40
+ it "decodes a polyline correctly with 1e6 precision" do
41
+ points = [[41.352217, -86.045630], [41.352217, -86.045437]]
42
+
43
+ expect(Polylines::Decoder.decode_polyline("q`}zmAzzxbcD?aK", 1e6)).to eq points
44
+ end
45
+ end
46
+
47
+ describe Polylines::Decoder, ".decode_polyline with a value that previously broke" do
48
+ it "decodes a polyline correctly" do
49
+ value = "kbdoH{ioqCoF_j@Lwc@lC{BhNoMzCuJbEm]?wKkBaQmD}EqM_GwFiBfCge@zE_K~SaTdT`L|Da\\\\xJsX|EyJtQgPpXuRjKAtJqBfM[pn@g^nF}G??"
50
+
51
+ expect(Polylines::Decoder.decode_polyline(value).length).to eq 27
15
52
  end
16
53
  end
@@ -2,15 +2,52 @@ require "spec_helper"
2
2
 
3
3
  describe Polylines::Encoder, ".encode" do
4
4
  it "encodes a single point" do
5
- Polylines::Encoder.encode(-179.9832104).should == "`~oia@"
5
+ expect(Polylines::Encoder.encode(-179.9832104)).to eq "`~oia@"
6
+ end
7
+
8
+ it "encodes a single point with 1e6 precision" do
9
+ expect(Polylines::Encoder.encode(-179.9832104, 1e6)).to eq "ruhhvI"
6
10
  end
7
11
  end
8
12
 
9
13
  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]] }
14
+ let(:points) { [[38.5, -120.2], [40.7, -120.95], [43.252, -126.453]] }
15
+
16
+ context "with default precision" do
17
+ it "encodes points correctly" do
18
+ polyline = "_p~iF~ps|U_ulLnnqC_mqNvxq`@"
19
+
20
+ expect(Polylines::Encoder.encode_points(points)).to eq polyline
21
+ end
22
+ end
23
+
24
+ context "with 1e6 precsion" do
25
+ it "encodes points correctly" do
26
+ polyline = "_izlhA~rlgdF_{geC~ywl@_kwzCn`{nI"
27
+
28
+ expect(Polylines::Encoder.encode_points(points, 1e6)).to eq polyline
29
+ end
30
+ end
31
+ end
12
32
 
33
+ describe Polylines::Encoder, ".encode_points that are very close together" do
13
34
  it "encodes points correctly" do
14
- Polylines::Encoder.encode_points(points).should == polyline
35
+ points = [[41.3522171071184, -86.0456299662023], [41.3522171071183, -86.0454368471533]]
36
+
37
+ expect(Polylines::Encoder.encode_points(points)).to eq "krk{FdxdlO?e@"
38
+ end
39
+
40
+ it "encodes points correctly with 1e6 precision" do
41
+ points = [[41.3522171071184, -86.0456299662023], [41.3522171071183, -86.0454368471533]]
42
+
43
+ expect(Polylines::Encoder.encode_points(points, 1e6)).to eq "q`}zmAzzxbcD?aK"
44
+ end
45
+ end
46
+
47
+ describe Polylines::Encoder, ".encode_points with same results as google's api" do
48
+ it "encodes without rounding errors" do
49
+ points = [[39.13594499,-94.4243478], [39.13558757,-94.4243471]]
50
+
51
+ expect(Polylines::Encoder.encode_points(points)).to eq "svzmFdgi_QdA?"
15
52
  end
16
53
  end
@@ -1,7 +1,3 @@
1
1
  require "rubygems"
2
2
  require "bundler/setup"
3
-
4
3
  require "polylines"
5
- #
6
- # RSpec.configure do |config|
7
- # end
metadata CHANGED
@@ -1,50 +1,55 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
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
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.0
10
5
  platform: ruby
11
- authors:
6
+ authors:
12
7
  - Josh Clayton
13
8
  autorequire:
14
9
  bindir: bin
15
10
  cert_chain: []
16
-
17
- date: 2011-02-19 00:00:00 -05:00
18
- default_executable:
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
11
+ date: 2020-12-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
21
14
  name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 3.10.0
20
+ type: :development
22
21
  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
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 3.10.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
33
34
  type: :development
34
- version_requirements: *id001
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
35
41
  description:
36
- email:
42
+ email:
37
43
  - joshua.clayton@gmail.com
38
44
  executables: []
39
-
40
45
  extensions: []
41
-
42
46
  extra_rdoc_files: []
43
-
44
- files:
45
- - .gitignore
47
+ files:
48
+ - ".gitignore"
46
49
  - Gemfile
47
50
  - Gemfile.lock
51
+ - LICENSE
52
+ - README.markdown
48
53
  - Rakefile
49
54
  - lib/polylines.rb
50
55
  - lib/polylines/base.rb
@@ -55,39 +60,29 @@ files:
55
60
  - spec/polylines/decoder_spec.rb
56
61
  - spec/polylines/encoder_spec.rb
57
62
  - spec/spec_helper.rb
58
- has_rdoc: true
59
- homepage: ""
63
+ homepage: ''
60
64
  licenses: []
61
-
65
+ metadata: {}
62
66
  post_install_message:
63
67
  rdoc_options: []
64
-
65
- require_paths:
68
+ require_paths:
66
69
  - lib
67
- required_ruby_version: !ruby/object:Gem::Requirement
68
- none: false
69
- requirements:
70
+ required_ruby_version: !ruby/object:Gem::Requirement
71
+ requirements:
70
72
  - - ">="
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:
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
+ requirements:
78
77
  - - ">="
79
- - !ruby/object:Gem::Version
80
- segments:
81
- - 0
82
- version: "0"
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
83
80
  requirements: []
84
-
85
- rubyforge_project:
86
- rubygems_version: 1.3.7
81
+ rubygems_version: 3.1.4
87
82
  signing_key:
88
- specification_version: 3
83
+ specification_version: 4
89
84
  summary: Easily handle Google polylines
90
- test_files:
85
+ test_files:
91
86
  - spec/polylines/decoder_spec.rb
92
87
  - spec/polylines/encoder_spec.rb
93
88
  - spec/spec_helper.rb