Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Events 多个层上的Openlayers和事件(OpenLayer.Layer.Vector)_Events_Openlayers - Fatal编程技术网

Events 多个层上的Openlayers和事件(OpenLayer.Layer.Vector)

Events 多个层上的Openlayers和事件(OpenLayer.Layer.Vector),events,openlayers,Events,Openlayers,又是一天使用openlayers和另一个问题 也就是说,我有多个向量层,每个向量层上都有不同类型的东西(汽车、历史旅行和地区)。他们都有我想抓住的事件。。。但正如我们所发现的,当你激活一层上的事件时,它会移到上面,而下面层上的事件不会触发 有没有办法绕过这个?因为当我在区域多边形上移动时,我希望事件触发并显示其名称,当我将鼠标移到汽车标记上时,我也希望事件触发。不,我不想把它们放在同一层上,因为我希望能够快速地关闭或打开它们,而不需要循环使用所有功能并禁用它们 艾伦 Edit1:我做了一些搜索,

又是一天使用openlayers和另一个问题

也就是说,我有多个向量层,每个向量层上都有不同类型的东西(汽车、历史旅行和地区)。他们都有我想抓住的事件。。。但正如我们所发现的,当你激活一层上的事件时,它会移到上面,而下面层上的事件不会触发

有没有办法绕过这个?因为当我在区域多边形上移动时,我希望事件触发并显示其名称,当我将鼠标移到汽车标记上时,我也希望事件触发。不,我不想把它们放在同一层上,因为我希望能够快速地关闭或打开它们,而不需要循环使用所有功能并禁用它们

艾伦

Edit1:我做了一些搜索,发现可以在多个层上使用相同的控件。这可能会为我解决这个问题。我正在atm机上检查,并测试向单个控件添加更多层是否能解决我的问题


我很荣幸被这样提到!:-)

最后,我在一个附加的js文件中覆盖了特性处理程序中的activate函数:(注释行是唯一的区别。)


我还发现select控件在不在顶部的层上工作,因此我认为您在控件中使用多个层的方法看起来不错。

好的,解决方案如下:

/*
* This method will be called each time you add more vector layers to your map.
* i get more data with ajax calls and some of this data will go to existing layers,
* some of it will go to new layers... Some layers will be added and some removed. 
*/

OpenMap.prototype.bindFeatureEvents = function (arr){
    var that = this;
    if ( this.initialized == true ){
    /* if map is already initialized we deactivate and remove control - 
    * we will re add it later. I havent tested if its really necessary...
    */
        this.carSelect.deactivate();
        this.mymap.removeControl(this.carSelect);
    } else {
        this.carSelect = new OpenLayers.Control.SelectFeature([], {
            'hover':true,
            'callbacks':{
                'click':function(f){
                    if ( typeof f.attributes.data.id != 'undefined'){
                        that.selectCar(f.attributes.data.id);
                    }
                }
        }});

        this.vectorsLayer.events.on({
            'featureselected': this.onFeatureSelect.bind(this),// these methods open and close popups.
            'featureunselected': this.onFeatureUnselect.bind(this)
        });

        this.carsLayer.events.on({
            'featureselected': this.onFeatureSelect.bind(this),
            'featureunselected': this.onFeatureUnselect.bind(this),
            'moveend': function(e) {
                if (e.zoomChanged) {
                    if (this.watchCar == true){
                        this.holdZoom = true;
                    }
                }
             }.bind(this)//without this the "this" in moveend callback is openlayers.layer.vector
        });
        /*
        * I save existing layers in two arrays... It seemed simpler to use two arrays.. 
        * or you could of course use one Object instead of two Arrays... 
        * and you really need to bind events to each layer only once... otherwise each rebinds
        * makes events firing more and more. 
        * each time bindFeatureEvents is called.. new events would be added.
        */
        var name = this.vectorsLayer.name;
        this.boundLayers.push(name)
        this.allLayers.push(this.vectorsLayer);
        var name = this.carsLayer.name;
        this.boundLayers.push(name)
        this.allLayers.push(this.carsLayer);
        this.initialized = true;
    }
    /*
    * We need to check if any arr was provided at bindFeatureEvents call. 
    * if not.. then ohwell. pass :P
    */
    if ( arr != null && typeof(arr)=='object' && arr instanceof Array && arr.length > 0 ){
        for ( i = 0 ; i < arr.length; i++){
            var name = arr[i].name;
            if ( name in oc(this.boundLayers) ){
                 // Tell me how to skip this part... 
            } else {
            //we add new layer to both arrays.
                this.boundLayers.push(name);
                this.allLayers.push(arr[i]);
            }
        }
    }
    /*
    * this next line is what made it sensible to use two arrays... you can
    * feed all layers easyer to setLayer method
    * We could also use bit of code to check if some layers were removed... 
    */
    this.carSelect.setLayer(this.allLayers);
    this.mymap.addControl(this.carSelect);
    this.carSelect.activate();
    /*
    * Yeah the control is acitvated again and the events are firing on all layers...
    */
};

//taken from http://snook.ca/archives/javascript/testing_for_a_v
function oc(array){
    var o = {};
    for(var i=0;i<array.length;i++){
        o[array[i]]='';
    }
    return o;
};
/*
*每次向地图添加更多矢量图层时,都将调用此方法。
*我通过ajax调用获得了更多的数据,其中一些数据将进入现有层,
*其中一些将被添加到新的图层中。。。将添加一些层,删除一些层。
*/
OpenMap.prototype.bindFeatureEvents=函数(arr){
var=这个;
if(this.initialized==true){
/*如果映射已初始化,我们将停用并删除控制-
*我们稍后会重新添加。我还没有测试它是否真的有必要。。。
*/
this.carSelect.deactivate();
this.mymap.removeControl(this.carSelect);
}否则{
this.carSelect=新建OpenLayers.Control.SelectFeature([]{
“悬停”:对,
“回调”:{
“单击”:函数(f){
if(f.attributes.data.id的类型!=“未定义”){
selectCar(f.attributes.data.id);
}
}
}});
此.vectorsLayer.events.on({
“featureselected”:this.onFeatureSelect.bind(this),//这些方法打开和关闭弹出窗口。
“featureunselected”:this.onFeatureUnselect.bind(this)
});
这是carsLayer.events.on({
“featureselected”:this.onFeatureSelect.bind(this),
“featureunselected”:this.onFeatureUnselect.bind(this),
“moveend”:函数(e){
如果(例如zoomChanged){
if(this.watchCar==true){
this.holdZoom=true;
}
}
}.bind(this)//如果没有这个,moveend回调中的“this”是openlayers.layer.vector
});
/*
*我将现有层保存在两个阵列中…使用两个阵列似乎更简单。。
*或者您当然可以使用一个对象而不是两个数组。。。
*你真的需要将事件绑定到每一层只有一次,否则每一层都会重新绑定
*使事件触发越来越多。
*每次调用bindFeatureEvents时,都会添加新事件。
*/
var name=this.vectorsLayer.name;
this.boundLayers.push(名称)
这个.allLayers.push(这个.vectorsLayer);
var name=this.carsLayer.name;
this.boundLayers.push(名称)
这个.allLayers.push(这个.carsLayer);
this.initialized=true;
}
/*
*我们需要检查bindFeatureEvents调用是否提供了任何arr。
*如果没有,那么好吧,通过:P
*/
如果(arr!=null&&typeof(arr)='object'&&arr instanceof Array&&arr.length>0){
对于(i=0;i对于(var i=0;i这解决了我的问题:

之前:

      map.addLayer(layer);
      layer.events.register("loadend", layer, function(){
        $("#progress").hide();
      });
      layer.events.register("loadend", layer, function(){
        $("#progress").hide();
      });
      map.addLayer(layer);
之后:

      map.addLayer(layer);
      layer.events.register("loadend", layer, function(){
        $("#progress").hide();
      });
      layer.events.register("loadend", layer, function(){
        $("#progress").hide();
      });
      map.addLayer(layer);

希望有帮助

当我遇到同样的问题,试图让多个层对鼠标事件做出反应时,我发现了这个问题

如果其他人发现此线程,解决方案会简单得多

SelectFeature控件接受一个向量层数组,如果需要对鼠标事件(悬停和单击)做出反应的所有层都在该数组中,则它们都可以工作,而不仅仅是移动到顶部的层

因此,在该线程的已批准解决方案中,通过执行以下操作可以大大简化:

this.carSelect = new OpenLayers.Control.SelectFeature(
    [this.vectorsLayer, this.carsLayer],
    {
        'hover':true,
        'callbacks': {
            blah blah blah
    }
});
这将在两个层上注册适当的事件,并使它们都处于活动状态

我希望这能帮助其他在这个问题上绊倒的人


正如其他地方所说,使用OpenLayers并不难,找到正确的方法来使用它并不难。

Mmmyeah……恐怕这对我来说不太管用。我仍在考虑在多个层上使用相同的选择控件。这看起来很有希望。如果有问题,我会发布解决方案