9 Commits

Author SHA1 Message Date
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
Râu Cao 0d66bc1266 1.4.0 2022-09-11 12:31:26 +02:00
Râu Cao ba3982d9a6 Add plausible analytics script 2022-09-11 12:30:52 +02:00
Râu Cao f2cc9a9783 1.3.0 2022-09-09 20:29:41 +02:00
Râu Cao 0c1aeebdf7 Load current tour status from server 2022-09-09 20:29:18 +02:00
Râu Cao 3324a57206 Update route 2022-09-09 20:29:00 +02:00
15 changed files with 229152 additions and 52845 deletions
-11
View File
File diff suppressed because one or more lines are too long
+11
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 260 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

+2 -1
View File
@@ -6,7 +6,8 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<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 type="module" crossorigin src="/assets/index.03aa5401.js"></script> <script defer data-domain="r2b22.kip.pe" src="https://plausible.io/js/plausible.js"></script>
<script type="module" crossorigin src="/assets/index.24fe7964.js"></script>
<link rel="stylesheet" href="/assets/index.eed9f443.css"> <link rel="stylesheet" href="/assets/index.eed9f443.css">
</head> </head>
<body> <body>
+182553
View File
File diff suppressed because it is too large Load Diff
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -6,6 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<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>
</head> </head>
<body> <body>
<div id="map"><div id="popup"></div></div> <div id="map"><div id="popup"></div></div>
+103 -82
View File
@@ -7,13 +7,15 @@ 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 './geo/r2b22-route.json'
import geojsonPOI from './geo/poi.json' import geojsonPOI from './geo/r2b22-poi.json';
import geojsonLegacy from './geo/legacy-route.json';
useGeographic(); useGeographic();
const styles = { async function main() {
const styles = {
lineOrange: new Style({ lineOrange: new Style({
stroke: new Stroke({ stroke: new Stroke({
color: '#FF9900', color: '#FF9900',
@@ -54,75 +56,89 @@ const styles = {
}), }),
}) })
}) })
} }
// //
// Route // Route
// //
const lastStageFinished = 2; const tourStatus = await fetch('https://r2b22.kip.pe/status.json').then(res => res.json());
const stagesCompleted = geojsonRoute.features.slice(0, lastStageFinished);
const stagesAhead = geojsonRoute.features.slice(lastStageFinished);
const vectorSourceStagesCompleted = new VectorSource();
const vectorSourceStagesAhead = new VectorSource();
for (const stage of stagesCompleted) { const lastStageFinished = tourStatus.lastStageFinished;
const stagesCompleted = geojsonRoute.features.slice(0, lastStageFinished);
const stagesAhead = geojsonRoute.features.slice(lastStageFinished);
const vectorSourceStagesCompleted = new VectorSource();
const vectorSourceStagesAhead = new VectorSource();
for (const stage of stagesCompleted) {
vectorSourceStagesCompleted.addFeature(new GeoJSON().readFeature(stage)); vectorSourceStagesCompleted.addFeature(new GeoJSON().readFeature(stage));
} }
for (const stage of stagesAhead) { for (const stage of stagesAhead) {
vectorSourceStagesAhead.addFeature(new GeoJSON().readFeature(stage)); vectorSourceStagesAhead.addFeature(new GeoJSON().readFeature(stage));
} }
const stagesCompletedLayer = new VectorLayer({ const stagesCompletedLayer = new VectorLayer({
source: vectorSourceStagesCompleted, source: vectorSourceStagesCompleted,
style: styles.lineOrange style: styles.lineOrange
}); });
const stagesAheadLayer = new VectorLayer({ const stagesAheadLayer = new VectorLayer({
source: vectorSourceStagesAhead, source: vectorSourceStagesAhead,
style: styles.lineGrey style: styles.lineGrey
}); });
// //
// Points of Interest // Points of Interest
// //
const vectorSourcePOI = new VectorSource({ const vectorSourcePOI = new VectorSource({
features: new GeoJSON().readFeatures(geojsonPOI), features: new GeoJSON().readFeatures(geojsonPOI),
}); });
const poiLayer = new VectorLayer({ const poiLayer = new VectorLayer({
source: vectorSourcePOI, source: vectorSourcePOI,
style: styles.circleBlack, style: styles.circleBlack,
}); });
const vectorSourceTrackedPoints = new VectorSource(); const vectorSourceTrackedPoints = new VectorSource();
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 trackable: true
}); });
vectorSourceTrackedPoints.addFeature(vanFeature); vectorSourceTrackedPoints.addFeature(vanFeature);
const trackedPointsLayer = new VectorLayer({ const trackedPointsLayer = new VectorLayer({
source: vectorSourceTrackedPoints, source: vectorSourceTrackedPoints,
style: styles.iconVan style: styles.iconVan
}); });
// //
// Map initialization // Legacy routes
// //
const view = new View({ const vectorSourceLegacy = new VectorSource();
vectorSourceLegacy.addFeatures(new GeoJSON().readFeatures(geojsonLegacy));
const legacyLayer = new VectorLayer({
source: vectorSourceLegacy,
style: styles.lineOrange
});
//
// Map initialization
//
const view = new View({
center: [10.6, 46.9], center: [10.6, 46.9],
zoom: 6.6 zoom: 6.6
}) })
window.view = view; window.view = view;
const map = new Map({ const map = new Map({
target: 'map', target: 'map',
layers: [ layers: [
new TileLayer({ new TileLayer({
@@ -130,45 +146,46 @@ const map = new Map({
}), }),
stagesCompletedLayer, stagesCompletedLayer,
stagesAheadLayer, stagesAheadLayer,
legacyLayer,
poiLayer, poiLayer,
trackedPointsLayer trackedPointsLayer
], ],
view: view view: view
}); });
// //
// Center map on current/next stage // Center map on current/next stage
// //
setTimeout(() => { setTimeout(() => {
const nextStageFeature = new GeoJSON().readFeature(stagesAhead[0]); const nextStageFeature = new GeoJSON().readFeature(stagesAhead[0]);
view.fit(nextStageFeature.getGeometry(), { view.fit(nextStageFeature.getGeometry(), {
maxZoom: 10, maxZoom: 10,
duration: 1000 duration: 1000
}); });
}, 3000); }, 3000);
// //
// Popups // Popups
// //
const popupEl = document.getElementById('popup'); const popupEl = document.getElementById('popup');
const popup = new Overlay({ const popup = new Overlay({
element: popupEl, element: popupEl,
positioning: 'bottom-center', positioning: 'bottom-center',
stopEvent: false, stopEvent: false,
}); });
map.addOverlay(popup); map.addOverlay(popup);
let popover; let popover;
function disposePopover() { function disposePopover() {
if (popover) { if (popover) {
popover.dispose(); popover.dispose();
popover = undefined; popover = undefined;
} }
} }
function createPopoverHtml(feature) { function createPopoverHtml(feature) {
const container = document.createElement('div'); const container = document.createElement('div');
const title = document.createElement('div'); const title = document.createElement('div');
title.textContent = feature.get('name'); title.textContent = feature.get('name');
@@ -183,10 +200,10 @@ function createPopoverHtml(feature) {
// linkParent.append(followLink); // linkParent.append(followLink);
// container.append(linkParent); // container.append(linkParent);
// } // }
} }
// display popup on click // display popup on click
map.on('click', function (evt) { map.on('click', function (evt) {
const feature = map.forEachFeatureAtPixel(evt.pixel, function (feature) { const feature = map.forEachFeatureAtPixel(evt.pixel, function (feature) {
return feature; return feature;
}); });
@@ -201,50 +218,51 @@ map.on('click', function (evt) {
content: createPopoverHtml(feature) content: createPopoverHtml(feature)
}); });
popover.show(); popover.show();
}); });
// change mouse cursor when over marker // change mouse cursor when over marker
map.on('pointermove', function (evt) { map.on('pointermove', function (evt) {
map.getTargetElement().style.cursor = map.hasFeatureAtPixel(evt.pixel) map.getTargetElement().style.cursor = map.hasFeatureAtPixel(evt.pixel)
? 'pointer' ? 'pointer'
: ''; : '';
}); });
// 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 = 5000;
let followedFeature = vanFeature; // let followedFeature = vanFeature;
let followedZoomed = false; // let followedZoomed = false;
// let followedFeature = null; // let followedFeature = null;
function startFollowing(feature, followLink) { function startFollowing(feature, followLink) {
followedFeature = feature; followedFeature = feature;
followLink.textContent = 'Stop following'; followLink.textContent = 'Stop following';
// followLink.removeEventListener('click', startFollowing); // followLink.removeEventListener('click', startFollowing);
followLink.addEventListener('click', stopFollowing(feature, followLink)); followLink.addEventListener('click', stopFollowing(feature, followLink));
} }
function stopFollowing(feature, followLink) { function stopFollowing(feature, followLink) {
followedFeature = null; followedFeature = null;
followedZoomed = false; followedZoomed = false;
followLink.textContent = 'Stop following'; followLink.textContent = 'Stop following';
// followLink.removeEventListener('click', stopFollowing); // followLink.removeEventListener('click', stopFollowing);
followLink.addEventListener('click', startFollowing(feature, followLink)); followLink.addEventListener('click', startFollowing(feature, followLink));
} }
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); console.log(data);
const coords = [data.lon, data.lat]; const van_data = data.find(i => i.name == 'satoshithevan');
vanFeature.getGeometry().setCoordinates(coords); const van_coords = [van_data.lon, van_data.lat];
vanFeature.getGeometry().setCoordinates(van_coords);
// let zoomLevel; // let zoomLevel;
// if (!followedZoomed) { // if (!followedZoomed) {
@@ -264,6 +282,9 @@ function updateData(startInterval=false) {
if (startInterval) { if (startInterval) {
setInterval(updateData, updateInterval); setInterval(updateData, updateInterval);
} }
}
updateData(true);
} }
updateData(true); main();
+2 -2
View File
@@ -1,12 +1,12 @@
{ {
"name": "ol-vite", "name": "ol-vite",
"version": "1.2.1", "version": "1.6.0",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "ol-vite", "name": "ol-vite",
"version": "1.2.1", "version": "1.6.0",
"dependencies": { "dependencies": {
"ol": "latest" "ol": "latest"
}, },
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "map", "name": "map",
"version": "1.2.1", "version": "1.6.0",
"scripts": { "scripts": {
"start": "vite", "start": "vite",
"build": "vite build", "build": "vite build",
Binary file not shown.

After

Width:  |  Height:  |  Size: 260 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB