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