nakarte

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

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