Mines and Mapbox GL JS

The new Mapbox GL JS is unreal. I made a quick and sloppy map to try out some of the new features. I grabbed a dataset of mines in the US from MSHA's website. I loaded it up into Mapbox and created two styles: satellite imagery and streets. I took some code from their GL JS how-to's and threw it together. My Frankencode is below. Side note: JavaScript is hard. I put in some code to toggle between the two base layers, and to add two more optional layers for hillshade and contours. 

Issues to fix and things to improve in the next version: The dataset was HUGE. I had to limit to zoom levels to keep the size reasonable. You'll notice that if you zoom out too much, the data disappears. I might need to pay for Mapbox to make this work... Also there are two attributions at the bottom of the map for OSM and Mapbox. I do love OSM enough to thank it twice, but I think this has to do with two styles being loaded in. Another thing to investigate with more time.

Cool features: Hold shift and use the arrow keys to fly around. Note how place labels stay horizontal while you spin the Earth as if you stuck a pin in it first. 

Thanks, Mapbox. Here's the code I embedded above.

    <meta charset='utf-8' />
    <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
    <script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.12.0/mapbox-gl.js'></script>
    <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.12.0/mapbox-gl.css' rel='stylesheet' />
        body { margin:0; padding:0; }
        #map { position:absolute; top:0; bottom:0; width:100%; }

    #menu {
        background: #fff;
        position: absolute;
        z-index: 1;
        top: 10px;
        right: 10px;
        border-radius: 3px;
        width: 120px;
        border: 1px solid rgba(0,0,0,0.4);
        font-family: 'Open Sans', sans-serif;
    #menu a {
        font-size: 13px;
        color: #404040;
        display: block;
        margin: 0;
        padding: 0;
        padding: 10px;
        text-decoration: none;
        border-bottom: 1px solid rgba(0,0,0,0.25);
        text-align: center;
    #menu a:last-child {
        border: none;
    #menu a:hover {
        background-color: #f8f8f8;
        color: #404040;
    #menu a.active {
        background-color: #3887be;
        color: #ffffff;
    #menu a.active:hover {
        background: #3074a4;

<div id='map'></div>
<div id='menu'>
    <input id='sarahmlevine/cihs248is00aa95lylu5a7x1d' type='radio' name='rtoggle' value='satellite' checked='checked'>
    <label for='satellite'>satellite layer</label>
    <input id='sarahmlevine/cihvjue4p00h095lyyyyv2347' type='radio' name='rtoggle' value='basic'>
    <label for='basic'>streets</label>
mapboxgl.accessToken = 'pk.eyJ1Ijoic2FyYWhtbGV2aW5lIiwiYSI6IlAweXNYVEUifQ._dz0522LtBABUYyfqP503Q';
var map = new mapboxgl.Map({
    container: 'map',
    style: 'mapbox://styles/sarahmlevine/cihs248is00aa95lylu5a7x1d',
    zoom: 8.1,
    center: [-121.41, 37.91]
var layerList = document.getElementById('menu');
var inputs = layerList.getElementsByTagName('input');
function switchLayer(layer) {
    var layerId = layer.target.id;
    map.setStyle('mapbox://styles/' + layerId);
for (var i = 0; i < inputs.length; i++) {
    inputs[i].onclick = switchLayer;
map.on('style.load', function () {
    map.addSource('contours', {
        type: 'vector',
        url: 'mapbox://mapbox.mapbox-terrain-v2'
        'id': 'contours',
        'type': 'line',
        'source': 'contours',
        'source-layer': 'contour',
        'layout': {
            'line-join': 'round',
            'line-cap': 'round'
        'paint': {
            'line-color': '#877b59',
            'line-width': 1
    map.addSource('hillshade', {
        type: 'vector',
        url: 'mapbox://mapbox.mapbox-terrain-v2'
        'id': 'hillshade',
        'type': 'line',
        'source': 'hillshade',
        'source-layer': 'hillshade',
        'layout': {
            'line-join': 'round',
            'line-cap': 'round'
        'paint': {
            'line-color:': '#877b59',
            'line-width': 1,
            'line-opacity': 0.6,
addLayer('Contours', 'contours');
addLayer('Hillshade', 'hillshade');
function addLayer(name, id) {
    var link = document.createElement('a');
    link.href = '#';
    link.className = 'active';
    link.textContent = name;
    link.onclick = function (e) {
        var visibility = map.getLayoutProperty(id, 'visibility');
        if (visibility === 'visible') {
            map.setLayoutProperty(id, 'visibility', 'none');
            this.className = '';
        } else {
            this.className = 'active';
            map.setLayoutProperty(id, 'visibility', 'visible');
    var layers = document.getElementById('menu');
// Add zoom and rotation controls to the map.
map.addControl(new mapboxgl.Navigation());