message error implementing google maps in ionic (touchstart,touchmove) - google-maps

I use cordova geolocation and the google maps javascript api, and a simple implementation and still keep the error, when trying to zoom in or out.
the problem appears when I move and zoomed the map.
**
It is good to mention that this message appears when I connect the mobile for real time debugging with
ionic cordova run android -L
and exploring console messages with remote devices using chrome
chrome://inspect/#devices
<pre>
import { Component, OnInit, ElementRef, ViewChild } from '#angular/core';
import { Geolocation, Geoposition } from '#ionic-native/geolocation/ngx';
import { LoadingController, IonSlides } from '#ionic/angular';
declare var google: any;
#Component({
selector: 'app-mapa',
templateUrl: './mapa.page.html',
styleUrls:['./mapa.page.scss'],
})
export class MapaPage implements OnInit {
map: any;
marker: any;
#ViewChild(IonSlides, { static: true }) slide: IonSlides;
#ViewChild('map', { read: ElementRef, static: false }) mapRef: ElementRef;
constructor(
private geolocation: Geolocation,
private loadingCtrl: LoadingController
) { }
ngOnInit() { }
ionViewDidEnter() {
this.showMap();
}
async showMap() {
const loading = await this.loadingCtrl.create();
loading.present();
const myLatLng = await this.getLocation();
const options = {
center: myLatLng,
zoom: 16,
mapTypeId: google.maps.MapTypeId.ROADMAP,
disableDefaultUI: true
};
this.map = new google.maps.Map(this.mapRef.nativeElement, options);
loading.dismiss();
}
</pre>

Related

Trying to Add Markers to Leaflet Map with button click (Using Angular)

I have the following code where I am creating a leaflet map on initial load of the page. I have about four jsons with lat/lon data that I would like to populate the map. What I'm looking for is four buttons that when clicked will add the json data as markers to the map.
What I'm getting is an error indicating the following:
Cannot read properties of undefined (reading 'addLayer').
Map Component:
import { Component, AfterViewInit, OnInit } from '#angular/core';
import { MapPointsService } from './map-points.service';
import * as L from 'leaflet';
#Component({
selector: 'app-map',
templateUrl: './map.component.html',
styleUrls: ['./map.component.css'],
})
export class MapComponent implements AfterViewInit {
private map: L.Map | L.LayerGroup<any> | undefined;
area: any;
markersLayer = new L.LayerGroup();
private initMap(): void {
this.map = L.map('map', {
center: [4.5709, -74.2973],
zoom: 3,
});
this.area = this.map;
const tiles = L.tileLayer(
'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
{
maxZoom: 18,
minZoom: 3,
attribution:
'© OpenStreetMap',
}
);
tiles.addTo(this.map);
}
constructor(private mapService: MapPointsService) {}
ngAfterViewInit(): void {
this.initMap();
// this.mapService.jsonMarkers(this.area);
}
addMarkers(): void {
this.mapService.jsonMarkers(this.area);
}
}
MapService
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
// import { MapComponent } from './map.component';
import * as L from 'leaflet';
#Injectable({
providedIn: 'root',
})
export class MapPointsService {
constructor(private http: HttpClient) {}
jsonMarkers(map: L.Map): void {
this.http
.get('/assets/data/<my_json>.json')
.subscribe((res: any) => {
for (const area of res.<json_item>) {
const lon = are.Longitude;
const lat = are.Latitude;
const marker = L.marker([lat, lon]);
/*if (map.hasLayer(marker)) {
map.removeLayer(marker);
}*/
marker.addTo(map);
// console.log(markers);
}
});
}
}
Info Component that calls function
import { Component, OnInit } from '#angular/core';
import { MapPointsService } from '../map/map-points.service';
import { MapComponent } from '../map/map.component';
import { MatSnackBar } from '#angular/material/snack-bar';
#Component({
selector: 'app-information',
templateUrl: './information.component.html',
styleUrls: ['./information.component.css'],
})
export class InformationComponent implements OnInit {
/**
* showSpinner boolean
*/
showSpinner = false;
constructor(
private _snackBar: MatSnackBar,
private mapService: MapPointsService
) {}
ngOnInit(): void {}
run(msg: string): void {
const snackBarRef = this._snackBar.open('Running ' + msg, 'Close', {
duration: 3000,
});
snackBarRef.afterDismissed().subscribe(() => {
this.showSpinner = false;
});
this.showSpinner = true;
}
mapData() {
let data = new MapComponent(this.mapService);
data.addMarkers();
}
}
Info Html
<button type="button" (click)='mapData()'></button>
If you manually instantiate an Angular component with just the new keyword (let data = new MapComponent(this.mapService)), it will not be mounted anywhere, and in particular its lifecycle methods, like ngAfterViewInit, will not be called.
Then in your case, this.map and this.area remain undefined, leading to your error message.
Since you do not show your templates, it is hard to tell how your components are supposed to be related.
In case your <app-information> (InformationComponent) contains the <app-map> (MapComponent), you can use #ViewChild in InformationComponent to get a reference to the child MapComponent, and from there you can call its addMarkers method.
In case they are in the opposite situation, IIRC you can just request a MapComponent type in InformationComponent constructor, and Angular will inject it from its ancestors tree.
And if they are somehow siblings, then you could manage from a common ancestor:
get a ref to the MapComponent as described first
add an #Output event emitter on InformationComponent that fires when your button is clicked, and in the ancestor you listen to that event, and call the MapComponent.addMarkers method.

Google API to detect location closest to the user from a list of locations

I have a phone app developed in Ionic which supposedly only supports a few stores. What I want to do is to use Cordova Geolocation to fetch the user's current location, and use it to find a store in our support list closest to their location. What would be the best Google API to use for this, Google Maps or Google Places? Also what would be the easiest way for me to achieve this?
Other than finding the store I don't need to use any other map functionality.
Place Search Requests (https://developers.google.com/places/web-service/search#PlaceSearchRequests)
A Nearby Search query
https://maps.googleapis.com/maps/api/place/nearbysearch/json?parameters
Required parameters in above query
key : Your applications API key.
location : The latitude/longitude around which to retrieve place information.
radius : Defines the distance (in meters) within which to return place results
rankby : distance
type : Restricts the results to places matching the specified type. list of supported types (https://developers.google.com/places/web-service/supported_types)
Example
https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=-33.8670522,151.1957362&radius=1500&type=store&key=YOUR_API_KEY
IONIC IMPLIMENTATION
Install the Cordova and Ionic Native plugins
`$ ionic cordova plugin add cordova-plugin-geolocation --variable GEOLOCATION_USAGE_DESCRIPTION="To locate you"`
`$ npm install --save #ionic-native/geolocation`
HTML
<ion-header>
<ion-navbar>
<ion-title>
Google Maps NearBy Search
</ion-title>
</ion-navbar>
</ion-header>
<ion-content>
<div #map id="map"></div>
</ion-content>
js
import { Component, ElementRef, ViewChild } from '#angular/core';
import { NavController, Platform } from 'ionic-angular';
import { Geolocation } from '#ionic-native/geolocation';
import { googlemaps } from 'googlemaps';
declare var google;
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
#ViewChild('map') mapElement: ElementRef;
map: any;
latLng: any;
options: any;
infowindow: any;
constructor(private ngZone: NgZone, private geolocation: Geolocation) {}
constructor(
public navCtrl: NavController,
public navParams: NavParams,
public geolocation: Geolocation) {}
ionViewDidLoad() {
this.initMap();
}
initMap() {
this.geolocation.getCurrentPosition().then((resp) => {
this.latLng = new google.maps.LatLng(resp.coords.latitude, resp.coords.longitude);
this.options = {
center: this.latLng,
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
this.map = new google.maps.Map(this.mapElement.nativeElement, this.options);
let service = new google.maps.places.PlacesService(this.map);
service.nearbySearch({
location: this.latLng,
radius: 1000,
type: ['store']
}, (results, status) => {
if (status === google.maps.places.PlacesServiceStatus.OK) {
for (var i = 0; i < results.length; i++) {
this.createMarker(results[i]);
}
}
});
}).catch((error) => {
console.log('Error getting location', error);
});
}
createMarker(place) {
var placeLoc = place.geometry.location;
var marker = new google.maps.Marker({
map: map,
position: placeLoc
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(place.name);
infowindow.open(map, this);
});
}
}

Ionic 2 Google Maps:: Uncaught (in promise): TypeError: Cannot read property 'firstChild' of null

I'm using ionic 2 and trying to load google map using its JS API.
Here is my code:
import { Component, ViewChild, ElementRef } from '#angular/core';
import { NavController, Platform, NavParams } from 'ionic-angular';
declare var google;
#Component({
selector: 'page-map',
templateUrl: 'map.html',
})
export class MapPage {
#ViewChild('map') mapElement: ElementRef;
map: any;
latitude : any;
longitude : any;
constructor(public platform: Platform, public navCtrl: NavController,public navParams: NavParams) {
this.platform = platform;
this.initializeMap();
}
ionViewDidLoad(){
this.initializeMap();
}
initializeMap() {
this.platform.ready().then(() => {
var minZoomLevel = 12;
this.map = new google.maps.Map(document.getElementById('map'), {
zoom: minZoomLevel,
center: new google.maps.LatLng(38.50, -90.50),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var position = new google.maps.LatLng("23.032612699999998", "72.56187790000001");
var dogwalkMarker = new google.maps.Marker({position: position, title: "Testing"});
dogwalkMarker.setMap(this.map);
});
}
}
I have also added reference of the JS in my index.html file before cordova.js:
<script src="http://maps.google.com/maps/api/js"></script>
Here is my html:
<ion-header>
<ion-navbar hideBackButton side="left">
<ion-title style="margin-left: 0px;"><span class="menuTitle">Map</span></ion-title>
</ion-navbar>
</ion-header>
<ion-content>
<div #map id="map"></div>
</ion-content>
The code does not display any error but when I try to load this page it displays error like:
Uncaught (in promise): TypeError: Cannot read property 'firstChild' of null
Use mapElement
Typescript file
let minZoomLevel = 12;
let mapOptions = {
zoom: minZoomLevel,
center: new google.maps.LatLng(38.50, -90.50),
mapTypeId: google.maps.MapTypeId.ROADMAP
}
this.map = new google.maps.Map(this.mapElement.nativeElement, mapOptions);

Ionic 2 Native Google Maps Error

Kindly check the image below:
I just followed the instructions from the docs: https://ionicframework.com/docs/native/google-maps/
The error happens on creating the map. It seems that GoogleMaps object doesn't have getPlugin method which results to property BaseArrayClass cannot be read.
Actual Codes
home.ts
import {
GoogleMaps,
GoogleMap,
GoogleMapsEvent,
GoogleMapOptions,
CameraPosition,
MarkerOptions,
Marker
} from '#ionic-native/google-maps';
import { Component, ViewChild } from '#angular/core';
import { IonicPage, NavController, NavParams, Nav } from 'ionic-angular';
#IonicPage()
#Component({
selector: 'page-home',
templateUrl: 'home.html',
})
export class HomePage {
map: GoogleMap;
mapElement: HTMLElement;
constructor(
private googleMaps: GoogleMaps,
public navCtrl: NavController,
public navParams: NavParams
) {
}
ionViewDidLoad() {
console.log('ionViewDidLoad HomePage');
console.log(this.googleMaps);
this.loadMap();
}
loadMap() {
this.mapElement = document.getElementById('map');
let mapOptions: GoogleMapOptions = {
camera: {
target: {
lat: 43.0741904,
lng: -89.3809802
},
zoom: 18,
tilt: 30
}
};
this.map = this.googleMaps.create(this.mapElement, mapOptions);
}
}

Ionic2 google maps image layer

I am building an Ionic2 app where I am using google maps as an orientation map and I need to put an image layer on top of the map. I am trying to put building layout image over the building complex in Google maps.
I found this solution for javascript here, which is exactly what I need: Google maps js API
I am quite new to Ionic2 and Anglular2 and having no luck figuring it out so far.
Any advice appreciated
My code :
import { Component, ViewChild, ElementRef } from '#angular/core';
import { NavController } from 'ionic-angular';
import { Geolocation } from '#ionic-native/geolocation';
declare var google;
#Component({
selector: 'map',
templateUrl: 'map.html'
})
export class MapPage {
#ViewChild('map') mapElement: ElementRef;
map: any;
lat : any ;
lng : any ;
constructor(public navCtrl: NavController, public geolocation: Geolocation) {
this.getGeoLocation();
}
initializeMap() {
var minZoomLevel = 17;
let mapOptions =
{
zoom: minZoomLevel,
center: new google.maps.LatLng(lat, lng),
mapTypeId: google.maps.MapTypeId.ROADMAP,
}
this.map = new google.maps.Map(this.mapElement.nativeElement, mapOptions);
}
getGeoLocation(){
this.geolocation.getCurrentPosition().then((position) => {
this.lat = position.coords.latitude;
this.lng = position.coords.longitude;
this.initializeMap();
}, (err) => {
console.log(err);
});
}
Well, apparently it was easier than I thought. You just define image boundaries and create an instance of an overlay and then add it to the map like this...
var oldBuilding = {
north: 53.27959,
west: -9.01287,
south: 53.278038,
east: -9.00876
};
this.oldBuildingOverLay = new google.maps.GroundOverlay('../assets/Map.png', oldBuilding);
this.oldBuildingOverLay.setMap(this.map);
Declare oldBuildingOverlay: any; and you're up and running.