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!
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> } }
There are two approaches:
This video provides a great demo: https://www.youtube.com/watch?v=aVjtFKkF9q8
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.