nakarte

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

gpx.js (4349B)


      1 import {decode as utf8_decode} from 'utf8';
      2 import {xmlGetNodeText} from './xmlUtils';
      3 import stripBom from '~/lib/stripBom';
      4 
      5 function parseGpx(txt, name, preferNameFromFile) {
      6     var error;
      7 
      8     function getSegmentPoints(segment_element) {
      9         var points_elements = segment_element.getElementsByTagName('trkpt');
     10         var points = [];
     11         for (var i = 0; i < points_elements.length; i++) {
     12             var point_element = points_elements[i];
     13             var lat = parseFloat(point_element.getAttribute('lat'));
     14             var lng = parseFloat(point_element.getAttribute('lon'));
     15             if (isNaN(lat) || isNaN(lng)) {
     16                 error = 'CORRUPT';
     17                 break;
     18             }
     19             points.push({lat: lat, lng: lng});
     20         }
     21         return points;
     22     }
     23 
     24     function getTrackSegments(xml) {
     25         var segments = [];
     26         var segments_elements = xml.getElementsByTagName('trkseg');
     27         for (var i = 0; i < segments_elements.length; i++) {
     28             var segment_points = getSegmentPoints(segments_elements[i]);
     29             if (segment_points.length) {
     30                 segments.push(segment_points);
     31             }
     32         }
     33         return segments;
     34     }
     35 
     36     function getRoutePoints(rte_element) {
     37         var points_elements = rte_element.getElementsByTagName('rtept');
     38         var points = [];
     39         for (var i = 0; i < points_elements.length; i++) {
     40             var point_element = points_elements[i];
     41             var lat = parseFloat(point_element.getAttribute('lat'));
     42             var lng = parseFloat(point_element.getAttribute('lon'));
     43             if (isNaN(lat) || isNaN(lng)) {
     44                 error = 'CORRUPT';
     45                 break;
     46             }
     47             points.push({lat: lat, lng: lng});
     48         }
     49         return points;
     50     }
     51 
     52     function getRoutes(xml) {
     53         var routes = [];
     54         var rte_elements = xml.getElementsByTagName('rte');
     55         for (var i = 0; i < rte_elements.length; i++) {
     56             var rte_points = getRoutePoints(rte_elements[i]);
     57             if (rte_points.length) {
     58                 routes.push(rte_points);
     59             }
     60         }
     61         return routes;
     62     }
     63 
     64     function getWaypoints(xml) {
     65         var waypoint_elements = xml.getElementsByTagName('wpt');
     66         var waypoints = [];
     67         for (var i = 0; i < waypoint_elements.length; i++) {
     68             var waypoint_element = waypoint_elements[i];
     69             var waypoint = {};
     70             waypoint.lat = parseFloat(waypoint_element.getAttribute('lat'));
     71             waypoint.lng = parseFloat(waypoint_element.getAttribute('lon'));
     72             if (isNaN(waypoint.lat) || isNaN(waypoint.lng)) {
     73                 error = 'CORRUPT';
     74                 continue;
     75             }
     76             let wptName = xmlGetNodeText(waypoint_element.getElementsByTagName('name')[0]) || '';
     77             try {
     78                 wptName = utf8_decode((wptName));
     79             } catch (e) {
     80                 error = 'CORRUPT';
     81                 wptName = '__invalid point name__';
     82             }
     83             waypoint.name = wptName;
     84             waypoint.symbol_name = xmlGetNodeText(waypoint_element.getElementsByTagName('sym')[0]);
     85             waypoints.push(waypoint);
     86         }
     87         return waypoints;
     88     }
     89 
     90     txt = stripBom(txt);
     91     // remove namespaces
     92     txt = txt.replace(/<([^ >]+):([^ >]+)/ug, '<$1_$2');
     93     let dom;
     94     try {
     95         dom = (new DOMParser()).parseFromString(txt, "text/xml");
     96     } catch (e) {
     97         return null;
     98     }
     99     if (dom.documentElement.nodeName === 'parsererror') {
    100         return null;
    101     }
    102     if (dom.getElementsByTagName('gpx').length === 0) {
    103         return null;
    104     }
    105     if (preferNameFromFile) {
    106         for (let trk of [...dom.getElementsByTagName('trk')]) {
    107             let trkName = trk.getElementsByTagName('name')[0];
    108             if (trkName) {
    109                 try {
    110                     trkName = utf8_decode(xmlGetNodeText(trkName));
    111                 } catch (e) {
    112                     error = 'CORRUPT';
    113                 }
    114                 if (trkName.length) {
    115                     name = trkName;
    116                     break;
    117                 }
    118             }
    119         }
    120     }
    121     return [{
    122         name: name,
    123         tracks: getTrackSegments(dom).concat(getRoutes(dom)),
    124         points: getWaypoints(dom),
    125         error: error
    126     }];
    127 }
    128 
    129 export default parseGpx;