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
.geojsonfile 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_rightandonewayproperties are mapped to RGB channels of the geometry - That geometry use a custom shader
stylethat draws arrows in the right direction, and mapped thespeedto 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 debounced 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)));