-
Notifications
You must be signed in to change notification settings - Fork 0
/
util.js
91 lines (82 loc) · 2.33 KB
/
util.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
const fetch = require('node-fetch');
const fs = require('fs');
const togeojson = require('@mapbox/togeojson');
const { DOMParser } = require('xmldom');
const FitParser = require('fit-file-parser').default;
/**
* Transform a '.fit' file imported from FitParser into GeoJSON.
*/
function fitToGeoJson(data) {
const geo = {
features: [],
type: 'FeatureCollection',
};
if (data && data.records) {
const feature = {
geometry: {
coordinates: [],
type: 'LineString',
},
properties: {
name: data.sport ? data.sport.name : '',
time: data.file_id.time_created,
},
type: 'Feature',
};
for (let i = 0; i < data.records.length; ++i) {
const record = data.records[i];
if (record.position_long && record.position_lat && record.altitude) {
feature.geometry.coordinates.push([
record.position_long,
record.position_lat,
record.altitude,
]);
}
}
geo.features.push(feature);
}
return geo;
}
/**
* Transform a '.gpx' or '.fit' file into GeoJSON.
*/
function toGeoJson(filePath) {
return new Promise(resolve => {
if (filePath.includes('.gpx')) {
const file = fs.readFileSync(filePath, 'utf8');
const path = togeojson.gpx(
new DOMParser().parseFromString(file, 'text/xml'),
);
resolve(path);
} else if (filePath.includes('.fit')) {
const file = fs.readFileSync(filePath);
const fitParser = new FitParser({
elapsedRecordField: true,
force: true,
lengthUnit: 'mi',
mode: 'both',
speedUnit: 'mph',
temperatureUnit: 'fahrenheit',
});
fitParser.parse(file, (_, data) => {
const path = fitToGeoJson(data);
resolve(path);
});
}
});
}
/**
* Get a place (city and country) given a longitude and latitude (i.e. a reverse geocode).
* @note You must pass in a Mapbox token for this function to work properly.
*/
async function reverseGeocode(long, lat, token = '') {
const url = `https://api.mapbox.com/geocoding/v5/mapbox.places/${long},${lat}.json?access_token=${token}`;
const res = await fetch(url);
const { features } = await res.json();
const [{ place_name }] = features.filter(({ id }) => id.includes('place'));
return place_name;
}
module.exports = {
reverseGeocode,
toGeoJson,
};