<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Geospatial Data on thomaspaulin.me</title><link>https://thomaspaulin.me/tags/geospatial-data/</link><description>Geospatial Data</description><generator>Hugo -- gohugo.io</generator><language>en-nz</language><lastBuildDate>Sat, 20 Mar 2021 00:00:00 +0000</lastBuildDate><atom:link href="https://thomaspaulin.me/tags/geospatial-data/index.xml" rel="self" type="application/rss+xml"/><item><title>It's A Bird! It's A Plane! Displaying Live Flight Information Using deck.gl</title><link>https://thomaspaulin.me/2021/03/deckgl-displaying-live-flight-info/</link><pubDate>Sat, 20 Mar 2021 00:00:00 +0000</pubDate><guid>https://thomaspaulin.me/2021/03/deckgl-displaying-live-flight-info/</guid><description>&lt;p>As part of another project I wished to render data points on a map in real-time, or as near to real-time as possible. Being new to &lt;a href="http://deck.gl">deck.gl&lt;/a> this seemed an opportune time to reduce the scope and focusing on rendering.&lt;/p>
&lt;p>For this project, I&amp;rsquo;ve chosen flight data because I&amp;rsquo;m a fan of anything aerospace. The OpenSky Network API provides &lt;a href="https://opensky-network.org/apidoc/">a free API for live flight information&lt;/a> (for research and non-commercial purposes). I wanted to use Earth observation data for this project, but that data is not real-time thanks to orbital periods.&lt;/p>
&lt;p>Information about the data provided by The OpenSky Network API can be found on their documentation. We will receive descriptive and positional information derived from &lt;a href="https://www.faa.gov/nextgen/programs/adsb/">ADS-B&lt;/a> and &lt;a href="https://trig-avionics.com/knowledge-bank/transponders/mode-s/">Mode-S transponder&lt;/a> messages. Using this information we can render the flight on a map.&lt;/p>
&lt;h1 id="the-cast">The Cast&lt;/h1>
&lt;ul>
&lt;li>&lt;a href="http://deck.gl">deck.gl&lt;/a> - used to render data on the map&lt;/li>
&lt;li>&lt;a href="https://www.mapbox.com/mapbox-gljs">Mapbox GL JS&lt;/a> - used to render the map itself. Provided by the deck.gl examples&lt;/li>
&lt;li>&lt;a href="https://opensky-network.org/">The OpenSky Network API&lt;/a> - provides the flight information&lt;/li>
&lt;li>&lt;a href="https://webpack.js.org/">Webpack&lt;/a> - to bundles everything nicely and provides a better developer experience&lt;/li>
&lt;li>npm - for package management&lt;/li>
&lt;li>&lt;a href="https://github.com/webpack/webpack-dev-server">webpack-dev-server package&lt;/a> - to run a local server and verify the results by eye. Provided by the deck.gl examples&lt;/li>
&lt;li>Javascript - for writing the code. Typescript takes extra setup which is unnecessary for our purposes&lt;/li>
&lt;/ul>
&lt;p>In the beginning, there was nothing, no code, no frameworks, just a blank directory staring back at us. To fix this we clone the &lt;a href="https://github.com/visgl/deck.gl/">deck.gl repository&lt;/a>. We will be working from the Mapbox directory (&lt;code>/examples/get-started/pure-js/mapbox/&lt;/code>).&lt;/p>
&lt;p>Next, it&amp;rsquo;s time to fetch our dependencies using &lt;code>npm install&lt;/code>.&lt;/p>
&lt;p>Once complete you should be able to run &lt;code>npm start&lt;/code> and see this:&lt;/p>
&lt;figure>&lt;img src="img/posts/2021/deckgl-mapbox-example-running.png"
alt="The deck.gl Mapbox example up and running">&lt;figcaption>
&lt;p>The Mapbox getting started example&lt;/p>
&lt;/figcaption>
&lt;/figure>
&lt;p>Your &lt;code>app.js&lt;/code> file should look something like this:&lt;/p>
&lt;script src="https://gist.github.com/thomaspaulin/39a188355403bdd9d38d66fdf2061b9f.js">&lt;/script>
&lt;p>&lt;a href="https://deck.gl/docs/developer-guide/performance">According to the deck.gl documentation&lt;/a> &amp;ldquo;Layer updates happen when the layer is first created, or when some layer props change.&amp;rdquo; Thus, we must have our live data cause a prop change when it is received. The obvious first step here is a callback that creates the layers arrays using the new data. It then sets the props of the Deck using those layers. Be wary of the &lt;a href="https://deck.gl/docs/developer-guide/performance">performance implications&lt;/a> that changing data can bring. We won&amp;rsquo;t be addressing those in this article.&lt;/p>
&lt;script src="https://gist.github.com/thomaspaulin/3d6961d8090d592eb28d20fae7cbb63d.js">&lt;/script>
&lt;p>Now we have a way to set the props from a callback we can fetch flight information from the OpenSky Network API. As a demonstration project, we only care about the latest information for all flights. Thus, we will get network&amp;rsquo;s entire state vector set, without authenticating. This means our request is: &lt;code>GET https://opensky-network.org/api/states/all&lt;/code>.&lt;/p>
&lt;p>The response we receive is not in the format &lt;a href="http://deck.gl">deck.gl&lt;/a> expects, and so we&amp;rsquo;ll need to transform it. Fortunately, the OpenSky Network API response is easy to handle meaning a simple mapping function is sufficient.&lt;/p>
&lt;script src="https://gist.github.com/thomaspaulin/d7f5ad040deca4a4d034a59ad21f12c9.js">&lt;/script>
&lt;p>Once we&amp;rsquo;ve added this mapping into the response chain we also call the same &lt;code>render(...)&lt;/code> function we created earlier. After running, we should see the flights rendered on the map.&lt;/p>
&lt;figure>&lt;img src="img/posts/2021/deckgl-opensky-flight-info-plotted.png"
alt="Flights plotted on the map using information from the OpenSky Network API">&lt;figcaption>
&lt;p>Flight information from the OpenSky Network API rendered&lt;/p>
&lt;/figcaption>
&lt;/figure>
&lt;h1 id="notes">Notes&lt;/h1>
&lt;ul>
&lt;li>The &lt;code>webpack.config.js&lt;/code> file says the local development overrides should be removed from the file. I haven&amp;rsquo;t had an issue with this so for now they can stay. If you wish to remove them, changing the final line to &lt;code>module.exports = env =&amp;gt; CONFIG;&lt;/code> should suffice.&lt;/li>
&lt;li>The &lt;a href="http://deck.gl">deck.gl&lt;/a> example works out of the box, but in case you don&amp;rsquo;t see the map, you should set the Mapbox token. See the comment in the first code snippet for how to do this.&lt;/li>
&lt;li>We don&amp;rsquo;t do any checks that the data is the latest, nor do we add any &amp;rsquo;thread safety&amp;rsquo;. It&amp;rsquo;s possible callbacks arrive out of order and our data &amp;lsquo;goes back in time&amp;rsquo;.&lt;/li>
&lt;li>Visit the &lt;a href="https://deck.gl/docs/developer-guide/custom-layers/layer-lifecycle">layer lifecycle&lt;/a> page to learn more about how the lifecycles work.&lt;/li>
&lt;/ul></description></item></channel></rss>