Overview
You will learn: how to display the latitude and longitude, scale, and zoom level of the map in a custom widget.
The out-of-the-box Map widget in ArcGIS Experience Builder contains an instance of a View from the ArcGIS Maps SDK for JavaScript. The View
provides a way to interact with the map and to retrieve information about the map location. Using properties and event handlers on the View
you can find the current spatial reference information, latitude and longitude, scale, and zoom level for the map or any screen point location. Once you have this information you can display it in a custom widget, use it to find other locations on the earth, or use it to set the initial extent of your Map when your Experience starts.
In this tutorial, you will access the map widget and display the latitude and longitude of the mouse cursor over the map in your custom widget.
Prerequisites
- Be sure to download, install, and configure ArcGIS Experience Builder.
- Complete the create a starter widget tutorial. It forms the base of this tutorial.
Steps
Get the starter widget
-
Download the Starter Widget template here.
If you have already completed the create a starter widget tutorial, you can start with that. Duplicate the widget folder within /client/your-extensions/widgets.
-
In the ArcGIS Experience Builder folder, extract the zip into the following path: /client/your-extensions/widgets.
Change the widget name
-
In the terminal where the
npm start
is running in the client folder, stop the script by pressingctrl + c
. -
In your file browser, go to the folder where Experience Builder was extracted.
-
In the Experience Builder folder, expand the following path: /client/your-extensions/widgets.
-
In the widgets folder, rename the starter-widget folder to
get-map-coordinates
. -
In the newly-renamed get-map-coordinates folder, open the manifest.json file in the code editor.
-
In the code editor, modify the
name
property toget-map-coordinates
.It is important that the
name
property of themanifest.json
matches the name of the folder for your widget. You can also update the other metadata in themanifest.json
file at this time, like the description of the widget, the author, etc.Use dark colors for code blocks Copy { // *** UPDATE *** // "name": "starter-widget", "name": "get-map-coordinates", "type": "widget", "version": "1.15.0",
-
After the
version
property in manifest.json, add ajimu-arcgis
dependency. Declaring this allows the usage of ArcGIS Maps SDK for JavaScript modules within the widget.Use dark colors for code blocks Copy { "name": "get-map-coordinates", "type": "widget", "version": "1.15.0", // *** ADD *** "dependency": ["jimu-arcgis"],
Implement the settings panel
A settings panel can be implemented to allow Experience authors to customize the widget. The settings panel appears in the right-hand sidebar when a widget is selected in ArcGIS Experience Builder. To create the panel, create a React component.
-
In the widget root folder, create a
config.json
file that contains an empty object.At a later time, widget configuration parameters can be added to this object to store widget setting values.
Use dark colors for code blocks Copy {}
-
In the src folder, create another folder called setting.
-
In the setting folder, create a
setting.tsx
file. -
Open the setting/setting.tsx file and include the following import statements.
Use dark colors for code blocks Copy import { React } from 'jimu-core' import { type AllWidgetSettingProps } from 'jimu-for-builder'
-
Add code to implement the component.
Use dark colors for code blocks Copy const Setting = (props: AllWidgetSettingProps<any>) => { return <div className="widget-setting-demo">This is your starter widget setting area!</div> } export default Setting
-
In the terminal, stop (
ctrl + c
) (if applicable) and start thenpm start
script in the client folder.
Enable selecting a map view data source
In ArcGIS Experience Builder, there can be more than one Map Widget on the page at a time. Because of this, a custom widget must have a section of its Settings Panel that allows the author to choose which map widget to use.
-
In the setting/setting.tsx file, include the
Map
module from theWidget Selector jimu
library.Use dark colors for code blocks Copy import { MapWidgetSelector } from 'jimu-ui/advanced/setting-components'
-
Within the component, define the
on
function.Map Widget Selected Use dark colors for code blocks Copy // *** ADD *** const onMapWidgetSelected = (useMapWidgetIds: string[]) => { props.onSettingChange({ id: props.id, useMapWidgetIds: useMapWidgetIds }) } return <div className="widget-setting-demo">This is your starter widget setting area!</div>;
-
In the
return()
statement, add a tag representing theMap
.Widget Selector Use dark colors for code blocks Copy return ( <div className="widget-setting-demo"> <MapWidgetSelector useMapWidgetIds={props.useMapWidgetIds} onSelect={onMapWidgetSelected} /> </div> )
Access the map
In the previous step, the settings panel was enhanced to allow the Map widget to be selected. The map object can be accessed using the Jimu
.
-
In the widget.tsx file, add the
Jimu
andMap View Component Jimu
types from theMap View jimu-arcgis
library, and destructure the React variable to get access to theget
import.State Use dark colors for code blocks Copy import { React, type AllWidgetProps } from 'jimu-core' /** ADD: **/ import { JimuMapViewComponent, type JimuMapView } from 'jimu-arcgis' const { useState } = React
-
To display the
latitude
andlongitude
property of the mouse, the mouse pointer state must be tracked. Within the component, set up the state usinguse
.State() Use dark colors for code blocks Copy const { useState } = React const Widget = (props: AllWidgetProps<any>) => { // *** ADD ***// const [latitude, setLatitude] = useState<string>('') const [longitude, setLongitude] = useState<string>('') return (
-
In the
return
section, add theJimu
to the JSX markup.Map View Component The first two lines of the added code (
{props.use
) are how to use conditionals in JSX. This is basically saying "only add the JimuMapViewComponent if the Experience author has chosen a valid map widget in the settings panel."Map Widget Ids &&... Use dark colors for code blocks Copy return ( <div className="widget-starter jimu-widget"> {props.useMapWidgetIds && props.useMapWidgetIds.length === 1 && ( <JimuMapViewComponent useMapWidgetId={props.useMapWidgetIds?.[0]} onActiveViewChange={activeViewChangeHandler} /> )} </div> )
-
At the top of
widget.tsx
, import thePoint
class, which will be used in the next step.Use dark colors for code blocks Copy import Point from 'esri/geometry/Point'
-
Define the
active
function, just below theView Change Handler set
commands. This function will be called once - when the map is ready. In this function, set up a listener to update the latitude and longitude state every time theState pointer-move
event is triggered.Create a Point object using the incoming mouse x and y position and then convert the coordinates to map coordinates using the
view.to
function. Set the state of the latitude and longitude to display the coordinate values.Map() Use dark colors for code blocks Copy /** ADD: **/ const activeViewChangeHandler = (jmv: JimuMapView) => { if (jmv) { // When the pointer moves, take the pointer location and create a Point // Geometry out of it (`view.toMap(...)`), then update the state. jmv.view.on('pointer-move', (evt) => { const point: Point = jmv.view.toMap({ x: evt.x, y: evt.y }) setLatitude(point.latitude.toFixed(3)) setLongitude(point.longitude.toFixed(3)) }) } }
Display the latitude and longitude coordinates
Now that the latitude and longitude is stored in the component's state, you can easily display the values in the the JSX that is returned from the function component.
-
In the
return()
statement (right after theJimu
placed earlier), add JSX to display the latitude and longitude.Map View Component Use dark colors for code blocks Copy return ( <div className="widget-starter jimu-widget"> {props.useMapWidgetIds && props.useMapWidgetIds.length === 1 && ( <JimuMapViewComponent useMapWidgetId={props.useMapWidgetIds?.[0]} onActiveViewChange={activeViewChangeHandler} /> )} {/* *** ADD: *** */} <p> Lat/Lon: {latitude} {longitude} </p> </div> );
Test the widget
Once the code changes have been made, you can test your widget by running ArcGIS Experience Builder and viewing your experience.
-
In a web browser, go to Experience Builder. e.g. https://localhost:3001
If Experience Builder did not open a tab for you, browse to https://localhost:3001. If you get a "Invalid SSL Certificate" issue, click "Proceed Anyway".
-
In Experience Builder, click Create New to create a new experience page.
-
Click the Create button on the Blank scrolling template.
-
The Insert widget panel is opened for you. From there, drag a Map widget and your new Get Map Coordinates widget onto the experience.
The widget may show an invalid icon right now. That's ok - you have not created one yet! -
In the widget settings panel, choose Map from the map selection dropdown.
-
In the Experience Builder toolbar, click Save then Preview and the experience will open in a new browser tab with your custom widget and a map. Mouse over the map to see the latitude and longitude of the cursor location.
Congratulations, you're done!
In the Experience Builder preview, hover over the map to see the latitude and longitude values dynamically change in the custom widget. Compare your widget with our completed widget, and see the top of this page for an example for how the Experience should look.