commit 5ea8f75aaa007f755b697c5449d54e6850a16ddb
parent 5b8185eb22a588daa5218fcff5fb41c3e4225f3a
Author: Sergej Orlov <wladimirych@gmail.com>
Date: Thu, 7 Nov 2019 22:04:14 +0100
google: replace complex API-based layers with simple tile layers
Solution inspired by SAS planet.
Also add Google Hybrid overlay.
Diffstat:
3 files changed, 66 insertions(+), 229 deletions(-)
diff --git a/src/layers.js b/src/layers.js
@@ -74,7 +74,7 @@ export default function getLayers() {
{
title: 'Google',
isDefault: true,
- layer: new L.Layer.Google('ROADMAP',
+ layer: new L.Layer.GoogleMap(
{
code: 'G',
isOverlay: false,
@@ -86,9 +86,24 @@ export default function getLayers() {
)
},
{
+ title: 'Google Hybrid',
+ isDefault: true,
+ layer: new L.Layer.GoogleHybrid(
+ {
+ code: 'Gh',
+ isOverlay: true,
+ scaleDependent: true,
+ print: true,
+ jnx: false,
+ shortName: 'google_hybrid',
+ isOverlayTransparent: true
+ }
+ )
+ },
+ {
title: 'Google Satellite',
isDefault: true,
- layer: new L.Layer.Google('SATELLITE',
+ layer: new L.Layer.GoogleSat(
{
code: 'L',
isOverlay: false,
@@ -102,8 +117,7 @@ export default function getLayers() {
{
title: 'Google Terrain',
isDefault: true,
- layer: new L.Layer.Google('TERRAIN',
- {
+ layer: new L.Layer.GoogleTerrain({
code: 'P',
isOverlay: false,
scaleDependent: false,
@@ -996,6 +1010,7 @@ export default function getLayers() {
{
title: 'Miscellaneous',
layers: [
+ 'Google Hybrid',
'Mountains by Aleksey Tsvetkov',
'Bing imagery acquisition dates',
'geocaching.su']
@@ -1089,6 +1104,7 @@ export default function getLayers() {
'#custom-top',
// line overlays
+ 'Google Hybrid',
'Waymarked Hiking Trails',
'Waymarked Cycling Trails',
'Bing imagery acquisition dates',
diff --git a/src/lib/leaflet.layer.google/index.js b/src/lib/leaflet.layer.google/index.js
@@ -1,192 +1,51 @@
-import L from 'leaflet';
-import getGoogle from 'lib/googleMapsApi';
-import logging from 'lib/logging';
-
-L.Layer.Google = L.GridLayer.extend({
- options: {},
-
- // Possible types: SATELLITE, ROADMAP, HYBRID, TERRAIN
- initialize: function(mapType, options) {
- L.GridLayer.prototype.initialize.call(this, 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) => {
- let zoom, center;
- if (map) {
- zoom = map.getZoom();
- center = map.getCenter;
- center = new google.maps.LatLng(center.lat, center.lng);
- } else {
- zoom = 0;
- center = new google.maps.LatLng(0, 0);
- }
- this.google = google;
- this._googleMap = new google.maps.Map(this._googleMapContainer, {
- center: center,
- zoom: zoom,
- tilt: 0,
- mapTypeId: google.maps.MapTypeId[this.mapType],
- disableDefaultUI: true,
- keyboardShortcuts: false,
- draggable: false,
- disableDoubleClickZoom: true,
- scrollwheel: false,
- streetViewControl: false,
- clickableIcons: false
- }
- );
- logging.logEvent('googleMapLoad');
- google.maps.event.addListener(this._googleMap, 'tilesloaded', this._onTilesLoaded.bind(this));
- setTimeout(this._syncPosition.bind(this), 0);
- }
- );
- map.on({
- viewreset: this._syncPosition,
- 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();
- L.DomUtil.remove(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 || !this._map) {
- return;
- }
- let center = this._map.getCenter();
- let googleCenter = new this.google.maps.LatLng(center.lat, center.lng);
- setTimeout(() => {
- if (!this._googleMap) {
- return;
- }
- this._googleMap.setCenter(googleCenter);
- this._googleMap.setZoom(this._map.getZoom());
- }, 0
- );
- },
-
- _onZoom: function(e) {
- if (!this.google) {
- return;
- }
- let center = e.center;
- let googleCenter = new this.google.maps.LatLng(center.lat, center.lng);
- setTimeout(() => {
- if (!this._googleMap) {
- return;
- }
- 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();
- },
+import L from "leaflet";
+
+L.Layer.GoogleBase = L.TileLayer.extend({
+ options: {
+ subdomains: '0123'
+ },
+
+ getTileUrl: function(coords) {
+ const data = {
+ x: coords.x,
+ y: coords.y,
+ z: 17 - this._getZoomForUrl(),
+ s: this._getSubdomain(coords),
+ lang: navigator.language || ''
+ };
+ return L.Util.template(this._url, data);
+ }
+});
- _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;
- },
+L.Layer.GoogleMap = L.Layer.GoogleBase.extend({
+ initialize: function(options) {
+ L.Layer.GoogleBase.prototype.initialize.call(
+ this, 'https://mt{s}.google.com/vt/lyrs=m@169000000&hl={lang}&x={x}&y={y}&zoom={z}', options);
+ }
+});
- _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];
- }
- }
- },
+L.Layer.GoogleTerrain = L.Layer.GoogleBase.extend({
+ initialize: function(options) {
+ L.Layer.GoogleBase.prototype.initialize.call(
+ this, 'https://mt{s}.google.com/vt/lyrs=t@130,r@206000000&hl={lang}&x={x}&y={y}&zoom={z}', options);
+ }
+});
- _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);
- }
- },
+L.Layer.GoogleHybrid = L.Layer.GoogleBase.extend({
+ initialize: function(options) {
+ L.Layer.GoogleBase.prototype.initialize.call(
+ this, 'https://mt{s}.google.com/vt/lyrs=h@169000000&hl={lang}&x={x}&y={y}&zoom={z}', options);
+ }
+});
- _tileOnError: function(done, tile, e) {
- done(e, tile);
- },
+L.Layer.GoogleSat = L.TileLayer.extend({
+ options: {
+ subdomains: '0123'
+ },
- 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;
- }
+ initialize: function(options) {
+ L.TileLayer.prototype.initialize.call(
+ this, 'https://mt{s}.google.com/vt/lyrs=s&x={x}&y={y}&z={z}', options)
}
-);
+});
diff --git a/src/lib/leaflet.layer.rasterize/Google.js b/src/lib/leaflet.layer.rasterize/Google.js
@@ -1,47 +1,9 @@
import L from 'leaflet';
import 'lib/leaflet.layer.google';
-import {TileLayerGrabMixin} from './TileLayer';
-
-
-const GooglePrint = L.Layer.Google.extend({
- includes: TileLayerGrabMixin,
-
- _rasterizeNeedsFullSizeMap: true,
-
- _dummyTile: L.DomUtil.create('div'),
-
- onAdd: function(map) {
- this._waitTilesReadyToGrab = new Promise((resolve) => {
- this._tilesReadyToGrab = resolve;
- });
- L.Layer.Google.prototype.onAdd.call(this, map);
- },
-
- waitTilesReadyToGrab: function() {
- return this._waitTilesReadyToGrab;
- },
-
- createTile: function() {
- return this._dummyTile;
- },
-
- _fullfillPendingTiles: function() {
- if (!Object.keys(this._readyTiles).length) {
- return;
- }
- this._tilesReadyToGrab();
- },
-
- getTileUrl: function(coords) {
- return this._readyTiles[this._tileCoordsToKey(coords)] || null;
- }
-});
-
-
-L.Layer.Google.include({
+L.Layer.GoogleBase.include({
cloneForPrint: function(options) {
- return new GooglePrint(this.mapType, L.Util.extend({}, this.options, options));
+ return new L.Layer.GoogleBase(this._url, L.Util.extend({}, this.options, options));
},
});