Integrating Google Maps in Your Angular Application

Introduction

In Angular, adding a map manually could be a tedious task. The angular community has solved this problem by designing a different package for maps. Angular has a different module for integrating maps in our Angular project. We just have to import the module and we are good to go. We need an API key from Google for using the map functionality in our project. We can go to google developers console for generating a map API key for our project. 

Installing the Angular Google Map(AGM) Package

We will use the NPM install command to import the AGM package to our project. Go to the terminal and type the following command:

$ npm i @agm/core --save

The above command will install the package and make an entry in the package.json file as well under the dependencies section. We can see the entry shown below in the image.



We will add the entry in the app.mdoule.ts file also. 

import { BrowserModule, DomSanitizer } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { HttpClientModule } from '@angular/common/http';
import { MaterialModule } from './modules/material/material.module';
import { AuthGuard } from './services/gaurds/auth.guard';
import { RolesAuthGuard } from './services/gaurds/roles.auth.guard';
import { AppComponent } from './app.component';
import { MatIconRegistry } from '@angular/material';
import { AgmCoreModule } from '@agm/core'

@NgModule({
  declarations: [
    AppComponent,   
  ],
  imports: [
    BrowserModule,
    NgxDatatableModule,
    AppRoutingModule,
    HttpClientModule,
    FormsModule,
    ReactiveFormsModule,
    BrowserAnimationsModule,
   AgmCoreModule.forRoot({
      apiKey: 'AIzaSyDShdMS18_xwv3VHpzQlGgr10v0SmD7SyE'
    }),
    
  ],
  providers: [ ],
  bootstrap: [AppComponent]
})

export class AppModule {
  constructor() {
  }
}

Now we can use the AGM map in our components. Let us create an agm-map component. We will go to the agm-map.component.html file and write the following code to show the map.

  <div>
    <agm-map #agmMap [latitude]="lat" [longitude]="lng"> </agm-map>
  </div>

Now we can see that to place the map at a particular coordinate we have defined the lat and lng value in the agm-map.component.ts file.

import { Component, OnInit, ViewChild, AfterViewInit, AfterContentInit } from '@angular/core';
import { AgmMap } from '@agm/core';

declare const google: any;

@Component({
  selector: 'app-dashboard-map',
  templateUrl: './dashboard-map.component.html',
  styleUrls: ['./dashboard-map.component.scss'],
  encapsulation: ViewEncapsulation.None,
})
export class DashboardMapComponent implements OnInit, AfterViewInit, AfterContentInit {
  lat: number = 29.0054352;
  lng: number = -101.7626926;

  @ViewChild("agmMap") agmMap: AgmMap;
}

Remember that we have to explicitly give height to the element in our CSS file to be visible on the screen. 
We will go to the component.scss file and define the height.

agm-map {
    height: 85vh; // This step is must to see the map on the screen
}


We have a number of different options to enhance the user-interaction and functionality in our map like zoom, maxZoom, mapTypeControl, mapTypeId, zoomControl, etc. We will include these options in our <agm-map> element. Some are defined below. You can refer full documentation for <agm-map> here.
  • zoom -  Using this property we can set the zoom level for the map. The default value is 8.
  • maxZoom - This property will set the maximum zoom level for the map. If we will not provide this property, then the map can be zoomed to any level. There will be no restrictions.
  • mapTypeControl - To see the map type controls, we can set the value of this property to true or false. 
  • mapTypeId - This defines the map type. Values can be "roadmap" or "hybrid" or "satellite" or "terrain" or string. "roadmap" is the default.
  • zoomControl - To see the zoom controls on our map, we can set the value to true or false. 

  <div>
    <agm-map #agmMap [latitude]="lat" [longitude]="lng" [zoom]="4" [maxZoom]="16" 
      [zoomControl]="true" [mapTypeId]="terrain" [mapTypeControl]="true"> </agm-map>
  </div>

Now we will add more components and directives to enhance the map. 

<agm-marker>

This element will render a marker on our <agm-map>. Suppose we want to see different markers on the map at different values of latitude and longitude. The icon should be some image given as png. How to show this on our map using <agm-marker> are as follows. Go to the agm-map.component.html file.
We will use [iconUrl]  for placing our own icon as a marker. We have used *ngFor directive to loop over the site array. On clicking the marker, markerClick() event will be called. 

  <div>
    <agm-map #agmMap [latitude]="lat" [longitude]="lng" [zoom]="4" [maxZoom]="16" 
      [zoomControl]="true" [mapTypeId]="terrain" [mapTypeControl]="true">
   <agm-marker  *ngFor="let site of sites" [latitude]="site.lat" [longitude]="site.lng" 
        [iconUrl]="'/images/icon-marker-image.png'"  (markerClick)="onMarkerClick($event)">
  </agm-marker>
 </agm-map>
  </div>

We will go to the agm-map.component.ts file and define the site array and onMarkerClick() method.

import { Component, OnInit, ViewChild, AfterViewInit, AfterContentInit } from '@angular/core';
import { AgmMap } from '@agm/core';

declare const google: any;

@Component({
  selector: 'app-dashboard-map',
  templateUrl: './dashboard-map.component.html',
  styleUrls: ['./dashboard-map.component.scss'],
  encapsulation: ViewEncapsulation.None,
})
export class DashboardMapComponent implements OnInit, AfterViewInit, AfterContentInit {
  lat: number = 29.0054352;
  lng: number = -101.7626926;
  sites= [
    { lat: 35.929673, lng: -78.948237 }
    { lat: 38.889513, lng: -78.477510 },
    { lat: 47.92394, lng: -97.472300 },
   ];
  @ViewChild("agmMap") agmMap: AgmMap;

    onMarkerClick(event){
     console.log("The selected marker coordinates are:"+ event.latitude +"and" + event.longitude);
    }
}

Comments