layers.js (58656B)
1 import L from "leaflet"; 2 import '~/lib/leaflet.layer.yandex'; 3 import '~/lib/leaflet.layer.google'; 4 import {BingLayer} from '~/lib/leaflet.layer.bing'; 5 import {BingDates} from '~/lib/leaflet.layer.bing/dates'; 6 import config from './config'; 7 import '~/lib/leaflet.layer.soviet-topomaps-grid'; 8 import '~/lib/leaflet.layer.westraPasses'; 9 import '~/lib/leaflet.layer.wikimapia'; 10 import {GeocachingSu} from '~/lib/leaflet.layer.geocaching-su'; 11 import {RetinaTileLayer} from '~/lib/leaflet.layer.RetinaTileLayer'; 12 import urlViaCorsProxy from '~/lib/CORSProxy'; 13 import '~/lib/leaflet.layer.TileLayer.cutline'; 14 import {getCutline} from '~/lib/layers-cutlines'; 15 import {LayerCutlineOverview} from '~/lib/leaflet.layer.LayerCutlineOverview'; 16 17 class LayerGroupWithOptions extends L.LayerGroup { 18 constructor(layers, options) { 19 super(layers); 20 L.setOptions(this, options); 21 } 22 } 23 24 const layersDefs = [ 25 { 26 title: 'OpenStreetMap', 27 description: 'OSM default style', 28 isDefault: true, 29 layer: L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', 30 { 31 code: 'O', 32 isOverlay: false, 33 scaleDependent: true, 34 print: true, 35 jnx: true, 36 shortName: 'osm', 37 attribution: '<a href="https://www.openstreetmap.org/copyright">' + 38 '© OpenStreetMap contributors</a>', 39 } 40 ) 41 }, 42 { 43 title: 'ESRI Satellite', 44 isDefault: true, 45 layer: L.tileLayer( 46 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', 47 { 48 code: 'E', 49 isOverlay: false, 50 scaleDependent: false, 51 maxNativeZoom: 18, 52 print: true, 53 jnx: true, 54 shortName: 'esri', 55 attribution: 56 '<a href="https://www.arcgis.com/home/item.html?id=10df2279f9684e4a9f6a7f08febac2a9">' + 57 'ESRI World Imagery for ArcGIS</a>', 58 } 59 ) 60 }, 61 { 62 title: 'Yandex map', 63 isDefault: true, 64 layer: new L.Layer.Yandex.Map( 65 { 66 scaleDependent: true, 67 code: 'Y', 68 isOverlay: false, 69 print: true, 70 jnx: true, 71 shortName: 'yandex', 72 attribution: '<a href="https://yandex.ru/maps/">Yandex</a>', 73 } 74 ) 75 }, 76 { 77 title: 'Yandex Satellite', 78 isDefault: true, 79 layer: new L.Layer.Yandex.Sat( 80 { 81 scaleDependent: false, 82 code: 'S', 83 isOverlay: false, 84 print: true, 85 jnx: true, 86 shortName: 'yandex_sat', 87 attribution: '<a href="https://yandex.ru/maps/?l=sat">Yandex</a>', 88 } 89 ) 90 }, 91 { 92 title: 'Google Map', 93 isDefault: true, 94 layer: new L.Layer.GoogleMap( 95 { 96 code: 'G', 97 isOverlay: false, 98 scaleDependent: true, 99 print: true, 100 jnx: true, 101 shortName: 'google', 102 attribution: '<a href="https://www.google.com/maps">Google</a>', 103 } 104 ) 105 }, 106 { 107 title: 'Google Hybrid', 108 isDefault: false, 109 layer: new L.Layer.GoogleHybrid( 110 { 111 code: 'Gh', 112 isOverlay: true, 113 scaleDependent: true, 114 print: true, 115 jnx: false, 116 shortName: 'google_hybrid', 117 isOverlayTransparent: true, 118 attribution: '<a href="https://www.google.com/maps/@43.0668619,60.5738071,13622628m' + 119 '/data=!3m1!1e3">Google</a>', 120 } 121 ) 122 }, 123 { 124 title: 'Google Satellite', 125 isDefault: true, 126 layer: new L.Layer.GoogleSat( 127 { 128 code: 'L', 129 isOverlay: false, 130 scaleDependent: false, 131 print: true, 132 jnx: true, 133 shortName: 'google_sat', 134 attribution: '<a href="https://www.google.com/maps/@43.0668619,60.5738071,13622628m' + 135 '/data=!3m1!1e3">Google</a>', 136 } 137 ) 138 }, 139 { 140 title: 'Google Terrain', 141 isDefault: true, 142 layer: new L.Layer.GoogleTerrain({ 143 code: 'P', 144 isOverlay: false, 145 scaleDependent: false, 146 print: true, 147 jnx: true, 148 shortName: 'google_terrain', 149 attribution: '<a href="https://www.google.com/maps/@43.1203575,42.1105049,9.58z' + 150 '/data=!5m1!1e4">Google</a>', 151 } 152 ) 153 }, 154 { 155 title: 'Bing Satellite', 156 isDefault: true, 157 layer: new BingLayer(config.bingKey, 158 { 159 code: 'I', 160 isOverlay: false, 161 scaleDependent: false, 162 print: true, 163 jnx: true, 164 shortName: 'bing_sat' 165 } 166 ) 167 }, 168 { 169 title: 'marshruty.ru', 170 isDefault: true, 171 layer: L.tileLayer('https://maps.marshruty.ru/ml.ashx?x={x}&y={y}&z={z}&i=1&al=1', 172 { 173 code: 'M', 174 isOverlay: false, 175 maxNativeZoom: 18, 176 noCors: true, 177 scaleDependent: true, 178 print: true, 179 jnx: true, 180 shortName: 'marshruty', 181 attribution: '<a href="https://www.marshruty.ru/Maps/Maps.aspx?x=60&y=55&z=8&t=4">' + 182 'marshruty.ru</a>', 183 } 184 ) 185 }, 186 { 187 title: 'Topomapper 1km', 188 isDefault: true, 189 layer: L.tileLayer( 190 urlViaCorsProxy( 191 'http://88.99.52.155/cgi-bin/tapp/tilecache.py/1.0.0/topomapper_v2/{z}/{x}/{y}.jpg' 192 ), 193 { 194 code: 'T', 195 isOverlay: false, 196 scaleDependent: false, 197 maxNativeZoom: 13, 198 noCors: false, 199 print: true, 200 jnx: true, 201 shortName: 'topomapper_1k', 202 attribution: '<a href="https://play.google.com/store/apps/' + 203 'details?id=com.atlogis.sovietmaps.free&hl=en&gl=US">Russian Topo Maps</a>', 204 } 205 ) 206 }, 207 208 { 209 title: 'Topo 10km', 210 isDefault: true, 211 layer: L.tileLayer("https://{s}.tiles.nakarte.me/topo001m/{z}/{x}/{y}", 212 { 213 code: 'D', 214 isOverlay: true, 215 isOverlayTransparent: false, 216 tms: true, 217 scaleDependent: false, 218 maxNativeZoom: 9, 219 print: true, 220 jnx: true, 221 shortName: 'topo_10k' 222 } 223 ) 224 }, 225 { 226 title: 'GGC 2 km', 227 isDefault: true, 228 layer: L.tileLayer("https://{s}.tiles.nakarte.me/ggc2000/{z}/{x}/{y}", 229 { 230 code: 'N', 231 isOverlay: true, 232 isOverlayTransparent: false, 233 tms: true, 234 scaleDependent: false, 235 maxNativeZoom: 12, 236 print: true, 237 jnx: true, 238 shortName: 'ggc_2k' 239 } 240 ) 241 }, 242 { 243 title: 'ArbaletMO', 244 isDefault: true, 245 layer: L.tileLayer("https://{s}.tiles.nakarte.me/ArbaletMO/{z}/{x}/{y}", 246 { 247 code: 'A', 248 isOverlay: true, 249 isOverlayTransparent: false, 250 tms: true, 251 scaleDependent: false, 252 maxNativeZoom: 13, 253 print: true, 254 jnx: true, 255 shortName: 'arbalet', 256 attribution: 257 '<a href="http://www.velozona.ru/forums/showmessage.php?id=3370">Arbalet (2004)</a>', 258 } 259 ) 260 }, 261 { 262 title: 'Slazav mountains', 263 isDefault: true, 264 layer: L.tileLayer("https://slazav.xyz/tiles/hr/{x}-{y}-{z}.png", 265 { 266 code: 'Q', 267 isOverlay: true, 268 isOverlayTransparent: false, 269 tms: false, 270 scaleDependent: false, 271 maxNativeZoom: 13, 272 noCors: true, 273 print: true, 274 jnx: true, 275 shortName: 'slazav_mountains', 276 attribution: '<a href="http://slazav.xyz/maps">Vladislav Zavjalov</a>', 277 } 278 ) 279 }, 280 { 281 title: 'GGC 1km', 282 isDefault: true, 283 layer: L.tileLayer("https://{s}.tiles.nakarte.me/ggc1000/{z}/{x}/{y}", 284 { 285 code: 'J', 286 isOverlay: true, 287 isOverlayTransparent: false, 288 tms: true, 289 scaleDependent: false, 290 maxNativeZoom: 13, 291 print: true, 292 jnx: true, 293 shortName: 'ggc_1k' 294 } 295 ) 296 }, 297 { 298 title: 'Topo 1km', 299 isDefault: true, 300 layer: L.tileLayer("https://{s}.tiles.nakarte.me/topo1000/{z}/{x}/{y}", 301 { 302 code: 'C', 303 isOverlay: true, 304 isOverlayTransparent: false, 305 tms: true, 306 scaleDependent: false, 307 maxNativeZoom: 13, 308 print: true, 309 jnx: true, 310 shortName: 'topo_1k' 311 } 312 ) 313 }, 314 { 315 title: 'GGC 500m', 316 isDefault: true, 317 layer: L.tileLayer("https://{s}.tiles.nakarte.me/ggc500/{z}/{x}/{y}", 318 { 319 code: 'F', 320 isOverlay: true, 321 isOverlayTransparent: false, 322 tms: true, 323 scaleDependent: false, 324 maxNativeZoom: 14, 325 print: true, 326 jnx: true, 327 shortName: 'ggc_500' 328 } 329 ) 330 }, 331 { 332 title: 'Topo 500m', 333 isDefault: true, 334 layer: L.tileLayer("https://{s}.tiles.nakarte.me/topo500/{z}/{x}/{y}", 335 { 336 code: 'B', 337 isOverlay: true, 338 isOverlayTransparent: false, 339 tms: true, 340 scaleDependent: false, 341 maxNativeZoom: 14, 342 print: true, 343 jnx: true, 344 shortName: 'topo_500' 345 } 346 ) 347 }, 348 { 349 title: 'GGC 250m', 350 isDefault: true, 351 layer: L.tileLayer("https://{s}.tiles.nakarte.me/ggc250/{z}/{x}/{y}", 352 { 353 code: 'K', 354 isOverlay: true, 355 isOverlayTransparent: false, 356 tms: true, 357 scaleDependent: false, 358 maxNativeZoom: 15, 359 print: true, 360 jnx: true, 361 shortName: 'ggc_250' 362 } 363 ) 364 }, 365 { 366 title: 'Slazav Moscow region map', 367 isDefault: true, 368 layer: L.tileLayer("https://slazav.xyz/tiles/podm/{x}-{y}-{z}.png", 369 { 370 code: 'Z', 371 isOverlay: true, 372 isOverlayTransparent: false, 373 tms: false, 374 scaleDependent: false, 375 maxNativeZoom: 14, 376 noCors: true, 377 print: true, 378 jnx: true, 379 shortName: 'slazav', 380 attribution: '<a href="http://slazav.xyz/maps">Vladislav Zavjalov</a>', 381 } 382 ) 383 }, 384 { 385 title: 'Races', 386 isDefault: true, 387 layer: L.tileLayer("https://{s}.tiles.nakarte.me/adraces/{z}/{x}/{y}", 388 { 389 code: 'U', 390 isOverlay: true, 391 isOverlayTransparent: false, 392 tms: true, 393 scaleDependent: false, 394 maxNativeZoom: 15, 395 print: true, 396 jnx: true, 397 shortName: 'races' 398 } 399 ) 400 }, 401 { 402 title: 'O-sport', 403 isDefault: true, 404 layer: L.tileLayer("https://{s}.tiles.nakarte.me/osport/{z}/{x}/{y}", 405 { 406 code: 'R', 407 isOverlay: true, 408 isOverlayTransparent: false, 409 tms: true, 410 scaleDependent: false, 411 maxNativeZoom: 17, 412 print: true, 413 jnx: true, 414 shortName: 'osport' 415 } 416 ) 417 }, 418 { 419 title: 'Soviet topo maps grid', 420 isDefault: true, 421 layer: new L.Layer.SovietTopoGrid({ 422 code: 'Ng', 423 isOverlay: true, 424 print: false, 425 jnx: false 426 }) 427 }, 428 { 429 title: 'Wikimapia', 430 isDefault: true, 431 layer: new L.Wikimapia({ 432 code: 'W', 433 isOverlay: true, 434 print: false, 435 jnx: false, 436 attribution: '<a href="https://wikimapia.org/">Wikimapia</a>', 437 tilesBaseUrl: config.wikimapiaTilesBaseUrl, 438 }) 439 }, 440 { 441 title: 'Mountain passes (Westra)', 442 isDefault: true, 443 layer: new L.Layer.WestraPasses(config.westraDataBaseUrl, { 444 code: 'Wp', 445 print: true, 446 jnx: false, 447 scaleDependent: true, 448 isOverlay: true, 449 isOverlayTransparent: true, 450 shortName: 'passes', 451 markersOptions: { 452 isOverlay: true, 453 isOverlayTransparent: true, 454 shortName: 'passes' 455 }, 456 attribution: '<a href="http://westra.ru/passes/">Westra passes catalog</a>', 457 }) 458 }, 459 { 460 title: 'OpenTopoMap', 461 isDefault: false, 462 layer: L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', 463 { 464 code: 'Otm', 465 isOverlay: false, 466 maxNativeZoom: 16, 467 scaleDependent: true, 468 print: true, 469 jnx: true, 470 noCors: false, 471 shortName: 'opentopo', 472 attribution: '<a href="https://opentopomap.org/">OpenTopoMap</a>', 473 hotkey: 'V', 474 } 475 ) 476 }, 477 { 478 title: 'OpenCycleMap', 479 description: '<a href="https://www.opencyclemap.org/docs/">(Info and key)</a>', 480 isDefault: false, 481 layer: L.tileLayer('https://{s}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png', 482 { 483 code: 'Ocm', 484 isOverlay: false, 485 scaleDependent: true, 486 print: true, 487 jnx: true, 488 shortName: 'opencyclemap', 489 attribution: '<a href="https://www.opencyclemap.org/">Thunderforest OpenCycleMap</a>', 490 } 491 ) 492 }, 493 { 494 title: 'OSM Outdoors', 495 isDefault: false, 496 layer: L.tileLayer('https://{s}.tile.thunderforest.com/outdoors/{z}/{x}/{y}.png', 497 { 498 code: 'Oso', 499 isOverlay: false, 500 scaleDependent: true, 501 print: true, 502 jnx: true, 503 shortName: 'osm_outdoors', 504 attribution: 505 '<a href="https://www.thunderforest.com/maps/outdoors/">Thunderforest Outdoors</a>', 506 } 507 ) 508 }, 509 { 510 title: 'Eurasia 25km', 511 description: '1975-80', 512 isDefault: false, 513 layer: L.tileLayer("https://{s}.tiles.nakarte.me/eurasia25km/{z}/{x}/{y}", 514 { 515 code: 'E25m', 516 isOverlay: true, 517 isOverlayTransparent: false, 518 tms: true, 519 maxNativeZoom: 9, 520 print: true, 521 jnx: true, 522 scaleDependent: false, 523 shortName: 'eurasia_25k' 524 } 525 ) 526 }, 527 { 528 title: 'Caucasus 1km', 529 isDefault: false, 530 layer: L.tileLayer("https://{s}.tiles.nakarte.me/new_gsh_100k/{z}/{x}/{y}", 531 { 532 code: 'NT1', 533 isOverlay: true, 534 isOverlayTransparent: false, 535 tms: true, 536 maxNativeZoom: 14, 537 print: true, 538 jnx: true, 539 scaleDependent: false, 540 shortName: 'caucasus_1k', 541 attribution: '<a href="http://genshtab-yuga.narod.ru/">Topo maps (2006)</a>', 542 } 543 ) 544 }, 545 { 546 title: 'Caucasus 500m', 547 isDefault: false, 548 layer: L.tileLayer("https://{s}.tiles.nakarte.me/new_gsh_050k/{z}/{x}/{y}", 549 { 550 code: 'NT5', 551 isOverlay: true, 552 isOverlayTransparent: false, 553 tms: true, 554 maxNativeZoom: 15, 555 print: true, 556 jnx: true, 557 scaleDependent: false, 558 shortName: 'caucasus_500', 559 attribution: '<a href="http://genshtab-yuga.narod.ru/">Topo maps (1998 - 2003)</a>', 560 } 561 ) 562 }, 563 { 564 title: 'Topo 250m', 565 isDefault: false, 566 layer: L.tileLayer("https://{s}.tiles.nakarte.me/topo250/{z}/{x}/{y}", 567 { 568 code: 'T25', 569 isOverlay: true, 570 isOverlayTransparent: false, 571 tms: true, 572 maxNativeZoom: 15, 573 print: true, 574 jnx: true, 575 scaleDependent: false, 576 shortName: 'topo_250' 577 } 578 ) 579 }, 580 { 581 title: 'Montenegro topo 250m', 582 description: '1970-72', 583 isDefault: false, 584 layer: L.tileLayer("https://{s}.tiles.nakarte.me/montenegro250m/{z}/{x}/{y}", 585 { 586 code: 'MN25', 587 isOverlay: true, 588 isOverlayTransparent: false, 589 tms: true, 590 maxNativeZoom: 15, 591 print: true, 592 jnx: true, 593 scaleDependent: false, 594 shortName: 'montenegro_250' 595 } 596 ) 597 }, 598 { 599 title: 'Mountains by Aleksey Tsvetkov', 600 description: 601 'Tian Shan, Dzungaria, <a href="http://pereval.g-utka.ru/">http://pereval.g-utka.ru/</a>', 602 isDefault: true, 603 layer: new LayerGroupWithOptions( 604 [ 605 L.tileLayer( 606 urlViaCorsProxy( 607 'http://nakartetiles.s3-website.eu-central-1.amazonaws.com/{z}/{x}/{y}.png' 608 ), 609 { 610 isOverlay: true, 611 isOverlayTransparent: false, 612 tms: false, 613 minZoom: 2, 614 maxNativeZoom: 15, 615 print: true, 616 jnx: true, 617 scaleDependent: false, 618 noCors: false, 619 shortName: 'tsvetkov_mountains', 620 cutline: getCutline('tsvetkov_mountains'), 621 bounds: [ 622 [40.66664, 71.00007], 623 [45.33338, 81.00001], 624 ], 625 attribution: '<a href="http://pereval.g-utka.ru/">Aleksey Tsvetkov</a>', 626 } 627 ), 628 new LayerCutlineOverview(getCutline('tsvetkov_mountains'), 6, 629 'Mountains by Aleksey Tsvetkov'), 630 ], 631 { 632 code: 'Mt', 633 isOverlay: true, 634 isWrapper: true, 635 } 636 ), 637 }, 638 { 639 title: 'Bing imagery acquisition dates', 640 isDefault: false, 641 layer: new BingDates({ 642 code: 'Bd', 643 isOverlay: true, 644 maxNativeZoom: 18, 645 print: false, 646 jnx: false, 647 scaleDependent: false, 648 noCors: true, 649 attribution: 650 '<a href="https://github.com/mvexel/bingimageanalyzer">Bing Aerial Imagery Analyzer</a>', 651 }) 652 }, 653 { 654 title: 'geocaching.su', 655 isDefault: false, 656 layer: new GeocachingSu(config.geocachingSuUrl, { 657 code: 'Gc', 658 isOverlay: true, 659 isOverlayTransparent: true, 660 print: true, 661 jnx: false, 662 shortName: 'geocaching', 663 attribution: '<a href="https://geocaching.su/">geocaching.su</a>', 664 }) 665 }, 666 { 667 title: 'OpenStreetMap GPS traces', 668 isDefault: false, 669 layer: L.tileLayer('https://{s}.gps-tile.openstreetmap.org/lines/{z}/{x}/{y}.png', 670 { 671 code: 'Ot', 672 isOverlay: true, 673 isOverlayTransparent: true, 674 scaleDependent: true, 675 print: true, 676 jnx: false, 677 shortName: 'osm_gps_traces', 678 attribution: '<a href="https://www.openstreetmap.org/#&layers=G">' + 679 'OpenStreetMap public GPS traces</a>', 680 } 681 ) 682 }, 683 { 684 title: 'Strava heatmap (all)', 685 isDefault: false, 686 layer: new RetinaTileLayer( 687 [ 688 urlViaCorsProxy( 689 'https://heatmap-external-a.strava.com/tiles-auth/all/hot/{z}/{x}/{y}.png?px=256' 690 ), 691 urlViaCorsProxy( 692 'https://heatmap-external-a.strava.com/tiles-auth/all/hot/{z}/{x}/{y}.png?px=512' 693 ), 694 ], 695 { 696 code: 'Sa', 697 isOverlay: true, 698 isOverlayTransparent: true, 699 scaleDependent: false, 700 print: true, 701 jnx: false, 702 subdomains: 'abc', 703 noCors: true, 704 shortName: 'strava_all', 705 retinaOptionsOverrides: [{maxNativeZoom: 16}, {maxNativeZoom: 15}], 706 attribution: '<a href="https://www.strava.com/heatmap">Strava Global Heatmap</a>', 707 opacity: 0.75, 708 } 709 ) 710 }, 711 { 712 title: 'Strava heatmap (run)', 713 isDefault: false, 714 layer: new RetinaTileLayer( 715 [ 716 urlViaCorsProxy( 717 'https://heatmap-external-a.strava.com/tiles-auth/run/hot/{z}/{x}/{y}.png?px=256' 718 ), 719 urlViaCorsProxy( 720 'https://heatmap-external-a.strava.com/tiles-auth/run/hot/{z}/{x}/{y}.png?px=512' 721 ), 722 ], 723 { 724 code: 'Sr', 725 isOverlay: true, 726 isOverlayTransparent: true, 727 scaleDependent: false, 728 print: true, 729 jnx: false, 730 subdomains: 'abc', 731 noCors: true, 732 shortName: 'strava_run', 733 retinaOptionsOverrides: [{maxNativeZoom: 16}, {maxNativeZoom: 15}], 734 attribution: '<a href="https://www.strava.com/heatmap">Strava Global Heatmap</a>', 735 opacity: 0.75, 736 } 737 ) 738 }, 739 { 740 title: 'Strava heatmap (ride)', 741 isDefault: false, 742 layer: new RetinaTileLayer( 743 [ 744 urlViaCorsProxy( 745 'https://heatmap-external-a.strava.com/tiles-auth/ride/hot/{z}/{x}/{y}.png?px=256' 746 ), 747 urlViaCorsProxy( 748 'https://heatmap-external-a.strava.com/tiles-auth/ride/hot/{z}/{x}/{y}.png?px=512' 749 ), 750 ], 751 { 752 code: 'Sb', 753 isOverlay: true, 754 isOverlayTransparent: true, 755 scaleDependent: false, 756 print: true, 757 jnx: false, 758 subdomains: 'abc', 759 noCors: true, 760 shortName: 'strava_ride', 761 retinaOptionsOverrides: [{maxNativeZoom: 16}, {maxNativeZoom: 15}], 762 attribution: '<a href="https://www.strava.com/heatmap">Strava Global Heatmap</a>', 763 opacity: 0.75, 764 } 765 ) 766 }, 767 { 768 title: 'Strava heatmap (winter)', 769 isDefault: false, 770 layer: new RetinaTileLayer( 771 [ 772 urlViaCorsProxy( 773 'https://heatmap-external-a.strava.com/tiles-auth/winter/hot/{z}/{x}/{y}.png?px=256' 774 ), 775 urlViaCorsProxy( 776 'https://heatmap-external-a.strava.com/tiles-auth/winter/hot/{z}/{x}/{y}.png?px=512' 777 ), 778 ], 779 { 780 code: 'Sw', 781 isOverlay: true, 782 isOverlayTransparent: true, 783 scaleDependent: false, 784 print: true, 785 jnx: false, 786 subdomains: 'abc', 787 noCors: true, 788 shortName: 'strava_winter', 789 retinaOptionsOverrides: [{maxNativeZoom: 16}, {maxNativeZoom: 15}], 790 attribution: '<a href="https://www.strava.com/heatmap">Strava Global Heatmap</a>', 791 opacity: 0.75, 792 } 793 ) 794 }, 795 { 796 title: 'Norway paper map', 797 isDefault: false, 798 layer: new L.TileLayer( 799 'https://opencache.statkart.no/gatekeeper/gk/gk.open_gmaps?layers=toporaster4&zoom={z}&x={x}&y={y}', // eslint-disable-line max-len 800 { 801 code: 'Np', 802 isOverlay: true, 803 isOverlayTransparent: false, 804 maxNativeZoom: 16, 805 tms: false, 806 print: true, 807 jnx: true, 808 scaleDependent: true, 809 noCors: false, 810 shortName: 'norway_paper', 811 bounds: [[57.81324, 4.19674], [71.27961, 31.56094]], 812 attribution: '<a href="https://www.geonorge.no/aktuelt/om-geonorge/brukerveiledning' + 813 '/#!#se_paa_kart">Geonorge</a>', 814 } 815 ) 816 }, 817 { 818 title: 'Norway topo', 819 isDefault: false, 820 layer: new L.TileLayer( 821 'https://opencache.statkart.no/gatekeeper/gk/gk.open_gmaps?layers=topo4&zoom={z}&x={x}&y={y}', 822 { 823 code: 'Nm', 824 isOverlay: true, 825 isOverlayTransparent: false, 826 tms: false, 827 print: true, 828 jnx: true, 829 scaleDependent: true, 830 noCors: false, 831 shortName: 'norway_topo', 832 bounds: [[57.81324, 4.19674], [71.27961, 31.56094]], 833 attribution: '<a href="https://www.geonorge.no/aktuelt/om-geonorge/brukerveiledning' + 834 '/#!#se_paa_kart">Geonorge</a>', 835 } 836 ) 837 }, 838 { 839 // Вместо 404 отдают 500 для отсутствующих тайлов 840 title: 'Norway roads', 841 description: '<a href="https://kart.finn.no/">https://kart.finn.no/</a>', 842 isDefault: false, 843 layer: L.tileLayer("https://maptiles1.finncdn.no/tileService/1.0.3/normap/{z}/{x}/{y}.png", 844 { 845 code: 'Nr', 846 isOverlay: true, 847 isOverlayTransparent: false, 848 tms: false, 849 print: true, 850 jnx: true, 851 scaleDependent: true, 852 noCors: false, 853 shortName: 'norway_roads', 854 bounds: [[57.81324, 4.19674], [71.27961, 31.56094]], 855 cutline: getCutline('norway'), 856 attribution: '<a href="https://kart.finn.no/">finn.no</a>', 857 } 858 ) 859 }, 860 { 861 title: 'Czech base', 862 isDefault: false, 863 layer: new RetinaTileLayer( 864 [ 865 'https://m{s}.mapserver.mapy.cz/base-m/{z}-{x}-{y}', 866 'https://m{s}.mapserver.mapy.cz/base-m/retina/{z}-{x}-{y}' 867 ], 868 { 869 code: 'Czb', 870 isOverlay: false, 871 tms: false, 872 print: true, 873 jnx: true, 874 subdomains: '1234', 875 scaleDependent: true, 876 shortName: 'czech', 877 attribution: '<a href="https://mapy.cz/zakladni">mapy.cz base map</a>', 878 } 879 ) 880 }, 881 { 882 title: 'mapy.cz tourist', 883 isDefault: true, 884 layer: new RetinaTileLayer( 885 [ 886 'https://m{s}.mapserver.mapy.cz/turist-m/{z}-{x}-{y}', 887 'https://m{s}.mapserver.mapy.cz/turist-m/retina/{z}-{x}-{y}', 888 ], 889 { 890 code: 'Czt', 891 isOverlay: false, 892 tms: false, 893 print: true, 894 jnx: true, 895 subdomains: '1234', 896 scaleDependent: true, 897 shortName: 'czech_tourist', 898 hotkey: 'H', 899 attribution: '<a href="https://mapy.cz/turisticka">mapy.cz outdoor map</a>', 900 } 901 ) 902 }, 903 { 904 title: 'Czech winter', 905 isDefault: false, 906 layer: new RetinaTileLayer( 907 [ 908 'https://m{s}.mapserver.mapy.cz/winter-m/{z}-{x}-{y}', 909 'https://m{s}.mapserver.mapy.cz/winter-m/retina/{z}-{x}-{y}', 910 ], 911 { 912 code: 'Czw', 913 isOverlay: false, 914 tms: false, 915 print: true, 916 jnx: true, 917 subdomains: '1234', 918 scaleDependent: true, 919 shortName: 'czech_winter', 920 attribution: '<a href="https://mapy.cz/zimni">mapy.cz winter map</a>', 921 } 922 ) 923 }, 924 { 925 title: 'Finland Topo', 926 description: '<a href="https://www.retkikartta.fi/?lang=en">https://www.retkikartta.fi/</a>', 927 isDefault: false, 928 layer: L.tileLayer( 929 "https://maps-mml.anderscloud.com/wmts/?" + 930 "ngsw-bypass=1&layer=maastokartta&style=default&tilematrixset=WGS84_Pseudo-Mercator" + 931 "&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image%2Fpng" + 932 "&TileMatrix={z}&TileCol={x}&TileRow={y}", 933 { 934 code: 'Fmk', 935 isOverlay: true, 936 isOverlayTransparent: false, 937 tms: false, 938 print: true, 939 jnx: true, 940 scaleDependent: true, 941 noCors: true, 942 shortName: 'finland_topo', 943 bound: [[59.45416, 19.08321], [70.09211, 31.58671]], 944 cutline: getCutline('finland'), 945 cutlineApprox: true, 946 attribution: '<a href="https://www.retkikartta.fi/">Retkikartta.fi</a>', 947 } 948 ) 949 }, 950 { 951 title: 'France Topo 250m', 952 isDefault: false, 953 layer: new LayerGroupWithOptions( 954 [ 955 L.tileLayer( 956 'https://wxs.ign.fr/an7nvfzojv5wa96dsga5nk8w/geoportail/wmts?' + 957 'layer=GEOGRAPHICALGRIDSYSTEMS.MAPS.SCAN25TOUR.CV&style=normal&tilematrixset=PM&' + 958 'Service=WMTS&Request=GetTile&Version=1.0.0&Format=image%2Fjpeg&' + 959 'TileMatrix={z}&TileCol={x}&TileRow={y}', 960 { 961 minZoom: 6, 962 maxNativeZoom: 16, 963 bounds: [ 964 [-46.44072, -178.18694], 965 [51.12562, 77.61086], 966 ], 967 isOverlay: true, 968 isOverlayTransparent: false, 969 tms: false, 970 print: true, 971 jnx: true, 972 scaleDependent: false, 973 shortName: 'france_topo_25k', 974 cutline: getCutline('france'), 975 attribution: '<a href="https://www.geoportail.gouv.fr/carte">' + 976 'IGN (France) topographic map</a>', 977 } 978 ), 979 new LayerCutlineOverview(getCutline('france'), 5, 'France Topo 250m (zoom ≥ 6)'), 980 ], 981 { 982 code: 'Ft', 983 isOverlay: true, 984 isWrapper: true, 985 } 986 ), 987 }, 988 { 989 title: 'Great Britain Topo', 990 isDefault: false, 991 layer: new LayerGroupWithOptions( 992 [ 993 new BingLayer(config.bingKey, { 994 type: 'OrdnanceSurvey', 995 minZoom: 12, 996 maxNativeZoom: 16, 997 bounds: [ 998 [49.83793, -7.75643], 999 [60.87164, 1.82356], 1000 ], 1001 isOverlay: true, 1002 isOverlayTransparent: false, 1003 scaleDependent: true, 1004 print: true, 1005 jnx: true, 1006 shortName: 'england_topo', 1007 cutline: getCutline('great_britain'), 1008 attribution: '<a href="https://docs.microsoft.com/en-us/bingmaps/v8-web-control/' + 1009 'map-control-api/maptypeid-enumeration">Ordnance Survey</a>', 1010 }), 1011 new LayerCutlineOverview(getCutline('great_britain'), 11, 'Great Britain Topo (zoom ≥ 12)'), 1012 ], 1013 { 1014 code: 'Gbt', 1015 isOverlay: true, 1016 isWrapper: true, 1017 } 1018 ), 1019 }, 1020 { 1021 title: 'Waymarked Cycling Trails', 1022 description: 1023 '<a href="https://cycling.waymarkedtrails.org/">https://cycling.waymarkedtrails.org</a>', 1024 isDefault: false, 1025 layer: L.tileLayer('https://tile.waymarkedtrails.org/cycling/{z}/{x}/{y}.png', 1026 { 1027 code: 'Wc', 1028 isOverlay: true, 1029 tms: false, 1030 print: true, 1031 jnx: false, 1032 scaleDependent: true, 1033 shortName: 'cycling_trails', 1034 isOverlayTransparent: true, 1035 attribution: '<a href="https://cycling.waymarkedtrails.org/">Waymarked Cycling Trails</a>', 1036 }) 1037 }, 1038 { 1039 title: 'Waymarked Hiking Trails', 1040 description: '<a href="https://hiking.waymarkedtrails.org/">https://hiking.waymarkedtrails.org</a>', 1041 isDefault: false, 1042 layer: L.tileLayer('https://tile.waymarkedtrails.org/hiking/{z}/{x}/{y}.png', 1043 { 1044 code: 'Wh', 1045 isOverlay: true, 1046 tms: false, 1047 print: true, 1048 jnx: false, 1049 scaleDependent: true, 1050 shortName: 'hiking_trails', 1051 isOverlayTransparent: true, 1052 attribution: '<a href="https://hiking.waymarkedtrails.org/">Waymarked Hiking Trails</a>', 1053 }) 1054 }, 1055 { 1056 title: 'Slovakia topo', 1057 description: '<a href="https://mapy.hiking.sk">https://mapy.hiking.sk/</a>', 1058 isDefault: false, 1059 layer: new LayerGroupWithOptions( 1060 [ 1061 L.tileLayer('https://static.mapy.hiking.sk/topo/{z}/{x}/{y}.png', { 1062 isOverlay: true, 1063 tms: false, 1064 print: true, 1065 jnx: true, 1066 scaleDependent: true, 1067 shortName: 'slovakia_topo', 1068 isOverlayTransparent: false, 1069 maxNativeZoom: 15, 1070 minZoom: 10, 1071 bounds: [ 1072 [47.5172, 16.74316], 1073 [49.91343, 22.74837], 1074 ], 1075 noCors: true, 1076 cutline: getCutline('slovakia'), 1077 attribution: '<a href="https://mapy.hiking.sk/">mapy.hiking.sk</a>', 1078 }), 1079 new LayerCutlineOverview(getCutline('slovakia'), 9, 'Slovakia topo (zoom ≥ 10)'), 1080 ], 1081 { 1082 code: 'St', 1083 isOverlay: true, 1084 isWrapper: true, 1085 } 1086 ), 1087 }, 1088 { 1089 title: 'Yandex tracks (zoom ≥ 10)', 1090 isDefault: false, 1091 layer: new L.Layer.Yandex.Tracks( 1092 { 1093 scaleDependent: true, 1094 code: 'Ytr', 1095 isOverlay: true, 1096 isOverlayTransparent: true, 1097 print: true, 1098 jnx: false, 1099 shortName: 'yandex_tracks', 1100 noCors: true, 1101 attribution: '<a href="https://n.maps.yandex.ru/">Yandex Map Editor</a>', 1102 } 1103 ) 1104 }, 1105 { 1106 title: 'Spain topo', 1107 isDefault: false, 1108 layer: L.tileLayer( 1109 'https://www.ign.es/wmts/mapa-raster?layer=MTN&style=default&' + 1110 'tilematrixset=GoogleMapsCompatible&Service=WMTS&Request=GetTile&Version=1.0.0&' + 1111 'Format=image%2Fjpeg&TileMatrix={z}&TileCol={x}&TileRow={y}', 1112 { 1113 code: 'Sp', 1114 isOverlay: true, 1115 tms: false, 1116 print: true, 1117 jnx: true, 1118 scaleDependent: true, 1119 shortName: 'spain_topo', 1120 isOverlayTransparent: false, 1121 bounds: [[35.9024, -9.51828], [43.8375, 4.50439]], 1122 noCors: false, 1123 cutline: getCutline('spain'), 1124 attribution: '<a href="https://www.ign.es/iberpix2/visor/">' + 1125 'IGN (Spain) topographic map</a>' 1126 } 1127 ) 1128 }, 1129 { 1130 title: 'Switzerland topo', 1131 isDefault: false, 1132 layer: new RetinaTileLayer( 1133 [ 1134 null, 1135 urlViaCorsProxy( 1136 'https:///wmts10.geo.admin.ch/1.0.0/ch.swisstopo.pixelkarte-farbe/default/current/' + 1137 '3857/{z}/{x}/{y}.jpeg' 1138 ), 1139 ], 1140 1141 { 1142 code: 'Si', 1143 isOverlay: true, 1144 tms: false, 1145 print: true, 1146 jnx: true, 1147 scaleDependent: true, 1148 shortName: 'swiss_topo', 1149 isOverlayTransparent: false, 1150 bounds: [[45.80269, 5.87352], [47.86445, 10.6847]], 1151 noCors: false, 1152 maxNativeZoom: 16, 1153 tileSize: 128, 1154 zoomOffset: 1, 1155 cutline: getCutline('switzerland'), 1156 attribution: '<a href="https://map.geo.admin.ch/?topic=swisstopo&lang=en&bgLayer=' + 1157 'ch.swisstopo.pixelkarte-farbe&E=2586000.76&N=1202020.96&zoom=1">Swisstopo' 1158 }, true 1159 ) 1160 }, 1161 ]; 1162 1163 const groupsDefs = [ 1164 { 1165 title: 'Default layers', 1166 layers: [ 1167 'OpenStreetMap', 1168 'ESRI Satellite', 1169 'Yandex map', 1170 'Yandex Satellite', 1171 'Google Map', 1172 'Google Satellite', 1173 'Google Terrain', 1174 'Bing Satellite', 1175 'marshruty.ru', 1176 'Topomapper 1km', 1177 'Topo 10km', 1178 'GGC 2 km', 1179 'ArbaletMO', 1180 'Mountains by Aleksey Tsvetkov', 1181 'Slazav mountains', 1182 'GGC 1km', 1183 'Topo 1km', 1184 'GGC 500m', 1185 'Topo 500m', 1186 'GGC 250m', 1187 'Slazav Moscow region map', 1188 'Races', 1189 'O-sport', 1190 'Soviet topo maps grid', 1191 'Wikimapia', 1192 'Mountain passes (Westra)' 1193 ], 1194 }, 1195 { 1196 title: 'OpenStreetMap alternatives', 1197 layers: [ 1198 'OpenTopoMap', 1199 'OpenCycleMap', 1200 'OSM Outdoors' 1201 ], 1202 }, 1203 { 1204 title: 'Topo maps', 1205 layers: [ 1206 'Eurasia 25km', 1207 'Caucasus 1km', 1208 'Caucasus 500m', 1209 'Topo 250m', 1210 'Montenegro topo 250m', 1211 'Finland Topo', 1212 'France Topo 250m', 1213 'Great Britain Topo', 1214 'Slovakia topo', 1215 'Spain topo', 1216 'Switzerland topo', 1217 ], 1218 }, 1219 { 1220 title: 'Miscellaneous', 1221 layers: [ 1222 'Google Hybrid', 1223 'Bing imagery acquisition dates', 1224 'geocaching.su' 1225 ] 1226 }, 1227 { 1228 title: 'Routes and traces', 1229 layers: [ 1230 'Waymarked Hiking Trails', 1231 'Waymarked Cycling Trails', 1232 'OpenStreetMap GPS traces', 1233 'Strava heatmap (all)', 1234 'Strava heatmap (run)', 1235 'Strava heatmap (ride)', 1236 'Strava heatmap (winter)', 1237 'Yandex tracks (zoom ≥ 10)', 1238 ], 1239 1240 }, 1241 { 1242 title: 'Norway <a href="https://www.ut.no/kart/">https://www.ut.no/kart/</a>', 1243 layers: [ 1244 'Norway paper map', 1245 'Norway topo', 1246 'Norway roads' 1247 ], 1248 1249 }, 1250 { 1251 title: 'Czech <a href="https://mapy.cz">https://mapy.cz</a>', 1252 layers: [ 1253 'Czech base', 1254 'mapy.cz tourist', 1255 'Czech winter' 1256 ], 1257 }, 1258 ]; 1259 1260 const titlesByOrder = [ 1261 // common base layers 1262 // OSM 1263 'OpenStreetMap', 1264 'OpenTopoMap', 1265 'OpenCycleMap', 1266 'OSM Outdoors', 1267 'mapy.cz tourist', 1268 // Satellite 1269 'ESRI Satellite', 1270 'Yandex Satellite', 1271 'Google Satellite', 1272 'Bing Satellite', 1273 // Commercial maps 1274 'Yandex map', 1275 'Google Map', 1276 'Google Terrain', 1277 // Topo maps 1278 'marshruty.ru', 1279 'Topomapper 1km', 1280 1281 // local base layers 1282 'Czech base', 1283 'Czech winter', 1284 1285 // map overlays 1286 '#custom-bottom', 1287 'Eurasia 25km', 1288 'Topo 10km', 1289 'GGC 2 km', 1290 'ArbaletMO', 1291 'Norway roads', 1292 'Norway paper map', 1293 'Norway topo', 1294 'Finland Topo', 1295 'Slovakia topo', 1296 'Spain topo', 1297 'Mountains by Aleksey Tsvetkov', 1298 'Slazav mountains', 1299 'GGC 1km', 1300 'Topo 1km', 1301 'Caucasus 1km', 1302 'Great Britain Topo', 1303 'GGC 500m', 1304 'Topo 500m', 1305 'Caucasus 500m', 1306 'GGC 250m', 1307 'Topo 250m', 1308 'Montenegro topo 250m', 1309 'France Topo 250m', 1310 'Switzerland topo', 1311 'Slazav Moscow region map', 1312 'Races', 1313 'O-sport', 1314 '#custom-top', 1315 1316 // line overlays 1317 'Google Hybrid', 1318 'Waymarked Hiking Trails', 1319 'Waymarked Cycling Trails', 1320 'Bing imagery acquisition dates', 1321 'OpenStreetMap GPS traces', 1322 'Strava heatmap (all)', 1323 'Strava heatmap (run)', 1324 'Strava heatmap (ride)', 1325 'Strava heatmap (winter)', 1326 'Yandex tracks (zoom ≥ 10)', 1327 'Soviet topo maps grid', 1328 'Wikimapia', 1329 1330 // point overlays 1331 'Mountain passes (Westra)', 1332 'geocaching.su', 1333 ]; 1334 1335 function getLayers() { 1336 // set metadata 1337 for (let layer of layersDefs) { 1338 layer.layer.meta = {title: layer.title}; 1339 } 1340 1341 // assign order to layers 1342 const orderByTitle = {}; 1343 for (let i = 0; i < titlesByOrder.length; i++) { 1344 let title = titlesByOrder[i]; 1345 orderByTitle[title] = i + 1; 1346 } 1347 1348 for (let layer of layersDefs) { 1349 const title = layer.title; 1350 layer.order = orderByTitle[title]; 1351 if (!layer.order) { 1352 throw new Error(`Layer title not found in titlesByOrder list: ${title}`); 1353 } 1354 } 1355 1356 // divide layers by groups 1357 const grouppedLayers = []; 1358 const layersByTitle = {}; 1359 for (let layer of layersDefs) { 1360 layersByTitle[layer.title] = layer; 1361 } 1362 for (let groupDef of groupsDefs) { 1363 let group = {group: groupDef.title, layers: []}; 1364 grouppedLayers.push(group); 1365 for (let title of groupDef.layers) { 1366 let layer = layersByTitle[title]; 1367 group.layers.push(layer); 1368 } 1369 } 1370 1371 return { 1372 layers: grouppedLayers, 1373 customLayersOrder: { 1374 top: orderByTitle['#custom-top'], 1375 bottom: orderByTitle['#custom-bottom'], 1376 1377 } 1378 }; 1379 } 1380 1381 export {getLayers, layersDefs, groupsDefs, titlesByOrder};