Better blending of adjacent lines on map
This commit is contained in:
parent
a5aa58d2ee
commit
37a9a1bd72
140
front/map.js
140
front/map.js
|
@ -1,5 +1,6 @@
|
||||||
require('ol/ol.css');
|
require('ol/ol.css');
|
||||||
|
|
||||||
|
const axios = require('axios');
|
||||||
const {Map, View} = require('ol');
|
const {Map, View} = require('ol');
|
||||||
|
|
||||||
const TileLayer = require('ol/layer/Tile').default;
|
const TileLayer = require('ol/layer/Tile').default;
|
||||||
|
@ -17,47 +18,77 @@ const proj = require('ol/proj');
|
||||||
const {Style, Fill, Stroke, Circle} = require('ol/style');
|
const {Style, Fill, Stroke, Circle} = require('ol/style');
|
||||||
const color = require('color');
|
const color = require('color');
|
||||||
|
|
||||||
const mapboxToken = 'pk.eyJ1IjoibWF0dGVvZGVsYWJyZSIsImEiOiJjazUxaWNsdXcwdWhjM2\
|
const mapboxToken = `pk.eyJ1IjoibWF0dGVvZGVsYWJyZSIsImEiOiJja2NxaTUyMmUwcmFhMn\
|
||||||
9tc2xndXJoNGtxIn0.xELwMerqJLFimIqU6RxnZw';
|
h0NmFsdzQ3emxqIn0.cyxF0h36emIMTk3cc4VqUw`;
|
||||||
|
|
||||||
const server = window.origin;
|
const server = window.origin;
|
||||||
|
|
||||||
const fetchDataSources = async () =>
|
const fetchDataSources = async () =>
|
||||||
{
|
{
|
||||||
const dataSource = new VectorSource();
|
const segmentsSource = new VectorSource();
|
||||||
|
const stopsSource = new VectorSource();
|
||||||
|
|
||||||
const res = await fetch(`${server}/network`);
|
const network = (await axios.get(`${server}/network`)).data;
|
||||||
const network = await res.json();
|
|
||||||
|
|
||||||
const stopPoints = Object.entries(network.stops)
|
segmentsSource.addFeatures(
|
||||||
.map(([stopId, stop]) =>
|
Object.values(network.lines).flatMap(({color, routes}) =>
|
||||||
new Feature({
|
|
||||||
type: 'stop',
|
|
||||||
color: network.lines[stop.lines[0]].color,
|
|
||||||
geometry: new Point(proj.fromLonLat([stop.lon, stop.lat])),
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
dataSource.addFeatures(stopPoints);
|
|
||||||
|
|
||||||
const segmentLines = Object.values(network.lines)
|
|
||||||
.flatMap(({color, routes}) =>
|
|
||||||
routes.map(({segments}) =>
|
routes.map(({segments}) =>
|
||||||
new Feature({
|
new Feature({
|
||||||
type: 'segment',
|
|
||||||
color,
|
color,
|
||||||
geometry: new LineString(segments.flat().map(
|
geometry: new LineString(segments.flat().map(
|
||||||
({lat, lon}) => proj.fromLonLat([lon, lat])
|
({lat, lon}) => proj.fromLonLat([lon, lat])
|
||||||
)),
|
)),
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
dataSource.addFeatures(segmentLines);
|
stopsSource.addFeatures(
|
||||||
|
Object.entries(network.stops).map(([stopId, stop]) =>
|
||||||
|
new Feature({
|
||||||
|
color: network.lines[stop.lines[0]].color,
|
||||||
|
geometry: new Point(proj.fromLonLat([stop.lon, stop.lat])),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
return dataSource;
|
return {segmentsSource, stopsSource};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const makeBorderColor = mainColor =>
|
||||||
|
{
|
||||||
|
const hsl = color(mainColor).hsl();
|
||||||
|
hsl.color = Math.max(0, hsl.color[2] -= 20);
|
||||||
|
return hsl.hex();
|
||||||
|
};
|
||||||
|
|
||||||
|
const segmentsBorderStyle = feature => new Style({
|
||||||
|
stroke: new Stroke({
|
||||||
|
color: makeBorderColor(feature.get('color')),
|
||||||
|
width: 8,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const segmentsInnerStyle = feature => new Style({
|
||||||
|
stroke: new Stroke({
|
||||||
|
color: feature.get('color'),
|
||||||
|
width: 6,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const stopsStyle = feature => new Style({
|
||||||
|
image: new Circle({
|
||||||
|
fill: new Fill({
|
||||||
|
color: feature.get('color'),
|
||||||
|
}),
|
||||||
|
stroke: new Stroke({
|
||||||
|
color: makeBorderColor(feature.get('color')),
|
||||||
|
width: 1.5,
|
||||||
|
}),
|
||||||
|
radius: 6,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
const createMap = async (target) =>
|
const createMap = async (target) =>
|
||||||
{
|
{
|
||||||
// Map background
|
// Map background
|
||||||
|
@ -74,54 +105,31 @@ const createMap = async (target) =>
|
||||||
});
|
});
|
||||||
|
|
||||||
// Data overlay
|
// Data overlay
|
||||||
const dataSource = await fetchDataSources();
|
const {segmentsSource, stopsSource} = await fetchDataSources();
|
||||||
|
|
||||||
const makeBorderColor = mainColor =>
|
const segmentsBorderLayer = new VectorLayer({
|
||||||
{
|
source: segmentsSource,
|
||||||
const hsl = color(mainColor).hsl();
|
style: segmentsBorderStyle,
|
||||||
hsl.color = Math.max(0, hsl.color[2] -= 20);
|
|
||||||
return hsl.hex();
|
|
||||||
};
|
|
||||||
|
|
||||||
const dataLayer = new VectorLayer({
|
|
||||||
source: dataSource,
|
|
||||||
updateWhileInteracting: true,
|
updateWhileInteracting: true,
|
||||||
updateWhileAnimating: true,
|
updateWhileAnimating: true,
|
||||||
style: feature =>
|
|
||||||
{
|
|
||||||
if (feature.get('type') === 'stop')
|
|
||||||
{
|
|
||||||
return new Style({
|
|
||||||
image: new Circle({
|
|
||||||
fill: new Fill({
|
|
||||||
color: feature.get('color'),
|
|
||||||
}),
|
|
||||||
stroke: new Stroke({
|
|
||||||
color: makeBorderColor(feature.get('color')),
|
|
||||||
width: 2,
|
|
||||||
}),
|
|
||||||
radius: 6,
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
else if (feature.get('type') === 'segment')
|
const segmentsInnerLayer = new VectorLayer({
|
||||||
{
|
source: segmentsSource,
|
||||||
return [
|
style: segmentsInnerStyle,
|
||||||
new Style({
|
|
||||||
stroke: new Stroke({
|
updateWhileInteracting: true,
|
||||||
color: makeBorderColor(feature.get('color')),
|
updateWhileAnimating: true,
|
||||||
width: 8,
|
});
|
||||||
}),
|
|
||||||
}),
|
const stopsLayer = new VectorLayer({
|
||||||
new Style({
|
source: stopsSource,
|
||||||
stroke: new Stroke({
|
style: stopsStyle,
|
||||||
color: feature.get('color'),
|
|
||||||
width: 6,
|
minZoom: 13,
|
||||||
}),
|
updateWhileInteracting: true,
|
||||||
}),
|
updateWhileAnimating: true,
|
||||||
];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Setup map
|
// Setup map
|
||||||
|
@ -129,7 +137,9 @@ const createMap = async (target) =>
|
||||||
target,
|
target,
|
||||||
layers: [
|
layers: [
|
||||||
backgroundLayer,
|
backgroundLayer,
|
||||||
dataLayer,
|
segmentsBorderLayer,
|
||||||
|
segmentsInnerLayer,
|
||||||
|
stopsLayer,
|
||||||
],
|
],
|
||||||
view: new View({
|
view: new View({
|
||||||
center: proj.fromLonLat([3.88, 43.605]),
|
center: proj.fromLonLat([3.88, 43.605]),
|
||||||
|
|
Loading…
Reference in New Issue