nakarte

Source code of https://map.sikmir.ru (fork)
git clone git://git.sikmir.ru/nakarte
Log | Files | Refs | LICENSE

commit 8aaa0bc72a76b43f23d9c22d0e876d2e9dea8e10
parent f0b7ab2c928dcd3ad28909dcf926697104874ff6
Author: Sergej Orlov <wladimirych@gmail.com>
Date:   Wed,  6 Jun 2018 10:57:58 +0300

Merge pull request #79 from binarycode/pdf-naming

name exported PDF according to layer, zoom and page size
Diffstat:
Msrc/layers.js | 688++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------
Msrc/lib/leaflet.control.layers.configure/index.js | 14+++++++-------
Msrc/lib/leaflet.control.printPages/control.js | 97+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
Msrc/lib/leaflet.control.printPages/map-render.js | 12++++++++----
Msrc/lib/leaflet.layer.rasterize/WestraPasses.js | 2+-
Msrc/lib/leaflet.layer.westraPasses/index.js | 2+-
6 files changed, 666 insertions(+), 149 deletions(-)

diff --git a/src/layers.js b/src/layers.js @@ -21,218 +21,413 @@ export default function getLayers() { title: 'OpenStreetMap', description: 'OSM default style', order: 100, - isOverlay: false, isDefault: true, layer: L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', - {code: 'O', scaleDependent: true, print: true, jnx: true} + { + code: 'O', + isOverlay: false, + scaleDependent: true, + print: true, + jnx: true, + shortName: 'osm' + } ) }, { title: 'ESRI Sat', order: 200, - isOverlay: false, isDefault: true, layer: L.tileLayer( 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', - {code: 'E', scaleDependent: false, maxNativeZoom: 18, print: true, jnx: true} + { + code: 'E', + isOverlay: false, + scaleDependent: false, + maxNativeZoom: 18, + print: true, + jnx: true, + shortName: 'esri' + } ) }, { title: 'Yandex map', order: 300, - isOverlay: false, isDefault: true, - layer: new L.Layer.Yandex('map', {scaleDependent: true, code: 'Y', print: true, jnx: true}) + layer: new L.Layer.Yandex('map', + { + scaleDependent: true, + code: 'Y', + isOverlay: false, + print: true, + jnx: true, + shortName: 'yandex' + } + ) }, { title: 'Yandex Satellite', order: 400, - isOverlay: false, isDefault: true, - layer: new L.Layer.Yandex('sat', {scaleDependent: false, code: 'S', print: true, jnx: true}) + layer: new L.Layer.Yandex('sat', + { + scaleDependent: false, + code: 'S', + isOverlay: false, + print: true, + jnx: true, + shortName: 'yandex_sat' + } + ) }, { title: 'Google', order: 500, - isOverlay: false, isDefault: true, - layer: new L.Layer.Google('ROADMAP', {code: 'G', scaleDependent: true, print: true, jnx: true}) + layer: new L.Layer.Google('ROADMAP', + { + code: 'G', + isOverlay: false, + scaleDependent: true, + print: true, + jnx: true, + shortName: 'google' + } + ) }, { title: 'Google Satellite', order: 600, - isOverlay: false, isDefault: true, - layer: new L.Layer.Google('SATELLITE', {code: 'L', scaleDependent: false, print: true, jnx: true}) + layer: new L.Layer.Google('SATELLITE', + { + code: 'L', + isOverlay: false, + scaleDependent: false, + print: true, + jnx: true, + shortName: 'google_sat' + } + ) }, { title: 'Google Terrain', order: 650, - isOverlay: false, isDefault: true, - layer: new L.Layer.Google('TERRAIN', {code: 'P', scaleDependent: false, print: true, jnx: true}) + layer: new L.Layer.Google('TERRAIN', + { + code: 'P', + isOverlay: false, + scaleDependent: false, + print: true, + jnx: true, + shortName: 'google_terrain' + } + ) }, { title: 'Bing Sat', order: 700, - isOverlay: false, isDefault: true, - layer: new BingLayer(config.bingKey, {code: 'I', scaleDependent: false, print: true, jnx: true}) + layer: new BingLayer(config.bingKey, + { + code: 'I', + isOverlay: false, + scaleDependent: false, + print: true, + jnx: true, + shortName: 'bing_sat' + } + ) }, { title: 'marshruty.ru', order: 800, - isOverlay: false, isDefault: true, layer: L.tileLayer('https://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} + { + code: 'M', + isOverlay: false, + maxNativeZoom: 18, + noCors: true, + scaleDependent: true, + print: true, + jnx: true, + shortName: 'marshruty' + } ) }, { title: 'Topomapper 1km', order: 900, - isOverlay: false, isDefault: true, layer: L.tileLayer( 'http://144.76.234.108/cgi-bin/tapp/tilecache.py/1.0.0/topomapper_v2/{z}/{x}/{y}.jpg', - {code: 'T', scaleDependent: false, maxNativeZoom: 13, noCors: true, print: true, jnx: true} + { + code: 'T', + isOverlay: false, + scaleDependent: false, + maxNativeZoom: 13, + noCors: true, + print: true, + jnx: true, + shortName: 'topomapper_1k' + } ) }, { title: 'Topo 10km', order: 10100, - isOverlay: true, isDefault: true, layer: L.tileLayer("https://tiles.nakarte.tk/topo001m/{z}/{x}/{y}", - {code: 'D', tms: true, scaleDependent: false, maxNativeZoom: 9, print: true, jnx: true} + { + code: 'D', + isOverlay: true, + isOverlayTransparent: false, + tms: true, + scaleDependent: false, + maxNativeZoom: 9, + print: true, + jnx: true, + shortName: 'topo_10k' + } ) }, { title: 'GGC 2 km', order: 10200, - isOverlay: true, isDefault: true, layer: L.tileLayer("https://tiles.nakarte.tk/ggc2000/{z}/{x}/{y}", - {code: 'N', tms: true, scaleDependent: false, maxNativeZoom: 12, print: true, jnx: true} + { + code: 'N', + isOverlay: true, + isOverlayTransparent: false, + tms: true, + scaleDependent: false, + maxNativeZoom: 12, + print: true, + jnx: true, + shortName: 'ggc_2k' + } ) }, { title: 'ArbaletMO', order: 10300, - isOverlay: true, isDefault: true, layer: L.tileLayer("https://tiles.nakarte.tk/ArbaletMO/{z}/{x}/{y}", - {code: 'A', tms: true, scaleDependent: false, maxNativeZoom: 13, print: true, jnx: true} + { + code: 'A', + isOverlay: true, + isOverlayTransparent: false, + tms: true, + scaleDependent: false, + maxNativeZoom: 13, + print: true, + jnx: true, + shortName: 'arbalet' + } ) }, { title: 'Slazav mountains', order: 10400, - isOverlay: true, isDefault: true, layer: L.tileLayer("https://tiles.nakarte.tk/map_hr/{z}/{x}/{y}", - {code: 'Q', tms: true, scaleDependent: false, maxNativeZoom: 13, print: true, jnx: true} + { + code: 'Q', + isOverlay: true, + isOverlayTransparent: false, + tms: true, + scaleDependent: false, + maxNativeZoom: 13, + print: true, + jnx: true, + shortName: 'slazav_mountains' + } ) }, { title: 'GGC 1km', order: 10500, - isOverlay: true, isDefault: true, layer: L.tileLayer("https://tiles.nakarte.tk/ggc1000/{z}/{x}/{y}", - {code: 'J', tms: true, scaleDependent: false, maxNativeZoom: 13, print: true, jnx: true} + { + code: 'J', + isOverlay: true, + isOverlayTransparent: false, + tms: true, + scaleDependent: false, + maxNativeZoom: 13, + print: true, + jnx: true, + shortName: 'ggc_1k' + } ) }, { title: 'Topo 1km', order: 10600, - isOverlay: true, isDefault: true, layer: L.tileLayer("https://tiles.nakarte.tk/topo1000/{z}/{x}/{y}", - {code: 'C', tms: true, scaleDependent: false, maxNativeZoom: 13, print: true, jnx: true} + { + code: 'C', + isOverlay: true, + isOverlayTransparent: false, + tms: true, + scaleDependent: false, + maxNativeZoom: 13, + print: true, + jnx: true, + shortName: 'topo_1k' + } ) }, { title: 'GGC 500m', order: 10700, - isOverlay: true, isDefault: true, layer: L.tileLayer("https://tiles.nakarte.tk/ggc500/{z}/{x}/{y}", - {code: 'F', tms: true, scaleDependent: false, maxNativeZoom: 14, print: true, jnx: true} + { + code: 'F', + isOverlay: true, + isOverlayTransparent: false, + tms: true, + scaleDependent: false, + maxNativeZoom: 14, + print: true, + jnx: true, + shortName: 'ggc_500' + } ) }, { title: 'Topo 500m', order: 10800, - isOverlay: true, isDefault: true, layer: L.tileLayer("https://tiles.nakarte.tk/topo500/{z}/{x}/{y}", - {code: 'B', tms: true, scaleDependent: false, maxNativeZoom: 14, print: true, jnx: true} + { + code: 'B', + isOverlay: true, + isOverlayTransparent: false, + tms: true, + scaleDependent: false, + maxNativeZoom: 14, + print: true, + jnx: true, + shortName: 'topo_500' + } ) }, { title: 'GGC 250m', order: 10900, - isOverlay: true, isDefault: true, layer: L.tileLayer("https://tiles.nakarte.tk/ggc250/{z}/{x}/{y}", - {code: 'K', tms: true, scaleDependent: false, maxNativeZoom: 15, print: true, jnx: true} + { + code: 'K', + isOverlay: true, + isOverlayTransparent: false, + tms: true, + scaleDependent: false, + maxNativeZoom: 15, + print: true, + jnx: true, + shortName: 'ggc_250' + } ) }, { title: 'Slazav map', order: 11000, - isOverlay: true, isDefault: true, layer: L.tileLayer("https://tiles.nakarte.tk/map_podm/{z}/{x}/{y}", - {code: 'Z', tms: true, scaleDependent: false, maxNativeZoom: 14, print: true, jnx: true} + { + code: 'Z', + isOverlay: true, + isOverlayTransparent: false, + tms: true, + scaleDependent: false, + maxNativeZoom: 14, + print: true, + jnx: true, + shortName: 'slazav' + } ) }, { title: 'Races', order: 11050, - isOverlay: true, isDefault: true, layer: L.tileLayer("https://tiles.nakarte.tk/adraces/{z}/{x}/{y}", - {code: 'U', tms: true, scaleDependent: false, maxNativeZoom: 15, print: true, jnx: true} + { + code: 'U', + isOverlay: true, + isOverlayTransparent: false, + tms: true, + scaleDependent: false, + maxNativeZoom: 15, + print: true, + jnx: true, + shortName: 'races' + } ) }, { title: 'O-sport', order: 11100, - isOverlay: true, isDefault: true, layer: L.tileLayer("https://tiles.nakarte.tk/osport/{z}/{x}/{y}", - {code: 'R', tms: true, scaleDependent: false, maxNativeZoom: 17, print: true, jnx: true} + { + code: 'R', + isOverlay: true, + isOverlayTransparent: false, + tms: true, + scaleDependent: false, + maxNativeZoom: 17, + print: true, + jnx: true, + shortName: 'osport' + } ) }, { title: 'Soviet topo maps grid', order: 11200, - isOverlay: true, isDefault: true, - layer: new L.Layer.SovietTopoGrid({code: 'Ng'}) + layer: new L.Layer.SovietTopoGrid({ + code: 'Ng', + isOverlay: true + }) }, { title: 'Wikimapia', order: 11300, - isOverlay: true, isDefault: true, - layer: new L.Wikimapia({code: 'W'}), + layer: new L.Wikimapia({ + code: 'W', + isOverlay: true + }) }, { title: 'Mountain passes (Westra)', order: 11400, - isOverlay: true, isDefault: true, layer: new L.Layer.WestraPasses(config.westraDataBaseUrl, { - code: 'Wp', - print: true, - scaleDependent: true + code: 'Wp', + print: true, + scaleDependent: true, + isOverlay: true, + isOverlayTransparent: true, + shortName: 'passes', + markersOptions: { + isOverlay: true, + isOverlayTransparent: true, + shortName: 'passes' } - ) + }) }, // { // title: 'Tracks', @@ -255,29 +450,49 @@ export default function getLayers() { { title: 'OpenTopoMap', order: 110, - isOverlay: false, isDefault: false, layer: L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', - {code: 'Otm', maxNativeZoom: 17, scaleDependent: true, print: true, jnx: true, noCors: false} + { + code: 'Otm', + isOverlay: false, + maxNativeZoom: 17, + scaleDependent: true, + print: true, + jnx: true, + noCors: false, + shortName: 'opentopo' + } ) }, { title: 'OpenCycleMap', description: '<a href="https://www.opencyclemap.org/docs/">(Info and key)</a>', order: 120, - isOverlay: false, isDefault: false, layer: L.tileLayer('https://{s}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png?apikey=' + config.thunderforestKey, - {code: 'Ocm', scaleDependent: true, print: true, jnx: true} + { + code: 'Ocm', + isOverlay: false, + scaleDependent: true, + print: true, + jnx: true, + shortName: 'opencyclemap' + } ) }, { title: 'OSM Outdoors', order: 130, - isOverlay: false, isDefault: false, layer: L.tileLayer('https://{s}.tile.thunderforest.com/outdoors/{z}/{x}/{y}.png?apikey=' + config.thunderforestKey, - {code: 'Oso', scaleDependent: true, print: true, jnx: true} + { + code: 'Oso', + isOverlay: false, + scaleDependent: true, + print: true, + jnx: true, + shortName: 'osm_outdoors' + } ) }, ] @@ -289,47 +504,92 @@ export default function getLayers() { title: 'Eurasia 25km', description: '1975-80', order: 10090, - isOverlay: true, isDefault: false, layer: L.tileLayer("https://tiles.nakarte.tk/eurasia25km/{z}/{x}/{y}", - {code: 'E25m', tms: true, maxNativeZoom: 9, print: true, jnx: true, scaleDependent: false} + { + code: 'E25m', + isOverlay: true, + isOverlayTransparent: false, + tms: true, + maxNativeZoom: 9, + print: true, + jnx: true, + scaleDependent: false, + shortName: 'eurasia_25k' + } ) }, { title: 'Caucasus 1km', order: 10610, - isOverlay: true, isDefault: false, layer: L.tileLayer("https://tiles.nakarte.tk/new_gsh_100k/{z}/{x}/{y}", - {code: 'NT1', tms: true, maxNativeZoom: 14, print: true, jnx: true, scaleDependent: false} + { + code: 'NT1', + isOverlay: true, + isOverlayTransparent: false, + tms: true, + maxNativeZoom: 14, + print: true, + jnx: true, + scaleDependent: false, + shortName: 'caucasus_1k' + } ) }, { title: 'Caucasus 500m', order: 10810, - isOverlay: true, isDefault: false, layer: L.tileLayer("https://tiles.nakarte.tk/new_gsh_050k/{z}/{x}/{y}", - {code: 'NT5', tms: true, maxNativeZoom: 15, print: true, jnx: true, scaleDependent: false} + { + code: 'NT5', + isOverlay: true, + isOverlayTransparent: false, + tms: true, + maxNativeZoom: 15, + print: true, + jnx: true, + scaleDependent: false, + shortName: 'caucasus_500' + } ) }, { title: 'Topo 250m', order: 10950, - isOverlay: true, isDefault: false, layer: L.tileLayer("https://tiles.nakarte.tk/topo250/{z}/{x}/{y}", - {code: 'T25', tms: true, maxNativeZoom: 15, print: true, jnx: true, scaleDependent: false} + { + code: 'T25', + isOverlay: true, + isOverlayTransparent: false, + tms: true, + maxNativeZoom: 15, + print: true, + jnx: true, + scaleDependent: false, + shortName: 'topo_250' + } ) }, { title: 'Montenegro topo 250m', description: '1970-72', order: 10960, - isOverlay: true, isDefault: false, layer: L.tileLayer("https://tiles.nakarte.tk/montenegro250m/{z}/{x}/{y}", - {code: 'MN25', tms: true, maxNativeZoom: 15, print: true, jnx: true, scaleDependent: false} + { + code: 'MN25', + isOverlay: true, + isOverlayTransparent: false, + tms: true, + maxNativeZoom: 15, + print: true, + jnx: true, + scaleDependent: false, + shortName: 'montenegro_250' + } ) } ] @@ -341,12 +601,13 @@ export default function getLayers() { title: 'Mountains by Aleksey Tsvetkov', description: 'Tian Shan, Dzungaria, <a href="http://pereval.g-utka.ru/">http://pereval.g-utka.ru/</a>', order: 10390, - isOverlay: true, isDefault: false, layer: L.tileLayer("http://map.g-utka.ru/{z}/{x}/{y}.png", // FIXME: сделать minZoom=5, когда перейдём на версию leaflet с поддержкой minNativeZoom { code: 'Mt', + isOverlay: true, + isOverlayTransparent: false, tms: false, minZoom: 7, minNativeZoom: 7, @@ -354,7 +615,8 @@ export default function getLayers() { print: true, jnx: true, scaleDependent: false, - noCors: true + noCors: true, + shortName: 'tsvetkov_mountains' } ) }] @@ -365,10 +627,10 @@ export default function getLayers() { { title: 'Bing imagery acquisition dates', order: 11110, - isOverlay: true, isDefault: false, layer: new BingDates({ code: 'Bd', + isOverlay: true, maxNativeZoom: 18, print: false, jnx: false, @@ -379,101 +641,166 @@ export default function getLayers() { { title: 'geocaching.su', order: 11500, - isOverlay: true, isDefault: false, layer: new GeocachingSu(config.geocachingSuUrl, { code: 'Gc', + isOverlay: true, + isOverlayTransparent: true, print: true, - jnx: false + jnx: false, + shortName: 'geocaching' }) }, { title: 'OpenStreetMap GPS traces', order: 11120, - isOverlay: true, isDefault: false, layer: L.tileLayer('https://{s}.gps-tile.openstreetmap.org/lines/{z}/{x}/{y}.png', - {code: 'Ot', scaleDependent: true, print: true, jnx: false} + { + code: 'Ot', + isOverlay: true, + isOverlayTransparent: true, + scaleDependent: true, + print: true, + jnx: false, + shortName: 'osm_gps_traces' + } ) }, { title: 'Strava heatmap (all)', order: 11130, - isOverlay: true, isDefault: false, layer: new StravaHeatmap('https://heatmap-external-{s}.strava.com/tiles-auth/all/hot/{z}/{x}/{y}.png?px=256', - {code: 'Sa', scaleDependent: true, print: false, jnx: false, subdomains: 'abc', - maxNativeZoom: 16, noCors: true} + { + code: 'Sa', + isOverlay: true, + scaleDependent: true, + print: false, + jnx: false, + subdomains: 'abc', + maxNativeZoom: 16, + noCors: true + } ) }, { title: 'Strava heatmap (run)', order: 11131, - isOverlay: true, isDefault: false, layer: new StravaHeatmap('https://heatmap-external-{s}.strava.com/tiles-auth/run/hot/{z}/{x}/{y}.png?px=256', - {code: 'Sr', scaleDependent: true, print: false, jnx: false, subdomains: 'abc', - maxNativeZoom: 16, noCors: true} + { + code: 'Sr', + isOverlay: true, + scaleDependent: true, + print: false, + jnx: false, + subdomains: 'abc', + maxNativeZoom: 16, + noCors: true + } ) }, { title: 'Strava heatmap (ride)', order: 11132, - isOverlay: true, isDefault: false, layer: new StravaHeatmap('https://heatmap-external-{s}.strava.com/tiles-auth/ride/hot/{z}/{x}/{y}.png?px=256', - {code: 'Sb', scaleDependent: true, print: false, jnx: false, subdomains: 'abc', - maxNativeZoom: 16, noCors: true} + { + code: 'Sb', + isOverlay: true, + scaleDependent: true, + print: false, + jnx: false, + subdomains: 'abc', + maxNativeZoom: 16, + noCors: true + } ) }, { title: 'Strava heatmap (winter)', order: 11133, - isOverlay: true, isDefault: false, layer: new StravaHeatmap('https://heatmap-external-{s}.strava.com/tiles-auth/winter/hot/{z}/{x}/{y}.png?px=256', - {code: 'Sw', scaleDependent: true, print: false, jnx: false, subdomains: 'abc', - maxNativeZoom: 16, noCors: true} + { + code: 'Sw', + isOverlay: true, + scaleDependent: true, + print: false, + jnx: false, + subdomains: 'abc', + maxNativeZoom: 16, + noCors: true + } ) }, { title: 'Strava heatmap lowres (all)', order: 11134, - isOverlay: true, isDefault: false, layer: L.tileLayer('https://heatmap-external-{s}.strava.com/tiles/all/hot/{z}/{x}/{y}.png?px=256', - {code: 'Sal', scaleDependent: true, print: false, jnx: false, subdomains: 'abc', - maxNativeZoom: 12, noCors: true} + { + code: 'Sal', + isOverlay: true, + scaleDependent: true, + print: false, + jnx: false, + subdomains: 'abc', + maxNativeZoom: 12, + noCors: true + } ) }, { title: 'Strava heatmap lowres (run)', order: 11135, - isOverlay: true, isDefault: false, layer: L.tileLayer('https://heatmap-external-{s}.strava.com/tiles/run/hot/{z}/{x}/{y}.png?px=256', - {code: 'Srl', scaleDependent: true, print: false, jnx: false, subdomains: 'abc', - maxNativeZoom: 12, noCors: true} + { + code: 'Srl', + isOverlay: true, + scaleDependent: true, + print: false, + jnx: false, + subdomains: 'abc', + maxNativeZoom: 12, + noCors: true + } ) }, { title: 'Strava heatmap lowres (ride)', order: 11136, - isOverlay: true, isDefault: false, layer: L.tileLayer('https://heatmap-external-{s}.strava.com/tiles/ride/hot/{z}/{x}/{y}.png?px=256', - {code: 'Sbl', scaleDependent: true, print: false, jnx: false, subdomains: 'abc', - maxNativeZoom: 12, noCors: true} + { + code: 'Sbl', + isOverlay: true, + scaleDependent: true, + print: false, + jnx: false, + subdomains: 'abc', + maxNativeZoom: 12, + noCors: true + } ) }, { title: 'Strava heatmap lowres (winter)', order: 11137, - isOverlay: true, isDefault: false, layer: L.tileLayer('https://heatmap-external-{s}.strava.com/tiles/winter/hot/{z}/{x}/{y}.png?px=256', - {code: 'Swl', scaleDependent: true, print: false, jnx: false, subdomains: 'abc', - maxNativeZoom: 12, noCors: true} + { + code: 'Swl', + isOverlay: true, + scaleDependent: true, + print: false, + jnx: false, + subdomains: 'abc', + maxNativeZoom: 12, + noCors: true + } ) }, ] @@ -486,46 +813,90 @@ export default function getLayers() { // Вместо 404 отдают 500 для отсутствующих тайлов title: 'Norway UT map', order: 5000, - isOverlay: false, isDefault: false, layer: L.tileLayer("https://tilesprod.ut.no/tilestache/ut_topo_light/{z}/{x}/{y}.jpg", - {code: 'Nu', tms: false, maxNativeZoom: 16, print: true, jnx: true, scaleDependent: true, noCors: false} + { + code: 'Nu', + isOverlay: false, + tms: false, + maxNativeZoom: 16, + print: true, + jnx: true, + scaleDependent: true, + noCors: false, + shortName: 'norway_ut' + } ) }, { title: 'Norway paper map', order: 10310, - isOverlay: true, isDefault: false, layer: new L.TileLayer.Nordeskart('https://gatekeeper1.geonorge.no/BaatGatekeeper/gk/gk.cache_gmaps?layers=toporaster3&zoom={z}&x={x}&y={y}&gkt={baatToken}', - {code: 'Np', maxNativeZoom: 16, tms: false, print: true, jnx: true, scaleDependent: true} + { + code: 'Np', + isOverlay: true, + isOverlayTransparent: false, + maxNativeZoom: 16, + tms: false, + print: true, + jnx: true, + scaleDependent: true, + shortName: 'norway_paper' + } ) }, { title: 'Norway map', order: 10320, - isOverlay: true, isDefault: false, layer: new L.TileLayer.Nordeskart('https://gatekeeper1.geonorge.no/BaatGatekeeper/gk/gk.cache_gmaps?layers=topo4&zoom={z}&x={x}&y={y}&gkt={baatToken}', - {code: 'Nm', tms: false, print: true, jnx: true, scaleDependent: true} + { + code: 'Nm', + isOverlay: true, + isOverlayTransparent: false, + tms: false, + print: true, + jnx: true, + scaleDependent: true, + shortName: 'norway' + } ) }, { title: 'Norway summer trails', order: 20000, - isOverlay: true, isDefault: false, layer: L.tileLayer("https://tilesprod.ut.no/tilestache/dnt_sommer/{z}/{x}/{y}.png", - {code: 'Ns', tms: false, print: true, jnx: true, scaleDependent: true, noCors: false} + { + code: 'Ns', + isOverlay: true, + isOverlayTransparent: true, + tms: false, + print: true, + jnx: true, + scaleDependent: true, + noCors: false, + shortName: 'norway_summer' + } ) }, { title: 'Norway winter trails', order: 20010, - isOverlay: true, isDefault: false, layer: L.tileLayer("https://tilesprod.ut.no/tilestache/dnt_vinter/{z}/{x}/{y}.png", - {code: 'Nw', tms: false, print: true, jnx: true, scaleDependent: true, noCors: false} + { + code: 'Nw', + isOverlay: true, + isOverlayTransparent: true, + tms: false, + print: true, + jnx: true, + scaleDependent: true, + noCors: false, + shortName: 'norway_winter' + } ) }, { @@ -533,10 +904,18 @@ export default function getLayers() { title: 'Norway roads', description: '<a href="https://kart.finn.no/">https://kart.finn.no/</a>', order: 5030, - isOverlay: false, isDefault: false, layer: L.tileLayer("https://maptiles1.finncdn.no/tileService/1.0.3/normap/{z}/{x}/{y}.png", - {code: 'Nr', tms: false, print: true, jnx: true, scaleDependent: true, noCors: true} + { + code: 'Nr', + isOverlay: false, + tms: false, + print: true, + jnx: true, + scaleDependent: true, + noCors: true, + shortName: 'norway_roads' + } ) }] }, @@ -546,46 +925,86 @@ export default function getLayers() { { title: 'Czech base', order: 5040, - isOverlay: false, isDefault: false, layer: L.tileLayer("https://m{s}.mapserver.mapy.cz/base-m/{z}-{x}-{y}", - {code: 'Czb', tms: false, print: true, jnx: true, subdomains: '1234', scaleDependent: true} + { + code: 'Czb', + isOverlay: false, + tms: false, + print: true, + jnx: true, + subdomains: '1234', + scaleDependent: true, + shortName: 'czech' + } ) }, { title: 'Czech tourist', order: 5050, - isOverlay: false, isDefault: false, layer: L.tileLayer("https://m{s}.mapserver.mapy.cz/turist-m/{z}-{x}-{y}", - {code: 'Czt', tms: false, print: true, jnx: true, subdomains: '1234', scaleDependent: true} + { + code: 'Czt', + isOverlay: false, + tms: false, + print: true, + jnx: true, + subdomains: '1234', + scaleDependent: true, + shortName: 'czech_tourist' + } ) }, { title: 'Czech summer', order: 5060, - isOverlay: false, isDefault: false, layer: L.tileLayer("https://m{s}.mapserver.mapy.cz/turist_aquatic-m/{z}-{x}-{y}", - {code: 'Czs', tms: false, print: true, jnx: true, subdomains: '1234', scaleDependent: true} + { + code: 'Czs', + isOverlay: false, + tms: false, + print: true, + jnx: true, + subdomains: '1234', + scaleDependent: true, + shortName: 'czech_summer' + } ) }, { title: 'Czech winter', order: 5070, - isOverlay: false, isDefault: false, layer: L.tileLayer("https://m{s}.mapserver.mapy.cz/winter-m/{z}-{x}-{y}", - {code: 'Czw', tms: false, print: true, jnx: true, subdomains: '1234', scaleDependent: true} + { + code: 'Czw', + isOverlay: false, + tms: false, + print: true, + jnx: true, + subdomains: '1234', + scaleDependent: true, + shortName: 'czech_winter' + } ) }, { title: 'Czech geographical', order: 5080, - isOverlay: false, isDefault: false, layer: L.tileLayer("https://m{s}.mapserver.mapy.cz/zemepis-m/{z}-{x}-{y}", - {code: 'Czg', tms: false, print: true, jnx: true, subdomains: '1234', scaleDependent: true} + { + code: 'Czg', + isOverlay: false, + tms: false, + print: true, + jnx: true, + subdomains: '1234', + scaleDependent: true, + shortName: 'czech_geo' + } ) }] } @@ -593,12 +1012,20 @@ export default function getLayers() { // TODO: move it to tests const codes = {}; const orders = {}; + const shortNames = new Set(); for (let group of layers) { for (let layer of group.layers) { - if (!layer.layer.options) { + const { layer: { options } } = layer + if (!options) { throw new Error('Layer without options: ' + layer.title); } - let code = layer.layer.options.code; + const { + code, + shortName, + print, + isOverlay, + isOverlayTransparent + } = options if (!code) { throw new Error('Layer without code: ' + layer.title); } @@ -614,6 +1041,19 @@ export default function getLayers() { throw new Error(`Duplicate layer order "${order}"`); } orders[order] = 1; + + if (print) { + if (isOverlay && (isOverlayTransparent === undefined)) { + throw new Error('Overlay layer without isOverlayTransparent: ' + layer.title); + } + if (!shortName) { + throw new Error('Layer without shortName: ' + layer.title); + } + if (shortNames.has(shortName)) { + throw new Error(`Duplicate layer shortName "${shortName}"`); + } + shortNames.add(shortName); + } } } return layers; diff --git a/src/lib/leaflet.control.layers.configure/index.js b/src/lib/leaflet.control.layers.configure/index.js @@ -194,8 +194,9 @@ function enableConfig(control, layers) { enabledLayers.sort((l1, l2) => l1.order - l2.order); enabledLayers.forEach((l) => { l.layer._justAdded = addedLayers && addedLayers.includes(l); - l.isOverlay ? this.addOverlay(l.layer, l.title) : this.addBaseLayer(l.layer, l.title); - if (!l.isOverlay && this._map.hasLayer(l.layer)) { + const { layer: { options: { isOverlay } } } = l + isOverlay ? this.addOverlay(l.layer, l.title) : this.addBaseLayer(l.layer, l.title); + if (!isOverlay && this._map.hasLayer(l.layer)) { hasBaselayerOnMap = true; } } @@ -203,7 +204,7 @@ function enableConfig(control, layers) { // если нет активного базового слоя, включить первый, если он есть if (!hasBaselayerOnMap) { for (let layer of enabledLayers) { - if (!layer.isOverlay) { + if (!layer.layer.options.isOverlay) { this._map.addLayer(layer.layer); break; } @@ -395,6 +396,7 @@ ${buttonsHtml}`; createCustomLayer: function(fieldValues) { const serialized = this.serializeCustomLayer(fieldValues); const tileLayer = L.tileLayer(fieldValues.url, { + isOverlay: fieldValues.isOverlay, tms: fieldValues.tms, maxNativeZoom: fieldValues.maxZoom, scaleDependent: fieldValues.scaleDependent, @@ -407,7 +409,6 @@ ${buttonsHtml}`; const customLayer = { title: fieldValues.name, - isOverlay: fieldValues.isOverlay, isDefault: false, isCustom: true, serialized: serialized, @@ -464,7 +465,7 @@ ${buttonsHtml}`; const newLayer = this.createCustomLayer(newFieldValues); this._customLayers.splice(layerPos, 0, newLayer); - if (this._map.hasLayer(layer.layer) && (!layer.isOverlay || newLayer.isOverlay)) { + if (this._map.hasLayer(layer.layer) && (!layer.layer.options.isOverlay || newLayer.layer.options.isOverlay)) { this._map.addLayer(newLayer.layer); } this._map.removeLayer(layer.layer); @@ -510,4 +511,4 @@ ${buttonsHtml}`; } -export default enableConfig; -\ No newline at end of file +export default enableConfig; diff --git a/src/lib/leaflet.control.printPages/control.js b/src/lib/leaflet.control.printPages/control.js @@ -33,14 +33,14 @@ ko.extenders.checkNumberRange = function(target, range) { ).extend({notify: 'always'}); }; -function savePagesPdf(imagesInfo, resolution) { +function savePagesPdf(imagesInfo, resolution, fileName) { let pdf = makePdf(imagesInfo, resolution); pdf = blobFromString(pdf); - saveAs(pdf, 'map.pdf', true); + saveAs(pdf, fileName, true); } -function savePageJpg(page) { - saveAs(blobFromString(page.data), 'map.jpg', true); +function savePageJpg(page, fileName) { + saveAs(blobFromString(page.data), fileName, true); } L.Control.PrintPages = L.Control.extend({ @@ -115,9 +115,9 @@ L.Control.PrintPages = L.Control.extend({ L.DomUtil.addClass(this._container, 'minimized'); }, - addPage: function(isLandsacape, center) { + addPage: function(isLandscape, center) { let [pageWidth, pageHeight] = this.printSize(); - if (isLandsacape) { + if (isLandscape) { [pageWidth, pageHeight] = [pageHeight, pageWidth]; } if (!center) { @@ -126,7 +126,7 @@ L.Control.PrintPages = L.Control.extend({ const page = new PageFeature(center, [pageWidth, pageHeight], this.scale(), (this.pages.length + 1).toString() ); - page._rotated = isLandsacape; + page._rotated = isLandscape; page.addTo(this._map); this.pages.push(page); this.pagesNum(this.pages.length); @@ -216,18 +216,28 @@ L.Control.PrintPages = L.Control.extend({ decorationLayers.push(new MagneticMeridians()); } decorationLayers.push(new OverlayScale()); + const scale = this.scale(); + const width = this.pageWidth(); + const height = this.pageHeight(); renderPages({ map: this._map, pages, zooms: this.zoomForPrint(), resolution, - scale: this.scale(), + scale, decorationLayers, progressCallback: this.incrementProgress.bind(this) } - ).then((images) => { + ).then(({images, renderedLayers}) => { if (images) { - savePagesPdf(images, resolution) + const fileName = this.getFileName({ + renderedLayers, + scale, + width, + height, + extension: 'pdf' + }); + savePagesPdf(images, resolution, fileName); } } ).catch((e) => { @@ -255,17 +265,29 @@ L.Control.PrintPages = L.Control.extend({ this.downloadProgressRange(1000); this.downloadProgressDone(undefined); this.makingPdf(true); + const scale = this.scale(); + const width = this.pageWidth(); + const height = this.pageHeight(); renderPages({ map: this._map, pages, zooms: this.zoomForPrint(), resolution: this.resolution(), - scale: this.scale(), + scale, decorationLayers, progressCallback: this.incrementProgress.bind(this) } ) - .then((images) => savePageJpg(images[0])) + .then(({images, renderedLayers}) => { + const fileName = this.getFileName({ + renderedLayers, + scale, + width, + height, + extension: 'jpg' + }); + savePageJpg(images[0], fileName); + }) .catch((e) => { logging.captureException(e); notify(`Failed to create JPEG from page: ${e.message}`); @@ -461,6 +483,57 @@ L.Control.PrintPages = L.Control.extend({ } } return true; + }, + + getFileName: function({renderedLayers, scale, width, height, extension}) { + let fileName = ''; + + let opaqueLayer; + const transparentOverlayLayers = []; + + renderedLayers.forEach(layer => { + const { + options: { + isOverlay, + isOverlayTransparent, + shortName + } + } = layer; + + if (!shortName) { + return; + } + + if (isOverlay) { + if (isOverlayTransparent) { + transparentOverlayLayers.push(layer); + } else { + opaqueLayer = layer; + } + } else if (!opaqueLayer) { + opaqueLayer = layer; + } + }); + + const appendLayerShortName = (layer) => { + fileName += `${layer.options.shortName}_`; + } + if (opaqueLayer) { + appendLayerShortName(opaqueLayer); + } + transparentOverlayLayers.forEach(appendLayerShortName); + + fileName += `${scale}m`; + + const currentPageSize = this.pageSizes.find((pageSize) => { + return (width === pageSize.width) && (height === pageSize.height); + }); + + if (currentPageSize) { + fileName += `_${currentPageSize.name}`; + } + + return `${fileName}.${extension}`; } } ); diff --git a/src/lib/leaflet.control.printPages/map-render.js b/src/lib/leaflet.control.printPages/map-render.js @@ -217,7 +217,7 @@ async function* iterateLayersTiles(layers, latLngBounds, destPixelSize, resoluti layerPromises.push(tilePromise.tilePromise); let progressInc = (layer._printProgressWeight || 1) / count; tilePromise.tilePromise = - tilePromise.tilePromise.then((tileInfo) => Object.assign({zoom, progressInc}, tileInfo)); + tilePromise.tilePromise.then((tileInfo) => Object.assign({zoom, progressInc, layer}, tileInfo)); doStop = yield tilePromise; if (doStop) { tilePromise.abortLoading(); @@ -276,6 +276,7 @@ async function renderPages({map, pages, zooms, resolution, scale, progressCallba } progressRange *= pages.length; const pageImagesInfo = []; + const renderedLayers = new Set(); for (let page of pages) { let destPixelSize = page.printSize.multiplyBy(resolution / 25.4).round(); let pixelBounds = L.bounds( @@ -301,6 +302,10 @@ async function renderPages({map, pages, zooms, resolution, scale, progressCallba } progressCallback(tileInfo.progressInc, progressRange); composer.putTile(tileInfo); + const {image, draw, layer} = tileInfo; + if ((image || draw) && !layer._layerDummy) { + renderedLayers.add(layer); + } } const dataUrl = composer.getDataUrl(); let data = dataUrl.substring(dataUrl.indexOf(',') + 1); @@ -312,8 +317,8 @@ async function renderPages({map, pages, zooms, resolution, scale, progressCallba } ); } - return pageImagesInfo; + return {images: pageImagesInfo, renderedLayers}; } -export {renderPages}; -\ No newline at end of file +export {renderPages}; diff --git a/src/lib/leaflet.layer.rasterize/WestraPasses.js b/src/lib/leaflet.layer.rasterize/WestraPasses.js @@ -20,7 +20,7 @@ WestraPassesMarkers.include({ }, cloneForPrint: function (options) { - options = L.Util.extend({}, options); + options = L.Util.extend({}, this.options, options); return new WestraPassesMarkers(this._baseUrl, options); }, diff --git a/src/lib/leaflet.layer.westraPasses/index.js b/src/lib/leaflet.layer.westraPasses/index.js @@ -12,7 +12,7 @@ L.Layer.WestraPasses = L.Layer.extend({ initialize: function(baseUrl, options) { L.setOptions(this, options); - this.markers = new WestraPassesMarkers(baseUrl); + this.markers = new WestraPassesMarkers(baseUrl, options.markersOptions); this.regions1 = new L.Layer.GeoJSONAjax(baseUrl + this.options.fileRegions1, { className: 'westra-region-polygon', onEachFeature: this._setRegionLabel.bind(this, 'regions1')