facebook-squared twitter-squared rss-squared YouTube icon gplus-squared

Add leaflet to Ionic Angular [Screencast]

Written by on 7 June 2020

Sunday

7

June 2020

3

COMMENTS

Leaflet is a lightweight, leading solution to interactive maps. It’s open source, beautiful and quite extensible. Not to forget it’s also a mobile friendly so works best with Ionic.

Why not Google Maps?

Well whenever map is concerned, Google Maps comes to the mind. Apparently GMaps (for short) provides more map services than just the interactive layer. It provides features like geocoding, forward search, backward search, clustering, fencing and many more.

More info regarding the comparison.

If you just need to add a minimal map or the one with minimum set of features than leaflet is your best bet.

If you are more of a video person that I have also attached the video at the end of the article

Watch Video

For the final source code you can visit the Github repo

Github

Getting Started

We obviously need a brand new ionic app. Ionic Version 5 is already on the market. The newer version of @ionic/[email protected] (aka magnesium) comes with Angular Ivy Rendering Engine. The most noticing thing in version 9 of angular is new compilation and rendering engine.

Ionic 5 comes with some new iOS designs, custom animation, icons and more. Further information about Ivy and Ionic 5 can be found here and here respectively.

    ionic start [project-name] tabs  --type=ionic-angular

Next we need to add leaflet dependency. We also gonna need the leaflet types as dev dependency. As they will help while developing our app with typescript.

    npm i leaflet
npm i @types/leaflet -D

As we have used ionic tabs starter project. Let’s target the first tab for our code. Let’s clear the ion-content and replace it with following code. That’s the only html we need for our demo.

<ion-content [fullscreen]="true">
  <div id="map"></div>
</ion-content>

Next for the css we need to make changes at two places. First we need to reference the leaflet stylesheet in global.scss file.

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

The above line placement could depend on the other project dependency. In our case at the end of the file will do the job.

There is one more CSS line we need to add. Right now if we preview our app we gonna see nothing. Because we have with zero height. So let’s add height to tab1.page.scss

    #map {
  min-height: 100%;
}

Now if we preview our app.

Leaflet in ionic angular preview before initializing map from technbuzz.com
As we can see, it’s blank app that’s because we need initialize the map via JavaScript.

Let’s head over to code behind file and add some code.

    export class Tab1Page {
  map: L.Map

  constructor() {}

  ngOnInit() {
    this.map = L.map('map', {
      center: [ 25.3791924,55.4765436 ],
      zoom: 15,
      renderer: L.canvas()
    })

  }
}

The Line from 7-11 creates new instance of leaflet. The first argument is ‘map’ in quotes. This refers to the div tag map id in our markup. We are also providing some other configuration i-e center latitude and longitude (which will be used starting point of our map)

Adding attribution

As an open source library we need to add the attribution text.

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

If you run your application now that you than the maps might now load properly. You need to resize the window load all of the map tiles. And people are querying about it online as:

  • leaflet angular map is not rendered until screen resize
  • leaflet map does not appear correctly until resize

There is a good stackoverflow answer to this well know leaflet problem which says

This is a known and well-documented issue with Leaflet. If the map container div doesn’t have a defined size at the point that the map initialises, the tiles don’t load. If it’s not possible to give the map container a size on page load due to something dynamic in your config, you can work round it by calling map.invalidateSize() after the container is initialised

So after adding the solution our final code snippet becomes;

    export class Tab1Page {
  map: L.Map

  constructor() {}

  ngOnInit() {
    this.map = L.map('map', {
      center: [ 25.3791924,55.4765436 ],
      zoom: 15,
      renderer: L.canvas()
    })

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


    setTimeout(() => {
      this.map.invalidateSize();
    }, 0);
  }
}

So from line 18-20 will run the code after the map is fully initialized. This helps in properly rendering the app. You might need to play with second argument (which is time in milliseconds) that setTimeout accepts, if you are not getting the desired result.

Final Preview

So if after goes well, we will see following preview. We can zoom in/out and pan around. I know it’s quite boring. It requires markers and popups that comes in next article. Kindly share your experience how did you liked integrating leaflet app. Don’t forget there is attached screenshot at the end.

Finally we see leaflet in display in Ionic and Angular from technbuzz.com

Screencast

3 Comments

  1. JA

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.