1

I have an application that is using OpenLayers 2.13.1. It is utilizing a bing basemap and overlaying WMS layers. I am using a FramedCloud popup. I would like the popup to appear where the user clicked and sometimes it does. Sometimes it appears randomly to the east or west of where the user clicked. Here is a snipit of code:

    this.click_radons = function(layerName) {
    if (layerName == "State Boundaries") {
        return null;
    }
    var map = innovateMapObj.map,
            layer = null,
            serviceURL = null,
            layers = map.layers.slice(),
            content = "",
            desc = null,
            img = null,
            priority = null;

    //because we don't want to query base layer
    for (var i = 0; i < layers.length; i++) {
        if (!(layers[i].isBaseLayer)) {
            layer = layers[i];
            serviceURL = layers[i].url;
            break;
        }
    }


    OpenLayers.ProxyHost = innovate.proxyURL;
    return new OpenLayers.Control.WMSGetFeatureInfo({
        layers: [layer],
        url: serviceURL,
        title: 'Identify features by clicking',
        queryVisible: true,
        eventListeners: {
            getfeatureinfo: function(event) {
                var thisObject = new innovate.Controls(innovateMapObj)
                obj = thisObject.makeObjectOutOfResponse(event.text);

                var boxSize = null;
                var mapID = innovateMapObj.config.id;
                //hide any open popup on click
                if (innovate.popupbox[mapID]) {
                    map.removePopup(innovate.popupbox[mapID]);
                    innovate.popupbox[mapID].destroy();
                    //$("#innovate_info_popup_" + mapID).hide();
                }
                if ($.isEmptyObject(obj) || obj === false) {
                    return;
                }
                innovate.lastPopupCenter[mapID] = map.getCenter();

                if (obj['radonzone'] == 1) {
                    desc = "<b>Zone 1 </b>counties have a predicted average indoor radon screening level greater than 4 pCi/L (picocuries per liter) <b>(red zones)</b>";
                    priority = "<b>Highest Potential</b>";
                    img = "3b6a386668a6d07b8d8e029744820282";
                } else if (obj['radonzone'] == 2) {
                    desc = "<b>Zone 2 </b>counties have a predicted average indoor radon screening level between 2 and 4 pCi/L <b>(orange zones)</b>";
                    priority = "<b>Moderate Potential</b>";
                    img = "52edb92fef3b3447d910ea3f4e3bad06";
                } else if (obj['radonzone'] == 3) {
                    desc = "<b>Zone 3 </b>counties have a predicted average indoor radon screening level less than 2 pCi/L <b>(yellow zones)</b>";
                    priority = "<b>Low Potential</b>";
                    img = "d1573b09a0505bef245b2a380a18e380";
                }
                var stateName = obj['statename'], initCapedStateName = "";
                stateName = stateName.split(" ");
                for (var keys in stateName) {
                    initCapedStateName += stateName[keys].substr(0, 1) + stateName[keys].substr(1).toLowerCase() + " ";
                }

                var imgURL = innovate.mapServiceBaseURL["legend"] + innovateMapObj.config.legend["url"] + "/../0/images/" + img;
                content = "<div>" + obj['namelsad'] + ", " + initCapedStateName + "</div>" +
                        "<div>Radon risk zone: " + obj['radonzone'] + "</div>" +
                        "<table style=\"width:420px\height:120px\"><tbody><tr style=\"background-color: #EEEEEE; border-color:#DDDDDD;border-style: solid; border-width: 1px 0 1px 0px;padding: 5px;\"><td valign=\"top\" align=\"center\"><div><img alt=\"\" src=\"" + imgURL + "\"></div></td>" +
                        "<td valign=\"top\" align=\"left\">" + desc + "</td>" +
                        "<td valign=\"top\" align=\"left\">" + priority + "</td></tr></tbody></table>";


                    innovate.popupbox[mapID] = new OpenLayers.Popup.FramedCloud(
                            "innovate_info_popup_" + mapID,
                            map.getLonLatFromViewPortPx(event.xy),
                            boxSize,
                            content,
                            null,
                            true,
                            function() {
                                this.div.style.display = 'none';
                                map.panTo(innovate.lastPopupCenter[mapID]);
                                map.removePopup(innovate.popupbox[mapID]);
                                }
                            );

                    map.addPopup(innovate.popupbox[mapID]);

            }
        }
    });
}

The problem is that sometime the popup appears east or west of where the user clicked on the map. This happens very inconsistently. I haven't been able to make the error occurr consistently. Any suggestions would be greatly appreciated.

The following code is from the Innovate class:

var innovate = {
popupbox: {}
,curMapPos: 0
,curMapID: 0
,openedMap: {}//collection of all innovate.Map objects
,opacitySelectors: {}
,legendOpen: false
,baseFolder: ""
,lastPopupCenter: {}
,fullScreenOn: false
,

proxyURL: "proxy.jsp?"
,

buildMap: function(v_mapID) {
    var obj = new innovate.Map(v_mapID);
    obj.buildMap();
    this.openedMap[v_mapID] = obj;
},
/*
 * Defined the base URL for maps and legends so when they change, I don't have to    serach and change in all files
 */
mapServiceBaseURL: {
    "map": "Put base URL here",
    "legend": "Put base URL here"
}
,
getUserConfigForMap: function(mapId) {
    for (i = 0; i < innovate_config.maps.length; i++) {
        if (innovate_config.maps[i]['id'] == mapId) {
            return innovate_config.maps[i];
        }
    }
    return null;
}
}

Below is code called for one map from the getUserConfigForMap

{
    'id':8//must match param id
    ,'header':'Map'
    ,'startResolution':2//gets the resolution from serverResolutions using the startResolution as index
    ,'endResolution':9//number of zoom levels you want, 21 is max and must be greater than startResolution
    ,'projection' : 'EPSG:3857'
    ,'maxExtent' : [-19951913.2278,-1643352.8198,20021888.1032,11554793.571]
    //,'zoomToExtent' : [-14617039.6948417,2697596.8976282,-6500380.5111317,6713979.93039427]
    ,'center' : [-120,38] 
    ,'defaultZoomLevel' : 3
    ,'footNote':'This is a test footer note for this exhibit'
    ,'dataSource':'Data Source'
    ,'legend':{
        "url":'Url without base url'
    }
    , 'baseMap': ['arcGisCanvasWorldLightGrayBase']
    ,'layers':['wms_layer','wms_stateboundariesThick']
    ,'controls':['Navigation','LayerSwitcher','click_radons','InnovateMapFullScreen','ScaleLine','Attribution','InnovateMapLegend']
    ,'hide_controls':['Navigation','PanZoomBar']
} 
2

You modify the size, content and location of your popup after it's creation. After the object creation, but before rendering, OpenLayers calculates relative size, position, etc of the popup and it's really hard to keep track of it. Simply destroy the popup and create a new one instead of saving it in a global variable, you will save a lot of headache.

...
    eventListeners: {
        getfeatureinfo: function (event) {
            var thisObject = new innovate.Controls(innovateMapObj)
                    , eventResponse = thisObject.getTableContentOutOfResponse(event.text);

            var boxSize = null;
            var mapID = innovateMapObj.config.id;
            //remove any open popup on click
            if (innovate.popupbox[mapID]) {
                map.removePopup(innovate.popupbox[mapID]);
                innovate.popupbox[mapID].destroy();
            }
            if (!(eventResponse)) {
                return;
            }

                //always create a new popup as OL calculates everything on creation
                innovate.popupbox[mapID] = new OpenLayers.Popup.FramedCloud(
                        "innovate_info_popup_" + mapID,
                        map.getLonLatFromViewPortPx(event.xy),
                        boxSize,
                        content,
                        null,
                        true,
                        function () {
                            this.div.style.display = 'none';
                            map.panTo(innovate.lastPopupCenter[mapID]);
                        }
                );
                map.addPopup(innovate.popupbox[mapID]);
                // Don't do that, let OL do it for you
                /*
                boxSize = new OpenLayers.Size((parseInt(($("#innovate_info_popup_" + mapID + "_contentDiv").css("width")).replace("px", "")) + 10), (parseInt(($("#innovate_info_popup_" + mapID + "_contentDiv").css("height")).replace("px", "")) + 20));
                innovate.popupbox[mapID].setSize(boxSize);
                */
            }
        }
    }
});

If you explain why you are setting the popup size after the popup creation, we can find a solution for that too.

  • Thanks, I have modified the code to only use one popup and it still will sometime offset the location of the popup away, either east or west of where the user clicks. Do I need to add any code for when the popup closes to destroy the popup? – dyarnell Nov 21 '13 at 16:37
  • Since you want to change the size of your popup, you need to destroy it and recreate it. I missed that in my answer so I edited it to add innovate.popupbox[mapID].destroy();. So to answer your question, yes you need to destroy it manually. – Julien-Samuel Lacroix Nov 21 '13 at 16:55
  • Ok I'm destroying the popups after the are used now. I am having the same problem though. Any ideas of what could be causeing such a random issue? – dyarnell Nov 22 '13 at 23:48
  • Please update your question with your new code or open a new question if it's another issue. – Julien-Samuel Lacroix Nov 23 '13 at 16:16
  • I have updated the code in my question, and has not changed. The popup sometime will place it's self east or west of where the user clicks on the map. – dyarnell Nov 25 '13 at 16:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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