aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/trips.ts115
-rw-r--r--lib/useEvent.ts20
-rw-r--r--lib/util.ts30
3 files changed, 0 insertions, 165 deletions
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;
- });
-}
diff --git a/lib/useEvent.ts b/lib/useEvent.ts
deleted file mode 100644
index 70d51b1..0000000
--- a/lib/useEvent.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { useEffect } from 'react';
-
-/**
- * A hook for creating event handlers.
- */
-export default function useEvent(
- event: string,
- handler: (e: KeyboardEvent | MouseEvent) => void,
- passive = false,
-): void {
- useEffect(() => {
- // initiate the event handler
- window.addEventListener(event, handler, passive);
-
- // this will clean up the event every time the component is re-rendered
- return function cleanup() {
- window.removeEventListener(event, handler);
- };
- });
-}
diff --git a/lib/util.ts b/lib/util.ts
deleted file mode 100644
index 5a00aed..0000000
--- a/lib/util.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * Converts time in seconds to HH:mm format.
- * @param time Time to convert in seconds.
- */
-export function secondsToTimeString(time: number): string {
- const h = Math.floor(time / 3600);
- const m = Math.floor((time % 3600) / 60);
-
- return `${h < 10 ? `0${h}` : h}:${m < 10 ? `0${m}` : m}`;
-}
-
-/**
- * Calculates distance between two geographical points.
- * @param latlng1 Coordinates of the first point.
- * @param latlng2 Coordinates of the second point.
- */
-export function distanceBetween(latlng1: number[], latlng2: number[]): number {
- const R = 6371000;
- const rad = Math.PI / 180;
- const lat1 = latlng1[0] * rad;
- const lat2 = latlng2[0] * rad;
- const sinDLat = Math.sin(((latlng2[0] - latlng1[0]) * rad) / 2);
- const sinDLon = Math.sin(((latlng2[1] - latlng1[1]) * rad) / 2);
- const a = sinDLat * sinDLat + Math.cos(lat1) * Math.cos(lat2) * sinDLon * sinDLon;
- const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
-
- return R * c;
-}
-
-export default { secondsToTimeString, distanceBetween };