3

How do you update a WMS in a LeafletJS Map?

Using a simple text box and submit button, as well as a variable to hold a CQL filter (SQL query text) I've been able to update the CQL filter value on the WMS layer but cannot figure out how to refresh the WMS image.

The text box simply takes a number, and appends it to a text value to create a simple CQL filter (ex: schnum = 450)

The CQL filter works in the Geoserver Openlayers preview, and serveral methods to test have shown it to work as well.

The problem is one of two things happens depending on the methods I've tried:

  • a new point is added but the old one is not removed
  • the basemap disappears

I've created a JSFiddle* to hopefully demonstrate this simple example: https://jsfiddle.net/dpsspatial/fqa4y1cd/1/

*NOTE: for some reason the script to update the SQL filter - set_sql() - doesn't seem to be recognized in the JSFiddle though it works locally.

2
+300

Can you check below code? I added comments about the errors you listed.

var map = L.map('map').setView([39.707045, -104.940817], 12);
    var sql_text = '1=1';
    var topPane = map.createPane('leaflet-top-pane', map.getPanes().mapPane);
    var bottomPane = map.createPane('leaflet-bottom-pane', map.getPanes().tilePane);
    //load maps
    //load google basemap
    load_schools();

    L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
        attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
    }).addTo(map);

    function load_schools() {
     //defeine schools as a global variable, without var keyword so it can be checked at set_sql function
     schools = L.tileLayer.wms('http://open-geode.dpsk12.org/geoserver/ows?', {
            layers: 'dps-sm:Schools_Current',
            transparent: true,
            format: 'image/png',
            cql_filter: sql_text,
            zIndex: 600,
            opacity: 1
        }).addTo(map);
    };

    function set_sql() {

        //Cause of error "the basemap disappears"
        //this part removes all of the layers(including base layer), so comment it out
        //map.eachLayer(function (layer) {
        //    map.removeLayer(layer);
        //});

        sql_value = document.getElementById('sql_input').value;
        sql_text = 'schnum = ' + sql_value;
        console.log(sql_text);

        //Remove old schools to prevent "a new point is added but the old one is not removed"
        //check if map has schools layer
       if (map.hasLayer(schools)) {
                map.removeLayer(schools);
                //if so, remove previously added schools layer before loading schools with new cql filter
            };

      load_schools(sql_text);
        }
  • I get an error at the map.hasLayer(schools) line of a 'missing semi-colon', but I'm not sure where to put it... thank you for your help with this!!! – DPSSpatial Jul 25 '17 at 16:06
  • Sorry, that line should be if(map.hasLayer(schools)) { – senol ozgur Jul 25 '17 at 16:08
  • I just edited your response to show that update - still can't get it to work, though... the function fires, but the map doesn't show the updated point... – DPSSpatial Jul 25 '17 at 16:24
  • I've tested on my computer and now it's working( with if(map.hasLayer(schools)) { map.removeLayer(schools); //if so, remove previously added schools layer before loading schools with new cql filter } ). – senol ozgur Jul 26 '17 at 5:11
  • Thanks - there are three methods here that are actually all valuable, so I'm testing each with my bigger project... many thanks for your help with this!! – DPSSpatial Jul 26 '17 at 16:02
6

The WMS layer object provides a setParams method that will do what you need. From the docs:

setParams(<Object> params, <Boolean> noRedraw?): Merges an object with the new parameters and re-requests tiles on the current screen (unless noRedraw was set to true).

Here is a fork of your fiddle that demonstrates it. The relevant code is in the set_sql() function:

window.set_sql = function set_sql() {
    var sql_value = document.getElementById('sql_input').value;
    var sql_text = 'schnum = ' + sql_value;
    console.log(sql_text);
    schools.setParams({cql_filter:sql_text});
}

If you open your browser's debug menu, you can see that the tiles are indeed immediately re-requested, and the new URLs include the cql_filter=schnum%20%3D%20263 parameter (for example).

  • 'schnum' doesn't show up as a property in Geoserver – Marc Pfister Jul 25 '17 at 17:07
  • OK that's weird the table I published to the external server had a primary key on SCHNUM but Geoserver wouldn't publish it - now both solutions are working... – DPSSpatial Jul 25 '17 at 17:14
  • Thanks for this - I'm to be utilizing both methods in different applications we're building... – DPSSpatial Jul 31 '17 at 15:50
0

Here is a modified fiddle based on your code. This simply adds and removes the schools layer with a new filter.

The problem you told about the base map disappearing, happened because you where removing all the layers in the set_sql method, and then adding only the schools layer.

// This was removing all the layers including the basemap
map.eachLayer(function(layer) {
    map.removeLayer(layer);
});

Edit: csd's is a better answer. Cleaner, and using an api method instead of a workaround.

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.