OL3 - 无法检测对功能的点击

OL3 - Trouble detecting clicks on features

我的目标是为我在 OpenLayers 3 中的工作创建一个具有多个图层的地图。一个人从 OpenStreetMaps 获取基本信息。另一个将是显示区域轮廓的透明层(尚未完成)。第三个是我遇到的问题,它显示了一系列图标,代表地图上 divudal 感兴趣的站点。我从作为单独脚本文件包含的 JS 数据结构加载站点。我已经设法让我的代码添加出现在正确 lat/lon 处的功能。我的下一步是让 HTML 框 (div) 在他们单击图标(以显示站点的详细信息)时出现在地图前面。但是,我无法让它工作。为我的菜鸟编码道歉,但它真的让我难住了,我真的很感激任何帮助。

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="ol.css" type="text/css">
    <link rel="stylesheet" href="map.css" type="text/css">
    <script src="ol.js" type="text/javascript"></script>
    <script src="sites.js" type="text/javascript"></script>
<script type="text/javascript">


function buildLayerFromSites(allSites)
// allSites is just an array of data structures
{
  var count, site;
  // for each site in the array, make a feature
  for (count=0;count<allSites.length;count++)
  {
    geom = new ol.geom.Point(ol.proj.fromLonLat([allSites[count].longitude,allSites[count].latitude]));
    site = new ol.Feature(geom);
    site.Name = allSites[count].siteName; // <-- can I assign further details in the structure like this?


    var siteStyle = new ol.style.Style({
      image: new ol.style.Icon ({
        src: 'icon-blue.png',
        scale: 0.1,
        opacity: 0.9,
        })
      })
    site.setStyle(siteStyle);
    siteFeatures[count] = site;
  }
  siteSource = new ol.source.Vector ({
    features: siteFeatures
  })
  siteLayer = new ol.layer.Vector({
    source: siteSource
  });
  map.addLayer(siteLayer);
}

</script>
    <title>Map</title>
  </head><body>
...
<div id="map" class="map">
...

<script type="text/javascript">


var map = new ol.Map({
  target: 'map',
  layers: [
    new ol.layer.Tile({
      source: new ol.source.OSM()
    })
  ],
  view: new ol.View({
    center: ol.proj.fromLonLat([115.51, -31.57]),
    zoom: 8
  })
});
buildLayerFromSites(includeSites);  // adds the second layer with the sites


// click event handler, basically same as http://openlayers.org/en/v3.12.1/examples/icon.html
map.on('click', function(evt) {
  var feature = map.forEachFeatureAtPixel(evt.pixel,
    function(feature,layer) {
      return feature;
    });
  if (feature) {
    console.log("feature got clicked on"); // do stuff
  } else {
    console.log("didn't click a feature");
  }
});
</script>
</body>
</html>

地图和图标已加载,但是当我单击图标时,无论我放大或缩小多少,它都没有检测到与我正在单击的图标匹配。问题是,事件处理程序代码与官方示例中的代码相同,这让我觉得这就是我创建功能的方式。另一方面,这些功能显示得很好,就像图标一样,只是点击事件似乎不起作用。示例中的鼠标光标发生了类似的奇怪变化。我猜这是因为我不明白 data/functions 在 OL 中的结构方式,而且我发现文档没有完全解释它是如何工作的,所以我一直在写这样的片段试图采取一看:

var myLayers = map.getLayers();
console.log("keys - " + myLayers.getKeys);  // prints out 'function (){return Object.keys(this.B)}' - what does that mean?
var mySource = myLayers.getSource;
console.log("source" + mySource.getProjection); // doesn't work
var features = mySource.getFeatures;  // says mySource is undefined

当然完全失败了。

如何让它检测 icons/features 上的点击,以便我可以告诉 div 在正确的时间出现并显示我的数据?我这样做对吗?我不了解 data/functions 的工作方式?我是一个 JS 菜鸟,所以我希望我没有做一些愚蠢的事情,但这给我带来了很多问题,我真的需要你的帮助!谢谢大家!

console.log("keys - " + myLayers.getKeys); // prints out 'function (){return Object.keys(this.B)}' - what does that mean?

这意味着您正在尝试打印函数本身,而不是它执行的结果。应该是

console.log("keys - " + myLayers.getKeys())

 mySource.getProjection();
 mySource.getFeatures();

通常,如果属性名称以 "get" 开头并以驼峰式书写 - 这是一个函数。记住这个提示:)

在长时间盯着屏幕并用头撞桌子后,我偶然发现了解决问题的方法。有点晦涩但是mind-numbinglysimple/stupid/silly。我想我会 post 在这里为其他人提供解决方案。

我写了几行代码来在页面加载时调整视口大小,并在 window 调整大小时再次调整,因此地图会根据可用的用户浏览器进行调整 window space。不幸的是,据我所知,OL 对此一无所知,因此图标和功能在调整大小后不再位于同一位置。虽然我不知道这一点,直到无数小时后我随机点击并调整它的大小,才检测到功能点击。

幸运的是,一旦您发现这是问题所在,就有一种简单的方法可以解决它。基本上只需将 map.updateSize() 添加到调整视口大小的代码部分。到目前为止,这似乎已经解决了问题。

如果其他人遇到此问题:我的解决方案是将功能图标 PNG 图像更改为不透明(无颜色)。

如果您的图片是 PNG 且具有透明度,

where it is transparent it won't be clickable

(我使用的是 OpenLayers v5)。例如,我有一个圆形的图像,它内部是透明的,只是在外边框上着色。 当我将图像更改为中间没有透明度的东西时(当然它仍然可以是 PNG),一切都很好。这似乎是 OpenLayers 处理图像像素的方式 - 如果可以通过图像看到地图,即使您在要素上,它也不是 'hover'。

这些函数仅适用于要素的像素,因此要解决此问题,您可以在图像中添加一些样式,并使用 rgb(255,0,0,0.001) 等属性进行填充。我试过了,我为我工作。