Get longitude and latitude from an Address with Google Maps programmatically

After some Googling on how to get Longitude and Latitde from an address using the Maps JavaScript API I soon understood that you actually can’t use this particular API, it is only for displaying the map, but you can easily use another api to do this which works in the same way.

The API we need to use to achieve this is Geocoding API. There you can easily get the longitude and latitude from an address of your choosing. You can complete the previous post if you want to keep up with setting up a project which uses Google Maps to display the visual map, but you can understand how to get the longitude and latitude from an address just by reading this post too!

Okay first, enable the API for Geocoding.

Then have your API key ready which you can get from clicking manage when you found that API and then click on Credentials. Under API Keys is your API key.

. We can get the details of the Google map location by passing in an address into the URL in this manner:

https://maps.googleapis.com/maps/api/geocode/json?address=Zimbabwe&key=MYAPIKEY

Obviously you must replace MYAPIKEY with your actual API key and then address works just like you would search on an address in Google Maps. Let’s add this to our application!

I have a LocationService where I am going to add Observable property called locations:

  locations: Observable<Object>

Then I am going get HttpClient to the constructor:

constructor(httpClient: HttpClient)  

Then add the code for retrieving the Google Maps location data inside the constructor:

  constructor(httpClient: HttpClient) { 
    this.locations = httpClient.get('https://maps.googleapis.com/maps/api/geocode/json?address=Zimbabwe&key=MYAPIKEY') .pipe(
      map((data) => {
        return data;
      }),
      catchError(val => {
        return of(val)
      }),
    );
  }

Then inside a component we call on the method to try it out:

 locationService.locations.subscribe(l => {
      console.log(l);
    });

When we run the application we can see the console.log of the data we get back which is indeed the Google location we wanted (Zimbabwe). That’s basically it!

Now as said previously, I have continued on my previous angular app with google maps project, so we already have the code for showing map markers, and a method to add locations where we want the markers. So what I’ll do is that I go through each location result and add a pin to our Google Map, like this:

    locationService.locations.subscribe((l: any) => {
      l.results.forEach(element => {
        this.addMarker(element.geometry.location)
      });
    });

Now when we look at the map we will see Zimbabwe since that is the address I put into the search url:

https://maps.googleapis.com/maps/api/geocode/json?address=Zimbabwe&key=MYAPIKEY

It’s that easy!

Create an Angular 11 app that use Google Maps

In case you are curious how to add Google Maps to your Angular app you can follow my little tutorial here. We add a new Angular project from scratch. I will use Angular 11, but of course you can probably use another version as well.

Since I had Angular 10 previously on my computer, I could update it simply with

install -g @angular/cli@latest

If you are in a previous Angular app project adding the Google Map and need to update Angular from 10 to 11 for example, you can do this

ng update @angular/cli @angular/core

Now let us first enable the API so we can actually load the Google Maps. It’s less work than you’d think, specially if you have a Google Cloud account already. If you don’t you have to create one so you can login to the Google Cloud Console. Now, to enable:

  1. Go to your project and then enable the API.
    Search for “Maps JavaScript API” which should take you here.
  2. Create credentials so you can get an API key for the Google Maps API (if you haven’t already)

I will now create a new project Angular 11 project from scratch.

ng new mymapproject
  • I get the question: Do you want to enforce stricter type checking and stricter bundle budgets in the workspace?
    This setting helps improve maintainability and catch bugs ahead of time.
    For more information, see https://angular.io/strict

    My answer is no.
  • Another question: Would you like to add Angular routing? (y/N)
    My answer is yes.
  • Which stylesheet format would you like to use? CSS

Remember to cd your way into your app root folder since you want to run commands in there.

 cd .\mymapproject\

Then I will create a new module file called tutorial-google-maps.module.ts with this ts code

import { NgModule } from '@angular/core';
import { GoogleMapsModule } from '@angular/google-maps';
import { CommonModule } from '@angular/common';
import { HttpClientModule, HttpClientJsonpModule } from '@angular/common/http';
import { TutorialGoogleMapsComponent } from './tutorial-google-maps/tutorial-google-maps.component';

@NgModule({
  declarations: [
    TutorialGoogleMapsComponent,
  ],
  imports: [
    CommonModule,
    GoogleMapsModule,
    HttpClientModule,
    HttpClientJsonpModule,
  ],
  exports: [
    TutorialGoogleMapsComponent,
  ],
})
export class TutorialGoogleMapsModule {}

Let us now download the package for @angular/google-maps like this:

npm i @angular/google-maps

One less error. Of course, we don’t have a component for the tutorial-google-maps.component yet so there is an error there, but we will add one. Let’s use the generate CLI command:

ng g component TutorialGoogleMaps --module tutorial-google-maps.module

Let’s add the actual Google map to our newly created component! First, let’s add some code for tutorial-google-maps.component.ts

import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { of } from 'rxjs/internal/observable/of';
import { map, catchError } from 'rxjs/operators';
@Component({
  selector: 'app-tutorial-google-maps',
  templateUrl: './tutorial-google-maps.component.html',
  styleUrls: ['./tutorial-google-maps.component.css']
})
export class TutorialGoogleMapsComponent implements OnInit {
  apiLoaded: Observable<boolean>;
 
  constructor(httpClient: HttpClient) {
    this.apiLoaded = httpClient.jsonp('https://maps.googleapis.com/maps/api/js?key=[Your API Key here]', 'callback')
      .pipe(
        map(() => true),
        catchError(() => of(false)),
      );
  }

  ngOnInit(): void {
  }
}

Don’t forget the imports for the rxjs.

Change the X to your own API key which you can find in the API & Services -> Credentials page in Google Cloud Console.

Then we are ready to have the element like this in our tutorial-google-maps.component.html file:

<div *ngIf="apiLoaded | async">
  <google-map></google-map>
</div>

Next step is to add our Module to the app module in the app.module.ts file

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    TutorialGoogleMapsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Now let’s add a element which refers to our component, go to app.component.html as seen in the picture below. Then what I’ve did is that I added the code just above <!– Next Steps –> comment which comes from the generated markup by Angular. You can obviously change everything on this page however you want.

  <app-tutorial-google-maps></app-tutorial-google-maps>
View from VS Code

Let’s try run our app!

ng serve

What will happen? Let’s see..

Google Maps in Angular
the result of adding google maps to our Angular app

And there we go, we have the map! Looks good I would say 🙂

If you are unlucky as me, then you might encounter the issue where you get spammed with bunch of errors about MouseEvent like this in your terminal:

node_modules/@angular/google-maps/map-marker/map-marker.d.ts:136:40 – error TS2694: Namespace ‘google.maps’ has no exported member ‘MouseEvent’.

But do not fear. The solution is to add googlemaps types in your packages.json file under your devDependencies like this

"@types/googlemaps": "3.39.14"

add this line and then do another install of your packages

npm i

and try the application again with serve. Now it should look good in your terminal!

Change location of the Google Map

Let us change the location for the Google Map. Create an object which holds various settings for our map including latitude and longitude. Add this property to your TutorialGoogleMapsComponent class inside the tutorial-google-maps.component.ts file. I want to hard set my location to Sweden because why not 🙂

  options: google.maps.MapOptions = {
    center: {lat: 64.48113363780652, lng: 16.33826752001327}, 
    zoom: 4
  };

Tips on finding latitude and longitude for your Angular App: Go to Google Maps and then find your location by searching on your location, then when the map is viewing your place you want to find the coordinates for, right click on the map and click on the top value which is numbers as seen in the image below. I just right clicked on the Empire State Building and there you have the coordinates.

Now let us ddit tutorial-google-maps.component.html so the map take use of the property

<div *ngIf="apiLoaded | async">
    <google-map [options]="options"></google-map>
</div>

Let’s take a look at our map.

Showing the map from our Angular 11 project

Now we are in Sweden, the country where I am from! Great. Next challenge is to take it a step further and set the map to our own location.

Set the Google Maps location to current position

Create a new folder under your app folder called Services. Then run the command for creating a new service:

ng generate service services/location

Then add a new function getPosition in the LocationService class in the file location.service.ts

 getPosition(): Promise<any> {
    return new Promise((resolve, reject) => {
      navigator.geolocation.getCurrentPosition(resp => {
        resolve({ lng: resp.coords.longitude, lat: resp.coords.latitude });
      },
        err => {
          reject(err);
        });
    });
  }

Then modify your tutorial-google-maps.component.ts file to take use of the service and show us the location of where we are. I am increasing the zoom little bit here also. This is now the whole file of tutorial-google-maps.component.ts. So what we do here in the constructor is that we wait for the value from the Promise in our Service function which returns our current location, and then we take those values and set the longitude and the latitude which we use for our map.

import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { of } from 'rxjs/internal/observable/of';
import { map, catchError } from 'rxjs/operators';
import { LocationService } from '../services/location.service';
@Component({
  selector: 'app-tutorial-google-maps',
  templateUrl: './tutorial-google-maps.component.html',
  styleUrls: ['./tutorial-google-maps.component.css']
})
export class TutorialGoogleMapsComponent implements OnInit {
  apiLoaded: Observable<boolean>;
  options: google.maps.MapOptions = {
    center: { lat: 64.48113363780652, lng: 16.33826752001327 },
    zoom: 5
  };
  constructor(httpClient: HttpClient,
    locationService: LocationService) {
    // Use our locationservice!
    locationService.getPosition().then(pos => {
      this.options.center.lat = pos.lat;
      this.options.center.lng = pos.lng;
    });

    this.apiLoaded = httpClient.jsonp('https://maps.googleapis.com/maps/api/js?key=[Your API Key here]', 'callback')
      .pipe(
        map(() => true),
        catchError(() => of(false)),
      );
  }

  ngOnInit(): void {
  }

}

Run your application and see that you must now accept the website trying to get your location.

Before comfirming the website can use my location
After approved website can use my location

And as you see in the image two, I can now see that it finds my location correctly since am in Stockholm. Now you can increase zoom level to like 14 or so and see the exact street and house like you would in Google Maps (maps.google.com) normally but I don’t wanna share my location to the world in this tutorial therefore I feel zoom value 5 is appropriate.

Add a marker to our current location to the map

A thing you might feel is missing is a marker of some kind. Right now it is just a map without much on it but to add markers is not a difficult task. Put a map-marker element inside the google-map element with a for loop of a array of objects of our markers and their location like this in the file tutorial-google-maps.component.html:

<div *ngIf="apiLoaded | async">
    <google-map [options]="options" (mapClick)="addMarker($event)">
        <map-marker *ngFor="let markerPosition of markerPositions" [position]="markerPosition"
            [options]="markerOptions"></map-marker>
    </google-map>
</div>

Then we change up our tutorial-google-maps.component.ts file:

import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { of } from 'rxjs/internal/observable/of';
import { map, catchError } from 'rxjs/operators';
import { LocationService } from '../services/location.service';
@Component({
  selector: 'app-tutorial-google-maps',
  templateUrl: './tutorial-google-maps.component.html',
  styleUrls: ['./tutorial-google-maps.component.css']
})
export class TutorialGoogleMapsComponent implements OnInit {
  apiLoaded: Observable<boolean>;

  options: google.maps.MapOptions = {
    center: { lat: 64.48113363780652, lng: 16.33826752001327 },
    zoom: 6
  };
  markerOptions: google.maps.MarkerOptions = { draggable: false };
  markerPositions: google.maps.LatLngLiteral[] = [];

  addMarker(latLng) {
    this.markerPositions.push(latLng);
  }
  constructor(httpClient: HttpClient,
    locationService: LocationService) {
    locationService.getPosition().then(pos => {
      this.options.center.lat = pos.lat;
      this.options.center.lng = pos.lng;
      let latLng =
      {
        lat: pos.lat,
        lng: pos.lng
      }
      this.addMarker(latLng);
    });

    this.apiLoaded = httpClient.jsonp('https://maps.googleapis.com/maps/api/js?key=AIzaSyCvly', 'callback')
      .pipe(
        map(() => true),
        catchError(() => of(false)),
      );
  }

  ngOnInit(): void {
  }

}

Result

We now see our current location pinned down in our app.

You can play around with more things at the github documentation here.