You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ol-Cesium中启用OpenLayers的map.forEachFeatureAtPixel功能

解决OpenLayers + ol-Cesium 3D模式下要素点击信息展示失效问题

我在OpenLayers中加载多份GeoJSON图层,实现了displayFeatureInfo函数用于点击多边形展示要素信息,同时通过ol-Cesium实现2D/3D视图切换,但切换到3D后点击事件失效,图层筛选功能正常。经过调试,以下是可用的实现方案:

核心思路

3D模式下OpenLayers原生singleclick事件无法直接拾取Cesium场景中的要素,需要结合ol-Cesium的特性:ol-Cesium渲染OpenLayers矢量图层时,会给Cesium的Primitive对象绑定olFeature属性,关联回原始OpenLayers要素。通过监听Cesium的点击事件,拾取该属性即可复用原有的displayFeatureInfo函数。

完整代码实现

// 初始化OpenLayers地图
const map = new ol.Map({
  target: 'map',
  layers: [
    // 示例GeoJSON图层,替换为你的实际图层
    new ol.layer.Vector({
      source: new ol.source.Vector({
        url: 'layer-1.geojson',
        format: new ol.format.GeoJSON()
      })
    }),
    new ol.layer.Vector({
      source: new ol.source.Vector({
        url: 'layer-2.geojson',
        format: new ol.format.GeoJSON()
      })
    })
  ],
  view: new ol.View({
    center: ol.proj.fromLonLat([116.397, 39.908]),
    zoom: 10
  })
});

// 初始化ol-Cesium实例
const ol3d = new olcs.OLCesium({map: map});
const scene = ol3d.getCesiumScene();

// 2D/3D切换按钮逻辑
document.getElementById('toggle-3d').addEventListener('click', () => {
  ol3d.setEnabled(!ol3d.getEnabled());
});

// 要素信息展示函数(复用原有逻辑)
function displayFeatureInfo(feature) {
  if (feature) {
    // 替换为你的信息展示逻辑,比如弹窗、页面元素更新
    console.log('要素详情:', feature.getProperties());
    document.getElementById('feature-info').innerHTML = `
      <h3>要素信息</h3>
      <p>ID: ${feature.getId()}</p>
      <p>名称: ${feature.get('name') || '无'}</p>
    `;
  } else {
    document.getElementById('feature-info').innerHTML = '<p>未选中任何要素</p>';
  }
}

// 动态切换2D/3D模式的点击事件监听
let activeClickHandler;

// 监听ol-Cesium启用状态变化
ol3d.on('change:enabled', () => {
  const is3dActive = ol3d.getEnabled();
  
  // 移除之前的事件监听
  if (activeClickHandler) {
    is3dActive 
      ? scene.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)
      : map.un('singleclick', activeClickHandler);
  }

  if (is3dActive) {
    // 3D模式:监听Cesium点击事件
    activeClickHandler = scene.screenSpaceEventHandler.setInputAction((event) => {
      const pickResult = scene.pick(event.position);
      if (pickResult?.primitive?.olFeature) {
        displayFeatureInfo(pickResult.primitive.olFeature);
      } else {
        displayFeatureInfo(null);
      }
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  } else {
    // 2D模式:使用OpenLayers原生点击事件
    activeClickHandler = map.on('singleclick', (evt) => {
      const feature = map.forEachFeatureAtPixel(evt.pixel, f => f);
      displayFeatureInfo(feature);
    });
  }
});

// 初始绑定2D模式点击事件
activeClickHandler = map.on('singleclick', (evt) => {
  const feature = map.forEachFeatureAtPixel(evt.pixel, f => f);
  displayFeatureInfo(feature);
});

关键说明

  • 图层显示/隐藏筛选功能不受影响,因为ol-Cesium会自动同步OpenLayers图层的可见性到Cesium场景。
  • 通过change:enabled事件动态切换事件监听逻辑,确保2D/3D模式下点击功能无缝衔接。

内容的提问来源于stack exchange,提问作者Elena Politi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 16:25:33