1

I am in the process of adding a WMS map server to a map I wrote in JavaScript using the Mapbox GL JS library.

The map server is using the WMS from the FEMA National Flood Hazard Layer, and I would like to subset that data to a few specific Fields and overlay that onto my map..

I am using this Mapbox GL JS tutorial to add the WMS layer, I am running into two problems:

  1. I can't get the layer to display
  2. I can't subset the right fields I need to display

The code I am using...

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset='utf-8' />
        <title></title>
        <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
        <script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.44.1/mapbox-gl.js'></script>
        <script src='https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v2.2.0/mapbox-gl-geocoder.min.js'></script>
        <link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet">
        <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.44.1/mapbox-gl.css' rel='stylesheet' />
        <link href="https://fonts.googleapis.com/css?family=Inconsolata" rel="stylesheet">
        <link rel='stylesheet' href='https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v2.2.0/mapbox-gl-geocoder.css' type='text/css' />
            <style>
                body {
                  margin: 0;
                  padding: 0;
                }
                #map {
                  position: absolute;
                  top: 0;
                  bottom: 0;
                  width: 100%;
                  height: 100%;
                }
            </style>
            </head>
            <body>
            <style>
                #menu {
                  position: absolute;
                  background: rgba(64, 64, 64, 0.15);
                  padding: 5px;
                  font-family: 'Inconsolata';
                  font-size: 12px;
                }
                .marker {
                  background-image: url('/maki_icons/icons/square-stroked-11.svg');
                  background-size: cover;
                  width: 12px;
                  height: 12px;
                  cursor: pointer;
                  padding: 0px;
                }
                .mapboxgl-popup {
                  max-width: 200px;
                }
                .mapboxgl-popup-content {
                  text-align: center;
                  font-family: 'Open Sans', sans-serif;
                }
              </style>
    <div id='map'></div>
    <div id='menu'>
        <input id='streets' type='radio' name='rtoggle' value='streets'>
        <label for='streets'>streets</label>
        <input id='light' type='radio' name='rtoggle' value='light'>
        <label for='light'>light</label>
        <input id='satellite' type='radio' name='rtoggle' value='satellite'>
        <label for='satellite'>satellite</label>
    </div>
    <script>
    mapboxgl.accessToken =
    'pk.eyJ1IjoiZHlhdnJvbSIsImEiOiJjamVoNDc0MGowYjBlMndvNjRkMjEwenExIn0.uTE8zI8ELLNs1rIT2_Od2A';

        //load map
          var map = new mapboxgl.Map({
            container: 'map',
            style: 'mapbox://styles/mapbox/streets-v10',
            center: [-96, 37.8],
            zoom: 3.5,
            attributionControl:false
          });

        //add second layer of data
            map.on('load', function() {

          //add the FEMA WMS layer
              map.addLayer({
                'id': 'wms-test-layer',
                'type': 'raster',
                'source': {
                'type': 'raster',
                'tiles': [
                  'https://hazards.fema.gov/gis/nfhl/rest/services/public/NFHL/MapServer/28'
                ],}}
              );
              });

          // Tile switcher
          var layerList = document.getElementById('menu');
          var inputs = layerList.getElementsByTagName('input');

          function switchLayer(layer) {
              var layerId = layer.target.id;
              map.setStyle('mapbox://styles/mapbox/' + layerId + '-v9');
          }

          for (var i = 0; i < inputs.length; i++) {
              inputs[i].onclick = switchLayer;
          }
    </script>
</body>
</html>
1

In your addLayer function, the tiles option must be the URL to the raster tiles. https://hazards.fema.gov/gis/nfhl/rest/services/public/NFHL/MapServer/28 is the URL to the HTML page describing the ERSI MapServer service.

Although that service doesn't appear to support WMS it supports an /export which we can force to return raster tiles in the right format for Mapbox GL JS. So you should replace your tiles URL with this:

https://hazards.fema.gov/gis/nfhl/rest/services/public/NFHL/MapServer/export?bbox={bbox-epsg-3857}&bboxSR=EPSG%3A3857&layers=28&layerDefs=&size=256%2c256&imageSR=&format=png&transparent=true&dpi=&time=&layerTimeOptions=&dynamicLayers=&gdbVersion=&mapScale=&f=image

You can change that layers=28 to another layer number or I think use a comma separated value for multiple layers.

You might want to consider inserting this layer below the roads and label layers as well.

  • Sorry I missed that part about filtering by an attribute, I can't see how to do that, but it might be possible. I would have suggested using the WFS feed but it seems to only support GML which would require an additonal library to convert it to GeoJSON hazards.fema.gov/gis/nfhl/services/public/NFHL/MapServer/… – AndrewHarvey Mar 19 '18 at 23:27
  • hey thats awesome, thanks very much! may I ask how or where you found out about the /export that was in the right format for Mapbox? I want to see if that bread crumb trail leads to learning how to filter out the necessary attributes. I'm not familiar with that syntax – Fred Mortensen Mar 21 '18 at 3:29
  • 1
    If you go up a level to hazards.fema.gov/gis/nfhl/rest/services/public/NFHL/MapServer you'll see at the bottom it says "Supported Operations: Export Map Identify Find Return Updates". The first one Export map returns a raster, so if you click through you can see all your options. mapbox.com/mapbox-gl-js/style-spec#sources has a section on WMS layers showing how GL JS can substitute in a bbox for each tile request, together with a setting the right coordinate system, image size and layers param you can get a raster tile for GL JS from that ArcGIS service. – AndrewHarvey Mar 21 '18 at 10:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.