layers.js (56362B)
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/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: 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: 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 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://cache.kartverket.no/v1/wmts/1.0.0/toporaster/default/webmercator/{z}/{y}/{x}.png', 792 { 793 code: 'Np', 794 isOverlay: true, 795 isOverlayTransparent: false, 796 tms: false, 797 print: true, 798 jnx: true, 799 scaleDependent: true, 800 noCors: false, 801 shortName: 'norway_paper', 802 bounds: [[57.81324, 4.19674], [71.27961, 31.56094]], 803 attribution: '<a href="https://kartverket.no/til-lands/kart/turkart">Kartverket</a>', 804 } 805 ) 806 }, 807 { 808 title: 'Norway topo', 809 isDefault: false, 810 layer: new L.TileLayer( 811 'https://cache.kartverket.no/v1/wmts/1.0.0/topo/default/webmercator/{z}/{y}/{x}.png', 812 { 813 code: 'Nm', 814 isOverlay: true, 815 isOverlayTransparent: false, 816 tms: false, 817 print: true, 818 jnx: true, 819 scaleDependent: true, 820 noCors: false, 821 shortName: 'norway_topo', 822 bounds: [[57.81324, 4.19674], [71.27961, 31.56094]], 823 attribution: '<a href="https://kartverket.no/til-lands/kart/turkart">Kartverket</a>', 824 } 825 ) 826 }, 827 { 828 // Вместо 404 отдают 500 для отсутствующих тайлов 829 title: 'Norway roads', 830 description: '<a href="https://kart.finn.no/">https://kart.finn.no/</a>', 831 isDefault: false, 832 layer: L.tileLayer("https://maptiles1.finncdn.no/tileService/1.0.3/normap/{z}/{x}/{y}.png", 833 { 834 code: 'Nr', 835 isOverlay: true, 836 isOverlayTransparent: false, 837 tms: false, 838 print: true, 839 jnx: true, 840 scaleDependent: true, 841 noCors: false, 842 shortName: 'norway_roads', 843 bounds: [[57.81324, 4.19674], [71.27961, 31.56094]], 844 cutline: getCutline('norway'), 845 attribution: '<a href="https://kart.finn.no/">finn.no</a>', 846 } 847 ) 848 }, 849 { 850 title: 'mapy.cz tourist', 851 isDefault: true, 852 layer: new RetinaTileLayer( 853 [ 854 'https://proxy.nakarte.me/mapy/turist-en/{z}-{x}-{y}', 855 'https://proxy.nakarte.me/mapy/turist-en/retina/{z}-{x}-{y}', 856 ], 857 { 858 code: 'Czt', 859 isOverlay: false, 860 tms: false, 861 print: true, 862 jnx: true, 863 scaleDependent: true, 864 shortName: 'czech_tourist', 865 hotkey: 'H', 866 attribution: '<a href="https://mapy.cz/turisticka">mapy.cz outdoor map</a>', 867 } 868 ) 869 }, 870 { 871 title: 'mapy.cz winter', 872 isDefault: false, 873 layer: new LayerGroupWithOptions([ 874 new L.TileLayer('https://proxy.nakarte.me/mapy/winter-en-down/{z}-{x}-{y}', { 875 tms: false, 876 print: true, 877 isOverlay: false, 878 jnx: true, 879 scaleDependent: true, 880 shortName: 'czech_winter', 881 }), 882 new L.TileLayer('https://proxy.nakarte.me/mapy/winter-en-up/{z}-{x}-{y}', { 883 tms: false, 884 print: true, 885 jnx: false, 886 isOverlay: true, 887 isOverlayTransparent: true, 888 scaleDependent: true, 889 }), 890 ], { 891 code: 'Czw', 892 isOverlay: false, 893 isWrapper: true, 894 attribution: '<a href="https://mapy.cz/zimni">mapy.cz winter map</a>', 895 }), 896 }, 897 { 898 title: 'Finland Topo', 899 description: '<a href="https://laji.fi/en/map/">LAJI.FI</a>', 900 isDefault: false, 901 layer: L.tileLayer( 902 "https://proxy.laji.fi/mml_wmts/maasto/wmts/1.0.0/maastokartta/default/WGS84_Pseudo-Mercator/" + 903 "{z}/{y}/{x}.png", 904 { 905 code: 'Fmk', 906 isOverlay: true, 907 isOverlayTransparent: false, 908 tms: false, 909 print: true, 910 jnx: true, 911 scaleDependent: true, 912 noCors: false, 913 shortName: 'finland_topo', 914 bound: [[59.45416, 19.08321], [70.09211, 31.58671]], 915 cutline: getCutline('finland'), 916 attribution: '<a href="https://laji.fi/en/map/">LAJI.FI</a>', 917 } 918 ) 919 }, 920 { 921 title: 'Great Britain Topo', 922 isDefault: false, 923 layer: new LayerGroupWithOptions( 924 [ 925 new BingLayer(config.bingKey, { 926 type: 'OrdnanceSurvey', 927 minZoom: 12, 928 maxNativeZoom: 16, 929 bounds: [ 930 [49.83793, -7.75643], 931 [60.87164, 1.82356], 932 ], 933 isOverlay: true, 934 isOverlayTransparent: false, 935 scaleDependent: true, 936 print: true, 937 jnx: true, 938 shortName: 'england_topo', 939 cutline: getCutline('great_britain'), 940 attribution: '<a href="https://docs.microsoft.com/en-us/bingmaps/v8-web-control/' + 941 'map-control-api/maptypeid-enumeration">Ordnance Survey</a>', 942 }), 943 new LayerCutlineOverview(getCutline('great_britain'), 11, 'Great Britain Topo (zoom ≥ 12)'), 944 ], 945 { 946 code: 'Gbt', 947 isOverlay: true, 948 isWrapper: true, 949 } 950 ), 951 }, 952 { 953 title: 'Waymarked Cycling Trails', 954 description: 955 '<a href="https://cycling.waymarkedtrails.org/">https://cycling.waymarkedtrails.org</a>', 956 isDefault: false, 957 layer: L.tileLayer('https://tile.waymarkedtrails.org/cycling/{z}/{x}/{y}.png', 958 { 959 code: 'Wc', 960 isOverlay: true, 961 tms: false, 962 print: true, 963 jnx: false, 964 scaleDependent: true, 965 shortName: 'cycling_trails', 966 isOverlayTransparent: true, 967 attribution: '<a href="https://cycling.waymarkedtrails.org/">Waymarked Cycling Trails</a>', 968 }) 969 }, 970 { 971 title: 'Waymarked Hiking Trails', 972 description: '<a href="https://hiking.waymarkedtrails.org/">https://hiking.waymarkedtrails.org</a>', 973 isDefault: false, 974 layer: L.tileLayer('https://tile.waymarkedtrails.org/hiking/{z}/{x}/{y}.png', 975 { 976 code: 'Wh', 977 isOverlay: true, 978 tms: false, 979 print: true, 980 jnx: false, 981 scaleDependent: true, 982 shortName: 'hiking_trails', 983 isOverlayTransparent: true, 984 attribution: '<a href="https://hiking.waymarkedtrails.org/">Waymarked Hiking Trails</a>', 985 }) 986 }, 987 { 988 title: 'Slovakia topo', 989 description: '<a href="https://mapy.hiking.sk">https://mapy.hiking.sk/</a>', 990 isDefault: false, 991 layer: new LayerGroupWithOptions( 992 [ 993 L.tileLayer('https://static.mapy.hiking.sk/topo/{z}/{x}/{y}.png', { 994 isOverlay: true, 995 tms: false, 996 print: true, 997 jnx: true, 998 scaleDependent: true, 999 shortName: 'slovakia_topo', 1000 isOverlayTransparent: false, 1001 maxNativeZoom: 15, 1002 minZoom: 10, 1003 bounds: [ 1004 [47.5172, 16.74316], 1005 [49.91343, 22.74837], 1006 ], 1007 noCors: true, 1008 cutline: getCutline('slovakia'), 1009 attribution: '<a href="https://mapy.hiking.sk/">mapy.hiking.sk</a>', 1010 }), 1011 new LayerCutlineOverview(getCutline('slovakia'), 9, 'Slovakia topo (zoom ≥ 10)'), 1012 ], 1013 { 1014 code: 'St', 1015 isOverlay: true, 1016 isWrapper: true, 1017 } 1018 ), 1019 }, 1020 { 1021 title: 'Spain topo', 1022 isDefault: false, 1023 layer: L.tileLayer( 1024 'https://www.ign.es/wmts/mapa-raster?layer=MTN&style=default&' + 1025 'tilematrixset=GoogleMapsCompatible&Service=WMTS&Request=GetTile&Version=1.0.0&' + 1026 'Format=image%2Fjpeg&TileMatrix={z}&TileCol={x}&TileRow={y}', 1027 { 1028 code: 'Sp', 1029 isOverlay: true, 1030 tms: false, 1031 print: true, 1032 jnx: true, 1033 scaleDependent: true, 1034 shortName: 'spain_topo', 1035 isOverlayTransparent: false, 1036 minZoom: 1, 1037 bounds: [[35.9024, -9.51828], [43.8375, 4.50439]], 1038 noCors: false, 1039 cutline: getCutline('spain'), 1040 attribution: '<a href="https://www.ign.es/iberpix2/visor/">' + 1041 'IGN (Spain) topographic map</a>' 1042 } 1043 ) 1044 }, 1045 { 1046 title: 'Switzerland topo', 1047 isDefault: false, 1048 layer: new RetinaTileLayer( 1049 [ 1050 null, 1051 urlViaCorsProxy( 1052 'https:///wmts10.geo.admin.ch/1.0.0/ch.swisstopo.pixelkarte-farbe/default/current/' + 1053 '3857/{z}/{x}/{y}.jpeg' 1054 ), 1055 ], 1056 1057 { 1058 code: 'Si', 1059 isOverlay: true, 1060 tms: false, 1061 print: true, 1062 jnx: true, 1063 scaleDependent: true, 1064 shortName: 'swiss_topo', 1065 isOverlayTransparent: false, 1066 bounds: [[45.80269, 5.87352], [47.86445, 10.6847]], 1067 noCors: false, 1068 maxNativeZoom: 16, 1069 tileSize: 128, 1070 zoomOffset: 1, 1071 cutline: getCutline('switzerland'), 1072 attribution: '<a href="https://map.geo.admin.ch/?topic=swisstopo&lang=en&bgLayer=' + 1073 'ch.swisstopo.pixelkarte-farbe&E=2586000.76&N=1202020.96&zoom=1">Swisstopo' 1074 }, true 1075 ) 1076 }, 1077 { 1078 title: 'Mountains by Alexander Purikov', 1079 isDefault: false, 1080 layer: L.tileLayer("https://{s}.tiles.nakarte.me/purikov/{z}/{x}/{y}", 1081 { 1082 code: 'Pur', 1083 isOverlay: true, 1084 isOverlayTransparent: false, 1085 tms: true, 1086 scaleDependent: false, 1087 maxNativeZoom: 14, 1088 noCors: false, 1089 print: true, 1090 jnx: true, 1091 shortName: 'purikov_mountains', 1092 attribution: '<a href="https://westra.ru/reports/">Alexander Purikov</a>', 1093 } 1094 ) 1095 }, 1096 { 1097 title: 'Sweden topo', 1098 isDefault: false, 1099 layer: L.tileLayer( 1100 'https://minkarta.lantmateriet.se/map/topowebbcache' + 1101 '?layer=topowebb&style=default&tilematrixset=3857&Service=WMTS&Request=GetTile&Version=1.0.0' + 1102 '&Format=image%2Fpng&TileMatrix={z}&TileCol={x}&TileRow={y}', 1103 { 1104 code: 'Se', 1105 isOverlay: true, 1106 tms: false, 1107 print: true, 1108 jnx: true, 1109 scaleDependent: true, 1110 shortName: 'sweden_topo', 1111 isOverlayTransparent: false, 1112 minZoom: 0, 1113 maxNativeZoom: 17, 1114 bounds: [[55.13493, 10.58876], [69.07200, 24.18365]], 1115 noCors: false, 1116 cutline: getCutline('sweden'), 1117 attribution: '<a href="https://minkarta.lantmateriet.se/">' + 1118 'Lantmäteriet</a>' 1119 } 1120 ) 1121 }, 1122 1123 ]; 1124 1125 const groupsDefs = [ 1126 { 1127 title: 'Default layers', 1128 layers: [ 1129 'OpenStreetMap', 1130 'CyclOSM', 1131 'ESRI Satellite', 1132 'Yandex map', 1133 'Yandex Satellite', 1134 'Google Map', 1135 'Google Satellite', 1136 'Google Terrain', 1137 'Bing Satellite', 1138 'Topomapper 1km', 1139 'Topo 10km', 1140 'GGC 2 km', 1141 'ArbaletMO', 1142 'Mountains by Aleksey Tsvetkov', 1143 'Slazav mountains', 1144 'GGC 1km', 1145 'Topo 1km', 1146 'GGC 500m', 1147 'Topo 500m', 1148 'GGC 250m', 1149 'Slazav Moscow region map', 1150 'Races', 1151 'O-sport', 1152 'Soviet topo maps grid', 1153 'Wikimapia', 1154 'Mountain passes (Westra)' 1155 ], 1156 }, 1157 { 1158 title: 'OpenStreetMap alternatives', 1159 layers: [ 1160 'OpenTopoMap', 1161 'OpenCycleMap', 1162 'OSM Outdoors', 1163 'mapy.cz tourist', 1164 'mapy.cz winter', 1165 1166 ], 1167 }, 1168 { 1169 title: 'Topo maps', 1170 layers: [ 1171 'Eurasia 25km', 1172 'Caucasus 1km', 1173 'Caucasus 500m', 1174 'Topo 250m', 1175 'Montenegro topo 250m', 1176 'Finland Topo', 1177 'Sweden topo', 1178 'Great Britain Topo', 1179 'Slovakia topo', 1180 'Spain topo', 1181 'Switzerland topo', 1182 ], 1183 }, 1184 { 1185 title: 'Miscellaneous', 1186 layers: [ 1187 'Mountains by Alexander Purikov', 1188 'Google Hybrid', 1189 'geocaching.su' 1190 ] 1191 }, 1192 { 1193 title: 'Routes and traces', 1194 layers: [ 1195 'Waymarked Hiking Trails', 1196 'Waymarked Cycling Trails', 1197 'OpenStreetMap GPS traces', 1198 'Strava heatmap (all)', 1199 'Strava heatmap (run)', 1200 'Strava heatmap (ride)', 1201 'Strava heatmap (winter)', 1202 ], 1203 1204 }, 1205 { 1206 title: 'Norway <a href="https://www.ut.no/kart/">https://www.ut.no/kart/</a>', 1207 layers: [ 1208 'Norway paper map', 1209 'Norway topo', 1210 'Norway roads' 1211 ], 1212 1213 }, 1214 ]; 1215 1216 const titlesByOrder = [ 1217 // common base layers 1218 // OSM 1219 'OpenStreetMap', 1220 'CyclOSM', 1221 'OpenTopoMap', 1222 'OpenCycleMap', 1223 'OSM Outdoors', 1224 'mapy.cz tourist', 1225 'mapy.cz winter', 1226 // Satellite 1227 'ESRI Satellite', 1228 'Yandex Satellite', 1229 'Google Satellite', 1230 'Bing Satellite', 1231 // Commercial maps 1232 'Yandex map', 1233 'Google Map', 1234 'Google Terrain', 1235 // Topo maps 1236 'Topomapper 1km', 1237 1238 // local base layers 1239 1240 // map overlays 1241 '#custom-bottom', 1242 'Eurasia 25km', 1243 'Topo 10km', 1244 'GGC 2 km', 1245 'ArbaletMO', 1246 'Norway roads', 1247 'Norway paper map', 1248 'Norway topo', 1249 'Finland Topo', 1250 'Sweden topo', 1251 'Slovakia topo', 1252 'Spain topo', 1253 'Mountains by Alexander Purikov', 1254 'Mountains by Aleksey Tsvetkov', 1255 'Slazav mountains', 1256 'GGC 1km', 1257 'Topo 1km', 1258 'Caucasus 1km', 1259 'Great Britain Topo', 1260 'GGC 500m', 1261 'Topo 500m', 1262 'Caucasus 500m', 1263 'GGC 250m', 1264 'Topo 250m', 1265 'Montenegro topo 250m', 1266 'Switzerland topo', 1267 'Slazav Moscow region map', 1268 'Races', 1269 'O-sport', 1270 '#custom-top', 1271 1272 // line overlays 1273 'Google Hybrid', 1274 'Waymarked Hiking Trails', 1275 'Waymarked Cycling Trails', 1276 'OpenStreetMap GPS traces', 1277 'Strava heatmap (all)', 1278 'Strava heatmap (run)', 1279 'Strava heatmap (ride)', 1280 'Strava heatmap (winter)', 1281 'Soviet topo maps grid', 1282 'Wikimapia', 1283 1284 // point overlays 1285 'Mountain passes (Westra)', 1286 'geocaching.su', 1287 ]; 1288 1289 function getLayers() { 1290 // set metadata 1291 for (let layer of layersDefs) { 1292 layer.layer.meta = {title: layer.title}; 1293 } 1294 1295 // assign order to layers 1296 const orderByTitle = {}; 1297 for (let i = 0; i < titlesByOrder.length; i++) { 1298 let title = titlesByOrder[i]; 1299 orderByTitle[title] = i + 1; 1300 } 1301 1302 for (let layer of layersDefs) { 1303 const title = layer.title; 1304 layer.order = orderByTitle[title]; 1305 if (!layer.order) { 1306 throw new Error(`Layer title not found in titlesByOrder list: ${title}`); 1307 } 1308 } 1309 1310 // divide layers by groups 1311 const grouppedLayers = []; 1312 const layersByTitle = {}; 1313 for (let layer of layersDefs) { 1314 layersByTitle[layer.title] = layer; 1315 } 1316 for (let groupDef of groupsDefs) { 1317 let group = {group: groupDef.title, layers: []}; 1318 grouppedLayers.push(group); 1319 for (let title of groupDef.layers) { 1320 let layer = layersByTitle[title]; 1321 group.layers.push(layer); 1322 } 1323 } 1324 1325 return { 1326 layers: grouppedLayers, 1327 customLayersOrder: { 1328 top: orderByTitle['#custom-top'], 1329 bottom: orderByTitle['#custom-bottom'], 1330 1331 } 1332 }; 1333 } 1334 1335 export {getLayers, layersDefs, groupsDefs, titlesByOrder};