nakarte

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

layers.js (55677B)


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