Added the maps-module to the iwmlib.
Migrated a ot of the content from the tuesch to the iwmlib. This is before the decoupeling of the layers.
This commit is contained in:
@@ -0,0 +1,148 @@
|
||||
import Projection from './projection'
|
||||
|
||||
/* */
|
||||
|
||||
export default class Robinson extends Projection {
|
||||
constructor(lng = 0) {
|
||||
super()
|
||||
|
||||
this.lng0 = lng
|
||||
this.lengthOfParallel = [
|
||||
1.0,
|
||||
0.9986,
|
||||
0.9954,
|
||||
0.99,
|
||||
0.9822,
|
||||
0.973,
|
||||
0.96,
|
||||
0.9427,
|
||||
0.9216,
|
||||
0.8962,
|
||||
0.8679,
|
||||
0.835,
|
||||
0.7986,
|
||||
0.7597,
|
||||
0.7186,
|
||||
0.6732,
|
||||
0.6213,
|
||||
0.5722,
|
||||
0.5322
|
||||
]
|
||||
this.distancesFromEquator = [
|
||||
0.0,
|
||||
0.062,
|
||||
0.124,
|
||||
0.186,
|
||||
0.248,
|
||||
0.31,
|
||||
0.372,
|
||||
0.434,
|
||||
0.4958,
|
||||
0.5571,
|
||||
0.6176,
|
||||
0.6769,
|
||||
0.7346,
|
||||
0.7903,
|
||||
0.8435,
|
||||
0.8936,
|
||||
0.9394,
|
||||
0.9761,
|
||||
1.0
|
||||
]
|
||||
}
|
||||
forward(coords) {
|
||||
let { x: lat, y: lng } = coords
|
||||
|
||||
lng = this._adjustLng(lng)
|
||||
|
||||
// Get the required indices, the remainder in between low and hight as ratio
|
||||
// and the sign of the found indices, as the tables are only in positive direction.
|
||||
let { low, high, ratio, sign } = this._getInterpolationValues(lat, 90)
|
||||
|
||||
// Values that lie inbetween two indices are interpolated.
|
||||
let y = this._interpolate(this.distancesFromEquator[low], this.distancesFromEquator[high], ratio)
|
||||
|
||||
// Reapply the sign to the vertical position.
|
||||
y *= sign
|
||||
|
||||
// The center of the projection is in the center of the map. Therefore we shift the
|
||||
// center to the top left corner.
|
||||
y = 1 - (y + 1) / 2
|
||||
|
||||
// The lengthOfParallel table provides us with the corresponding scaling factor
|
||||
// for a specific latitude. Inbetween values are interpolated as before.
|
||||
let proportionalLength = this._interpolate(this.lengthOfParallel[low], this.lengthOfParallel[high], ratio)
|
||||
|
||||
//To normalize the value to a range from -1 to 1.
|
||||
let x = (proportionalLength * lng) / 180
|
||||
|
||||
x = (x + 1) / 2
|
||||
|
||||
return { x, y }
|
||||
}
|
||||
|
||||
backward(position) {
|
||||
let { x, y } = position
|
||||
|
||||
y = 1 - 2 * y
|
||||
let sign = Math.sign(y)
|
||||
y = Math.abs(y)
|
||||
|
||||
let low = 0
|
||||
let high = 0
|
||||
for (let i = 0; i < this.distancesFromEquator.length - 1 && y > this.distancesFromEquator[i]; i++) {
|
||||
low = i
|
||||
high = i + 1
|
||||
}
|
||||
|
||||
let lowDist = this.distancesFromEquator[low]
|
||||
let highDist = this.distancesFromEquator[high]
|
||||
|
||||
let ratio = highDist - lowDist == 0 ? 0 : (y - lowDist) / (highDist - lowDist)
|
||||
|
||||
let lat = low * 5 + ratio * 5
|
||||
|
||||
let parallelLengthMin = this.lengthOfParallel[low]
|
||||
let parallelLengthMax = this.lengthOfParallel[high]
|
||||
|
||||
let completeLength = parallelLengthMin + (parallelLengthMax - parallelLengthMin) * ratio
|
||||
|
||||
x = x * 2 - 1
|
||||
let normalizedLength = x / completeLength
|
||||
|
||||
let lng = normalizedLength * 180
|
||||
|
||||
return { x: lat * sign, y: this._adjustLng(lng, true) }
|
||||
}
|
||||
|
||||
_adjustLng(lng, inv = false) {
|
||||
let moved = inv ? lng + this.lng0 : lng - this.lng0
|
||||
if (moved < -180) moved += 360
|
||||
if (moved > 180) moved -= 360
|
||||
|
||||
return moved
|
||||
}
|
||||
|
||||
_interpolate(a, b, ratio) {
|
||||
return a * (1 - ratio) + b * ratio
|
||||
}
|
||||
_getInterpolationValues(value, max) {
|
||||
let sign = Math.sign(value)
|
||||
value = Math.min(Math.abs(value), max)
|
||||
// Note that min and max can be the same. Which is true
|
||||
// when lat is dividable by 5. This also covers the edge cases 0 and 90.
|
||||
let minIndex = Math.floor(value / 5)
|
||||
let maxIndex = Math.ceil(value / 5)
|
||||
let ratio = (value % 5) / 5
|
||||
// console.log({ value, minIndex, maxIndex, ratio })
|
||||
// console.log(this.lengthOfParallel.length)
|
||||
return { low: minIndex, high: maxIndex, ratio, sign }
|
||||
}
|
||||
|
||||
toString() {
|
||||
return
|
||||
}
|
||||
get name() {
|
||||
return 'Robinson Projection'
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user