feat: ignore bad distances when measuring track length
This commit is contained in:
parent
5770229945
commit
d5f617e25c
65
src/_helpers/generators.js
Normal file
65
src/_helpers/generators.js
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
function* pairwise(iter) {
|
||||||
|
let last;
|
||||||
|
let firstLoop = true;
|
||||||
|
for (const it of iter) {
|
||||||
|
if (firstLoop) {
|
||||||
|
firstLoop = false;
|
||||||
|
} else {
|
||||||
|
yield [last, it];
|
||||||
|
}
|
||||||
|
last = it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function* enumerate(iter) {
|
||||||
|
let i = 0;
|
||||||
|
for (const it of iter) {
|
||||||
|
yield [i, it];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const map = (fn) =>
|
||||||
|
function* (iter) {
|
||||||
|
for (const [i, it] of enumerate(iter)) {
|
||||||
|
yield fn(it, i);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const filter = (fn) =>
|
||||||
|
function* (iter) {
|
||||||
|
for (const it of iter) {
|
||||||
|
if (fn(it)) {
|
||||||
|
yield it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const reduce = (fn, init) => (iter) => {
|
||||||
|
let acc = init;
|
||||||
|
for (const it of iter) {
|
||||||
|
acc = fn(acc, it);
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
};
|
||||||
|
|
||||||
|
const scan = (fn) =>
|
||||||
|
function* (iter, init) {
|
||||||
|
let acc = init;
|
||||||
|
for (const it of iter) {
|
||||||
|
acc = fn(acc, it);
|
||||||
|
yield acc;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const flow = (...reducers) => (input) => reducers.reduce((c, fn) => fn(c), input);
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
filter,
|
||||||
|
map,
|
||||||
|
enumerate,
|
||||||
|
pairwise,
|
||||||
|
flow,
|
||||||
|
reduce,
|
||||||
|
scan,
|
||||||
|
};
|
|
@ -2,6 +2,8 @@ const mongoose = require('mongoose');
|
||||||
const uniqueValidator = require('mongoose-unique-validator');
|
const uniqueValidator = require('mongoose-unique-validator');
|
||||||
const turf = require('turf');
|
const turf = require('turf');
|
||||||
|
|
||||||
|
const { flow, filter, map, pairwise, reduce } = require('../_helpers/generators');
|
||||||
|
|
||||||
const schema = new mongoose.Schema(
|
const schema = new mongoose.Schema(
|
||||||
{
|
{
|
||||||
slug: { type: String, lowercase: true, unique: true },
|
slug: { type: String, lowercase: true, unique: true },
|
||||||
|
@ -76,12 +78,17 @@ class TrackData extends mongoose.Model {
|
||||||
}
|
}
|
||||||
|
|
||||||
measureTrackLength() {
|
measureTrackLength() {
|
||||||
let totalLength = 0;
|
return flow(
|
||||||
for (const [a, b] of pairwise(map(this.points, (p) => turf.point([p.longitude, p.latitude])))) {
|
filter((p) => p.latitude != null && p.longitude != null),
|
||||||
const legLengthMeters = turf.distance(a, b) * 1000;
|
map((p) => turf.point([p.longitude, p.latitude])),
|
||||||
totalLength += legLengthMeters;
|
pairwise,
|
||||||
}
|
map(([a, b]) => turf.distance(a, b) * 1000),
|
||||||
return totalLength;
|
|
||||||
|
// Ignore distances between two points that are bigger than 100m, this
|
||||||
|
// must be a gap in the data or a mistake.
|
||||||
|
filter((d) => d <= 100),
|
||||||
|
reduce((c, d) => c + d, 0),
|
||||||
|
)(this.points);
|
||||||
}
|
}
|
||||||
|
|
||||||
get duration() {
|
get duration() {
|
||||||
|
@ -93,33 +100,6 @@ class TrackData extends mongoose.Model {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function* pairwise(iter) {
|
|
||||||
let last;
|
|
||||||
let firstLoop = true;
|
|
||||||
for (const it of iter) {
|
|
||||||
if (firstLoop) {
|
|
||||||
firstLoop = false;
|
|
||||||
} else {
|
|
||||||
yield [last, it];
|
|
||||||
}
|
|
||||||
last = it;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function* enumerate(iter) {
|
|
||||||
let i = 0;
|
|
||||||
for (const it of iter) {
|
|
||||||
yield [i, it];
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function* map(iter, fn) {
|
|
||||||
for (const [i, it] of enumerate(iter)) {
|
|
||||||
yield fn(it, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mongoose.model(TrackData, schema);
|
mongoose.model(TrackData, schema);
|
||||||
|
|
||||||
module.exports = TrackData;
|
module.exports = TrackData;
|
||||||
|
|
Loading…
Reference in a new issue