nakarte

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

layers.js (56362B)


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