integrate inside angular2 app Google Maps - Place Autocomplete - javascript

I'm using angularJS 2 and I'm trying to add google maps autocomplete following this guide.
I've also installed angular-maps from https://angular-maps.com and been able to display a simple basic google map.
In my index.html file I've inserted:
<script src="https://maps.googleapis.com/maps/api/js?key=xxxxxxx&libraries=places&callback=initAutocomplete">
My app.ts looks like this:
import {Component, provide} from 'angular2/core';
import {bootstrap} from 'angular2/platform/browser';
import {
MapsAPILoader,
NoOpMapsAPILoader,
MouseEvent,
ANGULAR2_GOOGLE_MAPS_PROVIDERS,
} from 'angular2-google-maps/core';
#Component({
selector: 'my-app',
directives: [ANGULAR2_GOOGLE_MAPS_DIRECTIVES],
template: `
<input id="pac-input" class="controls" type="text" placeholder="Search Box">
<div id="map"></div>
`
})
export class AppComponent
{
var map = new google.maps.Map(document.getElementById('map'), {
center: { lat: -33.8688, lng: 151.2195 },
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
// Create the search box and link it to the UI element.
var input = document.getElementById('pac-input');
var searchBox = new google.maps.places.SearchBox(input);
map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
// Bias the SearchBox results towards current map's viewport.
map.addListener('bounds_changed', function() {
searchBox.setBounds(map.getBounds());
});
var markers = [];
// Listen for the event fired when the user selects a prediction and retrieve
// more details for that place.
searchBox.addListener('places_changed', function()
{
var places = searchBox.getPlaces();
if (places.length == 0) {
return;
}
// Clear out the old markers.
markers.forEach(function(marker) {
marker.setMap(null);
});
markers = [];
// For each place, get the icon, name and location.
var bounds = new google.maps.LatLngBounds();
places.forEach(function(place)
{
var icon = {
url: place.icon,
size: new google.maps.Size(71, 71),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(17, 34),
scaledSize: new google.maps.Size(25, 25)
};
// Create a marker for each place.
markers.push(new google.maps.Marker({
map: map,
icon: icon,
title: place.name,
position: place.geometry.location
}));
if (place.geometry.viewport) {
// Only geocodes have viewport.
bounds.union(place.geometry.viewport);
} else {
bounds.extend(place.geometry.location);
}
});
map.fitBounds(bounds);
});
}
But I get this error:
angular2-polyfills.js:332 Error: ReferenceError: google is not
defined(…)ZoneDelegate.invoke
#angular2-polyfills.js:332Zone.run
#angular2-polyfills.js:227(anonymous function)
#angular2-polyfills.js:576ZoneDelegate.invokeTask
#angular2-polyfills.js:365Zone.runTask
#angular2-polyfills.js:263drainMicroTaskQueue
#angular2-polyfills.js:482ZoneTask.invoke
#angular2-polyfills.js:434

You need to make sure that you have installed the TypeScript declaration files for Google maps. I found the "googlemaps" DefinitelyTyped library to work:
$ npm install #types/googlemaps --save-dev

Related

How to implement Google Map JavaScript in Angular2+?

I am trying to implement Google Map in my Angular6 component. However, I am unable to do so. I have embedded Google Map JavaScript from -
https://developers.google.com/maps/documentation/javascript/examples/rectangle-simple
My map doesn't load.
app.component.html
<div id="map"></div>
app.component.ts
import { Component, OnInit,AfterViewInit } from '#angular/core';
import { ViewChild, ElementRef, Renderer } from '#angular/core'
const url = '../../../assets/googlemap.js'
#Component({
selector: 'app-search-api',
templateUrl: './search-api.component.html',
styleUrls: ['./search-api.component.scss']
})
export class SearchApiComponent implements OnInit, AfterViewInit {
PhotoGoogleSDK: any;
constructor() { }
ngOnInit() {
this.loadScript();
}
// ------------------ Javascript code ----------------
public loadScript() {
console.log('preparing to load...')
let node = document.createElement('script');
node.src = url;
node.type = 'text/javascript';
node.async = true;
node.charset = 'utf-8';
document.getElementsByTagName('head')[0].appendChild(node);
}
}
googlemap.js
var citymap = {
chicago: {
center: {lat: 41.878, lng: -87.629},
population: 2714856
}
};
function initMap() {
// Create the map.
var map = new google.maps.Map(document.getElementById('map'),
{
zoom: 4,
center: {lat: 37.090, lng: -95.712},
mapTypeId: 'terrain'
});
// Construct the circle for each value in citymap.
// Note: We scale the area of the circle based on the population.
for (var city in citymap) {
// Add the circle for this city to the map.
var cityCircle = new google.maps.Circle({
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35,
map: map,
center: citymap[city].center,
radius: Math.sqrt(citymap[city].population) * 100
});
}
}
var tag = document.createElement('script');
tag.src = "https://maps.googleapis.com/maps/api/js?key=AIzaSyCXNFDDBMRr6YX8LJtltvEbQJsLA&callback=initMap";
tag.defer = true;
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
In order to implement google maps in angular2+ you have to do these things.
Insert the google map script in your index.html file. (You need to get a API key from Google.)
Now in your component.ts declare const google as any
declare const google: any;
Now in your html of your component, add new div with an id
<div id="google_map" class="map"></div>
Include this method and run it when initialize (add method to ngOnInit())
public initializeMap() {
let _map = document.getElementById('google_map');
let lat = YOUR_INITIAL_LATITUDE;
let lng = YOUR_INITIAL_LONGITUDE;
let pos = new google.maps.LatLng(lat, lng);
let map = new google.maps.Map(_map, {
center: pos,
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP,
});
}
Note that you may need to install google typing.
npm install --save #types/googlemaps

add marker to the google maps in angular component

I am trying to add marker to the google maps.
but I am facing below error.
InvalidValueError: setMap: not an instance of Map; and not an instance of StreetViewPanorama
can you tell me how to fix it.
providing code and stackblitz below.
https://stackblitz.com/edit/angular-gmaps-api-suvdaf?file=src/app/map-loader.ts
return MapLoader.load().then((gapi) => {
this.map = new google.maps.Map(gmapElement.nativeElement, {
center: new google.maps.LatLng(lat, lng),
zoom: zoom,
mapTypeId: type,
// label: "A"
});
this.map1 = new google.maps.Marker({
label: "A",
position: { lat: 59.33555, lng: 18.029851 },
map: map,
title: 'Hello World!'
});
// let markerSimple = new google.maps.Marker({
// label: "A",
// position: { lat: 59.33555, lng: 18.029851 },
// map: map,
// title: 'Hello World!'
// });
});
If i have understand your question this modified code will add markers
import { Injectable } from '#angular/core';
import { } from '#types/googlemaps';
declare var window: any;
// Credits to: Günter Zöchbauer
// StackOverflow Post: https://stackoverflow.com/a/39331160/9687729
#Injectable()
export class MapLoader {
private static promise;
map: google.maps.Map;
public static load() {
if (!MapLoader.promise) { // load once
MapLoader.promise = new Promise((resolve) => {
window['__onGapiLoaded'] = (ev) => {
console.log('gapi loaded')
resolve(window.gapi);
}
console.log('loading..')
const node = document.createElement('script');
node.src = 'https://maps.googleapis.com/maps/api/js?callback=__onGapiLoaded';
node.type = 'text/javascript';
document.getElementsByTagName('head')[0].appendChild(node);
});
}
return MapLoader.promise;
}
initMap(gmapElement, lat, lng, zoom, type) {
return MapLoader.load().then((gapi) => {
this.map = new google.maps.Map(gmapElement.nativeElement, {
center: new google.maps.LatLng(lat, lng),
zoom: zoom,
mapTypeId: type,
// label: "A"
});
//after map load add markers
this.createMarker();
});
}
createMarker() {
// list of hardcoded positions markers
var myLatLngList = {
myLatLng : [{ lat: 37.76487, lng: -122.41948 }, { lat: 59.33555, lng: 18.029851 }]
};
//iterate latLng and add markers
for(const data of myLatLngList.myLatLng){
var marker = new google.maps.Marker({
position: data,
map: this.map,
title: 'markers'
});
}
};
}

Google Maps Geometry Library: how do I create a marker that is in a state of being dragged

My intention is to split a polyline (with two coordinates) in two on dragstart event.
What is happening in code below:
Polyline is waiting for dragstart
When user starts dragging Polyline, two new Polylines and a Marker in between them replace the old Polyline
Dragging stops at current mouse location without releasing mouse
Actual intention:
In step 3, dragging continues, but dragged element is the new Marker and not the removed Polyline.
How do I transfer "dragging" from Polyline to a Marker?
const path = new google.maps.MVCArray([
new google.maps.LatLng(0, 0),
new google.maps.LatLng(10, 10),
])
const polyline = new google.maps.Polyline({
map,
path,
draggable: true
})
let marker, newPolylineA, newPolylineB
const dragstartListener = polyline.addListener('dragstart', ({ latLng }) => {
google.maps.event.removeListener(dragstartListener)
polyline.setMap(null)
marker = new google.maps.Marker({
map,
position: latLng,
draggable: true,
})
newPolylineA = new google.maps.Polyline({
map,
path: [ path.getAt(0), latLng ],
})
newPolylineB = new google.maps.Polyline({
map,
path: [ latLng, path.getAt(1) ],
})
})
I solved it by hiding original Polyline with strokeOpacity and using drag and dragend events.
It's not actual swap of drag targets, but it at least imitates the result.
const coordinateA = new google.maps.LatLng(0, 0)
const coordinateB = new google.maps.LatLng(10, 10)
const path = new google.maps.MVCArray([
coordinateA,
coordinateB,
])
const polyline = new google.maps.Polyline({
map,
path,
draggable: true
})
let marker, newPolylineA, newPolylineB
const dragstartListener = polyline.addListener('dragstart', ({ latLng }) => {
polyline.setOptions({
strokeOpacity: 0
})
marker = new google.maps.Marker({
map,
position: latLng,
draggable: true,
})
newPolylineA = new google.maps.Polyline({
map,
path: [ path.getAt(0), latLng ],
})
newPolylineB = new google.maps.Polyline({
map,
path: [ latLng, path.getAt(1) ],
})
google.maps.event.removeListener(dragstartListener)
})
const dragListener = polyline.addListener('drag', ({ latLng }) => {
marker.setPosition(latLng)
newPolylineA.setPath([ coordinateA, latLng ])
newPolylineB.setPath([ latLng, coordinateB ])
})
const dragendListener = polyline.addListener('dragend', ({ latLng }) => {
google.maps.event.removeListener(dragendListener)
google.maps.event.removeListener(dragListener)
marker.setPosition(latLng)
newPolylineA.setPath([ coordinateA, latLng ])
newPolylineB.setPath([ latLng, coordinateB ])
polyline.setMap(null)
})

Draw Polyline between markers Ionic Google Maps JavaScript

Hi guys this is my first post in this site, im working in a App in Ionic that shows your position with a marker when you push a button, you can push it again to update your position and add a Marker on that position, i want to draw a Polyline between this markers but i havent succeed yet. i know there are some ways to draw polylines my idea is to extract the lat, long coordinates of the marker, save them in a array and then set that as a "path" to draw the Polyline but im having problems with the creation of the array like in the comment below. here is 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: 'home-page',
templateUrl: 'home.html'
})
export class HomePage {
#ViewChild('map') mapElement: ElementRef;
map: any;
me: any;
markers=[];
lat=[];
long=[];
constructor(public navCtrl: NavController, public geolocation: Geolocation) {
}
ionViewDidLoad(){
this.loadMap();
}
loadMap() {
this.geolocation.getCurrentPosition().then((position) => {
let mylatLng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
let mapOptions = {
center: mylatLng,
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
this.map = new google.maps.Map(this.mapElement.nativeElement, mapOptions);
},
(err) => {
console.log(err);
});
}
addMarker(){
let marker = new google.maps.Marker({
map: this.map,
animation: google.maps.Animation.DROP,
});
let content = '<p>Posición: ' + marker.setPosition() + '</p>'
if (navigator.geolocation) navigator.geolocation.getCurrentPosition(function(pos) {
var me = new google.maps.LatLng(pos.coords.latitude, pos.coords.longitude);
marker.setPosition(me);
},
function(error) {
// ...
});
this.markers.push(marker);
this.addInfoWindow(marker, content);
}
addInfoWindow(marker, content){
let infoWindow = new google.maps.InfoWindow({
content: content
});
if (navigator.geolocation) navigator.geolocation.getCurrentPosition(function(pos) {
var me = new google.maps.LatLng(pos.coords.latitude, pos.coords.longitude);
infoWindow.setContent('<p>Posición: ' + me + '</p>')
},
function(error) {
// ...
});
google.maps.event.addListener(marker, 'click', () => {
infoWindow.open(this.map, marker);
});
}
setMapAll(map) {
for (var i = 0; i < this.markers.length; i++) {
this.markers[i].setMap(map);
}
}
clearMarkers() {
this.setMapAll(null);
}
deleteMarkers() {
this.clearMarkers();
this.markers = [];
}
// Im having problems here
addPolyLine() {
var poly = new Array();
for (var j=0; j<this.lat.length;j++){
var pos= new google.maps.LatLng(this.lat[j],this.long[j])
poly.push(pos);
}
var flightPath = new google.maps.Polyline({
path: poly,
geodesic: true,
strokeColor: '#FF0000',
strokeOpacity: 1.0,
strokeWeight: 2
});
flightPath.setMap(this.map);
}
}
And the HTML page:
<ion-header>
<ion-navbar>
<ion-title>
MapaPrueba
</ion-title>
<ion-buttons end>
<button ion-button (click)="addMarker()"><ion-icon name="add"></ion-icon>Agregar Pos</button>
</ion-buttons>
</ion-navbar>
</ion-header>
<ion-content>
<div #map id="map"></div>
<ion-fab left bottom>
<button ion-fab color="light" (click)="clearMarkers()">
<ion-icon name="eye-off"></ion-icon>
</button>
</ion-fab>
</ion-content>
There is a full example of that in the official documentation and here below as well.
In short you have to:
Create a Polyline and set it on the map (one time)
Get the Polyline path with the Polyline getPath() method
Push your new
coordinates to the path
var map;
var polyLine;
var polyOptions;
function initialize() {
var mapOptions = {
zoom: 5,
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: new google.maps.LatLng(0,0)
};
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
polyOptions = {
strokeColor: '#0026b3',
strokeOpacity: 1.0,
strokeWeight: 1,
geodesic: true,
}
polyLine = new google.maps.Polyline(polyOptions);
polyLine.setMap(map);
google.maps.event.addListener(map, 'click', function(event) {
addPoint(event);
});
}
function addPoint(event) {
var path = polyLine.getPath();
path.push(event.latLng);
var marker = new google.maps.Marker({
position: event.latLng,
map: map,
});
map.setCenter(event.latLng);
}
initialize();
#map-canvas {
height: 200px;
}
<div id="map-canvas"></div>
<script src="https://maps.googleapis.com/maps/api/js"></script>

Initializing Markers and Infowindow in Ionic Google Maps

once again I have met my nemesis, adding google markers and setting content within and info-window. In this code, I have already completed a geolocation, and from my current location I, would like to perform a search on nearby places. The places I search will be retrieved from an Ionic list page I have already implemented. From what ever I choose on the list ex. Fire Stations, I would want my code to perform a Places Search, and the results turn up on my map as markers, with infowindow content from google libraries. My problem is that the markers are not on my map, and you can probably guess, that means no info window. If you could provide me with some direction. I am preforming this in Ionic.
import { Component } from '#angular/core';
import { NavController, NavParams } from 'ionic-angular';
import { DirectionPage} from '../direction/direction';
/**
* Generated class for the PlacesPage page.
*
* See https://ionicframework.com/docs/components/#navigation for more info on
* Ionic pages and navigation.
*/
declare var google;
this.marker = [];
#Component({
selector: 'page-places',
templateUrl: 'places.html',
})
export class PlacesPage {
places: Array<any>;
map: any;
currentLocation: any;
latitude: Number;
longitude: Number;
keyword: String;
searchType: String;
distance: Number;
constructor(public navCtrl: NavController, public navParams: NavParams) {
this.latitude = navParams.get('latitude');
this.longitude = navParams.get('longitude');
this.keyword = navParams.get('keyword');
this.searchType = navParams.get('type');
this.distance = navParams.get('distance');
}
ionViewDidLoad() {
this.queryPlaces().then((results : Array<any>)=>{
for (let i=0; i < results.length; i++){
this.createMarker(results[i]);
}
this.places = results;
}, (status)=>console.log(status));
}
queryPlaces(){
this.currentLocation = new google.maps.LatLng(this.latitude,this.longitude);
let mapOptions = {
zoom: 10,
center: this.currentLocation,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
this.map = new google.maps.Map(document.getElementById("map"), mapOptions);
let service = new google.maps.places.PlacesService("service");
let request = {
location : this.currentLocation,
radius: this.distance,
types: [this.searchType],
rankBy: google.maps.places.DISTANCE
};
return new Promise((resolve,reject)=>{
service.nearbySearch(request, function(results,status){
if (status == google.maps.places.PlacesServiceStatus.OK){
resolve(results);
}else{
reject(results);
}
});
});
}
createMarker(place){
let marker = new google.maps.Marker({
map: this.map,
animation: google.maps.Animation.DROP,
position: place.geometry.location,
title: place.name,
});
google.maps.event.addListener(marker, 'click', function(){
let infowindow = new google.maps.infowindow({
content : this.place
});
infowindow.open(this.map,marker);
});
}
goToDirectionPage(index){
}
}
I realized the "I" in infowindow needed to be capitalized. Also, place.geometry.location gets the position for the marker object.
createMarker(place){
let marker = new google.maps.Marker({
map: this.map,
animation: google.maps.Animation.DROP,
position: place.geometry.location,
title: place.name,
});
google.maps.event.addListener(marker, 'click', function(){
let infowindow = new google.maps.InfoWindow({
content: place.name
});
infowindow.open(this.map,marker);
})

Categories

Resources