简体   繁体   中英

Leaflet WMS Layer does not show when map is re-created

I have a Flask python application where the user can select a vehicle in the web page and depending on which vehicle is selected, the application should propose different WMS layers in the Leaflet layer control that the user can tick on / off depending of his needs. The logic of feeding new layers depending of vehicle selection is done via ajax, where the layers vs vehicle is fetched from a database.

This works fine the first time the vehicle is selected, however, when a different vehicle is selected and then the first vehicle again, the WMS layer does not show in the leaflet map, though the layer name can be selected in the layer control. To avoid having too many checkboxes the vessels has been added to the same marker group so the user only have the vessel group and a couple WMS layers to tick on/off.

I'm sure the solution is dead simple. However have been exhausing 'every' tip I could find on different forums.

JavaScript:

var vesselVar = null;
var mapVessel = null;
var layerControl = null;
var baseMaps = null;
var overlayMaps = null;
var layerNameArr = null;
var layerLinkArr = null;
var baseMapArr = null;
var myVessels = null;
var sLayerName = null;
var sUrl = null;
var wmsOptions = null;
var myWmsLayer = null;

function myOnSelectedVessel() {
    let sSelectedVessel = $('#sSelectedVessel').find(":selected").text()
    if (sSelectedVessel.length > 0) {
        $.ajax({
            url: '/vessel_map_set_vessel_id',
            data: {
                'sSelectedVesselName': sSelectedVessel,
            },
            type: 'POST',
            dataType: 'json',
            success: function (response) {
                if (response.result) {
                    alert(response.msg);
                }
                myCreateOverlay(response.liVessels, response.liLastVesselPos, response.arrLeaflet.toString());
                myCreateBaseLayers();
                myCreateMap(response.lat, response.lon);
                mapVessel.panTo(new L.LatLng(parseFloat(response.lat), parseFloat(response.lon)));
            },
            error: function (error) {
                alert("error in function vessel_map.myOnSelectedVessel");
            }
        });
    }
}


function myCreateVesselGroup(liVessels, liLastVesselPos) {
    try {
        myVessels = null;
        vesselVar = null;
        myVessels = L.layerGroup([]);
        vesselVar = [];
        let iLen = liLastVesselPos.length;
        const arrVesselNames = liVessels.toString().split(',');
        const arrVesselPos = liLastVesselPos.toString().split(',');
        let iCntVesselPos = 0;
        for (let iCn7 = 0; iCn7 < iLen; iCn7++) {
            arrPos = liLastVesselPos[iCn7];
            //alert(arrVesselNames[iCn7]);
            myAddVesselMarker(arrVesselNames[iCn7], arrVesselPos[iCntVesselPos], arrVesselPos[iCntVesselPos + 1]);
            myVessels.addLayer(vesselVar[iCn7]);
            iCntVesselPos += 2;
        }
    }
    catch (err) {
        alert("Error in function myCreateBaseLayers: " + err.message);
    }
}


function myCreateOverlay(liVessels, liLastVesselPos, sLeafletWmsString) {
    try {
        if (mapVessel !== null) {

            if ((overlayMaps !== null) && (layerControl !== null)) {
                mapVessel.eachLayer(function (layer) {
                    mapVessel.removeLayer(layer);
                });
            }
        }
        overlayMaps = null;
        overlayMaps = {};
        myCreateVesselGroup(liVessels, liLastVesselPos)
        overlayMaps['Vessels'] = myVessels;

        if (sLeafletWmsString.length > 1) {
            const arrLeaflet2 = sLeafletWmsString.split(',')
            let iLen = arrLeaflet2.length;
            for (let iCnt4 = 0; iCnt4 < iLen; iCnt4 += 2) {
                sLayerName = null;
                sLayerName = arrLeaflet2[iCnt4].toString();
                wmsOptions = null;
                wmsOptions = {};
                wmsOptions.layers = sLayerName;
                wmsOptions.format = 'image/png';
                wmsOptions.transparent = true;
                wmsOptions.opacity = 0.5;
                sUrl = null;
                sUrl = arrLeaflet2[iCnt4 + 1];
                myWmsLayer = null
                myWmsLayer = new L.tileLayer.wms(sUrl, wmsOptions);
                overlayMaps[sLayerName] = myWmsLayer;
            }
        }
    }
    catch (err) {
        alert("Error in function myCreateOverlay: " + err.message);
    }
}


function myCreateBaseLayers() {
    try {
        layerNameArr = null;
        layerLinkArr = null;
        baseMaps = null;
        layerNameArr = [];
        layerLinkArr = [];
        baseMaps = []
        layerNameArr.push('OpenStreetMap');
        layerLinkArr.push(L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 19, attribution: 'OpenStreetMap', transparent: true }));
        for (iCn2 = 0; iCn2 < layerLinkArr.length; iCn2++) {
            baseMaps[layerNameArr[iCn2]] = layerLinkArr[iCn2];
        }
    }
    catch (err) {
        alert("Error in function myCreateBaseLayers: " + err.message);
    }
}


function myAddVesselMarker(sTitle, dLat, dLon) {
    try {
        var markerOptions = {};
        markerOptions.title = sTitle;
        markerOptions.clickable = true;
        markerOptions.draggable = false;
        var sPopupText = "Lat: " + dLat.toString() + ", Lon: " + dLon.toString();
        vesselVar.push(L.marker([dLat, dLon], markerOptions).bindPopup(sPopupText));
    }
    catch (err) {
        alert("Error in function myAddVesselMarker: " + err.message);
    }
}


function myCreateMap(dLatCenter, dLonCenter) {
    try {
        if (mapVessel !== null) {
            mapVessel.invalidateSize();
            mapVessel.off();
            mapVessel.remove();
        }
        mapVessel = null;
        layerControl = null;
        mapVessel = new L.map('map', { center: [dLatCenter, dLonCenter], zoom: 13, layers: [layerLinkArr[0]] });
        layerControl = new L.control.layers(baseMaps, overlayMaps).addTo(mapVessel);
    }
    catch (err) {
        alert("Error in function myCreateMap: " + err.message);
    }
}

For anybody else that struggles with the same issue. My problem was that the '&' character in the url string is a javascript entity character that is interpreted as javascript code (even though the url string was a varaiable and not in the JS code itself). For the first on load draw I used Flask's Jinja2, which automatically modified all the '&' characters in the url string, hence why the first time draw showed up ok. Once I replaced all the '&' characters in the ajax string, that I sent back to javascript when the user changed a vehicle, with '&amp;', the overlay showed up also when I changed the vehicle.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM