Creating a web interface - Mapbox
In this tutorial, we will look at how to connect the open-sourced react-map-gl port of Mapbox project to the Tracking History API in a browser.
caution
#
Source codeYou can find and download the source code for this example here.
#
Setting up ReactFor the sake of simplicity, we are gonna use the create-react-app utility.
Simply start by the following commands:
We use the --template redux
flag to set up a Redux store in our app, since KeplerGL depends on Redux to work properly.
You should now have a React application running at http://localhost:3000.
#
Setting up MapboxIn order to get Mapbox to work, you will first need to get a Mapbox token. To get one, you will need to create an account here. We can now add react-map-gl to our application:
In our main App.js
file, we can then import at the top
We can now use the MapGL
component. Let start with cleaning up the previous default code.
We now have a Mapbox map instance visible in our app homepage.
#
Calling the Tracking History endpoint#
Fetching the dataWe can now call Spire Aviation Tracking History endpoint and get data from an aircraft.
Let's start by creating a function that does that. We will need to import the redux hook useDispatch
, which we will use to dispatch our success action to our aircraftReducer
.
We can now use a useEffect
hook, calling the API once on component mount:
info
If you feel like going the extra mile, you should directly create a form to select the ICAO address and dates you are interested in with a submission button that triggers the call to the API.
Here, we will call the API, filtering data for the ICAO address 398568
, for a one day period.
#
Parsing the dataThe response of our query to the Tracking History needs to be parsed. It is a set of JSON objects, each separated by a new line.
To parse that, we will use the split
function and then loop through each line, parsing the JSON inside it:
#
Storing the data in ReduxWe can now create our Redux store where we will store the parsed results. Let's start by creating a new folder named src/reducers
, with a aircraftReducer.js
file in it.
We can also update our store.js
file to take this new reducer into account:
#
Plotting the dataIn order to plot the data, we first need to select it from the redux store.
Let's add a useSelector
hook in order to select our data.
Now, let's create a new state variable, called plot
, that we will use for storing the aircraft plotted data.
We will also need to create a useEffect
hook, that will listen to changes on our data
state value, and generate/set the associated plot.
Finally, we need to add the Mapbox <Layer>
that will display the GeoJSON plot:
We also need to add the <Layer>
settings:
We now have a plot visible on our map!
One final thing we can add is the centering of the map where the aircraft plot is upon loading. We will simply update the viewport
of our map after receiving the new data.
#
Clickable pointsNow, let's see how we can do to have our points clickable, so we can get details upon a specific point when clicking it.
We will add 3 props to our <MapGL>
component:
Let's break down those newly added props:
- We added
interactiveLayerIds
, which describes which layers will have interactivity, and thus click events. If you remember, we added apointLayer
earlier in our code, containing the propertyid
. Thisid
is what is used to identify theinteractiveLayerIds
. - We also added the
clickRadius
to set how close the mouse needs to be from a point for the click event to be dispatched. - We also added our
onClick
handler, which receives a function as a parameter. The function has one parameter, which is a click event. In that even we can look forfeatures
, from which we will pick the first one. Thanks to oursetPlot
effect, we have theproperties
set in thatfeature
.
By adding a new state variable clickedPoint
, we can have the clicked point updated and displayed in our interface.
#
Animate the dataLet's now look at how we could animate our aircraft over its course. For that, we will need to add:
- A toggle button to have the static path or the animation mode
- The new
<Marker>
component used for our animation, containing the svg of our aircraft. - Two new state variables,
mode
andanimationIndex
.mode
will be used to toggle between modes, andanimationIndex
will contain the current index in the data array from which we create our animation.
Now, we need to create the actual animation, so we will loop through our data by increasing a data index in an interval callback. For that, we will create a new custom hook named useInterval
, in /src/hooks/useInterval.jsx
.
We can now use our useInterval
hook to animate our aircraft!
If we switch over to the Animation mode, the aircraft position will change every 10ms on our map.
#
Final resultNext steps
We could improve that example by plotting the aircraft route in the same layer as our animation. We could also improve the design of the page, adding loading etc ...