OpenLayers 3:在悬停

时间:2016-06-30 05:32:30

标签: javascript openlayers-3

我正试图找到一种方法,只有当鼠标悬停在功能图标上时,才能在OpenLayers矢量功能上显示标签。我找到了一些相似的事情的例子,但没有什么能做我需要做的事情。在我看来,它似乎相当简单,但我无法弄清楚如何开始。

这就是我的功能样式代码的样子(几个例子)。请注意,我从几个GeoJSON文件中引入了要素数据,因此颜色部分中有feature.get(...)个:

if (feature.get('level_pc') < 35 ) {
    var style = new ol.style.Style({
        fill: new ol.style.Fill({color: feature.get('shapefill')}),
        stroke: new ol.style.Stroke({color: feature.get('shapestroke')}),
        image: new ol.style.Icon(/** @type {olx.style.IconOptions} */ ({
            anchor: [16, 16],
            anchorXUnits: 'pixels',
            anchorYUnits: 'pixels',
            opacity: 0.75,
            src: '/icons/aws-red.png'
        })),
        text: new ol.style.Text({
            font: '12px Roboto',
            text: feature.get('label'),
            fill: new ol.style.Fill({
                color: feature.get('textfill')
            }),
            stroke: new ol.style.Stroke({
                color: feature.get('textstroke'),
                width: 1
            })
        })
    });
    return style
} else { ...

我真的希望有一种方法可以在创建悬停交互的样式定义中插入一些代码,而不必创建每个样式的副本,然后编写一些在hover / non之间切换的额外代码必要时悬停样式。也许可以通过在鼠标悬停时将文本颜色的alpha值设置为255,在其他时间设置为0。也许我太乐观了。

有没有人有我可以查看的想法或例子?

谢谢, 加雷

编辑:感谢何塞,我现在更接近目标了。自从我第一次提出这个问题以来,我的原始代码有所改变。我现在通过一个函数为每个特征应用样式,该函数从GeoJSON数据中读取图标文件的名称。例如,门显示有“门打开”或“门关闭”图标和带有“筒仓高”,“筒仓介质”或“筒仓低”图标的筒仓。所有功能都悬停显示正确的图标和文字,这很棒 - 只是当我没有悬停在图标上时,显示的图标不正确 - 它显示所有功能的'筒仓低'图标。当我将鼠标悬停在图标上时会显示正确的图标,然后在我不再悬停时恢复。

这是我更新的代码的重要部分:

var structuresStyleHover = function(feature, resolution) {
    style = new ol.style.Style({
        fill: new ol.style.Fill({color: feature.get('shapefill')}),
        stroke: new ol.style.Stroke({color: feature.get('shapestroke')}),
        image: new ol.style.Icon(/** @type {olx.style.IconOptions} */ ({
            anchor: [16, 16],
            anchorXUnits: 'pixels',
            anchorYUnits: 'pixels',
            opacity: 1,
            src: '/icons/'+feature.get('icon')+'-'+feature.get('status').toLowerCase()+'.png'
        })),
        text: new ol.style.Text({
            font: '12px Roboto',
            text: feature.get('label'),
            fill: new ol.style.Fill({
                color: feature.get('textfill')
            }),
            stroke: new ol.style.Stroke({
                color: feature.get('textstroke'),
                width: 1
            })
        })
    })
    return style;
};

var styleCache = {};
var styleFunction = function(feature,resolution) {
      var radius = 16;
      var style = styleCache[radius];
      if (!style) {
        style = new ol.style.Style({
            image: new ol.style.Icon(/** @type {olx.style.IconOptions} */ ({
                anchor: [16, 16],
                anchorXUnits: 'pixels',
                anchorYUnits: 'pixels',
                opacity: 0.5,
                src: '/icons/'+feature.get('icon')+'-'+feature.get('status').toLowerCase()+'.png'
            })),
        });
        styleCache[radius] = style;
      }
      return style;
};

var structuresLayer = new ol.layer.Vector({
    source: structuresSource,
    style: styleFunction
});

...

var map = new ol.Map({
    layers: [paddocksLayer,structuresLayer],
    interactions: ol.interaction.defaults({
        altShiftDragRotate: false,
        dragPan: false,
        rotate: false
    }).extend([new ol.interaction.DragPan({kinetic: null})]),
    target: olMapDiv,
    view: view
});

...

map.on('pointermove', function(evt) {
    if (evt.dragging) {
        return;
    }
    structuresLayer.getSource().getFeatures().forEach(f=>{
        f.setStyle(styleFunction);
    });
    var pixel = map.getEventPixel(evt.originalEvent);
    map.forEachFeatureAtPixel(pixel,function(feature,resolution) {
        feature.setStyle(structuresStyleHover(feature,resolution));
        return feature;
    });    

});

我没有收到任何错误 - 除非鼠标悬停在图标上,否则它不会显示正确的图标。

我确信我错过了一些非常明显的东西,但我无法解决这个问题。有什么想法吗?

1 个答案:

答案 0 :(得分:2)

您可以使用setStyle

&#13;
&#13;
var mystyle = new ol.style.Style({
  fill: new ol.style.Fill({color: '#00bbff'}),
  stroke: new ol.style.Stroke({color: '#fff'}),
  image: new ol.style.Icon(/** @type {olx.style.IconOptions} */ ({
    anchor: [16, 16],
    anchorXUnits: 'pixels',
    anchorYUnits: 'pixels',
    scale : 0.1,
    opacity: 1,
    src: 'http://2.bp.blogspot.com/_Sdh3wYnDKG0/TUiIRjXEimI/AAAAAAAAQeU/bGdHVRjwlhk/s1600/map+pin.png'
  })),
  text: new ol.style.Text({
    font: '12px Roboto',
    text: 'AAAAAAAAAAAAAAA',
    fill: new ol.style.Fill({
      color: '#ffbb00'
    }),
    stroke: new ol.style.Stroke({
      color: '#000',
      width: 1
    })
  })
});
var styleCache = {};
var styleFunction = function(feature) {
  var radius = 3;
  var style = styleCache[radius];
  if (!style) {
    style = new ol.style.Style({
      image: new ol.style.Circle({
        radius: radius,
        fill: new ol.style.Fill({
          color: 'rgba(255, 153, 0, 0.4)'
        }),
        stroke: new ol.style.Stroke({
          color: 'rgba(255, 204, 0, 0.2)',
          width: 1
        })
      })
    });
    styleCache[radius] = style;
  }
  return style;
};

var vector = new ol.layer.Vector({
  source: new ol.source.Vector({
    url: 'http://openlayers.org/en/v3.17.1/examples/data/kml/2012_Earthquakes_Mag5.kml',
    format: new ol.format.KML({
      extractStyles: false
    })
  }),
  style: styleFunction
});

var raster = new ol.layer.Tile({
  source: new ol.source.Stamen({
    layer: 'toner'
  })
});

var map = new ol.Map({
  layers: [raster, vector],
  target: 'map',
  view: new ol.View({
    center: [0, 0],
    zoom: 2
  })
});

map.on('pointermove', function(evt) {
  if (evt.dragging) {
    return;
  }
  vector.getSource().getFeatures().forEach(f=>{
    f.setStyle(styleFunction);
  });
  var pixel = map.getEventPixel(evt.originalEvent);
  map.forEachFeatureAtPixel(pixel,function(feature) {
    feature.setStyle(mystyle);
    return feature;
  });    

});
&#13;
#map {
  position: relative;
}
&#13;
<title>Earthquakes in KML</title>
<link rel="stylesheet" href="http://openlayers.org/en/v3.17.1/css/ol.css" type="text/css">
<script src="http://openlayers.org/en/v3.17.1/build/ol.js"></script>
<script src="https://code.jquery.com/jquery-2.2.3.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<div id="map" class="map"></div>
&#13;
&#13;
&#13;