Major update: storing trkpt and rtept inside trkseg and rte instead of independent documents.
This commit is contained in:
parent
ecae9b4037
commit
92ffe42ab9
15
README.md
15
README.md
|
@ -1,11 +1,15 @@
|
|||
# Dyomedea
|
||||
|
||||
## License
|
||||
|
||||
GPL 3.0.
|
||||
|
||||
## Branches
|
||||
|
||||
* master: dev branch (started as a React project; now using dolidjs)
|
||||
* multi-layers: attempt to create a native React map components. Went pretty far but there was still so many things to implement that I switched to:
|
||||
* openlayers: an attempt to use React with Openlayers. Wasn't that easy because Openlayers is heavily based on the DOM while React uses a "pseudo-dom". That has been one of the reasons why I switched (again) to:
|
||||
* solid: a SolidJS / Openlayers implementation that has replaced the master branch on Feb 5th, 2023.
|
||||
* master: dev (and only active) branch (started as a React project, now using solidjs)
|
||||
* multi-layers: (deprecated) attempt to create a native React map components. Went pretty far but there was still so many things to implement that I switched to:
|
||||
* openlayers: (deprecated) an attempt to use React with Openlayers. Wasn't that easy because Openlayers is heavily based on the DOM while React uses a "pseudo-dom". That has been one of the reasons why I switched (again) to:
|
||||
* solid: (merged into master and deprecated) a SolidJS / Openlayers implementation that has replaced the master branch on Feb 5th, 2023.
|
||||
|
||||
## Hiking app.
|
||||
|
||||
|
@ -350,6 +354,9 @@ Requires esrun (`sudo npm i -g @digitak/esrun`)
|
|||
|
||||
### Patches
|
||||
|
||||
```
|
||||
|
||||
|
||||
* suid: https://github.com/swordev/suid/issues/89
|
||||
|
||||
### NPM updates: use npm-check-updates !
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { Component, createEffect, createSignal, onCleanup } from 'solid-js';
|
||||
|
||||
import dispatch, { cancelDispatch } from '../../workers/dispatcher-main';
|
||||
import VectorSource from 'ol/source/Vector';
|
||||
import GeoJSON from 'ol/format/GeoJSON';
|
||||
import {
|
||||
|
@ -36,7 +35,7 @@ export const Rte: Component<Props> = ({ vectorSource, rteId, context }) => {
|
|||
createEffect(() => {
|
||||
console.log({ caller: 'Rte', vectorSource, rteId, rte: rte() });
|
||||
|
||||
if (rte()) {
|
||||
if (rte() && rte().rtept && rte().rtept.length > 0) {
|
||||
let geo: any = {
|
||||
type: 'FeatureCollection',
|
||||
features: [
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Component, createSignal } from 'solid-js';
|
||||
import { Component, createSignal, Show } from 'solid-js';
|
||||
import { peekCachedSignal } from '../../workers/cached-signals';
|
||||
import RteIcon from '../../icons/directions-svgrepo-com.svg?component-solid';
|
||||
import { useI18n } from '@solid-primitives/i18n';
|
||||
|
@ -74,11 +74,13 @@ const RteViewer: Component<Props> = ({ rteId }) => {
|
|||
<>
|
||||
<div>
|
||||
{getFormatedLength(lineString)} {t('from')}{' '}
|
||||
<Show when={false}>
|
||||
<DisplayOrGetAddress
|
||||
target={() => rte().rtept.at(0)}
|
||||
putAction='putRtept'
|
||||
putParamName='rtept'
|
||||
/>{' '}
|
||||
</Show>
|
||||
{t('to')}{' '}
|
||||
<DisplayOrGetAddress
|
||||
target={() => rte().rtept.at(-1)}
|
||||
|
|
|
@ -49,7 +49,7 @@ export const Trkseg: Component<Props> = ({
|
|||
createEffect(() => {
|
||||
console.log({ caller: 'Trkseg', vectorSource, trksegId, trkseg: trkseg() });
|
||||
|
||||
if (trkseg()) {
|
||||
if (trkseg() && trkseg().trkpt && trkseg().trkpt.length > 0) {
|
||||
let geo: any = {
|
||||
type: 'FeatureCollection',
|
||||
features: [
|
||||
|
|
|
@ -84,15 +84,15 @@ const prune = (
|
|||
if (
|
||||
key === 'wpt' ||
|
||||
key === 'rte' ||
|
||||
key === 'rtept' ||
|
||||
// key === 'rtept' ||
|
||||
key === 'trk' ||
|
||||
key === 'trkseg' ||
|
||||
key === 'trkpt'
|
||||
key === 'trkseg'
|
||||
// key === 'trkpt'
|
||||
) {
|
||||
const subObjects = object[key];
|
||||
for (const index in subObjects) {
|
||||
const subId = { ...id };
|
||||
if (key === 'trkpt') {
|
||||
/* if (key === 'trkpt') {
|
||||
// fix buggy times in GPX tracks
|
||||
const normalId = intToTrkptId(
|
||||
new Date(object[key][index].time).valueOf()
|
||||
|
@ -101,10 +101,10 @@ const prune = (
|
|||
normalId > previousIds.trk ? normalId : previousIds.trk + 1;
|
||||
subId[key] = id;
|
||||
previousIds.trk = id;
|
||||
} else {
|
||||
} else { */
|
||||
previousIds[key] = previousIds[key] + 1;
|
||||
subId[key] = previousIds[key];
|
||||
}
|
||||
/* } */
|
||||
// console.log({
|
||||
// caller: 'prune',
|
||||
// id,
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { debounce, memoize, property, wrap } from 'lodash';
|
||||
import { delay } from '../lib/delay';
|
||||
import getUri from '../lib/ids';
|
||||
import { appendToArray, putNewGpx } from './gpx';
|
||||
import { getFamily, put } from './lib';
|
||||
|
@ -32,9 +34,43 @@ export const putNewRte = async (id?: IdRte | IdGpx) => {
|
|||
return finalId as IdRte;
|
||||
};
|
||||
|
||||
export const getRte = async (params: any) => {
|
||||
// See https://stackoverflow.com/questions/28787436/debounce-a-function-with-argument
|
||||
const debounceByParam = (
|
||||
targetFunc: (params: any) => any,
|
||||
resolver: (params: any) => any,
|
||||
...debounceParams: any
|
||||
) =>
|
||||
wrap(
|
||||
memoize(() => debounce(targetFunc, ...debounceParams), resolver),
|
||||
(getMemoizedFunc, ...params) => getMemoizedFunc(...params)(...params)
|
||||
);
|
||||
|
||||
const compactRteOrTrkseg = (params: any) => {
|
||||
const { getDocs } = params;
|
||||
getDocs(params).then(({ docs }) => {
|
||||
if (docs.rows.length > 1) {
|
||||
const compactedDocs = docs.rows.map((row: any) => {
|
||||
if (['rte', 'trkseg'].includes(row.doc.type)) {
|
||||
return row.doc;
|
||||
}
|
||||
return { ...row.doc, doc: undefined, _deleted: true };
|
||||
});
|
||||
db.bulkDocs(compactedDocs);
|
||||
}
|
||||
console.log({ caller: 'compactRteOrTrkseg', params, compactedDocs });
|
||||
});
|
||||
};
|
||||
|
||||
export const compactRteOrTrksegDebounced = debounceByParam(
|
||||
compactRteOrTrkseg,
|
||||
property('id'),
|
||||
3600000 * (1 + Math.random())
|
||||
);
|
||||
|
||||
const getRteDocs = async (params: any) => {
|
||||
const { id } = params;
|
||||
const docs = await getFamily(id, { include_docs: true });
|
||||
// console.log({ caller: 'getRte', id, docs });
|
||||
let target: any[];
|
||||
let rte: Rte | undefined = undefined;
|
||||
docs.rows.every((row: any) => {
|
||||
|
@ -56,12 +92,21 @@ export const getRte = async (params: any) => {
|
|||
//level 1
|
||||
if (row.doc.type === 'rtept') {
|
||||
target.splice(1);
|
||||
row.doc.doc.id = row.doc._id;
|
||||
// row.doc.doc.id = row.doc._id;
|
||||
appendToArray(target.at(-1), row.doc.type, row.doc.doc);
|
||||
target.push(row.doc.doc);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return { docs, rte };
|
||||
};
|
||||
|
||||
export const getRte = async (params: any) => {
|
||||
const { id } = params;
|
||||
const { docs, rte } = await getRteDocs(params);
|
||||
if (docs.rows.length > 1) {
|
||||
compactRteOrTrksegDebounced({ id, getDocs: getRteDocs });
|
||||
}
|
||||
return rte;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
import getUri from '../lib/ids';
|
||||
import { put } from './lib';
|
||||
import { putNewRte } from './rte';
|
||||
|
||||
export const emptyRtept: Wpt = {
|
||||
$: { lat: 0, lon: 0 },
|
||||
|
@ -24,28 +21,3 @@ export const emptyRtept: Wpt = {
|
|||
dgpsid: undefined,
|
||||
extensions: undefined,
|
||||
};
|
||||
|
||||
export const putNewRtept = async (id?: IdGpx | IdRte | IdRtept) => {
|
||||
let finalId = { ...id };
|
||||
if (!('rtept' in finalId)) {
|
||||
const rteId = await putNewRte(id);
|
||||
finalId = { ...rteId, rtept: 0 };
|
||||
}
|
||||
const uri = getUri('rtept', finalId);
|
||||
await put(
|
||||
uri,
|
||||
'rtept',
|
||||
(rtept) => {
|
||||
return rtept;
|
||||
},
|
||||
emptyRtept
|
||||
);
|
||||
return finalId as IdRtept;
|
||||
};
|
||||
|
||||
export const putRtept = async (params: any) => {
|
||||
const { id, rtept } = params;
|
||||
rtept.id = undefined;
|
||||
await put(id, 'rtept', (doc) => rtept, rtept);
|
||||
return rtept;
|
||||
};
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import getUri, { intToTrkptId } from '../lib/ids';
|
||||
import { put } from './lib';
|
||||
import { putNewTrkseg } from './trkseg';
|
||||
|
||||
const emptyTrkpt: Wpt = {
|
||||
$: { lat: 0, lon: 0 },
|
||||
|
@ -31,24 +30,6 @@ const emptyTrkpt: Wpt = {
|
|||
},
|
||||
};
|
||||
|
||||
export const putNewTrkpt = async (id?: IdTrk | IdGpx | IdTrkseg | IdTrkpt) => {
|
||||
let finalId = { ...id };
|
||||
if (!('trkpt' in finalId)) {
|
||||
const trksegId = await putNewTrkseg(id);
|
||||
finalId = { ...trksegId, trkpt: intToTrkptId(Date.now()) };
|
||||
}
|
||||
const uri = getUri('trkpt', finalId);
|
||||
await put(
|
||||
uri,
|
||||
'trkpt',
|
||||
(trkpt) => {
|
||||
return trkpt;
|
||||
},
|
||||
emptyTrkpt
|
||||
);
|
||||
return finalId;
|
||||
};
|
||||
|
||||
|
||||
export const putTrkpt = async (params: any) => {
|
||||
const { id, trkpt } = params;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import getUri, { intToTrkptId } from '../lib/ids';
|
||||
import { appendToArray } from './gpx';
|
||||
import { getFamily, put } from './lib';
|
||||
import { compactRteOrTrksegDebounced } from './rte';
|
||||
import { putNewTrk } from './trk';
|
||||
import { emptyWpt } from './wpt';
|
||||
|
||||
|
@ -9,27 +10,10 @@ const emptyTrkseg: Trkseg = {
|
|||
extensions: undefined,
|
||||
};
|
||||
|
||||
export const putNewTrkseg = async (id?: IdTrk | IdGpx | IdTrkseg) => {
|
||||
let finalId = { ...id };
|
||||
if (!('trkseg' in finalId)) {
|
||||
const trkId = await putNewTrk(id);
|
||||
finalId = { ...trkId, trkseg: 0 };
|
||||
}
|
||||
const uri = getUri('trkseg', finalId);
|
||||
await put(
|
||||
uri,
|
||||
'trkseg',
|
||||
(trkseg) => {
|
||||
return trkseg;
|
||||
},
|
||||
emptyTrkseg
|
||||
);
|
||||
return finalId as IdTrkseg;
|
||||
};
|
||||
|
||||
export const getTrkseg = async (params: any) => {
|
||||
const getTrksegDocs = async (params: any) => {
|
||||
const { id } = params;
|
||||
const docs = await getFamily(id, { include_docs: true });
|
||||
console.log({ caller: 'getTrksegDocs', id, docs });
|
||||
let target: any[];
|
||||
let trkseg: Trkseg | undefined = undefined;
|
||||
docs.rows.every((row: any) => {
|
||||
|
@ -37,13 +21,12 @@ export const getTrkseg = async (params: any) => {
|
|||
if (row.doc.type === 'trkseg') {
|
||||
if (!!trkseg) {
|
||||
console.error({
|
||||
caller: 'getTrkseg',
|
||||
caller: 'getTrksegDocs',
|
||||
id,
|
||||
row,
|
||||
target,
|
||||
trkseg,
|
||||
});
|
||||
|
||||
return false; // Hack to stop if getFamily fails
|
||||
}
|
||||
target = [row.doc.doc];
|
||||
|
@ -52,12 +35,21 @@ export const getTrkseg = async (params: any) => {
|
|||
//level 1
|
||||
if (row.doc.type === 'trkpt') {
|
||||
target.splice(1);
|
||||
row.doc.doc.id = row.doc._id;
|
||||
// row.doc.doc.id = row.doc._id;
|
||||
appendToArray(target.at(-1), row.doc.type, row.doc.doc);
|
||||
target.push(row.doc.doc);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return { trkseg, docs };
|
||||
};
|
||||
|
||||
export const getTrkseg = async (params: any) => {
|
||||
const { id } = params;
|
||||
const { docs, trkseg } = await getTrksegDocs(params);
|
||||
if (docs.rows.length > 1) {
|
||||
compactRteOrTrksegDebounced({ id, getDocs: getTrksegDocs });
|
||||
}
|
||||
return trkseg;
|
||||
};
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@ import {
|
|||
} from '../db/gpx';
|
||||
import { putOverlays } from '../db/overlays';
|
||||
import { deleteRte, putRte } from '../db/rte';
|
||||
import { putRtept } from '../db/rtept';
|
||||
import { getSettings, putSettings } from '../db/settings';
|
||||
import { getState, setState } from '../db/state';
|
||||
import { deleteTrk, getTrk, putNewTrk } from '../db/trk';
|
||||
|
@ -52,7 +51,6 @@ onmessage = async function (e) {
|
|||
|
||||
putWpt,
|
||||
putRte,
|
||||
putRtept,
|
||||
putTrkpt,
|
||||
|
||||
deleteTrk,
|
||||
|
|
Loading…
Reference in New Issue