Skip to content

Learn how to add features from feature layers to a map.

Add a feature layer as GeoJSON using API key authentication

A feature layer is a dataset in a hosted feature service. Each feature layer contains features with a single geometry type (point, line, or polygon), and a set of attributes. You can access and display features by making query requests to the feature service and displaying them in a map.

In this tutorial, you access and display three different hosted feature layers. The data is accessed and displayed as GeoJSON.

The feature layers are:

Prerequisites

You need an ArcGIS Location Platform or ArcGIS Online account.

Steps

Get the starter app

Select a type of authentication and follow the steps to create a new app.

You can choose one of the following to create a new CodePen:

  • Option 1: Complete the Display a map tutorial; or,
  • Option 2: Start from the Display a map tutorial .

Set up authentication

Create a new API key credential with the correct privileges to get an access token.

  1. Go to the Create an API key tutorial and create an API key with the following privilege(s):
    • Privileges
      • Location services > Basemaps
    • Item access
      • Note: If you are using your own custom data layer for this tutorial, you need to grant the API key credentials access to the layer item. Learn more in Item access privileges.

Set developer credentials

Use the API key or OAuth developer credentials so your application can access ArcGIS services.

  1. Update the accessToken variable to use your API key.

    Expand
    Use dark colors for code blocks
    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83  /* Use for API key authentication */  const accessToken = "YOUR_ACCESS_TOKEN"; 
    Expand

Add references to ArcGIS REST JS

This tutorial uses ArcGIS REST JS for accessing the feature service. It also uses the ol-popup library to display pop-ups.

  1. In the <head> element, add references to the ArcGIS REST JS and ol-popup libraries.

    Expand
    Use dark colors for code blocks
    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@v10.7.0/ol.css">  <script src="https://cdn.jsdelivr.net/npm/ol@v10.7.0/dist/ol.js"></script>   <script src="https://cdn.jsdelivr.net/npm/ol-mapbox-style@13.1.1/dist/olms.js"></script>   <script src="https://unpkg.com/@esri/arcgis-rest-request@4/dist/bundled/request.umd.js"></script>  <script src="https://unpkg.com/ol-popup@5.1.1/dist/ol-popup.js"></script>  <link rel="stylesheet" href="https://unpkg.com/ol-popup@5.1.1/src/ol-popup.css"> 
    Expand

Add a point feature layer

The trailheads feature layer contains feature with a point geometry. Use a Vector layer to access the feature layer by URL and display the points. By default, they will display as white circles with blue outlines.

  1. Create a VectorSource. Pass a new GeoJSON as the format parameter. For the url parameter, pass a direct link to a FeatureServer endpoint.

    Expand
    Use dark colors for code blocks
    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182  const basemapId = "arcgis/streets";  const basemapURL = `https://basemapstyles-api.arcgis.com/arcgis/rest/services/styles/v2/styles/${basemapId}?token=${accessToken}`;   olms.apply(map, basemapURL).then(function (map) {   const pointLayerName = "Trailheads";  const pointLayerURL =  "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/" +  pointLayerName +  "/FeatureServer/0/query?where=1%3D1&outFields=*&returnGeometry=true&f=geojson";   const pointSource = new ol.source.Vector({  format: new ol.format.GeoJSON(),  url: pointLayerURL,   }); 
    Expand
  2. Add the data attribution for the feature layer source.

    • Go to the Trailheads (Santa Monica Mountains) item.
    • Scroll down to the Acknowledgments section and copy its value.
    • Paste the copied value to the attributions property.
      Expand
      Use dark colors for code blocks
      1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182  const basemapId = "arcgis/streets";  const basemapURL = `https://basemapstyles-api.arcgis.com/arcgis/rest/services/styles/v2/styles/${basemapId}?token=${accessToken}`;   olms.apply(map, basemapURL).then(function (map) {   const pointLayerName = "Trailheads";  const pointLayerURL =  "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/" +  pointLayerName +  "/FeatureServer/0/query?where=1%3D1&outFields=*&returnGeometry=true&f=geojson";   const pointSource = new ol.source.Vector({  format: new ol.format.GeoJSON(),  url: pointLayerURL,   // Attribution text retrieved from https://arcgis.com/home/item.html?id=883cedb8c9fe4524b64d47666ed234a7  attributions: ["Los Angeles GeoHub |"]   }); 
      Expand
  3. Create a Vector layer using the Vector source you defined.

    Expand
    Use dark colors for code blocks
    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182  const pointSource = new ol.source.Vector({  format: new ol.format.GeoJSON(),  url: pointLayerURL,   // Attribution text retrieved from https://arcgis.com/home/item.html?id=883cedb8c9fe4524b64d47666ed234a7  attributions: ["Los Angeles GeoHub |"]   });   const pointLayer = new ol.layer.Vector({  source: pointSource  }); 
    Expand

Add a line feature layer

The Trails feature layer contains features with a line geometry. Use a Vector layer to access the feature layer by URL and display the lines. By default, the features are displayed as blue lines.

  1. Create a VectorSource with format and url parameters.

    Expand
    Use dark colors for code blocks
    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182  const pointLayer = new ol.layer.Vector({  source: pointSource  });   const lineLayerName = "Trails";  const lineLayerURL =  "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/" +  lineLayerName +  "/FeatureServer/0/query?where=1%3D1&outFields=*&returnGeometry=true&f=geojson";   const lineSource = new ol.source.Vector({  format: new ol.format.GeoJSON(),  url: lineLayerURL,   }); 
    Expand
  2. Add the data attribution for the feature layer source.

    • Go to the Trails item.
    • Scroll down to the Acknowledgments section and copy its value.
    • Paste the copied value to the attributions property.
      Expand
      Use dark colors for code blocks
      1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182  const pointLayer = new ol.layer.Vector({  source: pointSource  });   const lineLayerName = "Trails";  const lineLayerURL =  "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/" +  lineLayerName +  "/FeatureServer/0/query?where=1%3D1&outFields=*&returnGeometry=true&f=geojson";   const lineSource = new ol.source.Vector({  format: new ol.format.GeoJSON(),  url: lineLayerURL,   // Attribution text retrieved from https://arcgis.com/home/item.html?id=69e12682738e467eb509d8b54dc73cbd  attributions: ["Los Angeles GeoHub |"]   }); 
      Expand
  3. Create a Vector layer using the Vector source you defined.

    Expand
    Use dark colors for code blocks
    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182  const lineSource = new ol.source.Vector({  format: new ol.format.GeoJSON(),  url: lineLayerURL,   // Attribution text retrieved from https://arcgis.com/home/item.html?id=69e12682738e467eb509d8b54dc73cbd  attributions: ["Los Angeles GeoHub |"]   });   const lineLayer = new ol.layer.Vector({  source: lineSource  }); 
    Expand

Add a polygon feature layer

The Parks and Open Space feature layer contains features with a polygon geometry. Use a Vector layer to access the feature layer by URL and display the polygons. By default, polygon features are displayed as translucent white fill with blue outlines.

  1. Create a VectorSource with format and url parameters.

    Expand
    Use dark colors for code blocks
    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182  const lineLayer = new ol.layer.Vector({  source: lineSource  });   const polygonLayerName = "Parks_and_Open_Space";  const polygonLayerURL =  "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/" +  polygonLayerName +  "/FeatureServer/0/query?where=1%3D1&outFields=*&returnGeometry=true&f=geojson";   const polygonSource = new ol.source.Vector({  format: new ol.format.GeoJSON(),  url: polygonLayerURL,   }); 
    Expand
  2. Add the data attribution for the feature layer source.

    • Go to the Parks and Open Space item.
    • Scroll down to the Acknowledgments section and copy its value.
    • Paste the copied value to the attributions property.
      Expand
      Use dark colors for code blocks
      1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182  const lineLayer = new ol.layer.Vector({  source: lineSource  });   const polygonLayerName = "Parks_and_Open_Space";  const polygonLayerURL =  "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/" +  polygonLayerName +  "/FeatureServer/0/query?where=1%3D1&outFields=*&returnGeometry=true&f=geojson";   const polygonSource = new ol.source.Vector({  format: new ol.format.GeoJSON(),  url: polygonLayerURL,   // Attribution text retrieved from https://arcgis.com/home/item.html?id=f2ea5d874dad427294641d2d45097c0e  attributions: ["Los Angeles GeoHub |"]   }); 
      Expand
  3. Create a Vector layer using the Vector source you defined.

    Expand
    Use dark colors for code blocks
    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182  const polygonSource = new ol.source.Vector({  format: new ol.format.GeoJSON(),  url: polygonLayerURL,   // Attribution text retrieved from https://arcgis.com/home/item.html?id=f2ea5d874dad427294641d2d45097c0e  attributions: ["Los Angeles GeoHub |"]   });   const polygonLayer = new ol.layer.Vector({  source: polygonSource  }); 
    Expand
  4. To display multiple layers in a specific order, you group them using a LayerGroup. Add all of the layers you created to the group, then display it on the map using map.addLayer().

    Expand
    Use dark colors for code blocks
    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182  const layerGroup = new ol.layer.Group({  layers: [polygonLayer, lineLayer, pointLayer]  });   map.addLayer(layerGroup); 
    Expand

Add a pop-up

You can use a Popup to show data attributes for a feature when you click on them. A popup is a type of Overlay so you add it to the map with map.addOverlay. To get a feature, you use the click event and map.getFeaturesAtPixel to get the features at a click point. You also use the point to position the Popup at the correct location.

  1. Create a Popup and save it to a popup variable. Add it to the map with map.addOverlay.

    Expand
    Use dark colors for code blocks
    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182  const polygonLayer = new ol.layer.Vector({  source: polygonSource  });   const layerGroup = new ol.layer.Group({  layers: [polygonLayer, lineLayer, pointLayer]  });   map.addLayer(layerGroup);   const popup = new Popup();  map.addOverlay(popup); 
    Expand
  2. Add a click event handler. Inside, check if a feature from the trailheads layer was clicked. If so, move the pop-up, and show the trailhead name and park name (TRL_NAME and PARK_NAME). Otherwise, check the trails layer; show the trail name, length and elevation gain (TRL_NAME, LENGTH_MI, ELEV_GAIN) if it was clicked. Otherwise, check the parks layer; show the park name and managing agency (PARK_NAME and MNG_AGENCY) if it was clicked. Otherwise, hide the pop-up with popup.hide;

    Expand
    Use dark colors for code blocks
    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182  const popup = new Popup();  map.addOverlay(popup);   map.on("click", (event) => {  let feature = map.getFeaturesAtPixel(event.pixel, {  layerFilter: (l) => l === pointLayer  })[0];  if (feature) {  popup.show(event.coordinate, `<strong>${feature.get("TRL_NAME")}</strong><br/>${feature.get("PARK_NAME")}`);  return;  }   feature = map.getFeaturesAtPixel(event.pixel, {  layerFilter: (l) => l === lineLayer  })[0];  if (feature) {  popup.show(  event.coordinate,  `<strong>${feature.get("TRL_NAME")}</strong><br/>${feature.get("LENGTH_MI")} miles, ${feature.get("ELEV_GAIN")} feet elevation gain.`  );  return;  }   feature = map.getFeaturesAtPixel(event.pixel, {  layerFilter: (l) => l === polygonLayer  })[0];  if (feature) {  popup.show(event.coordinate, `<strong>${feature.get("PARK_NAME")}</strong><br/>${feature.get("MNG_AGENCY")}`);  return;  }  popup.hide();  }); 
    Expand

Run the app

Run the app.

You should now be able to click on features to see information in a pop-up.

What's next?

Learn how to use additional location services in these tutorials:

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.