1

I'm creating a map with multiple KML layers, and have been able to get the KMLs to appear, however, implementing a simple checkbox to turn each layer on and off is proving to be a problem. I've tried omnivore, and several other plugin things, but none seem to work properly.

HTML Toggle:

<input type="checkbox" id="toggleScottsdale" onclick="toggleScottsdale();"><label>&nbsp;SCT AIR</label><br>
<input type="checkbox" id="toggleSilo" onclick="toggleSilo();"><label>&nbsp;MES SLO</label> 

Example KML Layer (there are 5 in total):

fetch('urltofile1.kml')
        .then(res => res.text())
        .then(kmltext => {
            // Create Scottsdale Overlay
            const parser = new DOMParser();
            const kml = parser.parseFromString(kmltext, 'text/xml');
            const scottsdale = new L.KML(kml);
            map.addLayer(scottsdale);
        }); 
fetch('urltofile2.kml')
        .then(res => res.text())
        .then(kmltext => {
            // Create Silo Overlay
            const parser = new DOMParser();
            const kml = parser.parseFromString(kmltext, 'text/xml');
            const scottsdale = new L.KML(kml);
            map.addLayer(silo);
        }); 

Toggle Function:

function toggleScottsdale() {
        if(map.addLayer(scottsdale)) {
            map.removeLayer(scottsdale);
        } else {
            map.addLayer(scottsdale);
        }
    }; 
function toggleSilo() {
        if(map.addLayer(silo)) {
            map.removeLayer(silo);
        } else {
            map.addLayer(silo);
        }
    };

Not only does console return that scottsdale is undefined, but I am unsure how to replicate a toggle for each layer.

1 Answer 1

0

One possible solution would be to store KML overlays in some global object, using overlay name as property name, and then use general toggleOverlay function that add/removes overly to the map on the basis of checkbox id that corresponds to overlay name.

Code could then look something like this:

HTML

<input type="checkbox" id="scottsdale" onclick="toggleOverlay(this)" checked><label>&nbsp;SCT AIR</label><br>
<input type="checkbox" id="silo" onclick="toggleOverlay(this)" checked><label>&nbsp;MES SLO</label> 

JS

var overlays = {};

function toggleOverlay(checkbox) {
  var overlay = overlays[checkbox.id];
  if (map.hasLayer(overlay)) {
    if (!checkbox.checked) map.removeLayer(overlay);
    }
  else if (checkbox.checked) {
    map.addLayer(overlay);
  }
}

fetch('urltofile1.kml')
  .then(res => res.text())
  .then(kmltext => {
    const parser = new DOMParser();
    const kml = parser.parseFromString(kmltext, 'text/xml');
    const scottsdale = new L.KML(kml);
    map.addLayer(scottsdale);
    overlays['scottsdale'] = scottsdale;
  }); 
fetch('urltofile2.kml')
  .then(res => res.text())
  .then(kmltext => {
    const parser = new DOMParser();
    const kml = parser.parseFromString(kmltext, 'text/xml');
    const silo = new L.KML(kml);
    map.addLayer(silo);
    overlays['silo'] = silo;
  }); 
7
  • Thanks for that - this was one of the initial solutions I had found elsewhere, but when I implement it, nothing happens but an error message in the console: (index):103 Uncaught TypeError: Cannot read properties of undefined (reading 'id') at toggleOverlay ((index):103:35) at HTMLInputElement.onclick ((index):31:77) Commented Feb 25, 2023 at 14:28
  • I implemented your version and got the same result, I thin I'm still missing some things - and have updated the question to include the entire script Commented Feb 25, 2023 at 14:33
  • You have toggleOverlay function defined twice. In the second definition (which prevails) you are using condition if (!checkbox.unchecked) map.removeLayer(overlay). Property unchecked does not exist.
    – TomazicM
    Commented Feb 25, 2023 at 14:41
  • I've been staring at this stuff too long - I sure did, thanks for pointing that out! After removing the second var overlays and toggleOverlay function, I'm still getting that error: Uncaught TypeError: Cannot read properties of undefined (reading 'id') at toggleOverlay ((index):42:35) at HTMLInputElement.onclick ((index):29:77) Commented Feb 25, 2023 at 15:10
  • Ups, sorry, missing parameter this when specifying onclick handler. See modified answer.
    – TomazicM
    Commented Feb 25, 2023 at 15:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.