nakarte

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

westraPassesMarkers.js (10564B)


      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>${escapeHtml(properties.altnames)}</td>
    152                     </tr>`;
    153             }
    154 
    155             if (!properties.is_summit) {
    156                 connects = `
    157                     <tr>
    158                         <td>Соединяет</td>
    159                         <td>${properties.connects ? escapeHtml(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 = (
    168                             `<span class="westra-passes-description-comment-author">${escapeHtml(comment.user)}:</span>`
    169                         );
    170                     }
    171                     comments += (
    172                         `<p class="westra-passes-description-comment">${user}${escapeHtml(comment.content)}</p>`
    173                     );
    174                 }
    175                 comments = `
    176                     <tr>
    177                         <td>Комментарии</td>
    178                         <td>${comments}</td>
    179                     </tr>`;
    180             }
    181             let reports;
    182             if (properties.reports_total) {
    183                 reports =
    184                     `<br>Отчетов: ${properties.reports_total}, ` +
    185                     `с фото: ${properties.reports_photo || 0}, ` +
    186                     `с описанием: ${properties.reports_tech || 0}`;
    187             } else {
    188                 reports = '<br>Отчетов нет';
    189             }
    190             let description = `
    191                 <table class="pass-details">
    192                     <tr>
    193                         <td>${properties.is_summit ? 'Вершина ' : 'Перевал '}</td>
    194                         <td>${properties.name ? escapeHtml(properties.name) : 'название неизвестно'}</td>
    195                     </tr>
    196                     ${altnames}
    197                     <tr>
    198                         <td>Категория</td>
    199                         <td>${properties.grade ? escapeHtml(properties.grade) : "неизвестная"}</td>
    200                     </tr>
    201                     <tr>
    202                         <td>Высота</td>
    203                         <td>${properties.elevation ? (escapeHtml(properties.elevation) + ' м') : 'неизвестная'}</td>
    204                     </tr>
    205                     ${connects}
    206                     <tr>
    207                         <td>Характеристика склонов</td>
    208                         <td>${properties.slopes ? escapeHtml(properties.slopes) : "неизвестная"}</td>
    209                     </tr>
    210                     <tr>
    211                         <td>Координаты</td>
    212                         <td>
    213                             <table class="coords">
    214                                 <tr class="header">
    215                                     <td>Широта</td>
    216                                     <td>Долгота</td>
    217                                 </tr>
    218                                 <tr>
    219                                     <td>${latLng.lat.toFixed(5)}</td>
    220                                     <td>${latLng.lng.toFixed(5)}</td>
    221                                     <td><a id="westra-pass-gpx" title="Сохранить">gpx</a></td>
    222                                     <td><a id="westra-pass-kml" title="Сохранить">kml</a></td>
    223                                 </tr>
    224                             </table>
    225                         </td>
    226                     </tr>
    227                     <tr>
    228                         <td>На сайте Вестры</td>
    229                         <td><a id="westra-pass-link" href="${url}">${url}</a>${reports}</td></tr>
    230                     <tr>
    231                         <td>Добавил</td>
    232                         <td>${properties.author ? escapeHtml(properties.author) : "неизвестно"}</td>
    233                     </tr>
    234                     ${comments}
    235                 </table>`;
    236             this._map.openPopup(description, latLng, {maxWidth: 500});
    237             document.getElementById('westra-pass-link').onclick = function() {
    238                 openPopupWindow(url, 780, 'westra-details');
    239                 return false;
    240             };
    241             document.getElementById('westra-pass-gpx').onclick = function() {
    242                 this._passToGpx(e.marker);
    243                 return false;
    244             }.bind(this);
    245             document.getElementById('westra-pass-kml').onclick = function() {
    246                 this._passToKml(e.marker);
    247                 return false;
    248             }.bind(this);
    249         }
    250     }
    251 );
    252 
    253 export {WestraPassesMarkers};