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};