1

Is it possible to change the opacity for the .kml file, that has been attached via leaflet-plugin?

Basically the plugin is here:

https://github.com/windycom/leaflet-kml

but after implementation into the Leaflet we have a full opaque image. It's fine for placemarks, but how about the icons/images included, which cover some box on the map?

My code looks like this:

var kml = fetch('Coventry.kml')
      .then( res => res.text() )
      .then( kmltext => {

            // Create new kml overlay
            parser = new DOMParser();
            kml = parser.parseFromString(kmltext,"text/xml");

            console.log(kml)

            const track = new L.KML(kml)
            map.addLayer(track)
            // Adjust map to show the kml
            const bounds = track.getBounds()
            map.fitBounds( bounds )
      }).setOpacity(0.6).addTo(map)

      $('#sldOpacity').on('change', function(){
$('#image-opacity').html(this.value);
kml.setStyle({opacity: this.value, fillOpacity: this.value});
 });

whereas to the pure code straight from the leaflet-kml example I added up sth like: .setOpacity(0.6).addTo(map)

but isn't working.

The console states, that:

Uncaught TypeError: fetch(...).then(...).then(...).setOpacity is not a function at (index):143

I was also trying this example:

Change opacity using leaflet without plugin

but it didn't help me unfortunately

In the L.KML.js file I found a snip:

 var value = e.childNodes[0].nodeValue;
                if (key === 'color') {
                    options.opacity = parseInt(value.substring(50, 50), 16) / 255.0;
                    options.color = '#' + value.substring(6, 8) + 
value.substring(4, 6) + value.substring(2, 4);
                } else if (key === 'width') {,

where in value.substring I put 50 instead of 0. No result at all.

Is it some way to make this .kml layer more transparent?

enter image description here

0

2 Answers 2

4

You mixed a few things here. kml is XML object, not a Leaflet layer, so you cannot set opacity to it with setOpacity function or add it to the map.

Leaflet layer that comes from kml and you are interested in is track. This is feature group layer for which you can set style with setStyle method. You have to declare it outside fetch, so it be available later to change it's opacity with slider.

Your code could then look something like this:

var track;

var kml = fetch('Coventry.kml')
  .then( res => res.text() )
  .then( kmltext => {
        parser = new DOMParser();
        kml = parser.parseFromString(kmltext,"text/xml");
        track = new L.KML(kml);
        map.addLayer(track);
        const bounds = track.getBounds();
        map.fitBounds(bounds);
  });

$('#sldOpacity').on('change', function(){
  $('#image-opacity').html(this.value);
  track.setStyle({opacity: this.value, fillOpacity: this.value});
 });

EDIT: In your JSFiddle code you are using JQuery without link to library and you are using slider code without required HTML elements. Here is working JSFiddle (KML is defined in code): https://jsfiddle.net/TomazicM/7nxfgtu8/

Here is the main part of the code:

<body>
<div id="mapid"></div>
<div>
  <span id="image-opacity">0.5</span>
  <input type="range" id="sldOpacity" min="0" max="1" step="0.1" value="0.5" />
</div>
<script>
var myKML = '<?xml version="1.0" encoding="UTF-8"?>' +
  '<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom"> ' +
  '<Document> ' +
    '<name>polygon.kml</name> ' +
    '<Style id="transYellowPoly"> ' +
      '<LineStyle> ' +
        '<width>1.5</width> ' +
      '</LineStyle> ' +
      '<PolyStyle> ' +
        '<color>7d00ffff</color> ' +
      '</PolyStyle> ' +
    '</Style> ' +
    '<Placemark> ' +
      '<name>Building 43</name> ' +
      '<visibility>0</visibility> ' +
      '<styleUrl>#transYellowPoly</styleUrl> ' +
      '<Polygon> ' +
        '<extrude>1</extrude> ' +
        '<altitudeMode>relativeToGround</altitudeMode> ' +
        '<outerBoundaryIs> ' +
          '<LinearRing> ' +
            '<coordinates> -122.0844371128284,37.42177253003091,19 ' +
              '-122.0845118855746,37.42191111542896,19 ' +
              '-122.0850470999805,37.42178755121535,19 ' +
              '-122.0850719913391,37.42143663023161,19 ' +
              '-122.084916406232,37.42137237822116,19 ' +
              '-122.0842193868167,37.42137237801626,19 ' +
              '-122.08421938659,37.42147617161496,19 ' +
              '-122.0838086419991,37.4214613409357,19 ' +
              '-122.0837899728564,37.42131306410796,19 ' +
              '-122.0832796534698,37.42129328840593,19 ' +
              '-122.0832609819207,37.42139213944298,19 ' +
              '-122.0829373621737,37.42137236399876,19 ' +
              '-122.0829062425667,37.42151569778871,19 ' +
              '-122.0828502269665,37.42176282576465,19 ' +
              '-122.0829435788635,37.42176776969635,19 ' +
              '-122.083217411188,37.42179248552686,19 ' +
              '-122.0835970430103,37.4217480074456,19 ' +
              '-122.0839455556771,37.42169364237603,19 ' +
              '-122.0840077894637,37.42176283815853,19 ' +
              '-122.084113587521,37.42174801104392,19 ' +
              '-122.0840762473784,37.42171341292375,19 ' +
              '-122.0841447047739,37.42167881534569,19 ' +
              '-122.084144704223,37.42181720660197,19 ' +
              '-122.0842503333074,37.4218170700446,19 ' +
              '-122.0844371128284,37.42177253003091,19 </coordinates> ' +
          '</LinearRing> ' +
        '</outerBoundaryIs> ' +
      '</Polygon> ' +
    '</Placemark> ' +
  '</Document> ' +
  '</kml>';

  var map = L.map('mapid').setView([37.42222, -122.08395], 14);
    L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
      attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a     href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a   href="https://www.mapbox.com/">Mapbox</a>',
        maxZoom: 21,
        id: 'mapbox.streets',
        accessToken: 'pk.eyJ1Ijoia3J1a2FyaXVzIiwiYSI6ImNqZ2tuaHZqODAxMjYzM28yam40MmpxMmEifQ.3chgJkJajjDBxsF4YHgENA'
    }).addTo(map);

  parser = new DOMParser();
  kml = parser.parseFromString(myKML,"text/xml");
  track = new L.KML(kml);

  map.addLayer(track);
  const bounds = track.getBounds();
  map.fitBounds(bounds);

  sldOpacity.onchange = function() {
    document.getElementById('image-opacity').innerHTML = this.value;
    track.setStyle({fillOpacity: this.value});
  };
</script>
</body>

Remark: If you just copy code from various sources without understanding what it does you'll be in trouble all the time.

12
  • Hi, I implemented your code, which looks correct (map looks as it was). But the layer is still opaque. I have created in my <style> section: #image-opacity { opacity: 0.6; } #sldOpacity { opacity: 0.6; } regarding to this function, but it's also not correct. I found something also here: stackoverflow.com/questions/47270647/… which means, that GeoJSON cannot be runned from the #sldOpacity function, although my file is .kml not geoJSON.
    – Geographos
    Oct 10, 2019 at 8:28
  • 1
    Syntax # in style means that you are defining style for specific HTML element with that id. You should have: .image-opacity { opacity: 0.6; } .sldOpacity { opacity: 0.6; }
    – TomazicM
    Oct 10, 2019 at 8:33
  • Unfortunately the same problem :( layers are still opaque
    – Geographos
    Oct 10, 2019 at 8:38
  • I found sth here: stackoverflow.com/questions/57589514/… But it refers to google maps and I am afraid won't work in leaflet conditions
    – Geographos
    Oct 10, 2019 at 8:40
  • 1
    In your code you refer to #sldOpacity and #image-opacity HTML element id's, but there are no such HTML elements in your code.
    – TomazicM
    Oct 10, 2019 at 14:36
2

It looks like I found a decent solution to make it:

First of all, the good code is provided by:

https://github.com/shramov/leaflet-plugins

where is the .kml section.

You must copy the KML.js file into your repository

Then in the front script code use:

  var track = new L.KML('Coventry.kml', {async: true})
    .on('loaded', function (e) {
        map.fitBounds(e.target.getBounds());
    })
    .addTo(map);
L.control.layers({}, {'Track':track}).addTo(map);

without any opacity settings in Javascript, because this plugin recognizes an Image opacity properties set in the .XML code:

 <GroundOverlay>
<name>Coventry.tif</name>
<description>http://localhost/testc/Coventry.tif</description>
<Icon>
    <href>https://i.imgur.com/58CbNhB.png</href>
    <viewBoundScale>0.75</viewBoundScale>
</Icon>
<color>55ffffff</color>
<LatLonBox>
    <north>52.39388512224325</north>
    <south>52.39299906007814</south>
    <east>-1.458241039649089</east>
    <west>-1.460061203494303</west>
</LatLonBox>
 </GroundOverlay>
 <GroundOverlay>
<name>Coventry2.tif</name>
<description>http://localhost/testc/Coventry.tif2</description>
<Icon>
    <href>https://i.imgur.com/58CbNhB.png</href>
    <viewBoundScale>0.75</viewBoundScale>
    <color>00ff6633</color>
</Icon>
<color>99ffffff</color>
<LatLonBox>
    <north>52.39299906007814</north>
    <south>52.39199906007814</south>
    <east>-1.458241039649089</east>
    <west>-1.460061203494303</west>
</LatLonBox>
</GroundOverlay>

This solution canb be applicable for Icons (External URL images) fetched by .kml file like

<Icon>
    <href>https://i.imgur.com/58CbNhB.png</href>
</Icon>

Unlike for the solution proposed above, that works easier for KML polygon transparency instead of icon included.

In the result your KML layer will loke as per in the image below:

enter image description here

Your Answer

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

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