Sean Gillies (Posts about turf)https://sgillies.net/tags/turf.atom2023-12-31T01:26:22ZSean GilliesNikolaJavaScript mapping in 2018https://sgillies.net/2019/05/22/javascript-mapping-in-2018.html2019-05-22T08:00:52-06:002019-05-22T08:00:52-06:00Sean Gillies<p>It's been five-and-a-half years since I <a class="reference external" href="https://sgillies.net/2013/10/08/linking-geojson.html">last blogged</a> about making maps in
a browser using JavaScript. It's cool that my old Syriac Places demo <a class="reference external" href="http://sgillies.github.io/syriaca/">still
works</a>. Yay for web standards. A lot of
things have changed in the meanwhile and this is my first chance to acknowledge
some of those changes.</p>
<p>I've been writing HTML and JavaScript every other day at work for the past
3 weeks, building a web app to give Sales and sales-supporting teams at Mapbox
insight into our imagery basemap. It's HTML and mostly Vanilla JS and has been
a fun exercise. Since it's for internal customers only I can use new browser
and JavaScript features.</p>
<p>Mapbox GL JS, the JavaScript mapping library that's maintained by my coworkers,
is the closest thing to a framework in my app. My current project is the first
in which I've used Mapbox GL JS. I'd like to point out some features and
aspects of the framework that I find especially notable.</p>
<p>Mapbox GL JS has excellent examples. This is a result of I cribbed freely from
<a class="reference external" href="https://docs.mapbox.com/mapbox-gl-js/examples/">https://docs.mapbox.com/mapbox-gl-js/examples/</a> and everything worked. Not all
projects have good examples. John Firebaugh (who has since moved on from
Mapbox), Colleen McGinnis, and the GL JS and Documentation teams put a ton of
work into these and it shows.</p>
<p>Mapbox GL JS makes a big and important case of dynamic maps simple. I have
a GeoJSON Source defined in my app's JavaScript. It is registered with a layer
and a map. When I remove features from the source, they disappear from the
map. When I add features to the source, they appear on the map. The map is
updated fast enough that I can do this on every mousemove event.</p>
<p>Mapbox GL JS Expressions give a developer ample control over styling and
filtering while keeping the styling API abstract and simple. In several parts
of its API, Mapbox GL JS can evaluate Lisp-like expressions composed of
JavaScript arrays. <code class="docutils literal"><span class="pre">["+",</span> 4, <span class="pre">["*",</span> 3, 2]]</code> evaluates to <code class="docutils literal">4 + (3 * 2)</code>, or
<code class="docutils literal">10</code>. In addition to the standard JavaScript operators, the namespace of GL
JS expressions operators contains feature property and map attribute getters.
An advantages of using JavaScript objects instead of conventional Lisp (as with
<a class="reference external" href="http://localhost:8000/2019/05/16/rasterio-1-0-23.html">snuggs and rio-calc</a>) is that developers
get syntax highlighting help when writing expressions, and can use JavaScript
to build expressions.</p>
<p>Another first for me is that I'm using Turf, the well-known simple features
geometry library created by Morgan Herlocker. In my app I'm creating features
on the fly derived from the intersections of features in a Mapbox tileset. Turf
is fast and its functions take and return GeoJSON objects, which makes it easy
for me to use and easy to integrate with Mapbox GL JS and other libraries or
plugins. Turf is indispensable for a web app like the one I'm writing.</p>
<p>Lastly, JavaScript itself has changed a lot in the last 5 years. I'm using
features of ES6 for the first time ever. You know this, I'll bet, but ES6 arrow
functions are like Scheme's lambda expressions and Python's lambda forms. I'm
using them exclusively, instead of the old anonymous functions, when filtering
and sorting arrays of features. For example, the following sorts features by
a date, in descending date order, without needing to type "function" or
"return". Handy, and to my eyes, more readable.</p>
<div class="code"><pre class="code javascript"><a id="rest_code_c1aff86d1159403b92e353d42b01dd50-1" name="rest_code_c1aff86d1159403b92e353d42b01dd50-1" href="https://sgillies.net/2019/05/22/javascript-mapping-in-2018.html#rest_code_c1aff86d1159403b92e353d42b01dd50-1"></a><span class="nx">features</span><span class="p">.</span><span class="nx">sort</span><span class="p">((</span><span class="nx">a</span><span class="p">,</span><span class="w"> </span><span class="nx">b</span><span class="p">)</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="nx">b</span><span class="p">.</span><span class="nx">properties</span><span class="p">.</span><span class="nx">render_date</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nx">a</span><span class="p">.</span><span class="nx">properties</span><span class="p">.</span><span class="nx">render_date</span><span class="p">)</span><span class="w"></span>
</pre></div>
<p>These are obviously not the only recent advances in the JavaScript mapping
field. Or even the most recent, which is why I chose the title "JavaScript
mapping in 2018". The app that I'm building could have been written a year ago
using the same software. For a glimpse at JavaScript mapping in 2019-2020,
I suggest <a class="reference external" href="https://observablehq.com/collection/@observablehq/maps">https://observablehq.com/collection/@observablehq/maps</a>.</p>