Add Marker to google Map when click Angular 2 - google-maps

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

Related

How to display route with native google maps on Ionic 3

I'm building a project in Ionic 3, I'm using the native maps plugin for Ionic, I can show the map and I can add a marker in a selected address, but I have not managed to show the recommended route on the map.
HTML:
<div id="map"></div>
TS:
loadMap(){
var lat = this.placeInfo.latitudeFrom;
var lng = this.placeInfo.longitudeFrom;
let mapOptions: GoogleMapOptions = {
camera: {
target: {
lat: lat,
lng: lng,
gestureHandling: 'none',
zoomControl: true
},
zoom: 18,
tilt: 30,
}
};
this.map = GoogleMaps.create('map', mapOptions);
this.map.one(GoogleMapsEvent.MAP_READY)
.then(() => {
let marker: Marker = this.map.addMarkerSync({
title: 'Ionic',
icon: 'blue',
animation: 'DROP',
position: {
lat: lat,
lng:lng
}
});
})
.catch(error =>{
console.log('error: ', error);
});
}
I'm trying this, but does not work
displayRoutev2() {
this.directionsService.route({
origin: this.placeInfo.startPoint,
destination: this.placeInfo.endPoint,
travelMode: 'DRIVING'
}, (response, status) => {
if (status === 'OK') {
this.directionsDisplay.setDirections(response);
this.directionsDisplay.setMap(this.map);
} else {
window.alert('No se encontraron rutas disponibles.' + status);
}
});
var service = new google.maps.DistanceMatrixService();
}
Can I use the var "service" to call any function? Or I need to try another way?
I can show route with another way that is not the better way, I need to use this native way, someone knows whats I can do?
import {AfterViewInit, Component, ElementRef, OnInit, ViewChild} from '#angular/core';
import {FormBuilder, FormGroup, Validators} from '#angular/forms';
declare var google;
#Component({
selector: 'app-direction',
templateUrl: './direction.page.html',
styleUrls: ['./direction.page.scss'],
})
export class DirectionPage implements OnInit, AfterViewInit {
#ViewChild('mapElement') mapNativeElement: ElementRef;
#ViewChild('directionsPanel') directionsPanel: ElementRef;
directionsService = new google.maps.DirectionsService;
directionsDisplay = new google.maps.DirectionsRenderer;
directionForm: FormGroup;
constructor(private fb: FormBuilder) {
this.createDirectionForm();
}
ngOnInit() {
}
createDirectionForm() {
this.directionForm = this.fb.group({
source: ['', Validators.required],
destination: ['', Validators.required]
});
}
ngAfterViewInit(): void {
const map = new google.maps.Map(this.mapNativeElement.nativeElement, {
zoom: 7,
center: {lat: 41.85, lng: -87.65}
});
this.directionsDisplay.setMap(map);
directionsDisplay.setPanel(this.directionsPanel.nativeElement);
}
DisplayRoute(formValues) {
const that = this;
this.directionsService.route({
origin: formValues.source,
destination: formValues.destination,
travelMode: 'DRIVING'
}, (response, status) => {
if (status === 'OK') {
that.directionsDisplay.setDirections(response);
} else {
window.alert('Directions request failed due to ' + status);
}
});
}
}
==In home.page.ts==
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-menu-button></ion-menu-button>
</ion-buttons>
<ion-title>Direction</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<form [formGroup]="directionForm" (ngSubmit)="DisplayRoute(directionForm.value)">
<ion-item>
<ion-label position="floating">Source</ion-label>
<ion-input formControlName="source"></ion-input>
</ion-item>
<ion-item>
<ion-label position="floating">Destination</ion-label>
<ion-input formControlName="destination"></ion-input>
</ion-item>
<ion-button expand="full" type="submit" [disabled]="directionForm.invalid">Get Direction</ion-button>
</form>
<ion-card>
<ion-card-content>
<div #directionsPanel></div>
</ion-card-content>
</ion-card>
<div #mapElement class="map"></div>
</ion-content>

ionic display multiple google maps in a page using ngFor

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

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>

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

Angular 2 HTTP GET with TypeScript google geocode service

I am new to angular2 and trying to find the coordinates(latitude,longitude) using the location.
here is my code,
GeoService.ts
import { Injectable } from '#angular/core';
import { Http } from '#angular/http';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/toPromise';
#Injectable()
export class GeoService {
constructor(private http: Http) { }
getLocation(term: string) {
return this.http.get('http://maps.google.com/maps/api/geocode/json?address=' + term + 'CA&sensor=false').map
((response) => response.json());
}
// tslint:disable-next-line:eofline
}
app.component.html
<!DOCTYPE HTML>
<h1> {{title}} </h1>
<input type="text" [(ngModel)]="location" />
<button (click)="findLocation($event)">Find location</button>
<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>
app.component.ts
import { Component } from '#angular/core';
import { GeoService } from './GeoService';
#Component({
selector: 'my-app',
moduleId: module.id,
templateUrl: `./app.component.html`,
styleUrls: ['/app.componenet.css'],
providers :[GeoService]
})
export class AppComponent {
title = 'Angular2 google map test';
lat: number = 51.673858;
lng: number = 7.815982;
zoom: number = 8;
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
}
];
location: string;
findLocation(): void {
this.result= this.geoService.getLocation(this.location);
}
constructor(private geoService: GeoService) {
}
clickedMarker(label: string, index: number) {
}
mapClicked($event: MouseEvent) {
}
markerDragEnd(m: marker, $event: MouseEvent) {
console.log('dragEnd', m, $event);
}
}
// tslint:disable-next-line:class-name
interface marker {
lat: number;
lng: number;
label?: string;
draggable: boolean;
}
how to get the result in app.component.ts?
findLocation(): void {
this.result= this.geoService.getLocation(this.location);
}
Hopefully you are not still stuck on this. While this might no longer help you, hopefully it will help someone else. Here is what I did just now. First change the getLocation function to this. This is for the current Angular2 release.
getLocation(term: string):Promise<any> {
return this.http.get('http://maps.google.com/maps/api/geocode/json?address=' + term + 'CA&sensor=false')
.toPromise()
.then((response) => Promise.resolve(response.json()));
.catch((error) => Promise.resolve(error.json()));
}
And then in app.component.ts, change it to this.
findLocation(): void {
this.geoService.getLocation(this.location)
.then((response) => this.result = response.results[0])
.catch((error) => console.error(error));
}
I added some error control because that is always good to have. And I had a results array return inside response so clarify with the user which address they want if there is more than one returned.
angular 7.1.4 httpclient is used. getLocation returns obserable
location.service.ts renamed GeoService.ts
import { Injectable } from "#angular/core";
import { HttpClient } from "#angular/common/http";
import { Observable } from "rxjs";
#Injectable({
providedIn: "root"
})
export class LocationService {
constructor(private http: HttpClient) {}
getLocation(term: string): Observable<any> {
return this.http.get(
"http://maps.google.com/maps/api/geocode/json?address=" +
term +
"CA&sensor=false&key=API_KEY"
);
}
}
location.component.ts
/// <reference types="#types/googlemaps" />
import { Component, OnInit, AfterContentInit, ViewChild } from "#angular/core";
import { LocationService } from "../location.service";
declare let google: any;
#Component({
selector: "app-location",
templateUrl: "./location.component.html",
styleUrls: ["./location.component.scss"],
providers: [LocationService]
})
export class LocationComponent implements OnInit {
#ViewChild("gmap") gmapElement: any;
map: google.maps.Map;
latitude: number;
longitude: number;
marker: google.maps.Marker;
locationStr: string;
public result: any;
countMarkers = 0;
constructor(public geoService: LocationService) {}
ngOnInit() {
this.setCurrentPosition();
// tslint:disable-next-line:prefer-const
let mapProp = {
center: new google.maps.LatLng(0, 0),
zoom: 18,
mapTypeId: google.maps.MapTypeId.ROADMAP,
disableDefaultUI: true
};
this.map = new google.maps.Map(this.gmapElement.nativeElement, mapProp);
}
setCenter(e: any) {
e.preventDefault();
this.map.setCenter(new google.maps.LatLng(this.latitude, this.longitude));
}
setCurrentPosition() {
navigator.geolocation.getCurrentPosition(position => {
console.log("Set position", position.coords);
this.latitude = position.coords.latitude;
this.longitude = position.coords.longitude;
this.map.setCenter(new google.maps.LatLng(this.latitude, this.longitude));
const location = new google.maps.LatLng(this.latitude, this.longitude);
this.map.panTo(location);
if (!this.marker) {
this.marker = new google.maps.Marker({
position: location,
map: this.map,
draggable: false,
title: "You Loation!"
});
this.marker.setLabel("You");
this.marker.setMap(this.map);
} else {
this.marker.setPosition(location);
}
});
}
setMarker(label = ".") {
const location = new google.maps.LatLng(this.latitude, this.longitude);
this.map.panTo(location);
if (!this.marker) {
this.marker = new google.maps.Marker({
position: location,
map: this.map,
draggable: false,
title: "You Loation!"
});
this.marker.setLabel(label);
this.marker.setMap(this.map);
} else {
this.marker.setLabel(label);
this.marker.setPosition(location);
}
}
addMarker(label = "") {
const location = new google.maps.LatLng(this.latitude, this.longitude);
// this.map.panTo(location);
const newMarker = new google.maps.Marker({
position: location,
map: this.map,
draggable: false,
title: "You Loation!"
});
this.countMarkers++;
label = this.countMarkers.toString();
newMarker.setLabel(label);
newMarker.setMap(this.map);
}
findLocation(): void {
this.geoService
.getLocation(this.locationStr)
.subscribe(
(data: any) => (
(this.result = data.results[0].geometry.location),
console.log(data.results[0].geometry.location),
(this.latitude = data.results[0].geometry.location.lat),
(this.longitude = data.results[0].geometry.location.lng),
this.map.setCenter(
new google.maps.LatLng(this.latitude, this.longitude)
),
this.addMarker()
),
(err: any) => console.log(err),
() => console.log("All done getting location.")
);
}
}