Skip to main content

Angular 10|9|8 Google Maps with Places Search and Draggable Marker using Angular Google Maps (@agm/core)

 1.Install Angular Google Maps

To use Google Maps in Angular application, install the @agm/core package

Run the following command to install AGM in Angular

Install Types for GoogleMaps


$ npm install @types/googlemaps --save-dev

Update App Module

Next, open the app.module.ts file, import AgmCoreModule then update the imports array

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';

import { AgmCoreModule } from '@agm/core';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AgmCoreModule.forRoot({
      apiKey: 'YOUR-API-KEY-HERE',
      libraries: ['places']
    })
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }



Adding Google Maps in Component

For creating a Google Map in the template, we add the <agm-map/> component with binding properties for setting latitude, longitude, zoom, and other configurations.

The map will also have a Marker, which is created by adding the <agm-marker/> component.

# Update App Template

Add the AGM template in the App component to show basic Google Map with the current location. To get current coordinates like longitude & latitude, we will use geolocation service in the navigator.

<!-- app.component.html -->
<agm-map 
[latitude]="latitude" 
[longitude]="longitude" 
[zoom]="zoom" >
  <agm-marker 
  [latitude]="latitude" 
  [longitude]="longitude"></agm-marker>
</agm-map>

 

# Update Component Class

On component load, we’ll call the navigator.geolocation API service to get current position of the user. The setCurrentLocation() method will fetch latitude and longitude to set Google Map to the current location.

//app.component.ts

import { Component, OnInit } from '@angular/core';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent  implements OnInit {
  title: string = 'AGM project';
  latitude: number;
  longitude: number;
  zoom:number;


  ngOnInit() {
    this.setCurrentLocation();
  }

    // Get Current Location Coordinates
    private setCurrentLocation() {
      if ('geolocation' in navigator) {
        navigator.geolocation.getCurrentPosition((position) => {
          this.latitude = position.coords.latitude;
          this.longitude = position.coords.longitude;
          this.zoom = 15;
        });
      }
    }

}

Add Map height in app.component.scss

agm-map {
    height: 300px;


Location/ Places Search bar

In app.component.html we will now add a search bar with address and Latitude & Longitude information.

The marker is now draggable so that the user can drag it to the desired location.

[markerDraggable]option is set to true.

(dragEnd)the event will fire to get the address of the current drop.

# Update the App component template

<!-- app.component.html -->
<div class="container">

  <h1>Angular Google Maps with Places Search Example</h1>

  <div class="form-group">
    <label>Enter address</label>
    <input type="text" class="form-control" (keydown.enter)="$event.preventDefault()" placeholder="Search Nearest Location" autocorrect="off" autocapitalize="off" spellcheck="off" type="text" #search>
  </div>

  <agm-map [latitude]="latitude" [longitude]="longitude" [zoom]="zoom">
    <agm-marker [latitude]="latitude" [longitude]="longitude" [markerDraggable]="true"
      (dragEnd)="markerDragEnd($event)"></agm-marker>
  </agm-map>

  <h5>Address: {{address}}</h5>
  <div>Latitude: {{latitude}}</div>
  <div>Longitude: {{longitude}}</div>
</div>

 

# Update Component Class

In app.component.ts we will add Google map Autocomplete method to return address data set.

Geocoder location service will return address based on provided Latitude & Longitude in the method getAddress()

The template reference variable #search on Input field is used to find the key events for fetching addresses based on current location.

The markerDragEnd() method is called after the user stops marker drag to fetch the address of the current marker position.

//app.component.ts

import { Component, OnInit, ViewChild, ElementRef, NgZone } from '@angular/core';
import { MapsAPILoader, MouseEvent } from '@agm/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  title: string = 'AGM project';
  latitude: number;
  longitude: number;
  zoom: number;
  address: string;
  private geoCoder;

  @ViewChild('search')
  public searchElementRef: ElementRef;


  constructor(
    private mapsAPILoader: MapsAPILoader,
    private ngZone: NgZone
  ) { }


  ngOnInit() {
    //load Places Autocomplete
    this.mapsAPILoader.load().then(() => {
      this.setCurrentLocation();
      this.geoCoder = new google.maps.Geocoder;

      let autocomplete = new google.maps.places.Autocomplete(this.searchElementRef.nativeElement);
      autocomplete.addListener("place_changed", () => {
        this.ngZone.run(() => {
          //get the place result
          let place: google.maps.places.PlaceResult = autocomplete.getPlace();

          //verify result
          if (place.geometry === undefined || place.geometry === null) {
            return;
          }

          //set latitude, longitude and zoom
          this.latitude = place.geometry.location.lat();
          this.longitude = place.geometry.location.lng();
          this.zoom = 12;
        });
      });
    });
  }

  // Get Current Location Coordinates
  private setCurrentLocation() {
    if ('geolocation' in navigator) {
      navigator.geolocation.getCurrentPosition((position) => {
        this.latitude = position.coords.latitude;
        this.longitude = position.coords.longitude;
        this.zoom = 8;
        this.getAddress(this.latitude, this.longitude);
      });
    }
  }


  markerDragEnd($event: MouseEvent) {
    console.log($event);
    this.latitude = $event.coords.lat;
    this.longitude = $event.coords.lng;
    this.getAddress(this.latitude, this.longitude);
  }

  getAddress(latitude, longitude) {
    this.geoCoder.geocode({ 'location': { lat: latitude, lng: longitude } }, (results, status) => {
      console.log(results);
      console.log(status);
      if (status === 'OK') {
        if (results[0]) {
          this.zoom = 12;
          this.address = results[0].formatted_address;
        } else {
          window.alert('No results found');
        }
      } else {
        window.alert('Geocoder failed due to: ' + status);
      }

    });
  }

}

 

For making it look beautiful we have added bootstrap.css in index.html

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">



Comments

  1. Superb Post!
    Thanks for providing such a comprehensive overview of this topic.
    Are you looking for the top PWA development company? Contact us - we create high-performance web apps that bridge the gap between web and mobile, ensuring user satisfaction.

    ReplyDelete

Post a Comment

Popular posts from this blog

How to use Ngx-Charts in Angular ?

Charts helps us to visualize large amount of data in an easy to understand and interactive way. This helps businesses to grow more by taking important decisions from the data. For example, e-commerce can have charts or reports for product sales, with various categories like product type, year, etc. In angular, we have various charting libraries to create charts.  Ngx-charts  is one of them. Check out the list of  best angular chart libraries .  In this article, we will see data visualization with ngx-charts and how to use ngx-charts in angular application ? We will see, How to install ngx-charts in angular ? Create a vertical bar chart Create a pie chart, advanced pie chart and pie chart grid Introduction ngx-charts  is an open-source and declarative charting framework for angular2+. It is maintained by  Swimlane . It is using Angular to render and animate the SVG elements with all of its binding and speed goodness and uses d3 for the excellent math functions, scales, axis and shape ge

JavaScript new features in ES2019(ES10)

The 2019 edition of the ECMAScript specification has many new features. Among them, I will summarize the ones that seem most useful to me. First, you can run these examples in  node.js ≥12 . To Install Node.js 12 on Ubuntu-Debian-Mint you can do the following: $sudo apt update $sudo apt -y upgrade $sudo apt update $sudo apt -y install curl dirmngr apt-transport-https lsb-release ca-certificates $curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash - $sudo apt -y install nodejs Or, in  Chrome Version ≥72,  you can try those features in the developer console(Alt +j). Array.prototype.flat && Array.prototype. flatMap The  flat()  method creates a new array with all sub-array elements concatenated into it recursively up to the specified depth. let array1 = ['a','b', [1, 2, 3]]; let array2 = array1.flat(); //['a', 'b', 1, 2, 3] We should also note that the method excludes gaps or empty elements in the array: let array1

Understand Angular’s forRoot and forChild

  forRoot   /   forChild   is a pattern for singleton services that most of us know from routing. Routing is actually the main use case for it and as it is not commonly used outside of it, I wouldn’t be surprised if most Angular developers haven’t given it a second thought. However, as the official Angular documentation puts it: “Understanding how  forRoot()  works to make sure a service is a singleton will inform your development at a deeper level.” So let’s go. Providers & Injectors Angular comes with a dependency injection (DI) mechanism. When a component depends on a service, you don’t manually create an instance of the service. You  inject  the service and the dependency injection system takes care of providing an instance. import { Component, OnInit } from '@angular/core'; import { TestService } from 'src/app/services/test.service'; @Component({ selector: 'app-test', templateUrl: './test.component.html', styleUrls: ['./test.component