How to add Google Map and Multiple Marker using Ionic 3

In most of the apps, maps are one of the most useful tools for users when included in an app. The Ionic allows us to integrate Google map in our application. We can achieve integrating Google map in Ionic in two-way

  1. Google Map JS library
  2. Ionic native SDK map

In this example, we will demonstrate how to use Google Map JS library. We will cover setting up the Google Maps API through the Google Developer Console, displaying a map with multiple markers in your applications, displaying the museum’s location. We are creating an application called museumGoogleMap to demonstrate

What are we learning?

  1. Displaying individual map for each museum.
  2. Displaying multiple markers on single Google map.
  3. Search box to search museum by state.

Step #1: Setup the project

ionic start museumGoogleJsMap blank

Step 2: Setting up Google  Map API in Google Developer Console

In order to use the Google Maps API, you must register your application on the Google Developer Console and enable the API. To do this, start by going to the Google Developer Console for Google JS API. If you already have a project created, you can skip the next section. If not, you can follow along and create a new project for your maps application.

On clicking on CREATE AND ENABLE API, you will get API to use Google map in our project and copy the API and the past in our Ionic project src/theme/index.html as


  <script src="http://maps.google.com/maps/api/js?key=YOUR API FROM GOOGLE DEVELOPER CONSOLE"></script>
  <!-- cordova.js required for cordova apps -->

  <script src="cordova.js"></script>

We can ignore the need for an API key while we develop our application, but API key is required for production. Is better to add the API.

Step 3: Installing Geolocation plugin

Now we will add the Geolocation plugin, run the following command

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

Step 4: Let’s build the apps, following all the steps as 

We have completed the external configuration, now time to write code for our museum Ionic Apps. We will add three more page.

ionic generate page searchMuseum
ionic generate page museum-detail
ionic generate page all-museum

Remove the default home page and replace rootPage value from Home Page to SearchMuseumPage  in the app.components.ts

import { Component } from '@angular/core';
import { Platform } from 'ionic-angular';
import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';

import { SearhcMuseumPage} from '../pages/searchMuseum/searchMuseum';

@Component({
  templateUrl: 'app.html'
})
export class MyApp {
  //rootPage:any = HomePage;
  
  rootPage: any = SearhcMuseumPage;

  constructor(platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen) {
    platform.ready().then(() => {
      statusBar.styleDefault();
      splashScreen.hide();
    });
  }
}

In app.module.ts file we also need to add the reference in app.modules for our three new page and we also have to register the provider for Geolocation plugin.

import { BrowserModule } from '@angular/platform-browser';
import { ErrorHandler, NgModule } from '@angular/core';
import { IonicApp, IonicErrorHandler, IonicModule } from 'ionic-angular';
import { SplashScreen } from '@ionic-native/splash-screen';
import { StatusBar } from '@ionic-native/status-bar';
import { MyApp } from './app.component';
import { HttpModule } from '@angular/http'

import { Geolocation } from '@ionic-native/geolocation';
import { SearhcMuseumPage } from '../pages/searchMuseum/searchMuseum';
import { MuseumDetailPage } from '../pages/museum-detail/museum-detail';
import { AllMuseumPage } from '../pages/all-museum/all-museum';


@NgModule({
  declarations: [
    MyApp,
    SearhcMuseumPage,
    MuseumDetailPage,
    AllMuseumPage
  ],
  imports: [
    BrowserModule,
    HttpModule,
    IonicModule.forRoot(MyApp)
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    SearhcMuseumPage,
    MuseumDetailPage,
    AllMuseumPage
  ],
  providers: [
    StatusBar,
    SplashScreen,
    {provide: ErrorHandler, useClass: IonicErrorHandler},
	  Geolocation
  ]
})
export class AppModule {}

Creating Museum Model

Inside src folder create a new folder called models and add the new file for museum model as a src/models/museum.ts. Add the following code

export interface Museum{
    name: string;
    state : string;
    latitude: any;
    longitude:any
}

 

Step 5: Adding museum list and search list page

We have to add the list of the museum in musuem.json file. In src/assets/data add a new file called museum.json file. Add the following museum lists.

{
  "museums": [
      {
        "name": "National Museum",
        "state" : "Delhi",
        "latitude": 28.6117993,
        "longitude": 77.2194934
      },
      {
        "name": "National Science Centre,",
        "state": "Delhi",
        "latitude": 28.6132098,
        "longitude": 77.245437
      },
      {
        "name": "The Sardar Patel Museum",
        "state": "Gujrat",
        "latitude": 21.1699005,
        "longitude": 72.7955734
      },
      {
        "name": "Library of Tibetan Works and Archives",
        "state": "Himachal",
        "latitude": 32.2263696,
        "longitude": 76.325326

      },
      {
        "name": "Chhatrapati Shivaji Maharaj Vastu Sangrahalaya",
        "state": "Maharashtra",
        "latitude": 18.926873,
        "longitude": 72.8326132
      },
      {
        "name": "Namgyal Institute of Tibetology",
        "state": "Sikkim",
        "latitude": 27.315948,
        "longitude": 88.6047829

      }
      ]
}

Making a REST HTTP Request, our apps will read a JSON file which contains all the museum and its details. An HTTP call is used to retrieve the JSON file content and loads the JSON to a local variable. We need to import HTTP module and Rxjs (Reactive Extensions Library for JavaScript).  We will add search box in our apps to search museum by state name or location name. Modify the following code in searchMuseum.html 

<ion-header>
  <ion-navbar color="primary">
     <ion-title>Museum in India</ion-title>
     <ion-buttons end>
        <button ion-button (click)="allMuseumMap()">
        <ion-icon ios="ios-pin" md="md-pin"></ion-icon>All Museum</button>
      </ion-buttons> 
  </ion-navbar>
</ion-header>

<ion-content padding>
  <ion-input type="text" placeholder="Search Museum..." (input)="searchMaps($event)"></ion-input>

  <ion-list *ngIf="!isfiltered">
    <ion-item *ngFor="let museum of museumList" (click)="itemTapped($event, museum)">
      <h2><ion-icon ios="ios-pin" md="md-pin"></ion-icon>{{museum.name}}</h2>
      <p>State name: {{museum.state}}</p>
    </ion-item>
  </ion-list>

  <ion-list *ngIf="isfiltered">
    <ion-item *ngFor="let museum of filteredMuseum" (click)="itemTapped($event, museum)">
      <h2><ion-icon ios="ios-pin" md="md-pin"></ion-icon>{{museum.name}}</h2>
        <p>State name: {{museum.state}}</p>
    </ion-item>
  </ion-list>
</ion-content>

In searchMuseum.ts modify the following code

import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import {Http} from '@angular/http';
import 'rxjs/add/operator/map';
import { MuseumDetailPage } from '../museum-detail/museum-detail';
import { AllMuseumPage } from '../all-museum/all-museum';

@IonicPage()
@Component({
  selector: 'page-searchMuseum',
  templateUrl: 'searchMuseum.html',
})
export class SearhcMuseumPage{
  museumList = [];
  filteredMuseum = [];
  isfiltered: boolean ;

  constructor(private http:Http, public navCtrl: NavController, public navParams: NavParams) {
    this.isfiltered = false;
    this.http.get('assets/data/museum.json')
    .map(res => res.json())
    .subscribe(data => {
        this.museumList = data.museums;
      },
      err => console.log("error is "+err), // error
      () => console.log('read museum data Complete '+ this.museumList) // complete
    );
  }

  searchMaps(event) {
    if(event.target.value.length > 2) {
      var filteredJson = this.museumList.filter(function (row) {
        if(row.state.indexOf(event.target.value) != -1) {
          return true
        } else {
          return false;
        }
      });
      this.isfiltered = true;
      this.filteredMuseum = filteredJson;
    }
  }

  itemTapped(event, museum) {
     this.navCtrl.push(MuseumDetailPage, {
       museum: museum
     });
  }

  allMuseumMap(){
    this.navCtrl.push(AllMuseumPage, {
       museumList: this.museumList
    });
  }
}

Add the following css code in searchMuseum.scss

ion-navbar ion-icon{
    padding-right:0.5rem;
}

input[type=text]{
    border: 1px solid blue;
    height: 2rem;
    padding:0.2rem;
}

ion-item  ion-icon{
    color:red;
    margin:0.8rem 0.5rem 0 0;
}

 

Step 6: Adding Mulitple marker on Google Map

We have created three-page in this apps, one to display the list of the museum with search methods. This page all-museum is to the display multiple markers on same Google map.  In searchMuseum page we have a button at the right top most “ALL MUSEUM” on clicking on this button will navigate us to the all-museum page to display all museum in Google map.  Modify the following code all-museum.html

<ion-header>
  <ion-navbar color="primary">
    <ion-title>Museum in India</ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding>
	<div #map id="map"></div>  
</ion-content>

Modify the following code in all-museum.ts

import { Component, ViewChild, ElementRef } from '@angular/core';
import { NavController, NavParams } from 'ionic-angular';
import { Geolocation } from '@ionic-native/geolocation';
import { Http } from '@angular/http';
 
declare var google;

@Component({
  selector: 'page-all-museum',
  templateUrl: 'all-museum.html',
})

export class AllMuseumPage {
  @ViewChild('map') mapContainer: ElementRef;
  map: any;
  museumList = [];

  constructor(public navCtrl: NavController, public navParams: NavParams, public geolocation: Geolocation, public http: Http) {
    this.museumList = navParams.get('museumList');
    console.log(this.museumList);
  }

  ionViewDidLoad() {
    this.displayGoogleMap();
    this.getMarkers();
  }

  displayGoogleMap() {
    let latLng = new google.maps.LatLng(28.6117993, 77.2194934);

    let mapOptions = {
      center: latLng,
      disableDefaultUI: true,
      zoom: 4,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    }
    this.map = new google.maps.Map(this.mapContainer.nativeElement, mapOptions);
  }

  getMarkers() {
    for (let _i = 0; _i < this.museumList.length; _i++) {
      if(_i > 0 )
       this.addMarkersToMap(this.museumList[_i]);
    }
  }

  addMarkersToMap(museum) {
      var position = new google.maps.LatLng(museum.latitude, museum.longitude);
      var museumMarker = new google.maps.Marker({position: position, title: museum.name});
      museumMarker.setMap(this.map);
  }

}




Add the following css code in all-museum.scss
page-all-museum {
	scroll {
    	height: 100%
    }
    #map {
        width: 100%;
        height: 100%;
    }
}

 

Step 6: Displaying individual map for each museum with museum information

In searchMuseum.html, we have a list of all the museum and on clicking on each museum we will display Google map for each museum with museum detail information like name of museum and state where it is located.  Modify the museum-detail.html

<ion-header>
  <ion-navbar color="primary">
    <ion-title> {{museum.state}}</ion-title> 
  </ion-navbar>
</ion-header>

<ion-content>
 <ion-card padding>
     <h3>Museum name : {{museum.name}}</h3>
     <p>Location : {{museum.state}}</p>
    <div #map id="map"></div>  
 </ion-card>
</ion-content>

Modify the following code in museum-detail.ts 

import { Component, ViewChild, ElementRef } from '@angular/core';
import { NavController, NavParams } from 'ionic-angular';
import { Geolocation } from '@ionic-native/geolocation';
import { Museum } from '../../models/museum';
 
declare var google;

@Component({
  selector: 'page-museum-detail',
  templateUrl: 'museum-detail.html',
})

export class MuseumDetailPage {
  @ViewChild('map') mapContainer: ElementRef;
  map: any;
  museum = {} as Museum;

  constructor(public navCtrl: NavController, public navParams: NavParams,public geolocation: Geolocation) {
    this.museum = navParams.get('museum');
  }

  ionViewDidLoad(){
    this.displayGoogleMap();
  }


  displayGoogleMap() {
    let latLng = new google.maps.LatLng(this.museum.latitude, this.museum.longitude);
    let mapOptions = {
      center: latLng,
      zoom: 15,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    };
  
    this.map = new google.maps.Map(this.mapContainer.nativeElement, mapOptions);
    let marker = new google.maps.Marker({
      map: this.map,
      animation: google.maps.Animation.DROP,
      position: latLng
    });
    this.addInfoWindow(marker, this.museum.name + this.museum.state);
  }
  
  addInfoWindow(marker, content){
    let infoWindow = new google.maps.InfoWindow({
      content: content
    });
    google.maps.event.addListener(marker, 'click', () => {
      infoWindow.open(this.map, marker);
    });
  }
}

Add the following css code in museum-detail.scss 


.ios, .md {
    page-museum-detail {
        .scroll {
            height: 100%
          }
     
        #map {
            width: 100%;
            height: 400px;
            margin-top:2em;
        }
    } 
}