Learn how to show places on a basemap.
The ArcGIS Basemap Styles service allows you to show or hide place locations in a basemap style. The places represent businesses, services, landmarks, and other places of interest (POIs) all over the world. When places are active, each is displayed with an icon and a name label.
In this tutorial, you set the basemap style preferences to show places and return place details from the ArcGIS Places service with ArcGIS REST JS.
Prerequisites
You need an ArcGIS Location Platform 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.
Display attributed places
The arcgis/navigation style contains a set of places that show up on the map based on the current zoom level and extent. The places displayed can be refined with the places parameter to show all places, no places, or places with attributes. The main attributes returned with the attributed value are name and esri.
-
Update the basemap style to
arcgis/navigationand set style preferences to display places by appending&places=attributedin the basemap URL.Use dark colors for code blocks const basemapId = "arcgis/navigation"; const basemapURL = `https://basemapstyles-api.arcgis.com/arcgis/rest/services/styles/v2/styles/${basemapId}?token=${accessToken}&places=attributed`; -
Change the map's viewpoint to
[-118.46651, 33.98621]with a zoom of16to focus on West Hollywood, California.Use dark colors for code blocks const map = new ol.Map({ target: "map" }); map.setView( new ol.View({ center: ol.proj.fromLonLat([-118.33873, 34.10151]), zoom: 16 }) ); const basemapId = "arcgis/navigation"; const basemapURL = `https://basemapstyles-api.arcgis.com/arcgis/rest/services/styles/v2/styles/${basemapId}?token=${accessToken}&places=attributed`;
Add script references
Each attributed place contains an esri. You can use the place ID with ArcGIS REST JS to call the Places service place/place operation and get additional attributes. You can display the place information with the ol-popup and Calcite libraries.
-
Reference the
requestandplacespackages from ArcGIS REST JS, theol-popup, and the Calcite Components libraries.Use dark colors for code blocks <!-- Load ArcGIS REST JS --> <script src="https://unpkg.com/@esri/arcgis-rest-request@4/dist/bundled/request.umd.js"></script> <script src="https://unpkg.com/@esri/arcgis-rest-places@1/dist/bundled/places.umd.js"></script> <!-- Calcite components --> <script type="module" src="https://js.arcgis.com/calcite-components/2.12.1/calcite.esm.js"></script> <link rel="stylesheet" href="https://js.arcgis.com/calcite-components/2.12.1/calcite.css"> <!-- OpenLayers popup --> <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">
Update interface
Create an HTML results panel using the <calcite-panel and <calcite-block elements. This panel will be hidden by default, and display when place details are returned from the Places service.
-
Inside
<body, copy and paste the following HTML to create a basic results panel that is hidden by default.> Use dark colors for code blocks <div id="map"></div> <calcite-panel id="panelPlace" closable hidden> <calcite-block id="addressLabel" class="hide" heading="Address" scale="l" > <calcite-icon slot="icon" icon="map-pin"></calcite-icon> </calcite-block> <calcite-block id="phoneLabel" class="hide" heading="Phone" scale="l" > <calcite-icon slot="icon" icon="mobile"></calcite-icon> </calcite-block> <calcite-block id="emailLabel" class="hide" heading="Email" scale="l" > <calcite-icon slot="icon" icon="email-address"></calcite-icon> </calcite-block> <calcite-block id="websiteLabel" class="hide" heading="Website" scale="l" > <calcite-icon slot="icon" icon="information"></calcite-icon> </calcite-block> <calcite-block id="facebookLabel" class="hide" heading="Facebook" scale="l" > <calcite-icon slot="icon" icon="speech-bubble-social"></calcite-icon> </calcite-block> <calcite-block id="twitterLabel" class="hide" heading="Twitter" scale="l" > <calcite-icon slot="icon" icon="speech-bubbles"></calcite-icon> </calcite-block> <calcite-block id="instagramLabel" class="hide" heading="Instagram" scale="l" > <calcite-icon slot="icon" icon="camera"></calcite-icon> </calcite-block> </calcite-panel> -
Add styling for the results panel.
Use dark colors for code blocks #panelPlace { position: absolute; top: 10px; right: 10px; width: 350px; height: calc(100% - 75px); } .hide { display: none; }
Get place details
When a user hovers over a POI, display a popup with the place's name and ID. When a user clicks on a POI, use the get method from ArcGIS REST JS to request detailed attributes for the selected place and display them in a Calcite panel.
-
Initialize a
Popupobject and add it to the map as an overlay.Use dark colors for code blocks const popup = new Popup({ autoPan: false }); map.addOverlay(popup); -
Listen for the
pointermoveevent on the map. Useforto get the feature under the mouse. If the feature containsEach Feature At Pixel esri, show a popup with the place's information._place _id Use dark colors for code blocks const popup = new Popup({ autoPan: false }); map.addOverlay(popup); map.on("pointermove", function (e) { if (e.dragging) return; const feature = map.forEachFeatureAtPixel(e.pixel, (f) => f); if (feature && feature.get("esri_place_id")) { map.getTargetElement().style.cursor = "pointer"; popup.show( e.coordinate, `<b>Place ID:</b> ${feature.get("esri_place_id")}` ); } else { map.getTargetElement().style.cursor = ""; popup.hide(); } }); -
Listen for the
clickevent on the feature. Store its properties and make the Calcite panel visible.Use dark colors for code blocks const panel = document.getElementById("panelPlace"); map.on("click", function (evt) { let placeFeature = null; map.forEachFeatureAtPixel(evt.pixel, function (feature) { const props = feature.getProperties(); if (props.esri_place_id) { placeFeature = props; } }); if (placeFeature) { const placeId = placeFeature.esri_place_id; panel.hidden = false; panel.closed = false; }); -
Use the ArcGIS REST JS
getmethod to fetch detailed information for that place.Place Details Use dark colors for code blocks const panel = document.getElementById("panelPlace"); map.on("click", function (evt) { let placeFeature = null; map.forEachFeatureAtPixel(evt.pixel, function (feature) { const props = feature.getProperties(); if (props.esri_place_id) { placeFeature = props; } }); if (placeFeature) { const placeId = placeFeature.esri_place_id; panel.hidden = false; panel.closed = false; arcgisRest.getPlaceDetails({ placeId, requestedFields: "all", authentication }).then((response) => { const details = response.placeDetails; setPlaceDetails(details); }); } }); -
Create a
showto populate the Calcite panel with attributes from the Places service response. Add a listener for the panel’sPlace Details calciteevent to hide it when closed.Panel Close Use dark colors for code blocks function setPlaceDetails(placeDetails) { panel.setAttribute("heading", placeDetails.name); setElement("addressLabel", placeDetails?.address?.streetAddress); setElement("phoneLabel", placeDetails?.contactInfo?.telephone); setElement("emailLabel", placeDetails?.contactInfo?.email); setElement("websiteLabel", placeDetails?.contactInfo?.website?.split("://")[1]?.split("/")[0]); setElement("facebookLabel", placeDetails?.socialMedia?.facebookId ? `facebook.com/${placeDetails.socialMedia.facebookId}` : null); setElement("twitterLabel", placeDetails?.socialMedia?.twitter ? `twitter.com/${placeDetails.socialMedia.twitter}` : null); setElement("instagramLabel", placeDetails?.socialMedia?.instagram ? `instagram.com/${placeDetails.socialMedia.instagram}` : null); panel.addEventListener("calcitePanelClose", function () { panel.hidden = true; panel.closed = true; }); } -
Create a helper function
setthat updates each Calcite label’s visibility and description. This ensures that only fields with values are displayed in the panel.Element Use dark colors for code blocks function setElement(id, value) { const el = document.getElementById(id); if (value) { el.classList.remove("hide"); el.description = value; } else { el.classList.add("hide"); el.description = ""; } }
Run the app
Run the app.
The map should display thearcgis/navigation basemap style with attributed places. When you hover over a place, a popup should appear that contains the place name and ID. When you click on a POI, the Places service returns details about it.
What's next?
Learn how to use additional location services in these tutorials:


