1

I am in the process of adding an ArcGIS map service to a map I wrote in JavaScript using the Mapbox GL JS library.

The map server is using the ArcGIS map service 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 ArcGIS map service 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>
nmtoken
13.6k5 gold badges39 silver badges91 bronze badges
asked Mar 19, 2018 at 15:59

1 Answer 1

2

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.

answered Mar 19, 2018 at 23:20
4
  • 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/… Commented Mar 19, 2018 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 Commented Mar 21, 2018 at 3:29
  • 2
    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. Commented Mar 21, 2018 at 10:13
  • @AndrewHarvey, I couldn't get the code sample to run. Is there anything else that needs to done? I couldn't find any documentation from FEMA on how to use the webservice in general, or how to form the url endpoint you posted. Is there a more general term I could look up that would teach me how to interact with services like this one? Then I could apply that general knowledge to this FEMA service. Thanks. Commented Jan 16, 2020 at 18:34

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.