commit 55ddab38179d53526ef478127d4d5e8bc5e1c396
parent 943179b0bba21436c8b32914902aaf20ee18b5bd
Author: Sergej Orlov <wladimirych@gmail.com>
Date: Thu, 10 Nov 2016 22:23:50 +0300
added google layers
Diffstat:
4 files changed, 209 insertions(+), 5 deletions(-)
diff --git a/src/config.js b/src/config.js
@@ -1,3 +1,4 @@
export default {
- email: 'nakarte@nakarte.tk'
+ email: 'nakarte@nakarte.tk',
+ googleApiUrl: 'https://maps.googleapis.com/maps/api/js?v=3&sensor=false'
}
diff --git a/src/layers.js b/src/layers.js
@@ -1,5 +1,6 @@
import L from "leaflet";
-import './lib/layer.yandex/yandex';
+import 'lib/layer.yandex/yandex';
+import 'lib/layer.google/google';
function getBaseMaps() {
// var bingKey = 'AhZy06XFi8uAADPQvWNyVseFx4NHYAOH-7OTMKDPctGtYo86kMfx2T0zUrF5AAaM';
@@ -13,9 +14,8 @@ function getBaseMaps() {
),
'Yandex': new L.Layer.Yandex('map', {scaleDependent: true, code: 'Y', print: true, jnx: true}),
'Yandex Sat': new L.Layer.Yandex('sat', {scaleDependent: false, code: 'S', print: true, jnx: true}),
- // 'Google': new L.Google('ROADMAP', {code: 'G', scaleDependent: true, print: true, jnx: true}),
- // 'Google Sat': new L.Google('SATELLITE', {code: 'L', print: true, jnx: true}),
- // 'Google Sat Hybrid': new L.Google('HYBRID', {code: 'H', scaleDependent: true, print: true, jnx: false}),
+ 'Google': new L.Layer.Google('ROADMAP', {code: 'G', scaleDependent: true, print: true, jnx: true}),
+ 'Google Sat': new L.Layer.Google('SATELLITE', {code: 'L', print: true, jnx: true}),
// 'Bing Sat': L.bingLayer(bingKey, {code: 'I', print: true, jnx: true}),
'marshruty.ru': L.tileLayer('http://maps.marshruty.ru/ml.ashx?x={x}&y={y}&z={z}&i=1&al=1',
{code: 'M', maxNativeZoom: 18, noCors: true, scaleDependent: true, print: true, jnx: true}
diff --git a/src/lib/googleMapsApi/googleMapsApi.js b/src/lib/googleMapsApi/googleMapsApi.js
@@ -0,0 +1,29 @@
+import loadScript from 'load-script';
+import config from 'config';
+
+let _google = null;
+let _pending = null;
+
+function getGoogle() {
+ if (_google) {
+ return Promise.resolve(_google);
+ }
+ if (!_pending) {
+ _pending = new Promise((resolve, reject) => {
+ loadScript(config.googleApiUrl, (error) => {
+ if (error) {
+ reject(error)
+ }
+ _google = window.google;
+ resolve(_google);
+ }
+ );
+
+ }
+ );
+ }
+ return _pending;
+}
+
+
+export default getGoogle;
+\ No newline at end of file
diff --git a/src/lib/layer.google/google.js b/src/lib/layer.google/google.js
@@ -0,0 +1,173 @@
+import L from 'leaflet';
+import getGoogle from 'lib/googleMapsApi/googleMapsApi';
+
+L.Layer.Google = L.GridLayer.extend({
+ options: {},
+
+ // Possible types: SATELLITE, ROADMAP, HYBRID, TERRAIN
+ initialize: function(mapType, options) {
+ L.GridLayer.prototype.initialize.call(this, options);
+ L.Layer.prototype.constructor(options);
+ this.mapType = mapType;
+ },
+
+ onAdd: function(map) {
+ this._clearTiles();
+ L.GridLayer.prototype.onAdd.call(this, map);
+ this._googleMapContainer = L.DomUtil.create('div', '', map.getContainer());
+ this._googleMapContainer.style.width = '100%';
+ this._googleMapContainer.style.height = '100%';
+ // this._googleMapContainer.style.opacity = 0;
+ this._googleMapContainer.style.visibility = 'hidden';
+ this._googleMapContainer.style.pointerEvents = 'none';
+ getGoogle().then((google) => {
+ this.google = google;
+ this._googleMap = new google.maps.Map(this._googleMapContainer, {
+ center: new google.maps.LatLng(0, 0),
+ zoom: 0,
+ tilt: 0,
+ mapTypeId: google.maps.MapTypeId[this.mapType],
+ disableDefaultUI: true,
+ keyboardShortcuts: false,
+ draggable: false,
+ disableDoubleClickZoom: true,
+ scrollwheel: false,
+ streetViewControl: false,
+ clickableIcons: false
+ }
+ );
+ google.maps.event.addListener(this._googleMap, 'tilesloaded', this._onTilesLoaded.bind(this));
+ setTimeout(this._syncPosition.bind(this), 0);
+ }
+ );
+ map.on({
+ viewreset: this._clearTiles,
+ resize: this._onResize,
+ move: this._syncPosition,
+ zoomanim: this._onZoom
+ }, this
+ );
+ },
+
+ onRemove: function(map) {
+ if (this.google) {
+ this.google.maps.event.clearInstanceListeners(this._googleMap);
+ }
+ this._googleMap = null;
+ this._clearTiles();
+ map.getContainer().removeChild(this._googleMapContainer);
+ map.off({
+ viewreset: this._clearTiles,
+ resize: this._onResize,
+ move: this._syncPosition,
+ zoomanim: this._onZoom
+ }, this
+ );
+ L.GridLayer.prototype.onRemove.call(this, map);
+ },
+
+ _clearTiles: function() {
+ this._pendingTiles = {};
+ this._readyTiles = {};
+ },
+
+ _onResize: function() {
+ if (!this.google) {
+ return;
+ }
+ this.google.maps.event.trigger(this._googleMap, 'resize');
+ },
+
+ _syncPosition: function() {
+ if (!this.google) {
+ return;
+ }
+ let center = this._map.getCenter();
+ setTimeout(() => {
+ let googleCenter = new this.google.maps.LatLng(center.lat, center.lng);
+ this._googleMap.setCenter(googleCenter);
+ this._googleMap.setZoom(this._map.getZoom());
+ }, 0
+ );
+ },
+
+ _onZoom: function(e) {
+ let center = e.center;
+ setTimeout(() => {
+ let googleCenter = new window.google.maps.LatLng(center.lat, center.lng);
+ this._googleMap.setCenter(googleCenter);
+ this._googleMap.setZoom(Math.round(e.zoom));
+ }, 0
+ );
+ },
+
+ _roadRegexp: /!1i(\d+)!2i(\d+)!3i(\d+)!/,
+ _satRegexp: /x=(\d+)&y=(\d+)&z=(\d+)/,
+
+ _onTilesLoaded: function() {
+ this._readyTiles = this._collectMapImageElements();
+ this._fullfillPendingTiles();
+ },
+
+ _collectMapImageElements: function() {
+ const images = this._googleMapContainer.getElementsByTagName('img');
+ const tiles = {};
+ for (let image of images) {
+ let url = image.src;
+ let match, coords;
+ match = url.match(this._roadRegexp);
+
+ if (match) {
+ coords = {z: match[1], x: match[2], y: match[3]}
+ } else {
+ match = url.match(this._satRegexp);
+ if (match) {
+ coords = {x: match[1], y: match[2], z: match[3]}
+ }
+ }
+ if (coords) {
+ tiles[this._tileCoordsToKey(coords)] = url;
+ }
+ }
+ return tiles;
+ },
+
+ _fullfillPendingTiles: function() {
+ for (let key of Object.keys(this._readyTiles)) {
+ if (key in this._pendingTiles) {
+ for (let [img, cb] of this._pendingTiles[key]) {
+ L.DomEvent.on(img, 'load', L.bind(this._tileOnLoad, this, cb, img));
+ L.DomEvent.on(img, 'error', L.bind(this._tileOnError, this, cb, img));
+ img.alt = '';
+ img.src = this._readyTiles[key];
+ }
+ delete this._pendingTiles[key];
+ }
+ }
+ },
+
+ _tileOnLoad: function(done, tile) {
+ // For https://github.com/Leaflet/Leaflet/issues/3332
+ if (L.Browser.ielt9) {
+ setTimeout(L.bind(done, this, null, tile), 0);
+ } else {
+ done(null, tile);
+ }
+ },
+
+ _tileOnError: function(done, tile, e) {
+ done(e, tile);
+ },
+
+ createTile: function(coords, done) {
+ const tile = L.DomUtil.create('img');
+ const key = this._tileCoordsToKey(coords);
+ if (!(key in this._pendingTiles)) {
+ this._pendingTiles[key] = [];
+ }
+ this._pendingTiles[key].push([tile, done]);
+ setTimeout(this._fullfillPendingTiles.bind(this), 0);
+ return tile;
+ }
+ }
+);