0

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);
kboul
  • 13,836
  • 5
  • 42
  • 53
Codehan25
  • 2,704
  • 10
  • 47
  • 94

2 Answers2

2

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

kboul
  • 13,836
  • 5
  • 42
  • 53
  • I have updated my question. I have to put the overlays in an array, as they come dynamically from a http call. I then iterate over this array and put every single ImageOverlays in a LayerGroup, which I want to insert into the LayersControl to be able to toggle it. The approach I put in my question works, bu this way I get two layer controls in my map.. – Codehan25 Apr 02 '19 at 11:42
  • You need to use one overlayGroup to get one layer control. Therefore, you need to add every singe image overlay in this overlayGroup as I did in the dummy example with two hard coded imageOverlays. I do not get why you fetch imageOverlays via http call. You just need the bounds and the url from the db to be able to build the overlays on the front-end. – kboul Apr 02 '19 at 11:56
  • The images are provided by a backend service (Rest API) and assigned to several locations on the map. So you have to work with several API calls. The bounds are also provided by the backend service and are always different. Unfortunately, I can not do that manually, because there are just too many overlays. I have already placed all ImageOverlays in the LayerGroup. As I said, the pictures are displayed correctly. It's just about the layers control. – Codehan25 Apr 02 '19 at 12:33
  • The LayerGroup, in which all my pictures are placed is considered as a single layer or not? My approach with L.control.layers(null, overlay).addTo(this.map); is working, when I add it the ol object in my question it doesn't.. – Codehan25 Apr 02 '19 at 12:33
  • Yes. it is considered a single layer. I edited my answer and the demo to include a similar approach with yours. Please check again – kboul Apr 02 '19 at 12:46
  • I have already solved it. I Have created a FeatureGroup, in which I put my LayerGroup with the ImageOverlays. Nevertheless, many thanks for your help. Also with my other question :) – Codehan25 Apr 02 '19 at 12:51
0

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
  }
};
Codehan25
  • 2,704
  • 10
  • 47
  • 94