如何修复自动平移叠加层时错误调用“选择”交互的点击?

问题描述 投票:0回答:1

如果我将叠加层的

autopan
设置为 true,则当我单击红色圆圈时:

  1. 出现叠加层
  2. 自动平移滚动地图,使整个叠加层可见
  3. Select
    交互获取点击事件并导致矩形变成红色

如果

autopan
为 false,当我单击红色圆圈时,会出现叠加层,但不会调用
Select
交互。

我认为发生的事情是在我单击后,自动平移移动物体,当

Select
交互检查是否需要处理单击时,由于红色圆圈而阻止它的代码无法阻止它,因为红色圆圈移动了。

可能需要在完整页面视图中查看代码片段,以便可以将红色圆圈放置在地图视图底部附近,并且自动平移可以导致显示整个叠加层。 我该如何解决这个问题?

//
// Create the Rectangle
//
function createRectangle(layerName) {
  const features = [];

  const feature = {
    type: "Feature",
    geometry: {
      type: "Polygon",
      coordinates: [
        [
          [30, 5],
          [30, 30],
          [85, 30],
          [85, 5]
        ]
      ]
    },
    properties: {
      id: `${layerName}`,
      layerName
    }
  };

  features.push(feature);

  const json = {
    type: "FeatureCollection",
    features
  };

  return json;
}

const rectangle = createRectangle("small");
const rectangleStyle = new ol.style.Style({
  stroke: new ol.style.Stroke({
    color: "hsla(120, 50%, 100%, 1.0)",
    width: 5
  }),
  fill: new ol.style.Fill({
    color: "hsla(120, 50%, 50%, 0.50)"
  })
});

const rectangleVectorLayer = new ol.layer.Vector({
  source: new ol.source.Vector({
    features: new ol.format.GeoJSON({
      featureProjection: "EPSG:4326" // 4326 3857
    }).readFeatures(rectangle)
  }),
  style: (feature) => rectangleStyle,
  zIndex: 4,
  properties: {
    name: "small"
  }
});

//
// Create the marker which will have the overlay attached
//

const markerStyle = new ol.style.Style({
  image: new ol.style.Circle({
    radius: 12,
    fill: new ol.style.Fill({ color: "#e00" }),
    stroke: new ol.style.Stroke({
      color: "black",
      width: 2
    })
  })
});

const markerLayer = new ol.layer.Vector({
  source: new ol.source.Vector({
    features: [
      new ol.Feature({
        geometry: new ol.geom.Point([55, 25])
      })
    ]
  }),
  style: (feature) => markerStyle,
  zIndex: 10
});

//
// Create OSM Layer
//

const osmLayer = new ol.layer.Tile({
  source: new ol.source.OSM()
});

//
// Create the Map
//

const map = new ol.Map({
  target: "map",
  layers: [osmLayer, rectangleVectorLayer, markerLayer],
  view: new ol.View({
    projection: "EPSG:4326",
    center: [55, 30],
    zoom: 5
  })
});

//
//
//

const selectedStyle = new ol.style.Style({
  fill: new ol.style.Fill({
    color: "hsla(0, 50%, 50%, 0.5)"
  }),
  stroke: new ol.style.Stroke({
    color: "hsla(0, 50%, 100%, 1)",
    width: 3
  }),
  zIndex: 1
});

const rectangleLayerInteraction = new ol.interaction.Select({
  style: (feature) => {
    return selectedStyle;
  },
  layers: [rectangleVectorLayer],
  condition: function (e) {
    const isSingleClick = ol.events.condition.singleClick(e);
    let passed = false;

    if (isSingleClick) {
      console.group();
      const features = map.getFeaturesAtPixel(e.pixel, {
        layerFilter: function (l) {
          //console.log(
          //  "rectangle layerFilter",
          //  l.getZIndex(),
          //  rectangleVectorLayer.getZIndex(),
          //  l.getZIndex() > rectangleVectorLayer.getZIndex()
          //);
          return l.getZIndex() > rectangleVectorLayer.getZIndex();
        }
      });
      const noFeatures = features.length === 0;

      passed = isSingleClick && noFeatures;

      //console.log("condition features", features);
      //console.log("condition noFeatures", noFeatures);
      //console.log("condition isSingleClick", isSingleClick);
      //console.log("condition passed", passed);

      console.groupEnd();
    }

    return passed;
  }
});

map.addInteraction(rectangleLayerInteraction);

//
// Add overlay and handler
//

const popup = new ol.Overlay({
  element: document.getElementById("popup"),
  autoPan: true
});

map.addOverlay(popup);

const markerLayerUID = ol.util.getUid(markerLayer);

map.on("click", (e) => {
  const hitFeatures = map.getFeaturesAtPixel(e.pixel, {
    layerFilter: (layer) => {
      return ol.util.getUid(layer) === markerLayerUID;
    }
  });

  //console.log("hitFeatures", hitFeatures);

  if (hitFeatures.length === 1) {
    const position = ol.extent.getBottomLeft(
      hitFeatures[0].getGeometry().getExtent()
    );
    popup.setPosition(position);
  } else {
    popup.setPosition(undefined);
  }
});
#map {
  height: 512px;
  width: 1024px;
}

.popup {
  width: 200px;
  height: 300px;
  background-color: blue;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/openlayers/7.3.0/ol.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/openlayers/7.3.0/dist/ol.min.js"></script>

<div id="map"></div>

<div id="popup" class="popup"></div>

openlayers
1个回答
0
投票

您可以检查地图是否在您选择的条件下动画

if (isSingleClick && !map.getView().getAnimating()) {
© www.soinside.com 2019 - 2024. All rights reserved.