From f2ecc1803f3ea294a0c6b7915b61348ed0395b26 Mon Sep 17 00:00:00 2001 From: Marcin Zelent Date: Wed, 16 Nov 2022 15:16:38 +0100 Subject: Remade and extended the app using React --- lib/trips.ts | 115 ----------------------------------------------------------- 1 file changed, 115 deletions(-) delete mode 100644 lib/trips.ts (limited to 'lib/trips.ts') diff --git a/lib/trips.ts b/lib/trips.ts deleted file mode 100644 index 40a71a4..0000000 --- a/lib/trips.ts +++ /dev/null @@ -1,115 +0,0 @@ -import path from 'path'; -import fs from 'fs'; -import { DOMParser } from 'xmldom'; -import { FeatureCollection, LineString } from 'geojson'; -import { gpx } from '@tmcw/togeojson'; -import gb from 'geojson-bounds'; -import * as ExifReader from 'exifreader'; -import _ from 'lodash'; - -import { Trip, Photo } from 'models'; -import { distanceBetween } from 'lib/util'; - -const tripsDirectory = path.join(process.cwd(), 'trips'); - -// extract photo metadata from EXIF -function getPhotoMetadata(filePath: string) { - const buffer = fs.readFileSync(filePath); - const tags = ExifReader.load(buffer, { expanded: true }); - - return { - latitude: tags.gps.Latitude, - longitude: tags.gps.Longitude, - time: tags.exif.DateTime.description.replace(':', '-').replace(':', '-'), - }; -} - -/** - * Reads GPX files and photos from trips folder. - */ -export default function getTripsData(): Trip[] { - // get folder names under /trips - const dirs = fs - .readdirSync(tripsDirectory, { withFileTypes: true }) - .filter((dirent) => dirent.isDirectory()) - .map((dirent) => dirent.name); - const allTripsData = dirs.map((dir: string) => { - const dirPath = path.join(tripsDirectory, dir); - const files = fs.readdirSync(dirPath); - - const gpxFiles = files.filter((f) => f.endsWith('.gpx')); - - // read GPX file as string - const fullPath = path.join(dirPath, gpxFiles[0]); - const fileContents = fs.readFileSync(fullPath, 'utf8'); - const contentsWithoutNS = fileContents.replace(/\sxmlns[^"]+"[^"]+"/g, ''); - - // create DOM from string - const doc = new DOMParser().parseFromString(contentsWithoutNS); - - // convert GPX to GeoJSON - const track: FeatureCollection = gpx(doc); - - // add bounding box - track.bbox = [gb.xMin(track), gb.yMin(track), gb.xMax(track), gb.yMax(track)]; - - const { coordTimes } = track.features[0].properties; - - // time of the first point - const start = coordTimes[0]; - - // time of the last point - const end = coordTimes[coordTimes.length - 1]; - - // total duration in seconds - const duration = (new Date(end).getTime() - new Date(start).getTime()) / 1000; - - // distance and speed - let totalDistance = 0; - const speeds = []; - const coords = (track.features[0].geometry as LineString).coordinates; - - for (let i = 0; i < coords.length - 1; i += 1) { - const a = [coords[i][1], coords[i][0]]; - const b = [coords[i + 1][1], coords[i + 1][0]]; - const distance = distanceBetween(a, b); - if (distance > 0) { - totalDistance += distance; - const timeBetween = - new Date(coordTimes[i + 1]).getTime() - new Date(coordTimes[i]).getTime(); - speeds.push(distance / timeBetween); - } - } - - // total distance in km - const distance = Math.floor(totalDistance / 10) / 100; - - // average speed in km/h - const speedMps = speeds.reduce((acc, val) => acc + val) / speeds.length; - const speed = Math.floor(speedMps * 3600 * 100) / 100; - - // photos - const photoFiles = files.filter((f) => f.endsWith('.jpg')); - const photos: Photo[] = photoFiles.map((p) => { - // eslint-disable-next-line global-require, import/no-dynamic-require, @typescript-eslint/no-var-requires - return { - name: _.kebabCase(p), - src: require(`trips/${dir}/${p}`).src, - thumbnail: require(`trips/${dir}/${p}?resize&sizes[]=36`).src, - ...getPhotoMetadata(path.join(dirPath, p)), - }; - }); - - const trip: Trip = { name: dir, track, distance, start, end, duration, speed, photos }; - - return trip; - }); - - // sort trips by name - return allTripsData.sort((a, b) => { - if (a.name < b.name) { - return 1; - } - return -1; - }); -} -- cgit v1.2.3