tone
tone

Reputation: 1434

In Leaflet, how to make a style the default style from now on

I have geoJson map regions rendered on a map with an initial opacity. I have a slider to change that opacity on the fly.

Here is the bit where I set the opacity on the fly (typescript), which I perform on the input change event within my custom leaflet control:

this.layers.forEach((r: L.GeoJSON<any>) => {
      r.eachLayer((layer: any) => {
             layer.setStyle({ fillOpacity: vm.mapOptions.heatmapOpacity });
      });
});
setTimeout(() => this.map.invalidateSize());

I also have the ability to hover over the regions, in which case I lower the opacity and put a border on the active region when they hover.

When they leave the region, it currently uses resetStyles on that region to reset it back to the previous style. I set this up in the options onFeature callback. The region is highlighted in the mouseover event, and reset in the mouseout event, as seen below.

options = {
            style: { stroke: false,
                     fillColor: regionColor,
                     fillOpacity: mapOptions.heatmapOpacity },
            onEachFeature: (feature, layer) => {
                layer.on({
                    mouseover: (e)=> {
                         const lr = e.target;
                         lr.setStyle({
                            weight: 5,
                            color: "#666",
                            dashArray: "",
                            fillOpacity: 0.7,
                           stroke: true
                         });
                        if (!L.Browser.ie && !L.Browser.opera12 && !L.Browser.edge) {
                           lr.bringToFront();
                        }
                    },
                    mouseout: (e) => {
                       prop.featureGeoJson.resetStyle(e.target);
                    }
                });
            }
        };

The problem is, if I have used setStyle to set the opacity to a different value, then I go into a region, then I leave the region again, calling resetStyle resets the style back to the original default style, before the change to the opacity was made.

Is it possible to set the default style on the layer, so that calling resetStyle will set the styles to my value with the new opacity, and not to the original opacity set when the region was created? How would I do that?

Upvotes: 3

Views: 5037

Answers (2)

ghybs
ghybs

Reputation: 53185

The resetStyle method of a Leaflet GeoJSON Layer Group re-applies the style that was applied at the time of creation of that group, or the default one if you did not provide style:

Resets the given vector layer's style to the original GeoJSON style, useful for resetting style after hover events.

If you later change the style of one or all of the vector layers in that group, it will be therefore overridden when you use resetStyle, and the initial style will be applied.

An easy workaround is simply to modify the GeoJSON Layer Group's style option as well. However, it will affect all its child layers:

group.options.style = newStyle;

(that is what is suggested in @GabyakaGPetrioli's answer, but you have to apply it on the group, not on individual features)

Another solution would be to record the new style of each vector layer, and use that recorded value when you want to restore the previous state, instead of using the group's resetStyle method.

var map = L.map("map").setView([48.85, 2.35], 12);

var geojson = {
  type: "Feature",
  geometry: {
    type: "Point",
    coordinates: [2.35, 48.85]
  }
};

var point;
var startStyle = {
  color: "red"
};
var newStyle = {
  color: 'green'
};

var group = L.geoJSON(geojson, {
  style: startStyle,
  pointToLayer: function(feature, latlng) {
    point = L.circleMarker(latlng);
    assignStyle(point, startStyle);
    return point;
  }
}).addTo(map);

// Record the style to the individual vector layer if necessary.
function assignStyle(leafletLayer, newStyle) {
  leafletLayer.setStyle(newStyle);
  leafletLayer._recordedStyle = newStyle;
}

// When desired, apply the style that has been previously recorded.
function reassignStyle(leafletLayer) {
  leafletLayer.setStyle(leafletLayer._recordedStyle);
}

document.getElementById('button').addEventListener('click', function(event) {
  event.preventDefault();

  // Either use the wrapper function that records the new style…
  //assignStyle(point, newStyle);

  // Or simply modify the group's style option, if it is acceptable affecting all child layers.
  point.setStyle(newStyle);
  group.options.style = newStyle;
});

group.on({
  mouseover: function(e) {
    e.target.setStyle({
      color: 'blue'
    });
  },
  mouseout: function(e) {
    //reassignStyle(e.layer);
    group.resetStyle(e.layer);
  }
});

L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
  attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css">
<script src="https://unpkg.com/[email protected]/dist/leaflet-src.js"></script>

<div id="map" style="height: 100px"></div>
<button id="button">Change color to Green…</button>
<p>…then mouseover and mouseout</p>

Upvotes: 1

Gabriele Petrioli
Gabriele Petrioli

Reputation: 195982

Use L.Util.setOptions

so instead of

layer.setStyle({ fillOpacity: vm.mapOptions.heatmapOpacity });

use

L.Util.setOptions(layer, { style: { fillOpacity: vm.mapOptions.heatmapOpacity } });

Upvotes: 0

Related Questions