nakarte

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

layers.js (55744B)


      1 import L from "leaflet";
      2 import '~/lib/leaflet.layer.yandex';
      3 import '~/lib/leaflet.layer.google';
      4 import {BingSatLayer, BingOrdnanceSurveyLayer} from '~/lib/leaflet.layer.bing';
      5 import config from './config';
      6 import '~/lib/leaflet.layer.soviet-topomaps-grid';
      7 import '~/lib/leaflet.layer.westraPasses';
      8 import '~/lib/leaflet.layer.wikimapia';
      9 import {GeocachingSu} from '~/lib/leaflet.layer.geocaching-su';
     10 import {RetinaTileLayer} from '~/lib/leaflet.layer.RetinaTileLayer';
     11 import {urlViaCorsProxy} from '~/lib/CORSProxy';
     12 import '~/lib/leaflet.layer.TileLayer.cutline';
     13 import {getCutline} from '~/lib/layers-cutlines';
     14 import {LayerCutlineOverview} from '~/lib/leaflet.layer.LayerCutlineOverview';
     15 
     16 class LayerGroupWithOptions extends L.LayerGroup {
     17     constructor(layers, options) {
     18         super(layers);
     19         L.setOptions(this, options);
     20     }
     21 }
     22 
     23     const layersDefs = [
     24                 {
     25                     title: 'OpenStreetMap',
     26                     isDefault: true,
     27                     layer: L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png',
     28                         {
     29                             code: 'O',
     30                             isOverlay: false,
     31                             scaleDependent: true,
     32                             print: true,
     33                             jnx: true,
     34                             shortName: 'osm',
     35                             attribution: '<a href="https://www.openstreetmap.org/copyright">' +
     36                                 '&copy; OpenStreetMap contributors</a>',
     37                         }
     38                     )
     39                 },
     40                 {
     41                     title: 'CyclOSM',
     42                     isDefault: true,
     43                     layer: L.tileLayer('https://{s}.tile-cyclosm.openstreetmap.fr/cyclosm/{z}/{x}/{y}.png',
     44                         {
     45                             code: 'Co',
     46                             isOverlay: false,
     47                             scaleDependent: true,
     48                             print: true,
     49                             jnx: true,
     50                             shortName: 'cyclosm',
     51                             attribution:
     52                                 '<a href="https://www.openstreetmap.org/copyright">' +
     53                                 '&copy; OpenStreetMap contributors</a>. ' +
     54                                 'Tiles style by <a href="https://www.cyclosm.org/">CyclOSM</a>',
     55                         }
     56                     )
     57                 },
     58                 {
     59                     title: 'ESRI Satellite',
     60                     isDefault: true,
     61                     layer: L.tileLayer(
     62                         'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
     63                         {
     64                             code: 'E',
     65                             isOverlay: false,
     66                             scaleDependent: false,
     67                             maxNativeZoom: 18,
     68                             print: true,
     69                             jnx: true,
     70                             shortName: 'esri',
     71                             attribution:
     72                                 '<a href="https://www.arcgis.com/home/item.html?id=10df2279f9684e4a9f6a7f08febac2a9">' +
     73                                 'ESRI World Imagery for ArcGIS</a>',
     74                         }
     75                     )
     76                 },
     77                 {
     78                     title: 'Yandex map',
     79                     isDefault: true,
     80                     layer: new L.Layer.Yandex.Map(
     81                         {
     82                             scaleDependent: true,
     83                             code: 'Y',
     84                             isOverlay: false,
     85                             print: true,
     86                             jnx: true,
     87                             shortName: 'yandex',
     88                             attribution: '<a href="https://yandex.ru/maps/">Yandex</a>',
     89                         }
     90                     )
     91                 },
     92                 {
     93                     title: 'Yandex Satellite',
     94                     isDefault: true,
     95                     layer: new L.Layer.Yandex.Sat(
     96                         {
     97                             scaleDependent: false,
     98                             code: 'S',
     99                             isOverlay: false,
    100                             print: true,
    101                             jnx: true,
    102                             shortName: 'yandex_sat',
    103                             attribution: '<a href="https://yandex.ru/maps/?l=sat">Yandex</a>',
    104                         }
    105                     )
    106                 },
    107                 {
    108                     title: 'Google Map',
    109                     isDefault: true,
    110                     layer: new L.Layer.GoogleMap(
    111                         {
    112                             code: 'G',
    113                             isOverlay: false,
    114                             scaleDependent: true,
    115                             print: true,
    116                             jnx: true,
    117                             shortName: 'google',
    118                             attribution: '<a href="https://www.google.com/maps">Google</a>',
    119                         }
    120                     )
    121                 },
    122                 {
    123                     title: 'Google Hybrid',
    124                     isDefault: false,
    125                     layer: new L.Layer.GoogleHybrid(
    126                         {
    127                             code: 'Gh',
    128                             isOverlay: true,
    129                             scaleDependent: true,
    130                             print: true,
    131                             jnx: false,
    132                             shortName: 'google_hybrid',
    133                             isOverlayTransparent: true,
    134                             attribution: '<a href="https://www.google.com/maps/@43.0668619,60.5738071,13622628m' +
    135                                 '/data=!3m1!1e3">Google</a>',
    136                         }
    137                     )
    138                 },
    139                 {
    140                     title: 'Google Satellite',
    141                     isDefault: true,
    142                     layer: new L.Layer.GoogleSat(
    143                         {
    144                             code: 'L',
    145                             isOverlay: false,
    146                             scaleDependent: false,
    147                             print: true,
    148                             jnx: true,
    149                             shortName: 'google_sat',
    150                             attribution: '<a href="https://www.google.com/maps/@43.0668619,60.5738071,13622628m' +
    151                                 '/data=!3m1!1e3">Google</a>',
    152                         }
    153                     )
    154                 },
    155                 {
    156                     title: 'Google Terrain',
    157                     isDefault: true,
    158                     layer: new L.Layer.GoogleTerrain({
    159                             code: 'P',
    160                             isOverlay: false,
    161                             scaleDependent: false,
    162                             print: true,
    163                             jnx: true,
    164                             shortName: 'google_terrain',
    165                             attribution: '<a href="https://www.google.com/maps/@43.1203575,42.1105049,9.58z' +
    166                                 '/data=!5m1!1e4">Google</a>',
    167                         }
    168                     )
    169                 },
    170                 {
    171                     title: 'Bing Satellite',
    172                     isDefault: true,
    173                     layer: new BingSatLayer(
    174                         {
    175                             code: 'I',
    176                             isOverlay: false,
    177                             scaleDependent: false,
    178                             print: true,
    179                             jnx: true,
    180                             shortName: 'bing_sat',
    181                             attribution: '<a href="https://www.bing.com/maps?style=h">Microsoft</a>',
    182                         }
    183                     )
    184                 },
    185                 {
    186                     title: 'Soviet topo maps (AtloMaps)',
    187                     isDefault: true,
    188                     layer: L.tileLayer(
    189                         urlViaCorsProxy(
    190                             'https://extern.atlogis.com/rtm/{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: 'soviet_topo',
    201                             attribution:
    202                                 '<a href="https://play.google.com/store/apps/details?id=com.atlogis.atlomaps">' +
    203                                 'AtloMaps</a>',
    204                         }
    205                     )
    206                 },
    207 
    208                 {
    209                     title: 'Topo 10km',
    210                     isDefault: true,
    211                     layer: L.tileLayer("https://{s}.tiles.nakarte.me/topo001m/{z}/{x}/{y}",
    212                         {
    213                             code: 'D',
    214                             isOverlay: true,
    215                             isOverlayTransparent: false,
    216                             tms: true,
    217                             scaleDependent: false,
    218                             maxNativeZoom: 10,
    219                             print: true,
    220                             jnx: true,
    221                             shortName: 'topo_10k'
    222                         }
    223                     )
    224                 },
    225                 {
    226                     title: 'GGC 2 km',
    227                     isDefault: true,
    228                     layer: L.tileLayer("https://{s}.tiles.nakarte.me/ggc2000/{z}/{x}/{y}",
    229                         {
    230                             code: 'N',
    231                             isOverlay: true,
    232                             isOverlayTransparent: false,
    233                             tms: true,
    234                             scaleDependent: false,
    235                             maxNativeZoom: 12,
    236                             print: true,
    237                             jnx: true,
    238                             shortName: 'ggc_2k'
    239                         }
    240                     )
    241                 },
    242                 {
    243                     title: 'ArbaletMO',
    244                     isDefault: true,
    245                     layer: L.tileLayer("https://{s}.tiles.nakarte.me/ArbaletMO/{z}/{x}/{y}",
    246                         {
    247                             code: 'A',
    248                             isOverlay: true,
    249                             isOverlayTransparent: false,
    250                             tms: true,
    251                             scaleDependent: false,
    252                             maxNativeZoom: 13,
    253                             print: true,
    254                             jnx: true,
    255                             shortName: 'arbalet',
    256                             attribution:
    257                                 '<a href="http://www.velozona.ru/forums/showmessage.php?id=3370">Arbalet (2004)</a>',
    258                         }
    259                     )
    260                 },
    261                 {
    262                     title: 'Slazav mountains',
    263                     isDefault: true,
    264                     layer: L.tileLayer("https://slazav.xyz/tiles/hr/{x}-{y}-{z}.png",
    265                         {
    266                             code: 'Q',
    267                             isOverlay: true,
    268                             isOverlayTransparent: false,
    269                             tms: false,
    270                             scaleDependent: false,
    271                             maxNativeZoom: 13,
    272                             noCors: true,
    273                             print: true,
    274                             jnx: true,
    275                             shortName: 'slazav_mountains',
    276                             attribution: '<a href="http://slazav.xyz/maps">Vladislav Zavjalov</a>',
    277                         }
    278                     )
    279                 },
    280                 {
    281                     title: 'GGC 1km',
    282                     isDefault: true,
    283                     layer: L.tileLayer("https://{s}.tiles.nakarte.me/ggc1000/{z}/{x}/{y}",
    284                         {
    285                             code: 'J',
    286                             isOverlay: true,
    287                             isOverlayTransparent: false,
    288                             tms: true,
    289                             scaleDependent: false,
    290                             maxNativeZoom: 13,
    291                             print: true,
    292                             jnx: true,
    293                             shortName: 'ggc_1k'
    294                         }
    295                     )
    296                 },
    297                 {
    298                     title: 'Topo 1km',
    299                     isDefault: true,
    300                     layer: L.tileLayer("https://{s}.tiles.nakarte.me/topo1000/{z}/{x}/{y}",
    301                         {
    302                             code: 'C',
    303                             isOverlay: true,
    304                             isOverlayTransparent: false,
    305                             tms: true,
    306                             scaleDependent: false,
    307                             maxNativeZoom: 13,
    308                             print: true,
    309                             jnx: true,
    310                             shortName: 'topo_1k'
    311                         }
    312                     )
    313                 },
    314                 {
    315                     title: 'GGC 500m',
    316                     isDefault: true,
    317                     layer: L.tileLayer("https://{s}.tiles.nakarte.me/ggc500/{z}/{x}/{y}",
    318                         {
    319                             code: 'F',
    320                             isOverlay: true,
    321                             isOverlayTransparent: false,
    322                             tms: true,
    323                             scaleDependent: false,
    324                             maxNativeZoom: 14,
    325                             print: true,
    326                             jnx: true,
    327                             shortName: 'ggc_500'
    328                         }
    329                     )
    330                 },
    331                 {
    332                     title: 'Topo 500m',
    333                     isDefault: true,
    334                     layer: L.tileLayer("https://{s}.tiles.nakarte.me/topo500/{z}/{x}/{y}",
    335                         {
    336                             code: 'B',
    337                             isOverlay: true,
    338                             isOverlayTransparent: false,
    339                             tms: true,
    340                             scaleDependent: false,
    341                             maxNativeZoom: 14,
    342                             print: true,
    343                             jnx: true,
    344                             shortName: 'topo_500'
    345                         }
    346                     )
    347                 },
    348                 {
    349                     title: 'GGC 250m',
    350                     isDefault: true,
    351                     layer: L.tileLayer("https://{s}.tiles.nakarte.me/ggc250/{z}/{x}/{y}",
    352                         {
    353                             code: 'K',
    354                             isOverlay: true,
    355                             isOverlayTransparent: false,
    356                             tms: true,
    357                             scaleDependent: false,
    358                             maxNativeZoom: 15,
    359                             print: true,
    360                             jnx: true,
    361                             shortName: 'ggc_250'
    362                         }
    363                     )
    364                 },
    365                 {
    366                     title: 'Slazav Moscow region map',
    367                     isDefault: true,
    368                     layer: L.tileLayer("https://slazav.xyz/tiles/podm/{x}-{y}-{z}.png",
    369                         {
    370                             code: 'Z',
    371                             isOverlay: true,
    372                             isOverlayTransparent: false,
    373                             tms: false,
    374                             scaleDependent: false,
    375                             maxNativeZoom: 14,
    376                             noCors: true,
    377                             print: true,
    378                             jnx: true,
    379                             shortName: 'slazav',
    380                             attribution: '<a href="http://slazav.xyz/maps">Vladislav Zavjalov</a>',
    381                         }
    382                     )
    383                 },
    384                 {
    385                     title: 'Races',
    386                     isDefault: true,
    387                     layer: L.tileLayer("https://{s}.tiles.nakarte.me/adraces/{z}/{x}/{y}",
    388                         {
    389                             code: 'U',
    390                             isOverlay: true,
    391                             isOverlayTransparent: false,
    392                             tms: true,
    393                             scaleDependent: false,
    394                             maxNativeZoom: 15,
    395                             print: true,
    396                             jnx: true,
    397                             shortName: 'races'
    398                         }
    399                     )
    400                 },
    401                 {
    402                     title: 'O-sport',
    403                     isDefault: true,
    404                     layer: L.tileLayer("https://{s}.tiles.nakarte.me/osport/{z}/{x}/{y}",
    405                         {
    406                             code: 'R',
    407                             isOverlay: true,
    408                             isOverlayTransparent: false,
    409                             tms: true,
    410                             scaleDependent: false,
    411                             maxNativeZoom: 17,
    412                             print: true,
    413                             jnx: true,
    414                             shortName: 'osport'
    415                         }
    416                     )
    417                 },
    418                 {
    419                     title: 'Soviet topo maps grid',
    420                     isDefault: true,
    421                     layer: new L.Layer.SovietTopoGrid({
    422                         code: 'Ng',
    423                         isOverlay: true,
    424                         print: false,
    425                         jnx: false
    426                     })
    427                 },
    428                 {
    429                     title: 'Wikimapia',
    430                     isDefault: true,
    431                     layer: new L.Wikimapia({
    432                         code: 'W',
    433                         isOverlay: true,
    434                         print: false,
    435                         jnx: false,
    436                         attribution: '<a href="https://wikimapia.org/">Wikimapia</a>',
    437                         tilesBaseUrl: config.wikimapiaTilesBaseUrl,
    438                     })
    439                 },
    440                 {
    441                     title: 'Mountain passes (Westra)',
    442                     isDefault: true,
    443                     layer: new L.Layer.WestraPasses(config.westraDataBaseUrl, {
    444                         code: 'Wp',
    445                         print: true,
    446                         jnx: false,
    447                         scaleDependent: true,
    448                         isOverlay: true,
    449                         isOverlayTransparent: true,
    450                         shortName: 'passes',
    451                         markersOptions: {
    452                             isOverlay: true,
    453                             isOverlayTransparent: true,
    454                             shortName: 'passes'
    455                         },
    456                         attribution: '<a href="http://westra.ru/passes/">Westra passes catalog</a>',
    457                     })
    458                 },
    459                 {
    460                     title: 'OpenTopoMap',
    461                     isDefault: false,
    462                     layer: L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png',
    463                         {
    464                             code: 'Otm',
    465                             isOverlay: false,
    466                             maxNativeZoom: 15,
    467                             scaleDependent: true,
    468                             print: true,
    469                             jnx: true,
    470                             noCors: false,
    471                             shortName: 'opentopo',
    472                             attribution: '<a href="https://opentopomap.org/">OpenTopoMap</a>',
    473                             hotkey: 'V',
    474                         }
    475                     )
    476                 },
    477                 {
    478                     title: 'OpenCycleMap',
    479                     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                     isDefault: true,
    608                     layer: new LayerGroupWithOptions(
    609                         [
    610                             L.tileLayer(
    611                                 urlViaCorsProxy(
    612                                     'https://maptiles.website.yandexcloud.net/{z}/{x}/{y}.png'
    613                                 ),
    614                                 {
    615                                     isOverlay: true,
    616                                     isOverlayTransparent: false,
    617                                     tms: false,
    618                                     minZoom: 2,
    619                                     maxNativeZoom: 15,
    620                                     print: true,
    621                                     jnx: true,
    622                                     scaleDependent: false,
    623                                     noCors: false,
    624                                     shortName: 'tsvetkov_mountains',
    625                                     cutline: getCutline('tsvetkov_mountains'),
    626                                     bounds: [
    627                                         [40.66664, 71.00007],
    628                                         [45.33338, 81.00001],
    629                                     ],
    630                                     attribution: '<a href="http://pereval.g-utka.ru/">Aleksey Tsvetkov</a>',
    631                                 }
    632                             ),
    633                             new LayerCutlineOverview(getCutline('tsvetkov_mountains'), 6,
    634                                 'Mountains by Aleksey Tsvetkov'),
    635                         ],
    636                         {
    637                             code: 'Mt',
    638                             isOverlay: true,
    639                             isWrapper: true,
    640                         }
    641                     ),
    642                 },
    643                 {
    644                     title: 'geocaching.su',
    645                     isDefault: false,
    646                     layer: new GeocachingSu(config.geocachingSuUrl, {
    647                         code: 'Gc',
    648                         isOverlay: true,
    649                         isOverlayTransparent: true,
    650                         print: true,
    651                         jnx: false,
    652                         shortName: 'geocaching',
    653                         attribution: '<a href="https://geocaching.su/">geocaching.su</a>',
    654                     })
    655                 },
    656                 {
    657                     title: 'OpenStreetMap GPS traces',
    658                     isDefault: false,
    659                     layer: L.tileLayer('https://{s}.gps-tile.openstreetmap.org/lines/{z}/{x}/{y}.png',
    660                         {
    661                             code: 'Ot',
    662                             isOverlay: true,
    663                             isOverlayTransparent: true,
    664                             scaleDependent: true,
    665                             print: true,
    666                             jnx: false,
    667                             shortName: 'osm_gps_traces',
    668                             attribution: '<a href="https://www.openstreetmap.org/#&layers=G">' +
    669                                 'OpenStreetMap public GPS traces</a>',
    670                         }
    671                     )
    672                 },
    673                 {
    674                     title: 'Strava heatmap (all)',
    675                     isDefault: false,
    676                     layer: new RetinaTileLayer(
    677                         [
    678                             urlViaCorsProxy(
    679                                 'https://content-a.strava.com/identified/globalheat/all/hot/{z}/{x}/{y}.png?px=256'
    680                             ),
    681                             urlViaCorsProxy(
    682                                 'https://content-a.strava.com/identified/globalheat/all/hot/{z}/{x}/{y}.png?px=512'
    683                             ),
    684                         ],
    685                         {
    686                             code: 'Sa',
    687                             isOverlay: true,
    688                             isOverlayTransparent: true,
    689                             scaleDependent: false,
    690                             print: true,
    691                             jnx: false,
    692                             subdomains: 'abc',
    693                             noCors: false,
    694                             shortName: 'strava_all',
    695                             retinaOptionsOverrides: [{maxNativeZoom: 16}, {maxNativeZoom: 15}],
    696                             attribution: '<a href="https://www.strava.com/heatmap">Strava Global Heatmap</a>',
    697                             opacity: 0.75,
    698                         }
    699                     )
    700                 },
    701                 {
    702                     title: 'Strava heatmap (run)',
    703                     isDefault: false,
    704                     layer: new RetinaTileLayer(
    705                         [
    706                             urlViaCorsProxy(
    707                                 'https://content-a.strava.com/identified/globalheat/run/hot/{z}/{x}/{y}.png?px=256'
    708                             ),
    709                             urlViaCorsProxy(
    710                                 'https://content-a.strava.com/identified/globalheat/run/hot/{z}/{x}/{y}.png?px=512'
    711                             ),
    712                         ],
    713                         {
    714                             code: 'Sr',
    715                             isOverlay: true,
    716                             isOverlayTransparent: true,
    717                             scaleDependent: false,
    718                             print: true,
    719                             jnx: false,
    720                             subdomains: 'abc',
    721                             noCors: false,
    722                             shortName: 'strava_run',
    723                             retinaOptionsOverrides: [{maxNativeZoom: 16}, {maxNativeZoom: 15}],
    724                             attribution: '<a href="https://www.strava.com/heatmap">Strava Global Heatmap</a>',
    725                             opacity: 0.75,
    726                         }
    727                     )
    728                 },
    729                 {
    730                     title: 'Strava heatmap (ride)',
    731                     isDefault: false,
    732                     layer: new RetinaTileLayer(
    733                         [
    734                             urlViaCorsProxy(
    735                                 'https://content-a.strava.com/identified/globalheat/ride/hot/{z}/{x}/{y}.png?px=256'
    736                             ),
    737                             urlViaCorsProxy(
    738                                 'https://content-a.strava.com/identified/globalheat/ride/hot/{z}/{x}/{y}.png?px=512'
    739                             ),
    740                         ],
    741                         {
    742                             code: 'Sb',
    743                             isOverlay: true,
    744                             isOverlayTransparent: true,
    745                             scaleDependent: false,
    746                             print: true,
    747                             jnx: false,
    748                             subdomains: 'abc',
    749                             noCors: false,
    750                             shortName: 'strava_ride',
    751                             retinaOptionsOverrides: [{maxNativeZoom: 16}, {maxNativeZoom: 15}],
    752                             attribution: '<a href="https://www.strava.com/heatmap">Strava Global Heatmap</a>',
    753                             opacity: 0.75,
    754                         }
    755                     )
    756                 },
    757                 {
    758                     title: 'Strava heatmap (winter)',
    759                     isDefault: false,
    760                     layer: new RetinaTileLayer(
    761                         [
    762                             urlViaCorsProxy(
    763                                 'https://content-a.strava.com/identified/globalheat/winter/hot/{z}/{x}/{y}.png?px=256'
    764                             ),
    765                             urlViaCorsProxy(
    766                                 'https://content-a.strava.com/identified/globalheat/winter/hot/{z}/{x}/{y}.png?px=512'
    767                             ),
    768                         ],
    769                         {
    770                             code: 'Sw',
    771                             isOverlay: true,
    772                             isOverlayTransparent: true,
    773                             scaleDependent: false,
    774                             print: true,
    775                             jnx: false,
    776                             subdomains: 'abc',
    777                             noCors: false,
    778                             shortName: 'strava_winter',
    779                             retinaOptionsOverrides: [{maxNativeZoom: 16}, {maxNativeZoom: 15}],
    780                             attribution: '<a href="https://www.strava.com/heatmap">Strava Global Heatmap</a>',
    781                             opacity: 0.75,
    782                         }
    783                     )
    784                 },
    785                 {
    786                     title: 'Norway paper map',
    787                     isDefault: false,
    788                     layer: new L.TileLayer(
    789                         'https://cache.kartverket.no/v1/wmts/1.0.0/toporaster/default/webmercator/{z}/{y}/{x}.png',
    790                         {
    791                             code: 'Np',
    792                             isOverlay: true,
    793                             isOverlayTransparent: false,
    794                             tms: false,
    795                             print: true,
    796                             jnx: true,
    797                             scaleDependent: true,
    798                             noCors: false,
    799                             shortName: 'norway_paper',
    800                             bounds: [[57.81324, 4.19674], [71.27961, 31.56094]],
    801                             attribution: '<a href="https://kartverket.no/til-lands/kart/turkart">Kartverket</a>',
    802                         }
    803                     )
    804                 },
    805                 {
    806                     title: 'Norway topo',
    807                     isDefault: false,
    808                     layer: new L.TileLayer(
    809                         'https://cache.kartverket.no/v1/wmts/1.0.0/topo/default/webmercator/{z}/{y}/{x}.png',
    810                         {
    811                             code: 'Nm',
    812                             isOverlay: true,
    813                             isOverlayTransparent: false,
    814                             tms: false,
    815                             print: true,
    816                             jnx: true,
    817                             scaleDependent: true,
    818                             noCors: false,
    819                             shortName: 'norway_topo',
    820                             bounds: [[57.81324, 4.19674], [71.27961, 31.56094]],
    821                             attribution: '<a href="https://kartverket.no/til-lands/kart/turkart">Kartverket</a>',
    822                         }
    823                     )
    824                 },
    825                 {
    826                     // Вместо 404 отдают 500 для отсутствующих тайлов
    827                     title: 'Norway roads',
    828                     isDefault: false,
    829                     layer: L.tileLayer("https://maptiles1.finncdn.no/tileService/1.0.3/normap/{z}/{x}/{y}.png",
    830                         {
    831                             code: 'Nr',
    832                             isOverlay: true,
    833                             isOverlayTransparent: false,
    834                             tms: false,
    835                             print: true,
    836                             jnx: true,
    837                             scaleDependent: true,
    838                             noCors: false,
    839                             shortName: 'norway_roads',
    840                             bounds: [[57.81324, 4.19674], [71.27961, 31.56094]],
    841                             cutline: getCutline('norway'),
    842                             attribution: '<a href="https://kart.finn.no/">finn.no</a>',
    843                         }
    844                     )
    845                 },
    846                 {
    847                     title: 'mapy.cz tourist (Out of order)',
    848                     isDefault: true,
    849                     layer: new RetinaTileLayer(
    850                         [
    851                             'https://proxy.nakarte.me/mapy/turist-en/{z}-{x}-{y}',
    852                             'https://proxy.nakarte.me/mapy/turist-en/retina/{z}-{x}-{y}',
    853                         ],
    854                         {
    855                             code: 'Czt',
    856                             isOverlay: false,
    857                             tms: false,
    858                             print: true,
    859                             jnx: true,
    860                             scaleDependent: true,
    861                             shortName: 'czech_tourist',
    862                             hotkey: 'H',
    863                             attribution: '<a href="https://mapy.cz/turisticka">mapy.cz outdoor map</a>',
    864                             maxZoom: -1,
    865                         }
    866                     )
    867                 },
    868                 {
    869                     title: 'mapy.cz winter (Out of order)',
    870                     isDefault: false,
    871                     layer: new LayerGroupWithOptions([
    872                         new L.TileLayer('https://proxy.nakarte.me/mapy/winter-en-down/{z}-{x}-{y}', {
    873                             tms: false,
    874                             print: true,
    875                             isOverlay: false,
    876                             jnx: true,
    877                             scaleDependent: true,
    878                             shortName: 'czech_winter',
    879                         }),
    880                         new L.TileLayer('https://proxy.nakarte.me/mapy/winter-en-up/{z}-{x}-{y}', {
    881                             tms: false,
    882                             print: true,
    883                             jnx: false,
    884                             isOverlay: true,
    885                             isOverlayTransparent: true,
    886                             scaleDependent: true,
    887                         }),
    888                     ], {
    889                         code: 'Czw',
    890                         isOverlay: false,
    891                         isWrapper: true,
    892                         attribution: '<a href="https://mapy.cz/zimni">mapy.cz winter map</a>',
    893                         maxZoom: -1,
    894                     }),
    895                 },
    896                 {
    897                     title: 'Finland Topo',
    898                     isDefault: false,
    899                     layer: L.tileLayer(
    900                         "https://proxy.laji.fi/mml_wmts/maasto/wmts/1.0.0/maastokartta/default/WGS84_Pseudo-Mercator/" +
    901                         "{z}/{y}/{x}.png",
    902                         {
    903                             code: 'Fmk',
    904                             isOverlay: true,
    905                             isOverlayTransparent: false,
    906                             tms: false,
    907                             print: true,
    908                             jnx: true,
    909                             scaleDependent: true,
    910                             noCors: false,
    911                             shortName: 'finland_topo',
    912                             bound: [[59.45416, 19.08321], [70.09211, 31.58671]],
    913                             cutline: getCutline('finland'),
    914                             attribution: '<a href="https://laji.fi/en/map/">LAJI.FI</a>',
    915                         }
    916                     )
    917                 },
    918                 {
    919                     title: 'Great Britain Topo',
    920                     isDefault: false,
    921                     layer: new LayerGroupWithOptions(
    922                         [
    923                             new BingOrdnanceSurveyLayer({
    924                                 minZoom: 12,
    925                                 maxNativeZoom: 16,
    926                                 bounds: [
    927                                     [49.83793, -7.75643],
    928                                     [60.87164, 1.82356],
    929                                 ],
    930                                 isOverlay: true,
    931                                 isOverlayTransparent: false,
    932                                 scaleDependent: true,
    933                                 print: true,
    934                                 jnx: true,
    935                                 shortName: 'england_topo',
    936                                 cutline: getCutline('great_britain'),
    937                                 attribution: '<a href="https://docs.microsoft.com/en-us/bingmaps/v8-web-control/' +
    938                                     'map-control-api/maptypeid-enumeration">Ordnance Survey</a>',
    939                             }),
    940                             new LayerCutlineOverview(getCutline('great_britain'), 11, 'Great Britain Topo (zoom ≥ 12)'),
    941                         ],
    942                         {
    943                             code: 'Gbt',
    944                             isOverlay: true,
    945                             isWrapper: true,
    946                         }
    947                     ),
    948                 },
    949                 {
    950                     title: 'Waymarked Cycling Trails',
    951                     isDefault: false,
    952                     layer: L.tileLayer('https://tile.waymarkedtrails.org/cycling/{z}/{x}/{y}.png',
    953                         {
    954                             code: 'Wc',
    955                             isOverlay: true,
    956                             tms: false,
    957                             print: true,
    958                             jnx: false,
    959                             scaleDependent: true,
    960                             shortName: 'cycling_trails',
    961                             isOverlayTransparent: true,
    962                             attribution: '<a href="https://cycling.waymarkedtrails.org/">Waymarked Cycling Trails</a>',
    963                         })
    964                 },
    965                 {
    966                     title: 'Waymarked Hiking Trails',
    967                     isDefault: false,
    968                     layer: L.tileLayer('https://tile.waymarkedtrails.org/hiking/{z}/{x}/{y}.png',
    969                         {
    970                             code: 'Wh',
    971                             isOverlay: true,
    972                             tms: false,
    973                             print: true,
    974                             jnx: false,
    975                             scaleDependent: true,
    976                             shortName: 'hiking_trails',
    977                             isOverlayTransparent: true,
    978                             attribution: '<a href="https://hiking.waymarkedtrails.org/">Waymarked Hiking Trails</a>',
    979                         })
    980                 },
    981                 {
    982                     title: 'Slovakia topo',
    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: 'Spain topo',
   1015                     isDefault: false,
   1016                     layer: L.tileLayer(
   1017                             'https://www.ign.es/wmts/mapa-raster?layer=MTN&style=default&' +
   1018                             'tilematrixset=GoogleMapsCompatible&Service=WMTS&Request=GetTile&Version=1.0.0&' +
   1019                             'Format=image%2Fjpeg&TileMatrix={z}&TileCol={x}&TileRow={y}',
   1020                             {
   1021                                 code: 'Sp',
   1022                                 isOverlay: true,
   1023                                 tms: false,
   1024                                 print: true,
   1025                                 jnx: true,
   1026                                 scaleDependent: true,
   1027                                 shortName: 'spain_topo',
   1028                                 isOverlayTransparent: false,
   1029                                 minZoom: 1,
   1030                                 bounds: [[35.9024, -9.51828], [43.8375, 4.50439]],
   1031                                 noCors: false,
   1032                                 cutline: getCutline('spain'),
   1033                                 attribution: '<a href="https://www.ign.es/iberpix2/visor/">' +
   1034                                     'IGN (Spain) topographic map</a>'
   1035                             }
   1036                     )
   1037                 },
   1038                 {
   1039                     title: 'Switzerland topo',
   1040                     isDefault: false,
   1041                     layer: new RetinaTileLayer(
   1042                         [
   1043                             null,
   1044                             urlViaCorsProxy(
   1045                                 'https:///wmts10.geo.admin.ch/1.0.0/ch.swisstopo.pixelkarte-farbe/default/current/' +
   1046                                 '3857/{z}/{x}/{y}.jpeg'
   1047                             ),
   1048                         ],
   1049 
   1050                         {
   1051                                 code: 'Si',
   1052                                 isOverlay: true,
   1053                                 tms: false,
   1054                                 print: true,
   1055                                 jnx: true,
   1056                                 scaleDependent: true,
   1057                                 shortName: 'swiss_topo',
   1058                                 isOverlayTransparent: false,
   1059                                 bounds: [[45.80269, 5.87352], [47.86445, 10.6847]],
   1060                                 noCors: false,
   1061                                 maxNativeZoom: 16,
   1062                                 tileSize: 128,
   1063                                 zoomOffset: 1,
   1064                                 cutline: getCutline('switzerland'),
   1065                                 attribution: '<a href="https://map.geo.admin.ch/?topic=swisstopo&lang=en&bgLayer=' +
   1066                                     'ch.swisstopo.pixelkarte-farbe&E=2586000.76&N=1202020.96&zoom=1">Swisstopo'
   1067                             }, true
   1068                     )
   1069                 },
   1070                 {
   1071                     title: 'Mountains by Alexander Purikov',
   1072                     isDefault: false,
   1073                     layer: L.tileLayer("https://{s}.tiles.nakarte.me/purikov/{z}/{x}/{y}",
   1074                         {
   1075                             code: 'Pur',
   1076                             isOverlay: true,
   1077                             isOverlayTransparent: false,
   1078                             tms: true,
   1079                             scaleDependent: false,
   1080                             maxNativeZoom: 14,
   1081                             noCors: false,
   1082                             print: true,
   1083                             jnx: true,
   1084                             shortName: 'purikov_mountains',
   1085                             attribution: '<a href="https://westra.ru/reports/">Alexander Purikov</a>',
   1086                         }
   1087                     )
   1088                 },
   1089                 {
   1090                     title: 'Sweden topo',
   1091                     isDefault: false,
   1092                     layer: L.tileLayer(
   1093                         'https://minkarta.lantmateriet.se/map/topowebbcache' +
   1094                         '?layer=topowebb&style=default&tilematrixset=3857&Service=WMTS&Request=GetTile&Version=1.0.0' +
   1095                         '&Format=image%2Fpng&TileMatrix={z}&TileCol={x}&TileRow={y}',
   1096                         {
   1097                             code: 'Se',
   1098                             isOverlay: true,
   1099                             tms: false,
   1100                             print: true,
   1101                             jnx: true,
   1102                             scaleDependent: true,
   1103                             shortName: 'sweden_topo',
   1104                             isOverlayTransparent: false,
   1105                             minZoom: 0,
   1106                             maxNativeZoom: 17,
   1107                             bounds: [[55.13493, 10.58876], [69.07200, 24.18365]],
   1108                             noCors: false,
   1109                             cutline: getCutline('sweden'),
   1110                             attribution: '<a href="https://minkarta.lantmateriet.se/">' +
   1111                                 'Lantmäteriet</a>'
   1112                         }
   1113                     )
   1114                 },
   1115 
   1116     ];
   1117 
   1118     const groupsDefs = [
   1119         {
   1120             title: 'Default layers',
   1121             layers: [
   1122                 'OpenStreetMap',
   1123                 'CyclOSM',
   1124                 'ESRI Satellite',
   1125                 'Yandex map',
   1126                 'Yandex Satellite',
   1127                 'Google Map',
   1128                 'Google Satellite',
   1129                 'Google Terrain',
   1130                 'Bing Satellite',
   1131                 'Soviet topo maps (AtloMaps)',
   1132                 'Topo 10km',
   1133                 'GGC 2 km',
   1134                 'ArbaletMO',
   1135                 'Mountains by Aleksey Tsvetkov',
   1136                 'Slazav mountains',
   1137                 'GGC 1km',
   1138                 'Topo 1km',
   1139                 'GGC 500m',
   1140                 'Topo 500m',
   1141                 'GGC 250m',
   1142                 'Slazav Moscow region map',
   1143                 'Races',
   1144                 'O-sport',
   1145                 'Soviet topo maps grid',
   1146                 'Wikimapia',
   1147                 'Mountain passes (Westra)'
   1148             ],
   1149         },
   1150         {
   1151             title: 'OpenStreetMap alternatives',
   1152             layers: [
   1153                 'OpenTopoMap',
   1154                 'OpenCycleMap',
   1155                 'OSM Outdoors',
   1156                 'mapy.cz tourist (Out of order)',
   1157                 'mapy.cz winter (Out of order)',
   1158 
   1159             ],
   1160         },
   1161         {
   1162             title: 'Topo maps',
   1163             layers: [
   1164                 'Eurasia 25km',
   1165                 'Caucasus 1km',
   1166                 'Caucasus 500m',
   1167                 'Topo 250m',
   1168                 'Montenegro topo 250m',
   1169                 'Finland Topo',
   1170                 'Sweden topo',
   1171                 'Great Britain Topo',
   1172                 'Slovakia topo',
   1173                 'Spain topo',
   1174                 'Switzerland topo',
   1175             ],
   1176         },
   1177         {
   1178             title: 'Miscellaneous',
   1179             layers: [
   1180                 'Mountains by Alexander Purikov',
   1181                 'Google Hybrid',
   1182                 'geocaching.su'
   1183             ]
   1184         },
   1185         {
   1186             title: 'Routes and traces',
   1187             layers: [
   1188                 'Waymarked Hiking Trails',
   1189                 'Waymarked Cycling Trails',
   1190                 'OpenStreetMap GPS traces',
   1191                 'Strava heatmap (all)',
   1192                 'Strava heatmap (run)',
   1193                 'Strava heatmap (ride)',
   1194                 'Strava heatmap (winter)',
   1195             ],
   1196 
   1197         },
   1198         {
   1199             title: 'Norway',
   1200             layers: [
   1201                 'Norway paper map',
   1202                 'Norway topo',
   1203                 'Norway roads'
   1204             ],
   1205 
   1206         },
   1207     ];
   1208 
   1209     const titlesByOrder = [
   1210         // common base layers
   1211         // OSM
   1212         'OpenStreetMap',
   1213         'CyclOSM',
   1214         'OpenTopoMap',
   1215         'OpenCycleMap',
   1216         'OSM Outdoors',
   1217         'mapy.cz tourist (Out of order)',
   1218         'mapy.cz winter (Out of order)',
   1219         // Satellite
   1220         'ESRI Satellite',
   1221         'Yandex Satellite',
   1222         'Google Satellite',
   1223         'Bing Satellite',
   1224         // Commercial maps
   1225         'Yandex map',
   1226         'Google Map',
   1227         'Google Terrain',
   1228         // Topo maps
   1229         'Soviet topo maps (AtloMaps)',
   1230 
   1231         // local base layers
   1232 
   1233         // map overlays
   1234         '#custom-bottom',
   1235         'Eurasia 25km',
   1236         'Topo 10km',
   1237         'GGC 2 km',
   1238         'ArbaletMO',
   1239         'Norway roads',
   1240         'Norway paper map',
   1241         'Norway topo',
   1242         'Finland Topo',
   1243         'Sweden topo',
   1244         'Slovakia topo',
   1245         'Spain topo',
   1246         'Mountains by Alexander Purikov',
   1247         'Mountains by Aleksey Tsvetkov',
   1248         'Slazav mountains',
   1249         'GGC 1km',
   1250         'Topo 1km',
   1251         'Caucasus 1km',
   1252         'Great Britain Topo',
   1253         'GGC 500m',
   1254         'Topo 500m',
   1255         'Caucasus 500m',
   1256         'GGC 250m',
   1257         'Topo 250m',
   1258         'Montenegro topo 250m',
   1259         'Switzerland topo',
   1260         'Slazav Moscow region map',
   1261         'Races',
   1262         'O-sport',
   1263         '#custom-top',
   1264 
   1265         // line overlays
   1266         'Google Hybrid',
   1267         'Waymarked Hiking Trails',
   1268         'Waymarked Cycling Trails',
   1269         'OpenStreetMap GPS traces',
   1270         'Strava heatmap (all)',
   1271         'Strava heatmap (run)',
   1272         'Strava heatmap (ride)',
   1273         'Strava heatmap (winter)',
   1274         'Soviet topo maps grid',
   1275         'Wikimapia',
   1276 
   1277         // point overlays
   1278         'Mountain passes (Westra)',
   1279         'geocaching.su',
   1280     ];
   1281 
   1282 function getLayers() {
   1283     // set metadata
   1284     for (let layer of layersDefs) {
   1285         layer.layer.meta = {title: layer.title};
   1286     }
   1287 
   1288     // assign order to layers
   1289     const orderByTitle = {};
   1290     for (let i = 0; i < titlesByOrder.length; i++) {
   1291         let title = titlesByOrder[i];
   1292         orderByTitle[title] = i + 1;
   1293     }
   1294 
   1295     for (let layer of layersDefs) {
   1296         const title = layer.title;
   1297         layer.order = orderByTitle[title];
   1298         if (!layer.order) {
   1299             throw new Error(`Layer title not found in titlesByOrder list: ${title}`);
   1300         }
   1301     }
   1302 
   1303     // divide layers by groups
   1304     const grouppedLayers = [];
   1305     const layersByTitle = {};
   1306     for (let layer of layersDefs) {
   1307         layersByTitle[layer.title] = layer;
   1308     }
   1309     for (let groupDef of groupsDefs) {
   1310         let group = {group: groupDef.title, layers: []};
   1311         grouppedLayers.push(group);
   1312         for (let title of groupDef.layers) {
   1313             let layer = layersByTitle[title];
   1314             group.layers.push(layer);
   1315         }
   1316     }
   1317 
   1318     return {
   1319         layers: grouppedLayers,
   1320         customLayersOrder: {
   1321             top: orderByTitle['#custom-top'],
   1322             bottom: orderByTitle['#custom-bottom'],
   1323 
   1324         }
   1325     };
   1326 }
   1327 
   1328 export {getLayers, layersDefs, groupsDefs, titlesByOrder};