Mapbox: Creating and Embedding Interactive Maps

A non-profit I consult for wanted a way of engaging visitors with an interactive map that illustrated the scope and reach of its activities. I was in geek-heaven when I discovered “mapbox“. Creating and customizing a mapbox map has a high learning curve and required hours of trial-and-error, but I could not imagine a more intuitively-designed, well-implemented, comprehensively documented interactive map service.

The mapbox documentation is superior. but what I found most useful was starting with an example/tutorial map and working my way bit by bit up to my end goal, which included clustered/zoomable data points, multiple data layers, a legend, and customized data point pop-ups.

Mapbox Quick Start

Mapbox offers a self-proclaimed “generous free tier”, which I found to be, well, quite generous. The mapbox pricing page has details, but in a nutshell, the free tier includes 50,000 monthly map page loads via the web, which is plenty for a low use (and probably even a medium use) website.

Once you create a mapbox.com account and login to mapbox.com, you’ll be shown your Mapbox public API access token. I found this sufficient for my single project, but for more or larger projects, consider creating a separate API Access Token for each.

Mapbox offers a variety of built-in map styles, but if they’re not exactly what you’re looking for, you can customize your map theme with the Mapbox Studio. I found the built-in map styles sufficient for my needs, but after playing a bit with Studio, I am confident I could design whatever style map I needed.

Great starting points are the Mapbox Examples and the Mapbox Tutorials. I won’t repeat what those resources already explain so well. Rather, I’d like to share some of the tips I learned along my learning path in developing two examples: our very own “Where Have We Been” and the interactive map I developed for ASIANetwork. Both of these projects required mapping data sets from a dynamic Google Sheet; any updates to the gSheet are automatically displayed on the Mapbox map. “Sheet Mapper” provides a foundation for gSheet/mapbox integration.

I built my first mapbox app in a single HTML file, but, I was more intentional about the structure of my second app. I broke out the app into the following components:

  • config.js: contains all of the app’s configuration variables, including my mapbox access token, stye, center lat/long, zoom value, and other app-specific values.
const config = {
     style:                      "mapbox://styles/mapbox/streets-v11",
     accessToken:        "my access token",
     CSV:                        "my gSheet csv export URL",
     center:                     [-120.234, 47.398], //Lng, Lat
     zoom:                      1, 
     title:                        "Where Have We Been",
     description:          "This is where we have been",
    [...]
 };
  • style.css: contains all of the CSS style definitions for the app. Some (.mapbox*) are standard, and others are app-specific.
  • app.jss: contains the guts of the app code.
  • index.html: is the wrapper that brings everything together.

Using a gSheet data set

Linking a gSheet to a mapbox app can be tricky, but the mapbox tutorial is very good. First, the gSheet should contain your location data, including columns with Latitude and Longitude coordinates. Nothing prevents you from looking up the latlong coordinates within your app, but it seems more efficient to have these pre-calculated and immediately available to your script.

You might find it helpful to add an Google Sheets GeoCoding script (or use this direct link to the source code) to your Google Sheet. (Copy the code, then paste it into Tools > Script Editor. As built, this script will geocode a Location column into Latitude and Longitude columns by selecting all three columns and running Geocode > “Geocode Selected Cells (Address to Latitude, Longitude)”.

With a little extra work similar to the example below, you can dynamically update the Latitude and Longitude cells when a Location cell is changed. (This code snippet is far from perfect. This script changes (and restores) the active cell, which causes a short UI burp. With some work to the underlying geocoding script, this could be prevented.)

function onEdit(e) {
     var range = e.range;
     var row = range.getRow();
     var col  = range.getColumn();
     var geo_range = "A"+row+":C"+row;
     var sheet = SpreadsheetApp.getActiveSpreadsheet();
     var new_range = sheet.getRange(geo_range);
      new_range.activate();        // this moves the active cell to the Location to be geocoded causing some user interruption
      addressToPosition();         // this performs the geocoding using the previously mentioned "GeoCoding" script
      range.activate();                 // this moves the active cell back to the original cell
}

Next, share your gSheet with a public link, and append “gviz/tq?tqx=out:csv” so the output is formatted as CSV.

https://docs.google.com/spreadsheets/d/[link to your gSheet]/gviz/tq?tqx=out:csv

Verify the URL from an incognito window.

Then, the magic happens with the csv2geojson JavaScript library.

    <script src='https://npmcdn.com/csv2geojson@latest/csv2geojson.js'></script>

and then call and parse the data set with something like:

    $(document).ready(function () {
          $.ajax({
            type: 'GET',
            url: config.CSV,
            dataType: 'text', 
            success: function (csvData) {
                makeGeoJSON(csvData);
            },
            error: function (request, status, error) {
                console.log(request);
                console.log(status);
                console.log(error);
            },
        });
    });

    function makeGeoJSON(csvData) {
        csv2geojson.csv2geojson(
            csvData,
            {
                latfield: 'Latitude',
                lonfield: 'Longitude',
                delimiter: ',',
            },
            function (err, data) {
                data.features.forEach(function (data, i) {
                [...]

When all is said and done, you can publish your interactive Mapbox map directly from a website or embed it into your WordPress site with any embedding widget or using adding custom HTML <iframe> block like:

<iframe 
        src="https://uniyatra.com/where-have-we-been/" 
        width="1000" 
        height="900" 
        id="whereHaveWeBeen" 
        title="Where Have We Been">
</iframe>

Leave a Comment

Your email address will not be published. Required fields are marked *