ionic display multiple google maps in a page using ngFor - google-maps

I have a list of array that contains latitudes and longitudes
locations = [
{ id: 1, lat: 1.4046821, lng: 103.8403383, name: location 1 }
{ id: 2, lat: 1.4410763, lng: 103.8059827, name: location 2 }
{ id: 3, lat: 1.3261783, lng: 103.8203441, name: location 3 }
];
Now, I want to display google maps foreach location using ionic ngFor
<div *ngFor="let location of locations">
<ion-card>
<div style="height: 250px; width: 100%" #mapCanvas id="map{{location.id}}"></div>
<ion-item>
<h2>{{location.name}}</h2>
</ion-item>
</ion-card>
</div>
Only the location name will display, but the map doesn't display
here's my .ts file
import { Component, ViewChild, ElementRef } from '#angular/core';
import { NavController } from 'ionic-angular';
declare var google;
#Component({
selector: 'page-locations',
templateUrl: 'locations.html',
})
export class LocationsPage {
locations = [
{ id: 1, lat: 1.4046821, lng: 103.8403383, name: location 1 }
{ id: 2, lat: 1.4410763, lng: 103.8059827, name: location 2 }
{ id: 3, lat: 1.3261783, lng: 103.8203441, name: location 3 }
];
#ViewChild('map') mapElement: ElementRef;
map: any;
constructor(private navCtrl: NavController) {
}
loadMap(lat, lng) {
let latLng = new google.maps.LatLng(lat, lng);
let mapOptions = {
center: latLng,
zoom: 18,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
this.map = new google.maps.Map(this.mapElement.nativeElement, mapOptions);
new google.maps.Marker({
map: this.map,
animation: google.maps.Animation.DROP,
position: this.map.getCenter()
});
}
}
But, I don't know how to reference or load a map to its corresponding div in ngFor.
I hope somebody can help me to display maps in ngFor

First : Id is unique by definition, use class instead, ViewChild is not appropriate in this case unless you loop on your HTML elements. What you can do is iterate your map.
To not waste your time : I am on mobile so I have some trouble to write text, hope you'll succeed to fix your problem. You can both use an id but you'll have to change it for each map or my class method so that you use the same class name all the time, if so :
EDIT with the solution that works :
http://weetrax.com/img/2maps.png
(did it here) https://www.w3schools.com/graphics/tryit.asp?filename=trymap_intro
<div class="googleMap" style="width:100%;height:400px;"></div>
<div class="googleMap" style="width:100%;height:400px;"></div>
<script>
function myMap() {
var maps = document.getElementsByClassName("googleMap");
var options= {
center:new google.maps.LatLng(51.508742,-0.120850),
zoom:5,
};
for (var i=0; i<maps.length; i++) {
console.log(maps[i]);
var map=new google.maps.Map(maps[i],options);
};
}
</script>
Here all the maps are inited as you can see on the picture ;)

Related

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);

NavController's push doesn't show Google Maps

I am trying to draw a map when a button is clicked. However, it doesn't seem to work when I use NavController.push(), but only with NavController.setRoot(). I don't get any errors, so I can't figure out what causes this.
This is the class that draws the map:
declare var google: any;
#Component({
selector: 'page-Map',
templateUrl: 'Map.html'
})
export class MapPage {
public directionsService: any;
public directionsDisplay: any;
public directions: any;
map: any;
markers = [];
constructor(private _theme: ThemeService, private shareService: ShareService, public ajaxService: AjaxService) {
let rendererOptions = { draggable: true };
this.directionsService = new google.maps.DirectionsService;
let googleDiplay = new google.maps.DirectionsRenderer(rendererOptions);
this.directionsDisplay = new google.maps.DirectionsRenderer({ draggable: true });
this.initMap();
}
//initialises the map
initMap() {
var point = { lat: 12.65, lng: 12.5683 };
let divMap = (<HTMLInputElement>document.getElementById('map'));
this.map = new google.maps.Map(divMap, {
center: point,
zoom: 15,
disableDefaultUI: true,
draggable: true,
zoomControl: true,
});
let locationOptions = { timeout: 30000, enableHighAccuracy: true, maximumAge: 0 };
navigator.geolocation.getCurrentPosition((position) => {
this.map.setCenter(new google.maps.LatLng(position.coords.latitude, position.coords.longitude));
}, (error) => { }, locationOptions);
//create marker and set to initialised map
var myLatLng = this.map.getCenter();
this.directionsDisplay.setMap(this.map);
}
}
This is the HTML:
<ion-header>
<ion-navbar>
<ion-title>Location</ion-title>
</ion-navbar>
</div>
</ion-header>
<ion-content>
<div id="map"></div>
</ion-content>
Try initializing the map after a platform.ready()
import { Platform } from 'ionic-angular';
constructor(public platform: Platform){
// ...ALL YOUR CODE...
platform.ready().then(() => {
this.initMap();
});
}
And be sure your map has the size it needs via css
#map {
width: 100%;
height: 100%; // 'auto' might work too
}
I have fixed the problem. The reason why it didn't work was that the id='map' was already in use, so I changed the id to id=map3 in the Map.html. So now my HTML file looks like this:
enter code here
I also changed
let divMap = (<HTMLInputElement>document.getElementById('map'));
to
let divMap = (<HTMLInputElement>document.getElementById('map3'));
and the CSS:
#map3 {
height: 100%;
}
and the HTML:
<ion-header>
<ion-navbar>
<ion-title>Location</ion-title>
</ion-navbar>
</div>
</ion-header>
<ion-content>
<div id="map3"></div>
</ion-content>

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.

Add Marker to google Map when click Angular 2

I'm trying to build an angular 2 application which add a marker when i click on my map.
this is my code:
<sebm-google-map (mapClick)="getPosition($event)" [latitude]="lat" [longitude]="lng" [zoom]="zoom" [backgroundColor]="backgroundColor" style="margin-bottom:900px">
<sebm-google-map-marker *ngFor=" let post of posts" [latitude]="post.lapti" [longitude]="post.longi" ></sebm-google-map-marker>
</sebm-google-map>
Any solution?
Fortunately, the plunker example that angular-maps provide has that exact functionality implemented already:
plunker: http://plnkr.co/edit/YX7W20?p=preview
here is a static copy just in case that plunker no longer exists:
#Component({
selector: 'my-app',
styles: [`
.sebm-google-map-container {
height: 300px;
}
`],
template: `
<sebm-google-map
[latitude]="lat"
[longitude]="lng"
[zoom]="zoom"
[disableDefaultUI]="false"
[zoomControl]="false"
(mapClick)="mapClicked($event)">
<sebm-google-map-marker
*ngFor="let m of markers; let i = index"
(markerClick)="clickedMarker(m.label, i)"
[latitude]="m.lat"
[longitude]="m.lng"
[label]="m.label"
[markerDraggable]="m.draggable"
(dragEnd)="markerDragEnd(m, $event)">
<sebm-google-map-info-window>
<strong>InfoWindow content</strong>
</sebm-google-map-info-window>
</sebm-google-map-marker>
<sebm-google-map-circle [latitude]="lat + 0.3" [longitude]="lng"
[radius]="5000"
[fillColor]="'red'"
[circleDraggable]="true"
[editable]="true">
</sebm-google-map-circle>
</sebm-google-map>
`})
export class App {
// google maps zoom level
zoom: number = 8;
// initial center position for the map
lat: number = 51.673858;
lng: number = 7.815982;
clickedMarker(label: string, index: number) {
console.log(`clicked the marker: ${label || index}`)
}
mapClicked($event: MouseEvent) {
this.markers.push({
lat: $event.coords.lat,
lng: $event.coords.lng
});
}
markerDragEnd(m: marker, $event: MouseEvent) {
console.log('dragEnd', m, $event);
}
markers: marker[] = [
{
lat: 51.673858,
lng: 7.815982,
label: 'A',
draggable: true
},
{
lat: 51.373858,
lng: 7.215982,
label: 'B',
draggable: false
},
{
lat: 51.723858,
lng: 7.895982,
label: 'C',
draggable: true
}
]
}
// just an interface for type safety.
interface marker {
lat: number;
lng: number;
label?: string;
draggable: boolean;
}

InvalidValueError: setCenter: not a LatLng or LatLngLiteral: in property lng: not a number

I am working on angular2-google-maps, but while implementing I am consistently getting this error
InvalidValueError: setCenter: not a LatLng or LatLngLiteral: in
property lng: not a number
please see my code
import { AgmCoreModule, MapsAPILoader, GoogleMapsAPIWrapper } from 'angular2-google-maps/core';
import { MapDirective } from './map.directive';
declare var google: any;
#Component({
selector: 'map-component',
templateUrl: './map.component.html',
styleUrls: ['./map.component.css',],
providers: [GoogleMapsAPIWrapper]
})
export class MapComponent implements OnInit {
geoloc: marker;
ngOnInit(): void {
navigator.geolocation.getCurrentPosition((position) => {
this.lat = <number>position.coords.latitude;
this.lng = <number>position.coords.longitude;
});
}
// google maps zoom level
zoom: number = 18;
// initial center position for the map
lat: number;
lng: number;
clickedMarker(label: string, index: number) {
console.log(`clicked the marker: ${label || index}`)
}
mapClicked($event: any) {
this.markers.push({
lat: $event.coords.lat,
lng: $event.coords.lng,
draggable: true
});
}
markerDragEnd(m: marker, $event: MouseEvent) {
console.log('dragEnd', m, $event);
}
markers: marker[] = [
{
lat: 51.673858,
lng: 7.815982,
label: 'A',
draggable: true
},
{
lat: 51.373858,
lng: 7.215982,
label: 'B',
draggable: false
},
{
lat: 51.723858,
lng: 7.895982,
label: 'C',
draggable: true
}
]
}
// just an interface for type safety.
interface marker {
lat: number;
lng: number;
label?: string;
draggable: boolean;
}
.sebm-google-map-container {
height: 100%;
}
<sebm-google-map
[latitude]="lat"
[longitude]="lng"
[zoom]="zoom"
[disableDefaultUI]="false"
[zoomControl]="true"
[mapTypeControl]="true"
(mapClick)="mapClicked($event)">
<!--<sebm-google-map-marker
(markerClick)="clickedMarker(geoloc.label, i)"
[latitude]="geoloc.lat"
[longitude]="geoloc.lng"
[label]="geoloc.label"
[markerDraggable]="geoloc.draggable"
(dragEnd)="markerDragEnd(geoloc, $event)">-->
<sebm-google-map-marker
*ngFor="let m of markers; let i = index"
(markerClick)="clickedMarker(m.label, i)"
[latitude]="m.lat"
[longitude]="m.lng"
[label]="m.label"
[markerDraggable]="m.draggable"
(dragEnd)="markerDragEnd(m, $event)">
<sebm-google-map-info-window>
<strong>InfoWindow content</strong>
</sebm-google-map-info-window>
</sebm-google-map-marker>
<sebm-google-map-circle [latitude]="lat + 0.3" [longitude]="lng"
[radius]="5000"
[fillColor]="'red'"
[circleDraggable]="true"
[editable]="true">
</sebm-google-map-circle>
</sebm-google-map>
its giving me my location on map but while using same coordinates its giving error.. please help