nakarte

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

layers.js (55853B)


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