2023-02-12 17:14:14 +00:00
|
|
|
import { Rowing } from '@suid/icons-material';
|
2022-12-23 15:30:24 +00:00
|
|
|
import { cloneDeep, isEmpty } from 'lodash';
|
2022-11-26 18:36:55 +00:00
|
|
|
import { PureComponent } from 'react';
|
2022-12-13 11:41:13 +00:00
|
|
|
import { $DEVCOMP } from 'solid-js';
|
2022-11-26 18:36:55 +00:00
|
|
|
import { Point, Rectangle } from '../components/map/types';
|
2023-02-13 10:23:17 +00:00
|
|
|
import { state } from '../db-admin/health-legacy';
|
2022-11-26 18:36:55 +00:00
|
|
|
import { lat2tile, lon2tile, rectanglesIntersect } from '../lib/geo';
|
2022-12-13 11:41:13 +00:00
|
|
|
import { findStartTime } from '../lib/gpx';
|
2022-12-10 17:31:51 +00:00
|
|
|
import getUri, { intToGpxId, intToTrkptId } from '../lib/ids';
|
2023-03-04 15:07:22 +00:00
|
|
|
import { dbUrlToUserId } from '../lib/user-id';
|
2022-11-26 18:36:55 +00:00
|
|
|
import { get, getDocsByType, getFamily, put, putAll } from './lib';
|
|
|
|
|
2022-12-12 19:57:25 +00:00
|
|
|
export const emptyGpx: Gpx = {
|
2022-11-26 18:36:55 +00:00
|
|
|
$: {
|
|
|
|
version: '1.1',
|
|
|
|
creator: 'dyomedea version 0.000002',
|
|
|
|
xmlns: 'http://www.topografix.com/GPX/1/1',
|
|
|
|
'xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance',
|
|
|
|
'xsi:schemaLocation':
|
|
|
|
'http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www8.garmin.com/xmlschemas/GpxExtensionsv3.xsd http://www.garmin.com/xmlschemas/WaypointExtension/v1 http://www8.garmin.com/xmlschemas/WaypointExtensionv1.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd',
|
|
|
|
'xmlns:gpxx': 'http://www.garmin.com/xmlschemas/GpxExtensions/v3',
|
|
|
|
'xmlns:wptx1': 'http://www.garmin.com/xmlschemas/WaypointExtension/v1',
|
|
|
|
'xmlns:gpxtpx': 'http://www.garmin.com/xmlschemas/TrackPointExtension/v1',
|
|
|
|
'xmlns:dyo': 'http://xmlns.dyomedea.com/',
|
|
|
|
},
|
|
|
|
metadata: {
|
|
|
|
name: undefined,
|
|
|
|
desc: undefined,
|
|
|
|
author: undefined,
|
|
|
|
copyright: undefined,
|
|
|
|
link: undefined,
|
|
|
|
time: undefined,
|
|
|
|
keywords: undefined,
|
|
|
|
bounds: undefined,
|
|
|
|
extensions: undefined,
|
|
|
|
},
|
|
|
|
wpt: undefined,
|
|
|
|
rte: undefined,
|
|
|
|
trk: undefined,
|
|
|
|
extensions: undefined,
|
|
|
|
};
|
|
|
|
|
2023-01-07 14:14:44 +00:00
|
|
|
export const newEmptyGpx = () => cloneDeep(emptyGpx);
|
|
|
|
|
2022-11-26 18:36:55 +00:00
|
|
|
export const putNewGpx = async (
|
|
|
|
id: IdGpx = { gpx: intToGpxId(Date.now()) }
|
|
|
|
) => {
|
|
|
|
const uri = getUri('gpx', id);
|
|
|
|
await put(
|
|
|
|
uri,
|
|
|
|
'gpx',
|
|
|
|
(gpx) => {
|
|
|
|
(gpx.metadata ??= {}).time = new Date(Date.now()).toISOString();
|
|
|
|
return gpx;
|
|
|
|
},
|
|
|
|
emptyGpx
|
|
|
|
);
|
|
|
|
return id;
|
|
|
|
};
|
|
|
|
|
|
|
|
export const existsGpx = async (id: IdGpx) => {
|
|
|
|
const uri = getUri('gpx', id);
|
|
|
|
try {
|
|
|
|
await get(uri);
|
|
|
|
return true;
|
|
|
|
} catch {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-12-13 11:41:13 +00:00
|
|
|
const prune = (
|
|
|
|
id: any,
|
|
|
|
object: any,
|
2023-02-03 13:57:40 +00:00
|
|
|
previousIds: {
|
|
|
|
rte: number;
|
|
|
|
wpt: number;
|
|
|
|
trk: number;
|
|
|
|
rtept: number;
|
|
|
|
trkseg: number;
|
|
|
|
trkpt: number;
|
|
|
|
},
|
2022-12-13 11:41:13 +00:00
|
|
|
extensions: any,
|
2023-02-13 10:23:17 +00:00
|
|
|
docs: any[],
|
2023-03-04 14:13:27 +00:00
|
|
|
to: string[]
|
2022-12-13 11:41:13 +00:00
|
|
|
) => {
|
2022-11-26 18:36:55 +00:00
|
|
|
if (typeof object === 'object') {
|
|
|
|
for (const key in object) {
|
|
|
|
if (
|
|
|
|
key === 'wpt' ||
|
|
|
|
key === 'rte' ||
|
2023-02-08 19:44:28 +00:00
|
|
|
// key === 'rtept' ||
|
2022-11-26 18:36:55 +00:00
|
|
|
key === 'trk' ||
|
2023-02-08 19:44:28 +00:00
|
|
|
key === 'trkseg'
|
|
|
|
// key === 'trkpt'
|
2022-11-26 18:36:55 +00:00
|
|
|
) {
|
|
|
|
const subObjects = object[key];
|
|
|
|
for (const index in subObjects) {
|
|
|
|
const subId = { ...id };
|
2023-02-08 19:44:28 +00:00
|
|
|
/* if (key === 'trkpt') {
|
2022-12-10 20:25:15 +00:00
|
|
|
// fix buggy times in GPX tracks
|
|
|
|
const normalId = intToTrkptId(
|
|
|
|
new Date(object[key][index].time).valueOf()
|
|
|
|
);
|
2023-02-03 13:57:40 +00:00
|
|
|
const id =
|
|
|
|
normalId > previousIds.trk ? normalId : previousIds.trk + 1;
|
2022-12-10 20:25:15 +00:00
|
|
|
subId[key] = id;
|
2023-02-03 13:57:40 +00:00
|
|
|
previousIds.trk = id;
|
2023-02-08 19:44:28 +00:00
|
|
|
} else { */
|
|
|
|
previousIds[key] = previousIds[key] + 1;
|
|
|
|
subId[key] = previousIds[key];
|
|
|
|
/* } */
|
2022-12-10 17:31:51 +00:00
|
|
|
// console.log({
|
|
|
|
// caller: 'prune',
|
|
|
|
// id,
|
|
|
|
// subId,
|
|
|
|
// key,
|
|
|
|
// object: object[key][index],
|
|
|
|
// time: object[key][index].time,
|
|
|
|
// });
|
2022-12-13 11:41:13 +00:00
|
|
|
subObjects[index].extensions = {
|
|
|
|
...extensions,
|
|
|
|
...subObjects[index].extensions,
|
|
|
|
};
|
2022-12-23 15:30:24 +00:00
|
|
|
if (isEmpty(subObjects[index].extensions)) {
|
|
|
|
subObjects[index].extensions = undefined;
|
|
|
|
}
|
2022-11-26 18:36:55 +00:00
|
|
|
docs.push({
|
|
|
|
_id: getUri(key, subId),
|
|
|
|
type: key,
|
2023-03-04 14:13:27 +00:00
|
|
|
to,
|
2023-03-04 15:07:22 +00:00
|
|
|
origin: dbUrlToUserId(state().remoteUrl),
|
2022-11-26 18:36:55 +00:00
|
|
|
doc: subObjects[index],
|
|
|
|
});
|
2023-03-04 14:13:27 +00:00
|
|
|
prune(subId, subObjects[index], previousIds, {}, docs, to);
|
2022-11-26 18:36:55 +00:00
|
|
|
}
|
|
|
|
object[key] = undefined;
|
2023-03-04 14:13:27 +00:00
|
|
|
} else prune(id, object[key], previousIds, extensions, docs, to);
|
2022-11-26 18:36:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-12-13 14:17:50 +00:00
|
|
|
const hasMissingTimestamps = (trk: Trk) => {
|
|
|
|
for (const trkseg of trk.trkseg!) {
|
|
|
|
for (const trkpt of trkseg.trkpt!) {
|
|
|
|
if (trkpt.time === undefined) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
};
|
|
|
|
|
|
|
|
const convertTrkToRteWhenNeeded = (gpx: Gpx) => {
|
|
|
|
if (gpx.trk === undefined) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const newTrks: Trk[] = [];
|
|
|
|
for (const trk of gpx.trk) {
|
|
|
|
if (hasMissingTimestamps(trk)) {
|
|
|
|
const rte = { ...trk, trkseg: undefined, rtept: [] };
|
|
|
|
for (const trkseg of trk.trkseg!) {
|
|
|
|
rte.rtept = rte.rtept.concat(trkseg.trkpt);
|
|
|
|
}
|
|
|
|
if (gpx.rte === undefined) {
|
|
|
|
gpx.rte = [];
|
|
|
|
}
|
|
|
|
gpx.rte.push(rte);
|
|
|
|
} else {
|
|
|
|
newTrks.push(trk);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
gpx.trk = newTrks;
|
|
|
|
};
|
|
|
|
|
2022-11-26 18:36:55 +00:00
|
|
|
export const pruneAndSaveImportedGpx = async (params: any) => {
|
2022-12-11 09:45:08 +00:00
|
|
|
console.log({ caller: 'pruneAndSaveImportedGpx', params });
|
2022-12-13 11:41:13 +00:00
|
|
|
const { id, gpx, tech } = params;
|
|
|
|
let gpxId: IdGpx;
|
|
|
|
let docs: any[] = [];
|
|
|
|
const extensions = {
|
|
|
|
...tech,
|
|
|
|
...gpx.extensions,
|
|
|
|
gpx: {
|
|
|
|
creator: gpx?.$?.creator,
|
|
|
|
metadata: gpx.metadata,
|
|
|
|
extensions: gpx.extensions,
|
2022-11-26 18:36:55 +00:00
|
|
|
},
|
2022-12-13 11:41:13 +00:00
|
|
|
};
|
2022-12-13 14:17:50 +00:00
|
|
|
convertTrkToRteWhenNeeded(gpx);
|
2022-12-13 11:41:13 +00:00
|
|
|
let previousGpx: Gpx | null = null;
|
2023-03-04 14:13:27 +00:00
|
|
|
let to: string[];
|
2022-12-13 11:41:13 +00:00
|
|
|
if (id === 'new') {
|
|
|
|
const currentDateTime = new Date().toISOString();
|
|
|
|
const startTime = new Date(findStartTime(gpx, currentDateTime));
|
|
|
|
if (gpx.metadata === undefined) {
|
|
|
|
gpx.metadata = {};
|
|
|
|
}
|
|
|
|
if (gpx.metadata.time === undefined) {
|
|
|
|
gpx.metadata.time = startTime.toISOString();
|
|
|
|
}
|
|
|
|
gpxId = { gpx: intToGpxId(startTime.valueOf()) };
|
|
|
|
docs = [
|
2023-02-13 10:23:17 +00:00
|
|
|
{
|
|
|
|
_id: getUri('gpx', gpxId),
|
|
|
|
type: 'gpx',
|
2023-03-04 15:07:22 +00:00
|
|
|
origin: dbUrlToUserId(state().remoteUrl),
|
2023-02-13 10:23:17 +00:00
|
|
|
doc: gpx,
|
2023-03-04 14:13:27 +00:00
|
|
|
// a new GPX isn't to...
|
2023-02-13 10:23:17 +00:00
|
|
|
},
|
2022-12-13 11:41:13 +00:00
|
|
|
{
|
|
|
|
_id: getUri('extensions', gpxId),
|
|
|
|
type: 'extensions',
|
2023-03-04 15:07:22 +00:00
|
|
|
origin: dbUrlToUserId(state().remoteUrl),
|
2022-12-13 11:41:13 +00:00
|
|
|
doc: {},
|
|
|
|
},
|
|
|
|
];
|
|
|
|
} else {
|
|
|
|
gpxId = getUri('gpx', id);
|
2023-02-03 10:59:40 +00:00
|
|
|
previousGpx = (await getGpx({ id })) ?? null;
|
2023-03-04 14:13:27 +00:00
|
|
|
if (previousGpx?.extensions?.to) {
|
|
|
|
to = previousGpx?.extensions?.to.split(/\s*,\s*/);
|
2023-02-13 10:23:17 +00:00
|
|
|
}
|
2023-02-03 10:59:40 +00:00
|
|
|
console.log({
|
|
|
|
caller: 'pruneAndSaveImportedGpx / previousGpx',
|
|
|
|
id,
|
|
|
|
previousGpx,
|
|
|
|
gpxId,
|
|
|
|
});
|
2022-12-13 11:41:13 +00:00
|
|
|
}
|
2023-02-03 13:57:40 +00:00
|
|
|
let previousIds = {
|
|
|
|
rte: -1,
|
|
|
|
wpt: -1,
|
|
|
|
trk: -1,
|
|
|
|
rtept: -1,
|
|
|
|
trkseg: -1,
|
|
|
|
trkpt: -1,
|
|
|
|
};
|
|
|
|
if (!!previousGpx?.wpt) {
|
|
|
|
const wptUri = previousGpx.wpt.at(-1);
|
|
|
|
const wptId = getUri('wpt', wptUri);
|
|
|
|
previousIds.wpt = wptId.wpt;
|
|
|
|
}
|
|
|
|
if (!!previousGpx?.rte) {
|
|
|
|
const rteUri = previousGpx.rte.at(-1);
|
|
|
|
const rteId = getUri('rte', rteUri);
|
|
|
|
previousIds.rte = rteId.rte;
|
|
|
|
}
|
|
|
|
if (!!previousGpx?.trk) {
|
|
|
|
const trkUri = previousGpx.trk.at(-1);
|
|
|
|
const trkId = getUri('trk', trkUri);
|
|
|
|
previousIds.trk = trkId.trk;
|
|
|
|
}
|
2023-03-04 14:13:27 +00:00
|
|
|
prune(gpxId, gpx, previousIds, extensions, docs, to);
|
2022-12-10 17:31:51 +00:00
|
|
|
console.log({ caller: 'pruneAndSaveImportedGpx / pruned', docs });
|
2022-11-26 18:36:55 +00:00
|
|
|
try {
|
|
|
|
const result = await putAll(docs);
|
|
|
|
console.log(JSON.stringify(result));
|
2022-12-13 11:41:13 +00:00
|
|
|
if (id !== 'new') {
|
|
|
|
put(id, 'gpx', (doc) => doc, {});
|
|
|
|
}
|
2022-11-26 18:36:55 +00:00
|
|
|
} catch (err) {
|
|
|
|
console.error(`error: ${err}`);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-11-27 13:32:21 +00:00
|
|
|
export const getAllGpxes = async () => {
|
2022-12-11 09:45:08 +00:00
|
|
|
try {
|
|
|
|
return (await get('gpx')).doc;
|
|
|
|
} catch {
|
|
|
|
return [];
|
|
|
|
}
|
2022-11-26 18:36:55 +00:00
|
|
|
};
|
|
|
|
|
2022-12-12 10:41:09 +00:00
|
|
|
export const getAllGpxesWithSummary = async () => {
|
|
|
|
const allGpxes = await getAllGpxes();
|
|
|
|
const result = await Promise.all(
|
|
|
|
allGpxes.map(async (id: string) => {
|
|
|
|
const gpxDoc = await get(id);
|
2022-12-12 17:55:14 +00:00
|
|
|
// console.log({ caller: 'getAllGpxesWithSummary', gpx: gpxDoc });
|
2022-12-12 10:41:09 +00:00
|
|
|
return {
|
|
|
|
id,
|
|
|
|
name: gpxDoc.doc.metadata?.name,
|
|
|
|
creator: gpxDoc.doc.$?.creator,
|
|
|
|
};
|
|
|
|
})
|
|
|
|
);
|
|
|
|
console.log({ caller: 'getAllGpxesWithSummary', result });
|
|
|
|
return result;
|
|
|
|
};
|
|
|
|
|
2022-11-27 15:09:08 +00:00
|
|
|
export const appendToArray = (target: any, key: string, value: any) => {
|
2022-11-26 18:36:55 +00:00
|
|
|
if (!(key in target)) {
|
|
|
|
target[key] = <any>[];
|
|
|
|
}
|
|
|
|
target[key].push(value);
|
|
|
|
};
|
|
|
|
|
|
|
|
export const getFullGpx = async (params: any) => {
|
|
|
|
const { id } = params;
|
|
|
|
const docs = await getFamily(id, { include_docs: true });
|
|
|
|
let target: any[];
|
|
|
|
let gpx: Gpx | undefined = undefined;
|
|
|
|
docs.rows.forEach((row: any) => {
|
|
|
|
// level 0
|
|
|
|
if (row.doc.type === 'gpx') {
|
|
|
|
target = [row.doc.doc];
|
|
|
|
gpx = row.doc.doc;
|
|
|
|
}
|
|
|
|
//level 1
|
|
|
|
if (
|
|
|
|
row.doc.type === 'wpt' ||
|
|
|
|
row.doc.type === 'rte' ||
|
|
|
|
row.doc.type === 'trk' ||
|
|
|
|
row.doc.type === 'extensions'
|
|
|
|
) {
|
|
|
|
target.splice(1);
|
|
|
|
appendToArray(target.at(-1), row.doc.type, row.doc.doc);
|
|
|
|
target.push(row.doc.doc);
|
|
|
|
}
|
|
|
|
// level 2
|
|
|
|
if (row.doc.type === 'rtept' || row.doc.type === 'trkseg') {
|
|
|
|
target.splice(2);
|
|
|
|
appendToArray(target.at(-1), row.doc.type, row.doc.doc);
|
|
|
|
target.push(row.doc.doc);
|
|
|
|
}
|
|
|
|
// level 3
|
|
|
|
if (row.doc.type === 'trkpt') {
|
|
|
|
appendToArray(target.at(-1), row.doc.type, row.doc.doc);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return gpx;
|
|
|
|
};
|
|
|
|
|
|
|
|
export const getGpx = async (params: any) => {
|
|
|
|
const { id } = params;
|
2022-12-12 19:57:25 +00:00
|
|
|
|
|
|
|
if (id === 'new') {
|
|
|
|
const newGpx = cloneDeep(emptyGpx);
|
|
|
|
newGpx.metadata!.time = new Date().toISOString();
|
|
|
|
return newGpx;
|
|
|
|
}
|
|
|
|
|
2022-11-26 18:36:55 +00:00
|
|
|
const docs = await getFamily(id, { include_docs: true });
|
2022-11-27 14:50:08 +00:00
|
|
|
let target: any[];
|
|
|
|
let gpx: Gpx | undefined = undefined;
|
2023-02-02 21:19:31 +00:00
|
|
|
docs.rows.every((row: any) => {
|
2022-11-27 14:50:08 +00:00
|
|
|
// level 0
|
|
|
|
if (row.doc.type === 'gpx') {
|
2023-02-02 21:19:31 +00:00
|
|
|
if (!!gpx) {
|
2023-02-03 10:59:40 +00:00
|
|
|
console.error({
|
|
|
|
caller: 'getGpx',
|
|
|
|
id,
|
|
|
|
row,
|
|
|
|
target,
|
|
|
|
gpx,
|
|
|
|
});
|
|
|
|
|
2023-02-02 21:19:31 +00:00
|
|
|
return false; // Hack to stop if getFamily fails
|
|
|
|
}
|
2022-11-27 14:50:08 +00:00
|
|
|
target = [row.doc.doc];
|
|
|
|
gpx = row.doc.doc;
|
|
|
|
}
|
|
|
|
//level 1 (extensions)
|
2022-12-23 14:41:03 +00:00
|
|
|
if (target !== undefined && row.doc.type === 'extensions') {
|
2023-02-12 17:14:14 +00:00
|
|
|
console.log({
|
|
|
|
caller: 'getGpx / extensions',
|
|
|
|
gpx,
|
|
|
|
row,
|
|
|
|
doc: row.doc.doc,
|
|
|
|
gpx_extensions: gpx?.extensions,
|
|
|
|
target,
|
|
|
|
});
|
|
|
|
|
|
|
|
gpx.extensions = row.doc.doc;
|
|
|
|
|
|
|
|
// target.splice(1);
|
|
|
|
// appendToArray(target.at(-1), row.doc.type, row.doc.doc);
|
|
|
|
// target.push(row.doc.doc);
|
2022-11-27 14:50:08 +00:00
|
|
|
}
|
|
|
|
//level 1 (others)
|
|
|
|
if (
|
2022-12-23 14:41:03 +00:00
|
|
|
target !== undefined &&
|
|
|
|
(row.doc.type === 'wpt' ||
|
|
|
|
row.doc.type === 'rte' ||
|
|
|
|
row.doc.type === 'trk')
|
2022-11-27 14:50:08 +00:00
|
|
|
) {
|
|
|
|
target.splice(1);
|
|
|
|
appendToArray(target.at(-1), row.doc.type, row.doc._id);
|
|
|
|
target.push(row.doc.doc);
|
|
|
|
}
|
2023-02-02 21:19:31 +00:00
|
|
|
return true;
|
2022-11-27 14:50:08 +00:00
|
|
|
});
|
|
|
|
return gpx;
|
2022-11-26 18:36:55 +00:00
|
|
|
};
|
2022-12-12 17:55:14 +00:00
|
|
|
|
2022-12-13 19:59:39 +00:00
|
|
|
export const getNextGpxTrkId = async (gpxId: string) => {
|
|
|
|
const docs = await getFamily(gpxId, { include_docs: true });
|
|
|
|
const gpxIdObj = getUri('gpx', gpxId);
|
|
|
|
console.log({ caller: 'getNextGpxTrkId', gpxId, gpxIdObj, docs });
|
|
|
|
let trkId = '';
|
|
|
|
docs.rows.forEach((row: any) => {
|
|
|
|
if (row.doc.type === 'trk') {
|
|
|
|
trkId = row.doc._id;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
if (trkId !== '') {
|
|
|
|
const trkIdObj = getUri('trk', trkId);
|
|
|
|
return getUri('trk', { gpx: gpxIdObj.gpx, trk: trkIdObj.trk + 1 });
|
|
|
|
}
|
|
|
|
return getUri('trk', { gpx: gpxIdObj.gpx, trk: 0 });
|
|
|
|
};
|
|
|
|
|
|
|
|
export const appendTrk = async (params: any) => {
|
|
|
|
const { gpxId, trk } = params;
|
|
|
|
const trkId = await getNextGpxTrkId(gpxId);
|
|
|
|
console.log({ caller: 'appendTrk', gpxId, trk, trkId });
|
|
|
|
await put(trkId, 'trk', (doc) => trk, {});
|
|
|
|
return trkId;
|
|
|
|
};
|
|
|
|
|
2022-12-12 17:55:14 +00:00
|
|
|
export const putGpx = async (params: any) => {
|
2022-12-12 19:57:25 +00:00
|
|
|
let { id, gpx } = params;
|
|
|
|
|
2023-02-13 14:59:41 +00:00
|
|
|
try {
|
2023-02-13 19:57:30 +00:00
|
|
|
if (id === 'new' || !id) {
|
2023-02-13 14:59:41 +00:00
|
|
|
const date = !!gpx.metadata.time
|
|
|
|
? new Date(gpx.metadata.time)
|
|
|
|
: new Date();
|
|
|
|
id = getUri('gpx', {
|
|
|
|
gpx: intToGpxId(date.valueOf()),
|
|
|
|
});
|
|
|
|
}
|
2023-02-12 17:14:14 +00:00
|
|
|
|
2023-03-04 14:13:27 +00:00
|
|
|
let previousTo;
|
2023-02-13 14:59:41 +00:00
|
|
|
try {
|
2023-03-04 14:13:27 +00:00
|
|
|
previousTo = (await get(`${id}/4extensions`)).doc?.to;
|
2023-02-13 14:59:41 +00:00
|
|
|
} catch (error) {}
|
2023-02-12 17:14:14 +00:00
|
|
|
|
2023-03-04 14:13:27 +00:00
|
|
|
console.log({ caller: 'putGpx', params, id, gpx, previousTo });
|
2023-02-13 14:59:41 +00:00
|
|
|
const extensions = gpx?.extensions;
|
2022-12-12 17:55:14 +00:00
|
|
|
|
2023-02-13 14:59:41 +00:00
|
|
|
gpx.extensions = undefined;
|
|
|
|
gpx.wpt = undefined;
|
|
|
|
gpx.trk = undefined;
|
|
|
|
gpx.rte = undefined;
|
2022-12-12 17:55:14 +00:00
|
|
|
|
2023-02-13 14:59:41 +00:00
|
|
|
await put(id, 'gpx', (doc) => gpx, gpx);
|
|
|
|
if (extensions !== undefined) {
|
|
|
|
try {
|
|
|
|
await put(
|
|
|
|
`${id}/4extensions`,
|
|
|
|
'extensions',
|
|
|
|
(doc) => extensions,
|
|
|
|
extensions
|
|
|
|
);
|
|
|
|
} catch (error) {
|
|
|
|
console.error({
|
|
|
|
caller: 'putGpx / extensions',
|
|
|
|
error,
|
|
|
|
});
|
|
|
|
}
|
2023-02-13 14:44:02 +00:00
|
|
|
}
|
2023-02-12 17:14:14 +00:00
|
|
|
|
2023-03-04 14:13:27 +00:00
|
|
|
if (previousTo !== extensions?.to) {
|
|
|
|
const to = extensions?.to.split(/\s*,\s*/);
|
2023-02-13 14:59:41 +00:00
|
|
|
const family = (await getFamily(id, { include_docs: true })).rows.map(
|
|
|
|
(row: any) => {
|
2023-03-04 14:13:27 +00:00
|
|
|
return { ...row.doc, to };
|
2023-02-13 14:59:41 +00:00
|
|
|
}
|
|
|
|
);
|
|
|
|
console.log({
|
2023-03-04 14:13:27 +00:00
|
|
|
caller: 'putGpx / updateTo',
|
2023-02-13 14:59:41 +00:00
|
|
|
params,
|
|
|
|
id,
|
|
|
|
gpx,
|
2023-03-04 14:13:27 +00:00
|
|
|
previousTo,
|
2023-02-13 14:59:41 +00:00
|
|
|
family,
|
|
|
|
});
|
|
|
|
await db.bulkDocs(family);
|
|
|
|
}
|
|
|
|
} catch (error) {
|
|
|
|
console.error({
|
|
|
|
caller: 'putGpx',
|
2023-02-12 17:14:14 +00:00
|
|
|
params,
|
|
|
|
id,
|
|
|
|
gpx,
|
2023-02-13 14:59:41 +00:00
|
|
|
error,
|
2023-02-12 17:14:14 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2022-12-12 17:55:14 +00:00
|
|
|
return id;
|
|
|
|
};
|