Multiple Ngx-leaflets maps on same page : all the tiles are displayed on the same map

707 Views Asked by At

I am converting a standard angular project to an Angular Universal project so I have to get rid of the "$window". The project did not use any but some of the modules that were used, like leaflet, are using it, so I switched to ngx-leaflet.

The component only accesses @types\leaflet objects to generate the configuration and the map generation is left to the html with the ngx-leaflet directive : leaflet. The html is as follows :

<div class="row w75 justify-content-center mb-5">
  <div class="content-wrapper col-lg-9 col-sm11" >
    <h3  class="center-title text-uppercase">Country locations</h3>
    <div class="title-block2"></div>
      <div id="map" leaflet [leafletOptions]="options" style="min-height: 700px">
      </div>
  </div>
</div>
<div class="row justify-content-center mt-3 mb-5">
  <div class="content-wrapper col-12" >
    <h3  class="center-title text-uppercase">Woldwide locations</h3>
    <div class="title-block2"></div>
    <div id="map2" leaflet  [leafletOptions]="options2" style="min-height: 700px">
    </div>
  </div>
</div>

The result is that the 2 maps do appear, each of them with its markers and funcionning pop-ups, but only the first map is displaying actual maps tiles, and actually displaying all the tiles of the 2 maps, so the second map is just gey backfgound.

Is there something I am missing in the usage of the ngx-leaflet ? Like for instance something like : [containerId]="'map'" ?

I attach screenshot :

the controller is as follows :

import {Component, OnInit} from '@angular/core';
import {icon, popup, marker, latLng, tileLayer, layerGroup, polyline,
  Polyline, LayerGroup, LatLng, TileLayer} from 'leaflet';
@Component({
  selector: 'app-map',
  templateUrl: './coverage.component.html',
  styleUrls: ['./coverage.component.scss']
})


export class CoverageComponent implements OnInit {
  title = 'leafletApps';
  popup = popup();
  width = window.innerWidth;
  polylinePoints: LatLng[] = [];
  polyline: Polyline;
  assetLayerGroup: LayerGroup = layerGroup();
  assetLayerGroup2: LayerGroup = layerGroup();
  myTitleLayer: TileLayer = tileLayer('https://tiles.stadiamaps.com/tiles/osm_bright/{z}/{x}/{y}{r}.png',
    { attribution: '© Angular LeafLet' });
  options: {layers: any[], zoom: number, center: LatLng , dragging: boolean,
            scrollWheelZoom: boolean } =
    {
      layers: [this.myTitleLayer, this.assetLayerGroup],
      zoom: 6,
      dragging: (this.width > 992),
      scrollWheelZoom: false,
      center: latLng(4.7110, -74.0721)
    };
  options2: {layers: any[], zoom: number, center: LatLng ,
             dragging: boolean, scrollWheelZoom: boolean } =
        {
          layers: [this.myTitleLayer, this.assetLayerGroup2],
          zoom: 3,
          dragging: (this.width > 992),
          scrollWheelZoom: false,
          center: latLng(20, 0)
        };
      constructor() {}
  ngOnInit() {
    this.assetLayerGroup = this.fillMap1();
    this.options.layers.push(this.myTitleLayer);
    this.options.layers.push(this.assetLayerGroup);
    this.assetLayerGroup2= this.fillMap2();
    this.options2.layers.push(this.myTitleLayer);
    this.options2.layers.push(this.assetLayerGroup2);
  }
}

Any idea where the error is ?

1

There are 1 best solutions below

0
On BEST ANSWER

Well while typing the question I found the answer.... But I posted the question anyway in case someone faces this :

The tiles are placed on the "titleLayer" that in fact are the "tileLayer". That spelling mistake of mine induced an error thinking it was just the title. So as my component did not duplicate the tile layer but used the same one for the 2 maps this was the issue.

The solution is to create 2 tile layers objects, even if they have identical content and asign one of each to the different maps...

correct component code as follows :

import {Component, OnInit} from '@angular/core';
import {icon, popup, marker, latLng, tileLayer, layerGroup, polyline,
  Polyline, LayerGroup, LatLng, TileLayer} from 'leaflet';
@Component({
  selector: 'app-map',
  templateUrl: './coverage.component.html',
  styleUrls: ['./coverage.component.scss']
})


export class CoverageComponent implements OnInit {
  title = 'leafletApps';
  popup = popup();
  width = window.innerWidth;
  polylinePoints: LatLng[] = [];
  polyline: Polyline;
  assetLayerGroup: LayerGroup = layerGroup();
  assetLayerGroup2: LayerGroup = layerGroup();
  myTileLayer1: TileLayer = tileLayer('https://tiles.stadiamaps.com/tiles/osm_bright/{z}/{x}/{y}{r}.png',
    { attribution: '© Angular LeafLet' });
  myTileLayer2: TileLayer = tileLayer('https://tiles.stadiamaps.com/tiles/osm_bright/{z}/{x}/{y}{r}.png',
    { attribution: '© Angular LeafLet' });
  options: {layers: any[], zoom: number, center: LatLng , dragging: boolean,
            scrollWheelZoom: boolean } =
    {
      layers: [this.myTileLayer1, this.assetLayerGroup],
      zoom: 6,
      dragging: (this.width > 992),
      scrollWheelZoom: false,
      center: latLng(4.7110, -74.0721)
    };
  options2: {layers: any[], zoom: number, center: LatLng ,
             dragging: boolean, scrollWheelZoom: boolean } =
        {
          layers: [this.myTileLayer2, this.assetLayerGroup2],
          zoom: 3,
          dragging: (this.width > 992),
          scrollWheelZoom: false,
          center: latLng(20, 0)
        };
      constructor() {}
  ngOnInit() {
    this.assetLayerGroup = this.fillMap1();
    this.options.layers.push(this.myTileLayer1);
    this.options.layers.push(this.assetLayerGroup);
    this.assetLayerGroup2= this.fillMap2();
    this.options2.layers.push(this.myTileLayer2);
    this.options2.layers.push(this.assetLayerGroup2);
  }
}