JSFiddle - React, Tailwind, and code Playground
by aadaam
HTML
<button id="zoomin">+</button>
<button id="zoomout">-</button>
<button id="panwest"><</button>
<button id="pannorth">^</button>
<button id="pansouth">v</button>
<button id="paneast">></button>
<br>
<canvas id="mymap" width=500 height=500></canvas>
JavaScript
(function() {
"use strict";
//Zoomlevels on the server
var MAX_ZOOMLEVEL = 20;
//Size of a single tile
var BITS_PER_TILE = 8; // 256 -> 8 bits...
//This will be our resolution
var NR_OF_BITS = MAX_ZOOMLEVEL + BITS_PER_TILE; // < 2^31 ?
var NR_OF_PIXELS_ON_LAST_ZOOMLEVEL = 1 << NR_OF_BITS; // 2^28
//-------------
/** @class Coordinate
* @abstract
*/
var Coordinate = function() {};
Coordinate.prototype = {
precision: NR_OF_BITS,
x: undefined,
y: undefined,
offset: function(coordinate) {
//TODO: it's actually tricky with multiple precisions, homework... ;-)
//Hint: What does 3 << -1 give in JS?
var coord = new Coordinate();
coord.x = this.x + coordinate.x;
coord.y = this.y + coordinate.y;
return coord;
}
};
//helper function
var beget = function(o) {
var F = function() {};
F.prototype = o;
return new F();
};
/** @class GeoCoordinate
* @implements Coordinate
* A GeoCoordinate is a Coordinate in WGS-84 space, stored in max-resolution mercator.
*/
var GeoCoordinate = function(lat, lng) {
this.lat = lat;
this.lng = lng;
this.doTheMercatorMagic(lat, lng);
};
GeoCoordinate.prototype = beget(Coordinate.prototype);
GeoCoordinate.prototype.precision = NR_OF_BITS;
GeoCoordinate.prototype.doTheMercatorMagic = function(lat, lng) {
//Flatten the Earth! Yay!
var m = Math,
min = m.min,
max = m.max,
tan = m.tan,
PI = m.PI,
exp = m.exp,
log = m.log,
round = m.round;
this.x = round((lng / 360 + 0.5) * NR_OF_PIXELS_ON_LAST_ZOOMLEVEL);
this.y = round(min(1, max(0, 0.5 - (log(tan(PI / 4 + PI / 2 * lat / 180)) / PI) / 2)) * NR_OF_PIXELS_ON_LAST_ZOOMLEVEL);
};
...