noruka-google-vector-tiles
Version:
A vector map tiler for google map
156 lines (140 loc) • 4.98 kB
JavaScript
const MERCATOR = {
fromLatLngToPoint: function (latLng) {
var siny = Math.min(Math.max(Math.sin(latLng.lat() * (Math.PI / 180)),
-.9999),
.9999);
return {
x: 128 + latLng.lng() * (256 / 360),
y: 128 + 0.5 * Math.log((1 + siny) / (1 - siny)) * -(256 / (2 * Math.PI))
};
},
fromPointToLatLng: function (point) {
return {
lat: (2 * Math.atan(Math.exp((point.y - 128) / -(256 / (2 * Math.PI)))) -
Math.PI / 2) / (Math.PI / 180),
lng: (point.x - 128) / (256 / 360)
};
},
getTileAtLatLng: function (latLng, zoom) {
var t = Math.pow(2, zoom),
s = 256 / t,
p = this.fromLatLngToPoint(latLng);
return {
x: Math.floor(p.x / s),
y: Math.floor(p.y / s),
z: zoom
};
},
getTileBounds: function (tile) {
tile = this.normalizeTile(tile);
var t = Math.pow(2, tile.z),
s = 256 / t,
sw = {
x: tile.x * s,
y: (tile.y * s) + s
},
ne = {
x: tile.x * s + s,
y: (tile.y * s)
};
return {
sw: this.fromPointToLatLng(sw),
ne: this.fromPointToLatLng(ne)
}
},
normalizeTile: function (tile) {
var t = Math.pow(2, tile.z);
tile.x = ((tile.x % t) + t) % t;
tile.y = ((tile.y % t) + t) % t;
return tile;
},
fromLatLngToPixels: function (map, latLng) {
var bounds = map.getBounds();
var ne = bounds.getNorthEast();
var sw = bounds.getSouthWest();
var topRight = map.getProjection().fromLatLngToPoint(ne);
var bottomLeft = map.getProjection().fromLatLngToPoint(sw);
var scale = Math.pow(2, map.getZoom());
var worldPoint = map.getProjection().fromLatLngToPoint(latLng);
return {
x: (worldPoint.x - bottomLeft.x) * scale,
y: (worldPoint.y - topRight.y) * scale
}
},
fromLatLngToTilePoint: function (map, evt) {
var zoom = map.getZoom();
var tile = this.getTileAtLatLng(evt.latLng, zoom);
var tileBounds = this.getTileBounds(tile);
var tileSwLatLng = new google.maps.LatLng(tileBounds.sw);
var tileNeLatLng = new google.maps.LatLng(tileBounds.ne);
var tileSwPixels = this.fromLatLngToPixels(map, tileSwLatLng);
var tileNePixels = this.fromLatLngToPixels(map, tileNeLatLng);
return {
x: evt.pixel.x - tileSwPixels.x,
y: evt.pixel.y - tileNePixels.y
}
},
// todo: sometimes it does not work properly
isPointInPolygon: function (point, polygon) {
if (polygon && polygon.length) {
for (var c = false, i = -1, l = polygon.length, j = l - 1; ++i < l; j = i) {
((polygon[i].y <= point.y && point.y < polygon[j].y) || (polygon[j].y <= point.y && point.y < polygon[i].y))
&& (point.x < (polygon[j].x - polygon[i].x) * (point.y - polygon[i].y) / (polygon[j].y - polygon[i].y) + polygon[i].x)
&& (c = !c);
}
return c;
}
},
in_circle: function (center_x, center_y, radius, x, y) {
var square_dist = Math.pow((center_x - x), 2) + Math.pow((center_y - y), 2);
return square_dist <= Math.pow(radius, 2);
},
getDistanceFromLine: function (point, line) {
var minDistance = Number.POSITIVE_INFINITY;
if (line && line.length > 1) {
for (var i = 0, l = line.length - 1; i < l; i++) {
var distance = this.projectPointOnLineSegment(point, line[i], line[i + 1]);
if (distance <= minDistance) {
minDistance = distance;
}
}
}
return minDistance;
},
projectPointOnLineSegment: function (point, r0, r1) {
var x = point.x;
var y = point.y;
var x1 = r0.x;
var y1 = r0.y;
var x2 = r1.x;
var y2 = r1.y;
var A = x - x1;
var B = y - y1;
var C = x2 - x1;
var D = y2 - y1;
var dot = A * C + B * D;
var len_sq = C * C + D * D;
var param = -1;
if (len_sq != 0) //in case of 0 length line
param = dot / len_sq;
var xx, yy;
if (param < 0) {
xx = x1;
yy = y1;
}
else if (param > 1) {
xx = x2;
yy = y2;
}
else {
xx = x1 + param * C;
yy = y1 + param * D;
}
var dx = x - xx;
var dy = y - yy;
return Math.sqrt(dx * dx + dy * dy);
}
}
export {
MERCATOR
}