I have a Ionic App using google maps . I am trying to get latitude and longitude from data json api for flight route then inject that data arrays to Google Maps polyline . Fetch data json api working fine without problem , but when l put objects inside Google Maps l get error
ERROR Error: Uncaught (in promise): TypeError: Cannot use 'in' operator to search for 'getPosition' in 40.11882
TypeError: Cannot use 'in' operator to search for 'getPosition' in 40.11882
at getLatLng (Common.js:544)
at Array.map (<anonymous>)
at Object.convertToPositionArray (Common.js:575)
at Map.addPolyline (Map.js:1231)
at vendor.js:76340
my code
export class HomePage{
map: GoogleMap;
latitude: any;
longitude: any;
dates=[]
constructor(
public toastCtrl: ToastController,
private platform: Platform,
private http: HTTP
) { }
ngOnInit() {
// Since ngOnInit() is executed before `deviceready` event,
// you have to wait the event.
this.platform.ready();
this.getmarker();
this.loadMap();
}
async getmarker(){
this.http.get('/v1/flightjson?flightId=201',{},{})
.then( data=>{
// this.latitude = JSON.parse(data.data).result.response.data.flight.track.latitude
// this.longitude = JSON.parse(data.data).result.response.data.flight.track
for(let datas of JSON.parse(data.data).result.response.data.flight['track']) {
this.longitude = datas.longitude
this.latitude = datas.latitude
console.log(this.longitude, this.latitude)
}
})
}
loadMap() {
let AIR_PORTS = [
this.longitude = datas.longitude
this.latitude = datas.latitude
];
console.log(AIR_PORTS)
this.map = GoogleMaps.create('map_canvas');
let polyline: Polyline = this.map.addPolylineSync({
points: AIR_PORTS,
color: '#AA00FF',
width: 10,
geodesic: true,
clickable: true // clickable = false in default
});
polyline.on(GoogleMapsEvent.POLYLINE_CLICK).subscribe((params: any) => {
let position: LatLng = <LatLng>params[0];
let marker: Marker = this.map.addMarkerSync({
position: position,
title: position.toUrlValue(),
disableAutoPan: true
});
marker.showInfoWindow();
});
}
}
console log for AIR_PORTS
my data json url
original code
export class PolylinePage implements OnInit {
map: GoogleMap;
constructor(private platform: Platform) { }
async ngOnInit() {
// Since ngOnInit() is executed before `deviceready` event,
// you have to wait the event.
await this.platform.ready();
await this.loadMap();
}
loadMap() {
let HND_AIR_PORT = {lat: 35.548852, lng: 139.784086};
let SFO_AIR_PORT = {lat: 37.615223, lng: -122.389979};
let HNL_AIR_PORT = {lat: 21.324513, lng: -157.925074};
let AIR_PORTS = [
HND_AIR_PORT,
HNL_AIR_PORT,
SFO_AIR_PORT
];
this.map = GoogleMaps.create('map_canvas', {
camera: {
target: AIR_PORTS
}
});
let polyline: Polyline = this.map.addPolylineSync({
points: AIR_PORTS,
color: '#AA00FF',
width: 10,
geodesic: true,
clickable: true // clickable = false in default
});
polyline.on(GoogleMapsEvent.POLYLINE_CLICK).subscribe((params: any) => {
let position: LatLng = <LatLng>params[0];
let marker: Marker = this.map.addMarkerSync({
position: position,
title: position.toUrlValue(),
disableAutoPan: true
});
marker.showInfoWindow();
});
}
}
i think the way you are reading data and passing data to the GoogleMap is incorrect, Please try the following
export class HomePage{
map: GoogleMap;
points: {lng: number, lat: number}[] = [];
constructor(
public toastCtrl: ToastController,
private platform: Platform,
private http: HTTP
) { }
ngOnInit() {
this.platform.ready();
this.getmarker();
this.loadMap();
}
async getmarker(){
this.http.get('/v1/flightjson?flightId=201',{},{})
.then( data=>{
for(let datas of JSON.parse(data.data).result.response.data.flight['track']) {
this.points.push({lng: datas.longitude, lat: datas.latitude});
}
})
}
loadMap() {
let AIR_PORTS = this.points;
console.log(AIR_PORTS)
this.map = GoogleMaps.create('map_canvas');
let polyline: Polyline = this.map.addPolylineSync({
points: AIR_PORTS,
color: '#AA00FF',
width: 10,
geodesic: true,
clickable: true // clickable = false in default
});
polyline.on(GoogleMapsEvent.POLYLINE_CLICK).subscribe((params: any) => {
let position: LatLng = <LatLng>params[0];
let marker: Marker = this.map.addMarkerSync({
position: position,
title: position.toUrlValue(),
disableAutoPan: true
});
marker.showInfoWindow();
});
}
}
you can find a working example here which i tried with your data - Example Demo.
And code from here Example Code
Related
My map is not loading and no error is being displayed in the console.
please help.
this is the error screenshot as shown in the browser
there is no build error while compiling the code neither any error is thrown but the ma form mabox is not loading and is written as - Missing mapbox Gl JS CSS
the following is the code snippet for the same
// code for map.component.ts
import { Component, OnInit } from '#angular/core';
import * as mapboxgl from 'mapbox-gl';
import { MapService } from '../map.service';
import { GeoJson, FeatureCollection } from '../map';
#Component({
selector: 'app-map-box',
templateUrl: './map-box.component.html',
styleUrls: ['./map-box.component.css']
})
export class MapBoxComponent implements OnInit{
/// default settings
map: mapboxgl.Map;
style = 'mapbox://styles/kanavmalik10/cjfbjx6fp70fl2snuphc7zjw2';
lat = 37.75;
lng = -122.41;
message = 'Hello World!';
// data
source: any;
markers: any;
constructor(private mapService: MapService) {
}
ngOnInit() {
this.markers = this.mapService.getMarkers()
this.initializeMap()
}
private initializeMap() {
/// locate the user
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(position => {
this.lat = position.coords.latitude;
this.lng = position.coords.longitude;
this.map.flyTo({
center: [this.lng, this.lat]
})
});
}
this.buildMap()
}
buildMap() {
this.map = new mapboxgl.Map({
container: 'map',
style: this.style,
zoom: 13,
center: [this.lng, this.lat]
});
/// Add map controls
this.map.addControl(new mapboxgl.NavigationControl());
//// Add Marker on Click
this.map.on('click', (event) => {
const coordinates = [event.lngLat.lng, event.lngLat.lat]
const newMarker = new GeoJson(coordinates, { message: this.message })
this.mapService.createMarker(newMarker)
})
/// Add realtime firebase data on map load
this.map.on('load', (event) => {
/// register source
this.map.addSource('firebase', {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: []
}
});
/// get source
this.source = this.map.getSource('firebase')
/// subscribe to realtime database and set data source
this.markers.subscribe(markers => {
let data = new FeatureCollection(markers)
this.source.setData(data)
})
/// create map layers with realtime data
this.map.addLayer({
id: 'firebase',
source: 'firebase',
type: 'symbol',
layout: {
'text-field': '{message}',
'text-size': 24,
'text-transform': 'uppercase',
'icon-image': 'rocket-15',
'text-offset': [0, 1.5]
},
paint: {
'text-color': '#f16624',
'text-halo-color': '#fff',
'text-halo-width': 2
}
})
})
}
/// Helpers
removeMarker(marker) {
this.mapService.removeMarker(marker.$key)
}
flyTo(data: GeoJson) {
this.map.flyTo({
center: data.geometry.coordinates
})
}
}
<input type="text" [(ngModel)]="message" placeholder="your message...">
<h1>Markers</h1>
<div *ngFor="let marker of markers | async">
<button (click)="flyTo(marker)">{{ marker.properties.message }}</button>
<button (click)="removeMarker(marker)">Delete</button>
</div>
<div class="map" id="map"></div>
You seed to include the GL JS CSS stylesheet. See the quickstart at https://docs.mapbox.com/mapbox-gl-js/overview/#quickstart
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.45.0/mapbox-gl.css' rel='stylesheet' />
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>
I have implemented Google maps in Angular2 without using any of the npm libraries available and need to add a button to the infoWindow that fires an Angular function. Can this be done???.
My best effort so far does not work, the airport.name shows but the (click)="setAirport('departure', airport)" does not. I assume it's not connected to Angular in any way.
My component has the following function when the user clicks to activate the marker & infoWindow.
showAirport(idx, airport) {
const markerInfo =
<h4>${airport.name}</h4><div class='row' style='margin:0; margin-top:20px'>
<div class="col-xs-6">
<a class="btn btn-primary btn-block" (click)="setAirport('departure',airport)">Set as Departure</a>
</div>
<div class="col-xs-6">
<a class="btn btn-primary btn-block" (click)="setAirport('arrival',airport)">Set as Arrival</a>
</div>
</div>
;
this.setCurrentAirport(idx);
this.infoWindow.setContent(markerInfo);
this.infoWindow.open(this.map, this.markers[idx]);
}
Here is more of the component ts file.
import { Component, ViewChild, ElementRef, OnInit } from '#angular/core';
import { Response } from '#angular/http';
declare var google;
#Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
#ViewChild('map') mapElement: ElementRef;
map: any;
infoWindow = new google.maps.InfoWindow();
private allItems: any[];
lat = 51.5287718;
lng = -0.1;
airports = [];
markers = [];
flights = [];
polylines = [];
bounds = {
w: 0,
e: 0,
n: 0,
s: 0
};
loadAirports(apiBounds) {
this.airportsService.byBounds(apiBounds)
.subscribe(
(airportData: any[]) => {
for (let i = 0; i < airportData['data'].length; i++) {
const tmpAirport = {
id: i,
airportID: airportData['data'][i].id,
name: airportData['data'][i].airportName,
lat: airportData['data'][i].lat,
lng: airportData['data'][i].lng
};
this.airports.push(tmpAirport);
this.addMarker(tmpAirport, tmpAirport['name'], i);
}
},
(error: Response) => {
const errorData = error.json();
}
);
};
showAirport(idx, airport) {
console.log(airport);
// this is where I want to be able to include the buttons
const markerInfo = `<h4>${airport.name}</h4>`;
this.infoWindow.setContent(markerInfo);
this.infoWindow.open(this.map, this.markers[idx]);
}
loadMap() {
const latLng = new google.maps.LatLng(51, -0.5);
const mapOptions = {
center: latLng,
scrollwheel: false,
zoom: 9,
minZoom: 6,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
this.map = new google.maps.Map(this.mapElement.nativeElement, mapOptions);
new google.maps.event.addListenerOnce(this.map, 'bounds_changed', () => {
this.loadAirports(this.bounds);
});
}
addMarker(airport, info, markerIndex) {
const position = new google.maps.LatLng(airport['lat'], airport['lng']);
const marker = new google.maps.Marker({
map: this.map,
position: position,
markerIndex: markerIndex
});
const markerInfo = '<b>' + airport.name + '</b>';
this.addInfoWindow(marker, markerInfo, markerIndex);
this.markers.push(marker);
}
addInfoWindow(marker, content, markerIndex) {
google.maps.event.addListener(marker, 'click', () => {
this.infoWindow.setContent(content);
this.infoWindow.open(this.map, marker);
});
}
constructor() {}
ngOnInit() {
this.loadMap();
}
}
Not the prettiest solution, but you could always assign clases/ids to the buttons inside the InfoWindow, and then bind to them:
showAirport(idx, airport) {
console.log(airport);
// this is where I want to be able to include the buttons
const markerInfo = `
<h4>${airport.name}</h4>
<a class="btn btn-primary btn-block" id="departure-button">Set as Departure</a>
`;
this.infoWindow.setContent(markerInfo);
this.infoWindow.open(this.map, this.markers[idx]);
const departureButton = this.mapElement.nativeElement.getElementById('departure-button');
departureButton.onclick = this.setAirport('departure', airport);
google.maps.event.addListener(this.infoWindow, 'closeclick', () => {
departureButton.onclick = null;
});
});
Just assign this to that and use it,
addInfoWindow(marker, content, markerIndex) {
let that = this;
google.maps.event.addListener(marker, 'click', () => {
that.infoWindow.setContent(content);
that.infoWindow.open(this.map, marker);
});
}
Crazy right ;). variable scope for this is not the this that you need so this don't have infoWindow but by assigning this to that now we have infowWindow.
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.")
);
}
}
I've searched the web for hours now and can't seem to find the problem to my seemingly, pretty simple issue.
Simply put, the icon property of google.maps.Marker doesn't seem to do anything when I ionic serve the app, despite everything else working out fine.
In other words, what does Ionic 2 use with the Google Maps Javascript API that allows it to define the icon images for custom markers?
I'll provide all my relevant code here but I have a feeling that it might not be very helpful for a question like this.
With what I know about Ionic 2, I've been able to integrate Google Maps, it's online/offline states, and some default markers into a page on my app.
BTW, my test image files are located in the same folder as google-maps.ts (just doing this for now as I figure out what's happening).
All the code for initializing google maps and creating the addMarker functions are located in this one file (This huge piece of code is placed here just in case, skip the code below to the next snippet to see the most relevant section of it):
src/providers/google-maps.ts
import { Injectable } from '#angular/core';
import { Connectivity } from './connectivity';
import { Geolocation } from 'ionic-native';
/*
Generated class for the GoogleMaps provider.
See https://angular.io/docs/ts/latest/guide/dependency-injection.html
for more info on providers and Angular 2 DI.
*/
declare var google;
#Injectable()
export class GoogleMaps {
mapElement: any;
pleaseConnect: any;
map: any;
mapInitialised: boolean = false;
mapLoaded: any;
mapLoadedObserver: any;
markers: any = [];
apiKey: string;
styles: any;
constructor(public connectivityService: Connectivity) {
}
init(mapElement: any, pleaseConnect: any): Promise<any> {
this.mapElement = mapElement;
this.pleaseConnect = pleaseConnect;
return this.loadGoogleMaps();
}
loadGoogleMaps(): Promise<any> {
return new Promise((resolve) => {
if(typeof google == "undefined" || typeof google.maps == "undefined") {
console.log("Google maps Javascript needs to be loaded");
this.disableMap();
if(this.connectivityService.isOnline()) {
window['mapInit'] = () => {
this.initMap().then(() => {
resolve(true);
});
this.enableMap();
}
let script = document.createElement("script");
script.id = "googleMaps";
if(this.apiKey) {
script.src = 'http://maps.google.com/maps/api/js?key=' + this.apiKey
+ '&callback=mapInit';
} else {
script.src = 'http://maps.google.com/maps/api/js?callback=mapInit';
}
document.body.appendChild(script);
}
}
else {
if(this.connectivityService.isOnline()) {
this.initMap();
this.enableMap();
} else {
this.disableMap();
}
}
this.addConnectivityListeners();
})
}
initMap(): Promise<any> {
this.mapInitialised = true;
return new Promise((resolve) => {
Geolocation.getCurrentPosition().then((position) => {
let latLng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
let mapOptions = {
center: latLng,
zoom: 15,
//mapTypeId: google.maps.MapTypeId.ROADMAP, -Doesn't seem necessary anymore
styles: [
{
"featureType": "poi.business",
"stylers": [
{
"visibility": "off"
}
]
},
{
"featureType": "road",
"elementType": "labels.icon",
"stylers": [
{
"visibility": "off"
}
]
},
{
"featureType": "transit",
"stylers": [
{
"visibility": "off"
}
]
}
]
}
this.map = new google.maps.Map(this.mapElement, mapOptions);
resolve(true);
});
});
}
disableMap(): void {
if(this.pleaseConnect) {
this.pleaseConnect.style.display = "block";
}
}
enableMap(): void {
if(this.pleaseConnect) {
this.pleaseConnect.style.display = "none";
}
}
addConnectivityListeners(): void {
document.addEventListener('online', () => {
console.log("online");
setTimeout(() => {
if(typeof google == "undefined" || typeof google.maps == "undefined") {
this.loadGoogleMaps();
}
else {
if(!this.mapInitialised) {
this.initMap();
}
this.enableMap();
}
},2000);
}, false);
}
//Setting up custom Google Maps markers
//iconBase: any = 'https://maps.google.com/mapfiles/kml/shapes/'; -Probably not necessary
icons: any = {
partner: {
icon: 'partner.png'
},
boughtFrom: {
icon: 'boughtFrom.png'
}
}
addMarker(lat: number, lng: number, feature: any): void {
let latLng = new google.maps.LatLng(lat, lng);
let marker = new google.maps.Marker({
map: this.map,
animation: google.maps.Animation.DROP,
position: latLng,
icon: this.icons[feature].icon
});
this.markers.push(marker);
}
}
The part that isn't working for me is the "icon" assignment in that last "addMarker()" function:
addMarker(lat: number, lng: number, feature: any): void {
let latLng = new google.maps.LatLng(lat, lng);
let marker = new google.maps.Marker({
map: this.map,
animation: google.maps.Animation.DROP,
position: latLng,
icon: this.icons[feature].icon //Doesn't do anything
});
this.markers.push(marker);
}
Currently I'm attempting to also call different types of markers for different locations, but even if I simply replace it with partners.png or { url: 'partners.img' }, it still doesn't recognize anything.
In case this matters, these are also the two test markers I'm using that appear in default style on the map:
src/assets/data/locations.json
{
"locations": [
{
"latitude": 40.79567309999999,
"longitude": -73.97358559999998,
"type": "partner"
},
{
"latitude": 40.8107211,
"longitude": -73.95413259999998,
"type": "boughtFrom"
}
]
}
I'll also include the map page that integrates all this info:
src/pages/home.ts
import { Component, ElementRef, ViewChild } from '#angular/core';
import { Locations } from '../../providers/locations';
import { GoogleMaps } from '../../providers/google-maps';
import { NavController, Platform } from 'ionic-angular';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
#ViewChild('map') mapElement: ElementRef;
#ViewChild('pleaseConnect') pleaseConnect: ElementRef;
constructor(public navCtrl: NavController, public maps: GoogleMaps,
public Platform: Platform, public locations: Locations) {
}
ionViewDidLoad() {
this.Platform.ready().then(() => {
let mapLoaded = this.maps.init(this.mapElement.nativeElement, this.pleaseConnect.nativeElement);
let locationsLoaded = this.locations.load();
Promise.all([
mapLoaded,
locationsLoaded
]).then((result) => {
let locations = result[1];
for(let location of locations) {
this.maps.addMarker(location.latitude, location.longitude, location.type);
}
})
});
}
}
Thank you for your time!
Any and all help is appreciated.
In other words, what does Ionic 2 use with the Google Maps Javascript API that allows it to define the icon images for custom markers?
Nothing. Ionic has no responsibility for this whatsoever.
BTW, my test image files are located in the same folder as google-maps.ts (just doing this for now as I figure out what's happening).
This is the issue. The build process takes typescript files from a place and compiles them in to a single file. In to build www/build/main.js.
These images are not there with the main.js
Move your images to assets folder and give the proper path.
For example:
icon: 'assets/icon1.png'