diff --git a/package-lock.json b/package-lock.json index 8db8097..4dc53c7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,8 +5,8 @@ "packages": { "": { "dependencies": { + "@dwayneparton/geojson-to-gpx": "^0.0.30", "file-saver": "^2.0.5", - "gpx-builder": "^5.2.1", "leaflet": "^1.9.4", "nanoid": "^5.0.3", "preact": "^10.13.1" @@ -419,17 +419,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/runtime": { - "version": "7.23.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.2.tgz", - "integrity": "sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==", - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/template": { "version": "7.22.15", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", @@ -479,6 +468,11 @@ "node": ">=6.9.0" } }, + "node_modules/@dwayneparton/geojson-to-gpx": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/@dwayneparton/geojson-to-gpx/-/geojson-to-gpx-0.0.30.tgz", + "integrity": "sha512-POg5xLwnZ3leGWwNVQzCZCNiuwFR/ijv++ejOJLB+N2yVIJbDNubyoyQ877F6DNsIH6sscXu4RSfSSzbVeD/FA==" + }, "node_modules/@esbuild/android-arm": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", @@ -1055,50 +1049,6 @@ "node": ">= 8" } }, - "node_modules/@oozcitak/dom": { - "version": "1.15.10", - "resolved": "https://registry.npmjs.org/@oozcitak/dom/-/dom-1.15.10.tgz", - "integrity": "sha512-0JT29/LaxVgRcGKvHmSrUTEvZ8BXvZhGl2LASRUgHqDTC1M5g1pLmVv56IYNyt3bG2CUjDkc67wnyZC14pbQrQ==", - "dependencies": { - "@oozcitak/infra": "1.0.8", - "@oozcitak/url": "1.0.4", - "@oozcitak/util": "8.3.8" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/@oozcitak/infra": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@oozcitak/infra/-/infra-1.0.8.tgz", - "integrity": "sha512-JRAUc9VR6IGHOL7OGF+yrvs0LO8SlqGnPAMqyzOuFZPSZSXI7Xf2O9+awQPSMXgIWGtgUf/dA6Hs6X6ySEaWTg==", - "dependencies": { - "@oozcitak/util": "8.3.8" - }, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/@oozcitak/url": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@oozcitak/url/-/url-1.0.4.tgz", - "integrity": "sha512-kDcD8y+y3FCSOvnBI6HJgl00viO/nGbQoCINmQ0h98OhnGITrWR3bOGfwYCthgcrV8AnTJz8MzslTQbC3SOAmw==", - "dependencies": { - "@oozcitak/infra": "1.0.8", - "@oozcitak/util": "8.3.8" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/@oozcitak/util": { - "version": "8.3.8", - "resolved": "https://registry.npmjs.org/@oozcitak/util/-/util-8.3.8.tgz", - "integrity": "sha512-T8TbSnGsxo6TDBJx/Sgv/BlVJL3tshxZP7Aq5R1mSnM5OcHY2dQaxLMu2+E8u3gN0MLOzdjurqN4ZRVuzQycOQ==", - "engines": { - "node": ">=8.0" - } - }, "node_modules/@pkgr/utils": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/@pkgr/utils/-/utils-2.4.2.tgz", @@ -3019,18 +2969,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/esquery": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", @@ -3448,15 +3386,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/gpx-builder": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/gpx-builder/-/gpx-builder-5.2.1.tgz", - "integrity": "sha512-j7g9/bWQncZ2TaHXxjNSnNI+EaFWLQqm03A2si0dvzc78H/lWFVF770tdwEzdIFbd5eZeT4d99/UGbPmkplLBg==", - "dependencies": { - "@babel/runtime": "^7.20.7", - "xmlbuilder2": "^3.0.2" - } - }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", @@ -4843,11 +4772,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/regenerator-runtime": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", - "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" - }, "node_modules/regexp.prototype.flags": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", @@ -5321,11 +5245,6 @@ "node": ">=0.10.0" } }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" - }, "node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", @@ -5975,40 +5894,6 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, - "node_modules/xmlbuilder2": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/xmlbuilder2/-/xmlbuilder2-3.1.1.tgz", - "integrity": "sha512-WCSfbfZnQDdLQLiMdGUQpMxxckeQ4oZNMNhLVkcekTu7xhD4tuUDyAPoY8CwXvBYE6LwBHd6QW2WZXlOWr1vCw==", - "dependencies": { - "@oozcitak/dom": "1.15.10", - "@oozcitak/infra": "1.0.8", - "@oozcitak/util": "8.3.8", - "js-yaml": "3.14.1" - }, - "engines": { - "node": ">=12.0" - } - }, - "node_modules/xmlbuilder2/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/xmlbuilder2/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", diff --git a/package.json b/package.json index 08d296f..4705063 100644 --- a/package.json +++ b/package.json @@ -11,8 +11,8 @@ "preview": "vite preview" }, "dependencies": { + "@dwayneparton/geojson-to-gpx": "^0.0.30", "file-saver": "^2.0.5", - "gpx-builder": "^5.2.1", "leaflet": "^1.9.4", "nanoid": "^5.0.3", "preact": "^10.13.1" diff --git a/src/exporters/gpx.ts b/src/exporters/gpx.ts index db53c3c..d6609bd 100644 --- a/src/exporters/gpx.ts +++ b/src/exporters/gpx.ts @@ -1,19 +1,21 @@ +import GeoJsonToGpx from '@dwayneparton/geojson-to-gpx'; import { saveAs } from 'file-saver'; -import { GarminBuilder, buildGPX } from 'gpx-builder'; import { Waypoint } from '../shared/types'; export const exportMarkersToGpx = (waypoints: Waypoint[]) => { - const builder = new GarminBuilder(); - builder.setSegmentPoints( - waypoints.map( - ({ coordinates }) => - new GarminBuilder.MODELS.Point( - coordinates.lat, - coordinates.lng, - ), - ), - ); - const gpx = buildGPX(builder.toObject()); - const gpxBlob = new Blob([gpx], { type: 'application/gpx+xml' }); + const gpx = GeoJsonToGpx({ + type: 'Feature', + geometry: { + type: 'LineString', + coordinates: waypoints.map(({ coordinates }) => [ + coordinates.lng, + coordinates.lat, + ]), + }, + properties: {}, + }); + const gpxBlob = new Blob([new XMLSerializer().serializeToString(gpx)], { + type: 'application/gpx+xml', + }); saveAs(gpxBlob, 'route.gpx'); };