layers.js (55677B)
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 'https://tiles.nakarte.me/topomapper/{z}/{x}/{y}', 190 { 191 code: 'T', 192 isOverlay: false, 193 scaleDependent: true, 194 maxNativeZoom: 13, 195 noCors: false, 196 print: true, 197 jnx: true, 198 shortName: 'soviet_topo', 199 attribution: 200 '<a href="https://play.google.com/store/apps/details?id=com.atlogis.atlomaps">' + 201 'AtloMaps</a>', 202 } 203 ) 204 }, 205 206 { 207 title: 'Topo 10km', 208 isDefault: true, 209 layer: L.tileLayer("https://{s}.tiles.nakarte.me/topo001m/{z}/{x}/{y}", 210 { 211 code: 'D', 212 isOverlay: true, 213 isOverlayTransparent: false, 214 tms: true, 215 scaleDependent: false, 216 maxNativeZoom: 10, 217 print: true, 218 jnx: true, 219 shortName: 'topo_10k' 220 } 221 ) 222 }, 223 { 224 title: 'GGC 2 km', 225 isDefault: true, 226 layer: L.tileLayer("https://{s}.tiles.nakarte.me/ggc2000/{z}/{x}/{y}", 227 { 228 code: 'N', 229 isOverlay: true, 230 isOverlayTransparent: false, 231 tms: true, 232 scaleDependent: false, 233 maxNativeZoom: 12, 234 print: true, 235 jnx: true, 236 shortName: 'ggc_2k' 237 } 238 ) 239 }, 240 { 241 title: 'ArbaletMO', 242 isDefault: true, 243 layer: L.tileLayer("https://{s}.tiles.nakarte.me/ArbaletMO/{z}/{x}/{y}", 244 { 245 code: 'A', 246 isOverlay: true, 247 isOverlayTransparent: false, 248 tms: true, 249 scaleDependent: false, 250 maxNativeZoom: 13, 251 print: true, 252 jnx: true, 253 shortName: 'arbalet', 254 attribution: 255 '<a href="http://www.velozona.ru/forums/showmessage.php?id=3370">Arbalet (2004)</a>', 256 } 257 ) 258 }, 259 { 260 title: 'Slazav mountains', 261 isDefault: true, 262 layer: L.tileLayer("https://slazav.xyz/tiles/hr/{x}-{y}-{z}.png", 263 { 264 code: 'Q', 265 isOverlay: true, 266 isOverlayTransparent: false, 267 tms: false, 268 scaleDependent: false, 269 maxNativeZoom: 13, 270 noCors: true, 271 print: true, 272 jnx: true, 273 shortName: 'slazav_mountains', 274 attribution: '<a href="http://slazav.xyz/maps">Vladislav Zavjalov</a>', 275 } 276 ) 277 }, 278 { 279 title: 'GGC 1km', 280 isDefault: true, 281 layer: L.tileLayer("https://{s}.tiles.nakarte.me/ggc1000/{z}/{x}/{y}", 282 { 283 code: 'J', 284 isOverlay: true, 285 isOverlayTransparent: false, 286 tms: true, 287 scaleDependent: false, 288 maxNativeZoom: 13, 289 print: true, 290 jnx: true, 291 shortName: 'ggc_1k' 292 } 293 ) 294 }, 295 { 296 title: 'Topo 1km', 297 isDefault: true, 298 layer: L.tileLayer("https://{s}.tiles.nakarte.me/topo1000/{z}/{x}/{y}", 299 { 300 code: 'C', 301 isOverlay: true, 302 isOverlayTransparent: false, 303 tms: true, 304 scaleDependent: false, 305 maxNativeZoom: 13, 306 print: true, 307 jnx: true, 308 shortName: 'topo_1k' 309 } 310 ) 311 }, 312 { 313 title: 'GGC 500m', 314 isDefault: true, 315 layer: L.tileLayer("https://{s}.tiles.nakarte.me/ggc500/{z}/{x}/{y}", 316 { 317 code: 'F', 318 isOverlay: true, 319 isOverlayTransparent: false, 320 tms: true, 321 scaleDependent: false, 322 maxNativeZoom: 14, 323 print: true, 324 jnx: true, 325 shortName: 'ggc_500' 326 } 327 ) 328 }, 329 { 330 title: 'Topo 500m', 331 isDefault: true, 332 layer: L.tileLayer("https://{s}.tiles.nakarte.me/topo500/{z}/{x}/{y}", 333 { 334 code: 'B', 335 isOverlay: true, 336 isOverlayTransparent: false, 337 tms: true, 338 scaleDependent: false, 339 maxNativeZoom: 14, 340 print: true, 341 jnx: true, 342 shortName: 'topo_500' 343 } 344 ) 345 }, 346 { 347 title: 'GGC 250m', 348 isDefault: true, 349 layer: L.tileLayer("https://{s}.tiles.nakarte.me/ggc250/{z}/{x}/{y}", 350 { 351 code: 'K', 352 isOverlay: true, 353 isOverlayTransparent: false, 354 tms: true, 355 scaleDependent: false, 356 maxNativeZoom: 15, 357 print: true, 358 jnx: true, 359 shortName: 'ggc_250' 360 } 361 ) 362 }, 363 { 364 title: 'Slazav Moscow region map', 365 isDefault: true, 366 layer: L.tileLayer("https://slazav.xyz/tiles/podm/{x}-{y}-{z}.png", 367 { 368 code: 'Z', 369 isOverlay: true, 370 isOverlayTransparent: false, 371 tms: false, 372 scaleDependent: false, 373 maxNativeZoom: 14, 374 noCors: true, 375 print: true, 376 jnx: true, 377 shortName: 'slazav', 378 attribution: '<a href="http://slazav.xyz/maps">Vladislav Zavjalov</a>', 379 } 380 ) 381 }, 382 { 383 title: 'Races', 384 isDefault: true, 385 layer: L.tileLayer("https://{s}.tiles.nakarte.me/adraces/{z}/{x}/{y}", 386 { 387 code: 'U', 388 isOverlay: true, 389 isOverlayTransparent: false, 390 tms: true, 391 scaleDependent: false, 392 maxNativeZoom: 15, 393 print: true, 394 jnx: true, 395 shortName: 'races' 396 } 397 ) 398 }, 399 { 400 title: 'O-sport', 401 isDefault: true, 402 layer: L.tileLayer("https://{s}.tiles.nakarte.me/osport/{z}/{x}/{y}", 403 { 404 code: 'R', 405 isOverlay: true, 406 isOverlayTransparent: false, 407 tms: true, 408 scaleDependent: false, 409 maxNativeZoom: 17, 410 print: true, 411 jnx: true, 412 shortName: 'osport' 413 } 414 ) 415 }, 416 { 417 title: 'Soviet topo maps grid', 418 isDefault: true, 419 layer: new L.Layer.SovietTopoGrid({ 420 code: 'Ng', 421 isOverlay: true, 422 print: false, 423 jnx: false 424 }) 425 }, 426 { 427 title: 'Wikimapia', 428 isDefault: true, 429 layer: new L.Wikimapia({ 430 code: 'W', 431 isOverlay: true, 432 print: false, 433 jnx: false, 434 attribution: '<a href="https://wikimapia.org/">Wikimapia</a>', 435 tilesBaseUrl: config.wikimapiaTilesBaseUrl, 436 }) 437 }, 438 { 439 title: 'Mountain passes (Westra)', 440 isDefault: true, 441 layer: new L.Layer.WestraPasses(config.westraDataBaseUrl, { 442 code: 'Wp', 443 print: true, 444 jnx: false, 445 scaleDependent: true, 446 isOverlay: true, 447 isOverlayTransparent: true, 448 shortName: 'passes', 449 markersOptions: { 450 isOverlay: true, 451 isOverlayTransparent: true, 452 shortName: 'passes' 453 }, 454 attribution: '<a href="http://westra.ru/passes/">Westra passes catalog</a>', 455 }) 456 }, 457 { 458 title: 'OpenTopoMap', 459 isDefault: false, 460 layer: L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', 461 { 462 code: 'Otm', 463 isOverlay: false, 464 maxNativeZoom: 17, 465 scaleDependent: true, 466 print: true, 467 jnx: true, 468 noCors: false, 469 shortName: 'opentopo', 470 attribution: '<a href="https://opentopomap.org/">OpenTopoMap</a>', 471 hotkey: 'V', 472 } 473 ) 474 }, 475 { 476 title: 'OpenCycleMap', 477 isDefault: false, 478 layer: new RetinaTileLayer( 479 [ 480 'https://{s}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png', 481 'https://{s}.tile.thunderforest.com/cycle/{z}/{x}/{y}@2x.png', 482 ], 483 { 484 code: 'Ocm', 485 isOverlay: false, 486 scaleDependent: true, 487 print: true, 488 jnx: true, 489 shortName: 'opencyclemap', 490 attribution: '<a href="https://www.opencyclemap.org/">Thunderforest OpenCycleMap</a>', 491 } 492 ) 493 }, 494 { 495 title: 'OSM Outdoors', 496 isDefault: false, 497 layer: new RetinaTileLayer( 498 [ 499 'https://{s}.tile.thunderforest.com/outdoors/{z}/{x}/{y}.png', 500 'https://{s}.tile.thunderforest.com/outdoors/{z}/{x}/{y}@2x.png', 501 ], 502 { 503 code: 'Oso', 504 isOverlay: false, 505 scaleDependent: true, 506 print: true, 507 jnx: true, 508 shortName: 'osm_outdoors', 509 attribution: 510 '<a href="https://www.thunderforest.com/maps/outdoors/">Thunderforest Outdoors</a>', 511 } 512 ) 513 }, 514 { 515 title: 'Eurasia 25km', 516 // description: '1975-80', 517 isDefault: false, 518 layer: L.tileLayer("https://{s}.tiles.nakarte.me/eurasia25km/{z}/{x}/{y}", 519 { 520 code: 'E25m', 521 isOverlay: true, 522 isOverlayTransparent: false, 523 tms: true, 524 maxNativeZoom: 9, 525 print: true, 526 jnx: true, 527 scaleDependent: false, 528 shortName: 'eurasia_25k' 529 } 530 ) 531 }, 532 { 533 title: 'Caucasus 1km', 534 isDefault: false, 535 layer: L.tileLayer("https://{s}.tiles.nakarte.me/new_gsh_100k/{z}/{x}/{y}", 536 { 537 code: 'NT1', 538 isOverlay: true, 539 isOverlayTransparent: false, 540 tms: true, 541 maxNativeZoom: 14, 542 print: true, 543 jnx: true, 544 scaleDependent: false, 545 shortName: 'caucasus_1k', 546 attribution: '<a href="http://genshtab-yuga.narod.ru/">Topo maps (2006)</a>', 547 } 548 ) 549 }, 550 { 551 title: 'Caucasus 500m', 552 isDefault: false, 553 layer: L.tileLayer("https://{s}.tiles.nakarte.me/new_gsh_050k/{z}/{x}/{y}", 554 { 555 code: 'NT5', 556 isOverlay: true, 557 isOverlayTransparent: false, 558 tms: true, 559 maxNativeZoom: 15, 560 print: true, 561 jnx: true, 562 scaleDependent: false, 563 shortName: 'caucasus_500', 564 attribution: '<a href="http://genshtab-yuga.narod.ru/">Topo maps (1998 - 2003)</a>', 565 } 566 ) 567 }, 568 { 569 title: 'Topo 250m', 570 isDefault: false, 571 layer: L.tileLayer("https://{s}.tiles.nakarte.me/topo250/{z}/{x}/{y}", 572 { 573 code: 'T25', 574 isOverlay: true, 575 isOverlayTransparent: false, 576 tms: true, 577 maxNativeZoom: 15, 578 print: true, 579 jnx: true, 580 scaleDependent: false, 581 shortName: 'topo_250' 582 } 583 ) 584 }, 585 { 586 title: 'Montenegro topo 250m', 587 // description: '1970-72', 588 isDefault: false, 589 layer: L.tileLayer("https://{s}.tiles.nakarte.me/montenegro250m/{z}/{x}/{y}", 590 { 591 code: 'MN25', 592 isOverlay: true, 593 isOverlayTransparent: false, 594 tms: true, 595 maxNativeZoom: 15, 596 print: true, 597 jnx: true, 598 scaleDependent: false, 599 shortName: 'montenegro_250' 600 } 601 ) 602 }, 603 { 604 title: 'Mountains by Aleksey Tsvetkov', 605 isDefault: true, 606 layer: new LayerGroupWithOptions( 607 [ 608 L.tileLayer( 609 urlViaCorsProxy( 610 'https://maptiles.website.yandexcloud.net/{z}/{x}/{y}.png' 611 ), 612 { 613 isOverlay: true, 614 isOverlayTransparent: false, 615 tms: false, 616 minZoom: 2, 617 maxNativeZoom: 15, 618 print: true, 619 jnx: true, 620 scaleDependent: false, 621 noCors: false, 622 shortName: 'tsvetkov_mountains', 623 cutline: getCutline('tsvetkov_mountains'), 624 bounds: [ 625 [40.66664, 71.00007], 626 [45.33338, 81.00001], 627 ], 628 attribution: '<a href="http://pereval.g-utka.ru/">Aleksey Tsvetkov</a>', 629 } 630 ), 631 new LayerCutlineOverview(getCutline('tsvetkov_mountains'), 6, 632 'Mountains by Aleksey Tsvetkov'), 633 ], 634 { 635 code: 'Mt', 636 isOverlay: true, 637 isWrapper: true, 638 } 639 ), 640 }, 641 { 642 title: 'geocaching.su', 643 isDefault: false, 644 layer: new GeocachingSu(config.geocachingSuUrl, { 645 code: 'Gc', 646 isOverlay: true, 647 isOverlayTransparent: true, 648 print: true, 649 jnx: false, 650 shortName: 'geocaching', 651 attribution: '<a href="https://geocaching.su/">geocaching.su</a>', 652 }) 653 }, 654 { 655 title: 'OpenStreetMap GPS traces', 656 isDefault: false, 657 layer: L.tileLayer('https://{s}.gps-tile.openstreetmap.org/lines/{z}/{x}/{y}.png', 658 { 659 code: 'Ot', 660 isOverlay: true, 661 isOverlayTransparent: true, 662 scaleDependent: true, 663 print: true, 664 jnx: false, 665 shortName: 'osm_gps_traces', 666 attribution: '<a href="https://www.openstreetmap.org/#&layers=G">' + 667 'OpenStreetMap public GPS traces</a>', 668 } 669 ) 670 }, 671 { 672 title: 'Strava heatmap (all)', 673 isDefault: false, 674 layer: new RetinaTileLayer( 675 [ 676 urlViaCorsProxy( 677 'https://content-a.strava.com/identified/globalheat/all/hot/{z}/{x}/{y}.png?px=256' 678 ), 679 urlViaCorsProxy( 680 'https://content-a.strava.com/identified/globalheat/all/hot/{z}/{x}/{y}.png?px=512' 681 ), 682 ], 683 { 684 code: 'Sa', 685 isOverlay: true, 686 isOverlayTransparent: true, 687 scaleDependent: false, 688 print: true, 689 jnx: false, 690 subdomains: 'abc', 691 noCors: false, 692 shortName: 'strava_all', 693 retinaOptionsOverrides: [{maxNativeZoom: 16}, {maxNativeZoom: 15}], 694 attribution: '<a href="https://www.strava.com/heatmap">Strava Global Heatmap</a>', 695 opacity: 0.75, 696 } 697 ) 698 }, 699 { 700 title: 'Strava heatmap (run)', 701 isDefault: false, 702 layer: new RetinaTileLayer( 703 [ 704 urlViaCorsProxy( 705 'https://content-a.strava.com/identified/globalheat/run/hot/{z}/{x}/{y}.png?px=256' 706 ), 707 urlViaCorsProxy( 708 'https://content-a.strava.com/identified/globalheat/run/hot/{z}/{x}/{y}.png?px=512' 709 ), 710 ], 711 { 712 code: 'Sr', 713 isOverlay: true, 714 isOverlayTransparent: true, 715 scaleDependent: false, 716 print: true, 717 jnx: false, 718 subdomains: 'abc', 719 noCors: false, 720 shortName: 'strava_run', 721 retinaOptionsOverrides: [{maxNativeZoom: 16}, {maxNativeZoom: 15}], 722 attribution: '<a href="https://www.strava.com/heatmap">Strava Global Heatmap</a>', 723 opacity: 0.75, 724 } 725 ) 726 }, 727 { 728 title: 'Strava heatmap (ride)', 729 isDefault: false, 730 layer: new RetinaTileLayer( 731 [ 732 urlViaCorsProxy( 733 'https://content-a.strava.com/identified/globalheat/ride/hot/{z}/{x}/{y}.png?px=256' 734 ), 735 urlViaCorsProxy( 736 'https://content-a.strava.com/identified/globalheat/ride/hot/{z}/{x}/{y}.png?px=512' 737 ), 738 ], 739 { 740 code: 'Sb', 741 isOverlay: true, 742 isOverlayTransparent: true, 743 scaleDependent: false, 744 print: true, 745 jnx: false, 746 subdomains: 'abc', 747 noCors: false, 748 shortName: 'strava_ride', 749 retinaOptionsOverrides: [{maxNativeZoom: 16}, {maxNativeZoom: 15}], 750 attribution: '<a href="https://www.strava.com/heatmap">Strava Global Heatmap</a>', 751 opacity: 0.75, 752 } 753 ) 754 }, 755 { 756 title: 'Strava heatmap (winter)', 757 isDefault: false, 758 layer: new RetinaTileLayer( 759 [ 760 urlViaCorsProxy( 761 'https://content-a.strava.com/identified/globalheat/winter/hot/{z}/{x}/{y}.png?px=256' 762 ), 763 urlViaCorsProxy( 764 'https://content-a.strava.com/identified/globalheat/winter/hot/{z}/{x}/{y}.png?px=512' 765 ), 766 ], 767 { 768 code: 'Sw', 769 isOverlay: true, 770 isOverlayTransparent: true, 771 scaleDependent: false, 772 print: true, 773 jnx: false, 774 subdomains: 'abc', 775 noCors: false, 776 shortName: 'strava_winter', 777 retinaOptionsOverrides: [{maxNativeZoom: 16}, {maxNativeZoom: 15}], 778 attribution: '<a href="https://www.strava.com/heatmap">Strava Global Heatmap</a>', 779 opacity: 0.75, 780 } 781 ) 782 }, 783 { 784 title: 'Norway paper map', 785 isDefault: false, 786 layer: new L.TileLayer( 787 'https://cache.kartverket.no/v1/wmts/1.0.0/toporaster/default/webmercator/{z}/{y}/{x}.png', 788 { 789 code: 'Np', 790 isOverlay: true, 791 isOverlayTransparent: false, 792 tms: false, 793 print: true, 794 jnx: true, 795 scaleDependent: true, 796 noCors: false, 797 shortName: 'norway_paper', 798 bounds: [[57.81324, 4.19674], [71.27961, 31.56094]], 799 attribution: '<a href="https://kartverket.no/til-lands/kart/turkart">Kartverket</a>', 800 } 801 ) 802 }, 803 { 804 title: 'Norway topo', 805 isDefault: false, 806 layer: new L.TileLayer( 807 'https://cache.kartverket.no/v1/wmts/1.0.0/topo/default/webmercator/{z}/{y}/{x}.png', 808 { 809 code: 'Nm', 810 isOverlay: true, 811 isOverlayTransparent: false, 812 tms: false, 813 print: true, 814 jnx: true, 815 scaleDependent: true, 816 noCors: false, 817 shortName: 'norway_topo', 818 bounds: [[57.81324, 4.19674], [71.27961, 31.56094]], 819 attribution: '<a href="https://kartverket.no/til-lands/kart/turkart">Kartverket</a>', 820 } 821 ) 822 }, 823 { 824 // Вместо 404 отдают 500 для отсутствующих тайлов 825 title: 'Norway roads', 826 isDefault: false, 827 layer: L.tileLayer("https://maptiles1.finncdn.no/tileService/1.0.3/normap/{z}/{x}/{y}.png", 828 { 829 code: 'Nr', 830 isOverlay: true, 831 isOverlayTransparent: false, 832 tms: false, 833 print: true, 834 jnx: true, 835 scaleDependent: true, 836 noCors: false, 837 shortName: 'norway_roads', 838 bounds: [[57.81324, 4.19674], [71.27961, 31.56094]], 839 cutline: getCutline('norway'), 840 attribution: '<a href="https://kart.finn.no/">finn.no</a>', 841 } 842 ) 843 }, 844 { 845 title: 'mapy.cz tourist (Out of order)', 846 isDefault: true, 847 layer: new RetinaTileLayer( 848 [ 849 'https://proxy.nakarte.me/mapy/turist-en/{z}-{x}-{y}', 850 'https://proxy.nakarte.me/mapy/turist-en/retina/{z}-{x}-{y}', 851 ], 852 { 853 code: 'Czt', 854 isOverlay: false, 855 tms: false, 856 print: true, 857 jnx: true, 858 scaleDependent: true, 859 shortName: 'czech_tourist', 860 hotkey: 'H', 861 attribution: '<a href="https://mapy.cz/turisticka">mapy.cz outdoor map</a>', 862 maxZoom: -1, 863 } 864 ) 865 }, 866 { 867 title: 'mapy.cz winter (Out of order)', 868 isDefault: false, 869 layer: new LayerGroupWithOptions([ 870 new L.TileLayer('https://proxy.nakarte.me/mapy/winter-en-down/{z}-{x}-{y}', { 871 tms: false, 872 print: true, 873 isOverlay: false, 874 jnx: true, 875 scaleDependent: true, 876 shortName: 'czech_winter', 877 }), 878 new L.TileLayer('https://proxy.nakarte.me/mapy/winter-en-up/{z}-{x}-{y}', { 879 tms: false, 880 print: true, 881 jnx: false, 882 isOverlay: true, 883 isOverlayTransparent: true, 884 scaleDependent: true, 885 }), 886 ], { 887 code: 'Czw', 888 isOverlay: false, 889 isWrapper: true, 890 attribution: '<a href="https://mapy.cz/zimni">mapy.cz winter map</a>', 891 maxZoom: -1, 892 }), 893 }, 894 { 895 title: 'Finland Topo', 896 isDefault: false, 897 layer: L.tileLayer( 898 "https://proxy.laji.fi/mml_wmts/maasto/wmts/1.0.0/maastokartta/default/WGS84_Pseudo-Mercator/" + 899 "{z}/{y}/{x}.png", 900 { 901 code: 'Fmk', 902 isOverlay: true, 903 isOverlayTransparent: false, 904 tms: false, 905 print: true, 906 jnx: true, 907 scaleDependent: true, 908 noCors: false, 909 shortName: 'finland_topo', 910 bound: [[59.45416, 19.08321], [70.09211, 31.58671]], 911 cutline: getCutline('finland'), 912 attribution: '<a href="https://laji.fi/en/map/">LAJI.FI</a>', 913 } 914 ) 915 }, 916 { 917 title: 'Great Britain Topo', 918 isDefault: false, 919 layer: new LayerGroupWithOptions( 920 [ 921 new BingOrdnanceSurveyLayer({ 922 minZoom: 12, 923 maxNativeZoom: 16, 924 bounds: [ 925 [49.83793, -7.75643], 926 [60.87164, 1.82356], 927 ], 928 isOverlay: true, 929 isOverlayTransparent: false, 930 scaleDependent: true, 931 print: true, 932 jnx: true, 933 shortName: 'england_topo', 934 cutline: getCutline('great_britain'), 935 attribution: '<a href="https://docs.microsoft.com/en-us/bingmaps/v8-web-control/' + 936 'map-control-api/maptypeid-enumeration">Ordnance Survey</a>', 937 }), 938 new LayerCutlineOverview(getCutline('great_britain'), 11, 'Great Britain Topo (zoom ≥ 12)'), 939 ], 940 { 941 code: 'Gbt', 942 isOverlay: true, 943 isWrapper: true, 944 } 945 ), 946 }, 947 { 948 title: 'Waymarked Cycling Trails', 949 isDefault: false, 950 layer: L.tileLayer('https://tile.waymarkedtrails.org/cycling/{z}/{x}/{y}.png', 951 { 952 code: 'Wc', 953 isOverlay: true, 954 tms: false, 955 print: true, 956 jnx: false, 957 scaleDependent: true, 958 shortName: 'cycling_trails', 959 isOverlayTransparent: true, 960 attribution: '<a href="https://cycling.waymarkedtrails.org/">Waymarked Cycling Trails</a>', 961 }) 962 }, 963 { 964 title: 'Waymarked Hiking Trails', 965 isDefault: false, 966 layer: L.tileLayer('https://tile.waymarkedtrails.org/hiking/{z}/{x}/{y}.png', 967 { 968 code: 'Wh', 969 isOverlay: true, 970 tms: false, 971 print: true, 972 jnx: false, 973 scaleDependent: true, 974 shortName: 'hiking_trails', 975 isOverlayTransparent: true, 976 attribution: '<a href="https://hiking.waymarkedtrails.org/">Waymarked Hiking Trails</a>', 977 }) 978 }, 979 { 980 title: 'Slovakia topo', 981 isDefault: false, 982 layer: new LayerGroupWithOptions( 983 [ 984 L.tileLayer('https://static.mapy.hiking.sk/topo/{z}/{x}/{y}.png', { 985 isOverlay: true, 986 tms: false, 987 print: true, 988 jnx: true, 989 scaleDependent: true, 990 shortName: 'slovakia_topo', 991 isOverlayTransparent: false, 992 maxNativeZoom: 15, 993 minZoom: 10, 994 bounds: [ 995 [47.5172, 16.74316], 996 [49.91343, 22.74837], 997 ], 998 noCors: true, 999 cutline: getCutline('slovakia'), 1000 attribution: '<a href="https://mapy.hiking.sk/">mapy.hiking.sk</a>', 1001 }), 1002 new LayerCutlineOverview(getCutline('slovakia'), 9, 'Slovakia topo (zoom ≥ 10)'), 1003 ], 1004 { 1005 code: 'St', 1006 isOverlay: true, 1007 isWrapper: true, 1008 } 1009 ), 1010 }, 1011 { 1012 title: 'Spain topo', 1013 isDefault: false, 1014 layer: L.tileLayer( 1015 'https://www.ign.es/wmts/mapa-raster?layer=MTN&style=default&' + 1016 'tilematrixset=GoogleMapsCompatible&Service=WMTS&Request=GetTile&Version=1.0.0&' + 1017 'Format=image%2Fjpeg&TileMatrix={z}&TileCol={x}&TileRow={y}', 1018 { 1019 code: 'Sp', 1020 isOverlay: true, 1021 tms: false, 1022 print: true, 1023 jnx: true, 1024 scaleDependent: true, 1025 shortName: 'spain_topo', 1026 isOverlayTransparent: false, 1027 minZoom: 1, 1028 bounds: [[35.9024, -9.51828], [43.8375, 4.50439]], 1029 noCors: false, 1030 cutline: getCutline('spain'), 1031 attribution: '<a href="https://www.ign.es/iberpix2/visor/">' + 1032 'IGN (Spain) topographic map</a>' 1033 } 1034 ) 1035 }, 1036 { 1037 title: 'Switzerland topo', 1038 isDefault: false, 1039 layer: new RetinaTileLayer( 1040 [ 1041 null, 1042 urlViaCorsProxy( 1043 'https:///wmts10.geo.admin.ch/1.0.0/ch.swisstopo.pixelkarte-farbe/default/current/' + 1044 '3857/{z}/{x}/{y}.jpeg' 1045 ), 1046 ], 1047 1048 { 1049 code: 'Si', 1050 isOverlay: true, 1051 tms: false, 1052 print: true, 1053 jnx: true, 1054 scaleDependent: true, 1055 shortName: 'swiss_topo', 1056 isOverlayTransparent: false, 1057 bounds: [[45.80269, 5.87352], [47.86445, 10.6847]], 1058 noCors: false, 1059 maxNativeZoom: 16, 1060 tileSize: 128, 1061 zoomOffset: 1, 1062 cutline: getCutline('switzerland'), 1063 attribution: '<a href="https://map.geo.admin.ch/?topic=swisstopo&lang=en&bgLayer=' + 1064 'ch.swisstopo.pixelkarte-farbe&E=2586000.76&N=1202020.96&zoom=1">Swisstopo' 1065 }, true 1066 ) 1067 }, 1068 { 1069 title: 'Mountains by Alexander Purikov', 1070 isDefault: false, 1071 layer: L.tileLayer("https://{s}.tiles.nakarte.me/purikov/{z}/{x}/{y}", 1072 { 1073 code: 'Pur', 1074 isOverlay: true, 1075 isOverlayTransparent: false, 1076 tms: true, 1077 scaleDependent: false, 1078 maxNativeZoom: 14, 1079 noCors: false, 1080 print: true, 1081 jnx: true, 1082 shortName: 'purikov_mountains', 1083 attribution: '<a href="https://westra.ru/reports/">Alexander Purikov</a>', 1084 } 1085 ) 1086 }, 1087 { 1088 title: 'Sweden topo', 1089 isDefault: false, 1090 layer: L.tileLayer( 1091 'https://minkarta.lantmateriet.se/map/topowebbcache' + 1092 '?layer=topowebb&style=default&tilematrixset=3857&Service=WMTS&Request=GetTile&Version=1.0.0' + 1093 '&Format=image%2Fpng&TileMatrix={z}&TileCol={x}&TileRow={y}', 1094 { 1095 code: 'Se', 1096 isOverlay: true, 1097 tms: false, 1098 print: true, 1099 jnx: true, 1100 scaleDependent: true, 1101 shortName: 'sweden_topo', 1102 isOverlayTransparent: false, 1103 minZoom: 0, 1104 maxNativeZoom: 17, 1105 bounds: [[55.13493, 10.58876], [69.07200, 24.18365]], 1106 noCors: false, 1107 cutline: getCutline('sweden'), 1108 attribution: '<a href="https://minkarta.lantmateriet.se/">' + 1109 'Lantmäteriet</a>' 1110 } 1111 ) 1112 }, 1113 1114 ]; 1115 1116 const groupsDefs = [ 1117 { 1118 title: 'Default layers', 1119 layers: [ 1120 'OpenStreetMap', 1121 'CyclOSM', 1122 'ESRI Satellite', 1123 'Yandex map', 1124 'Yandex Satellite', 1125 'Google Map', 1126 'Google Satellite', 1127 'Google Terrain', 1128 'Bing Satellite', 1129 'Soviet topo maps (AtloMaps)', 1130 'Topo 10km', 1131 'GGC 2 km', 1132 'ArbaletMO', 1133 'Mountains by Aleksey Tsvetkov', 1134 'Slazav mountains', 1135 'GGC 1km', 1136 'Topo 1km', 1137 'GGC 500m', 1138 'Topo 500m', 1139 'GGC 250m', 1140 'Slazav Moscow region map', 1141 'Races', 1142 'O-sport', 1143 'Soviet topo maps grid', 1144 'Wikimapia', 1145 'Mountain passes (Westra)' 1146 ], 1147 }, 1148 { 1149 title: 'OpenStreetMap alternatives', 1150 layers: [ 1151 'OpenTopoMap', 1152 'OpenCycleMap', 1153 'OSM Outdoors', 1154 'mapy.cz tourist (Out of order)', 1155 'mapy.cz winter (Out of order)', 1156 1157 ], 1158 }, 1159 { 1160 title: 'Topo maps', 1161 layers: [ 1162 'Eurasia 25km', 1163 'Caucasus 1km', 1164 'Caucasus 500m', 1165 'Topo 250m', 1166 'Montenegro topo 250m', 1167 'Finland Topo', 1168 'Sweden topo', 1169 'Great Britain Topo', 1170 'Slovakia topo', 1171 'Spain topo', 1172 'Switzerland topo', 1173 ], 1174 }, 1175 { 1176 title: 'Miscellaneous', 1177 layers: [ 1178 'Mountains by Alexander Purikov', 1179 'Google Hybrid', 1180 'geocaching.su' 1181 ] 1182 }, 1183 { 1184 title: 'Routes and traces', 1185 layers: [ 1186 'Waymarked Hiking Trails', 1187 'Waymarked Cycling Trails', 1188 'OpenStreetMap GPS traces', 1189 'Strava heatmap (all)', 1190 'Strava heatmap (run)', 1191 'Strava heatmap (ride)', 1192 'Strava heatmap (winter)', 1193 ], 1194 1195 }, 1196 { 1197 title: 'Norway', 1198 layers: [ 1199 'Norway paper map', 1200 'Norway topo', 1201 'Norway roads' 1202 ], 1203 1204 }, 1205 ]; 1206 1207 const titlesByOrder = [ 1208 // common base layers 1209 // OSM 1210 'OpenStreetMap', 1211 'CyclOSM', 1212 'OpenTopoMap', 1213 'OpenCycleMap', 1214 'OSM Outdoors', 1215 'mapy.cz tourist (Out of order)', 1216 'mapy.cz winter (Out of order)', 1217 // Satellite 1218 'ESRI Satellite', 1219 'Yandex Satellite', 1220 'Google Satellite', 1221 'Bing Satellite', 1222 // Commercial maps 1223 'Yandex map', 1224 'Google Map', 1225 'Google Terrain', 1226 // Topo maps 1227 'Soviet topo maps (AtloMaps)', 1228 1229 // local base layers 1230 1231 // map overlays 1232 '#custom-bottom', 1233 'Eurasia 25km', 1234 'Topo 10km', 1235 'GGC 2 km', 1236 'ArbaletMO', 1237 'Norway roads', 1238 'Norway paper map', 1239 'Norway topo', 1240 'Finland Topo', 1241 'Sweden topo', 1242 'Slovakia topo', 1243 'Spain topo', 1244 'Mountains by Alexander Purikov', 1245 'Mountains by Aleksey Tsvetkov', 1246 'Slazav mountains', 1247 'GGC 1km', 1248 'Topo 1km', 1249 'Caucasus 1km', 1250 'Great Britain Topo', 1251 'GGC 500m', 1252 'Topo 500m', 1253 'Caucasus 500m', 1254 'GGC 250m', 1255 'Topo 250m', 1256 'Montenegro topo 250m', 1257 'Switzerland topo', 1258 'Slazav Moscow region map', 1259 'Races', 1260 'O-sport', 1261 '#custom-top', 1262 1263 // line overlays 1264 'Google Hybrid', 1265 'Waymarked Hiking Trails', 1266 'Waymarked Cycling Trails', 1267 'OpenStreetMap GPS traces', 1268 'Strava heatmap (all)', 1269 'Strava heatmap (run)', 1270 'Strava heatmap (ride)', 1271 'Strava heatmap (winter)', 1272 'Soviet topo maps grid', 1273 'Wikimapia', 1274 1275 // point overlays 1276 'Mountain passes (Westra)', 1277 'geocaching.su', 1278 ]; 1279 1280 function getLayers() { 1281 // set metadata 1282 for (let layer of layersDefs) { 1283 layer.layer.meta = {title: layer.title}; 1284 } 1285 1286 // assign order to layers 1287 const orderByTitle = {}; 1288 for (let i = 0; i < titlesByOrder.length; i++) { 1289 let title = titlesByOrder[i]; 1290 orderByTitle[title] = i + 1; 1291 } 1292 1293 for (let layer of layersDefs) { 1294 const title = layer.title; 1295 layer.order = orderByTitle[title]; 1296 if (!layer.order) { 1297 throw new Error(`Layer title not found in titlesByOrder list: ${title}`); 1298 } 1299 } 1300 1301 // divide layers by groups 1302 const grouppedLayers = []; 1303 const layersByTitle = {}; 1304 for (let layer of layersDefs) { 1305 layersByTitle[layer.title] = layer; 1306 } 1307 for (let groupDef of groupsDefs) { 1308 let group = {group: groupDef.title, layers: []}; 1309 grouppedLayers.push(group); 1310 for (let title of groupDef.layers) { 1311 let layer = layersByTitle[title]; 1312 group.layers.push(layer); 1313 } 1314 } 1315 1316 return { 1317 layers: grouppedLayers, 1318 customLayersOrder: { 1319 top: orderByTitle['#custom-top'], 1320 bottom: orderByTitle['#custom-bottom'], 1321 1322 } 1323 }; 1324 } 1325 1326 export {getLayers, layersDefs, groupsDefs, titlesByOrder};
