Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making more than one vector layer clickable in OpenLayers

I'm working on a OpenLayers map that will display multiple KML layers at once. I want to be able to click on a feature from any layer and have a pop-up show me some info. So far I can only click on the most recently added layer. If I want to click on a previously added layer I have to turn off all the layers that were added before. Obviously this is less than ideal. Here's my code so far:

var select = [];
function addLayer(layerId, layerLink, layerColor)
{

    var kmlLayer = new OpenLayers.Layer.Vector("Layer_"+layerId, {
        strategies: [new OpenLayers.Strategy.Fixed()],
        protocol: new OpenLayers.Protocol.HTTP({
            url: layerLink,
            format: new OpenLayers.Format.KML({
        extractStyles: true, 
        extractAttributes: true,
        maxDepth: 2
        })
    })
    });

    kmlLayer.events.on({
        "featureselected": onKMLSelect,
        "featureunselected": onKMLUnselect
    });

    select["Layer_"+layerId] = new OpenLayers.Control.SelectFeature(kmlLayer);
    map.addControl(select["Layer_"+layerId]);
    select["Layer_"+layerId].activate();  

    map.addLayer(kmlLayer);

}
function onKMLPopupClose(evt) {
    for(s in select)
    {
        select[s].unselectAll();
    }
}
function onKMLSelect(event) {
        var feature = event.feature;

    var content = "<h2>"+feature.attributes.name + "</h2>" + feature.attributes.description;
    popup = new OpenLayers.Popup.FramedCloud("chicken", 
                             feature.geometry.getBounds().getCenterLonLat(),
                             new OpenLayers.Size(100,100),
                             content,
                             null, true, onKMLPopupClose);
    feature.popup = popup;
    map.addPopup(popup);
}
function onKMLUnselect(event) {
    var feature = event.feature;
    if(feature.popup) {
        map.removePopup(feature.popup);
        feature.popup.destroy();
        delete feature.popup;
    }
}

Any help would be greatly appreciated. Thanks,

like image 604
etherton Avatar asked Feb 04 '12 18:02

etherton


2 Answers

I had the same problem a while ago. You can find good example about this from Openlayers Examples: OpenLayers Select Feature on Multiple Layers Example.

Here is main parts of the code:

var map, selectControl;
function init(){
    map = new OpenLayers.Map('map');
    var wmsLayer = new OpenLayers.Layer.WMS(
        "OpenLayers WMS", 
        "http://vmap0.tiles.osgeo.org/wms/vmap0",
        {layers: 'basic'}
    ); 

    var vectors1 = new OpenLayers.Layer.Vector("Vector Layer 1");
    var vectors2 = new OpenLayers.Layer.Vector("Vector Layer 2");

    map.addLayers([wmsLayer, vectors1, vectors2]);
    map.addControl(new OpenLayers.Control.LayerSwitcher());

    selectControl = new OpenLayers.Control.SelectFeature(
        [vectors1, vectors2]
    );

    map.addControl(selectControl);
    selectControl.activate();

    map.setCenter(new OpenLayers.LonLat(0, 0), 3);

    vectors1.addFeatures(createFeatures());
    vectors2.addFeatures(createFeatures());


    vectors1.events.on({
        "featureselected": function(e) {
            showStatus("selected feature "+e.feature.id+" on Vector Layer 1");
        },
        "featureunselected": function(e) {
            showStatus("unselected feature "+e.feature.id+" on Vector Layer 1");
        }
    });
    vectors2.events.on({
        "featureselected": function(e) {
            showStatus("selected feature "+e.feature.id+" on Vector Layer 2");
        },
        "featureunselected": function(e) {
            showStatus("unselected feature "+e.feature.id+" on Vector Layer 2");
        }
    });
}
like image 81
Petteri Vaarala Avatar answered Nov 11 '22 02:11

Petteri Vaarala


this is what i do to have all features on CHOSEN layers become selectable calling to popup windows:

var selectStop = new OpenLayers.Control.SelectFeature([layerKMLClient, layerKMLStops,  layerKMLTarget],{onSelect: onFeatureSelect, onUnselect: onFeatureUnselect});
    layerKMLStops.events.on({
                "featureselected": onFeatureSelect,
                "featureunselected": onFeatureUnselect
            });
    layerKMLClient.events.on({
                "featureselected": onFeatureSelect,
                "featureunselected": onFeatureUnselect
            });
    layerKMLTarget.events.on({
                "featureselected": onFeatureSelect,
                "featureunselected": onFeatureUnselect
            });
    map.addControl(selectStop);
    selectStop.activate(); 

note that i have multiple other layers (mostly from KML files, but also some vector layers from txt files) whose features are NOT SELECTABLE. you can change your behaviors by customizing the onFeatureSelect for each layer type.

BONUS: if you decide to use cluster strategy on (some of) your layers (believe me, you will, at some point in time) - include a check for feature.cluster being true inside your onFeatureSelected function statement:

function onFeatureSelect(event) {
   var feature = event.feature;
   if (feature.cluster) {
like image 1
tony gil Avatar answered Nov 11 '22 02:11

tony gil