1

I've got a webmap showing data coming from a Geoserver instance. With better.WMS.js I made it possible to display popups.

Everything works nice except that the map shows popups too where there is no feature selected.

The code is hosted on GitHub. I'll try to put a working map online though one may see the problem clearly. The map shouldn't display a popup window when no feature is selected.

Does anyone has an idea how to fix that?

  • It was suggested as a quick-and-dirty workaround here but as the author states there might be a nicer solution. – hoge6b01 Mar 19 '15 at 15:58
2

You can switch to infoformat=application/json so you will get a json response from Geoserver. Then just check how many features are returned and if features.length>0 is true show the popup otherwise not. For this solution you will have to create a table from the json-response. You could do something like that:

set infoformat in your L.TileLayer.BetterWMS.js:

params = {
          request: 'GetFeatureInfo',
          service: 'WMS',
          srs: 'EPSG:4326',
          styles: this.wmsParams.styles,
          transparent: this.wmsParams.transparent,
          version: this.wmsParams.version,      
          format: this.wmsParams.format,
          bbox: this._map.getBounds().toBBoxString(),
          height: size.y,
          width: size.x,
          layers: this.wmsParams.layers,
          query_layers: this.wmsParams.layers,
          info_format: 'application/json'
          ,propertyName:'LAND,DATUM'  // only get attributes "Land" and "Name"
        };

// Create a function that will return a table from a json response:

function buildpopup(content){

    var record; 

    var info = "<div class=\"mypopupinfo\">";

    for (var i=0 ; i < content.features.length; i++ ){

        record = content.features[i];

        info += "<div class=\"popupinfo\"><table>"
        info += "<tr><th><b>Name: </b></th></tr>";
        info += "<tr><td>" + record.properties.name + "</td></tr>";
        info+="</table></div>";


        if (i!= (content.features.length-1)){
            info += "<br />";
        }

    }

    info += "</div>"


    return info;

}

and use this function while setting the content of the popup:

    showGetFeatureInfo: function (err, latlng, content) {
    if (err) {
    return;
    } // do nothing if there's an error

    if (content.features.length>0)
    {
    // Otherwise show the content in a popup, or something.
    L.popup({ maxWidth: 800})
      .setLatLng(latlng)
      .setContent(buildpopup(content))
      .openOn(this._map);
      }
      else 
      {
      }
  }

Screenshot from my working example with json response: enter image description here

EDIT1: added two gists:

html-part: https://gist.github.com/anonymous/aa86f117f1342179f2e3

js-part: https://gist.github.com/anonymous/f6e7dc3d4eff9e0ed62b

  • If I see your screenshot seems to work. I couldn't get it work. Would you mind to post the .js and the index.html? thank you – hoge6b01 Mar 25 '15 at 22:08
  • just added two gists above ;) – Thomas B Mar 26 '15 at 11:44
1

Here is what I do:

In your GeoServer content.ftl file (explained here FTL), add a hidden list item like this:

<li style="display:none";>popup</li>

You can change the key word 'popup' to anything you like. You will be searching for this word in you popup javascript. This word will only appear in the getFeatureInfo request if there is a feature returned.

Then use the JavaScript to search for the word in the returned text. If you don't see the key word, then don't open the popup. In OpenLayers 2, it would look something like this:

var info = new OpenLayers.Control.WMSGetFeatureInfo
({
    url : 'https://myserver/geoserver/wms',
    layerUrls : [('https://myserver/geoserver/gwc/service/wms')],
    layers : [layer1, layer2],
    queryVisible : true,
    eventListeners : {
        getfeatureinfo : function (event) {
            if (event.text.search("popup") != -1) {
                var myPopup = new myPopupClass
                    (
                        "chicken",
                        map.getLonLatFromPixel(event.xy),
                        null,
                        event.text,
                        null,
                        true);
                map.addPopup(myPopup);
            }
        }
    }
});

The event.text.search will be looking for your key word. If you don't see it, don't add the popup.

  • Might be a solution. But only if one has access to the .ftl file. If requesting a third-party GeoServer this solution wouldn't work. – hoge6b01 Mar 26 '15 at 8:52
  • Fair enough. Then you could look at the feature vs no feature response difference in something like the google chrome debbugger (hit F12 in chrome). Go to the Network tab. If you click on an area that has no feature, the response would not contain the <li> item. You can then search for '<li...', or whatever you find in the feature response vs the non-feature response. Look for that in you event.text.search and open the popup accordingly. – maw269 Mar 26 '15 at 15:58

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.