index.js (3615B)
1 import L from 'leaflet'; 2 3 import config from '~/config'; 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: 'https://api.mapy.cz/v0/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 this.apiKey = config.mapyCz; 36 }, 37 38 search: async function (query, {latlng, zoom}) { 39 if (!(await this.waitNoNewRequestsSent())) { 40 return {error: 'Request cancelled'}; 41 } 42 const url = new URL(this.options.apiUrl); 43 url.searchParams.append('phrase', query); 44 url.searchParams.append('lat', latlng.lat); 45 url.searchParams.append('lon', latlng.lng); 46 url.searchParams.append('zoom', zoom); 47 url.searchParams.append('lang', this.langStr); 48 if (this.options.maxResponses) { 49 url.searchParams.append('count', this.options.maxResponses); 50 } 51 url.searchParams.append('apikey', this.apiKey); 52 let xhr; 53 try { 54 xhr = await fetch(url.href, {responseType: 'json', timeout: 5000}); 55 } catch (e) { 56 if (e.name === 'XMLHttpRequestPromiseError') { 57 logging.captureException(e, 'Error response from mapy.cz search api'); 58 return {error: `Search failed: ${e.message}`}; 59 } 60 throw e; 61 } 62 const places = xhr.responseJSON.result 63 .filter((it) => it.userData.suggestSecondRow !== 'Poloha') 64 .map((it) => { 65 const data = it.userData; 66 const iconId = icons[data.poiTypeId]; 67 const icon = iconId ? `https://api.mapy.cz/poiimg/icon/${iconId}?scale=1` : null; 68 const place = { 69 latlng: L.latLng(data.latitude, data.longitude), 70 title: data.suggestFirstRow, 71 address: data.suggestSecondRow, 72 category: categories[data.poiTypeId]?.[this.categoriesLanguage] || data.suggestThirdRow || null, 73 icon, 74 }; 75 if (data.bbox) { 76 place.bbox = L.latLngBounds([data.bbox[0], data.bbox[1]], [data.bbox[2], data.bbox[3]]); 77 } else { 78 place.zoom = 17; 79 } 80 return place; 81 }); 82 const poiIds = xhr.responseJSON.result 83 .filter((it) => Boolean(it.userData.poiTypeId)) 84 .map((it) => ({ 85 typeId: it.userData.poiTypeId, 86 poiId: it.userData.id, 87 source: it.userData.source, 88 })); 89 if (poiIds.length > 0) { 90 logging.logEvent('SearchMapyCzPoiIds', {poiIds}); 91 } 92 return {results: places}; 93 }, 94 }); 95 96 export {MapyCzProvider};