nakarte

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

photon.js (3103B)


      1 import L from 'leaflet';
      2 
      3 import * as logging from '~/lib/logging';
      4 import {fetch} from '~/lib/xhr-promise';
      5 
      6 import {BaseProvider} from './remoteBase';
      7 
      8 const PhotonProvider = BaseProvider.extend({
      9     name: 'Photon',
     10 
     11     options: {
     12         apiUrl: 'https://photon.komoot.io/api/',
     13         attribution: {
     14             text: 'Photon by Komoot',
     15             url: 'https://photon.komoot.io/',
     16         },
     17         delay: 700,
     18         languages: ['en', 'de', 'fr', 'it'],
     19         defaultLanguage: 'en',
     20     },
     21 
     22     initialize: function (options) {
     23         BaseProvider.prototype.initialize.call(this, options);
     24         this.lang = this.getRequestLanguages(this.options.languages, this.options.defaultLanguage)[0];
     25     },
     26 
     27     search: async function (query, {latlng}) {
     28         if (!(await this.waitNoNewRequestsSent())) {
     29             return {error: 'Request cancelled'};
     30         }
     31         const url = new URL(this.options.apiUrl);
     32         if (this.options.maxResponses) {
     33             url.searchParams.append('limit', this.options.maxResponses);
     34         }
     35         url.searchParams.append('q', query);
     36         url.searchParams.append('lang', 'en');
     37         url.searchParams.append('lat', latlng.lat);
     38         url.searchParams.append('lon', latlng.lng);
     39         let xhr;
     40         try {
     41             xhr = await fetch(url.href, {responseType: 'json', timeout: 5000});
     42         } catch (e) {
     43             if (e.name === 'XMLHttpRequestPromiseError') {
     44                 logging.captureException(e, 'Error response from photon search api');
     45                 return {error: `Search failed: ${e.message}`};
     46             }
     47             throw e;
     48         }
     49         const places = xhr.responseJSON.features.map((feature) => {
     50             const properties = feature.properties;
     51             let address = [
     52                 properties.street,
     53                 properties.housenumber,
     54                 properties.city,
     55                 properties.state,
     56                 properties.country,
     57             ]
     58                 .filter((it) => it)
     59                 .join(', ');
     60             let bbox = null;
     61             let zoom = null;
     62             if (properties.extent) {
     63                 bbox = L.latLngBounds([
     64                     [properties.extent[1], properties.extent[0]],
     65                     [properties.extent[3], properties.extent[2]],
     66                 ]);
     67             } else {
     68                 zoom = 17;
     69             }
     70             let title = properties.name;
     71             if (!title) {
     72                 title = address;
     73                 address = null;
     74             }
     75             let category = properties.osm_value;
     76             if (['yes'].includes(category)) {
     77                 category = properties.osm_key;
     78             }
     79             category = category.replace('_', ' ');
     80             return {
     81                 title,
     82                 latlng: L.latLng(feature.geometry.coordinates[1], feature.geometry.coordinates[0]),
     83                 bbox,
     84                 category,
     85                 address,
     86                 zoom,
     87                 icon: null,
     88             };
     89         });
     90         return {results: places};
     91     },
     92 });
     93 
     94 export {PhotonProvider};