spherical_mercator 0.1.0 → 1.1.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 16bd516923907417c8a6900535ae5492b8e2f028
4
- data.tar.gz: 0d75745f7a75eec2b9b563af0461133d6d731831
3
+ metadata.gz: 2c25752283cbaf577010569270ec2ca240d97a62
4
+ data.tar.gz: f2aecd50cd93e790880921c098216008574f8853
5
5
  SHA512:
6
- metadata.gz: c1f7eebc8eea7dfadef4006a775e45dfa40aef3c4e763dcf0a70ddd7bef8f7cfcc38778c33239413fe2f4305a51cee228e36caeabb5b858a3ca41c3e2164b277
7
- data.tar.gz: 525366eebcf95f726443b684462c9e702b493e8ac6a26b14cb46e61f2b633383f6b43d08c7a05f36fa9e5d694c78eb8ede60887a516fc9f4dd1279c59af4e815
6
+ metadata.gz: adfdd9971e141456233f590684c200ae7577917402ca6ff31559dd8f235b3c72958ec893e166cfb67963475b2bd3dc0704bb7dfc55bcd5670719733df297ff86
7
+ data.tar.gz: 1109a332fad241f5eecbf619ce2fbdfea81d411584c63c809693eaba2d75b95382a6d1f8453794b03b274af4375c4a0e5f5aaa5b65817dde14e98caad5ff72e3
data/README.md CHANGED
@@ -46,7 +46,7 @@ of `px`
46
46
 
47
47
  ### `bbox(x, y, zoom, tms_style, srs)`
48
48
 
49
- Convert tile xyz value to bbox of the form `[w, s, e, n]`
49
+ Convert tile xyz value to bbox of the form `[west, south, east, north]`
50
50
 
51
51
  * `x` {Number} x (longitude) number.
52
52
  * `y` {Number} y (latitude) number.
@@ -54,35 +54,35 @@ Convert tile xyz value to bbox of the form `[w, s, e, n]`
54
54
  * `tms_style` {Boolean} whether to compute using tms-style. (optional, default `false`)
55
55
  * `srs` {String} projection for resulting bbox ('WGS84'|'900913'). (optional, default 'WGS84')
56
56
 
57
- Returns bbox array of values in form `[w, s, e, n]`.
57
+ Returns bbox array of values in form `[west, south, east, north]`.
58
58
 
59
59
  ### `xyz(bbox, zoom, tms_style, srs)`
60
60
 
61
61
  Convert bbox to xyz bounds
62
62
 
63
- * `bbox` {Number} bbox in the form `[w, s, e, n]`.
63
+ * `bbox` {Number} bbox in the form `[west, south, east, north]`.
64
64
  * `zoom` {Number} zoom.
65
65
  * `tms_style` {Boolean} whether to compute using tms-style. (optional, default `false`)
66
66
  * `srs` {String} projection of input bbox ('WGS84'|'900913'). (optional, default 'WGS84')
67
67
 
68
- Returns {Object} XYZ bounds containing minX, maxX, minY, maxY properties.
68
+ Returns `Hash` object (`{...}`) for XYZ bounds containing `:minX`, `:maxX`, `:minY`, `:maxY` properties.
69
69
 
70
70
  ### `convert(bbox, to)`
71
71
 
72
72
  Convert bbox from 900913 to WGS84 or vice versa
73
73
 
74
- * `bbox` {Number} bbox in the form `[w, s, e, n]`.
74
+ * `bbox` {Number} bbox in the form `[west, south, east, north]`.
75
75
  * `to` {String} projection of resulting bbox ('WGS84'|'900913'). (optional, default 'WGS84')
76
76
 
77
- Returns bbox array of values in form `[w, s, e, n]`.
77
+ Returns bbox array of values in form `[west, south, east, north]`.
78
78
 
79
79
  ### `forward(lon_lat)`
80
80
 
81
- Convert lon, lat values to mercator x, y
81
+ Convert lon, lat values (must be an array like `[lon, lat]`) to mercator x, y
82
82
 
83
83
  ### `inverse(xy)`
84
84
 
85
- Convert mercator x, y values to lon, lat
85
+ Convert mercator x, y values (`xy` must be an array like `[x, y]`) to lon, lat
86
86
 
87
87
  ## Contributing
88
88
 
@@ -47,22 +47,46 @@ class SphericalMercator
47
47
  @zc = cache[self.size]['zc']
48
48
  end
49
49
 
50
+ # function isFloat(n)
51
+ def float?(value)
52
+ number = Float(value)
53
+ number % 1 != 0
54
+ rescue ArgumentError
55
+ false
56
+ end
57
+
50
58
  # Convert lon lat to screen pixel value
51
59
  #
52
60
  # - `ll` {Array} `[lon, lat]` array of geographic coordinates.
53
61
  # - `zoom` {Number} zoom level.
54
62
  def px(lon_lat, zoom)
55
- d = @zc[zoom]
56
- # JS: Math.min(Math.max(Math.sin(D2R * ll[1]), -0.9999), 0.9999);
57
- f = [[Math.sin(D2R * lon_lat[1]), -0.9999].max, 0.9999].min
58
- x = (d + lon_lat[0] * @bc[zoom]).round
59
- y = (d + 0.5 * Math.log((1 + f) / (1 - f)) * (-@cc[zoom])).round
60
- (x > @ac[zoom]) && (x = @ac[zoom])
61
- (y > @ac[zoom]) && (y = @ac[zoom])
62
-
63
- # (x < 0) && (x = 0);
64
- # (y < 0) && (y = 0);
65
- [x, y]
63
+ if float?(zoom)
64
+ size = @size * (2**zoom)
65
+ d = size / 2
66
+ bc = (size / 360)
67
+ cc = (size / (2 * Math::PI))
68
+ ac = size
69
+ f = [[Math.sin(D2R * lon_lat[1]), -0.9999].max, 0.9999].min
70
+ x = d + lon_lat[0] * bc
71
+ y = d + 0.5 * Math.log((1 + f) / (1 - f)) * -cc
72
+ (x > ac) && (x = ac)
73
+ (y > ac) && (y = ac)
74
+ # (x < 0) && (x = 0)
75
+ # (y < 0) && (y = 0)
76
+ [x, y]
77
+ else
78
+ d = @zc[zoom]
79
+ # JS: Math.min(Math.max(Math.sin(D2R * ll[1]), -0.9999), 0.9999)
80
+ f = [[Math.sin(D2R * lon_lat[1]), -0.9999].max, 0.9999].min
81
+ x = (d + lon_lat[0] * @bc[zoom]).round
82
+ y = (d + 0.5 * Math.log((1 + f) / (1 - f)) * (-@cc[zoom])).round
83
+ (x > @ac[zoom]) && (x = @ac[zoom])
84
+ (y > @ac[zoom]) && (y = @ac[zoom])
85
+
86
+ # (x < 0) && (x = 0)
87
+ # (y < 0) && (y = 0)
88
+ [x, y]
89
+ end
66
90
  end
67
91
 
68
92
  # Convert screen pixel value to lon lat
@@ -70,10 +94,21 @@ class SphericalMercator
70
94
  # - `px` {Array} `[x, y]` array of geographic coordinates.
71
95
  # - `zoom` {Number} zoom level.
72
96
  def ll(px, zoom)
73
- g = (px[1] - @zc[zoom]) / (-@cc[zoom])
74
- lon = (px[0] - @zc[zoom]) / @bc[zoom]
75
- lat = R2D * (2 * Math.atan(Math.exp(g)) - 0.5 * Math::PI)
76
- [lon, lat]
97
+ if float?(zoom)
98
+ size = @size * (2**zoom)
99
+ bc = (size / 360)
100
+ cc = (size / (2 * Math::PI))
101
+ zc = size / 2
102
+ g = (px[1] - zc) / -cc
103
+ lon = (px[0] - zc) / bc
104
+ lat = R2D * (2 * Math.atan(Math.exp(g)) - 0.5 * Math::PI)
105
+ [lon, lat]
106
+ else
107
+ g = (px[1] - @zc[zoom]) / (-@cc[zoom])
108
+ lon = (px[0] - @zc[zoom]) / @bc[zoom]
109
+ lat = R2D * (2 * Math.atan(Math.exp(g)) - 0.5 * Math::PI)
110
+ [lon, lat]
111
+ end
77
112
  end
78
113
 
79
114
  # Convert tile xyz value to bbox of the form `[w, s, e, n]`
@@ -3,11 +3,9 @@ class SphericalMercator
3
3
  Gem::Version.new VERSION::STRING
4
4
  end
5
5
 
6
- ##
7
- # AlphaCard semantic versioning
8
6
  module VERSION
9
7
  # Major version number
10
- MAJOR = 0
8
+ MAJOR = 1
11
9
  # Minor version number
12
10
  MINOR = 1
13
11
  # Smallest version number
@@ -12,8 +12,12 @@ def rand_float
12
12
  rand(0.0...1.0)
13
13
  end
14
14
 
15
+ def round(val)
16
+ val.to_f.round(6)
17
+ end
18
+
15
19
  describe SphericalMercator do
16
- let!(:sm) {SphericalMercator.new}
20
+ let!(:sm) { SphericalMercator.new }
17
21
 
18
22
  context '#bbox' do
19
23
  it '[0,0,0] converted to proper bbox' do
@@ -27,11 +31,11 @@ describe SphericalMercator do
27
31
 
28
32
  context '#xyz' do
29
33
  it 'World extents converted to proper tile ranges' do
30
- expect(sm.xyz([-180, -85.05112877980659, 0, 0], 1, true, 'WGS84')).to eq({minX: 0, minY: 0, maxX: 0, maxY: 0})
34
+ expect(sm.xyz([-180, -85.05112877980659, 0, 0], 1, true, 'WGS84')).to eq({ minX: 0, minY: 0, maxX: 0, maxY: 0 })
31
35
  end
32
36
 
33
37
  it 'SW converted to proper tile ranges' do
34
- expect(sm.xyz([-180, -85.05112877980659, 180, 85.0511287798066], 0, true, 'WGS84')).to eq({minX: 0, minY: 0, maxX: 0, maxY: 0})
38
+ expect(sm.xyz([-180, -85.05112877980659, 180, 85.0511287798066], 0, true, 'WGS84')).to eq({ minX: 0, minY: 0, maxX: 0, maxY: 0 })
35
39
  end
36
40
 
37
41
  it 'broken' do
@@ -87,11 +91,45 @@ describe SphericalMercator do
87
91
 
88
92
  context '#extents' do
89
93
  it 'Maximum extents enforced on conversion to tile ranges' do
90
- expect(sm.xyz([-240, -90, 240, 90], 4, true, 'WGS84')).to eq({minX: 0, minY: 0, maxX: 15, maxY: 15})
94
+ expect(sm.xyz([-240, -90, 240, 90], 4, true, 'WGS84')).to eq({ minX: 0, minY: 0, maxX: 15, maxY: 15 })
91
95
  end
92
96
 
93
97
  it '' do
94
98
  expect(sm.convert([-240, -90, 240, 90], '900913')).to eq(MAX_EXTENT_MERC)
95
99
  end
96
100
  end
101
+
102
+ context '#ll' do
103
+ it 'LL with int zoom value converts' do
104
+ expect(sm.ll([200, 200], 9)).to eq([-179.45068359375, 85.00351401304403])
105
+ end
106
+
107
+ it 'LL with float zoom value converts' do
108
+ expect(sm.ll([200, 200], 8.6574)).to eq([-179.3034449476476, 84.99067388699072])
109
+ end
110
+ end
111
+
112
+ context '#pp' do
113
+ it 'PX with int zoom value converts' do
114
+ expect(sm.px([-179, 85], 9)).to eq([364, 215])
115
+ end
116
+
117
+ it 'PX with float zoom value converts' do
118
+ expect(sm.px([-179, 85], 8.6574)).to eq([287.12734093961626, 169.30444219392666])
119
+ end
120
+ end
121
+
122
+ context 'high precision float' do
123
+ let(:withInt) { sm.ll([200, 200], 4) }
124
+ let(:withFloat) { sm.ll([200, 200], 4.0000000001) }
125
+
126
+ it 'first six decimals are the same' do
127
+ expect(round(withInt[0])).to eq(round(withFloat[0]))
128
+ end
129
+
130
+
131
+ it 'first six decimals are the same' do
132
+ expect(round(withInt[1])).to eq(round(withFloat[1]))
133
+ end
134
+ end
97
135
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spherical_mercator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nikita Bulai