我正在寻找一种方法,只在该特征上渲染悬停特征向量,基本上在其特征上渲染悬停向量,而不在其他特征上渲染(特别是LineString悬停不在近似标记上渲染)。
我的悬停设置没有问题,因为根据 矢量例子,特征都按照我想要的顺序渲染(LineStrings在标记下方)。问题是,当一个LineString被悬停在其悬停特征上时,不仅会在该LineString上呈现,而且会在该LineString下交叉的任何标记上呈现,因此LineString在该标记上的悬停会有一个很大的条纹。仅仅考虑到特征叠加向量的工作原理,我就能明白这有什么意义,但我看不出如何按照自己的意愿来调整。
我发现有几个帖子似乎提供了关于在样式中设置zIndex或使用renderOrder函数的不一致的建议,尽管没有一个帖子似乎完全适用于这种情况,或者超出了我的n00b能力。我试过在所有相关的样式上设置一个zIndex,也试过类似这样的方法 这个renderOrder函数但没有达到预期的效果。具体到后者,我不知道该把函数放在哪里,以便悬停可以根据它来渲染。
如果有任何建议,我将不胜感激
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
target: 'map',
view: new ol.View({
center: ol.proj.fromLonLat([132.4903, 34.0024]),
zoom: 4
})
});
var vectorLayer = new ol.layer.Vector({
source: new ol.source.Vector({
url: '../static/gpx/summer3.kml',
format: new ol.format.KML({
extractStyles: false
})
}),
style: function(feature) {
return routeStyle;
},
});
vectorLayer.getSource().on('addfeature', function(event) {
event.feature.set('hoverstyle', 'route');
});
map.addLayer(vectorLayer);
var vectorLayer = new ol.layer.Vector({
source: new ol.source.Vector({
url: '../static/gpx/testmoo3.kml',
format: new ol.format.KML({
extractStyles: false,
}),
}),
style: function(feature) {
return iconStyle;
},
});
vectorLayer.getSource().on('addfeature', function(event) {
event.feature.set('hoverstyle', 'route');
});
map.addLayer(vectorLayer);
var hoverStyles = {
'moo': new ol.style.Icon({
anchor: [0.5, 30],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
src: '../static/GPX/icon/mooinb.png',
}),
'route': new ol.style.Stroke({
color: 'rgba(236, 26, 201, 0.5)',
width: 5
})
};
var routeStyle = new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'rgba(209,14,14,.6)',
width: 4
})
});
var iconStyle = new ol.style.Style({
image: new ol.style.Icon({
anchor: [0.5, 30],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
src: '../static/GPX/icon/moo7.png',
}),
});
var hoverStyleCache = {}
function hoverStyler(feature, resolution) {
var hover = feature.get('hoverstyle');
var geometry = feature.getGeometry().getType();
console.log(hover);
while (geometry === 'Point') {
if (!hoverStyleCache[hover]) {
hoverStyleCache[hover] = new ol.style.Style({
image: hoverStyles[hover],
})
}
return [hoverStyleCache[hover]];
}
while (geometry === 'LineString') {
if (!hoverStyleCache[hover]) {
hoverStyleCache[hover] = new ol.style.Style({
stroke: hoverStyles[hover]
})
}
return [hoverStyleCache[hover]];
}
}
var featureOverlay = new ol.layer.Vector({
source: new ol.source.Vector(),
map: map,
style: hoverStyler
});
var highlight;
var hover = function(pixel) {
var feature = map.forEachFeatureAtPixel(pixel, function(feature) {
return feature;
});
if (feature !== highlight) {
if (highlight) {
featureOverlay.getSource().removeFeature(highlight);
}
if (feature) {
featureOverlay.getSource().addFeature(feature);
}
highlight = feature;
}
};
map.on('pointermove', function(evt) {
if (evt.dragging) {
return;
}
var pixel = map.getEventPixel(evt.originalEvent);
hover(pixel);
});
***** 编辑1 *****
这里有一个plunkr,至少说明了我的意思。 (悬停向量与标记重叠).我继续摸索,确实达到了我想要的效果,把点和线状的 "featureOverlay "向量分离成两个独立的向量。
我继续摆弄了一下,确实得到了我想要的东西,通过将点和线段的 "featureOverlay "向量分离成两个独立的向量,尽管为了让它工作,我还必须重复它所暗示的一切(hoverStyler函数,悬停特征等)。
以及,当我在上面提到不一致的建议,特别是到了前面,因为我能够设置zIndex上的任何向量层,但不是在Styles中,因为我在几乎所有其他问题中读到,我发现,但向量本身。因此,我可以在任何矢量图层上设置zIndex,但不是在样式中设置,而是在我找到的所有其他问题中设置,而是在矢量本身中设置。
var featureOverlay = new ol.layer.Vector({
source: new ol.source.Vector(),
map: map,
style: hoverStyler,
zIndex: 1,
});
工作(zIndex同样适用于任何其他矢量层),但由于点和线型图共享Overlay功能,这也意味着标记的悬停矢量图像在它要悬停的标记下方:以这种方式应用于线型图和标记或两者都不悬停。
因此,我试图想出一个类似于hoverStyler的函数来区分它们。
function zIndexer(feature, resolution) {
var geometry = feature.getGeometry().getType();
if (geometry === 'Point') {
return 5
}
if (geometry === 'LineString') {
return 1
}
}
但无济于事(我不确定到底应该返回什么,于是尝试了各种输入;这和其他人一样没有用)。
所以,我可以满足于重复的featureOverlay设备,但一个方便的zIndex函数当然是更好的 :)
(*注:我无法让zIndex在plunkr中工作,如上所述,在Styles中或不在Styles中,因此它不能说明我后来的摆弄,而只能说明最初的问题)
***** 编辑2 *****
我在下面对所提供的答案的评论中指出,虽然这个答案非常好用,但它确实使通过函数(在原帖中没有提到)样式的群集无法工作。我用下面的向量克服了这个问题,它可以工作,但我没有资格说工作得很好。
var clusterCache = {}
var CLM = new ol.layer.Vector({
source: new ol.source.Vector(),
style: function(feature) {
var size = feature.get('features').length;
var style = clusterCache[size]
if (size === 1) {
return [hoverStyles['moo']]
}
else if (size > 1) {
if (!style) {
style = new ol.style.Style({
image:new ol.style.Icon({
anchor: [0.5, 30],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
src: '../static/GPX/icon/moo3Hover.png',
}),
text: new ol.style.Text({
text: size.toString(),
font: '12px Calibri,sans-serif',
fill: new ol.style.Fill({
color: '#fff'
}),
stroke: new ol.style.Stroke({
color: '#000',
width: 5
}),
offsetX: 22,
offsetY: 6,
})
}),
clusterCache[size] = style;
}
return style;
}
}
});
hoverLayers['clustermoo'] = CLM;
办法
基本的想法是你需要为路线和图标(从上到下)分别设置悬浮层。
这意味着一个未悬停的图标会画在悬停路线的上方。
ZIndex
你不能使用样式zIndex,因为它只适用于一个图层中的特征。也就是说,图层 zIndex 比样式 zIndex 有更高的优先级。在你的 plunkr 中,我根本无法让图层 zIndex 工作,但它隐含在图层添加的顺序中。
所以,你需要
风格缓存
还有一点,你的样式缓存的实现是相当可疑的。事实上,你不需要样式缓存,因为你使用的是图层样式,而且它们只被分配创建一次。
Plunkr
这里是一个更新的plunkr,有以上的变化。https:/plnkr.coeditgpswRq3tjTTy9O0L。
var createHoverLayer = function(style) {
return new ol.layer.Vector({
source: new ol.source.Vector(),
style: style,
});
}
var hoverLayers = {};
hoverLayers['route'] = createHoverLayer([hoverStyles['route']]);
hoverLayers['moo'] = createHoverLayer([hoverStyles['moo']]);
map.addLayer(routeLayer);
map.addLayer(hoverLayers['route']);
map.addLayer(mooLayer);
map.addLayer(hoverLayers['moo']);
var highlight;
var hover = function(pixel) {
var feature = map.forEachFeatureAtPixel(pixel, function(feature) {
return feature;
});
if (feature !== highlight) {
if (highlight) {
var highlightType = highlight.get('type');
hoverLayers[highlightType].getSource().removeFeature(highlight);
}
if (feature) {
var featureType = feature.get('type');
hoverLayers[featureType].getSource().addFeature(feature);
}
highlight = feature;
}
};
替代方法