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