1

I'm having some issues trying to show a map on a page in Ionic using Angular.

While the map itself works without bugs, there are a few rendering issues that annoy me:

  1. The map's tile loading is initially extremely slow
  2. The coordinates which the map is meant to be showing with setView are in the top left corner of the map div (I can see this with a marker placed on the same coords)
  3. If I resize the window, the tiles load normally as they should and the marker is centered.

I'd like the third option to be the case at all times: the coordinates I point to with setView should be at the center of the map.

Here is my code as it is:

export class MyPage implements OnInit {

  public acc;

  posLatitude: number;
  posLongitude: number;
  map: L.Map;
  markerIcon = L.icon(
    {
      iconUrl:'assets/pin.svg',
      iconSize: [32, 32],
    }
  );

  constructor(
    private myService: MyService,
  ) { }

  ngOnInit() {
    this.acc = MyService.getAcc();
    this.posLongitude = this.acc["Long"];
    this.posLatitude = this.acc["Lat"];
    this.map = L.map('map').setView([this.posLatitude, this.posLongitude], 16);

    // center the map

    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      attribution: 'jsp.com'
     }).addTo(this.map);

    L.marker([this.posLatitude, this.posLongitude], {icon : this.markerIcon}).addTo(this.map)
      .bindPopup('Accident');

    console.log(this.acc);
  }

}
<div id="map" style="height: 75%;"></div>
  • See https://stackoverflow.com/questions/36246815/data-toggle-tab-does-not-download-leaflet-map/36257493#36257493 – ghybs Jan 17 '20 at 18:11
  • Does this answer your question? [Data-toggle tab does not download Leaflet map](https://stackoverflow.com/questions/36246815/data-toggle-tab-does-not-download-leaflet-map) – IvanSanchez Jan 18 '20 at 01:52

3 Answers3

2
export class MyPage implements OnInit {
  public acc;

  posLatitude: number;
  posLongitude: number;
  map: L.Map;
  markerIcon = L.icon(
    {
      iconUrl:'assets/pin.svg',
      iconSize: [32, 32],
    }
  );

  constructor(private myService: MyService) { }

  public ngOnInit(): void {
    this.acc = MyService.getAcc();
    this.posLongitude = this.acc["Long"];
    this.posLatitude = this.acc["Lat"];
    this.map = L.map('map');

    // center the map
    const observer = new MutationObserver(() => {
      map.invalidateSize();
      map.setView([this.posLatitude, this.posLongitude], 16);
      observer.disconnect();
    });

    observer.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ['class'],
      childList: false,
      characterData: false,
    });

    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      attribution: 'jsp.com'
     }).addTo(this.map);

    L.marker([this.posLatitude, this.posLongitude], {icon : this.markerIcon}).addTo(this.map)
      .bindPopup('Accident');
  }
}

Basically, when the Ionic app starts, the entire app is hidden until it's "hydrated".

html:not(.hydrated) body {
  display: none;
}

When everything is ready to render, Ionic adds the hydrated class to the HTML-element and at this point the entire app is ready to render. But at this point, Leaflet has already initialized the map with the size of 0px in both width and height, making it render a single tile.

While I haven't found a way to listen for an event that everything is ready to render, you can listen for class changes to the HTML-element. In the code above, this is done using an MutationObserver. That will trigger the callback when the the class-property on the HTML-element has been changed, and at that point invalidate the map size (so leaflet will re-calculate the size it has) and center the map.

0

It should work for all types of ionic application. the issue is due to loading of leaflet map before the ionic components. so try the below one it should work

ionViewDidEnter(){
   let osmMap = L.map('map');
   L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
   }).addTo(osmMap);
   osmMap.invalidateSize();
}
developer
  • 80
  • 1
  • 1
  • 12
0

Firstly you need to add the leaflet's CSS in the global.scss file :

@import "~leaflet/dist/leaflet.css";

another thing is to set the height and width to 100% in your HTML :

  <div id="map" style="width: 100%; height: 100%;"> </div>

if this did not resolve your issue, just reload your app until it runs fast, this happened to me too many times, and when I refresh the page it fixes it.