DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
  1. DZone
  2. Coding
  3. Frameworks
  4. Isoline Mapping With HERE in an Ionic Framework Progressive Web Application

Isoline Mapping With HERE in an Ionic Framework Progressive Web Application

In this post, we learn how to create an Ionic application and use it to create a map application.

Nic Raboy user avatar by
Nic Raboy
·
May. 08, 19 · Tutorial
Like (2)
Save
Tweet
Share
6.82K Views

Join the DZone community and get the full member experience.

Join For Free

I've been giving quite a few demonstrations of isoline graphs, both in person and through previous blog tutorials. It is, in my opinion, one of the most awesome features that HERE offers to developers because of how little is required from the developer while accomplishing so much. In case you're unfamiliar, an isoline is a calculation from a starting point and some range value. Given this information we can visualize how long it might take us to get somewhere within that range or how far we can get. This is not to be confused with a radius which might be inaccurate based on traffic or roads that cannot be traveled.

You might remember that I previously demonstrated how to work with isolines using strictly Angular, but this time around we're going to take a look at working with isolines using the progressive web application framework, Ionic.

To get an idea of what we hope to accomplish, take a look at the following animated image:

Ionic PWA

To keep things simple, we're only going to be worrying about displaying an isoline at our map's center rather than collecting user input as part of a search functionality. You'll notice that this is compatible in the web as well as a mobile Android or iOS application.

Building an Ionic Framework With HERE Maps Application

To start this project we are going to create a new project. However, we'll be using Ionic 4.x and a lot of this code will be recycled from a previous tutorial that was centered around Leaflet, which is a third party rendering library. In this particular tutorial, we'll use the default renderer rather than Leaflet.

Assuming the Ionic CLI is installed, execute the following:

ionic start HereMapsProject blank

The above command will create a new blank project with only one page. We're going for simplicity in an effort to eliminate any confusion that might come out of this subject material.

Now that we have our project, we need to get up to speed with our mapping component. Because I already wrote extensively on the configuration, we're going to breeze through this with minor detail.

Open the project's src/index.html file so we can include our HERE JavaScript SDK:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>Ionic HERE Map</title>
        <base href="/" />
        <meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
        <meta name="format-detection" content="telephone=no" />
        <meta name="msapplication-tap-highlight" content="no" />
        <link rel="icon" type="image/png" href="assets/icon/favicon.png" />
        <meta name="apple-mobile-web-app-capable" content="yes" />
        <meta name="apple-mobile-web-app-status-bar-style" content="black" />
        <link rel="stylesheet" type="text/css" href="https://js.api.here.com/v3/3.0/mapsjs-ui.css?dp-version=1533195059" />
    </head>
    <body>
        <app-root></app-root>
        <script src="https://js.api.here.com/v3/3.0/mapsjs-core.js" type="text/javascript" charset="utf-8"></script>
        <script src="https://js.api.here.com/v3/3.0/mapsjs-service.js" type="text/javascript" charset="utf-8"></script>
        <script src="https://js.api.here.com/v3/3.0/mapsjs-places.js" type="text/javascript" charset="utf-8"></script>
        <script src="https://js.api.here.com/v3/3.0/mapsjs-mapevents.js" type="text/javascript" charset="utf-8"></script>
        <script src="https://js.api.here.com/v3/3.0/mapsjs-ui.js" type="text/javascript" charset="utf-8"></script>
    </body>
</html>

To give us isoline functionality, we've included several of the JavaScript components as well as the CSS library. Different HERE functionality will require different components.

With the JavaScript SDK in place, we need to create our map component by executing the following:

ionic generate component here-map

The above command will create several files, this first of which is for our HTML markup. Open the project's src/app/here-map/here-map.component.html file and include the following:

<div #map style="width: 100%; height: 100%;"></div>

With the container for our map in place, we can start developing the TypeScript logic to go with it. Open the project's src/app/here-map/here-map.component.ts file and include the following:

import { Component, OnInit, ViewChild, ElementRef, Input } from '@angular/core';

declare var H: any;

@Component({
    selector: 'here-map',
    templateUrl: './here-map.component.html',
    styleUrls: ['./here-map.component.scss']
})
export class HereMapComponent implements OnInit {

    @ViewChild("map")
    public mapElement: ElementRef;

    @Input()
    public appId: any;

    @Input()
    public appCode: any;

    @Input()
    public lat: any;

    @Input()
    public lng: any;

    private platform: any;
    private map: any;
    private router: any;

    public constructor() { }

    public ngOnInit() {
        this.platform = new H.service.Platform({
            "app_id": this.appId,
            "app_code": this.appCode
        });
        this.router = this.platform.getRoutingService();
    }

    public ngAfterViewInit() {
        setTimeout(() => {
            let defaultLayers = this.platform.createDefaultLayers();
            this.map = new H.Map(
                this.mapElement.nativeElement,
                defaultLayers.normal.map,
                {
                    zoom: 10,
                    center: { lat: this.lat, lng: this.lng }
                }
            );
            let behavior = new H.mapevents.Behavior(new H.mapevents.MapEvents(this.map));
        }, 100);
    }

    public isoline() { }

}

Everything should look pretty familiar up until now if you saw the previous tutorials I wrote. One difference between this code and the Leaflet code is how we are refreshing the component when the view has finished loading.

You'll notice that the entire ngAfterViewInit method is wrapped with a setTimeout. This is necessary because in the Ionic Framework, the view size isn't instantly ready, even in the lifecycle hooks that Angular offers. We could either add a timeout to the whole code, or we could optionally set a timeout like this:

setTimeout(() => {
    this.map.getViewPort().resize();
}, 100);

What you decide to use is totally up to you. The use of the resize method more similarly matches what I used in the Leaflet example where I used invalidateSize instead.

Before we can start using the component in our pages, we need to add it to the module for the pages we wish to use it in. Open the project's src/app/home/home.module.ts file and make it look like the following:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { IonicModule } from '@ionic/angular';
import { FormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';

import { HereMapComponent } from '../here-map/here-map.component';

import { HomePage } from './home.page';

@NgModule({
    imports: [
        CommonModule,
        FormsModule,
        IonicModule,
        RouterModule.forChild([
            {
                path: '',
                component: HomePage
            }
        ])
    ],
    declarations: [HomePage, HereMapComponent],
    exports: [HereMapComponent]
})
export class HomePageModule {}

We've imported the HereMapComponent and added it to the @NgModule block. Finally we can use it in our page. Open the project's src/app/home/home.page.html file and include the following:

<ion-header>
    <ion-toolbar>
        <ion-title>
            Ionic HERE Map
        </ion-title>
    </ion-toolbar>
</ion-header>

<ion-content>
    <here-map appId="APP-ID-HERE" appCode="APP-CODE-HERE" lat="37.7397" lng="-121.4252"></here-map>
</ion-content>

You'll need to have registered for a free account with HERE in order to get your app id and app code values. But notice that these are the expected inputs that are defined in the previous TypeScript file. The lat and lng values will also represent our center point on the map as well as the center point to our isoline.

Just like I previously mentioned, the goal of this article was not to go in depth with showing HERE maps in an Ionic Framework application. This was already covered in my previous article titled, Interacting with a Leaflet Map in an Ionic Framework PWA. We just needed the foundation in place so we can work with isoline functionality.

Calculating an Isoline With a Center Point and Range Variable

With the application functional, we can worry about our isoline, which is actually just a few lines of code.

Open the project's src/app/here-map/here-map.component.ts file and include the following isoline method:

public isoline() {
    let params = {
        "mode": "fastest;car;traffic:enabled",
        "range": "300",
        "rangetype": "time",
        "departure": "now",
        "start": this.lat + "," + this.lng
    }
    this.map.removeObjects(this.map.getObjects());
    this.router.calculateIsoline(params, data => {
        if(data.response) {
            let center = new H.geo.Point(data.response.center.latitude, data.response.center.longitude),
                isolineCoords = data.response.isoline[0].component[0].shape,
                linestring = new H.geo.LineString(),
                isolinePolygon,
                isolineCenter;
            isolineCoords.forEach(coords => {
                linestring.pushLatLngAlt.apply(linestring, coords.split(','));
            });
            isolinePolygon = new H.map.Polygon(linestring);
            isolineCenter = new H.map.Marker(center);
            this.map.addObjects([isolineCenter, isolinePolygon]);
            this.map.setViewBounds(isolinePolygon.getBounds());
        }
    }, error => {
        console.error(error);
    });
}

So what is happening in the above code?

To calculate an isoline, a few parameters must be defined. We need to know how the isoline is being measured, which in our case is transport by car with traffic being monitored. We need to know the range that we're measuring, which in our case is 300 seconds. Because traffic is involved, we need to specify a time to track where now is the current traffic conditions rather than a date in the past. The start point is the center of our isoline which for this example is the center of the map.

Every time we run this method we are going to clear the map. When we calculate the isoline we are going to get the coordinate information necessary from the response in order to draw our polygons and lines. We're also placing a marker at the given center of the isoline.

The calculation through the API is quite simple in comparison to what it could be if you had to do all of this by hand.

Conclusion

You just saw how to work with isolines in an Ionic Framework application that works for both the web as well as mobile. This particular example used the default HERE map and Ionic 4.x. If you're still using Ionic 3.x and you need help configuring your application to use HERE, you might check out my previous tutorial titled, Display an Interactive HERE Map in an Ionic Framework Application.

This example should build for the web with no added dependencies. If you wish to build for Android or iOS, you'll need Apache Cordova available to you. However, no changes to the code are necessary to cross build.

mobile app Ionic (mobile app framework) Framework Web application

Published at DZone with permission of Nic Raboy, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Real-Time Analytics for IoT
  • 5 Software Developer Competencies: How To Recognize a Good Programmer
  • Front-End Troubleshooting Using OpenTelemetry
  • HTTP vs Messaging for Microservices Communications

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: