Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove all Popups from OpenLayers Features

I am using OpenLayers to create a map and plot locations. Each location has a marker and a popup and are created using OpenLayers.Feature - at the moment, I'm definitely outside of my comfort zone here, so am cobbling example code together.

A marker is created as follows (I've chopped what I hope are obvious variable assignments for brevity):

function addMarker(ll, popupClass, popupContentHTML, closeBox, overflow, type)
{
    var feature = new OpenLayers.Feature(markerLayer, ll);  
    feature.closeBox = closeBox;
    feature.popupClass = popupClass;
    feature.data.icon = icon;
    feature.data.popupContentHTML = popupContentHTML;
    feature.data.overflow = (overflow) ? "auto" : "hidden";

    var marker = feature.createMarker();
    var markerClick = function (evt) {
        if (this.popup == null) {
            this.popup = this.createPopup(this.closeBox);
            map.addPopup(this.popup);
            this.popup.show();
        } else {
            this.popup.toggle();
    }
        currentPopup = this.popup;
        OpenLayers.Event.stop(evt);
    };

    marker.events.register("mousedown", feature, markerClick);
    markerLayer.addMarker(marker);
}

The map can contain many markers.

When a marker is clicked a popup toggles on and off. What I am trying to ado is make ALL popups relating to all markers on the map close when a new marker is clicked and a popup toggles on - that is, I only want one popup to display at a time.

It may be that my approach is all wrong, but would be grateful for pointers, even just ideas to try.

like image 992
Christian Mayne Avatar asked Feb 14 '12 09:02

Christian Mayne


3 Answers

What I remember about OpenLayers is that you should implement a control for the feature selection.

I hope it will works with your markers...

var selectedFeature, selectControl;
function init() {
...
  selectControl = new OpenLayers.Control.SelectFeature(yourMainLayer, {
        onSelect: onFeatureSelect, // will be called on feature select
        onUnselect: onFeatureUnselect // will be called on feature unselect
  });
  selectControl.activate();
...
}

function onFeatureSelect(feature) {
            popup = new OpenLayers.Popup.FramedCloud("chicken", 
                                     feature.geometry.getBounds().getCenterLonLat(),
                                     null,
                                     "some informations",
                                     null, true, onPopupClose);
            feature.popup = popup;
            map.addPopup(popup);
}
function onFeatureUnselect(feature) {
   map.removePopup(feature.popup);
   feature.popup.destroy();
   feature.popup = null;
} 
function onPopupClose(evt) {
   selectControl.unselect(selectedFeature);
}
like image 38
j_freyre Avatar answered Oct 10 '22 21:10

j_freyre


IF you implement a solution whereas only one popup is active at a time (i.e. every time a popup is unselected it disappears), you will NEVER have more than one popup at a time.

read this STACKOVERFLOW answer which i wrote for exactly this problem. you have all the necessary pseudocode there (with lengthy explanations about everything).

if you dont need the explanations, this shows the solution:

var urlKML = 'parseKMLTrack07d.php';         
var layerKML = new OpenLayers.Layer.Vector("KML1", {
            strategies: [new OpenLayers.Strategy.Fixed()],
            protocol: new OpenLayers.Protocol.HTTP({
                url: urlKML,
                format: new OpenLayers.Format.KML({
                    extractStyles: true, 
                    extractAttributes: true,
                    maxDepth: 2
                })
            })
        });

var layerOSM = new OpenLayers.Layer.OSM();
var map = new OpenLayers.Map({
    div: "map",
    layers: [
        layerOSM,
        layerKML 
    ]
});

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

function onFeatureSelect(event) {
    var feature = event.feature;
    var content = feature.attributes.name + '<br/>'+feature.attributes.description;
    popup = new OpenLayers.Popup.FramedCloud("chicken", 
                             feature.geometry.getBounds().getCenterLonLat(),
                             new OpenLayers.Size(100,100),
                             content,
                             null, true, onFeatureUnselect);
    feature.popup = popup;
    map.addPopup(popup);
    // GLOBAL variable, in case popup is destroyed by clicking CLOSE box
    lastfeature = feature;
}
function onFeatureUnselect(event) {
    var feature = lastfeature;  
    if(feature.popup) {
        map.removePopup(feature.popup);
        feature.popup.destroy();
        delete feature.popup;
    }
}

now, if you REALLY want to destroy all popups, regardless (which i very much discourage):

function popupClear() {
    //alert('number of popups '+map.popups.length);
    while( map.popups.length ) {
         map.removePopup(map.popups[0]);
    }
}
like image 121
tony gil Avatar answered Oct 10 '22 21:10

tony gil


Why don't you throw the open popups into an array on the if(this.popup == null) branch, and on the else branch loop over this array and hide all popups.

like image 1
mihai Avatar answered Oct 10 '22 21:10

mihai