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