diff --git a/.prettierignore b/.prettierignore index 6644623..cc6dedb 100644 --- a/.prettierignore +++ b/.prettierignore @@ -4,8 +4,14 @@ dist/ yarn.lock .idea .gitignore +.eslintignore .prettierignore .tx/ layers/ locales/*.json resources/boundaries/ +*.sh +profiles2/ +Dockerfile +tests/**/*.json +tests/**/*.gpx diff --git a/gulpfile.js b/gulpfile.js index 6c50707..11f844b 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -71,6 +71,7 @@ var paths = { 'js/LayersConfig.js', 'js/router/BRouter.js', 'js/util/*.js', + 'js/format/*.js', 'js/plugin/*.js', 'js/control/*.js', 'js/index.js', diff --git a/js/format/Gpx.js b/js/format/Gpx.js new file mode 100644 index 0000000..e70a3f2 --- /dev/null +++ b/js/format/Gpx.js @@ -0,0 +1,76 @@ +BR.Gpx = { + format: function (geoJson) { + const gpx = togpx(geoJson, { + featureDescription: function () {}, + }); + const statsComment = BR.Gpx._statsComment(geoJson); + const xml = '' + statsComment + gpx; + return BR.Gpx.pretty(xml, 1); + }, + + // + _statsComment: function (geoJson) { + const props = geoJson.features?.[0].properties; + if (!props) return ''; + + let comment = ''; + return comment; + }, + + // modified version of + // https://gist.github.com/sente/1083506#gistcomment-2254622 + // MIT License, Copyright (c) 2016 Stuart Powers, ES6 version by Jonathan Gruber + pretty: function (xml, indentSize = 2) { + const PADDING = ' '.repeat(indentSize); + const newline = '\n'; + // break into lines, keep trkpt with subelement ele in single line + const reg = /(>)(<)(?!ele|\/trkpt)(\/?)/g; + let pad = 0; + + xml = xml.replace('', ''); + xml = xml.replace(reg, `$1${newline}$2$3`); + + let lines = xml.split(newline); + lines = lines.map((node, index) => { + let indent = 0; + if (node.match(/.+<\/\w[^>]*>$/)) { + indent = 0; + } else if (node.match(/^<\/\w/) && pad > 0) { + pad -= 1; + } else if (node.match(/^<\w[^>]*[^\/]>.*$/)) { + indent = 1; + } else { + indent = 0; + } + + pad += indent; + + return PADDING.repeat(pad - indent) + node; + }); + + for (const [i, line] of lines.entries()) { + // break gpx attributes into separate lines + if (line.includes('\n [^<]*<\/name>/, `\n ${name}`); + gpx = gpx + .split(newline) + .map((line) => line.replace(/lon="([^"]*)" lat="([^"]*)"/, 'lat="$2" lon="$1"')) + .join(newline); + gpx = gpx.replace(/0">/g, '">'); + gpx = gpx.replace('\n', ''); + + return gpx; +} + +function read(fileName) { + return adoptGpx(fs.readFileSync(path + fileName, 'utf8')); +} + +test('simple track', () => { + const brouterGpx = read('track.gpx'); + const gpx = BR.Gpx.format(geoJson); + expect(gpx).toEqual(brouterGpx); +}); diff --git a/tests/format/data/track.gpx b/tests/format/data/track.gpx new file mode 100644 index 0000000..8091802 --- /dev/null +++ b/tests/format/data/track.gpx @@ -0,0 +1,20 @@ + + + + + Track + + 101.5 + 101.5 + 101.5 + 101.5 + 101.75 + 103.5 + 99.75 + + + diff --git a/tests/format/data/track.json b/tests/format/data/track.json new file mode 100644 index 0000000..6c8902f --- /dev/null +++ b/tests/format/data/track.json @@ -0,0 +1,40 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "creator": "BRouter-1.1", + "name": "Track", + "track-length": "319", + "filtered ascend": "2", + "plain-ascend": "-1", + "total-time": "44", + "total-energy": "4412", + "cost": "533", + "voicehints": [ + [1,5,0], + [5,2,0] + ], + "messages": [ + ["Longitude", "Latitude", "Elevation", "Distance", "CostPerKm", "ElevCost", "TurnCost", "NodeCost", "InitialCost", "WayTags", "NodeTags"], + ["8468340", "49488794", "101", "89", "1000", "0", "0", "0", "0", "highway=residential surface=asphalt cycleway=lane oneway=yes lcn=yes smoothness=good route_bicycle_icn=yes route_bicycle_ncn=yes route_bicycle_rcn=yes", ""], + ["8470671", "49488909", "99", "230", "1150", "0", "180", "0", "0", "highway=residential surface=asphalt oneway=yes smoothness=good", ""] + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [8.467714, 49.488115, 101.5], + [8.468340, 49.488794, 101.5], + [8.468586, 49.488698, 101.5], + [8.468743, 49.488636, 101.5], + [8.469161, 49.488473, 101.75], + [8.469971, 49.488151, 103.5], + [8.470610, 49.488842, 99.75] + ] + } + } + ] +} +