8 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
14 changed files with 182639 additions and 65 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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 260 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

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.892cac62.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>

116
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,53 +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 van_data = data.find(i => i.name == 'satoshithevan'); const vanCoords = [vanData.lon, vanData.lat];
const van_coords = [van_data.lon, van_data.lat]; vanFeature.getGeometry().setCoordinates(vanCoords);
vanFeature.getGeometry().setCoordinates(van_coords);
// 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.5.0", "version": "1.9.0",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "ol-vite", "name": "ol-vite",
"version": "1.5.0", "version": "1.9.0",
"dependencies": { "dependencies": {
"ol": "latest" "ol": "latest"
}, },

View File

@@ -1,6 +1,6 @@
{ {
"name": "map", "name": "map",
"version": "1.5.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;