Thursday, June 27, 2019

Ionic 4 | Get Device Latitude, Longitude and Address using Geolocation and Native Geocoder Services in Ionic 4 Native Application

Previously we implemented Geolocation and Geocoder plugins in Ionic 3 application, In this post, we will create an application in latest Ionic version 4 beta. Using Geolocation service we can get Lattitude, Longitude, Accuracy of location, Speed, Altitude etc of the device. After that Latitude and Longitude can be used to get Addresses available on these coordinates. To fetch address from coordinates of the device, we use Geocoder service.

Create a new Ionic Application

Install latest version of Ionic and Cordova CLI.
$ npm install -g ionic cordova
Now we will create a new blank application
$ ionic start Ionic3Geolocation_Geocoder blank
After the application is created, go to the root using the CD command
$ cd Ionic3Geolocation_Geocoder

Install the Cordova and Ionic Native plugins
Geolocation
$ ionic cordova plugin add cordova-plugin-geolocation
$ npm install @ionic-native/geolocation
Geocoder
$ ionic cordova plugin add cordova-plugin-nativegeocoder
$ npm install @ionic-native/native-geocoder

Add this plugin in the application’s module file
in app.module.ts, import plugin and add in imports array.
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouteReuseStrategy } from '@angular/router';

import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';

import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';

import { Geolocation } from '@ionic-native/geolocation/ngx';
import { NativeGeocoder } from '@ionic-native/native-geocoder/ngx';

@NgModule({
  declarations: [AppComponent],
  entryComponents: [],
  imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule],
  providers: [
    StatusBar,
    SplashScreen,
    Geolocation,
    NativeGeocoder,
    { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

In home.page.html, add following HTML
<ion-header>
  <ion-toolbar>
    <ion-title>
      Ionic 4 Geolocation & Geocoder
    </ion-title>
  </ion-toolbar>
</ion-header>

<ion-content padding>
  <h1>Get Location</h1>

  <ion-button (click)="getGeolocation()">
    Get Location
  </ion-button>
  <ion-button (click)="watchLocation()">
    Watch Location Updates
  </ion-button>
  <ion-button (click)="stopLocationWatch()">
    Stop Location Watch
  </ion-button>

  <div *ngIf="geoLatitude">
    <p>Latitude : {{geoLatitude}}</p>
    <p>Longitude : {{geoLongitude}}</p>
    <p>Accuracy : {{geoAccuracy}}</p>
    <p class="address-text">

      <span class="watch-text" *ngIf="isWatching; else notWatching">
        Watching Location
      </span>
      <ng-template #notWatching>
        Location Watch Stopped
      </ng-template>

      <br>Address : {{geoAddress }}
    </p>
  </div>

</ion-content>
Update component with methods
 in home.page.ts file
 import { Component } from '@angular/core';
import { Geolocation } from '@ionic-native/geolocation/ngx';
import { NativeGeocoder,NativeGeocoderOptions,NativeGeocoderReverseResult } from '@ionic-native/native-geocoder/ngx';

@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage {

  geoLatitude: number;
  geoLongitude: number;
  geoAccuracy:number;
  geoAddress: string;

  watchLocationUpdates:any;
  loading:any;
  isWatching:boolean;

  //Geocoder configuration
  geoencoderOptions: NativeGeocoderOptions = {
    useLocale: true,
    maxResults: 5
  };
  constructor(
    private geolocation: Geolocation,
    private nativeGeocoder: NativeGeocoder
  ) {
  }


    //Get current coordinates of device
    getGeolocation(){
      this.geolocation.getCurrentPosition().then((resp) => {
        this.geoLatitude = resp.coords.latitude;
        this.geoLongitude = resp.coords.longitude;
        this.geoAccuracy = resp.coords.accuracy;
        this.getGeoencoder(this.geoLatitude,this.geoLongitude);
       }).catch((error) => {
         alert('Error getting location'+ JSON.stringify(error));
       });
    }

    //geocoder method to fetch address from coordinates passed as arguments
    getGeoencoder(latitude,longitude){
      this.nativeGeocoder.reverseGeocode(latitude, longitude, this.geoencoderOptions)
      .then((result: NativeGeocoderReverseResult[]) => {
        this.geoAddress = this.generateAddress(result[0]);
      })
      .catch((error: any) => {
        alert('Error getting location'+ JSON.stringify(error));
      });
    }

    //Return Comma saperated address
    generateAddress(addressObj){
        let obj = [];
        let address = "";
        for (let key in addressObj) {
          obj.push(addressObj[key]);
        }
        obj.reverse();
        for (let val in obj) {
          if(obj[val].length)
          address += obj[val]+', ';
        }
      return address.slice(0, -2);
    }


    //Start location update watch
    watchLocation(){
      this.isWatching = true;
      this.watchLocationUpdates = this.geolocation.watchPosition();
      this.watchLocationUpdates.subscribe((resp) => {
        this.geoLatitude = resp.coords.latitude;
        this.geoLongitude = resp.coords.longitude;
        this.getGeoencoder(this.geoLatitude,this.geoLongitude);
      });
    }

    //Stop location update watch
    stopLocationWatch(){
      this.isWatching = false;
      this.watchLocationUpdates.unsubscribe();
    }
}
CSS styling in home.page.scss
page-home {
    .address-text{
        text-align: center;
        font-size: 20px;
    }
    .watch-text{
        font-size: 18px;
    }
}


No comments:

Post a Comment