layers.js (55853B)
1 import L from "leaflet"; 2 import '~/lib/leaflet.layer.yandex'; 3 import '~/lib/leaflet.layer.google'; 4 import {BingLayer} from '~/lib/leaflet.layer.bing'; 5 import 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 description: 'OSM default style', 27 isDefault: true, 28 layer: L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', 29 { 30 code: 'O', 31 isOverlay: false, 32 scaleDependent: true, 33 print: true, 34 jnx: true, 35 shortName: 'osm', 36 attribution: '<a href="https://www.openstreetmap.org/copyright">' + 37 '© OpenStreetMap contributors</a>', 38 } 39 ) 40 }, 41 { 42 title: 'CyclOSM', 43 isDefault: true, 44 layer: L.tileLayer('https://{s}.tile-cyclosm.openstreetmap.fr/cyclosm/{z}/{x}/{y}.png', 45 { 46 code: 'Co', 47 isOverlay: false, 48 scaleDependent: true, 49 print: true, 50 jnx: true, 51 shortName: 'cyclosm', 52 attribution: 53 '<a href="https://www.openstreetmap.org/copyright">' + 54 '© OpenStreetMap contributors</a>. ' + 55 'Tiles style by <a href="https://www.cyclosm.org/">CyclOSM</a>', 56 } 57 ) 58 }, 59 { 60 title: 'ESRI Satellite', 61 isDefault: true, 62 layer: L.tileLayer( 63 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', 64 { 65 code: 'E', 66 isOverlay: false, 67 scaleDependent: false, 68 maxNativeZoom: 18, 69 print: true, 70 jnx: true, 71 shortName: 'esri', 72 attribution: 73 '<a href="https://www.arcgis.com/home/item.html?id=10df2279f9684e4a9f6a7f08febac2a9">' + 74 'ESRI World Imagery for ArcGIS</a>', 75 } 76 ) 77 }, 78 { 79 title: 'Yandex map', 80 isDefault: true, 81 layer: new L.Layer.Yandex.Map( 82 { 83 scaleDependent: true, 84 code: 'Y', 85 isOverlay: false, 86 print: true, 87 jnx: true, 88 shortName: 'yandex', 89 attribution: '<a href="https://yandex.ru/maps/">Yandex</a>', 90 } 91 ) 92 }, 93 { 94 title: 'Yandex Satellite', 95 isDefault: true, 96 layer: new L.Layer.Yandex.Sat( 97 { 98 scaleDependent: false, 99 code: 'S', 100 isOverlay: false, 101 print: true, 102 jnx: true, 103 shortName: 'yandex_sat', 104 attribution: '<a href="https://yandex.ru/maps/?l=sat">Yandex</a>', 105 } 106 ) 107 }, 108 { 109 title: 'Google Map', 110 isDefault: true, 111 layer: new L.Layer.GoogleMap( 112 { 113 code: 'G', 114 isOverlay: false, 115 scaleDependent: true, 116 print: true, 117 jnx: true, 118 shortName: 'google', 119 attribution: '<a href="https://www.google.com/maps">Google</a>', 120 } 121 ) 122 }, 123 { 124 title: 'Google Hybrid', 125 isDefault: false, 126 layer: new L.Layer.GoogleHybrid( 127 { 128 code: 'Gh', 129 isOverlay: true, 130 scaleDependent: true, 131 print: true, 132 jnx: false, 133 shortName: 'google_hybrid', 134 isOverlayTransparent: true, 135 attribution: '<a href="https://www.google.com/maps/@43.0668619,60.5738071,13622628m' + 136 '/data=!3m1!1e3">Google</a>', 137 } 138 ) 139 }, 140 { 141 title: 'Google Satellite', 142 isDefault: true, 143 layer: new L.Layer.GoogleSat( 144 { 145 code: 'L', 146 isOverlay: false, 147 scaleDependent: false, 148 print: true, 149 jnx: true, 150 shortName: 'google_sat', 151 attribution: '<a href="https://www.google.com/maps/@43.0668619,60.5738071,13622628m' + 152 '/data=!3m1!1e3">Google</a>', 153 } 154 ) 155 }, 156 { 157 title: 'Google Terrain', 158 isDefault: true, 159 layer: new L.Layer.GoogleTerrain({ 160 code: 'P', 161 isOverlay: false, 162 scaleDependent: false, 163 print: true, 164 jnx: true, 165 shortName: 'google_terrain', 166 attribution: '<a href="https://www.google.com/maps/@43.1203575,42.1105049,9.58z' + 167 '/data=!5m1!1e4">Google</a>', 168 } 169 ) 170 }, 171 { 172 title: 'Bing Satellite', 173 isDefault: true, 174 layer: new BingLayer(config.bingKey, 175 { 176 code: 'I', 177 isOverlay: false, 178 scaleDependent: false, 179 print: true, 180 jnx: true, 181 shortName: 'bing_sat' 182 } 183 ) 184 }, 185 { 186 title: 'Topomapper 1km', 187 isDefault: true, 188 layer: L.tileLayer( 189 urlViaCorsProxy( 190 'http://88.99.52.155/cgi-bin/tapp/tilecache.py/1.0.0/topomapper_v2/{z}/{x}/{y}.jpg' 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: 9, 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: 16, 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 description: '<a href="https://www.opencyclemap.org/docs/">(Info and key)</a>', 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 description: 608 'Tian Shan, Dzungaria, <a href="http://pereval.g-utka.ru/">http://pereval.g-utka.ru/</a>', 609 isDefault: true, 610 layer: new LayerGroupWithOptions( 611 [ 612 L.tileLayer( 613 urlViaCorsProxy( 614 'http://nakartetiles.s3-website.eu-central-1.amazonaws.com/{z}/{x}/{y}.png' 615 ), 616 { 617 isOverlay: true, 618 isOverlayTransparent: false, 619 tms: false, 620 minZoom: 2, 621 maxNativeZoom: 15, 622 print: true, 623 jnx: true, 624 scaleDependent: false, 625 noCors: false, 626 shortName: 'tsvetkov_mountains', 627 cutline: getCutline('tsvetkov_mountains'), 628 bounds: [ 629 [40.66664, 71.00007], 630 [45.33338, 81.00001], 631 ], 632 attribution: '<a href="http://pereval.g-utka.ru/">Aleksey Tsvetkov</a>', 633 } 634 ), 635 new LayerCutlineOverview(getCutline('tsvetkov_mountains'), 6, 636 'Mountains by Aleksey Tsvetkov'), 637 ], 638 { 639 code: 'Mt', 640 isOverlay: true, 641 isWrapper: true, 642 } 643 ), 644 }, 645 { 646 title: 'geocaching.su', 647 isDefault: false, 648 layer: new GeocachingSu(config.geocachingSuUrl, { 649 code: 'Gc', 650 isOverlay: true, 651 isOverlayTransparent: true, 652 print: true, 653 jnx: false, 654 shortName: 'geocaching', 655 attribution: '<a href="https://geocaching.su/">geocaching.su</a>', 656 }) 657 }, 658 { 659 title: 'OpenStreetMap GPS traces', 660 isDefault: false, 661 layer: L.tileLayer('https://{s}.gps-tile.openstreetmap.org/lines/{z}/{x}/{y}.png', 662 { 663 code: 'Ot', 664 isOverlay: true, 665 isOverlayTransparent: true, 666 scaleDependent: true, 667 print: true, 668 jnx: false, 669 shortName: 'osm_gps_traces', 670 attribution: '<a href="https://www.openstreetmap.org/#&layers=G">' + 671 'OpenStreetMap public GPS traces</a>', 672 } 673 ) 674 }, 675 { 676 title: 'Strava heatmap (all)', 677 isDefault: false, 678 layer: new RetinaTileLayer( 679 [ 680 urlViaCorsProxy( 681 'https://heatmap-external-a.strava.com/tiles-auth/all/hot/{z}/{x}/{y}.png?px=256' 682 ), 683 urlViaCorsProxy( 684 'https://heatmap-external-a.strava.com/tiles-auth/all/hot/{z}/{x}/{y}.png?px=512' 685 ), 686 ], 687 { 688 code: 'Sa', 689 isOverlay: true, 690 isOverlayTransparent: true, 691 scaleDependent: false, 692 print: true, 693 jnx: false, 694 subdomains: 'abc', 695 noCors: true, 696 shortName: 'strava_all', 697 retinaOptionsOverrides: [{maxNativeZoom: 16}, {maxNativeZoom: 15}], 698 attribution: '<a href="https://www.strava.com/heatmap">Strava Global Heatmap</a>', 699 opacity: 0.75, 700 } 701 ) 702 }, 703 { 704 title: 'Strava heatmap (run)', 705 isDefault: false, 706 layer: new RetinaTileLayer( 707 [ 708 urlViaCorsProxy( 709 'https://heatmap-external-a.strava.com/tiles-auth/run/hot/{z}/{x}/{y}.png?px=256' 710 ), 711 urlViaCorsProxy( 712 'https://heatmap-external-a.strava.com/tiles-auth/run/hot/{z}/{x}/{y}.png?px=512' 713 ), 714 ], 715 { 716 code: 'Sr', 717 isOverlay: true, 718 isOverlayTransparent: true, 719 scaleDependent: false, 720 print: true, 721 jnx: false, 722 subdomains: 'abc', 723 noCors: true, 724 shortName: 'strava_run', 725 retinaOptionsOverrides: [{maxNativeZoom: 16}, {maxNativeZoom: 15}], 726 attribution: '<a href="https://www.strava.com/heatmap">Strava Global Heatmap</a>', 727 opacity: 0.75, 728 } 729 ) 730 }, 731 { 732 title: 'Strava heatmap (ride)', 733 isDefault: false, 734 layer: new RetinaTileLayer( 735 [ 736 urlViaCorsProxy( 737 'https://heatmap-external-a.strava.com/tiles-auth/ride/hot/{z}/{x}/{y}.png?px=256' 738 ), 739 urlViaCorsProxy( 740 'https://heatmap-external-a.strava.com/tiles-auth/ride/hot/{z}/{x}/{y}.png?px=512' 741 ), 742 ], 743 { 744 code: 'Sb', 745 isOverlay: true, 746 isOverlayTransparent: true, 747 scaleDependent: false, 748 print: true, 749 jnx: false, 750 subdomains: 'abc', 751 noCors: true, 752 shortName: 'strava_ride', 753 retinaOptionsOverrides: [{maxNativeZoom: 16}, {maxNativeZoom: 15}], 754 attribution: '<a href="https://www.strava.com/heatmap">Strava Global Heatmap</a>', 755 opacity: 0.75, 756 } 757 ) 758 }, 759 { 760 title: 'Strava heatmap (winter)', 761 isDefault: false, 762 layer: new RetinaTileLayer( 763 [ 764 urlViaCorsProxy( 765 'https://heatmap-external-a.strava.com/tiles-auth/winter/hot/{z}/{x}/{y}.png?px=256' 766 ), 767 urlViaCorsProxy( 768 'https://heatmap-external-a.strava.com/tiles-auth/winter/hot/{z}/{x}/{y}.png?px=512' 769 ), 770 ], 771 { 772 code: 'Sw', 773 isOverlay: true, 774 isOverlayTransparent: true, 775 scaleDependent: false, 776 print: true, 777 jnx: false, 778 subdomains: 'abc', 779 noCors: true, 780 shortName: 'strava_winter', 781 retinaOptionsOverrides: [{maxNativeZoom: 16}, {maxNativeZoom: 15}], 782 attribution: '<a href="https://www.strava.com/heatmap">Strava Global Heatmap</a>', 783 opacity: 0.75, 784 } 785 ) 786 }, 787 { 788 title: 'Norway paper map', 789 isDefault: false, 790 layer: new L.TileLayer( 791 'https://opencache.statkart.no/gatekeeper/gk/gk.open_gmaps?layers=toporaster4&zoom={z}&x={x}&y={y}', // eslint-disable-line max-len 792 { 793 code: 'Np', 794 isOverlay: true, 795 isOverlayTransparent: false, 796 maxNativeZoom: 16, 797 tms: false, 798 print: true, 799 jnx: true, 800 scaleDependent: true, 801 noCors: false, 802 shortName: 'norway_paper', 803 bounds: [[57.81324, 4.19674], [71.27961, 31.56094]], 804 attribution: '<a href="https://www.geonorge.no/aktuelt/om-geonorge/brukerveiledning' + 805 '/#!#se_paa_kart">Geonorge</a>', 806 } 807 ) 808 }, 809 { 810 title: 'Norway topo', 811 isDefault: false, 812 layer: new L.TileLayer( 813 'https://opencache.statkart.no/gatekeeper/gk/gk.open_gmaps?layers=topo4&zoom={z}&x={x}&y={y}', 814 { 815 code: 'Nm', 816 isOverlay: true, 817 isOverlayTransparent: false, 818 tms: false, 819 print: true, 820 jnx: true, 821 scaleDependent: true, 822 noCors: false, 823 shortName: 'norway_topo', 824 bounds: [[57.81324, 4.19674], [71.27961, 31.56094]], 825 attribution: '<a href="https://www.geonorge.no/aktuelt/om-geonorge/brukerveiledning' + 826 '/#!#se_paa_kart">Geonorge</a>', 827 } 828 ) 829 }, 830 { 831 // Вместо 404 отдают 500 для отсутствующих тайлов 832 title: 'Norway roads', 833 description: '<a href="https://kart.finn.no/">https://kart.finn.no/</a>', 834 isDefault: false, 835 layer: L.tileLayer("https://maptiles1.finncdn.no/tileService/1.0.3/normap/{z}/{x}/{y}.png", 836 { 837 code: 'Nr', 838 isOverlay: true, 839 isOverlayTransparent: false, 840 tms: false, 841 print: true, 842 jnx: true, 843 scaleDependent: true, 844 noCors: false, 845 shortName: 'norway_roads', 846 bounds: [[57.81324, 4.19674], [71.27961, 31.56094]], 847 cutline: getCutline('norway'), 848 attribution: '<a href="https://kart.finn.no/">finn.no</a>', 849 } 850 ) 851 }, 852 { 853 title: 'Finland Topo', 854 description: '<a href="https://laji.fi/en/map/">LAJI.FI</a>', 855 isDefault: false, 856 layer: L.tileLayer( 857 "https://proxy.laji.fi/mml_wmts/maasto/wmts/1.0.0/maastokartta/default/WGS84_Pseudo-Mercator/" + 858 "{z}/{y}/{x}.png", 859 { 860 code: 'Fmk', 861 isOverlay: true, 862 isOverlayTransparent: false, 863 tms: false, 864 print: true, 865 jnx: true, 866 scaleDependent: true, 867 noCors: false, 868 shortName: 'finland_topo', 869 bound: [[59.45416, 19.08321], [70.09211, 31.58671]], 870 cutline: getCutline('finland'), 871 attribution: '<a href="https://laji.fi/en/map/">LAJI.FI</a>', 872 } 873 ) 874 }, 875 { 876 title: 'France Topo 250m', 877 isDefault: false, 878 layer: new LayerGroupWithOptions( 879 [ 880 L.tileLayer( 881 'https://wxs.ign.fr/an7nvfzojv5wa96dsga5nk8w/geoportail/wmts?' + 882 'layer=GEOGRAPHICALGRIDSYSTEMS.MAPS.SCAN25TOUR.CV&style=normal&tilematrixset=PM&' + 883 'Service=WMTS&Request=GetTile&Version=1.0.0&Format=image%2Fjpeg&' + 884 'TileMatrix={z}&TileCol={x}&TileRow={y}', 885 { 886 minZoom: 6, 887 maxNativeZoom: 16, 888 bounds: [ 889 [-46.44072, -178.18694], 890 [51.12562, 77.61086], 891 ], 892 isOverlay: true, 893 isOverlayTransparent: false, 894 tms: false, 895 print: true, 896 jnx: true, 897 scaleDependent: false, 898 shortName: 'france_topo_25k', 899 cutline: getCutline('france'), 900 attribution: '<a href="https://www.geoportail.gouv.fr/carte">' + 901 'IGN (France) topographic map</a>', 902 } 903 ), 904 new LayerCutlineOverview(getCutline('france'), 5, 'France Topo 250m (zoom ≥ 6)'), 905 ], 906 { 907 code: 'Ft', 908 isOverlay: true, 909 isWrapper: true, 910 } 911 ), 912 }, 913 { 914 title: 'Great Britain Topo', 915 isDefault: false, 916 layer: new LayerGroupWithOptions( 917 [ 918 new BingLayer(config.bingKey, { 919 type: 'OrdnanceSurvey', 920 minZoom: 12, 921 maxNativeZoom: 16, 922 bounds: [ 923 [49.83793, -7.75643], 924 [60.87164, 1.82356], 925 ], 926 isOverlay: true, 927 isOverlayTransparent: false, 928 scaleDependent: true, 929 print: true, 930 jnx: true, 931 shortName: 'england_topo', 932 cutline: getCutline('great_britain'), 933 attribution: '<a href="https://docs.microsoft.com/en-us/bingmaps/v8-web-control/' + 934 'map-control-api/maptypeid-enumeration">Ordnance Survey</a>', 935 }), 936 new LayerCutlineOverview(getCutline('great_britain'), 11, 'Great Britain Topo (zoom ≥ 12)'), 937 ], 938 { 939 code: 'Gbt', 940 isOverlay: true, 941 isWrapper: true, 942 } 943 ), 944 }, 945 { 946 title: 'Waymarked Cycling Trails', 947 description: 948 '<a href="https://cycling.waymarkedtrails.org/">https://cycling.waymarkedtrails.org</a>', 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 description: '<a href="https://hiking.waymarkedtrails.org/">https://hiking.waymarkedtrails.org</a>', 966 isDefault: false, 967 layer: L.tileLayer('https://tile.waymarkedtrails.org/hiking/{z}/{x}/{y}.png', 968 { 969 code: 'Wh', 970 isOverlay: true, 971 tms: false, 972 print: true, 973 jnx: false, 974 scaleDependent: true, 975 shortName: 'hiking_trails', 976 isOverlayTransparent: true, 977 attribution: '<a href="https://hiking.waymarkedtrails.org/">Waymarked Hiking Trails</a>', 978 }) 979 }, 980 { 981 title: 'Slovakia topo', 982 description: '<a href="https://mapy.hiking.sk">https://mapy.hiking.sk/</a>', 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: 'Yandex tracks (zoom ≥ 10)', 1015 isDefault: false, 1016 layer: new L.Layer.Yandex.Tracks( 1017 { 1018 scaleDependent: true, 1019 code: 'Ytr', 1020 isOverlay: true, 1021 isOverlayTransparent: true, 1022 print: true, 1023 jnx: false, 1024 shortName: 'yandex_tracks', 1025 noCors: true, 1026 attribution: '<a href="https://n.maps.yandex.ru/">Yandex Map Editor</a>', 1027 } 1028 ) 1029 }, 1030 { 1031 title: 'Spain topo', 1032 isDefault: false, 1033 layer: L.tileLayer( 1034 'https://www.ign.es/wmts/mapa-raster?layer=MTN&style=default&' + 1035 'tilematrixset=GoogleMapsCompatible&Service=WMTS&Request=GetTile&Version=1.0.0&' + 1036 'Format=image%2Fjpeg&TileMatrix={z}&TileCol={x}&TileRow={y}', 1037 { 1038 code: 'Sp', 1039 isOverlay: true, 1040 tms: false, 1041 print: true, 1042 jnx: true, 1043 scaleDependent: true, 1044 shortName: 'spain_topo', 1045 isOverlayTransparent: false, 1046 bounds: [[35.9024, -9.51828], [43.8375, 4.50439]], 1047 noCors: false, 1048 cutline: getCutline('spain'), 1049 attribution: '<a href="https://www.ign.es/iberpix2/visor/">' + 1050 'IGN (Spain) topographic map</a>' 1051 } 1052 ) 1053 }, 1054 { 1055 title: 'Switzerland topo', 1056 isDefault: false, 1057 layer: new RetinaTileLayer( 1058 [ 1059 null, 1060 urlViaCorsProxy( 1061 'https:///wmts10.geo.admin.ch/1.0.0/ch.swisstopo.pixelkarte-farbe/default/current/' + 1062 '3857/{z}/{x}/{y}.jpeg' 1063 ), 1064 ], 1065 1066 { 1067 code: 'Si', 1068 isOverlay: true, 1069 tms: false, 1070 print: true, 1071 jnx: true, 1072 scaleDependent: true, 1073 shortName: 'swiss_topo', 1074 isOverlayTransparent: false, 1075 bounds: [[45.80269, 5.87352], [47.86445, 10.6847]], 1076 noCors: false, 1077 maxNativeZoom: 16, 1078 tileSize: 128, 1079 zoomOffset: 1, 1080 cutline: getCutline('switzerland'), 1081 attribution: '<a href="https://map.geo.admin.ch/?topic=swisstopo&lang=en&bgLayer=' + 1082 'ch.swisstopo.pixelkarte-farbe&E=2586000.76&N=1202020.96&zoom=1">Swisstopo' 1083 }, true 1084 ) 1085 }, 1086 { 1087 title: 'Mountains by Alexander Purikov', 1088 isDefault: false, 1089 layer: L.tileLayer("https://{s}.tiles.nakarte.me/purikov/{z}/{x}/{y}", 1090 { 1091 code: 'Pur', 1092 isOverlay: true, 1093 isOverlayTransparent: false, 1094 tms: true, 1095 scaleDependent: false, 1096 maxNativeZoom: 14, 1097 noCors: false, 1098 print: true, 1099 jnx: true, 1100 shortName: 'purikov_mountains', 1101 attribution: '<a href="https://westra.ru/reports/">Alexander Purikov</a>', 1102 } 1103 ) 1104 }, 1105 ]; 1106 1107 const groupsDefs = [ 1108 { 1109 title: 'Default layers', 1110 layers: [ 1111 'OpenStreetMap', 1112 'CyclOSM', 1113 'ESRI Satellite', 1114 'Yandex map', 1115 'Yandex Satellite', 1116 'Google Map', 1117 'Google Satellite', 1118 'Google Terrain', 1119 'Bing Satellite', 1120 'Topomapper 1km', 1121 'Topo 10km', 1122 'GGC 2 km', 1123 'ArbaletMO', 1124 'Mountains by Aleksey Tsvetkov', 1125 'Slazav mountains', 1126 'GGC 1km', 1127 'Topo 1km', 1128 'GGC 500m', 1129 'Topo 500m', 1130 'GGC 250m', 1131 'Slazav Moscow region map', 1132 'Races', 1133 'O-sport', 1134 'Soviet topo maps grid', 1135 'Wikimapia', 1136 'Mountain passes (Westra)' 1137 ], 1138 }, 1139 { 1140 title: 'OpenStreetMap alternatives', 1141 layers: [ 1142 'OpenTopoMap', 1143 'OpenCycleMap', 1144 'OSM Outdoors', 1145 ], 1146 }, 1147 { 1148 title: 'Topo maps', 1149 layers: [ 1150 'Eurasia 25km', 1151 'Caucasus 1km', 1152 'Caucasus 500m', 1153 'Topo 250m', 1154 'Montenegro topo 250m', 1155 'Finland Topo', 1156 'France Topo 250m', 1157 'Great Britain Topo', 1158 'Slovakia topo', 1159 'Spain topo', 1160 'Switzerland topo', 1161 ], 1162 }, 1163 { 1164 title: 'Miscellaneous', 1165 layers: [ 1166 'Mountains by Alexander Purikov', 1167 'Google Hybrid', 1168 'geocaching.su' 1169 ] 1170 }, 1171 { 1172 title: 'Routes and traces', 1173 layers: [ 1174 'Waymarked Hiking Trails', 1175 'Waymarked Cycling Trails', 1176 'OpenStreetMap GPS traces', 1177 'Strava heatmap (all)', 1178 'Strava heatmap (run)', 1179 'Strava heatmap (ride)', 1180 'Strava heatmap (winter)', 1181 'Yandex tracks (zoom ≥ 10)', 1182 ], 1183 1184 }, 1185 { 1186 title: 'Norway <a href="https://www.ut.no/kart/">https://www.ut.no/kart/</a>', 1187 layers: [ 1188 'Norway paper map', 1189 'Norway topo', 1190 'Norway roads' 1191 ], 1192 1193 }, 1194 ]; 1195 1196 const titlesByOrder = [ 1197 // common base layers 1198 // OSM 1199 'OpenStreetMap', 1200 'CyclOSM', 1201 'OpenTopoMap', 1202 'OpenCycleMap', 1203 'OSM Outdoors', 1204 // Satellite 1205 'ESRI Satellite', 1206 'Yandex Satellite', 1207 'Google Satellite', 1208 'Bing Satellite', 1209 // Commercial maps 1210 'Yandex map', 1211 'Google Map', 1212 'Google Terrain', 1213 // Topo maps 1214 'Topomapper 1km', 1215 1216 // local base layers 1217 1218 // map overlays 1219 '#custom-bottom', 1220 'Eurasia 25km', 1221 'Topo 10km', 1222 'GGC 2 km', 1223 'ArbaletMO', 1224 'Norway roads', 1225 'Norway paper map', 1226 'Norway topo', 1227 'Finland Topo', 1228 'Slovakia topo', 1229 'Spain topo', 1230 'Mountains by Alexander Purikov', 1231 'Mountains by Aleksey Tsvetkov', 1232 'Slazav mountains', 1233 'GGC 1km', 1234 'Topo 1km', 1235 'Caucasus 1km', 1236 'Great Britain Topo', 1237 'GGC 500m', 1238 'Topo 500m', 1239 'Caucasus 500m', 1240 'GGC 250m', 1241 'Topo 250m', 1242 'Montenegro topo 250m', 1243 'France Topo 250m', 1244 'Switzerland topo', 1245 'Slazav Moscow region map', 1246 'Races', 1247 'O-sport', 1248 '#custom-top', 1249 1250 // line overlays 1251 'Google Hybrid', 1252 'Waymarked Hiking Trails', 1253 'Waymarked Cycling Trails', 1254 'OpenStreetMap GPS traces', 1255 'Strava heatmap (all)', 1256 'Strava heatmap (run)', 1257 'Strava heatmap (ride)', 1258 'Strava heatmap (winter)', 1259 'Yandex tracks (zoom ≥ 10)', 1260 'Soviet topo maps grid', 1261 'Wikimapia', 1262 1263 // point overlays 1264 'Mountain passes (Westra)', 1265 'geocaching.su', 1266 ]; 1267 1268 function getLayers() { 1269 // set metadata 1270 for (let layer of layersDefs) { 1271 layer.layer.meta = {title: layer.title}; 1272 } 1273 1274 // assign order to layers 1275 const orderByTitle = {}; 1276 for (let i = 0; i < titlesByOrder.length; i++) { 1277 let title = titlesByOrder[i]; 1278 orderByTitle[title] = i + 1; 1279 } 1280 1281 for (let layer of layersDefs) { 1282 const title = layer.title; 1283 layer.order = orderByTitle[title]; 1284 if (!layer.order) { 1285 throw new Error(`Layer title not found in titlesByOrder list: ${title}`); 1286 } 1287 } 1288 1289 // divide layers by groups 1290 const grouppedLayers = []; 1291 const layersByTitle = {}; 1292 for (let layer of layersDefs) { 1293 layersByTitle[layer.title] = layer; 1294 } 1295 for (let groupDef of groupsDefs) { 1296 let group = {group: groupDef.title, layers: []}; 1297 grouppedLayers.push(group); 1298 for (let title of groupDef.layers) { 1299 let layer = layersByTitle[title]; 1300 group.layers.push(layer); 1301 } 1302 } 1303 1304 return { 1305 layers: grouppedLayers, 1306 customLayersOrder: { 1307 top: orderByTitle['#custom-top'], 1308 bottom: orderByTitle['#custom-bottom'], 1309 1310 } 1311 }; 1312 } 1313 1314 export {getLayers, layersDefs, groupsDefs, titlesByOrder};