10 Commits

Author SHA1 Message Date
Râu Cao
e74e460480 1.9.0 2022-09-15 10:02:34 +02:00
Râu Cao
0cb10203c7 Only show riders when tracking timestamp is newer than 3 hours ago 2022-09-15 10:02:15 +02:00
Râu Cao
a8c0aefbd6 1.8.0 2022-09-14 19:05:41 +02:00
Râu Cao
9c18cc19b7 Add popover for rider markers 2022-09-14 19:05:15 +02:00
Râu Cao
1dc218ca8a 1.7.0 2022-09-14 18:50:38 +02:00
Râu Cao
bfd9b4fdf6 Add riders to map 2022-09-14 18:50:02 +02:00
Râu Cao
67707b7ded 1.6.0 2022-09-14 10:18:29 +02:00
Râu Cao
9c96037e32 Add legacy routes 2022-09-14 10:17:55 +02:00
Râu Cao
fc4c63b519 1.5.0 2022-09-13 07:55:53 +02:00
Râu Cao
fe1c9f6300 Adjust for multiple tracked POIs 2022-09-13 07:55:09 +02:00
12 changed files with 182639 additions and 64 deletions

182553
data/legacy-route.json Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

11
dist/assets/index.b6f9bc24.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

3
dist/index.html vendored
View File

@@ -7,11 +7,12 @@
<title>Road2Bitcoin Live Map</title> <title>Road2Bitcoin Live Map</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/css/bootstrap.min.css"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/css/bootstrap.min.css">
<script defer data-domain="r2b22.kip.pe" src="https://plausible.io/js/plausible.js"></script> <script defer data-domain="r2b22.kip.pe" src="https://plausible.io/js/plausible.js"></script>
<script type="module" crossorigin src="/assets/index.148d1b99.js"></script> <script type="module" crossorigin src="/assets/index.b6f9bc24.js"></script>
<link rel="stylesheet" href="/assets/index.eed9f443.css"> <link rel="stylesheet" href="/assets/index.eed9f443.css">
</head> </head>
<body> <body>
<div id="map"><div id="popup"></div></div> <div id="map"><div id="popup"></div></div>
<div id="people"></div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/js/bootstrap.bundle.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/js/bootstrap.bundle.min.js"></script>
</body> </body>

View File

@@ -10,6 +10,7 @@
</head> </head>
<body> <body>
<div id="map"><div id="popup"></div></div> <div id="map"><div id="popup"></div></div>
<div id="people"></div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/js/bootstrap.bundle.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/js/bootstrap.bundle.min.js"></script>
<script type="module" src="./main.js"></script> <script type="module" src="./main.js"></script>
</body> </body>

115
main.js
View File

@@ -7,9 +7,10 @@ import Point from 'ol/geom/Point';
import {Tile as TileLayer, Vector as VectorLayer} from 'ol/layer'; import {Tile as TileLayer, Vector as VectorLayer} from 'ol/layer';
import {Circle as CircleStyle, Fill, Icon, Stroke, Style} from 'ol/style'; import {Circle as CircleStyle, Fill, Icon, Stroke, Style} from 'ol/style';
import {OSM, Vector as VectorSource} from 'ol/source'; import {OSM, Vector as VectorSource} from 'ol/source';
import {useGeographic, fromLonLat} from 'ol/proj'; import {useGeographic} from 'ol/proj';
import geojsonRoute from './geo/route.json' import geojsonRoute from './data/r2b22-route.json'
import geojsonPOI from './geo/poi.json' import geojsonPOI from './data/r2b22-poi.json';
import geojsonLegacy from './data/legacy-route.json';
useGeographic(); useGeographic();
@@ -103,8 +104,7 @@ async function main() {
const vanFeature= new Feature({ const vanFeature= new Feature({
geometry: new Point([8.918618, 44.407408]), geometry: new Point([8.918618, 44.407408]),
name: 'Support Van', name: 'Support Van'
trackable: true
}); });
vectorSourceTrackedPoints.addFeature(vanFeature); vectorSourceTrackedPoints.addFeature(vanFeature);
@@ -114,6 +114,18 @@ async function main() {
style: styles.iconVan style: styles.iconVan
}); });
//
// Legacy routes
//
const vectorSourceLegacy = new VectorSource();
vectorSourceLegacy.addFeatures(new GeoJSON().readFeatures(geojsonLegacy));
const legacyLayer = new VectorLayer({
source: vectorSourceLegacy,
style: styles.lineOrange
});
// //
// Map initialization // Map initialization
// //
@@ -133,6 +145,7 @@ async function main() {
}), }),
stagesCompletedLayer, stagesCompletedLayer,
stagesAheadLayer, stagesAheadLayer,
legacyLayer,
poiLayer, poiLayer,
trackedPointsLayer trackedPointsLayer
], ],
@@ -177,15 +190,6 @@ async function main() {
title.textContent = feature.get('name'); title.textContent = feature.get('name');
container.append(title); container.append(title);
return container.innerHTML; return container.innerHTML;
// if (feature.get('trackable')) {
// const linkParent = document.createElement('div');
// const followLink = document.createElement('a');
// followLink.textContent = 'Follow';
// followLink.href = '#';
// followLink.addEventListener('click', startFollowing(feature, followLink));
// linkParent.append(followLink);
// container.append(linkParent);
// }
} }
// display popup on click // display popup on click
@@ -194,9 +198,7 @@ async function main() {
return feature; return feature;
}); });
disposePopover(); disposePopover();
if (!feature) { if (!feature) return;
return;
}
popup.setPosition(evt.coordinate); popup.setPosition(evt.coordinate);
popover = new bootstrap.Popover(popupEl, { popover = new bootstrap.Popover(popupEl, {
placement: 'top', placement: 'top',
@@ -216,52 +218,69 @@ async function main() {
// Close the popup when the map is moved // Close the popup when the map is moved
map.on('movestart', disposePopover); map.on('movestart', disposePopover);
// //
// Tracking // Tracking
// //
const updateInterval = 5000; const updateInterval = 10000;
// let followedFeature = vanFeature; const peopleOverlays = {};
// let followedZoomed = false;
// let followedFeature = null;
function startFollowing(feature, followLink) { function createParticipantHTML (name) {
followedFeature = feature; if (document.getElementById(`user-${name}`)) return;
followLink.textContent = 'Stop following'; const el = document.createElement('img');
// followLink.removeEventListener('click', startFollowing); el.src = `https://r2b22.kip.pe/avatars/${name}.png`;
followLink.addEventListener('click', stopFollowing(feature, followLink)); el.id = `user-${name}`;
el.style = 'width: 40px; height: 40px; border-radius: 20px; cursor: pointer';
document.getElementById('people').append(el);
} }
function stopFollowing(feature, followLink) { function createParticipantOverlay (name) {
followedFeature = null; if (peopleOverlays[name]) return;
followedZoomed = false; const overlayElement = new Overlay({
followLink.textContent = 'Stop following'; stopEvent: false,
// followLink.removeEventListener('click', stopFollowing); positioning: 'center-center',
followLink.addEventListener('click', startFollowing(feature, followLink)); element: document.getElementById(`user-${name}`)
});
peopleOverlays[name] = overlayElement;
map.addOverlay(overlayElement);
}
function isRecentTimestamp (tst) {
// newer than 2 hours ago?
return (tst * 1000) > (Date.now() - 2*60*60*1000);
} }
function updateData(startInterval=false) { function updateData(startInterval=false) {
fetch('https://r2b22.kip.pe/last.json') fetch('https://r2b22.kip.pe/last.json')
.then(response => response.json()) .then(response => response.json())
.then(data => { .then(data => {
console.log(data); const vanData = data.find(i => i.name == 'satoshithevan');
const coords = [data.lon, data.lat]; const vanCoords = [vanData.lon, vanData.lat];
vanFeature.getGeometry().setCoordinates(coords); vanFeature.getGeometry().setCoordinates(vanCoords);
// let zoomLevel; for (const item of data) {
// if (!followedZoomed) { if (!tourStatus.participants.includes(item.name)) continue;
// zoomLevel = 13; if (!isRecentTimestamp(item.tst)) continue;
// followedZoomed = true; createParticipantHTML(item.name);
// } createParticipantOverlay(item.name);
const overlay = peopleOverlays[item.name];
overlay.setPosition([item.lon, item.lat]);
// if (followedFeature) { function clickHandler () {
// view.animate({ disposePopover();
// center: followedFeature.getGeometry().getCoordinates(), popup.setPosition([item.lon, item.lat]);
// duration: 500, popover = new bootstrap.Popover(popupEl, {
// zoom: zoomLevel placement: 'top',
// }); html: true,
// } content: `Rider: ${item.name}`
});
popover.show();
}
const avatarEl = document.getElementById(`user-${item.name}`);
avatarEl.removeEventListener('click', clickHandler);
avatarEl.addEventListener('click', clickHandler);
}
}); });
if (startInterval) { if (startInterval) {

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "ol-vite", "name": "ol-vite",
"version": "1.4.0", "version": "1.9.0",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "ol-vite", "name": "ol-vite",
"version": "1.4.0", "version": "1.9.0",
"dependencies": { "dependencies": {
"ol": "latest" "ol": "latest"
}, },

View File

@@ -1,6 +1,6 @@
{ {
"name": "map", "name": "map",
"version": "1.4.0", "version": "1.9.0",
"scripts": { "scripts": {
"start": "vite", "start": "vite",
"build": "vite build", "build": "vite build",

View File

@@ -4,6 +4,7 @@ html, body {
margin: 0; margin: 0;
height: 100%; height: 100%;
} }
#map { #map {
position: absolute; position: absolute;
top: 0; top: 0;