index.js (3554B)
1 import L from 'leaflet'; 2 3 import {urlViaCorsProxy} from '~/lib/CORSProxy'; 4 import * as logging from '~/lib/logging'; 5 import {fetch} from '~/lib/xhr-promise'; 6 7 import _categories from './categories.csv'; 8 import icons from './icons.json'; 9 import {BaseProvider} from '../remoteBase'; 10 11 const categories = Object.assign({}, ..._categories.map((it) => ({[String(it.id)]: it}))); 12 13 const MapyCzProvider = BaseProvider.extend({ 14 name: 'Mapy.cz', 15 16 options: { 17 apiUrl: urlViaCorsProxy('https://pro.mapy.cz/suggest/'), 18 attribution: { 19 text: 'Mapy.cz', 20 url: 'https://mapy.cz', 21 }, 22 delay: 300, 23 languages: ['en', 'cs', 'de', 'pl', 'sk', 'ru', 'es', 'fr'], 24 categoriesLanguages: ['en', 'ru'], 25 defaultLanguage: 'en', 26 }, 27 28 initialize: function (options) { 29 BaseProvider.prototype.initialize.call(this, options); 30 this.langStr = this.getRequestLanguages(this.options.languages).join(','); 31 this.categoriesLanguage = this.getRequestLanguages( 32 this.options.categoriesLanguages, 33 this.options.defaultLanguage 34 )[0]; 35 }, 36 37 search: async function (query, {latlng, zoom}) { 38 if (!(await this.waitNoNewRequestsSent())) { 39 return {error: 'Request cancelled'}; 40 } 41 const url = new URL(this.options.apiUrl); 42 url.searchParams.append('phrase', query); 43 url.searchParams.append('lat', latlng.lat); 44 url.searchParams.append('lon', latlng.lng); 45 url.searchParams.append('zoom', zoom); 46 url.searchParams.append('lang', this.langStr); 47 if (this.options.maxResponses) { 48 url.searchParams.append('count', this.options.maxResponses); 49 } 50 let xhr; 51 try { 52 xhr = await fetch(url.href, {responseType: 'json', timeout: 5000}); 53 } catch (e) { 54 if (e.name === 'XMLHttpRequestPromiseError') { 55 logging.captureException(e, 'Error response from mapy.cz search api'); 56 return {error: `Search failed: ${e.message}`}; 57 } 58 throw e; 59 } 60 const places = xhr.responseJSON.result 61 .filter((it) => it.userData.suggestSecondRow !== 'Poloha') 62 .map((it) => { 63 const data = it.userData; 64 const iconId = icons[data.poiTypeId]; 65 const icon = iconId ? `https://api.mapy.cz/poiimg/icon/${iconId}?scale=1` : null; 66 const place = { 67 latlng: L.latLng(data.latitude, data.longitude), 68 title: data.suggestFirstRow, 69 address: data.suggestSecondRow, 70 category: categories[data.poiTypeId]?.[this.categoriesLanguage] || data.suggestThirdRow || null, 71 icon, 72 }; 73 if (data.bbox) { 74 place.bbox = L.latLngBounds([data.bbox[0], data.bbox[1]], [data.bbox[2], data.bbox[3]]); 75 } else { 76 place.zoom = 17; 77 } 78 return place; 79 }); 80 const poiIds = xhr.responseJSON.result 81 .filter((it) => Boolean(it.userData.poiTypeId)) 82 .map((it) => ({ 83 typeId: it.userData.poiTypeId, 84 poiId: it.userData.id, 85 source: it.userData.source, 86 })); 87 if (poiIds.length > 0) { 88 logging.logEvent('SearchMapyCzPoiIds', {poiIds}); 89 } 90 return {results: places}; 91 }, 92 }); 93 94 export {MapyCzProvider};