javascript 强制 OpenLayers Markers 图层在顶部绘制,并在下方具有可选图层
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4728852/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Forcing an OpenLayers Markers layer to draw on top, and having selectable layers beneath
提问by Niklas Wulff
I have an OpenLayers map with a raster base layer, a vector layer and a markers layer in that order. They display fine, in the correct order with the markers on top of the vectors, great.
我有一个 OpenLayers 地图,其中包含一个栅格基础层、一个矢量图层和一个标记层。它们以正确的顺序显示得很好,标记位于矢量顶部,很棒。
But when I add a SelectFeature Control and point it to the vector layer, it is suddenly drawn above the markers layer, despite all efforts to raise the marker layer or setting the Z index. It seems that the SelectFeature control overrides all drawing order settings. Is this by design, or can I overcome this somehow?
但是当我添加一个 SelectFeature 控件并将其指向矢量图层时,它突然被绘制在标记层上方,尽管努力提高标记层或设置 Z 索引。SelectFeature 控件似乎覆盖了所有绘图顺序设置。这是设计使然,还是我可以以某种方式克服它?
The layer definitions:
层定义:
var baselayer = new OpenLayers.Layer.WMS('Norden',
'http://{myarcgisserver}/ArcGIS/services/mylayer/MapServer/WMSServer', {
layers :'1,2',
transparent :false,
width :'auto',
height :'auto',
filter :null
}, {
isBaseLayer: true,
singleTile :true,
ratio :1,
alpha :false,
transitionEffect :'resize'
});
var vectorLayer = new OpenLayers.Layer.Vector("Work orders", {
projection: new OpenLayers.Projection("EPSG:2400"),
strategies: [new OpenLayers.Strategy.Fixed(), refresh],
protocol: new OpenLayers.Protocol.HTTP({
url: "/WorkOrder/WorkOrders.ashx?output=geojson",
format: new OpenLayers.Format.GeoJSON()
})
});
var markerlayer = new OpenLayers.Layer.Markers("Markers", {
projection: new OpenLayers.Projection("EPSG:2400"),
displayInLayerSwitcher: false
}
);
The control definition:
控件定义:
var selectctrl = new OpenLayers.Control.SelectFeature(
vectorLayer,
{
clickout: true,
toggle: false,
multiple: false,
hover: false,
toggleKey: "ctrlKey", // ctrl key removes from selection
multipleKey: "shiftKey", // shift key adds to selection
box: false
}
);
Activation: (Without this, the layers draw in correct order)
激活:(没有这个,图层以正确的顺序绘制)
map.addControl(selectctrl);
selectctrl.activate();
Edit: Found this in OpenLayers.Handler.Feature, where the "moveLayerToTop" feels like the culprit... Will try to overcome it, but if someone knows it to be impossible, please let me know!
编辑:在 OpenLayers.Handler.Feature 中找到了这个,其中“moveLayerToTop”感觉像是罪魁祸首......将尝试克服它,但如果有人知道这是不可能的,请告诉我!
/**
* Method: activate
* Turn on the handler. Returns false if the handler was already active.
*
* Returns:
* {Boolean}
*/
activate: function() {
var activated = false;
if(OpenLayers.Handler.prototype.activate.apply(this, arguments)) {
this.moveLayerToTop();
this.map.events.on({
"removelayer": this.handleMapEvents,
"changelayer": this.handleMapEvents,
scope: this
});
activated = true;
}
return activated;
},
采纳答案by Niklas Wulff
The answer - if it's ok to call it that lies in the activate function that I mention above. I tried to override that and removed the call to moveLayerToTop, and it works like a charm.
答案 - 如果可以调用它,那就是我上面提到的 activate 函数。我试图覆盖它并删除了对 moveLayerToTop 的调用,它就像一个魅力。
EDIT: I ended up adding this code to a js file outside the OL code library, overriding the handlers activate function. This is because I would otherwise lose the change on an update of the OpenLayers code base.
编辑:我最终将此代码添加到 OL 代码库之外的 js 文件中,覆盖了处理程序激活函数。这是因为否则我会在更新 OpenLayers 代码库时丢失更改。
OpenLayers.Handler.Feature.prototype.activate = function() {
var activated = false;
if (OpenLayers.Handler.prototype.activate.apply(this, arguments)) {
//this.moveLayerToTop();
this.map.events.on({
"removelayer": this.handleMapEvents,
"changelayer": this.handleMapEvents,
scope: this
});
activated = true;
}
return activated;
};
回答by Martin Fraser
I found this when I had the same issue, trying to get multiple layers to react to mouse events.
当我遇到同样的问题时,我发现了这一点,试图让多个图层对鼠标事件做出反应。
The solution, just in case anyone else finds this thread is much simpler.
解决方案,以防万一其他人发现此线程要简单得多。
The SelectFeature control takes an array of Vector layers and if all the laters you need to react to mouse events (hover and click) are in that array, they ALL work, not just the one that was moved to the top.
SelectFeature 控件采用矢量层数组,如果您需要对鼠标事件(悬停和单击)做出反应的所有后期都在该数组中,则它们都可以工作,而不仅仅是移动到顶部的图层。
The documentation suggests against using markers layers at all. While my solution revolves around PostGIS geometry fields and lends itself to rendering POINT data in a vector layer, anything that uses Markers can be done this way, and according to OpenLayers, should.
该文档建议完全不要使用标记层。虽然我的解决方案围绕 PostGIS 几何字段并有助于在矢量图层中渲染 POINT 数据,但任何使用标记的东西都可以通过这种方式完成,根据 OpenLayers 的说法,应该这样做。
So, the approved solution to this thread can be much simplified using Vector Layers for the markers and doing something like this:
因此,可以使用矢量层作为标记并执行以下操作,从而大大简化该线程的已批准解决方案:
this.carSelect = new OpenLayers.Control.SelectFeature(
[vectorsLayer, markersLayer],
{
'hover':true,
'callbacks': {
blah blah blah
}
});
This will register the appropriate events on both layers and make them both live.
这将在两个层上注册适当的事件并使它们都处于活动状态。
I hope this helps anyone else stumbling on this issue.
我希望这可以帮助其他在这个问题上绊倒的人。
As said elsewhere, using OpenLayers is not hard, finding the correct way to do things with it is.
正如其他地方所说,使用 OpenLayers 并不难,找到正确的方法来处理它才是。

