Search code examples
javascripthtmlopenlayerskml

show popups correctly with external hyperlinks in openlayers 4


I have an openlayers map that loads a couple of kml files containing about 120 polygon placemarks each. As they're too many to show a popup for each, I had to create an outside-map menu, so the user can click on any one of these features and see it's info / location.

I use this function to create the outside-map menu, containing all the features:

        vEnergeticos.getSource().on('change', function(evt){
            var source = evt.target;
            if (source.getState() === 'ready') {
                var energeticos = source.getFeatures();
                for (var i in energeticos) {
                    var figura = energeticos[i].getGeometry().getExtent();
                    var myCenter = ol.extent.getCenter(figura);
                    $("#containerLeft").append("<a href=javascript:showMenuPopup(" + myCenter + "," + energeticos[i].get('ID') + ")>" + energeticos[i].get('name') + "</a><br>");
                }
            }
        });

and then when the user clicks on any of these options, this function is called:

        function showMenuPopup(xx, yy, theID){
            var myPixel = map.getPixelFromCoordinate([xx, yy]);
            var elNombre = "";
            var laDescripcion = "";
            map.forEachFeatureAtPixel(myPixel, function(feature, layer) {
                if (feature.get('ID') == theID){
                    elNombre = feature.get('name');
                    laDescripcion = feature.get('description');
                }
            });

            popupTitle.innerHTML = elNombre;
            popupContent.innerHTML = laDescripcion;
            overlay.setPosition([xx,yy]);
        }

This works in some situations, however, when the selected feature is outside of the current map view, the map relocates successfully (overlay.setPosition([xx,yy]);), the popup is shown, but the popup is empty. If the feature is visible when the user clicks from the left menu, then the popup is shown correctly.

Just to be clear enough, imagine you're seeing a map where you can see part of Europe, and then you click on some item located in Canada (using the off-map menu), you'll see the map relocates in Canada, but the popup that is shown is empty. If you click again on that very same off-map link, or any other feature that is visible at that location/zoom view, then the popup is shown correctly.

I tried to use the "moveend (ol.MapEvent)" in order to fix this, so the popup was loaded after the map is relocated, but it didn't work for me. The moveend event is called before the map starts to move using overlay.setPosition([xx,yy]), and I haven't been able to find some other "after-relocation" event that I could use.

I've been struggling with this for many days now, so any help will be really appreciated.

Regards!!


Solution

  • The problem is that the features outside of the current map view are not "AtPixel", so you won't catch them with map.forEachFeatureAtPixel.

    I suggest you to avoid passing coordinates to showMenuPopup: you just need the feature id, than you can retrieve the feature's coordinates inside showMenuPopup.

    $("#containerLeft").append("<a href=javascript:showMenuPopup('" + energeticos[i].getId() + "')>" + energeticos[i].get('name') + "</a><br>");
    

    Then

    function showMenuPopup(featureId){
        var feature = vEnergeticos.getSource().getFeatureById(featureId);
        var elNombre = feature.get('name');
        var laDescripcion = feature.get('description');
        var figura = feature.getGeometry().getExtent();
        var myCenter = ol.extent.getCenter(figura);
    
        popupTitle.innerHTML = elNombre;
        popupContent.innerHTML = laDescripcion;
        overlay.setPosition(myCenter);
    }