import { streamToArrayPromise, toStream } from "../utils/streams"; import { compile } from "ejs"; import fs from "fs"; import Database from "../database/database"; import { Field, PadId, Type } from "facilmap-types"; import { compileExpression, prepareObject, quoteHtml } from "facilmap-utils"; import { LineWithTrackPoints } from "../database/line"; import { keyBy } from "lodash"; import highland from "highland"; const lineTemplateP = fs.promises.readFile(`${__dirname}/gpx-line.ejs`).then((t) => { return compile(t.toString()); }); function dataToText(fields: Field[], data: Record) { if(fields.length == 1 && fields[0].name == "Description") return data["Description"] || ""; const text = [ ]; for(let i=0; i { return toStream(async () => { const filterFunc = compileExpression(filter); const [padData, types] = await Promise.all([ database.pads.getPadData(padId), streamToArrayPromise(database.types.getTypes(padId)).then((types) => keyBy(types, 'id')) ]); if (!padData) throw new Error(`Pad ${padId} could not be found.`); const markers = database.markers.getPadMarkers(padId).filter((marker) => filterFunc(prepareObject(marker, types[marker.typeId]))); const lines = database.lines.getPadLinesWithPoints(padId).filter((line) => filterFunc(prepareObject(line, types[line.typeId]))); return highland([ `\n` + `\n` + `\t\n` + `\t\t${quoteHtml(padData.name)}\n` + `\t\t\n` + `\t\n` ]).concat(markers.map((marker) => ( `\t\n` + `\t\t${quoteHtml(marker.name)}\n` + `\t\t${quoteHtml(dataToText(types[marker.typeId].fields, marker.data))}\n` + `\t\n` ))).concat(lines.map((line) => ((useTracks || line.mode == "track") ? ( `\t\n` + `\t\t${quoteHtml(line.name)}\n` + `\t\t${dataToText(types[line.typeId].fields, line.data)}\n` + `\t\t\n` + line.trackPoints.map((trackPoint) => ( `\t\t\t\n` )).join("") + `\t\t\n` + `\t\n` ) : ( `\t\n` + `\t\t${quoteHtml(line.name)}\n` + `\t\t${quoteHtml(dataToText(types[line.typeId].fields, line.data))}\n` + line.routePoints.map((routePoint) => ( `\t\t\n` )).join("") + `\t\n` )))).concat([ `` ]); }).flatten(); } type LineForExport = Partial>; export async function exportLineToGpx(line: LineForExport, type: Type | undefined, useTracks: boolean): Promise { const lineTemplate = await lineTemplateP; return lineTemplate({ useTracks: (useTracks || line.mode == "track"), time: new Date().toISOString(), desc: type && dataToText(type.fields, line.data ?? {}), line }); }