Learn how to add features as GeoJSON to a map.
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 the Trailheads feature layer to get GeoJSON and display the features as clusters. Working with GeoJSON is often useful for dynamically generated data, but not suitable for large datasets.
Prerequisites
This tutorial requires an ArcGIS Location Platform or ArcGIS Online account.
Steps
Create a new pen
- To get started, you can complete the Display a map tutorial or use the .
Get an access token
You need an access token with the correct privileges to access the resources used in this tutorial.
-
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.
- Privileges
-
Copy the API key access token to your clipboard when prompted.
-
In CodePen, update the
access
variable to use your access token.Token Use dark colors for code blocks const accessToken = "YOUR_ACCESS_TOKEN"; const basemapEnum = "arcgis/outdoor"; const map = new maplibregl.Map({ container: "map", // the id of the div element style: `https://basemapstyles-api.arcgis.com/arcgis/rest/services/styles/v2/styles/${basemapEnum}?token=${accessToken}`, zoom: 12, // starting zoom center: [-118.805, 34.027] // starting location [longitude, latitude] });
-
Run the code to ensure the basemap is displayed in the map.
To learn about the other types of authentication available, go to Types of authentication.
Add a load event handler
You need to wait for the map to be completely loaded before adding any layers.
-
Add an event handler to the map
load
event.For more information about the
load
event, see the MapLibre GL JS documentation.Use dark colors for code blocks <script> const accessToken = "YOUR_ACCESS_TOKEN"; const basemapEnum = "arcgis/outdoor"; const map = new maplibregl.Map({ container: "map", // the id of the div element style: `https://basemapstyles-api.arcgis.com/arcgis/rest/services/styles/v2/styles/${basemapEnum}?token=${accessToken}`, zoom: 12, // starting zoom center: [-118.805, 34.027] // starting location [longitude, latitude] }); map.once("load", () => { // This code runs once the base style has finished loading. }); // Add Esri attribution // Learn more in https://esriurl.com/attribution map._controls[0].options.customAttribution += " | Powered by Esri " map._controls[0]._updateAttributions() </script>
Add a GeoJSON source
To add GeoJSON from a feature service, you need to define a source of type geojson
and reference the feature layer. The source tells MapLibre GL JS how to access the data for the layer, but does not visually add it to the map. To get GeoJSON features from a feature layer, you provide a URL to query the feature service and return features in GeoJSON format. Features can then be displayed by adding the source to a layer.
While there are several types of sources, the two most common are geojson
(for a set of features represented as GeoJSON) and vector
(for vector tiles). For more information, see the MapLibre Style Specification.
-
Inside the load event handler, add a
source
. Set theid
totrailheads
andtype
togeojson
. Setdata
to the URL for thetrailheads
feature layer. Appendquery?f=pgeojson&where=1=1
to the URL to request all of the features as GeoJSON.Use dark colors for code blocks map.once("load", () => { // This code runs once the base style has finished loading. map.addSource("trailheads", { type: "geojson", data: "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trailheads/FeatureServer/0/query?f=pgeojson&where=1=1", }); });
-
Add the data attribution for the feature layer source.
- Go to the Trailheads (Santa Monica Mountains) item.
- Scroll down to the Credits (Attribution) section and copy its value.
- Create an
attribution
property and paste the attribution value from the item.Use dark colors for code blocks map.once("load", () => { // This code runs once the base style has finished loading. map.addSource("trailheads", { type: "geojson", data: "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trailheads/FeatureServer/0/query?f=pgeojson&where=1=1", // Attribution text retrieved from https://arcgis.com/home/item.html?id=883cedb8c9fe4524b64d47666ed234a7 attribution: "Los Angeles GeoHub" }); });
Add a circle layer
A layer in MapLibre GL JS is a visual representation of the data within one source. Use a layer of type circle
to display the trailheads.
-
Use
add
to add aLayer circle
layer with idtrailheads-circle
. Setsource
totrailheads
to reference the source you just created. Addpaint
properties to make the circles black.The
type
property defines how it will be displayed. Commonly used layer types includecircle
,line
,fill
andsymbol
(used for text and icons).The
id
property is an identifier you choose. You will need it if you want to manipulate the layer, such as hiding it or changing its properties dynamically.The
source
property references theid
property of the source you just created.The
paint
properties control the visual attributes of the layer and are specific to the type of layer.For more information, see the MapLibre Style Specification.
Use dark colors for code blocks map.once("load", () => { // This code runs once the base style has finished loading. map.addSource("trailheads", { type: "geojson", data: "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trailheads/FeatureServer/0/query?f=pgeojson&where=1=1", // Attribution text retrieved from https://arcgis.com/home/item.html?id=883cedb8c9fe4524b64d47666ed234a7 attribution: "Los Angeles GeoHub" }); map.addLayer({ id: "trailheads-circle", type: "circle", source: "trailheads", paint: { "circle-color": "hsla(0,0%,0%,0.75)", "circle-stroke-width": 1.5, "circle-stroke-color": "white", } }); });
-
At the top right, click Run to display the basemap with trailheads as black dots.
Use clusters to display points
One benefit of using GeoJSON to load points in MapLibre GL JS is you can use clustering. This technique replaces a number of overlapping points with a single point that represents the cluster. It simplifies the visual appearance of the map by reducing detail, particularly at lower zoom levels.
To enable clustering, you pass additional parameters when defining the source: cluster
: true
and the optional parameters cluster
and cluster
.
Points that represent clusters have a cluster
property that is set to true
. You can use this in your trailheads-circle
layer to make those points larger, by using a data-driven expression for circle-radius
. You use the case
and get
expressions for this.
They also have a point
attribute which contains the number of points in the cluster. You can display this as a text label, using a symbol layer.
-
Add
cluster
,cluster
andRadius cluster
attributes to the definition of theMax Zoom trailheads
source.Use dark colors for code blocks map.addSource("trailheads", { type: "geojson", data: "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trailheads/FeatureServer/0/query?f=pgeojson&where=1=1", cluster: true, clusterRadius: 20, // cluster two trailheads if less than 20 pixels apart clusterMaxZoom: 14, // display all trailheads individually from zoom 14 up // Attribution text retrieved from https://arcgis.com/home/item.html?id=883cedb8c9fe4524b64d47666ed234a7 attribution: "Los Angeles GeoHub" });
-
Make each point larger if it represents a cluster.
Use dark colors for code blocks map.addLayer({ id: "trailheads-circle", type: "circle", source: "trailheads", paint: { "circle-color": "hsla(0,0%,0%,0.75)", "circle-stroke-width": 1.5, "circle-stroke-color": "white", "circle-radius": ["case", ["get", "cluster"], 10, 5] // 10 pixels for clusters, 5 pixels otherwise } });
-
Add a symbol layer,
trailheads-cluster-count
. Use the attributepoint
as the value for_count text-field
.Use dark colors for code blocks paint: { "circle-color": "hsla(0,0%,0%,0.75)", "circle-stroke-width": 1.5, "circle-stroke-color": "white", "circle-radius": ["case", ["get", "cluster"], 10, 5] // 10 pixels for clusters, 5 pixels otherwise } }); map.addLayer({ id: "trailheads-cluster-count", type: "symbol", source: "trailheads", layout: { "text-font": ["Arial Bold"], "text-field": ["get", "point_count"], "text-offset": [0, 0.1] // move the label vertically downwards slightly to improve centering }, paint: { "text-color": "white" } });
Run the app
In CodePen, run your code to display the map.
The map should display the trailheads as clusters with a number on a large circle. Zoom in to see the clusters split into smaller clusters, and eventually split into single trailhead features.
What's next?
Learn how to use additional ArcGIS location services in these tutorials:
Query a feature layer (SQL)
Execute a SQL query to access polygon features from a feature layer.
Query a feature layer (spatial)
Execute a spatial query to access polygon features from a feature service.
Style a feature layer
Use data-driven styling to apply symbol colors and styles to feature layers.
Display a pop-up
Display feature attributes in a popup.