Skip to content

Commit dde3b2e

Browse files
authored
Visualisation de tous les véhicules présents dans tous les GTFS-RT référencés (#2224)
* Add new route * Save useful exploratory code from past days * Add view * Add basic controller * Inject top scripts for demo * Add main body * Add demo bottom * Add channel socket * Register asset * Add boilerplate for poller * Supervise poller * Reference javascript * Add ticker * Fix warning * Start ticking * Lower the frequency * Trigger immediate refresh at start (less wait for me) * Pick one resource, fetch it regularly, prepare some JSON out of it * Avoid one SQL log per refresh (for clarity of debugging on my side) * Remove inspect * Declare channel * Implement required channel serverside-part * Connect from client * Broadcast positions (a single topic for now for simplicity) * Rename event * Replace deckgl demo by our usual maps constructs * Ignore yarn error log from git * Add minimal (no react) deck.gl install as package https://github.com/visgl/deck.gl/tree/master/examples/get-started/pure-js/leaflet helped massively * Remove apparently unused import * Bring back adapted sample to gradually specify imports in a way that works * Extract bounds * Add actual data as hard-coded, to help me configure the layer * Use larger resource * Disable for now * Update vehicles.livemd * Use real data * Save resource_id for layer identification * Propagate data with resource_id (including empty for now, on error) * Properly track each resource via its id in a dictionary * Improve default position * Tweak size * Mix format * Mix format * Mix format * Mix format * Mix format * Mix format * Load everything we have and show it * Add tooltip with resource id and (per-resource) vehicle id * Add resource_id to logs * trigger deploy * Trigger deploy * Fix some credo warnings * Move processing to the worker * Try to fix launch condition * Bring back processing to front See https://twitter.com/thibaut_barrere/status/1506205865501773824 * Extract method * Track anonymous users via "Presence" * Activate polling only when at least 1 user is on the page * Replace todo (credo) * Remove credo warning * Fix credo warning * Extract key * Reuse key * Reuse key * Extract configuration for clarity * Clarify comment The mailbox cannot currently overload (I did some testing then read my code :P). * Propagate the fact that an error occurred to the client * Add log * Format code * Show header & title * Add explanation * Make linter happy * Trigger deploy * Add explanation * Fix doc * Remove useless tweaks * Add quick controller test * Move @moduledoc at the top * Move @moduledoc at the top * Fix typo * Dev - only run if webserver is activated * Fix typos * Simplify launch clause * Go back to fitBounds * Adjust height
1 parent 9508c9a commit dde3b2e

File tree

21 files changed

+672
-1
lines changed

21 files changed

+672
-1
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,4 @@ config/proxy-config.yml
4545
config/dev.secret.exs
4646
scripts/siri/config.yml
4747
transport-tools
48+
apps/transport/client/yarn-error.log
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import { Socket } from 'phoenix'
2+
import Leaflet from 'leaflet'
3+
import { LeafletLayer } from 'deck.gl-leaflet'
4+
import { ScatterplotLayer } from '@deck.gl/layers'
5+
import { MapView } from '@deck.gl/core'
6+
7+
const socket = new Socket('/socket', { params: { token: window.userToken } })
8+
socket.connect()
9+
const channel = socket.channel('explore', {})
10+
channel.join()
11+
.receive('ok', resp => { console.log('Joined successfully', resp) })
12+
.receive('error', resp => { console.log('Unable to join', resp) })
13+
14+
const Mapbox = {
15+
url: 'https://api.mapbox.com/styles/v1/istopopoki/ckg98kpoc010h19qusi9kxcct/tiles/256/{z}/{x}/{y}?access_token={accessToken}',
16+
accessToken: 'pk.eyJ1IjoiaXN0b3BvcG9raSIsImEiOiJjaW12eWw2ZHMwMGFxdzVtMWZ5NHcwOHJ4In0.VvZvyvK0UaxbFiAtak7aVw',
17+
attribution: 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors <a href="https://spdx.org/licenses/ODbL-1.0.html">ODbL</a>, Imagery © <a href="http://mapbox.com">Mapbox</a>',
18+
maxZoom: 20
19+
}
20+
21+
const metropolitanFranceBounds = [[51.1, -4.9], [41.2, 9.8]]
22+
const map = Leaflet.map('map', { renderer: Leaflet.canvas() }).fitBounds(metropolitanFranceBounds)
23+
24+
Leaflet.tileLayer(Mapbox.url, {
25+
accessToken: Mapbox.accessToken,
26+
attribution: Mapbox.attribution,
27+
maxZoom: Mapbox.maxZoom
28+
}).addTo(map)
29+
30+
function prepareLayer (layerId, layerData) {
31+
return new ScatterplotLayer({
32+
id: layerId,
33+
data: layerData,
34+
pickable: true,
35+
opacity: 1,
36+
stroked: true,
37+
filled: true,
38+
radiusScale: 3,
39+
radiusMinPixels: 1,
40+
radiusMaxPixels: 3,
41+
lineWidthMinPixels: 1,
42+
getPosition: d => {
43+
return [d.position.longitude, d.position.latitude]
44+
},
45+
getRadius: d => 100000,
46+
getFillColor: d => [127, 150, 255],
47+
getLineColor: d => [100, 100, 200]
48+
})
49+
}
50+
51+
const deckLayer = new LeafletLayer({
52+
views: [
53+
new MapView({
54+
repeat: true
55+
})
56+
],
57+
layers: [],
58+
getTooltip: ({ object }) => object && { html: `transport_resource: ${object.transport.resource_id}<br>id: ${object.vehicle.id}` }
59+
})
60+
map.addLayer(deckLayer)
61+
62+
// internal dictionary
63+
const layers = {}
64+
65+
channel.on('vehicle-positions', payload => {
66+
if (payload.error) {
67+
console.log(`Resource ${payload.resource_id} failed to load`)
68+
} else {
69+
layers[payload.resource_id] = prepareLayer(payload.resource_id, payload.vehicle_positions)
70+
deckLayer.setProps({ layers: Object.values(layers) })
71+
}
72+
})
73+
74+
export default socket

apps/transport/client/package.json

+3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
"core-js": "3",
1919
"leaflet": "^1.4.0",
2020
"leaflet.pattern": "^0.1.0",
21+
"@deck.gl/core": "^8.7.0",
22+
"@deck.gl/layers": "^8.7.0",
23+
"deck.gl-leaflet": "^1.2.1",
2124
"papaparse": "^5.1.1",
2225
"phoenix": "file:../../../deps/phoenix",
2326
"phoenix_html": "file:../../../deps/phoenix_html",

apps/transport/client/stylesheets/main.scss

+6
Original file line numberDiff line numberDiff line change
@@ -195,3 +195,9 @@ nav.navigation input {
195195
.no-margin {
196196
margin: 0;
197197
}
198+
199+
.explore_map {
200+
width: 100vw;
201+
height: 80vh;
202+
border-top: 1px solid #ccc;
203+
}

apps/transport/client/webpack.common.js

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ module.exports = {
1212
clipboard: './javascripts/clipboard.js',
1313
map: './javascripts/map.js',
1414
resourceviz: './javascripts/resource-viz.js',
15+
explore: './javascripts/explore.js',
1516
mapgeojson: './javascripts/map-geojson.js',
1617
datasetmap: './javascripts/dataset-map.js',
1718
validationmap: './javascripts/validation-map.js',

0 commit comments

Comments
 (0)