Maps!

I only began traveling recently to locations where photographing the landscape was the primary goal of the trip. I have had many cameras accompany me over the years wherever I explored, and I also logged my location to quantify how long and difficult a trek was with a watch or other device. I wanted to have both my images and this information combined for a more complete summary of the trip, so I determined a way to integrate Mapbox into my Squarespace website. I am happy with the end result, although I hope that any code presented here will help one duplicate my effort in a fraction of the time.

Step 1: Input Data

Mapbox Studio allows a user to customize the look and functionality of a map and allows it to be integrated into a webpage or into a mobile app. Mapbox Datasets store point, line, or polygon information, along with descriptor data. This data is pushed to a Tileset, which splits the data up into zoomable, vector data for use in a map. A Mapbox map then uses this Tileset information, along with the selection of a map style into the appropriately named Styles. Datasets require information in the form of GeoJSON or CSV files, while my watch data is typically in the form of GPX files. To convert between GPX and GeoJSON, one can either use an online converter, or download the source code to complete the conversion locally. This GeoJSON file can be uploaded into a Mapbox Dataset as a new feature. Each separate file will be treated as a new feature within the same Dataset, and resulting Tileset.

Step 2: Journal Entry Linking

When the map is zoomed out, all of the features can be viewed together. I wanted to take advantage of this by making each feature clickable, so that trip journal entries can searched by location. I created the data field url in each feature and included code needed for a link to the appropriate journal entry.

<strong><a href=http://douglasdevoto.com/journal/2017/6/24/summit-lake target=\"_blank\" >Summit Lake</a></strong>

Step 3: Map Customization

The code needed to display a Mapbox map onto a Squarespace page is shown below, along with a few customizations. The mouse changes from a cursor to a pointer when it hovers over a trail, and a popup is shown if the trail is clicked. This popup accesses the code in the the Dataset for the link, so that new trips can be added independently of the webpage's embedded code. I also included the ability to alternate between terrain and satellite map styles through radio buttons.

<!DOCTYPE html>
<html>
  <head>
    <meta charset='utf-8' />
    <title>Trails</title>
    <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
    <script src='https://api.mapbox.com/mapbox-gl-js/v0.39.0/mapbox-gl.js'></script>
    <link href='https://api.mapbox.com/mapbox-gl-js/v0.39.0/mapbox-gl.css' rel='stylesheet' />

    <style>
      body {margin: 0; padding: 0;}
      #map {position: relative; top: 0; bottom: 0; width: 100%; height: 500px;}
    </style>
    </head>

  <body>
    <style>
      #menu {position: relative; background: #fff; padding: 10px; font-family: 'Open Sans', sans-serif;}
    </style>

    <div id='map'></div>

    <div id='menu'> //Insert your own Mapbox Styles
        <input id='mapbox://styles/' type='radio' name='rtoggle' value='outdoors' checked='checked'>
        <label for='outdoors'>terrain</label>
        <input id='mapbox://styles/' type='radio' name='rtoggle' value='satellite'>
        <label for='satellite'>satellite</label>
    </div>

    <script>
    mapboxgl.accessToken = 'pk.'; // replace this with your access token

    var map = new mapboxgl.Map({
      container: 'map',
      style: 'mapbox://styles/', // replace this with your style URL
      center: [-95, 40], // starting position
      zoom: 3.2,
    });

    var layerList = document.getElementById('menu');
    var inputs = layerList.getElementsByTagName('input');
    function switchLayer(layer) {
    var layerId = layer.target.id;
    map.setStyle(layerId);
    }
    for (var i = 0; i < inputs.length; i++) {
    inputs[i].onclick = switchLayer;
    }

    // When a click event occurs on a feature in the states layer, open a popup at the
        // location of the click, with description HTML from its properties.
        map.on('click', 'gpx', function (e) {
       new mapboxgl.Popup()
           .setLngLat(e.lngLat)
           .setHTML(e.features[0].properties.url)
           .addTo(map);
   });

    // Change the cursor to a pointer when the mouse is over a gpx layer.
       map.on('mouseenter', 'gpx', function () {
           map.getCanvas().style.cursor = 'pointer';
       });

       // Change it back to a pointer when it leaves.
       map.on('mouseleave', 'gpx', function () {
           map.getCanvas().style.cursor = '';
       });

    map.addControl(new mapboxgl.NavigationControl());

    </script>
    </body>
    </html>

If I were better at coding, this code would be cleaner and it would have taken me a fraction of the time, but I am happy it is working! The only modification needed for new webpages is to update the zoom level and latitude/ longitude coordinates to have the map centered in the desired location.

Trails
Douglas DeVoto