Подтвердить что ты не робот

Принуждение слоя маркеров OpenLayers для рисования сверху и с возможностью выбора слоев ниже

У меня есть карта OpenLayers с базовым слоем растра, векторным слоем и слоем маркеров в этом порядке. Они отлично отображаются в правильном порядке с маркерами на вершине векторов. Отлично.

Но когда я добавляю элемент управления SelectFeature и указываю его на векторный слой, он неожиданно рисуется над слоем маркеров, несмотря на все усилия по повышению уровня маркера или установке индекса Z. Кажется, что элемент управления SelectFeature отменяет все настройки порядка рисования. Это по дизайну, или я могу как-то преодолеть это?

Определения слоев:

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
}
);

Определение управления:

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
    }
);

Активация: (Без этого слои рисуют в правильном порядке)

map.addControl(selectctrl);

selectctrl.activate();

Изменить: Обнаружил это в 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;
},
4b9b3361

Ответ 1

Ответ - если это нормально, то это называется функцией активации, о которой я упоминал выше. Я попытался переопределить это и удалить вызов moveLayerToTop, и он работает как шарм.

ИЗМЕНИТЬ: Я закончил тем, что добавил этот код в js файл вне библиотеки кода OL, переопределяя функцию активации обработчиков. Это связано с тем, что в противном случае я потерял бы изменения при обновлении базы данных 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;
};

Ответ 2

Я нашел это, когда у меня была такая же проблема, пытаясь заставить несколько слоев реагировать на события мыши.

Решение, на всякий случай, если кто-либо еще найдет этот поток намного проще.

Элемент управления SelectFeature принимает массив слоев Vector, и если все латнеры, которые вам нужно реагировать на события мыши (наведите указатель мыши и нажмите), находятся в этом массиве, они ВСЕ работают, а не только тот, который был перемещен в начало.

Документация предлагает не использовать слои маркеров. Хотя мое решение вращается вокруг полей геометрии PostGIS и дает рендеринг POINT-данных в векторном слое, все, что использует маркеры, может быть выполнено таким образом, и согласно OpenLayers, должно быть.

Итак, одобренное решение этой темы может быть значительно упрощено с помощью Vector Layers для маркеров и сделать что-то вроде этого:

this.carSelect = new OpenLayers.Control.SelectFeature(
    [vectorsLayer, markersLayer],
    {
        'hover':true,
        'callbacks': {
            blah blah blah
    }
});

Это приведет к регистрации соответствующих событий на обоих уровнях и сделает их живыми.

Я надеюсь, что это поможет кому-то еще наткнуться на эту проблему.

Как сказано в другом месте, использование OpenLayers не сложно, найти правильный способ сделать что-то с ним.