Pages

Integrating MapBox GL JS map into an Ionic 2 Application

Integrating MapBox GL JS map into an Ionic 2  application is similar to that of  my previous blog post How to Integrate Mapbox GL JS maps with an Ionic application , but with small changes.

In this tutorial i am going to explain how to integrate mapbox gl js map into ionic 2 application.

Run the Following Command to create a new ionic project
 ionic start Mapbox-Gl-maps tabs --v2 
After the Project is created, navigate to the project folder, in my case "Mapbox-Gl-maps" is the folder name. Since we want our app to work on Both ios and Android we should also add respective platform's to the ionic project.
Run the following commands to add the Android & iOS platforms

ionic platform add ios

ionic platform add android

Now, that you have added the platform's, lets add the required plugins into our project.

Add MapBox GL JS Library

To display the mapbox  map in our ionic 2 application, we need to import some js files in to our application. we will use npm to import required js files.

Run the Following Command to install mapbox gl js library
 npm install --save-dev mapbox-gl

Add Geolocation Plugin

we also need geolocation plugin to get the exact location of the user.


Run the Following Command to install geolocation plugin
 cordova plugin add cordova-plugin-geolocation

Now, that you have installed the required plugin's, lets get to coding. view the app that you just created by just running the below server command.
 ionic serve

This will start a live-reload server for your project. When changes are made to any HTML, CSS, or JS files, the browser will automatically reload when the files are saved. 
your app should look like this in the browser.


Add the Map code to homepage

Add the following code to home.ts after constructor


     ionViewDidEnter() {

       /*Initializing Map*/
      mapboxgl.accessToken = '<your mapbox gl js access token>';
      var map = new mapboxgl.Map({
      style: 'mapbox://styles/mapbox/light-v9',
      center: [-74.0066, 40.7135],
      zoom: 16,
      pitch: 80,
      minZoom: 7.5, //restrict map zoom - buildings not visible beyond 13
      maxZoom: 17,
      container: 'map'
    });
  
  }

now when your app is reloaded, you will get an error like " cannot find name mapboxgl ". that is because we have to imported mapboxgl  js  to our page.

Note: AccessToken is provided by mapbox once you signup @ https://www.mapbox.com. 


copy and past the below code to your home.ts file
import mapboxgl from 'mapbox-gl/dist/mapbox-gl.js'

your app should reload without any errors now. but to display map on your home page add the folloing code to your home.html file.


copy and past the below html code to your home.html file
<div id='map'></div> 
Now you can see that the map is loaded, but the height and width need's a little modification right!


copy and past the below css code to your home.scss file
#map{
 width: 100%;
 height:100%;
}
 reload your app and you can see that the map perfectly adjusts to the window now as shown below.


Display 3D Buildings

To display 3d building on your mapbox map add the following code below the map initialization code.



copy and past the below code to your home.ts file 
    map.on('load', function() {
        map.addLayer({
            'id': '3d-buildings',
            'source': 'composite',
            'source-layer': 'building',
            'filter': ['==', 'extrude', 'true'],
            'type': 'fill-extrusion',
            'minzoom': 15,
            'paint': {
                'fill-extrusion-color': '#aaa',
                'fill-extrusion-height': {
                    'type': 'identity',
                    'property': 'height'
                },
                'fill-extrusion-base': {
                    'type': 'identity',
                    'property': 'min_height'
                },
                'fill-extrusion-opacity': .6
            }
        });
    }); 

after your app is reloaded you can see that the mapbox map loads map with 3d buildings as shown below.



Get Current Location

As you can see i'have given static coordinates to the map, to get the current location of the user/device we need the geolocation plugin that we have installed earlier and below given peace of code.
copy and past the below code to your home.ts file's ionViewDidEnter 
   /*Initializing geolocation*/
  let options = {
    frequency: 3000,
    enableHighAccuracy: true
  };

  this.watch = Geolocation.watchPosition(options)
  .subscribe((position: Geoposition) => {
    console.log(position);
    this.Coordinates = position.coords;
    this.executemap()
  }); 

    });

modify the already written code, move the map Initializing code from ionViewDidEnter method to executemap method and also add the below variables within HomePage class.


   Coordinates: any;
   watch:any;
replace the map code to executemap method
 executemap(){

     /*Initializing Map*/
     mapboxgl.accessToken = 'pk.eyJ1IjoidmVua2F0aXRvbiIsImEiOiJjaXhsdGZ2amIwMDQwMnFxdDdoMTZ3NHlpIn0.X9Zmsqs7wCS30_RGxa_Kzw';
    var map = new mapboxgl.Map({
       style: 'mapbox://styles/mapbox/light-v9',
       center: [this.Coordinates.longitude, this.Coordinates.latitude],
       zoom: 16,
       pitch: 80,
       minZoom: 7.5, //restrict map zoom - buildings not visible beyond 13
       maxZoom: 17,
       container: 'map'
     });
      map.on('load', function() {
   map.addLayer({
    'id': '3d-buildings',
    'source': 'composite',
    'source-layer': 'building',
    'filter': ['==', 'extrude', 'true'],
    'type': 'fill-extrusion',
    'minzoom': 15,
    'paint': {
     'fill-extrusion-color': '#aaa',
     'fill-extrusion-height': {
      'type': 'identity',
      'property': 'height'
     },
     'fill-extrusion-base': {
      'type': 'identity',
      'property': 'min_height'
     },
     'fill-extrusion-opacity': .6
    }
   });
  });
 }
Once completed your app should load with your current location coordinates.

below is the complete code of the home.ts file
copy and past the below code if you have problem's loading map
import { Component } from '@angular/core';
import mapboxgl from 'mapbox-gl/dist/mapbox-gl.js'
import { NavController } from 'ionic-angular';
import { Geolocation, Geoposition} from 'ionic-native'; 

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  Coordinates: any;
  watch:any;
  constructor(public navCtrl: NavController) {

  }
  
    ionViewDidEnter() {
  
   /*Initializing geolocation*/
  let options = {
    frequency: 3000,
    enableHighAccuracy: true
  };

  this.watch = Geolocation.watchPosition(options)
  .subscribe((position: Geoposition) => {
    console.log(position);
    this.Coordinates = position.coords;
    this.executemap()
  }); 
   }
  

 executemap(){

     /*Initializing Map*/
     mapboxgl.accessToken = '<your mapbox gl js access token>';
    var map = new mapboxgl.Map({
       style: 'mapbox://styles/mapbox/light-v9',
       center: [this.Coordinates.longitude, this.Coordinates.latitude],
       zoom: 16,
       pitch: 80,
       minZoom: 7.5, //restrict map zoom - buildings not visible beyond 13
       maxZoom: 17,
       container: 'map'
     });
      map.on('load', function() {
   map.addLayer({
    'id': '3d-buildings',
    'source': 'composite',
    'source-layer': 'building',
    'filter': ['==', 'extrude', 'true'],
    'type': 'fill-extrusion',
    'minzoom': 15,
    'paint': {
     'fill-extrusion-color': '#aaa',
     'fill-extrusion-height': {
      'type': 'identity',
      'property': 'height'
     },
     'fill-extrusion-base': {
      'type': 'identity',
      'property': 'min_height'
     },
     'fill-extrusion-opacity': .6
    }
   });
  });
 }

}


vinay kumar

Founder of Gowriter.Blogspot.com, Tech Enthusiast, Normal type of Person with passion toward's work.

10 comments:

Play Studio said...

Wow, I love this tutorial. Thanks

Anonymous said...

Hi, i have issues when i try to add layers such as user's location or buildings. Where exactly do you put the "addLayer" code ?
I always end up with an error saying that :"Style is not done loading".

Slayug said...
This comment has been removed by the author.
Slayug said...

Hello,
thanks for this tutorial.

I followed it, but for instance if after that you want to add Marker, or other things like Icons, image on the map, you will have some issues (markers don't stay on their position when zooming/unzooming, ..).
You have to add the css mapbox in your index.html
I think it's also the problem of Anonymous.

apo said...

Hi and thanks a lot for your article

i followed it until Get Current Location.
i have an error in home.ts:

import { Geolocation, Geoposition} from 'ionic-native';

Runtime Error
Cannot find module "ionic-native"

than i tried
import { Geolocation, Geoposition} from '@ionic-native/geolocation';

and now i've

Runtime Error
__WEBPACK_IMPORTED_MODULE_3__ionic_native_geolocation__.a.watchPosition is not a function


any suggestion?
thanks

Anonymous said...

Hi,

first install these..

ionic cordova plugin add cordova-plugin-geolocation
npm install --save @ionic-native/geolocation


next,

import { Geolocation, Geoposition } from '@ionic-native/geolocation';

in app.module.ts

and then add Geolocation in providers like this.

providers: [
Geolocation
]


next, in constructor where you want to use geolocation declare like this.

constructor(private geolocation: Geolocation) {}

Now, replace Geolocation with this.geolocation ie.

'Geolocation.watchPosition()' with 'this.geolocation.watchPosition()'

thats it, you should be doing fine now..

apo said...

thanks mate it worked!!
;-)

Anonymous said...

I can not run this code in with --prod mode.

I published this coment:
https://forum.ionicframework.com/t/issue-in-ionic-production-build-for-mapbox-gl-js-feature/95056?u=jesusperez82

Luca Gavelli said...

Thank you for sharing this example.
You know if it is possible in ionic to put offline mapbox maps ? Tnx

Anonymous said...

Did you tried even running this with Android Emulator or Real Device.
It does not Work!

https://github.com/mapbox/mapbox-gl-js/issues/6693