forked from dereekb/geo-viewport
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
73 lines (61 loc) · 2.35 KB
/
index.js
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
var SphericalMercator = require('@mapbox/sphericalmercator');
// The SphericalMercator library only accepts a variable
// tileSize on instantiation, which it uses to pre-cache
// calculations by zoom level.
// We cache each instantiation, keyed by tile size, to avoid
// repeating this cost when working with a single tile size
// (assumed to be the most-common use case).
var smCache = {};
module.exports.viewport = viewport;
module.exports.bounds = bounds;
function fetchMerc(tileSize, allowAntiMeridian) {
tileSize = tileSize || 256;
antiMeridian = allowAntiMeridian || false;
var cacheKey = tileSize + String(antiMeridian);
if (!smCache[cacheKey]) {
smCache[cacheKey] = new SphericalMercator({ size: tileSize, antimeridian: antiMeridian });
}
return smCache[cacheKey];
}
function getAdjusted(base, ratios, allowFloat) {
var adjusted = Math.min(
base - (Math.log(ratios[0]) / Math.log(2)),
base - (Math.log(ratios[1]) / Math.log(2)));
return allowFloat ? adjusted : Math.floor(adjusted);
}
function viewport(bounds, dimensions, minzoom, maxzoom, tileSize, allowFloat, allowAntiMeridian) {
minzoom = (minzoom === undefined) ? 0 : minzoom;
maxzoom = (maxzoom === undefined) ? 20 : maxzoom;
var merc = fetchMerc(tileSize, allowAntiMeridian);
var base = maxzoom;
var bl = merc.px([bounds[0], bounds[1]], base);
var tr = merc.px([bounds[2], bounds[3]], base);
var width = tr[0] - bl[0];
var height = bl[1] - tr[1];
var centerPixelX = bl[0] + (width / 2);
var centerPixelY = tr[1] + (height / 2);
var ratios = [width / dimensions[0], height / dimensions[1]];
var adjusted = getAdjusted(base, ratios, allowFloat);
var center = merc.ll([centerPixelX, centerPixelY], base);
var zoom = Math.max(minzoom, Math.min(maxzoom, adjusted));
return { center, zoom };
}
function bounds(viewport, zoom, dimensions, tileSize) {
if (viewport.lon !== undefined) {
viewport = [
viewport.lon,
viewport.lat
];
}
var merc = fetchMerc(tileSize);
var px = merc.px(viewport, zoom);
var tl = merc.ll([
px[0] - (dimensions[0] / 2),
px[1] - (dimensions[1] / 2)
], zoom);
var br = merc.ll([
px[0] + (dimensions[0] / 2),
px[1] + (dimensions[1] / 2)
], zoom);
return [tl[0], br[1], br[0], tl[1]];
}