diff --git a/db/__debug_bin2531684965 b/db/__debug_bin2531684965 new file mode 100755 index 00000000..51fc79e8 Binary files /dev/null and b/db/__debug_bin2531684965 differ diff --git a/web/src/lib/util/gpx_util.ts b/web/src/lib/util/gpx_util.ts index 310cdeb3..8fc0a132 100644 --- a/web/src/lib/util/gpx_util.ts +++ b/web/src/lib/util/gpx_util.ts @@ -14,6 +14,7 @@ import EasyFit from "$lib/vendor/easy-fit/easy-fit"; import type { Feature, FeatureCollection, GeoJSON, GeoJsonProperties, Position } from 'geojson'; import * as xmldom from 'xmldom'; import { bbox, splitMultiLineStringToLineStrings } from "./geojson_util"; +import JSZip from "jszip"; export async function gpx2trail(gpxString: string, fallbackName?: string) { @@ -108,28 +109,34 @@ export async function fromFile(file: File | Blob) { const fileContent = await file.text(); const fileBuffer = await file.arrayBuffer(); - if (!isFITFile(fileBuffer)) { - if (fileContent.includes("http://www.opengis.net/kml")) { - gpxData = fromKML(fileContent); - gpxFile = new Blob([gpxData], { - type: "application/gpx+xml", - }); - } else if (fileContent.includes("TrainingCenterDatabase")) { - gpxData = fromTCX(fileContent); - gpxFile = new Blob([gpxData], { - type: "application/gpx+xml", - }); - } else { - gpxData = fileContent; - gpxFile = file; - } - } else { + if (isFITFile(fileBuffer)) { gpxData = await fromFIT(fileBuffer); gpxFile = new Blob([gpxData], { type: "application/gpx+xml", }); + + } else if (isKMZFile(fileBuffer)) { + gpxData = await fromKMZ(fileBuffer); + gpxFile = new Blob([gpxData], { + type: "application/gpx+xml", + }); + + } else if (fileContent.includes("http://www.opengis.net/kml")) { + gpxData = fromKML(fileContent); + gpxFile = new Blob([gpxData], { + type: "application/gpx+xml", + }); + } else if (fileContent.includes("TrainingCenterDatabase")) { + gpxData = fromTCX(fileContent); + gpxFile = new Blob([gpxData], { + type: "application/gpx+xml", + }); + } else { + gpxData = fileContent; + gpxFile = file; } + return { gpxData, gpxFile }; } @@ -143,6 +150,13 @@ export function fromKML(kmlData: string) { return gpx } +export async function fromKMZ(kmzData: ArrayBuffer) { + const zip = new JSZip() + const zipContents = await zip.loadAsync(kmzData) + const kmlFile = await zip.file('doc.kml')?.async('string'); + return fromKML(kmlFile ?? "") +} + export function fromTCX(tcxData: string) { const parser = browser ? new DOMParser() : new xmldom.DOMParser(); const nodes = parser.parseFromString(tcxData, "text/xml") @@ -315,6 +329,11 @@ export function isFITFile(buffer: ArrayBuffer) { return true; } +function isKMZFile(buffer: ArrayBuffer) { + const blob = new Uint8Array(buffer); + return blob[0] === 0x50 && blob[1] === 0x4B && blob[2] === 0x03 && blob[3] === 0x04; +} + export function toGeoJson(gpxData: string) { const parser = browser ? new DOMParser() : new xmldom.DOMParser(); let geojson = gpx(