Learn how to use style feature layers.
A feature layer is a dataset in a feature service hosted in ArcGIS. Each feature layer contains features with a single geometry type (point, line, or polygon), and a set of attributes. Layers in OpenLayers can contain style functions, which use attribute values to change the appearance of features. This allows you to create complex, data-driven visualizations by relating visual variables to data attributes.
In this tutorial, you apply different styles to enhance the visualization of the Trailheads, Trails and Parks and Open Spaces feature layers.
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.
Choose API key authentication if you:
- Want the easiest way to get started.
- Want to build public applications that access ArcGIS Location Services and secure items.
- Have an ArcGIS Location Platform or ArcGIS Online account.
Choose user authentication if you:
- Want to build private applications.
- Require application users to sign in with their own ArcGIS account and access resources their behalf.
- Have an ArcGIS Online account.
To learn more about both types of authentication, go to Authentication.
Set up authentication
Set developer credentials
Use the API key or OAuth developer credentials so your application can access ArcGIS services.
Style trailheads with an image and labels
A Style in OpenLayers has several possible components: an image, text, stroke, fill and so on. To display a hiker icon for the trailheads layer, you use an Icon style as the image component. Specify which image file as the src, and the size as the scale parameter.
To display the trailhead name, you use a Text style. Use a left value for text with an offset of 10 to display the labels to the right of the icons. Use Fill and Stroke styles as the fill and stroke properties to give the labels white text with a teal outline. The font property is a CSS font definition. Since the label for each trailhead is different, use a function to return a Style for a given feature. Set the text property using feature's TRL attribute.
-
Inside
olmsload handler, create atrailheadfunction that takes aStyle featureand returns aStylecontaining anIconstyle. Usehttpfor the://static.arcgis.com/images/ Symbols/ NP S/nps Pictograph _0231b.png srcand set ascaleof 25%.Use dark colors for code blocks 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 trailheadStyle = function (feature) { return new ol.style.Style({ image: new ol.style.Icon({ src: "http://static.arcgis.com/images/Symbols/NPS/npsPictograph_0231b.png", scale: 0.25 }), -
Add a
Textstyle to display labels with white text, teal outline, in an italic sans-serif font. Set thetextproperty using the feature'sTRLattribute._NAME Use dark colors for code blocks const trailheadStyle = function (feature) { return new ol.style.Style({ image: new ol.style.Icon({ src: "http://static.arcgis.com/images/Symbols/NPS/npsPictograph_0231b.png", scale: 0.25 }), text: new ol.style.Text({ text: feature.get("TRL_NAME"), font: "italic 12px sans-serif", offsetX: 10, textAlign: "left", fill: new ol.style.Fill({ color: "#FFFFFF" }), stroke: new ol.style.Stroke({ color: "#5E8D74", width: 3 }) }) }); }; -
Add a
Vectorlayer with aVectorsource to load and display the trailheads feature layer. Setdeclutterto be true to prevent label overlap. Pass thetrailheadsfunction as theStyle styleproperty.Use dark colors for code blocks stroke: new ol.style.Stroke({ color: "#5E8D74", width: 3 }) }) }); }; const trailheadsLayerName = "Trailheads"; const trailheadsLayerURL = "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/" + trailheadsLayerName + "/FeatureServer/0/query?where=1%3D1&outFields=*&returnGeometry=true&f=pgeojson"; const trailheadsLayer = new ol.layer.Vector({ source: new ol.source.Vector({ format: new ol.format.GeoJSON(), url: trailheadsLayerURL, }), style: trailheadStyle, declutter: true });For more information about adding feature layers using GeoJSON, see the Add a feature layer as GeoJSON tutorial.
-
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
attributionsproperty.Use dark colors for code blocks stroke: new ol.style.Stroke({ color: "#5E8D74", width: 3 }) }) }); }; const trailheadsLayerName = "Trailheads"; const trailheadsLayerURL = "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/" + trailheadsLayerName + "/FeatureServer/0/query?where=1%3D1&outFields=*&returnGeometry=true&f=pgeojson"; const trailheadsLayer = new ol.layer.Vector({ source: new ol.source.Vector({ format: new ol.format.GeoJSON(), url: trailheadsLayerURL, // Attribution text retrieved from https://arcgis.com/home/item.html?id=883cedb8c9fe4524b64d47666ed234a7 attributions: ["Los Angeles GeoHub |"] }), style: trailheadStyle, declutter: true });
Style trail width by elevation gain
To visualize the elevation gain of a trail you can use the width of a Stroke style. To do this, create another function which returns a Style. The width of the style's stroke property will be a calculation converting feet of elevation gain to pixels of width.
-
Create a
trailfunction that takes aStyle featureand returns aStylewith aStrokestyle. Set thecolorto pink, and calculate thewidthproperty from the feature'sELEVattribute._GAIN Use dark colors for code blocks style: trailheadStyle, declutter: true }); const trailStyle = function (feature) { return new ol.style.Style({ stroke: new ol.style.Stroke({ color: "#BA55D3", width: 3 + (4 * feature.get("ELEV_GAIN")) / 2300 }) }); }; -
Add the Trails feature layer as a
Vectorlayer with a GeoJSONVectorsource. Pass yourtrailfunction as theStyle styleproperty.Use dark colors for code blocks const trailStyle = function (feature) { return new ol.style.Style({ stroke: new ol.style.Stroke({ color: "#BA55D3", width: 3 + (4 * feature.get("ELEV_GAIN")) / 2300 }) }); }; const trailsLayerName = "Trails"; const trailsLayerURL = "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/" + trailsLayerName + "/FeatureServer/0/query?where=1%3D1&outFields=*&returnGeometry=true&f=pgeojson"; const trailsLayer = new ol.layer.Vector({ source: new ol.source.Vector({ format: new ol.format.GeoJSON(), url: trailsLayerURL, }), style: trailStyle }); -
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
attributionsproperty.Use dark colors for code blocks const trailStyle = function (feature) { return new ol.style.Style({ stroke: new ol.style.Stroke({ color: "#BA55D3", width: 3 + (4 * feature.get("ELEV_GAIN")) / 2300 }) }); }; const trailsLayerName = "Trails"; const trailsLayerURL = "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/" + trailsLayerName + "/FeatureServer/0/query?where=1%3D1&outFields=*&returnGeometry=true&f=pgeojson"; const trailsLayer = new ol.layer.Vector({ source: new ol.source.Vector({ format: new ol.format.GeoJSON(), url: trailsLayerURL, // Attribution text retrieved from https://arcgis.com/home/item.html?id=69e12682738e467eb509d8b54dc73cbd attributions: ["Los Angeles GeoHub |"] }), style: trailStyle });
-
Create a
bikefunction. If the feature has aTrails Style Yesvalue forUSE, return a white dashed_BIKE Strokestyle. Otherwise, do not return aStyle, so the feature will not be displayed.Use dark colors for code blocks style: trailStyle }); const bikeTrailsStyle = function (feature) { if (feature.get("USE_BIKE") === "Yes") { return new ol.style.Style({ stroke: new ol.style.Stroke({ lineDash: [1, 4], color: "white", width: 2 }) }); } }; -
Add a
bikeusing the source fromTrails Layer trails, with theLayer bikefunction.Trails Style Use dark colors for code blocks stroke: new ol.style.Stroke({ lineDash: [1, 4], color: "white", width: 2 }) }); } }; const bikeTrailsLayer = new ol.layer.Vector({ source: trailsLayer.getSource(), style: bikeTrailsStyle });
Style park colors by type
You can use color to communicate the category of a feature, such as the type of a park or open space. Use a style function to returns a Fill style, in which you derive the color property from the feature's TYPE property.
-
Create a
parksfunction which returns aStyle Fillstyle. Look up the feature'sTYPEattribute in a table to give a different color forNatural Areas,Regionla Open Space,Local ParkandRegional Recreation Park. If the type is not one of these, make the color transparent.Use dark colors for code blocks const bikeTrailsLayer = new ol.layer.Vector({ source: trailsLayer.getSource(), style: bikeTrailsStyle }); const parksStyle = function (feature) { const colorTable = { "Natural Areas": "#9E559C", "Regional Open Space": "#A7C636", "Local Park": "#149ECE", "Regional Recreation Park": "#ED5151" }; return new ol.style.Style({ fill: new ol.style.Fill({ color: colorTable[feature.get("TYPE")] || "transparent" }) }); }; -
Create a
Vectorlayer with aVectorsource for the parks feature layer. Pass yourparksfunction as theStyle styleproperty, with a low opacity.Use dark colors for code blocks return new ol.style.Style({ fill: new ol.style.Fill({ color: colorTable[feature.get("TYPE")] || "transparent" }) }); }; const parksLayerName = "Parks_and_Open_Space"; const parksLayerURL = "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/" + parksLayerName + "/FeatureServer/0/query?where=1%3D1&outFields=*&returnGeometry=true&f=pgeojson"; const parksLayer = new ol.layer.Vector({ source: new ol.source.Vector({ format: new ol.format.GeoJSON(), url: parksLayerURL, }), opacity: 0.2, style: parksStyle }); -
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
attributionsproperty.Use dark colors for code blocks return new ol.style.Style({ fill: new ol.style.Fill({ color: colorTable[feature.get("TYPE")] || "transparent" }) }); }; const parksLayerName = "Parks_and_Open_Space"; const parksLayerURL = "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/" + parksLayerName + "/FeatureServer/0/query?where=1%3D1&outFields=*&returnGeometry=true&f=pgeojson"; const parksLayer = new ol.layer.Vector({ source: new ol.source.Vector({ format: new ol.format.GeoJSON(), url: parksLayerURL, // Attribution text retrieved from https://arcgis.com/home/item.html?id=f2ea5d874dad427294641d2d45097c0e attributions: ["Los Angeles GeoHub |"] }), opacity: 0.2, style: parksStyle });
Add all layers to map
To display multiple layers in a specific order, you group them using a LayerGroup. This makes it easier to manage and organize your map layers. Once the group is set up, you can display on it to the map using map.add.
-
Create a layer group to add all the layers with the correct ordering.
Use dark colors for code blocks const layerGroup = new ol.layer.Group({ layers: [parksLayer, bikeTrailsLayer, trailsLayer, trailheadsLayer] }); -
Display the layers on the map.
Use dark colors for code blocks const layerGroup = new ol.layer.Group({ layers: [parksLayer, bikeTrailsLayer, trailsLayer, trailheadsLayer] }); map.addLayer(layerGroup);
Run the app
Run the app.
You should now see parks of different colors, beneath the trails and trailhead layers.What's next?
Learn how to use additional location services in these tutorials:


