5

im really having an issue here.

I am trying to realise a map where i can hover over the features and they get highlighted (works), then i want to be able to click them (works) , i also want a div to change accordingly to the feature (partially works) and i want the popup to close.

Im aware that this question sounds kind of easy, though ive found out that multiple events on a feature are not an easy task to implement.

The map works as far as : I can hover a field, click on it, get a popup but heres where the fun begins. Once the popup is open i cannot close it anymore. Though the popup can be closed when clicking anywhere outside of the feature , so i think this has got to do with my clickout implementation. so far ive tried some stuff and im not seeing any progress.

If the feature im hovering hasnt been clicked on and i hover out of the feature without clicking, the feature stays selected as if the mouse was still hovering. This effect goes away once the feature has been clicked once, but comes back immediately if you start the procedure again (so hover feature 1-hoverStyle,hoverout-still hoverStyle, click feature 1- clickStyle, clickout- standard style, hover feature2- hoverStyle, hoverout-still hoverStyle, hover feature 1- hoverStyle , hoverOut- no Style ). I hope you can get something out of this information.

so now to the div change. i have it working on another layer, but in the layer with all the select and hover bla, it just doesnt want to work.

Heres some code for you to understand or help me with my Problem:

    {


    function tooltipSelect(event){
    var feature = event.feature;
    var selectedFeature = feature;
    //if there is already an opened details window, don\'t draw the 
    tooltip
    if(feature.popup != null){
        return;
    }
    //if there are other tooltips active, destroy them
    if(tooltipPopup != null){
        map.removePopup(tooltipPopup);
        tooltipPopup.destroy();
        if(lastFeature != null){
            delete lastFeature.popup;
            tooltipPopup = null;
        }
    }
    lastFeature = feature;
    var tooltipPopup = new OpenLayers.Popup("activetooltip",
            feature.geometry.getBounds().getCenterLonLat(),
            new OpenLayers.Size(80,12),
            " "+feature.attributes.name,
            true );
    //this is messy, but I'm not a CSS guru
    tooltipPopup.contentDiv.style.backgroundColor='ffffcb';
    tooltipPopup.closeDiv.style.backgroundColor='ffffcb';
    tooltipPopup.contentDiv.style.overflow='hidden';
    tooltipPopup.contentDiv.style.padding='3px';
    tooltipPopup.contentDiv.style.margin='0';
    tooltipPopup.closeOnMove = true;
    tooltipPopup.autoSize = true;
    feature.popup = tooltipPopup;
    map.addPopup(tooltipPopup);
}
function tooltipUnselect(event){
    var feature = event.feature;
    if(feature != null && feature.popup != null){
        map.removePopup(feature.popup);
        feature.popup.destroy();
        delete feature.popup;
        tooltipPopup = null;
        lastFeature = null;
    }
}

function onMarkerSelect(event) {
    //unselect any previous selections
    tooltipUnselect(event);
    var feature = event.feature;
    var selectedFeature = feature;
    var popup = new OpenLayers.Popup.FramedCloud("activeAlarm",
            feature.geometry.getBounds().getCenterLonLat(),
            new OpenLayers.Size(100,100),
            "Loading...",
            null, true, onMarkerPopupClose );
    feature.popup = popup;
    popup.setOpacity(0.7);
    map.addPopup(popup);
    //call ajax to get the data
    loadDetails(feature.attributes.description);
}
function onMarkerUnselect(event) {
    var feature = event.feature;
    if(feature.popup) {
        map.removePopup(feature.popup);
        feature.popup.destroy();
        delete feature.popup;
    }
}
function onMarkerPopupClose(evt) {
    select.unselectAll();
}


//lType: Region-Type
//0=Alle, 1=Land, 2=Reg.Bezirk, 3= Kreis, 4=Gemeinde             
function loadLayersByColour (lType) {

    // alert("in loadLaysersByColour");
    // 1.) einmaliges Erstellen der Filterliste fuer WebService Request
    if (listRun == false){buildFilterLists(6,0);};
    // 2.) entfernen eventuell bereits vorhandener alter Layer
    if (listRun != false) {removeLayer(0);};

    // 3.) aufbauen der Layer

    // zunächst  Bundesländer
    if (lType==1 || lType==0) {

        // create a wfs layer with the style map
        states = new OpenLayers.Layer.WFS(
                "Bundesländer",
                "http://myServer/geoserver/wfs",
                {typename: "myStore:layer"},
                {isBaseLayer: false, extractAttributes: true, styleMap: myStyleMapL}
        );      
        map.addLayers([states]);

        /*
            ctrlSelectFeatures = new OpenLayers.Control.SelectFeature(
                    states,
                    {
                        clickout: true, toggle: false,
                        multiple: false, hover: false,
                        toggleKey: "ctrlKey", // ctrl key removes from selection
                        multipleKey: "shiftKey" // shift key adds to selection
                    }
            );

            map.addControl(ctrlSelectFeatures);
            ctrlSelectFeatures.activate();

            var aktLayer = 1; //index of a vectorlayer
            map.layers[aktLayer].events.register('featureselected',   map.layers[aktLayer], regFeatureSelected);
            map.layers[aktLayer].events.register('featureunselected', map.layers[aktLayer], regFeatureUnselected);

         */

        /*
        if (typeof(clickCtrl) !== 'undefined' && clickCtrl != null ) {
          alert("clickCtrl defined and not null ");
        } else {alert("clickCtrl undefined or null");}; 
         */        
        // map.addControl(selectL);
        // map.addControl(clickCtrl);        
        // map.addControl(selectCtrlClick);
        // selectL.activate();
        // clickCtrl.activate();
        // selectCtrlClick.activate();

        // fuer popup
        //selectedControl = new OpenLayers.Control.SelectFeature(states,
        //  {onSelect: onFeatureSelect, onUnselect: onFeatureUnselect});

        //AENDERUNG
        //add the main select (for regular select)
        selectedControl = new OpenLayers.Control.SelectFeature(states, {
            toggle: true,
            clickout: true,
            multiple: false,
            onSelect: alert("hier"),
        });
        states.events.on({ "featureselected": onMarkerSelect, 
            "featureunselected": tooltipUnselect()});
        //"featureunselected": onMarkerUnselect});

        //add the second select for tooltips:
        var highlightCtrl = new OpenLayers.Control.SelectFeature(states, { 
            hover: true,
            highlightOnly: true,
            renderIntent: "temporary",
            eventListeners: { featurehighlighted: tooltipSelect, 
            featureunhighlighted: tooltipUnselect } });

        //the order in which you add these lines seems to matter!
        map.addControl(highlightCtrl);
        map.addControl(selectedControl);
        highlightCtrl.activate();
        selectedControl.activate();



    };

    // Globale Variable für Merken der geladenen Layertypen  setzen
    lStat = lType; 

};


//  "<div style='font-size:.8em'>Feature: " + feature.id +"<br />Area: " + feature.geometry.getArea()+"</div>",    
function onFeatureSelect(feature) {
    selectedFeature = feature;
    popup = new OpenLayers.Popup.FramedCloud("chicken", 
            feature.geometry.getBounds().getCenterLonLat(),
            null,
            "<div style='font-size:.8em'>Feature: "  +"<br />Area: " + "</div>", 
            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) {
    selectedControl.unselect(selectedFeature);
};

function regFeatureSelected()
{
    aktPopup = create_Popup();
    var objF = this.selectedFeatures[0];
    var desc   = objF.attributes['gen'] ? objF.attributes['gen'] : "about:blank";
    $("nodelist").innerHTML = "Selektiertes Land " + ", " + desc;
}

function regFeatureUnselected()
{
    if(aktPopup)
        map.removePopup(aktPopup.popup);

    document.getElementById("nodelist").innerHTML = "selected feature description";
}



}
4
  • What software? Please tag it with the software/library name. I can guess but I shouldn't have to.
    – Nathan W
    Commented Mar 3, 2011 at 11:44
  • oh sorry. im using OpenLayers
    – 1amtoo1337
    Commented Mar 3, 2011 at 11:59
  • Please format the code you pasted. It's currently unreadable.
    – underdark
    Commented Mar 3, 2011 at 12:28
  • im sorry that it looks this way, i have tried about everything to make it look right. it looks good on any other page. im very sorry.
    – 1amtoo1337
    Commented Mar 3, 2011 at 12:43

3 Answers 3

2

I have no time to check your code but, indeed, handling multiple events is not that easy with openlayers. I also had to struggle with that.

These two links could hopefully help you or at least give you some ideas to find a workaround : http://dev.openlayers.org/examples/highlight-feature.html

http://trac.osgeo.org/openlayers/ticket/1596

1
  • thanks for the information about the ticket. ive been basing my project on this example. yeah.
    – 1amtoo1337
    Commented Mar 4, 2011 at 12:38
2

Here is the code I recently wrote to solve the popup and tooltip popup problem. It works ok for me exact some tooltip(anchored Popup remain on screen until map is refreshed). Hope this helps you.

        //Add a selector control to the vectorLayer with popup functions
            var controls = {
                highlightCtrl: new OpenLayers.Control.SelectFeature(vectorLayer, {
                    hover: true,
                    highlightOnly: true,
                    renderIntent: "temporary",
                    eventListeners: {
                        beforefeaturehighlighted: showTooltip,
                        featurehighlighted: report,
                        featureunhighlighted: hideTooltip
                    }
                }),
                selector: new OpenLayers.Control.SelectFeature(vectorLayer, {
                    onSelect: createPopup,
                    onUnselect: destroyPopup
                })
            };

            function createPopup(feature) {
                var contentHTML = "<div style='font-size:1.7em'><p><b>Type: </b>" + feature.attributes.type + "<br>"
                + feature.attributes.timeago + "<br>"
                + "<b>Magnitude: </b>" + feature.attributes.magnitude + "<br>"
                + "<b>DateTime: </b>" + feature.attributes.datetime + "<br>"
                + "<b>Region: </b>" + feature.attributes.region + "<br>"
                + "<b>Depth: </b>" + feature.attributes.depth + "<br>"
                + "<b>Source: </b>" + feature.attributes.source + "</p></div>";
                feature.popup = new OpenLayers.Popup.FramedCloud("pop",
                        feature.geometry.getBounds().getCenterLonLat(),
                        null,
                        contentHTML,
                        null,
                        true,
                        function() {
                            controls['selector'].unselectAll();
                        }
                );
                //feature.popup.closeOnMove = true;
                //feature.popup.relativePosition = "tl";
                feature.popup.calculateRelativePosition = function() {
                    return 'tl';
                };

                if (tooltip !== null) {
                     map.removePopup(tooltip);
                    tooltip.destroy();
                    tooltip = null;
                }
                map.addPopup(feature.popup);

            }

            function destroyPopup(feature) {
                feature.popup.destroy();
                feature.popup = null;
                if (tooltip !== null) {
                    map.removePopup(tooltip);
                    tooltip.destroy();
                    tooltip = null;
                }
            }

            function hideTooltip(event) {
                map.removePopup(tooltip);
                tooltip.destroy();
                tooltip = null;
                //OpenLayers.Util.safeStopPropagation(e);
            }

            function showTooltip(event) {
                tooltip = new OpenLayers.Popup.Anchored('tooltip');
                tooltip.displayClass = "olpopupwindow";
                tooltip.lonlat = event.feature.geometry.getBounds().getCenterLonLat();
                //tooltip.size = new OpenLayers.Size(20,20);
                tooltip.contentHTML = "<div style='font-size:.8em'>" + event.feature.attributes.tooltip + "</div>";
                //tooltip.backgroundColor= "#808080";
                tooltip.opacity = 0.9;
                tooltip.autoSize = true;
                var offset = {'size': new OpenLayers.Size(0, 0), 'offset': new OpenLayers.Pixel(50, 30)};
                tooltip.anchor = offset;
                tooltip.panMapIfOutOfView = true;
                tooltip.relativePosition = "bl";
                tooltip.calculateRelativePosition = function() {
                    return 'bl';
                };
                map.addPopup(tooltip);
            }

            map.addControl(controls['highlightCtrl']);
            map.addControl(controls['selector']);
            controls['highlightCtrl'].activate();
            controls['selector'].activate();
0
0

It's actually intented not to work anymore, apparently you cannot create 2 Control features and expect both events to work on them. Instead you need to create one and apply this to both layers. The support for this was removed in 2.7 as stated in the docs. There is a good example of how to do this with 2 different Vector Layers. This took me days to realize. You just need a way in your popup to determine what layer you are on and act accordingly so it seems.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.