Applying the same update to trkpt

This commit is contained in:
Eric van der Vlist 2023-02-10 15:30:45 +01:00
parent d8d15d9d83
commit b30af4c3ac
4 changed files with 263 additions and 42 deletions

View File

@ -86,13 +86,13 @@ export const getRteDocs: ({
rte.rtept.push(row.doc.doc);
});
}
console.log({
caller: 'getRteDocs',
id,
docs,
nbRteptIn: docs.rows[0].doc.doc.rtept?.length,
nbRteptTotal: rte?.rtept?.length,
});
// console.log({
// caller: 'getRteDocs',
// id,
// docs,
// nbRteptIn: docs.rows[0].doc.doc.rtept?.length,
// nbRteptTotal: rte?.rtept?.length,
// });
return { docs, rte };
};
@ -100,6 +100,10 @@ export const getRte = async (params: any) => {
const { id } = params;
const { docs, rte } = await getRteDocs(params);
if (docs.rows.length > 1) {
console.log({
caller: 'getRte compactRteOrTrksegDebounced required',
id,
});
compactRteOrTrksegDebounced({ id, getDocs: getRteDocs });
}
return rte;

197
src/db/trkpt.test.ts Normal file
View File

@ -0,0 +1,197 @@
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import shell from 'shelljs';
import PouchDB from 'pouchdb';
import { getTrkseg, getTrksegDocs, putTrkseg } from './trkseg';
import { putTrkpt } from './trkpt';
import { get, getFamily, put } from './lib';
import { emptyWpt } from './wpt';
const test = it;
const jest = vi;
declare global {
var db: any;
var dbReady: boolean;
}
const originalDb = globalThis.db;
const originalDateNow = globalThis.Date.now;
describe('The trkpt module with a real db', () => {
beforeEach(async () => {
globalThis.db = new PouchDB('dyomedea', {
auto_compaction: false,
});
globalThis.Date.now = () => 0;
// vi.mock('./rte', async () => {
// const originalModule = await vi.importActual('./rte');
// return {
// ...originalModule,
// compactTrksegOrTrksegDebounced: () => {
// console.log('mocked compactTrksegOrTrksegDebounced');
// },
// };
// });
});
afterEach(async () => {
try {
await db.destroy();
} catch (err) {
// console.error(err);
await shell.exec('rm -rf $*$');
}
globalThis.db = undefined;
globalThis.dbReady = false;
globalThis.Date.now = originalDateNow;
});
it('can write a trkpt inside a trkseg', async () => {
const idTrkseg = 'gpx/4320836410265485/2trkseg/000034';
const trkpt: Wpt = {
$: { lat: 2, lon: 2 },
};
const trkseg0: Trkseg = {
trkpt: [
{
$: { lat: 0, lon: 0 },
},
{
$: { lat: 1, lon: 1 },
},
],
};
const trkseg1: Trkseg = {
trkpt: [
{
$: { lat: 0, lon: 0 },
},
{
$: { lat: 2, lon: 2 },
},
],
};
const trksegPut = await putTrkseg(idTrkseg, trkseg0);
expect(trksegPut).toEqual(idTrkseg);
const trksegPutTrksegpt = await putTrkpt({
id: idTrkseg,
index: 1,
wpt: trkpt,
});
const trksegGetTrksegpt = await getTrkseg({ id: idTrkseg });
expect(trksegGetTrksegpt).toEqual(trkseg1);
});
it('can write a trkpt outside a trkseg', async () => {
const idTrkseg = 'gpx/4320836410265485/2trkseg/000034';
const idTrksegpt = 'gpx/4320836410265485/2trkseg/000034/000035';
const trkpt3: Wpt = {
$: { lat: 3, lon: 3 },
};
const trkpt4: Wpt = {
$: { lat: 4, lon: 4 },
};
const trkseg0: Trkseg = {
trkpt: [
{
$: { lat: 1, lon: 1 },
},
{
$: { lat: 2, lon: 2 },
},
],
};
const trkseg1: Trkseg = {
trkpt: [
{
$: { lat: 1, lon: 1 },
},
{
$: { lat: 2, lon: 2 },
},
trkpt3,
],
};
const trkseg2: Trkseg = {
trkpt: [
{
$: { lat: 1, lon: 1 },
},
{
$: { lat: 2, lon: 2 },
},
trkpt4,
],
};
const trksegPut = await putTrkseg(idTrkseg, trkseg0);
expect(trksegPut).toEqual(idTrkseg);
expect(await getTrkseg({ id: idTrkseg })).toEqual(trkseg0);
await put(idTrksegpt, 'trkpt', () => trkpt3, emptyWpt);
const { trkseg, docs } = await getTrksegDocs({ id: idTrkseg });
console.log({
caller: 'test',
trkptIn: JSON.stringify(docs.rows[0].doc.doc.trkpt),
});
expect(await getTrkseg({ id: idTrkseg })).toEqual(trkseg1);
await putTrkpt({
id: idTrkseg,
index: 2,
wpt: trkpt4,
});
expect((await getFamily(idTrkseg)).rows.length).toEqual(2);
expect(await getTrkseg({ id: idTrkseg })).toEqual(trkseg2);
expect((await get(idTrksegpt)).doc).toEqual(trkpt4);
});
it('can write a trkpt outside a trkseg with a negative index', async () => {
const idTrkseg = 'gpx/4320836410265485/2trkseg/000034';
const idTrksegpt = 'gpx/4320836410265485/2trkseg/000034/000035';
const trkpt3: Wpt = {
$: { lat: 3, lon: 3 },
};
const trkpt4: Wpt = {
$: { lat: 4, lon: 4 },
};
const trkseg0: Trkseg = {
trkpt: [
{
$: { lat: 1, lon: 1 },
},
{
$: { lat: 2, lon: 2 },
},
],
};
const trkseg1: Trkseg = {
trkpt: [
{
$: { lat: 1, lon: 1 },
},
{
$: { lat: 2, lon: 2 },
},
trkpt3,
],
};
const trkseg2: Trkseg = {
trkpt: [
{
$: { lat: 1, lon: 1 },
},
{
$: { lat: 2, lon: 2 },
},
trkpt4,
],
};
const trksegPut = await putTrkseg(idTrkseg, trkseg0);
await put(idTrksegpt, 'trkpt', () => trkpt3, emptyWpt);
await putTrkpt({
id: idTrkseg,
index: -1,
wpt: trkpt4,
});
expect(await getTrkseg({ id: idTrkseg })).toEqual(trkseg2);
expect((await get(idTrksegpt)).doc).toEqual(trkpt4);
});
});

View File

@ -1,5 +1,7 @@
import getUri, { intToTrkptId } from '../lib/ids';
import { put } from './lib';
import { getTrksegDocs, putTrkseg } from './trkseg';
import { emptyWpt } from './wpt';
const emptyTrkpt: Wpt = {
$: { lat: 0, lon: 0 },
@ -30,10 +32,28 @@ const emptyTrkpt: Wpt = {
},
};
export const putTrkpt = async (params: any) => {
const { id, trkpt } = params;
trkpt.id = undefined;
await put(id, 'trkpt', (doc) => trkpt, trkpt);
return trkpt;
const { id, index, wpt } = params;
const { docs } = await getTrksegDocs({ id: id });
const trkseg = docs.rows[0].doc.doc;
const nbWptInTrkseg = trkseg && trkseg.trkpt ? trkseg.trkpt.length : 0;
const nbWptOutTrkseg = docs.rows.length - 1;
const nbWpt = nbWptInTrkseg + nbWptOutTrkseg;
const positiveIndex = index >= 0 ? index : nbWpt + index;
console.log({
caller: 'putTrkpt',
nbWptInTrkseg,
nbWptOutTrkseg,
nbWpt,
positiveIndex,
trkpt: JSON.stringify(trkseg.trkpt),
});
if (positiveIndex < nbWptInTrkseg) {
trkseg.trkpt[positiveIndex] = wpt;
await putTrkseg(id, trkseg);
} else {
const trkptId = docs.rows[1 + positiveIndex - nbWptInTrkseg].doc._id;
await put(trkptId, 'trkpt', () => wpt, emptyWpt);
}
return wpt;
};

View File

@ -1,3 +1,4 @@
import { cloneDeep } from 'lodash';
import getUri, { intToTrkptId } from '../lib/ids';
import { appendToArray } from './gpx';
import { getFamily, put } from './lib';
@ -10,44 +11,43 @@ const emptyTrkseg: Trkseg = {
extensions: undefined,
};
const getTrksegDocs = async (params: any) => {
export const getTrksegDocs: ({
id,
}: {
id: string;
}) => Promise<{ docs: any; trkseg: Trkseg }> = async (params) => {
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) => {
// level 0
if (row.doc.type === 'trkseg') {
if (!!trkseg) {
console.error({
caller: 'getTrksegDocs',
id,
row,
target,
trkseg,
});
return false; // Hack to stop if getFamily fails
}
target = [row.doc.doc];
trkseg = row.doc.doc;
let trkseg: Trkseg;
if (docs.rows.length === 1) {
trkseg = docs.rows[0].doc.doc;
} else {
trkseg = cloneDeep(docs.rows[0].doc.doc);
if (!trkseg.trkpt) {
trkseg.trkpt = [];
}
//level 1
if (row.doc.type === 'trkpt') {
target.splice(1);
// 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 };
docs.rows.slice(1).forEach((row: any) => {
trkseg.trkpt.push(row.doc.doc);
});
}
// console.log({
// caller: 'getRteDocs',
// id,
// docs,
// nbRteptIn: docs.rows[0].doc.doc.rtept?.length,
// nbRteptTotal: rte?.rtept?.length,
// });
return { docs, trkseg };
};
export const getTrkseg = async (params: any) => {
const { id } = params;
const { docs, trkseg } = await getTrksegDocs(params);
if (docs.rows.length > 1) {
console.log({
caller: 'getTrkseg compactRteOrTrksegDebounced required',
id,
});
compactRteOrTrksegDebounced({ id, getDocs: getTrksegDocs });
}
return trkseg;