nakarte

Source code of https://map.sikmir.ru (fork)
git clone git://git.sikmir.ru/nakarte
Log | Files | Refs | LICENSE

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                                 '&copy; 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                                 '&copy; 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};