summaryrefslogtreecommitdiff
path: root/gui/js/maps.js
blob: c6f44d2298fa2a050c8f5196c65d91944cc4eacf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// Robinson projection calculation

// Written by Niklas Bichinger (bichinger.de). This code is Public Domain - use as you like.

// source of robinson numbers: https://simplemaps.com/static/img/flash/robinson_projection_table.jpg
var robinsonAA = [
    0.84870000,
    0.84751182,
    0.84479598,
    0.84021300,
    0.83359314,
    0.82578510,
    0.81475200,
    0.80006949,
    0.78216192,
    0.76060494,
    0.73658673,
    0.70866450,
    0.67777182,
    0.64475739,
    0.60987582,
    0.57134484,
    0.52729731,
    0.48562614,
    0.45167814
];
var robinsonBB = [
    0.00000000,
    0.08384260,
    0.16768520,
    0.25152780,
    0.33537040,
    0.41921300,
    0.50305560,
    0.58689820,
    0.67047034,
    0.75336633,
    0.83518048,
    0.91537187,
    0.99339958,
    1.06872269,
    1.14066505,
    1.20841528,
    1.27035062,
    1.31998003,
    1.35230000
];

function project(latitude, longitude, mapWidth, heightFactor, mapOffsetX, mapOffsetY) {
    if (typeof heightFactor === 'undefined') { heightFactor = 1; }
    if (typeof mapOffsetX === 'undefined') { mapOffsetX = 0; }
    if (typeof mapOffsetY === 'undefined') { mapOffsetY = 0; }

    // Robinson's latitude interpolation points are in 5-degree-steps
    var latitudeAbs = Math.abs(latitude);
    var latitudeStepFloor = Math.floor(latitudeAbs / 5);
    var latitudeStepCeil = Math.ceil(latitudeAbs / 5);
    // calc interpolation factor (>=0 to <1) between two steps
    var latitudeInterpolation = (latitudeAbs - latitudeStepFloor * 5) / 5;

    // interpolate robinson table values
    var AA = robinsonAA[latitudeStepFloor] + (robinsonAA[latitudeStepCeil] - robinsonAA[latitudeStepFloor]) * latitudeInterpolation;
    var BB = robinsonBB[latitudeStepFloor] + (robinsonBB[latitudeStepCeil] - robinsonBB[latitudeStepFloor]) * latitudeInterpolation;

    var robinsonWidth = 2 * Math.PI * robinsonAA[0];
    var widthFactor = mapWidth / robinsonWidth;
    var latitudeSign = Math.sign(latitude) || 1;
    var x = (widthFactor * AA * longitude * Math.PI) / 180 + mapOffsetX;
    var y = widthFactor * BB * latitudeSign * heightFactor + mapOffsetY;

    return {x: x, y: y};
}

function projectAbsolute(latitude, longitude, mapWidth, heightFactor, mapOffsetX, mapOffsetY) {
    if (typeof heightFactor === 'undefined') { heightFactor = 1; }

    var relative = project(latitude, longitude, mapWidth, heightFactor, mapOffsetX, mapOffsetY);
    var widthHeightRatio = Math.PI * robinsonAA[0] / robinsonBB[18];
    var x = mapWidth / 2 + relative.x;
    var y = mapWidth / widthHeightRatio * heightFactor / 2 - relative.y;

    return {x: x, y: y};
}