google-map-react
Version:
isomorphic google map react component, allows render react components on the google map
263 lines (209 loc) • 6.68 kB
JavaScript
'use strict';
exports.__esModule = true;
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
exports.convertNeSwToNwSe = convertNeSwToNwSe;
exports.convertNwSeToNeSw = convertNwSeToNeSw;
exports.fitBounds = fitBounds;
exports.meters2ScreenPixels = meters2ScreenPixels;
exports.tile2LatLng = tile2LatLng;
exports.latLng2Tile = latLng2Tile;
exports.getTilesIds = getTilesIds;
var _log = require('./math/log2');
var _log2 = _interopRequireDefault(_log);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var GOOGLE_TILE_SIZE = 256;
function latLng2World(_ref) {
var lat = _ref.lat,
lng = _ref.lng;
var sin = Math.sin(lat * Math.PI / 180);
var x = lng / 360 + 0.5;
var y = 0.5 - 0.25 * Math.log((1 + sin) / (1 - sin)) / Math.PI;
y = y < 0 // eslint-disable-line
? 0 : y > 1 ? 1 : y;
return { x: x, y: y };
}
function world2LatLng(_ref2) {
var x = _ref2.x,
y = _ref2.y;
var n = Math.PI - 2 * Math.PI * y;
// TODO test that this is faster
// 360 * Math.atan(Math.exp((180 - y * 360) * Math.PI / 180)) / Math.PI - 90;
return {
lat: 180 / Math.PI * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n))),
lng: x * 360 - 180
};
}
// Thank you wiki https://en.wikipedia.org/wiki/Geographic_coordinate_system
function latLng2MetersPerDegree(_ref3) {
var lat = _ref3.lat;
var phi = lat * Math.PI / 180;
var metersPerLatDegree = 111132.92 - 559.82 * Math.cos(2 * phi) + 1.175 * Math.cos(4 * phi) - 0.0023 * Math.cos(6 * phi);
var metersPerLngDegree = 111412.84 * Math.cos(phi) - 93.5 * Math.cos(3 * phi) + 0.118 * Math.cos(5 * phi);
return { metersPerLatDegree: metersPerLatDegree, metersPerLngDegree: metersPerLngDegree };
}
function meters2LatLngBounds(meters, _ref4) {
var lat = _ref4.lat,
lng = _ref4.lng;
var _latLng2MetersPerDegr = latLng2MetersPerDegree({
lat: lat
}),
metersPerLatDegree = _latLng2MetersPerDegr.metersPerLatDegree,
metersPerLngDegree = _latLng2MetersPerDegr.metersPerLngDegree;
var latDelta = 0.5 * meters / metersPerLatDegree;
var lngDelta = 0.5 * meters / metersPerLngDegree;
return {
nw: {
lat: lat - latDelta,
lng: lng - lngDelta
},
se: {
lat: lat + latDelta,
lng: lng + lngDelta
}
};
}
function meters2WorldSize(meters, _ref5) {
var lat = _ref5.lat,
lng = _ref5.lng;
var _meters2LatLngBounds = meters2LatLngBounds(meters, { lat: lat, lng: lng }),
nw = _meters2LatLngBounds.nw,
se = _meters2LatLngBounds.se;
var nwWorld = latLng2World(nw);
var seWorld = latLng2World(se);
var w = Math.abs(seWorld.x - nwWorld.x);
var h = Math.abs(seWorld.y - nwWorld.y);
return { w: w, h: h };
}
function fitNwSe(nw, se, width, height) {
var EPS = 0.000000001;
var nwWorld = latLng2World(nw);
var seWorld = latLng2World(se);
var dx = nwWorld.x < seWorld.x ? seWorld.x - nwWorld.x : 1 - nwWorld.x + seWorld.x;
var dy = seWorld.y - nwWorld.y;
if (dx <= 0 && dy <= 0) {
return null;
}
var zoomX = (0, _log2.default)(width / GOOGLE_TILE_SIZE / dx);
var zoomY = (0, _log2.default)(height / GOOGLE_TILE_SIZE / dy);
var zoom = Math.floor(EPS + Math.min(zoomX, zoomY));
// TODO find center just unproject middle world point
var middle = {
x: nwWorld.x < seWorld.x // eslint-disable-line
? 0.5 * (nwWorld.x + seWorld.x) : nwWorld.x + seWorld.x - 1 > 0 ? 0.5 * (nwWorld.x + seWorld.x - 1) : 0.5 * (1 + nwWorld.x + seWorld.x),
y: 0.5 * (nwWorld.y + seWorld.y)
};
var scale = Math.pow(2, zoom);
var halfW = width / scale / GOOGLE_TILE_SIZE / 2;
var halfH = height / scale / GOOGLE_TILE_SIZE / 2;
var newNW = world2LatLng({
x: middle.x - halfW,
y: middle.y - halfH
});
var newSE = world2LatLng({
x: middle.x + halfW,
y: middle.y + halfH
});
return {
center: world2LatLng(middle),
zoom: zoom,
newBounds: {
nw: newNW,
se: newSE
}
};
}
function convertNeSwToNwSe(_ref6) {
var ne = _ref6.ne,
sw = _ref6.sw;
return {
nw: {
lat: ne.lat,
lng: sw.lng
},
se: {
lat: sw.lat,
lng: ne.lng
}
};
}
function convertNwSeToNeSw(_ref7) {
var nw = _ref7.nw,
se = _ref7.se;
return {
ne: {
lat: nw.lat,
lng: se.lng
},
sw: {
lat: se.lat,
lng: nw.lng
}
};
}
function fitBounds(_ref8, _ref9) {
var nw = _ref8.nw,
se = _ref8.se,
ne = _ref8.ne,
sw = _ref8.sw;
var width = _ref9.width,
height = _ref9.height;
var fittedData = void 0;
if (nw && se) {
fittedData = fitNwSe(nw, se, width, height);
} else {
var calculatedNwSe = convertNeSwToNwSe({ ne: ne, sw: sw });
fittedData = fitNwSe(calculatedNwSe.nw, calculatedNwSe.se, width, height);
}
return _extends({}, fittedData, {
newBounds: _extends({}, fittedData.newBounds, convertNwSeToNeSw(fittedData.newBounds))
});
}
// -------------------------------------------------------------------
// Helpers to calc some markers size
function meters2ScreenPixels(meters, _ref10, zoom) {
var lat = _ref10.lat,
lng = _ref10.lng;
var _meters2WorldSize = meters2WorldSize(meters, { lat: lat, lng: lng }),
w = _meters2WorldSize.w,
h = _meters2WorldSize.h;
var scale = Math.pow(2, zoom);
var wScreen = w * scale * GOOGLE_TILE_SIZE;
var hScreen = h * scale * GOOGLE_TILE_SIZE;
return {
w: wScreen,
h: hScreen
};
}
// --------------------------------------------------
// Helper functions for working with svg tiles, (examples coming soon)
function tile2LatLng(_ref11, zoom) {
var x = _ref11.x,
y = _ref11.y;
var n = Math.PI - 2 * Math.PI * y / Math.pow(2, zoom);
return {
lat: 180 / Math.PI * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n))),
lng: x / Math.pow(2, zoom) * 360 - 180
};
}
function latLng2Tile(_ref12, zoom) {
var lat = _ref12.lat,
lng = _ref12.lng;
var worldCoords = latLng2World({ lat: lat, lng: lng });
var scale = Math.pow(2, zoom);
return {
x: Math.floor(worldCoords.x * scale),
y: Math.floor(worldCoords.y * scale)
};
}
function getTilesIds(_ref13, zoom) {
var from = _ref13.from,
to = _ref13.to;
var scale = Math.pow(2, zoom);
var ids = [];
for (var x = from.x; x !== (to.x + 1) % scale; x = (x + 1) % scale) {
for (var y = from.y; y !== (to.y + 1) % scale; y = (y + 1) % scale) {
ids.push([zoom, x, y]);
}
}
return ids;
}