nakarte

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

loadTracksFromJson.js (3611B)


      1 import utf8 from 'utf8';
      2 
      3 import * as urlSafeBase64 from '../../parsers/urlSafeBase64';
      4 import {TRACKLIST_TRACK_COLORS} from '../../../track-list';
      5 import loadFromUrl from '../../loadFromUrl';
      6 
      7 function parseWaypoint(rawPoint) {
      8     let name = rawPoint.n;
      9     let lat = Number(rawPoint.lt);
     10     let lng = Number(rawPoint.ln);
     11     if (typeof name !== 'string' || !name || isNaN(lat) || isNaN(lng) ||
     12         lat < -90 || lat > 90 || lng < -180 || lng > 180) {
     13         return {valid: false};
     14     }
     15     return {
     16         valid: true,
     17         point: {lat, lng, name}
     18     };
     19 }
     20 
     21 function parseTrack(rawTrack) {
     22     if (!rawTrack.length) {
     23         return {valid: false};
     24     }
     25     const track = [];
     26     for (let rawSegment of rawTrack) {
     27         let segment = [];
     28         if (!rawSegment || !rawSegment.length) {
     29             return {valid: false};
     30         }
     31         for (let rawPoint of rawSegment) {
     32             if (!rawPoint || rawPoint.length !== 2) {
     33                 return {valid: false};
     34             }
     35             let [lat, lng] = rawPoint.map(Number);
     36             if (isNaN(lat) || isNaN(lng) || lat < -90 || lat > 90) {
     37                 return {valid: false};
     38             }
     39             segment.push({lat, lng});
     40         }
     41         track.push(segment);
     42     }
     43     return {valid: true, track};
     44 }
     45 
     46 async function loadTracksFromJson(value) { // eslint-disable-line complexity
     47     const errCorrupt = [{name: 'Track in url', error: 'CORRUPT'}];
     48     let jsonString = urlSafeBase64.decode(value);
     49     try {
     50         jsonString = utf8.decode(jsonString);
     51     } catch (e) {
     52         // so it was not encoded in utf-8, leave it as it is
     53     }
     54     let data;
     55     try {
     56         data = JSON.parse(jsonString);
     57     } catch (e) {
     58         return errCorrupt;
     59     }
     60     if (!data || !data.length) {
     61         return errCorrupt;
     62     }
     63     const geoDataArray = [];
     64 
     65     for (let el of data) {
     66         // Each track should contain either url or at least one of tracks and points
     67         if (!el.u && !(el.p || el.t)) {
     68             return errCorrupt;
     69         }
     70         let geodata;
     71         if (el.u) {
     72             geodata = await
     73                 loadFromUrl(el.u);
     74             if (el.n && geodata.length === 1 && !geodata[0].error) {
     75                 geodata[0].name = el.n;
     76             }
     77         } else {
     78             geodata = {};
     79             geodata.name = el.n || 'Track';
     80             if (el.t) {
     81                 const res = parseTrack(el.t);
     82                 if (!res.valid) {
     83                     return errCorrupt;
     84                 }
     85                 geodata.tracks = res.track;
     86             }
     87             if (el.p) {
     88                 geodata.points = [];
     89                 for (let rawPoint of el.p) {
     90                     let res = parseWaypoint(rawPoint);
     91                     // eslint-disable-next-line max-depth
     92                     if (!res.valid) {
     93                         return errCorrupt;
     94                     }
     95                     geodata.points.push(res.point);
     96                 }
     97             }
     98             geodata = [geodata];
     99         }
    100         let viewProps = {};
    101         if ('c' in el) {
    102             let color = Number(el.c);
    103             if (color < 0 || color >= TRACKLIST_TRACK_COLORS.length) {
    104                 return errCorrupt;
    105             }
    106             viewProps.color = color;
    107         }
    108         if ('v' in el) {
    109             viewProps.trackHidden = !el.v;
    110         }
    111         if ('m' in el) {
    112             viewProps.measureTicksShown = Boolean(el.m);
    113         }
    114         geodata.forEach((el) => Object.assign(el, viewProps));
    115         geoDataArray.push(...geodata);
    116     }
    117     return geoDataArray;
    118 }
    119 
    120 export default loadTracksFromJson;