index.js (3421B)
1 import BaseService from '../baseService'; 2 import {parseNktkSequence, parseTrackUrlData, parseNktkFragment} from '../../parsers/nktk'; 3 import config from '~/config'; 4 import {parseHashParams} from '~/lib/leaflet.hashState/hashState'; 5 import loadFromUrl from '../../loadFromUrl'; 6 import loadTracksFromJson from './loadTracksFromJson'; 7 import {fetch} from '~/lib/xhr-promise'; 8 9 function flattenArray(ar) { 10 const res = []; 11 for (const it of ar) { 12 res.push(...it); 13 } 14 return res; 15 } 16 17 function parsePointFromHashValues(values) { 18 if (values.length < 2) { 19 return [{name: 'Point in url', error: 'CORRUPT'}]; 20 } 21 const lat = parseFloat(values[0]); 22 const lng = parseFloat(values[1]); 23 if (isNaN(lat) || isNaN(lng) || lat < -90 || lat > 90 || lng < -180 || lng > 180) { 24 return [{name: 'Point in url', error: 'CORRUPT'}]; 25 } 26 const name = ((values[2] || '').trim()) || 'Point'; 27 return [{name, points: [{name, lat, lng}]}]; 28 } 29 30 class NakarteTrack extends BaseService { 31 isOurUrl() { 32 return this.origUrl.indexOf('track://') > -1; 33 } 34 35 requestOptions() { 36 return []; 37 } 38 39 parseResponse() { 40 const i = this.origUrl.indexOf('track://'); 41 return parseTrackUrlData(this.origUrl.substring(i + 8)); 42 } 43 } 44 45 class NakarteUrlLoader { 46 constructor() { 47 this.loaders = { 48 nktk: this.loadFromTextEncodedTrack, 49 nktl: this.loadFromTextEncodedTrackId, 50 nktu: this.loadFromUrlencodedUrls, 51 nktp: this.loadPoint, 52 nktj: this.loadFromJSON 53 }; 54 } 55 56 paramNames() { 57 return Object.keys(this.loaders); 58 } 59 60 async geoData(paramName, values) { 61 const loader = this.loaders[paramName]; 62 return loader.call(this, values); 63 } 64 65 async loadFromTextEncodedTrack(values) { 66 return flattenArray(values.map(parseNktkFragment)); 67 } 68 69 async loadFromTextEncodedTrackId(values) { 70 const requests = values.map((trackId) => 71 fetch( 72 `${config.tracksStorageServer}/track/${trackId}`, 73 {responseType: 'binarystring', withCredentials: true} 74 ) 75 ); 76 let responses; 77 try { 78 responses = await Promise.all(requests); 79 } catch (e) { 80 return [{name: 'Track from nakarte server', error: 'NETWORK'}]; 81 } 82 return flattenArray(responses.map((r) => parseNktkSequence(r.responseBinaryText))); 83 } 84 85 async loadFromJSON(values) { 86 return flattenArray(await Promise.all(values.map(loadTracksFromJson))); 87 } 88 89 async loadFromUrlencodedUrls(values) { 90 return flattenArray(await Promise.all(values.map(decodeURIComponent).map(loadFromUrl))); 91 } 92 93 async loadPoint(values) { 94 return parsePointFromHashValues(values.map(decodeURIComponent)); 95 } 96 } 97 98 class NakarteUrl { 99 constructor(url) { 100 const paramNames = new NakarteUrlLoader().paramNames(); 101 this._params = Object.entries(parseHashParams(url)) 102 .filter(([name]) => paramNames.includes(name)); 103 } 104 105 isOurUrl() { 106 return this._params.length > 0; 107 } 108 109 async geoData() { 110 const promises = this._params.map(([paramName, value]) => new NakarteUrlLoader().geoData(paramName, value)); 111 return flattenArray(await Promise.all(promises)); 112 } 113 } 114 115 export {NakarteTrack, NakarteUrl, NakarteUrlLoader};