Native maps with side-menu

Hello All,

I am having an issue with native google maps. I have followed this tutorial to integrate native maps into my app. My app has a side menu with maps page that can be selected. When I choose this page in the side menu the map will load properly. However, when I open the side menu to navigate the a different pager, I am unable to choose a different page. Let it also be noted that I can move the map around with the side menu is open. It seems that the side menu is not on top of the map which would be why the side menu is working properly even though it is. All other pages work just fine. Can anyone help me. I also want to note that JavaScript maps work just fine, but I would really like to use native.

One more this, If anyone can help me fix my problem; could you also provide me with an example to add multiple markers. The plugin docs do not give an example using Typescript. Thanks

import { Component } from ‘@angular/core’;
import { NavController, NavParams, Platform } from ‘ionic-angular’;
import { GoogleMap, GoogleMapsEvent, GoogleMapsLatLng } from ‘ionic-native’;

@Component({
selector: ‘page-bases-map-2’,
templateUrl: ‘bases-map-2.html’
})

export class BasesMap2Page {

map: GoogleMap;

constructor(public navCtrl: NavController,
public navParams: NavParams,
public platform: Platform) { }

ionViewDidLoad() {
console.log(‘ionViewDidLoad BasesMap2Page’);
this.platform.ready().then(() => {
this.loadMap();
});
}

loadMap() {
let location = new GoogleMapsLatLng(-34.9290, 138.6010);

this.map = new GoogleMap('map', {
  'backgroundColor': 'white',
  'controls': {
    'compass': true,
    'myLocationButton': true,
    'indoorPicker': true,
    'zoom': true
  },
  'gestures': {
    'scroll': true,
    'tilt': true,
    'rotate': true,
    'zoom': true
  },
  'camera': {
    'latLng': location,
    'tilt': 30,
    'zoom': 15,
    'bearing': 50
  }
});
this.map.on(GoogleMapsEvent.MAP_READY).subscribe(() => {
  console.log('Map is ready!');
});

}

}

I’ve been using this plugin for a bit and its excellent but very hard to find good documentation on it.

With regards to your issues as for adding markers heres some code that will add a marker to the clicked position on the map.

You will need a few things imported first too so don’t forget them.

import { GoogleMap, GoogleMapsLatLng, GoogleMapsEvent, GoogleMapsMarker, GoogleMapsMarkerOptions } from 'ionic-native';

// when the map is ready
this.map.on(GoogleMapsEvent.MAP_READY).subscribe(() => {

  // attach a click event
  this.map.on(GoogleMapsEvent.MAP_CLICK).subscribe((ev) => {
    // create new marker with current position
    let markerOptions: GoogleMapsMarkerOptions = {
      position: new GoogleMapsLatLng(ev.lat, ev.lng),
      title: 'This is my new marker'
    };
    // add the marker to the map
    this.map.addMarker(markerOptions)
      .then((marker: GoogleMapsMarker) => {
         marker.showInfoWindow();
       });
  });
});

For your issue regarding the side menu, I have not used the side menu in my maps application but if you have the project, or a demo application on git, I can take a look.

This is something we have seen when building the conference app out.
It’s because the native maps plugin renders on a different native layer than the webview.

We actually removed the native maps plugin for this very reason. Since there’s nothing that can be really done about this.

  ionViewDidLoad() {
    console.log('ionViewDidLoad DashboardPage');

    // handle side menu issue...
    let leftMenu = this.menuController.get('left');

    if (leftMenu) {
      leftMenu.ionOpen.subscribe(() => {
        if (this.map) {
          this.map.setClickable(false);
        }
      });

      leftMenu.ionClose.subscribe(() => {
        if (this.map) {
          this.map.setClickable(true);
        }
      });
    }

  }
4 Likes

Thank you for all of the help. I am going to your suggestion aaronksaunders.
However, if for some reson I am not able to get it to work can someone help me work out the small kink I am having with my JavaScript map. I have a footer that will appear at the bottom with the name of the location and a button that will push to a details page when the marker is clicked. This footer will be hidden when anywhere else on the map that is not a marker is clicked. The problem is that there is a delay from click on the map to footer. Can anyone help. Here is the code:

TS File

import { Component, ViewChild, ElementRef } from '@angular/core';
import { NavController, LoadingController } from 'ionic-angular';
import { Geolocation } from 'ionic-native';
import { BasesProvider } from '../../providers/bases-provider';

declare var google;

@Component({
  selector: 'page-bases-map',
  templateUrl: 'bases-map.html'
})
export class BasesMapPage {

  @ViewChild('map') mapElement: ElementRef;
  bases: any;
  map: any;
  currentLocation: any;
  selectedBase: any;
  baseName: string;
  footer: boolean;

  constructor(public navCtrl: NavController,
    public loadingCtrl: LoadingController,
    public basesProvider: BasesProvider) {
    this.selectedBase = {};
    this.baseName = '';
    this.footer = false;
  }

  ionViewDidLoad() {
    this.loadMap();
  }

  loadMap() {
    let loader = this.loadingCtrl.create({
      content: 'Please wait...'
    });
    loader.present().then(() => {
      this.basesProvider.loadAllBases().then(data => {
        this.bases = data;
      }).then(() => {
        Geolocation.getCurrentPosition().then((position) => {
          this.currentLocation = {
            lat: position.coords.latitude,
            lng: position.coords.longitude
          };
        }).catch((error) => {
          console.log('Error getting location', error);
        }).then(() => {
          let currentPosition = new google.maps.LatLng(this.currentLocation.lat, this.currentLocation.lng);

          let mapOptions = {
            center: currentPosition,
            zoom: 3,
            mapTypeId: google.maps.MapTypeId.ROADMAP,
            zoomControl: false,
            streetViewControl: false,
            mapTypeControl: false
          }

          let infoWindow = new google.maps.InfoWindow();

          this.map = new google.maps.Map(this.mapElement.nativeElement, mapOptions);

          for (let i = 0; i < this.bases.length; i++) {
            let basePosition = new google.maps.LatLng(this.bases[i].location.latitude, this.bases[i].location.longitude);

            let baseMarker = new google.maps.Marker({
              position: basePosition,
              title: this.bases[i].name
            });

            google.maps.event.addListener(baseMarker, 'click', () => {
              infoWindow.setContent('<h4>' + this.bases[i].name + '</h4>');
              infoWindow.open(this.map, baseMarker);
              this.map.setCenter(baseMarker.getPosition());
              this.selectedBase = {
                id: this.bases[i].id,
                name: this.bases[i].name,
                state: this.bases[i].state,
                lat: this.bases[i].location.latitude,
                lon: this.bases[i].location.longitude
              }
              this.baseName = this.selectedBase.name;
              this.footer = true;
            });
            baseMarker.setMap(this.map);
          }

          google.maps.event.addListener(this.map, 'click', () => {
            infoWindow.close();
            this.map.setCenter(this.currentLocation);
            this.baseName = '';
            this.footer = false;
          });
        }).then(() => {
          loader.dismiss();
        });
      });
    });
  }

  baseDetails() {
    console.log(this.selectedBase);
  }

}

HTML File

<ion-header>
  <ion-navbar>
    <button ion-button menuToggle>
      <ion-icon name="menu"></ion-icon>
    </button>
    <ion-title>Bases Map</ion-title>
  </ion-navbar>
</ion-header>
<ion-content>
  <div #map id="map"></div>
</ion-content>
<div [hidden]="!footer">
  <ion-footer>
    <ion-toolbar>
      <!--<ion-title>{{selectedBase.name}}</ion-title>-->
      <ion-title>{{baseName}}</ion-title>
      <ion-buttons end>
        <button ion-button clear (click)="baseDetails()">Details</button>
      </ion-buttons>
    </ion-toolbar>
  </ion-footer>
</div>

Thanks Aaron, you probably saved me a couple of hours.

Aarons solution works.

Thanks @aaronksaunders

I adapted your solution and it works great. :+1:
For everyone who is interested, here is a link to the current documentation of MenuController

Thank you so much aaronksaunders, This solution works.:+1:

Another solution which worked for us:

  1. Change to overlay menu
    (I don’t know if this is necessary, but I think it looks better)

<ion-menu type="overlay" [content]="content">

  1. Change order of and in app.html
    (not sure either if necessary)

<ion-nav> goes first, then <ion-menu>

  1. Change z-index of menu
ion-menu {
  &[type='overlay'] {
    z-index: 500 !important; 
  }
}

Now the side menu works like the one in google maps.

1 Like

Clear solution. Worked great for me. Thank you!

Thanks @aaronksaunders is work 100%