1

The leaflet map (image map in CRS Simple) was created using QGIS2WEB and I am trying to display the content of pop-up at a constant position (top-corner), opening when hovered over a polygon by the function highlightFeature.

The popup Content should appear into a Custom Info Control, as explain here (https://leafletjs.com/examples/choropleth/). I don't understand (perpetual newbie here) how to write the var popupContent into the props function.

The Pop-up text is based on infos contained in a CSS file and returned through this lines

var popupContent = '<table>\
        <tr>\
          <th scope="row">\
            <td>' + (feature.properties['Themen'] !== null ? autolinker.link(feature.properties['Themen'].toLocaleString()) : '') + '</td>\
       </tr>\
       <tr>\
          <th scope="row">\
            <td>' + (feature.properties['Description'] !== null ? autolinker.link(feature.properties['Description'].toLocaleString()) : '') + '</td>\
        </tr>\
    </table>';

This is what I want to integrate into the QGIS2web export

    var info = L.control();
    
    info.onAdd = function (map) {
        this._div = L.DomUtil.create('div', 'info'); // create a div with a class "info"
        this.update();
        return this._div;
    };
    
    // method that we will use to update the control based on feature properties passed
    info.update = function (props) {
        this._div.innerHTML = '<h4>US Population Density</h4>' +  (props ?
            '<b>' + props.name + '</b><br />' + props.density + ' people / mi<sup>2</sup>'
            : 'Hover over a state');
    };
    
    info.addTo(map);

Here is the full code of the QGIS2web html export

<!doctype html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="initial-scale=1,user-scalable=no,maximum-scale=1,width=device-width">
        <meta name="mobile-web-app-capable" content="yes">
        <meta name="apple-mobile-web-app-capable" content="yes">
        <link rel="stylesheet" href="css/leaflet.css">
        <link rel="stylesheet" href="css/qgis2web.css"><link rel="stylesheet" href="css/fontawesome-all.min.css">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
        <style>
        html, body, #map {
            width: 100%;
            height: 100%;
            padding: 0px;
            margin: 10px;
        }
        #map {
            width: 1000px;
            height: 700px;
            }
        </style>
        <title></title>
    </head>
    <body>
        <div id="map">
        </div>
        <script src="js/qgis2web_expressions.js"></script>
        <script src="js/leaflet.js"></script>
        <script src="js/leaflet.rotatedMarker.js"></script>
        <script src="js/leaflet.pattern.js"></script>
        <script src="js/leaflet-hash.js"></script>
        <script src="js/Autolinker.min.js"></script>
        <script src="js/rbush.min.js"></script>
        <script src="js/labelgun.min.js"></script>
        <script src="js/labels.js"></script>
        <script src="data/TZ_Feldarbeiten_buffer_1.js"></script>
        <script>
        var highlightLayer;
        function highlightFeature(e) {
            highlightLayer = e.target;
            highlightLayer.openPopup();
        }
        var map = L.map('map', {
        crs: L.CRS.Simple,
            zoomControl:true, maxZoom:3, minZoom:-2
        }).fitBounds([[0,0],[-2327.0,3295.0]])      
        .setView([0, 0]);;
        var bounds = L.latLngBounds([[0.0, 3295.0], [-2327.0,0]]);
        map.setMaxBounds(bounds);
        map.on('drag', function() {
        map.panInsideBounds(bounds, { animate: false });
        }); 
        
        var hash = new L.Hash(map);
        //map.attributionControl.setPrefix('<a href="https://github.com/tomchadwin/qgis2web" target="_blank">qgis2web</a> &middot; <a href="https://leafletjs.com" title="A JS library for interactive maps">Leaflet</a> &middot; <a href="https://qgis.org">QGIS</a>');
        var autolinker = new Autolinker({truncate: {length: 30, location: 'smart'}});
        var bounds_group = new L.featureGroup([]);
        function setBounds() {
            if (bounds_group.getLayers().length) {
                map.fitBounds(bounds_group.getBounds());
            }
        }
        
        map.createPane('pane_Wimmelbild_Interactiv4_nolabel_0');
        map.getPane('pane_Wimmelbild_Interactiv4_nolabel_0').style.zIndex = 400;
        var img_Wimmelbild_Interactiv4_nolabel_0 = 'data/Wimmelbild_Interactiv4_nolabel_0.png';
        var img_bounds_Wimmelbild_Interactiv4_nolabel_0 = [[0.0,0.0],[-2327.0,3295.0]];
        var layer_Wimmelbild_Interactiv4_nolabel_0 = new L.imageOverlay(img_Wimmelbild_Interactiv4_nolabel_0,
                                              img_bounds_Wimmelbild_Interactiv4_nolabel_0,
                                              {pane: 'pane_Wimmelbild_Interactiv4_nolabel_0'});
        bounds_group.addLayer(layer_Wimmelbild_Interactiv4_nolabel_0);
        map.addLayer(layer_Wimmelbild_Interactiv4_nolabel_0);
        function pop_TZ_Feldarbeiten_buffer_1(feature, layer) {
            layer.on({
                mouseout: function(e) {
                    if (typeof layer.closePopup == 'function') {
                        layer.closePopup();
                    } else {
                        layer.eachLayer(function(feature){
                            feature.closePopup()
                        });
                    }
                },
                mouseover: highlightFeature,
            });
            var popupContent = '<table>\
                    <tr>\
                        <th scope="row">\
                        <td>' + (feature.properties['Themen'] !== null ? autolinker.link(feature.properties['Themen'].toLocaleString()) : '') + '</td>\
                    </tr>\
                    <tr>\
                        <th scope="row"><strong></strong>\
                        <td>' + (feature.properties['Descriptio'] !== null ? autolinker.link(feature.properties['Descriptio'].toLocaleString()) : '') + '</td>\
                    </tr>\
                </table>';
            
            layer.bindPopup(popupContent, {maxHeight: 200, closeButton: false}).openPopup();
        }

        function style_TZ_Feldarbeiten_buffer_1_0() {
            return {
                pane: 'pane_TZ_Feldarbeiten_buffer_1',
                opacity: 1,
                color: 'rgba(35,35,35,1.0)',
                dashArray: '',
                lineCap: 'butt',
                lineJoin: 'miter',
                weight: 1.0, 
                fill: true,
                fillOpacity: 1,
                fillColor: 'rgba(229,182,54,1.0)',
                interactive: true,
            }
        }
        map.createPane('pane_TZ_Feldarbeiten_buffer_1');
        map.getPane('pane_TZ_Feldarbeiten_buffer_1').style.zIndex = 401;
        map.getPane('pane_TZ_Feldarbeiten_buffer_1').style['mix-blend-mode'] = 'normal';
        var layer_TZ_Feldarbeiten_buffer_1 = new L.geoJson(json_TZ_Feldarbeiten_buffer_1, {
            attribution: '',
            interactive: true,
            dataVar: 'json_TZ_Feldarbeiten_buffer_1',
            layerName: 'layer_TZ_Feldarbeiten_buffer_1',
            pane: 'pane_TZ_Feldarbeiten_buffer_1',
            onEachFeature: pop_TZ_Feldarbeiten_buffer_1,
            style: style_TZ_Feldarbeiten_buffer_1_0,
        });
        bounds_group.addLayer(layer_TZ_Feldarbeiten_buffer_1);
        map.addLayer(layer_TZ_Feldarbeiten_buffer_1);
        var title = new L.Control();
            title.onAdd = function (map) {
                this._div = L.DomUtil.create('div', 'info');
                this.update();
                return this._div;
            };
            title.update = function () {
                this._div.innerHTML = '<h2>Die Entwicklungszusammenarbeit</h2>';
            };
            title.addTo(map);
            
        var baseMaps = {};
        L.control.layers(baseMaps,{'<img src="legend/TZ_Feldarbeiten_buffer_1.png" /> TZ_Feldarbeiten_buffer': layer_TZ_Feldarbeiten_buffer_1,"Wimmelbild_Interactiv4_nolabel": layer_Wimmelbild_Interactiv4_nolabel_0,}).addTo(map);
        setBounds();
        L.ImageOverlay.include({
            getBounds: function () {
                return this._bounds;
            }
        });


        </script>
    </body>
</html>

How should it be written?

0
0

If you look at the cited Leaflet choropleth example , you'll see that info.update method updates contents of info control. info.update is called within highlightFeature event processing feature when mouse gets over a feature, taking as parameter properties object of the feature.

You just have to apply the same logic in you case. Relevant code could then look something like this:

var info = L.control();

info.onAdd = function (map) {
  this._div = L.DomUtil.create('div', 'info');
  this.update();
  return this._div;
};

info.update = function (props) {
  var infoContent = '<h4>Info about feature</h4>';
  if (props)
    infoContent += '<table>\
      <tr>\
        <th scope="row">\
        <td>' + (props['Themen'] !== null ? autolinker.link(props['Themen'].toLocaleString()) : '') + '</td>\
      </tr>\
      <tr>\
        <th scope="row"><strong></strong>\
        <td>' + (props['Descriptio'] !== null ? autolinker.link(props['Descriptio'].toLocaleString()) : '') + '</td>\
      </tr>\
    </table>';
  else {
    infoContent += 'Hover over a feature';
  }
  this._div.innerHTML = infoContent;
};
info.addTo(map);

function highlightFeature(e) {
  layer = e.target;
  info.update(layer.feature.properties);
}

function resetHighlight(e) {
  info.update();
}

function pop_TZ_Feldarbeiten_buffer_1(feature, layer) {
  layer.on({
    mouseout: resetHighlight,
    mouseover: highlightFeature
  });
}
1
  • It works perfectly and I got to understand a bit more how it should be organised. Thanks for your help
    – Per Nett
    Sep 17 at 8:17

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.