Languages: English • 简体中文 • 繁體中文
SensorThings API - Visualizing More Locations
In Part 2 of this series, we:
- Retrieved the most recent bike availability
Observation
for eachLocation
- Displayed each
Location
on a map, with its color set by the number of available bikes
Locations
. In this part, we are
going to show you how to retrieve and show all of the Locations
in the SensorThings server.
It's Getting Crowded
Let's take another look at the Locations
we received from SensorThings.
If you look at the top of the response, you'll see that there is an
@iot.count
property indicating the total number of
Locations
that match the query. There is also an
@iot.nextLink
property telling you how to retrieve the
next page of results.
If we retrieve all the results, this is what the map looks like.
It's a bit congested, no? In any case, let's take a look at what
we've done to retrieve all the Locations
.
/Locations
with a
followNextLink
function.
followNextLink(
axios.get('https://toronto-bike-snapshot.sensorup.com/v1.0/Locations', {
params: {
'$expand': "Things/Datastreams($filter=ObservedProperty/name eq 'available_bikes'),Things/Datastreams/Observations($orderby=phenomenonTime desc;$top=1)"
}
})
)
The followNextLink
function implementation, which should be added
to the script, follows all @iot.nextLink
links, and concatenates
all the value
s so that the complete results are returned
in one array. If you're curious about the nuts-and-bolts of this function, you'll need an
understanding of recursion
and JavaScript Promises.
It's interesting, but a bit outside the scope of this tutorial.
function followNextLink(responsePromise) {
return responsePromise.then(function(lastSuccess) {
if(lastSuccess.data['@iot.nextLink']) {
return followNextLink(axios.get(lastSuccess.data['@iot.nextLink'])).then(function(nextLinkSuccess) {
nextLinkSuccess.data.value = lastSuccess.data.value.concat(nextLinkSuccess.data.value);
return nextLinkSuccess;
});
}
else {
return lastSuccess;
}
});
}
Clustering
It definitely reduces our clutter, but now we can't see which stations are running out of available bikes! Of course, this information is still available if we zoom in, but it's useful to be able to see our data at a glance, even when viewing our map from "high in the air."
Sometimes it's the Simple Solutions
radius
and weight
(stroke width) of our
circle markers, we can shrink the markers to better suit our data.
return L.circleMarker(latlng, {
color: availableBikes > 5 ? enoughBikeColor : fewBikesColor,
radius: 5,
weight: 2
});
What's Next
So far, we've been showing the latest bike availability data from the server. However, it's often useful to be able to show historical data. Were there bikes available an hour ago? Are there usually bikes available on Fridays at 9pm? What is the average number of bikes available in winter vs summer? With the right data, SensorThings can help you answer all of those questions, but let's start with the basics. In the next tutorial, we're going to show you how to query for bike availability data before a specific date/time.
So, let's go time traveling.