Migrate geolib to turf, reduce bundle size

This commit is contained in:
Mattéo Delabre 2020-07-25 16:28:51 +02:00
parent 3b8a0de9b0
commit 35cd0e1e72
Signed by: matteo
GPG Key ID: AE3FBD02DC583ABB
6 changed files with 31221 additions and 32410 deletions

1981
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -13,12 +13,14 @@
"author": "",
"license": "ISC",
"dependencies": {
"@turf/along": "^6.0.1",
"@turf/helpers": "^6.1.4",
"@turf/length": "^6.0.2",
"@turf/turf": "^5.1.6",
"axios": "^0.19.2",
"color": "^3.1.2",
"csv-parse": "^4.8.3",
"express": "^4.17.1",
"geolib": "^3.2.1",
"ol": "^6.1.1",
"unzip-stream": "^0.3.0"
},

View File

@ -3,6 +3,9 @@ require('ol/ol.css');
const axios = require('axios');
const {Map, View} = require('ol');
const GeoJSON = require('ol/format/GeoJSON').default;
const reader = new GeoJSON({featureProjection: 'EPSG:3857'});
const TileLayer = require('ol/layer/Tile').default;
const XYZSource = require('ol/source/XYZ').default;
@ -25,22 +28,6 @@ h0NmFsdzQ3emxqIn0.cyxF0h36emIMTk3cc4VqUw`;
const simulation = require('../tam/simulation');
const network = require('../tam/network.json');
const getRoutesLines = routes => routes.filter(
// Only consider normal routes (excluding alternate routes)
([lineRef, routeRef]) =>
network.lines[lineRef].routes[routeRef].state === 'normal'
).map(([lineRef]) => lineRef);
const getLinesColors = lines =>
{
if (lines.length >= 1)
{
return lines.map(lineRef => network.lines[lineRef].color);
}
return ['#FFFFFF'];
};
const lineFeaturesOrder = (feature1, feature2) =>
{
const lines1 = feature1.get('lines');
@ -65,28 +52,29 @@ const makeDataSources = () =>
const segmentsSource = new VectorSource();
const stopsSource = new VectorSource();
segmentsSource.addFeatures(
Object.values(network.segments).map(({routes, nodes}) =>
new Feature({
lines: getRoutesLines(routes),
colors: getLinesColors(getRoutesLines(routes)),
geometry: new LineString(nodes.map(
({lat, lon}) => proj.fromLonLat([lon, lat])
)),
})
)
);
const readFeatures = hash => Object.values(hash).map(json =>
{
json.properties.lines = json.properties.routes.filter(
// Only consider normal routes (excluding alternate routes)
([lineRef, routeRef]) =>
network.lines[lineRef].routes[routeRef].state === 'normal'
).map(([lineRef]) => lineRef);
stopsSource.addFeatures(
Object.values(network.stops).map(({routes, lon, lat}) =>
new Feature({
lines: getRoutesLines(routes),
colors: getLinesColors(getRoutesLines(routes)),
geometry: new Point(proj.fromLonLat([lon, lat])),
})
)
);
if (json.properties.lines.length >= 1)
{
json.properties.colors = json.properties.lines.map(
lineRef => network.lines[lineRef].color);
}
else
{
json.properties.colors = ['#FFFFFF'];
}
return reader.readFeature(json);
});
segmentsSource.addFeatures(readFeatures(network.segments));
stopsSource.addFeatures(readFeatures(network.stops));
return {segmentsSource, stopsSource};
};

View File

@ -12,7 +12,8 @@
* the `script/update-network` script.
*/
const geolib = require('geolib');
const turfHelpers = require('@turf/helpers');
const turfLength = require('@turf/length').default;
const util = require('../util');
const osm = require('./sources/osm');
const tam = require('./sources/tam');
@ -89,16 +90,20 @@ a “ref” tag`);
if (!(stop.tags.ref in stops))
{
stops[stop.tags.ref] = {
lat: stop.lat,
lon: stop.lon,
stops[stop.tags.ref] = turfHelpers.point([
stop.lon,
stop.lat
], {
name: stop.tags.name,
routes: [[lineRef, routeRef]],
};
});
}
else
{
stops[stop.tags.ref].routes.push([lineRef, routeRef]);
stops[stop.tags.ref].properties.routes.push([
lineRef,
routeRef
]);
}
}
}
@ -215,42 +220,31 @@ ${name} is one-way and cannot be used in reverse.`);
if (id in segments)
{
if (!util.arraysEqual(nodesIds, segments[id].nodesIds))
if (!util.arraysEqual(
nodesIds,
segments[id].properties.nodesIds
))
{
throw new Error(`Segment ${id} is defined as a
different sequence of nodes in two or more lines.`);
}
segments[id].routes.push([lineRef, routeRef]);
segments[id].properties.routes.push([lineRef, routeRef]);
}
else
{
const nodes = nodesIds.map(id => ({
lat: elements[id].lat,
lon: elements[id].lon
}));
if (nodes.length)
{
// Augment each node with the distance to the start
nodes[0].distance = 0;
for (let i = 1; i < nodes.length; ++i)
{
nodes[i].distance = geolib.getPreciseDistance(
nodes[i - 1],
nodes[i],
) + nodes[i - 1].distance;
}
}
segments[id] = {
segments[id] = turfHelpers.lineString(nodesIds.map(id => [
elements[id].lon,
elements[id].lat
]), {
// Keep track of the original sequence of nodes to
// compare with duplicates
nodesIds,
nodes,
routes: [[lineRef, routeRef]],
};
});
segments[id].properties.length = (
1000 * turfLength(segments[id]));
}
}
@ -269,7 +263,7 @@ different sequence of nodes in two or more lines.`);
// Remove OSM nodes from segments that were only used for checking validity
for (let segment of Object.values(segments))
{
delete segment.nodesIds;
delete segment.properties.nodesIds;
}
return {stops, lines, segments};

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,6 @@
const axios = require('axios');
const turf = require('@turf/turf');
const turfAlong = require('@turf/along').default;
const turfProjection = require('@turf/projection');
const network = require('./network.json');
const server = 'http://localhost:4321';
@ -137,78 +138,36 @@ class Course
tick(time)
{
if (this.state === null)
{
// Ignore uninitalized courses
}
else if (this.state === 'moving')
if (this.state === 'moving')
{
// Integrate current speed in travelled distance
const delta = this.speed * time;
this.traveledDistance += this.speed * time;
const segment = this.currentSegment;
const length = segment.nodes[segment.nodes.length - 1].distance;
this.traveledDistance += delta;
if (this.traveledDistance >= length)
if (this.traveledDistance >= segment.properties.length)
{
this.arriveToStop(this.arrivalStop);
return;
}
// Recompute updated position
const departureStop = network.stops[this.departureStop];
const arrivalStop = network.stops[this.arrivalStop];
const nextNodeIndex = segment.nodes.findIndex(
({distance}) => distance >= this.traveledDistance);
// Compute updated position and angle based on a small step
const step = 10; // In meters
if (nextNodeIndex === 0)
{
this.position = turf.toMercator([
departureStop.lon,
departureStop.lat
]);
}
else
{
const previousNode = segment.nodes[nextNodeIndex - 1];
const nextNode = segment.nodes[nextNodeIndex];
const positions = [
Math.max(0, this.traveledDistance - step / 2),
this.traveledDistance,
this.traveledDistance + step / 2
].map(distance => turfProjection.toMercator(turfAlong(
segment,
distance / 1000
)).geometry.coordinates);
const previousPoint = turf.toMercator([
previousNode.lon,
previousNode.lat
]);
this.angle = Math.atan2(
positions[0][1] - positions[2][1],
positions[2][0] - positions[0][0],
);
const nextPoint = turf.toMercator([
nextNode.lon,
nextNode.lat
]);
const curLength = this.traveledDistance
- previousNode.distance;
const totalLength = nextNode.distance
- previousNode.distance;
const t = curLength / totalLength;
this.position = [
t * nextPoint[0] + (1 - t) * previousPoint[0],
t * nextPoint[1] + (1 - t) * previousPoint[1],
];
this.angle = Math.atan2(
previousPoint[1] - nextPoint[1],
nextPoint[0] - previousPoint[0],
);
}
}
else // this.state === 'stopped'
{
const currentNode = network.stops[this.currentStop];
this.position = turf.toMercator([
currentNode.lon,
currentNode.lat
]);
this.position = positions[1];
}
}
@ -221,10 +180,9 @@ class Course
{
this.state = 'stopped';
this.currentStop = stop;
this.position = turf.toMercator([
network.stops[this.currentStop].lon,
network.stops[this.currentStop].lat,
]);
this.position = (
turfProjection.toMercator(network.stops[stop])
.geometry.coordinates);
this.history.push(['arriveToStop', stop]);
}
@ -250,10 +208,6 @@ ${this.currentStop} to stop ${stop}. Teleporting to ${stop}`);
this.arrivalTime = arrivalTime;
this.traveledDistance = 0;
this.speed = 0;
this.position = turf.toMercator([
network.stops[this.departureStop].lon,
network.stops[this.departureStop].lat,
]);
this.history.push(['moveToStop', stop, arrivalTime]);
console.info(`Course ${this.id} leaving stop ${this.currentStop} \
@ -271,10 +225,10 @@ with initial speed ${this.computeTheoreticalSpeed() * 3600} km/h`);
}
const segment = this.currentSegment;
const length = segment.nodes[segment.nodes.length - 1].distance;
const remainingTime = this.arrivalTime - Date.now();
const remainingDistance = length - this.traveledDistance;
const remainingDistance = (
segment.properties.length - this.traveledDistance
);
if (remainingDistance <= 0)
{