From 9b23bcec5ce001b41b81438b6267b13cfd6649de Mon Sep 17 00:00:00 2001 From: evlist Date: Tue, 15 Nov 2022 15:24:21 +0100 Subject: [PATCH] Computing bounding boxes when saving GPX files. --- src/components/dialogs/GpxImport.tsx | 12 ++++- src/db/gpx.ts | 72 +++++++++++++++++++++++++++- 2 files changed, 81 insertions(+), 3 deletions(-) diff --git a/src/components/dialogs/GpxImport.tsx b/src/components/dialogs/GpxImport.tsx index 7f497d4..bcb577b 100644 --- a/src/components/dialogs/GpxImport.tsx +++ b/src/components/dialogs/GpxImport.tsx @@ -26,7 +26,17 @@ const GpxImport: React.FC<{}> = () => { const startTime = new Date(findStartTime(gpx)!); dispatch({ action: 'pruneAndSaveImportedGpx', - params: { id: { gpx: intToGpxId(startTime.valueOf()) }, gpx: gpx }, + params: { + id: { gpx: intToGpxId(startTime.valueOf()) }, + gpx: gpx, + tech: { + lastModified: new Date(file.lastModified).toISOString(), + importDate: new Date().toISOString(), + name: file.name, + size: file.size, + type: file.type, + }, + }, }); // pushGpx(db, { // gpx, diff --git a/src/db/gpx.ts b/src/db/gpx.ts index cba91e1..92d8611 100644 --- a/src/db/gpx.ts +++ b/src/db/gpx.ts @@ -1,4 +1,6 @@ import { PureComponent } from 'react'; +import { Point } from '../components/map/types'; +import { lat2tile, lon2tile } from '../lib/geo'; import getUri, { intToGpxId } from '../lib/ids'; import { get, put, putAll } from './lib'; @@ -86,9 +88,75 @@ const prune = (id: any, object: any, docs: any[]) => { } }; +const techFromObject = ( + object: any, + tech = { + viewport: { topLeft: {}, bottomRight: {} }, + bbox: { + minLon: undefined, + minLat: undefined, + maxLon: undefined, + maxLat: undefined, + }, + } +) => { + if (typeof object === 'object') { + if ('$' in object) { + const attributes = object.$; + if ('lat' in attributes) { + const lat = +attributes.lat; + if (tech.bbox.minLat === undefined || lat < tech.bbox.minLat) { + tech.bbox.minLat = lat; + } + if (tech.bbox.maxLat === undefined || lat > tech.bbox.maxLat) { + tech.bbox.maxLat = lat; + } + } + if ('lon' in attributes) { + const lon = +attributes.lon; + if (tech.bbox.minLon === undefined || lon < tech.bbox.minLon) { + tech.bbox.minLon = lon; + } + if (tech.bbox.maxLon === undefined || lon > tech.bbox.minLon) { + tech.bbox.maxLon = lon; + } + } + } + for (const key in object) { + techFromObject(object[key], tech); + } + } + return tech; +}; + +const techFromGpx = (gpx: Gpx) => { + const tech = techFromObject(gpx); + if (tech.bbox.maxLat !== undefined && tech.bbox.minLon !== undefined) { + tech.viewport.topLeft = { + x: lon2tile(tech.bbox.minLon, 0), + y: lat2tile(tech.bbox.maxLat, 0), + }; + } + if (tech.bbox.minLat !== undefined && tech.bbox.maxLon !== undefined) { + tech.viewport.bottomRight = { + x: lon2tile(tech.bbox.maxLon, 0), + y: lat2tile(tech.bbox.minLat, 0), + }; + } + + return tech; +}; + export const pruneAndSaveImportedGpx = async (params: any) => { - const { id, gpx } = params; - let docs: any[] = [{ _id: getUri('gpx', id), type: 'gpx', doc: gpx }]; + const { id, gpx, tech } = params; + let docs: any[] = [ + { _id: getUri('gpx', id), type: 'gpx', doc: gpx }, + { + _id: getUri('tech', id), + type: 'tech', + doc: { ...tech, ...techFromGpx(gpx) }, + }, + ]; prune(id, gpx, docs); console.log(JSON.stringify(docs)); try {