I understand we can restrict a web map's navigation extent as a configurable option in ArcGIS Online, but there aren't any such options in Enterprise 10.9.1 with which I'm working.
Does anyone have any direction on how I might achieve restricting the pan and zoom options within my Experience Builder Developer (v1.13) app to the area of interest?
Many thanks in advance!
There are two approaches:
This video provides a great demo: https://www.youtube.com/watch?v=aVjtFKkF9q8
ExB Dev 1.13. Here is the widget.tsx code for a custom widget that restricts the map view
/** Licensing Copyright 2022 Esri Modified from 'map-view' sample code widget (JR, YH) Map view widget that will restrict the map view to the minZoomScale specified and restrict panning to the original extent of the map */ import { React, jimuHistory, DataSourceComponent, type AllWidgetProps, type IMState, type IMUrlParameters } from 'jimu-core' import MapView from 'esri/views/MapView' import type WebMap from 'esri/WebMap' import Extent from 'esri/geometry/Extent' import Point from "@arcgis/core/geometry/Point.js"; import { MapViewManager, type WebMapDataSource } from 'jimu-arcgis' // Bring the 'Home' and 'Scalebar' properties into the map import Home from '@arcgis/core/widgets/Home'; import ScaleBar from '@arcgis/core/widgets/ScaleBar'; import Popup from "@arcgis/core/widgets/Popup.js"; // Alert component state interface State { isValidCenter: boolean; } // Not sure what the following does from the sample 'map-view' widget from which this code was modified queries the URL REST parameters for a mapview extent interface ExtraProps { queryObject: IMUrlParameters } // Set a minimum zoom scale to prevent user from zooming out beyond the valid extent const minZoomScale = 6 export default class Widget extends React.PureComponent<AllWidgetProps<unknown> & ExtraProps, State> { mapContainer = React.createRef<HTMLDivElement>() mapView: MapView webMap: WebMap extentWatch: __esri.WatchHandle mvManager: MapViewManager = MapViewManager.getInstance(); constructor(props) { super(props); this.state = { isValidCenter: true, // Initialize state with default value }; } static mapExtraStateProps = (state: IMState): ExtraProps => { return { queryObject: state.queryObject } } onDsCreated = (webmapDs: WebMapDataSource) => { console.log("Webmap loaded") if (!webmapDs) { console.log("Webmap not initialized") return } if (!this.mvManager.getJimuMapViewById(this.props.id)) { const options: __esri.MapViewProperties = { map: webmapDs.map, container: this.mapContainer.current, constraints:{ minZoom: minZoomScale, snapToZoom: false } } console.log("minZoom set:", minZoomScale) this.mvManager.createJimuMapView({ mapWidgetId: this.props.id, view: new MapView(options), dataSourceId: webmapDs.id, isActive: true, mapViewManager: this.mvManager }).then(jimuMapView => { // Create and add the Home widget to the map view const homeWidget = new Home({ view: jimuMapView.view }); jimuMapView.view.ui.add(homeWidget, 'top-left'); // Need to explictly cast the view to --esri.MapViewProperties // to ensure type compatibility with the scalebar const mapView = jimuMapView.view as __esri.MapViewProperties; // Create and add the Scalebar widget to the map view const scaleBarWidget = new ScaleBar({ view: mapView }); jimuMapView.view.ui.add(scaleBarWidget,'bottom-left') //console.log(mapView.extent) const view = jimuMapView.view as __esri.MapView; const extentLimit = view.extent.clone(); view.constraints.geometry = extentLimit }) } } mapNode = <div className="widget-map" style={{ width: '100%', height: '100%' }} ref={this.mapContainer}></div> render () { if (!this.props.useDataSources || this.props.useDataSources.length === 0) { return 'Select a webmap in the settings panel' } return <DataSourceComponent useDataSource={this.props.useDataSources[0]} onDataSourceCreated={this.onDsCreated}> {this.mapNode} </DataSourceComponent> } }
Signed in members can post, follow updates, and more. New here? Register a free account.
Find useful guides, FAQs, and documents to help you navigate and make the most of Esri Community.