Codehan25
Codehan25

Reputation: 3014

Adding multiple overlays to leaflet's layers control

I have a LayerGroup in which several ImageOverlays are placed. These are all displayed correctly.

Now I would like to be able to show and hide this LayerGroup within the LayersControl.

My LayerGroup is defined within a function like this:

this.imgOvl.forEach((img) => {
  this.imgOvlGp.addLayer(img);
});

If I add this LayerGroup to my existing and working overlays object, I get an error message:

 lControl = {
    bLayers: {
      'Open Street Map': xyz
    },
    ol: {
      'GeoJSONs': xyz,
      'Image Overlays': this.imgOvlGp // does not work
    }
  };

I get this error message in the browser:

MapViewComponent.html:1 ERROR TypeError: Cannot read property 'on' of undefined at NewClass._addLayer (leaflet-src.js:5101) at NewClass.addOverlay (leaflet-src.js:5005) at leaflet-control-layers.wrapper.js:52 at DefaultKeyValueDiffer.push../node_modules/@angular/core/fesm5/core.js.DefaultKeyValueDiffer.forEachAddedItem (core.js:19640) at leaflet-control-layers.wrapper.js:51 at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:391) at Zone.push../node_modules/zone.js/dist/zone.js.Zone.run (zone.js:150) at NgZone.push../node_modules/@angular/core/fesm5/core.js.NgZone.runOutsideAngular (core.js:17248) at LeafletControlLayersWrapper.push../node_modules/@asymmetrik/ngx-leaflet/dist/leaflet/layers/control/leaflet-control-layers.wrapper.js.LeafletControlLayersWrapper.applyChanges (leaflet-control-layers.wrapper.js:41) at LeafletControlLayersWrapper.push../node_modules/@asymmetrik/ngx-leaflet/dist/leaflet/layers/control/leaflet-control-layers.wrapper.js.LeafletControlLayersWrapper.applyOverlayChanges (leaflet-control-layers.wrapper.js:32)

If I remove the the line..

 'Image Overlays': this.imgOvlGp // does not work

..from the ol object, everything is working fine.

Any ideas?


UPDATE

  this.overlays = imgOverlays;
  this.overLayGroup = new L.LayerGroup().addTo(this.map);

  this.overlays.forEach((img) => {
    this.overLayGroup.addLayer(img);
  });

  // If I do it like this, it works..
  const overlay = {'Overlays': this.overLayGroup};
  L.control.layers(null, overlay).addTo(this.map);

Upvotes: 0

Views: 5680

Answers (2)

Codehan25
Codehan25

Reputation: 3014

I solved it by creating a FeatureGroup and dropping my LayerGroup into it.

Then I added the FeatureGroup of multiple ImageOverlays to my overlays object.

// Create FeatureGroup
featureGroup = new FeatureGroup ();

// Add LayerGroup of multiple Images to the FeatureGroup
this.overlayGroup.addTo(this.featureGroup);

// Add FeatureGroup to the ol object to display the toggle functionality in the layers group
lControl = {
  bLayers: {
    'Open Street Map': xyz
  },
  ol: {
    'GeoJSONs': xyz,
    'Image Overlays': this.featureGroup // does not work
  }
};

Upvotes: 0

kboul
kboul

Reputation: 14570

The difference between adding a single or multiple imageOverlays as a leaflet overlay is that you have to create & add each imageOverlay into a L.layerGroup() like this:

overlaysGroup = L.layerGroup();

imageUrl = "http://www.lib.utexas.edu/maps/historical/newark_nj_1922.jpg";
imageBounds: L.LatLngBoundsExpression = [
    [-33.865, 151.2094],
    [-35.865, 154.2094]
];
imageOverlay = imageOverlay(this.imageUrl, this.imageBounds)
       .addTo(this.overlaysGroup)

imageUrl2 = 'https://upload.wikimedia.org/wikipedia/commons/thumb/7/7c/Sydney_Opera_House_-_Dec_2008.jpg/1024px-Sydney_Opera_House_-_Dec_2008.jpg',
imageBounds2: L.LatLngBoundsExpression = [
    [-30.8650, 151.2094],
    [-32.865, 154.2094]
];
imageOverlay2 = imageOverlay(this.imageUrl2, this.imageBounds2)
          .addTo(this.overlaysGroup)

then simply assign the overlaysGroup to overlays object as per desired string when using ngx-leaflet similarly to native leaflet implementation:

overlays: {
    "overlays": this.overlaysGroup
}

Alternative approach

Create an array and store the imageOverlays

 allOverlays = [this.imageOverlay, this.imageOverlay2]

Listen to onMapReady event & loop over the array of imageOverlays and add the overlays to overlayGroup over there once map is loaded

onMapReady(map) {
    // map.fitBounds(this.imageOverlay.getBounds());
    this.allOverlays.forEach(overlay => {
      overlay.addTo(this.overlaysGroup)
    });
}

Demo

Upvotes: 2

Related Questions