layers.js (55744B)
1 import L from "leaflet"; 2 import '~/lib/leaflet.layer.yandex'; 3 import '~/lib/leaflet.layer.google'; 4 import {BingSatLayer, BingOrdnanceSurveyLayer} from '~/lib/leaflet.layer.bing'; 5 import config from './config'; 6 import '~/lib/leaflet.layer.soviet-topomaps-grid'; 7 import '~/lib/leaflet.layer.westraPasses'; 8 import '~/lib/leaflet.layer.wikimapia'; 9 import {GeocachingSu} from '~/lib/leaflet.layer.geocaching-su'; 10 import {RetinaTileLayer} from '~/lib/leaflet.layer.RetinaTileLayer'; 11 import {urlViaCorsProxy} from '~/lib/CORSProxy'; 12 import '~/lib/leaflet.layer.TileLayer.cutline'; 13 import {getCutline} from '~/lib/layers-cutlines'; 14 import {LayerCutlineOverview} from '~/lib/leaflet.layer.LayerCutlineOverview'; 15 16 class LayerGroupWithOptions extends L.LayerGroup { 17 constructor(layers, options) { 18 super(layers); 19 L.setOptions(this, options); 20 } 21 } 22 23 const layersDefs = [ 24 { 25 title: 'OpenStreetMap', 26 isDefault: true, 27 layer: L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', 28 { 29 code: 'O', 30 isOverlay: false, 31 scaleDependent: true, 32 print: true, 33 jnx: true, 34 shortName: 'osm', 35 attribution: '<a href="https://www.openstreetmap.org/copyright">' + 36 '© OpenStreetMap contributors</a>', 37 } 38 ) 39 }, 40 { 41 title: 'CyclOSM', 42 isDefault: true, 43 layer: L.tileLayer('https://{s}.tile-cyclosm.openstreetmap.fr/cyclosm/{z}/{x}/{y}.png', 44 { 45 code: 'Co', 46 isOverlay: false, 47 scaleDependent: true, 48 print: true, 49 jnx: true, 50 shortName: 'cyclosm', 51 attribution: 52 '<a href="https://www.openstreetmap.org/copyright">' + 53 '© OpenStreetMap contributors</a>. ' + 54 'Tiles style by <a href="https://www.cyclosm.org/">CyclOSM</a>', 55 } 56 ) 57 }, 58 { 59 title: 'ESRI Satellite', 60 isDefault: true, 61 layer: L.tileLayer( 62 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', 63 { 64 code: 'E', 65 isOverlay: false, 66 scaleDependent: false, 67 maxNativeZoom: 18, 68 print: true, 69 jnx: true, 70 shortName: 'esri', 71 attribution: 72 '<a href="https://www.arcgis.com/home/item.html?id=10df2279f9684e4a9f6a7f08febac2a9">' + 73 'ESRI World Imagery for ArcGIS</a>', 74 } 75 ) 76 }, 77 { 78 title: 'Yandex map', 79 isDefault: true, 80 layer: new L.Layer.Yandex.Map( 81 { 82 scaleDependent: true, 83 code: 'Y', 84 isOverlay: false, 85 print: true, 86 jnx: true, 87 shortName: 'yandex', 88 attribution: '<a href="https://yandex.ru/maps/">Yandex</a>', 89 } 90 ) 91 }, 92 { 93 title: 'Yandex Satellite', 94 isDefault: true, 95 layer: new L.Layer.Yandex.Sat( 96 { 97 scaleDependent: false, 98 code: 'S', 99 isOverlay: false, 100 print: true, 101 jnx: true, 102 shortName: 'yandex_sat', 103 attribution: '<a href="https://yandex.ru/maps/?l=sat">Yandex</a>', 104 } 105 ) 106 }, 107 { 108 title: 'Google Map', 109 isDefault: true, 110 layer: new L.Layer.GoogleMap( 111 { 112 code: 'G', 113 isOverlay: false, 114 scaleDependent: true, 115 print: true, 116 jnx: true, 117 shortName: 'google', 118 attribution: '<a href="https://www.google.com/maps">Google</a>', 119 } 120 ) 121 }, 122 { 123 title: 'Google Hybrid', 124 isDefault: false, 125 layer: new L.Layer.GoogleHybrid( 126 { 127 code: 'Gh', 128 isOverlay: true, 129 scaleDependent: true, 130 print: true, 131 jnx: false, 132 shortName: 'google_hybrid', 133 isOverlayTransparent: true, 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 Satellite', 141 isDefault: true, 142 layer: new L.Layer.GoogleSat( 143 { 144 code: 'L', 145 isOverlay: false, 146 scaleDependent: false, 147 print: true, 148 jnx: true, 149 shortName: 'google_sat', 150 attribution: '<a href="https://www.google.com/maps/@43.0668619,60.5738071,13622628m' + 151 '/data=!3m1!1e3">Google</a>', 152 } 153 ) 154 }, 155 { 156 title: 'Google Terrain', 157 isDefault: true, 158 layer: new L.Layer.GoogleTerrain({ 159 code: 'P', 160 isOverlay: false, 161 scaleDependent: false, 162 print: true, 163 jnx: true, 164 shortName: 'google_terrain', 165 attribution: '<a href="https://www.google.com/maps/@43.1203575,42.1105049,9.58z' + 166 '/data=!5m1!1e4">Google</a>', 167 } 168 ) 169 }, 170 { 171 title: 'Bing Satellite', 172 isDefault: true, 173 layer: new BingSatLayer( 174 { 175 code: 'I', 176 isOverlay: false, 177 scaleDependent: false, 178 print: true, 179 jnx: true, 180 shortName: 'bing_sat', 181 attribution: '<a href="https://www.bing.com/maps?style=h">Microsoft</a>', 182 } 183 ) 184 }, 185 { 186 title: 'Soviet topo maps (AtloMaps)', 187 isDefault: true, 188 layer: L.tileLayer( 189 urlViaCorsProxy( 190 'https://extern.atlogis.com/rtm/{z}/{x}/{y}' 191 ), 192 { 193 code: 'T', 194 isOverlay: false, 195 scaleDependent: false, 196 maxNativeZoom: 13, 197 noCors: false, 198 print: true, 199 jnx: true, 200 shortName: 'soviet_topo', 201 attribution: 202 '<a href="https://play.google.com/store/apps/details?id=com.atlogis.atlomaps">' + 203 'AtloMaps</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: 10, 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: 15, 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 isDefault: false, 480 layer: new RetinaTileLayer( 481 [ 482 'https://{s}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png', 483 'https://{s}.tile.thunderforest.com/cycle/{z}/{x}/{y}@2x.png', 484 ], 485 { 486 code: 'Ocm', 487 isOverlay: false, 488 scaleDependent: true, 489 print: true, 490 jnx: true, 491 shortName: 'opencyclemap', 492 attribution: '<a href="https://www.opencyclemap.org/">Thunderforest OpenCycleMap</a>', 493 } 494 ) 495 }, 496 { 497 title: 'OSM Outdoors', 498 isDefault: false, 499 layer: new RetinaTileLayer( 500 [ 501 'https://{s}.tile.thunderforest.com/outdoors/{z}/{x}/{y}.png', 502 'https://{s}.tile.thunderforest.com/outdoors/{z}/{x}/{y}@2x.png', 503 ], 504 { 505 code: 'Oso', 506 isOverlay: false, 507 scaleDependent: true, 508 print: true, 509 jnx: true, 510 shortName: 'osm_outdoors', 511 attribution: 512 '<a href="https://www.thunderforest.com/maps/outdoors/">Thunderforest Outdoors</a>', 513 } 514 ) 515 }, 516 { 517 title: 'Eurasia 25km', 518 // description: '1975-80', 519 isDefault: false, 520 layer: L.tileLayer("https://{s}.tiles.nakarte.me/eurasia25km/{z}/{x}/{y}", 521 { 522 code: 'E25m', 523 isOverlay: true, 524 isOverlayTransparent: false, 525 tms: true, 526 maxNativeZoom: 9, 527 print: true, 528 jnx: true, 529 scaleDependent: false, 530 shortName: 'eurasia_25k' 531 } 532 ) 533 }, 534 { 535 title: 'Caucasus 1km', 536 isDefault: false, 537 layer: L.tileLayer("https://{s}.tiles.nakarte.me/new_gsh_100k/{z}/{x}/{y}", 538 { 539 code: 'NT1', 540 isOverlay: true, 541 isOverlayTransparent: false, 542 tms: true, 543 maxNativeZoom: 14, 544 print: true, 545 jnx: true, 546 scaleDependent: false, 547 shortName: 'caucasus_1k', 548 attribution: '<a href="http://genshtab-yuga.narod.ru/">Topo maps (2006)</a>', 549 } 550 ) 551 }, 552 { 553 title: 'Caucasus 500m', 554 isDefault: false, 555 layer: L.tileLayer("https://{s}.tiles.nakarte.me/new_gsh_050k/{z}/{x}/{y}", 556 { 557 code: 'NT5', 558 isOverlay: true, 559 isOverlayTransparent: false, 560 tms: true, 561 maxNativeZoom: 15, 562 print: true, 563 jnx: true, 564 scaleDependent: false, 565 shortName: 'caucasus_500', 566 attribution: '<a href="http://genshtab-yuga.narod.ru/">Topo maps (1998 - 2003)</a>', 567 } 568 ) 569 }, 570 { 571 title: 'Topo 250m', 572 isDefault: false, 573 layer: L.tileLayer("https://{s}.tiles.nakarte.me/topo250/{z}/{x}/{y}", 574 { 575 code: 'T25', 576 isOverlay: true, 577 isOverlayTransparent: false, 578 tms: true, 579 maxNativeZoom: 15, 580 print: true, 581 jnx: true, 582 scaleDependent: false, 583 shortName: 'topo_250' 584 } 585 ) 586 }, 587 { 588 title: 'Montenegro topo 250m', 589 // description: '1970-72', 590 isDefault: false, 591 layer: L.tileLayer("https://{s}.tiles.nakarte.me/montenegro250m/{z}/{x}/{y}", 592 { 593 code: 'MN25', 594 isOverlay: true, 595 isOverlayTransparent: false, 596 tms: true, 597 maxNativeZoom: 15, 598 print: true, 599 jnx: true, 600 scaleDependent: false, 601 shortName: 'montenegro_250' 602 } 603 ) 604 }, 605 { 606 title: 'Mountains by Aleksey Tsvetkov', 607 isDefault: true, 608 layer: new LayerGroupWithOptions( 609 [ 610 L.tileLayer( 611 urlViaCorsProxy( 612 'https://maptiles.website.yandexcloud.net/{z}/{x}/{y}.png' 613 ), 614 { 615 isOverlay: true, 616 isOverlayTransparent: false, 617 tms: false, 618 minZoom: 2, 619 maxNativeZoom: 15, 620 print: true, 621 jnx: true, 622 scaleDependent: false, 623 noCors: false, 624 shortName: 'tsvetkov_mountains', 625 cutline: getCutline('tsvetkov_mountains'), 626 bounds: [ 627 [40.66664, 71.00007], 628 [45.33338, 81.00001], 629 ], 630 attribution: '<a href="http://pereval.g-utka.ru/">Aleksey Tsvetkov</a>', 631 } 632 ), 633 new LayerCutlineOverview(getCutline('tsvetkov_mountains'), 6, 634 'Mountains by Aleksey Tsvetkov'), 635 ], 636 { 637 code: 'Mt', 638 isOverlay: true, 639 isWrapper: true, 640 } 641 ), 642 }, 643 { 644 title: 'geocaching.su', 645 isDefault: false, 646 layer: new GeocachingSu(config.geocachingSuUrl, { 647 code: 'Gc', 648 isOverlay: true, 649 isOverlayTransparent: true, 650 print: true, 651 jnx: false, 652 shortName: 'geocaching', 653 attribution: '<a href="https://geocaching.su/">geocaching.su</a>', 654 }) 655 }, 656 { 657 title: 'OpenStreetMap GPS traces', 658 isDefault: false, 659 layer: L.tileLayer('https://{s}.gps-tile.openstreetmap.org/lines/{z}/{x}/{y}.png', 660 { 661 code: 'Ot', 662 isOverlay: true, 663 isOverlayTransparent: true, 664 scaleDependent: true, 665 print: true, 666 jnx: false, 667 shortName: 'osm_gps_traces', 668 attribution: '<a href="https://www.openstreetmap.org/#&layers=G">' + 669 'OpenStreetMap public GPS traces</a>', 670 } 671 ) 672 }, 673 { 674 title: 'Strava heatmap (all)', 675 isDefault: false, 676 layer: new RetinaTileLayer( 677 [ 678 urlViaCorsProxy( 679 'https://content-a.strava.com/identified/globalheat/all/hot/{z}/{x}/{y}.png?px=256' 680 ), 681 urlViaCorsProxy( 682 'https://content-a.strava.com/identified/globalheat/all/hot/{z}/{x}/{y}.png?px=512' 683 ), 684 ], 685 { 686 code: 'Sa', 687 isOverlay: true, 688 isOverlayTransparent: true, 689 scaleDependent: false, 690 print: true, 691 jnx: false, 692 subdomains: 'abc', 693 noCors: false, 694 shortName: 'strava_all', 695 retinaOptionsOverrides: [{maxNativeZoom: 16}, {maxNativeZoom: 15}], 696 attribution: '<a href="https://www.strava.com/heatmap">Strava Global Heatmap</a>', 697 opacity: 0.75, 698 } 699 ) 700 }, 701 { 702 title: 'Strava heatmap (run)', 703 isDefault: false, 704 layer: new RetinaTileLayer( 705 [ 706 urlViaCorsProxy( 707 'https://content-a.strava.com/identified/globalheat/run/hot/{z}/{x}/{y}.png?px=256' 708 ), 709 urlViaCorsProxy( 710 'https://content-a.strava.com/identified/globalheat/run/hot/{z}/{x}/{y}.png?px=512' 711 ), 712 ], 713 { 714 code: 'Sr', 715 isOverlay: true, 716 isOverlayTransparent: true, 717 scaleDependent: false, 718 print: true, 719 jnx: false, 720 subdomains: 'abc', 721 noCors: false, 722 shortName: 'strava_run', 723 retinaOptionsOverrides: [{maxNativeZoom: 16}, {maxNativeZoom: 15}], 724 attribution: '<a href="https://www.strava.com/heatmap">Strava Global Heatmap</a>', 725 opacity: 0.75, 726 } 727 ) 728 }, 729 { 730 title: 'Strava heatmap (ride)', 731 isDefault: false, 732 layer: new RetinaTileLayer( 733 [ 734 urlViaCorsProxy( 735 'https://content-a.strava.com/identified/globalheat/ride/hot/{z}/{x}/{y}.png?px=256' 736 ), 737 urlViaCorsProxy( 738 'https://content-a.strava.com/identified/globalheat/ride/hot/{z}/{x}/{y}.png?px=512' 739 ), 740 ], 741 { 742 code: 'Sb', 743 isOverlay: true, 744 isOverlayTransparent: true, 745 scaleDependent: false, 746 print: true, 747 jnx: false, 748 subdomains: 'abc', 749 noCors: false, 750 shortName: 'strava_ride', 751 retinaOptionsOverrides: [{maxNativeZoom: 16}, {maxNativeZoom: 15}], 752 attribution: '<a href="https://www.strava.com/heatmap">Strava Global Heatmap</a>', 753 opacity: 0.75, 754 } 755 ) 756 }, 757 { 758 title: 'Strava heatmap (winter)', 759 isDefault: false, 760 layer: new RetinaTileLayer( 761 [ 762 urlViaCorsProxy( 763 'https://content-a.strava.com/identified/globalheat/winter/hot/{z}/{x}/{y}.png?px=256' 764 ), 765 urlViaCorsProxy( 766 'https://content-a.strava.com/identified/globalheat/winter/hot/{z}/{x}/{y}.png?px=512' 767 ), 768 ], 769 { 770 code: 'Sw', 771 isOverlay: true, 772 isOverlayTransparent: true, 773 scaleDependent: false, 774 print: true, 775 jnx: false, 776 subdomains: 'abc', 777 noCors: false, 778 shortName: 'strava_winter', 779 retinaOptionsOverrides: [{maxNativeZoom: 16}, {maxNativeZoom: 15}], 780 attribution: '<a href="https://www.strava.com/heatmap">Strava Global Heatmap</a>', 781 opacity: 0.75, 782 } 783 ) 784 }, 785 { 786 title: 'Norway paper map', 787 isDefault: false, 788 layer: new L.TileLayer( 789 'https://cache.kartverket.no/v1/wmts/1.0.0/toporaster/default/webmercator/{z}/{y}/{x}.png', 790 { 791 code: 'Np', 792 isOverlay: true, 793 isOverlayTransparent: false, 794 tms: false, 795 print: true, 796 jnx: true, 797 scaleDependent: true, 798 noCors: false, 799 shortName: 'norway_paper', 800 bounds: [[57.81324, 4.19674], [71.27961, 31.56094]], 801 attribution: '<a href="https://kartverket.no/til-lands/kart/turkart">Kartverket</a>', 802 } 803 ) 804 }, 805 { 806 title: 'Norway topo', 807 isDefault: false, 808 layer: new L.TileLayer( 809 'https://cache.kartverket.no/v1/wmts/1.0.0/topo/default/webmercator/{z}/{y}/{x}.png', 810 { 811 code: 'Nm', 812 isOverlay: true, 813 isOverlayTransparent: false, 814 tms: false, 815 print: true, 816 jnx: true, 817 scaleDependent: true, 818 noCors: false, 819 shortName: 'norway_topo', 820 bounds: [[57.81324, 4.19674], [71.27961, 31.56094]], 821 attribution: '<a href="https://kartverket.no/til-lands/kart/turkart">Kartverket</a>', 822 } 823 ) 824 }, 825 { 826 // Вместо 404 отдают 500 для отсутствующих тайлов 827 title: 'Norway roads', 828 isDefault: false, 829 layer: L.tileLayer("https://maptiles1.finncdn.no/tileService/1.0.3/normap/{z}/{x}/{y}.png", 830 { 831 code: 'Nr', 832 isOverlay: true, 833 isOverlayTransparent: false, 834 tms: false, 835 print: true, 836 jnx: true, 837 scaleDependent: true, 838 noCors: false, 839 shortName: 'norway_roads', 840 bounds: [[57.81324, 4.19674], [71.27961, 31.56094]], 841 cutline: getCutline('norway'), 842 attribution: '<a href="https://kart.finn.no/">finn.no</a>', 843 } 844 ) 845 }, 846 { 847 title: 'mapy.cz tourist (Out of order)', 848 isDefault: true, 849 layer: new RetinaTileLayer( 850 [ 851 'https://proxy.nakarte.me/mapy/turist-en/{z}-{x}-{y}', 852 'https://proxy.nakarte.me/mapy/turist-en/retina/{z}-{x}-{y}', 853 ], 854 { 855 code: 'Czt', 856 isOverlay: false, 857 tms: false, 858 print: true, 859 jnx: true, 860 scaleDependent: true, 861 shortName: 'czech_tourist', 862 hotkey: 'H', 863 attribution: '<a href="https://mapy.cz/turisticka">mapy.cz outdoor map</a>', 864 maxZoom: -1, 865 } 866 ) 867 }, 868 { 869 title: 'mapy.cz winter (Out of order)', 870 isDefault: false, 871 layer: new LayerGroupWithOptions([ 872 new L.TileLayer('https://proxy.nakarte.me/mapy/winter-en-down/{z}-{x}-{y}', { 873 tms: false, 874 print: true, 875 isOverlay: false, 876 jnx: true, 877 scaleDependent: true, 878 shortName: 'czech_winter', 879 }), 880 new L.TileLayer('https://proxy.nakarte.me/mapy/winter-en-up/{z}-{x}-{y}', { 881 tms: false, 882 print: true, 883 jnx: false, 884 isOverlay: true, 885 isOverlayTransparent: true, 886 scaleDependent: true, 887 }), 888 ], { 889 code: 'Czw', 890 isOverlay: false, 891 isWrapper: true, 892 attribution: '<a href="https://mapy.cz/zimni">mapy.cz winter map</a>', 893 maxZoom: -1, 894 }), 895 }, 896 { 897 title: 'Finland Topo', 898 isDefault: false, 899 layer: L.tileLayer( 900 "https://proxy.laji.fi/mml_wmts/maasto/wmts/1.0.0/maastokartta/default/WGS84_Pseudo-Mercator/" + 901 "{z}/{y}/{x}.png", 902 { 903 code: 'Fmk', 904 isOverlay: true, 905 isOverlayTransparent: false, 906 tms: false, 907 print: true, 908 jnx: true, 909 scaleDependent: true, 910 noCors: false, 911 shortName: 'finland_topo', 912 bound: [[59.45416, 19.08321], [70.09211, 31.58671]], 913 cutline: getCutline('finland'), 914 attribution: '<a href="https://laji.fi/en/map/">LAJI.FI</a>', 915 } 916 ) 917 }, 918 { 919 title: 'Great Britain Topo', 920 isDefault: false, 921 layer: new LayerGroupWithOptions( 922 [ 923 new BingOrdnanceSurveyLayer({ 924 minZoom: 12, 925 maxNativeZoom: 16, 926 bounds: [ 927 [49.83793, -7.75643], 928 [60.87164, 1.82356], 929 ], 930 isOverlay: true, 931 isOverlayTransparent: false, 932 scaleDependent: true, 933 print: true, 934 jnx: true, 935 shortName: 'england_topo', 936 cutline: getCutline('great_britain'), 937 attribution: '<a href="https://docs.microsoft.com/en-us/bingmaps/v8-web-control/' + 938 'map-control-api/maptypeid-enumeration">Ordnance Survey</a>', 939 }), 940 new LayerCutlineOverview(getCutline('great_britain'), 11, 'Great Britain Topo (zoom ≥ 12)'), 941 ], 942 { 943 code: 'Gbt', 944 isOverlay: true, 945 isWrapper: true, 946 } 947 ), 948 }, 949 { 950 title: 'Waymarked Cycling Trails', 951 isDefault: false, 952 layer: L.tileLayer('https://tile.waymarkedtrails.org/cycling/{z}/{x}/{y}.png', 953 { 954 code: 'Wc', 955 isOverlay: true, 956 tms: false, 957 print: true, 958 jnx: false, 959 scaleDependent: true, 960 shortName: 'cycling_trails', 961 isOverlayTransparent: true, 962 attribution: '<a href="https://cycling.waymarkedtrails.org/">Waymarked Cycling Trails</a>', 963 }) 964 }, 965 { 966 title: 'Waymarked Hiking Trails', 967 isDefault: false, 968 layer: L.tileLayer('https://tile.waymarkedtrails.org/hiking/{z}/{x}/{y}.png', 969 { 970 code: 'Wh', 971 isOverlay: true, 972 tms: false, 973 print: true, 974 jnx: false, 975 scaleDependent: true, 976 shortName: 'hiking_trails', 977 isOverlayTransparent: true, 978 attribution: '<a href="https://hiking.waymarkedtrails.org/">Waymarked Hiking Trails</a>', 979 }) 980 }, 981 { 982 title: 'Slovakia topo', 983 isDefault: false, 984 layer: new LayerGroupWithOptions( 985 [ 986 L.tileLayer('https://static.mapy.hiking.sk/topo/{z}/{x}/{y}.png', { 987 isOverlay: true, 988 tms: false, 989 print: true, 990 jnx: true, 991 scaleDependent: true, 992 shortName: 'slovakia_topo', 993 isOverlayTransparent: false, 994 maxNativeZoom: 15, 995 minZoom: 10, 996 bounds: [ 997 [47.5172, 16.74316], 998 [49.91343, 22.74837], 999 ], 1000 noCors: true, 1001 cutline: getCutline('slovakia'), 1002 attribution: '<a href="https://mapy.hiking.sk/">mapy.hiking.sk</a>', 1003 }), 1004 new LayerCutlineOverview(getCutline('slovakia'), 9, 'Slovakia topo (zoom ≥ 10)'), 1005 ], 1006 { 1007 code: 'St', 1008 isOverlay: true, 1009 isWrapper: true, 1010 } 1011 ), 1012 }, 1013 { 1014 title: 'Spain topo', 1015 isDefault: false, 1016 layer: L.tileLayer( 1017 'https://www.ign.es/wmts/mapa-raster?layer=MTN&style=default&' + 1018 'tilematrixset=GoogleMapsCompatible&Service=WMTS&Request=GetTile&Version=1.0.0&' + 1019 'Format=image%2Fjpeg&TileMatrix={z}&TileCol={x}&TileRow={y}', 1020 { 1021 code: 'Sp', 1022 isOverlay: true, 1023 tms: false, 1024 print: true, 1025 jnx: true, 1026 scaleDependent: true, 1027 shortName: 'spain_topo', 1028 isOverlayTransparent: false, 1029 minZoom: 1, 1030 bounds: [[35.9024, -9.51828], [43.8375, 4.50439]], 1031 noCors: false, 1032 cutline: getCutline('spain'), 1033 attribution: '<a href="https://www.ign.es/iberpix2/visor/">' + 1034 'IGN (Spain) topographic map</a>' 1035 } 1036 ) 1037 }, 1038 { 1039 title: 'Switzerland topo', 1040 isDefault: false, 1041 layer: new RetinaTileLayer( 1042 [ 1043 null, 1044 urlViaCorsProxy( 1045 'https:///wmts10.geo.admin.ch/1.0.0/ch.swisstopo.pixelkarte-farbe/default/current/' + 1046 '3857/{z}/{x}/{y}.jpeg' 1047 ), 1048 ], 1049 1050 { 1051 code: 'Si', 1052 isOverlay: true, 1053 tms: false, 1054 print: true, 1055 jnx: true, 1056 scaleDependent: true, 1057 shortName: 'swiss_topo', 1058 isOverlayTransparent: false, 1059 bounds: [[45.80269, 5.87352], [47.86445, 10.6847]], 1060 noCors: false, 1061 maxNativeZoom: 16, 1062 tileSize: 128, 1063 zoomOffset: 1, 1064 cutline: getCutline('switzerland'), 1065 attribution: '<a href="https://map.geo.admin.ch/?topic=swisstopo&lang=en&bgLayer=' + 1066 'ch.swisstopo.pixelkarte-farbe&E=2586000.76&N=1202020.96&zoom=1">Swisstopo' 1067 }, true 1068 ) 1069 }, 1070 { 1071 title: 'Mountains by Alexander Purikov', 1072 isDefault: false, 1073 layer: L.tileLayer("https://{s}.tiles.nakarte.me/purikov/{z}/{x}/{y}", 1074 { 1075 code: 'Pur', 1076 isOverlay: true, 1077 isOverlayTransparent: false, 1078 tms: true, 1079 scaleDependent: false, 1080 maxNativeZoom: 14, 1081 noCors: false, 1082 print: true, 1083 jnx: true, 1084 shortName: 'purikov_mountains', 1085 attribution: '<a href="https://westra.ru/reports/">Alexander Purikov</a>', 1086 } 1087 ) 1088 }, 1089 { 1090 title: 'Sweden topo', 1091 isDefault: false, 1092 layer: L.tileLayer( 1093 'https://minkarta.lantmateriet.se/map/topowebbcache' + 1094 '?layer=topowebb&style=default&tilematrixset=3857&Service=WMTS&Request=GetTile&Version=1.0.0' + 1095 '&Format=image%2Fpng&TileMatrix={z}&TileCol={x}&TileRow={y}', 1096 { 1097 code: 'Se', 1098 isOverlay: true, 1099 tms: false, 1100 print: true, 1101 jnx: true, 1102 scaleDependent: true, 1103 shortName: 'sweden_topo', 1104 isOverlayTransparent: false, 1105 minZoom: 0, 1106 maxNativeZoom: 17, 1107 bounds: [[55.13493, 10.58876], [69.07200, 24.18365]], 1108 noCors: false, 1109 cutline: getCutline('sweden'), 1110 attribution: '<a href="https://minkarta.lantmateriet.se/">' + 1111 'Lantmäteriet</a>' 1112 } 1113 ) 1114 }, 1115 1116 ]; 1117 1118 const groupsDefs = [ 1119 { 1120 title: 'Default layers', 1121 layers: [ 1122 'OpenStreetMap', 1123 'CyclOSM', 1124 'ESRI Satellite', 1125 'Yandex map', 1126 'Yandex Satellite', 1127 'Google Map', 1128 'Google Satellite', 1129 'Google Terrain', 1130 'Bing Satellite', 1131 'Soviet topo maps (AtloMaps)', 1132 'Topo 10km', 1133 'GGC 2 km', 1134 'ArbaletMO', 1135 'Mountains by Aleksey Tsvetkov', 1136 'Slazav mountains', 1137 'GGC 1km', 1138 'Topo 1km', 1139 'GGC 500m', 1140 'Topo 500m', 1141 'GGC 250m', 1142 'Slazav Moscow region map', 1143 'Races', 1144 'O-sport', 1145 'Soviet topo maps grid', 1146 'Wikimapia', 1147 'Mountain passes (Westra)' 1148 ], 1149 }, 1150 { 1151 title: 'OpenStreetMap alternatives', 1152 layers: [ 1153 'OpenTopoMap', 1154 'OpenCycleMap', 1155 'OSM Outdoors', 1156 'mapy.cz tourist (Out of order)', 1157 'mapy.cz winter (Out of order)', 1158 1159 ], 1160 }, 1161 { 1162 title: 'Topo maps', 1163 layers: [ 1164 'Eurasia 25km', 1165 'Caucasus 1km', 1166 'Caucasus 500m', 1167 'Topo 250m', 1168 'Montenegro topo 250m', 1169 'Finland Topo', 1170 'Sweden topo', 1171 'Great Britain Topo', 1172 'Slovakia topo', 1173 'Spain topo', 1174 'Switzerland topo', 1175 ], 1176 }, 1177 { 1178 title: 'Miscellaneous', 1179 layers: [ 1180 'Mountains by Alexander Purikov', 1181 'Google Hybrid', 1182 'geocaching.su' 1183 ] 1184 }, 1185 { 1186 title: 'Routes and traces', 1187 layers: [ 1188 'Waymarked Hiking Trails', 1189 'Waymarked Cycling Trails', 1190 'OpenStreetMap GPS traces', 1191 'Strava heatmap (all)', 1192 'Strava heatmap (run)', 1193 'Strava heatmap (ride)', 1194 'Strava heatmap (winter)', 1195 ], 1196 1197 }, 1198 { 1199 title: 'Norway', 1200 layers: [ 1201 'Norway paper map', 1202 'Norway topo', 1203 'Norway roads' 1204 ], 1205 1206 }, 1207 ]; 1208 1209 const titlesByOrder = [ 1210 // common base layers 1211 // OSM 1212 'OpenStreetMap', 1213 'CyclOSM', 1214 'OpenTopoMap', 1215 'OpenCycleMap', 1216 'OSM Outdoors', 1217 'mapy.cz tourist (Out of order)', 1218 'mapy.cz winter (Out of order)', 1219 // Satellite 1220 'ESRI Satellite', 1221 'Yandex Satellite', 1222 'Google Satellite', 1223 'Bing Satellite', 1224 // Commercial maps 1225 'Yandex map', 1226 'Google Map', 1227 'Google Terrain', 1228 // Topo maps 1229 'Soviet topo maps (AtloMaps)', 1230 1231 // local base layers 1232 1233 // map overlays 1234 '#custom-bottom', 1235 'Eurasia 25km', 1236 'Topo 10km', 1237 'GGC 2 km', 1238 'ArbaletMO', 1239 'Norway roads', 1240 'Norway paper map', 1241 'Norway topo', 1242 'Finland Topo', 1243 'Sweden topo', 1244 'Slovakia topo', 1245 'Spain topo', 1246 'Mountains by Alexander Purikov', 1247 'Mountains by Aleksey Tsvetkov', 1248 'Slazav mountains', 1249 'GGC 1km', 1250 'Topo 1km', 1251 'Caucasus 1km', 1252 'Great Britain Topo', 1253 'GGC 500m', 1254 'Topo 500m', 1255 'Caucasus 500m', 1256 'GGC 250m', 1257 'Topo 250m', 1258 'Montenegro topo 250m', 1259 'Switzerland topo', 1260 'Slazav Moscow region map', 1261 'Races', 1262 'O-sport', 1263 '#custom-top', 1264 1265 // line overlays 1266 'Google Hybrid', 1267 'Waymarked Hiking Trails', 1268 'Waymarked Cycling Trails', 1269 'OpenStreetMap GPS traces', 1270 'Strava heatmap (all)', 1271 'Strava heatmap (run)', 1272 'Strava heatmap (ride)', 1273 'Strava heatmap (winter)', 1274 'Soviet topo maps grid', 1275 'Wikimapia', 1276 1277 // point overlays 1278 'Mountain passes (Westra)', 1279 'geocaching.su', 1280 ]; 1281 1282 function getLayers() { 1283 // set metadata 1284 for (let layer of layersDefs) { 1285 layer.layer.meta = {title: layer.title}; 1286 } 1287 1288 // assign order to layers 1289 const orderByTitle = {}; 1290 for (let i = 0; i < titlesByOrder.length; i++) { 1291 let title = titlesByOrder[i]; 1292 orderByTitle[title] = i + 1; 1293 } 1294 1295 for (let layer of layersDefs) { 1296 const title = layer.title; 1297 layer.order = orderByTitle[title]; 1298 if (!layer.order) { 1299 throw new Error(`Layer title not found in titlesByOrder list: ${title}`); 1300 } 1301 } 1302 1303 // divide layers by groups 1304 const grouppedLayers = []; 1305 const layersByTitle = {}; 1306 for (let layer of layersDefs) { 1307 layersByTitle[layer.title] = layer; 1308 } 1309 for (let groupDef of groupsDefs) { 1310 let group = {group: groupDef.title, layers: []}; 1311 grouppedLayers.push(group); 1312 for (let title of groupDef.layers) { 1313 let layer = layersByTitle[title]; 1314 group.layers.push(layer); 1315 } 1316 } 1317 1318 return { 1319 layers: grouppedLayers, 1320 customLayersOrder: { 1321 top: orderByTitle['#custom-top'], 1322 bottom: orderByTitle['#custom-bottom'], 1323 1324 } 1325 }; 1326 } 1327 1328 export {getLayers, layersDefs, groupsDefs, titlesByOrder};
