nakarte

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

westraPassesMarkers.js (10258B)


      1 import L from 'leaflet';
      2 import '~/lib/leaflet.layer.canvasMarkers';
      3 import {openPopupWindow} from '~/lib/popup-window';
      4 import escapeHtml from 'escape-html';
      5 import {saveAs} from '~/vendored/github.com/eligrey/FileSaver';
      6 import iconFromBackgroundImage from '~/lib/iconFromBackgroundImage';
      7 import {fetch} from '~/lib/xhr-promise';
      8 import {notify} from '~/lib/notifications';
      9 import * as logging from '~/lib/logging';
     10 
     11 const WestraPassesMarkers = L.Layer.CanvasMarkers.extend({
     12         options: {
     13             filePasses: 'westra_passes.json',
     14             scaleDependent: true
     15         },
     16 
     17         initialize: function(baseUrl, options) {
     18             L.Layer.CanvasMarkers.prototype.initialize.call(this, null, options);
     19             this.on('markerclick', this.showPassDescription, this);
     20             this._baseUrl = baseUrl;
     21             this.url = baseUrl + this.options.filePasses;
     22         },
     23 
     24         loadData: function() {
     25             if (this._downloadStarted) {
     26                 return;
     27             }
     28             this._downloadStarted = true;
     29             fetch(this.url)
     30                 .then(
     31                     (xhr) => this._loadMarkers(xhr),
     32                     (e) => {
     33                         this._downloadStarted = false;
     34                         logging.captureException(e, 'failed to get westra passes');
     35                         notify('Failed to get Westra passes data');
     36                     }
     37                 );
     38         },
     39 
     40         onAdd: function(map) {
     41             L.Layer.CanvasMarkers.prototype.onAdd.call(this, map);
     42             this.loadData();
     43         },
     44 
     45         _makeTooltip: function(marker) {
     46             var properties = marker.properties,
     47                 toolTip = properties.grade || '';
     48             if (toolTip && properties.elevation) {
     49                 toolTip += ', ';
     50             }
     51             toolTip += properties.elevation || '';
     52             if (toolTip) {
     53                 toolTip = ' (' + toolTip + ')';
     54             }
     55             toolTip = (properties.name || 'без названия') + toolTip;
     56             toolTip = (properties.is_summit ? 'Вершина ' : 'Перевал ') + toolTip;
     57             return toolTip;
     58         },
     59 
     60         _passToGpx: function(marker) {
     61             let label = marker.tooltip;
     62             if (typeof label === 'function') {
     63                 label = label(marker);
     64             }
     65             label = escapeHtml(label);
     66             const gpx = `<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
     67                 <gpx xmlns="http://www.topografix.com/GPX/1/1"
     68                      creator="http://nakarte.me"
     69                      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     70                      xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd"
     71                      version="1.1">
     72                     <wpt lat="${marker.latlng.lat.toFixed(6)}" lon="${marker.latlng.lng.toFixed(6)}">
     73                         <name>${label}</name>
     74                     </wpt>
     75                 </gpx>
     76             `;
     77             var filename = marker.properties.name || 'Без названия';
     78             saveAs(new Blob([gpx], {type: 'application/gpx+xml'}), filename + '.gpx', true);
     79         },
     80 
     81         _passToKml: function(marker) {
     82             let label = marker.tooltip;
     83             if (typeof label === 'function') {
     84                 label = label(marker);
     85             }
     86             label = escapeHtml(label);
     87             const kml = `<?xml version="1.0" encoding="UTF-8"?>
     88                 <kml xmlns="http://www.opengis.net/kml/2.2">
     89                     <Placemark>
     90                         <name>${label}</name>
     91                         <Point>
     92                             <coordinates>
     93                                 ${marker.latlng.lng.toFixed(6)},${marker.latlng.lat.toFixed(6)},0
     94                             </coordinates>
     95                         </Point>
     96                     </Placemark>
     97                 </kml>
     98             `;
     99             var filename = marker.properties.name || 'Без названия';
    100             saveAs(new Blob([kml], {type: 'application/vnd.google-earth.kml+xml'}), filename + '.kml', true);
    101         },
    102 
    103         _makeIcon: function(marker) {
    104             var className;
    105             className = 'westra-pass-marker ';
    106             if (marker.properties.is_summit) {
    107                 className += 'westra-pass-marker-summit';
    108             } else {
    109                 className += 'westra-pass-marker-' + marker.properties.grade_eng;
    110             }
    111             return iconFromBackgroundImage(className);
    112         },
    113 
    114         _loadMarkers: function(xhr) {
    115             var markers = [],
    116                 features = JSON.parse(xhr.response),
    117                 feature, i, marker;
    118             for (i = 0; i < features.length; i++) {
    119                 feature = features[i];
    120                 marker = {
    121                     latlng: {
    122                         lat: feature.latlon[0],
    123                         lng: feature.latlon[1]
    124                     },
    125                     label: feature.name || "",
    126                     icon: this._makeIcon,
    127                     tooltip: this._makeTooltip.bind(this),
    128                     properties: feature
    129                 };
    130                 markers.push(marker);
    131             }
    132             this.addMarkers(markers);
    133             this._dataLoaded = true;
    134             this.fire('data-loaded');
    135         },
    136 
    137         showPassDescription: function(e) {
    138             if (!this._map) {
    139                 return;
    140             }
    141             const properties = e.marker.properties,
    142                 latLng = e.marker.latlng,
    143                 url = 'https://westra.ru/passes/Passes/' + properties.id;
    144             let altnames = '',
    145                 connects = '',
    146                 comments = '';
    147             if (properties.altnames) {
    148                 altnames = `
    149                     <tr>
    150                         <td>Другие названия</td>
    151                         <td>${properties.altnames}</td>
    152                     </tr>`;
    153             }
    154 
    155             if (!properties.is_summit) {
    156                 connects = `
    157                     <tr>
    158                         <td>Соединяет</td>
    159                         <td>${properties.connects || "неизвестнo"}</td>
    160                     </tr>`;
    161             }
    162 
    163             if (properties.comments) {
    164                 for (let comment of properties.comments) {
    165                     let user = '';
    166                     if (comment.user) {
    167                         user = `<span class="westra-passes-description-comment-author">${comment.user}:</span>`;
    168                     }
    169                     comments += `<p class="westra-passes-description-comment">${user}${comment.content}</p>`;
    170                 }
    171                 comments = `
    172                     <tr>
    173                         <td>Комментарии</td>
    174                         <td>${comments}</td>
    175                     </tr>`;
    176             }
    177             let reports;
    178             if (properties.reports_total) {
    179                 reports =
    180                     `<br>Отчетов: ${properties.reports_total}, ` +
    181                     `с фото: ${properties.reports_photo || 0}, ` +
    182                     `с описанием: ${properties.reports_tech || 0}`;
    183             } else {
    184                 reports = '<br>Отчетов нет';
    185             }
    186             let description = `
    187                 <table class="pass-details">
    188                     <tr>
    189                         <td>${properties.is_summit ? 'Вершина ' : 'Перевал '}</td>
    190                         <td>${properties.name || 'название неизвестно'}</td>
    191                     </tr>
    192                     ${altnames}
    193                     <tr>
    194                         <td>Категория</td>
    195                         <td>${properties.grade || "неизвестная"}</td>
    196                     </tr>
    197                     <tr>
    198                         <td>Высота</td>
    199                         <td>${properties.elevation ? (properties.elevation + ' м') : 'неизвестная'}</td>
    200                     </tr>
    201                     ${connects}
    202                     <tr>
    203                         <td>Характеристика склонов</td>
    204                         <td>${properties.slopes || "неизвестная"}</td>
    205                     </tr>
    206                     <tr>
    207                         <td>Координаты</td>
    208                         <td>
    209                             <table class="coords">
    210                                 <tr class="header">
    211                                     <td>Широта</td>
    212                                     <td>Долгота</td>
    213                                 </tr>
    214                                 <tr>
    215                                     <td>${latLng.lat.toFixed(5)}</td>
    216                                     <td>${latLng.lng.toFixed(5)}</td>
    217                                     <td><a id="westra-pass-gpx" title="Сохранить">gpx</a></td>
    218                                     <td><a id="westra-pass-kml" title="Сохранить">kml</a></td>
    219                                 </tr>
    220                             </table>
    221                         </td>
    222                     </tr>
    223                     <tr>
    224                         <td>На сайте Вестры</td>
    225                         <td><a id="westra-pass-link" href="${url}">${url}</a>${reports}</td></tr>
    226                     <tr>
    227                         <td>Добавил</td>
    228                         <td>${properties.author || "неизвестно"}</td>
    229                     </tr>
    230                     ${comments}
    231                 </table>`;
    232             this._map.openPopup(description, latLng, {maxWidth: 500});
    233             document.getElementById('westra-pass-link').onclick = function() {
    234                 openPopupWindow(url, 780, 'westra-details');
    235                 return false;
    236             };
    237             document.getElementById('westra-pass-gpx').onclick = function() {
    238                 this._passToGpx(e.marker);
    239                 return false;
    240             }.bind(this);
    241             document.getElementById('westra-pass-kml').onclick = function() {
    242                 this._passToKml(e.marker);
    243                 return false;
    244             }.bind(this);
    245         }
    246     }
    247 );
    248 
    249 export {WestraPassesMarkers};