> > > #3 – Mapping with Angular, Google Maps API and GeoJSON

#3 – Mapping with Angular, Google Maps API and GeoJSON

This post is a continuation of my previous post titled: Indoor Mapping with Google Maps API and GeoJSON.

In the previous post I have described how to create an indoor mapping web app using Google Maps API in pure JavaScript. In this post we will see how to convert that application to use Angular framework and TypeScript instead of JavaScript. Currently, only a part of the whole application is converted which include the following:

  1. Base map using Google Map
  2. GeoJSON data imported without level switch control and Information Bar.

So, let’s start!

1. Creating a new Angular project

I have used the Angular CLI to create a new Angular project. Angular CLI is a command line interface tool which can do much more that creating a project. This include, adding files to project, testing, bundling, deployment, etc.

To install Angular CLI, use the command:

npm install -g @angular/cli

Pr-requirements:  Node 6.9+ and npm 3+

To create a new project, run the command:

ng new indoor-map-agm

Where “indoor-map-agm” is the name of our project.

Wait for while to complete process.

2. Installing Angular Google Maps (AGM)

Angular Google Maps (AGM) is a package which provides angular components and directives to implement Google Maps API in Angular 2 and above. In order to use AGM, we have to first install it into our project.

AGM can be installed using npm:

cd indoor-map-agm
npm install @agm/core --save

3. Setting Up app.module, app.component and Service

We have to import the AgmCoreModule in the app.module.ts and set it up within the @NgModule decorator. Also, it is important to place our Google Maps API key in the @NgModule.

After performing these changes, our app.module.ts now look like this:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule, ApplicationRef } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { HttpModule } from '@angular/http';
import { AgmCoreModule } from '@agm/core';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    CommonModule,
    FormsModule,
    HttpModule,
    AgmCoreModule.forRoot({
      apiKey: 'AIzaSyCuF0jO6w-aCgx7P28epp7zKGbNJwjlw6g'
    })
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Our app.component.ts is given below:

import { Component, OnInit } from '@angular/core';
import { IndoorDataService } from "./indoordata.service";

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  providers: [IndoorDataService]
})

export class AppComponent implements OnInit {
  title: string = 'Mapping with Angular';
  lat: number = 12.992634899999999;
  lng: number = 77.71721695;
  zoom: number = 20;
  geoJsonObject: Object;

  constructor(private _indoorDataService: IndoorDataService) {}

  // function to consume IndoorDataService observable
  getGeoJSON(): void {
    this._indoorDataService.getGeoJson()
      .subscribe(resGeoJsonData => this.geoJsonObject = resGeoJsonData);
  }
  // on init lifecycle hook
  // We get the GeoJSON here
  ngOnInit() : void {
    this.getGeoJSON();
  }

  styleFunc(feature) {
    // get level - 0/1
    var level = feature.getProperty('level');
    var color = 'green';
    // only show level one features
    var visibility = level == 1 ? true : false;
    return {
      // icon for point geometry(in this case - doors)
      icon: 'assets/images/door.png',
      // set fill color for polygon features
      fillColor: color,
      // stroke color for polygons
      strokeColor: color,
      strokeWeight: 1,
      // make layer 1 features visible
      visible: visibility
    };
  }
}

Everything except the highlighted lines are self explanatory as we have already done it in the previous post. The highlighted code is concerned with importing and consuming the Angular Service which is responsible for fetching the GeoJSON file from the server. A detailed explanation of Service and Observables can be seen in this video.

As we can see, we have imported the IndoorDataService  from indoordata.service.ts. The content of indoordata.service.ts is shown below:

import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import 'rxjs/add/operator/map';

@Injectable()
export class IndoorDataService {

  // location of GeoJSON file in server
  private _url: string = 'assets/pg.json';

  constructor(private _http: Http) {}

  // fetch the file and parse the result as JSON
  getGeoJson() {
    return this._http.get(this._url)
      .map((response: Response) => response.json());
  }
}

4. HTML and CSS

As declared in the app.component.ts file’s @Component decorator, we have two separate file which include the HTML and CSS respectivley for rendering the map.

The content of the app.component.html is shown below:

<!-- this creates a google map on the page with the given lat/lng from -->
<!-- the component as the initial center of the map: -->
<agm-map [latitude]="lat" [longitude]="lng" [zoom]="zoom">
     <agm-data-layer *ngIf="geoJsonObject" [geoJson]="geoJsonObject" (layerClick)="clicked($event)" [style]="styleFunc" >
     </agm-data-layer>
</agm-map>

This agm-map component is provided by AGM and it takes the inputs longitude, latitude and zoom. Also the agm-data-layer component is used to import the GeoJSON to map. The *ngIf directive check if the geoJsonObject is not null (whether it is loaded or not). This is important as, if not used, the feature style wont apply correctly.

The CSS file contain minimal rules to set the height of the map:

html, body {
  height: 100%;
  margin: 0;
  padding: 0;
}
app-root, agm-map {
  height: 500px;
}

5. Running the Application

Finally to run the app and see our map in action, use the command:

ng serve --open

angular-gogle map geojsonThe complete code is available here: github

The following two tabs change content below.

Vipin Raj

Vipin Raj is a software developer specialized in PostgreSQL Database and Data Modeling, the man behind technobytz and an IoT and Security enthusiast. Having 3+ years of experience in the IT industry, he is currently pursuing his masters in computer science and information security. He spend his free time writing blog posts with the intension of sharing his knowledge to the tech community.

2 thoughts on “#3 – Mapping with Angular, Google Maps API and GeoJSON

  • November 2, 2017 at 10:29 pm
    Permalink

    Hi, your github link is broken. Could you restore it?

    Reply
    • December 6, 2017 at 10:39 pm
      Permalink

      Sorry. It is restored now!

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *