This map can be used in two ways: against a live API or against a local cached copy of a GeoJSON extract.
To use against a live OTv2 API, you will need to specify two query parameters:
server
- hostname for the APIsecret_key
- to authenticate against the API
For example: http://opentraffic.io/tangram-viz-experiments/?server=host.opentraffic.io&secret=password
To use against a local cached copy of a GeoJSON extract:
- Construct a query to the OTv2 API using the available query parameters.
- Save the response as a
.geojson
file to a local copy of this repository. - Update the data source within the Tangram scene file to reference that file: scene.yaml#L9-L12
- Update the initial map start position: index.html#L190
The pipeline for this is:
- Interaction on the map
- Get map BoundingBox
- Do HTTP request to OpenTraffic server
- Load the GeoJSON Reply as a Tangram data
source
- In Tangram scene YAML file, filter the data into a layer where the
speed
,drive_on_right
andoneway
properties are mapped to RGB channels of the geometry - That geometry use a custom shader
style
that draws arrows in the right direction, and mapped thespeed
to a palette defined by a .png file (that can be generated by Spectrum App or any other software.)
When the map changes position...
map.on('moveend', debounce(function() {
// Update the displayed information
update();
}, 1000));
Note: the call is debounce
d to avoid unnecessary multiple calls
Get the bounding box and present time to construct a HTTP call to OpenTraffic.
NOTE: the call have to be change to ask for a year
of data instead of an hour
. Also the query should be made for only one day of the week (using dow
) to reduce stream of data. (Check all this with Kevin)
function update() {
// Get the current boundaries of the displayed area on the map
var bbox = map.getBounds();
var day = moment().format('YYYY-MM-DD')
var hour = moment().format('HH:MM:SS')
// Make the URL for OpenWeatherMaps API, asking for all stations inside that area (bounding box)
var url = 'https://localhost:3000/query?';
url += '&start_date_time=' + day + 'T'+ moment().subtract(1,'hour').format('HH:MM:SS');
url += '&end_date_time=' + day + 'T' + moment().format('HH:MM:SS');
url += '&boundingbox=' + bbox.getSouthWest().lng + ',' +bbox.getSouthWest().lat + ',' + bbox.getNorthEast().lng + ',' + bbox.getNorthEast().lat;
console.log('Fake call to:', url);
// Make the request and wait for the reply
fetch(url)
.then(function (response) {
// If we get a positive response...
if (response.status !== 200) {
console.log('Error getting data: ' + response.status);
return;
}
// ... parse it to JSON
return response.json();
})
.then(function(json) {
var data = { " opentraffic": json };
// Pass the POIs as a GeoJSON FeaturesCollection to tangram
scene.setDataSource('opentraffic', {type: 'GeoJSON', data: json});
})
.catch(function(error) {
console.log('Error parsing the GeoJSON.', error)
})
}
Warning: the data on the valhalla tile that Kevin send me have a single float for speed. THIS WILL CHANGE there going to be multiple speed according to
layers:
opentraffic:
data: { source: opentraffic }
draw:
ot-roads:
order: 10001
width: [[10,2px],[15,5px],[20,5m]]
color: |
function () {
return [ feature.speed/255, feature.drive_on_right, feature.oneway ];
}
Use the color to draw an chevron arrow pattern in the right direction, and for the speed color use a regular .png
(that can be generated by Spectrum App or any other software.)
textures:
palette:
url: assets/palette-01.png
styles:
ot-roads:
base: lines
mix: [functions-zoom, functions-aastep, generative-random]
texcoords: true
animated: true
lighting: false
blend: inlay
shaders:
defines:
ZOOM_START: 15.
ZOOM_END: 20.
ZOOM_IN: .0
ZOOM_OUT: .5
uniforms:
u_palette: palette
blocks:
width: |
// One or two lanes
width = mix(width*v_texcoord.x, width, a_color.b);
color: |
// Speed to color from palette LUT
color = texture2D(u_palette, vec2(smoothstep(0.,.3,v_color.r),.5));
// Draw arrows
vec2 st = v_texcoord.xy+vec2(.5,0.);
// Flip direction if the the drive is not on the right.
st.y = mix(1.-fract(st.y),st.y,v_color.g);
// Adjust the speed to the speed
st.y -= u_time*10.*v_color.r;
// Make chrevone arrow
color.a *= aastep(zoom(),fract(st.y+abs(st.x*.5-.5)));