ArcGIS中如何编程触发marker点击事件实现侧边栏位置联动
问题场景
开发中基于ArcGIS实现点位标记功能:
- 地图上根据经纬度渲染点位标记(marker)
- 页面配置导航抽屉,抽屉内罗列全部位置项
- 需要实现交互:点击抽屉内任意位置项,自动触发地图上对应关联marker的点击事件
之前尝试通过emit方法触发点击事件返回false,未实现预期效果。
现有代码
Marker绘制逻辑
let marker = new Graphic({ geometry: { longitude: item.longitude, latitude: item.latitude, type: 'point', spatialReference: { wkid: 3857 }, }, symbol: this._Constants.MARKER_FLAT, popupTemplate: { title: item.name, content: function () { var div = document.createElement('div'); div.innerHTML = `<p>Testing</p>`; return div; }, }, }); marker.setAttribute('id', String(item.id)); marker.setAttribute('name', String(item.name)); this.mapView.graphics.add(marker); this.marker = marker;
之前尝试的错误触发逻辑
if ( // this.mapView.emit('click', { // 试过这个写法也不行 this.mapView.map.emit('click', { mapPoint: this.marker, }) ) { console.log('Triggered'); } else { console.log('NOT Triggered'); }
实现方案
之前触发失败有两个核心原因:
- ArcGIS的
click事件绑定在MapView实例上,而非map对象上;且事件要求传入的mapPoint是合法的Point几何对象,直接传入Graphic(marker实例)不符合参数规范 - 手动派发的原生click事件不会自动触发MapView内部的点位命中检测逻辑,就算参数传对也不会自动弹出marker绑定的弹窗
推荐用更稳定的直接调用API方式实现,不需要模拟点击事件,效果和手动点击marker完全一致:
- 首先建立markerID和marker实例的映射关系,不要只把最后一个marker赋值给
this.marker
// 初始化时提前创建映射表 this.markerMap = new Map() // 每次创建marker添加到图层后,存入映射表 this.mapView.graphics.add(marker); this.markerMap.set(String(item.id), marker)
- 实现抽屉项点击的处理逻辑
/** * 抽屉位置项点击回调 * @param {string|number} selectedId 选中项的ID */ async function onDrawerItemClick(selectedId) { const targetMarker = this.markerMap.get(String(selectedId)) if (!targetMarker) return // 地图平滑定位到目标点位,可根据业务调整缩放级别 await this.mapView.goTo({ target: targetMarker.geometry, zoom: 15 }) // 直接打开目标marker绑定的弹窗,和手动点击marker的效果完全一致 this.mapView.popup.open({ features: [targetMarker], location: targetMarker.geometry }) }
如果一定要走模拟点击的逻辑,需要正确构造事件参数,注意该方式受ArcGIS JS API版本影响较大,不推荐优先使用:
async function simulateMarkerClick(selectedId) { const targetMarker = this.markerMap.get(String(selectedId)) if (!targetMarker) return await this.mapView.goTo(targetMarker.geometry) // 将地理坐标转为屏幕像素坐标 const screenPoint = this.mapView.toScreen(targetMarker.geometry) // 按MapView要求构造完整的click事件参数 const triggerRes = this.mapView.emit('click', { mapPoint: targetMarker.geometry, x: screenPoint.x, y: screenPoint.y, button: 0, buttons: 0, type: 'click', stopPropagation: () => {}, timestamp: Date.now() }) console.log(triggerRes ? '事件触发成功' : '事件触发失败') }
注意:现有代码中几何坐标系配置存在问题,传入的经纬度属于WGS84坐标系(wkid:4326),如果直接指定spatialReference为3857(Web墨卡托)会导致点位偏移,需要提前做坐标转换,或者将spatialReference的wkid改为4326。
内容的提问来源于stack exchange,提问作者Sanoop Surendran
相关产品推荐
相关产品推荐

