What I am trying to achieve is to load a map and display route between two markers retrieved from database. I want to be able to retrieve new coordinates every few seconds and draw and place markers on map without reloading map. I was able to do this using javascript and ajax but now i need same implementation using ionic typescript. But honestly dont know how
Current Project Setup
Ionic:
Ionic CLI : 7.1.1 (/Users/remmessesthegreat/.nvm/versions/node/v16.4.2/lib/node_modules/@ionic/cli)
Ionic Framework : @ionic/angular 5.8.5
@angular-devkit/build-angular : 12.1.4
@angular-devkit/schematics : 12.2.12
@angular/cli : 12.1.4
@ionic/angular-toolkit : 4.0.0
Capacitor:
Capacitor CLI : 3.4.1
@capacitor/android : 3.4.1
@capacitor/core : 3.4.1
@capacitor/ios : 3.4.1
Cordova:
Cordova CLI : 11.0.0
Cordova Platforms : none
Cordova Plugins : no whitelisted plugins (0 plugins total)
Utility:
cordova-res : 0.15.4
native-run (update available: 1.7.2) : 1.5.0
System:
NodeJS : v16.4.2 (/Users/remmessesthegreat/.nvm/versions/node/v16.4.2/bin/node)
npm : 8.18.0
OS : macOS Unknown
Xcode : Xcode 14.3 Build version 14E222b
Currently this is the code i have thats working on displaying routes and markers. I know its a bit messy and all over the place but should give an idea of what i want to create but honestly i’m not that good at this.
import { Component, ViewChild, ElementRef } from '@angular/core';
import { Geolocation } from '@ionic-native/geolocation/ngx';
import { NativeGeocoder, NativeGeocoderResult, NativeGeocoderOptions } from '@ionic-native/native-geocoder/ngx';
import { ModalController, AlertController, LoadingController } from '@ionic/angular';
import { HttpClient } from '@angular/common/http';
import { Storage } from '@capacitor/storage';
import { google } from "google-maps";
import * as GoogleMapsLoader from 'google-maps';
@Component({
selector: 'app-track',
templateUrl: './track.page.html',
styleUrls: ['./track.page.scss'],
})
export class TrackPage{
@ViewChild('hmap', { static: false }) mapElement: ElementRef;
map: any;
pois: any;
address: string;
email: string;
latitude: any;
longitude: any;
duration: any;
distance: any;
mlat: any;
mlng: any;
userid: string =""
deliverToLat: any =""
deliverToLng: any =""
currentaddress: string =""
deliverTo: string =""
contractor_name: string =""
driverdetails: any;
markerData: any;
private loader: HTMLIonLoadingElement;
private loaderLoading = false;
constructor(
public modalController: ModalController,
public alert: AlertController,
public loadingController: LoadingController,
private http: HttpClient,
private geolocation: Geolocation,
private nativeGeocoder: NativeGeocoder
) {
}
ngOnInit() {
}
ionViewWillEnter() {
var heighDevice = window.screen.height;
var FirstELement = document.getElementById('hmap');//MyAppModal id element
var heightElm = (heighDevice * 100) / 100; // 40 is height in vh
// add the height to the element
FirstELement.style["height"] = heightElm + "px";
// somecode
this.simpleLoader();
this.getDriverLocation();
this.dismissLoading();
}
loadMap() {
var directionDisplay;
this.map = new google.maps.Map(
document.getElementById("hmap") as HTMLElement,
{
zoom: 20,
disableDefaultUI: true,
mapTypeId: 'roadmap',
center: { lat: this.mlat, lng: this.mlng },
}
);
var rendererOptions = {
map: this.map,
suppressMarkers: true
};
const directionsRenderer = new google.maps.DirectionsRenderer();
const directionsService = new google.maps.DirectionsService();
directionDisplay = new google.maps.DirectionsRenderer(rendererOptions);
directionDisplay.setMap(this.map);
this.calculateAndDisplayRoute(directionsService, directionDisplay);
}
async calculateAndDisplayRoute(
directionsService: google.maps.DirectionsService,
directionsRenderer: google.maps.DirectionsRenderer
) {
directionsService
.route({
origin: { lat: this.mlat, lng: this.mlng }, // Haight.
destination: { lat: parseFloat(this.deliverToLat), lng: parseFloat(this.deliverToLng) }, // Ocean Beach.
// Note that Javascript allows us to access the constant
// using square brackets and a string value as its
// "property."
travelMode: google.maps.TravelMode.DRIVING,
})
.then((response) => {
directionsRenderer.setDirections(response);
this.addContractorMarker();
this.addUserMarker();
const directionData = response.routes[0].legs[0];
this.duration = directionData.duration.text;
this.distance = directionData.distance.text;
})
.catch((e) => window.alert("Directions request failed due to " + e));
}
async setSessionObject(latitude,longitude) {
await Storage.set({
key: 'userlocation',
value: JSON.stringify({
latitude: latitude,
longitude: longitude
})
});
}
async getSessionObject()
{
const ret = await Storage.get({ key: 'user'});
const user = JSON.parse(ret.value);
this.email = user.email;
return user;
}
dismiss() {
// using the injected ModalController this page
// can "dismiss" itself and optionally pass back data
this.modalController.dismiss({
'dismissed': true
});
}
async getDriverLocation()
{
const ret = await Storage.get({ key: 'driver'});
const profile = JSON.parse(ret.value);
this.deliverTo = profile.deliverTo;
this.contractor_name = profile.first_name
this.http.get('https://driversauth.example.co.za/Controller/getDriverLocation?driver_id='+ profile.driverid)
.subscribe(data => {
this.driverdetails = data['driverlocation'];
console.log(data);
this.mlng= parseFloat(this.driverdetails.longitude),
this.mlat = parseFloat(this.driverdetails.latitude)
this.getAddressDetails();
});
console.log('New location');
}
async getAddressDetails(){
const ret = await Storage.get({ key: 'user'});
const user = JSON.parse(ret.value);
this.http.get('https://usersauth.example.co.za/UserAddress/gethomeaddress?user_id='+ user.user_id)
.subscribe(data => {
this.currentaddress = data['user']['homeaddress'];
if(this.deliverTo == 'homeaddress')
{
this.deliverToLat = data['user']['homelat'];
this.deliverToLng = data['user']['homelng'];
}
if(this.deliverTo == 'workaddress')
{
this.deliverToLat = data['user']['worklat'];
this.deliverToLng = data['user']['worklng'];
}
this.loadMap();
}, error => {
console.log(error);
});
}
async addContractorMarker(){
let position = new google.maps.LatLng(this.mlat,this.mlng);
let mapMarker = new google.maps.Marker({
position: position,
icon: {
url:'../assets/icon/bluepulse.gif',
size: new google.maps.Size(36, 30),
scaledSize: new google.maps.Size(36, 30),
anchor: new google.maps.Point(20, 20)
}
});
mapMarker.setMap(this.map);
}
async addUserMarker(){
let position = new google.maps.LatLng(this.deliverToLat,this.deliverToLng);
let mapMarker = new google.maps.Marker({
position: position,
icon: {
url:'../assets/icon/location-marker.gif',
size: new google.maps.Size(36, 30),
scaledSize: new google.maps.Size(36, 30),
anchor: new google.maps.Point(20, 20)
}
});
mapMarker.setMap(this.map);
}
async removeMarkers(){
let mapMarker = new google.maps.Marker();
mapMarker.setMap(null);
}
public simpleLoader() {
this.loaderLoading = true;
this.loadingController.create({
message:'Loading...',
cssClass:'loader-css-class',
showBackdrop: true
}).then(load => {
this.loader = load;
load.present().then(() => { this.loaderLoading = false; });
});
}
public dismissLoading() {
const interval = setInterval(() => {
if (this.loader || !this.loaderLoading) {
this.loader.dismiss().then(() => { this.loader = null; clearInterval(interval)});
} else if (!this.loader && !this.loaderLoading) {
clearInterval(interval);
}
}, 1000);
}
}
The code above output the following. What i need help with is
- Page Lifecycle I want to load the data first before loading the map. Once data has loaded use data to draw route and add markers.
- I want to be able to get data from database at certain intervals and update map with new data without reloading the map or refreshing the page.
- if possible i would also like the duration and distance to also update as the driver moves towards destination.
Just to add a little bit of context. There is a driver who has an app that updates his/her location as they move. coordinates are saved on database as they move. User gets to see driver as they are coming to them and duration and distance.
I’m not the best of programmers and honestly need help with this specific functionality to get the app to be more interactive with user being able to see or track the driver as they are approaching. I apologise if my explanation is bad. Thank you in advance
1 post - 1 participant