Skip To Content ArcGIS for Developers Sign In Dashboard

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 API 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, longitude, scale, and zoom level of the map in your custom widget.

Before you begin

Install ArcGIS Experience Builder

Be sure to download, install, and configure ArcGIS Experience Builder Developer Edition.

Steps

Get the starter widget

  1. Download the Starter Widget template here.

  2. In the Experience Builder folder, extract the zip into the following path: /client/your-extensions/widgets.

Change the widget name

  1. In the terminal where the npm start is running in the client folder, stop the script by pressing ctrl + c.

  2. In your file browser, go to the folder where Experience Builder was extracted.

  3. In the Experience Builder folder, expand the following path: /client/your-extensions/widgets.

  4. In the widgets folder, rename the starter-widget folder to get-map-coordinates.

  5. In the newly-renamed get-map-coordinates folder, open the manifest.json file in the code editor.

  6. In the code editor, modify the name property to get-map-coordinates.

     {
       // *** UPDATE ***
       // "name": "starter-widget",
       "name": "get-map-coordinates",
       "type": "widget",
       "version": "1.0.0",
    
  7. After the version property in manifest.json, add a jimu-arcgis dependency. Declaring this allows the usage of ArcGIS API for JavaScript modules within the widget.

    {
       "name": "get-map-coordinates",
       "type": "widget",
       "version": "1.0.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 Experience Builder. To create the panel, implement the BaseWidgetSetting class.

  1. In the widget root folder, create a config.json file that contains an empty object.

{}
  1. In the src folder, create another folder called setting.
  2. In the setting folder, create a setting.tsx file.
  3. Open the setting/setting.tsx file and include the following import statements.
/** @jsx jsx */
import { React, jsx } from "jimu-core";
import { BaseWidgetSetting, AllWidgetSettingProps } from "jimu-for-builder";
  1. Add code to implement BaseWidgetSetting.
export default class Setting extends BaseWidgetSetting<AllWidgetSettingProps<any>, any> {
  render() {
    return <div className="widget-setting-demo">This is your starter widget setting area!</div>;
  }
}
  1. In the terminal, stop (ctrl + c) (if applicable) and start the npm start script in the client folder.

Enable selecting a map view data source

In 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.

  1. In the setting/setting.tsx file, include the JimuMapViewSelector module from the jimu library.

    import { JimuMapViewSelector } from "jimu-ui/setting-components";
    
  2. Before the render function, define the onMapWidgetSelected function.

     // *** ADD ***
     onMapWidgetSelected = (useMapWidgetIds: string[]) => {
       this.props.onSettingChange({
         id: this.props.id,
         useMapWidgetIds: useMapWidgetIds
       });
     };
     render() {
       return <div className="widget-setting-demo">This is your starter widget setting area!</div>;
     }
    
  3. In the render function, in the return() statement, add a tag representing the JimuMapViewSelector.

     render() {
       return <div className="widget-setting-demo">
         <JimuMapViewSelector
           useMapWidgetIds={this.props.useMapWidgetIds}
           onSelect={this.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 JimuMapViewComponent.

  1. In the Widget.tsx file, add the JimuMapViewComponent and the JimuMapView type from the jimu library.

    import { JimuMapViewComponent, JimuMapView } from "jimu-arcgis";
    
  2. Before the render function, set up the default state.

     export default class Widget extends BaseWidget<AllWidgetProps<any>, any> {
     // *** ADD ***//
     state = {
       jimuMapView: null
     };
     render() {
    
  3. Add a function to update the state every time the JimuMapView data source changes.

    state = {
     jimuMapView: null
    };
    // *** ADD ***//
    activeViewChangeHandler = (jmv: JimuMapView) => {
      if (jmv) {
        this.setState({
          jimuMapView: jmv
        });
      }
    };
    
  4. In the render function, add the JimuMapViewComponent to the JSX markup.

     render() {
       return (
         <div className="widget-starter jimu-widget">
           {/* *** ADD *** */}
           {this.props.hasOwnProperty("useMapWidgetIds") &&
             this.props.useMapWidgetIds &&
             this.props.useMapWidgetIds.length === 1 && (
               <JimuMapViewComponent
                 useMapWidgetIds={this.props.useMapWidgetIds}
                 onActiveViewChange={this.activeViewChangeHandler}
               />
             )
           }
         </div>
       );
     }
    

Track the latitude and longitude

  1. To display the latitude and longitude property of the mouse, the mouse pointer state must be tracked. In the Widget.tsx file, add latitude and longitude properties to the state object.

     state = {
       jimuMapView: null,
       //*** ADD ***//
       latitude: "",
       longitude: ""
     };
    
  2. At the top of the file, import the Point class.

    import Point = require("esri/geometry/Point");
    
  3. In the activeViewChangeHandler function, just below the setState command, get the latitude and longitude and update the state every time the pointer-move event is triggered.

     jmv.view.on("pointer-move", evt => {
       const point: Point = this.state.jimuMapView.view.toMap({
         x: evt.x,
         y: evt.y
       });
       this.setState({
         latitude: point.latitude.toFixed(3),
         longitude: point.longitude.toFixed(3)
       });
     });
    

Display the latitude and longitude coordinates

With that latitude and longitude in the component's state, you can easily display the values in the render function.

  1. In the render function, in the return() statement (right after the JimuMapViewComponent placed earlier), add JSX to display the latitude and longitude.
     render() {
       return (
         <div className="widget-starter jimu-widget">
           {this.props.hasOwnProperty("useMapWidgetIds") &&
             this.props.useMapWidgetIds &&
             this.props.useMapWidgetIds.length === 1 && (
               <JimuMapViewComponent
                 useMapWidgetIds={this.props.useMapWidgetIds}
                 onActiveViewChange={this.activeViewChangeHandler}
               />
             )
           }
           {/* *** ADD *** */}
           <p>Lat/Lon: {this.state.latitude} {this.state.longitude}</p>
         </div>
       );
     }
    

Test the widget

Once the code changes have been made, you can test your widget by running Experience Builder and viewing your Experience.

  1. In a web browser, go to Experience Builder. e.g. https://localhost:3001

  2. In Experience Builder, click Create New to create a new experience page.

  3. Click the Create button on the Blank scrolling page template.

  4. Click the Insert widget button, and drag a Map widget and your new Get Map Coordinates widget onto the experience.

  5. In the widget settings panel, choose Map 1 from the map selection dropdown.

  6. 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.

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.

Challenge

Add "zoom level" and "scale"

Add the map's zoom level and scale to the display right next to the latitude and longitude. (Challenge solution)