离子3谷歌地图组件不等待加载地图

时间:2018-06-06 08:46:49

标签: google-maps ionic3

基于https://www.joshmorony.com/creating-an-advanced-google-maps-component-in-ionic-2/我在离子3上使用地图和许多标记(约50个)构建了一个应用程序。地图加载正常,但不显示标记,如果我退出并重新进入地图,我可以看到它们。

我调试了代码,并且我可以理解,当Google加载(this.initMap().then(() => { ...)时,地图还没有被绘制,因此当我创建标记时,它们“落入虚空”。 当最终地图准备就绪时,我看不到任何标记。我怎么能确定一切都已加载?

谢谢

    // PAGE: pages/page-maps/page-maps.ts

ionViewDidEnter(){
    .....
    let mapLoaded = this.maps.init(this.form,this.mapElement.nativeElement, this.pleaseConnect.nativeElement, this.viewCtrl.name).then(() => {
        this.filterEcosportelliMap(false);
    });
}

....
async filterEcosportelliMap(hideLoading = false, comune=null) {
    ....
    for (let location of this.ecosportelli) {
        if(location.comune_id!="0"){
            this.maps.addLocationMarker(location.latLng, location["id"], text, this.icon);

        }
    }
});


// PROVIDER: providers/google-maps/google-maps.ts

import { Injectable } from '@angular/core';
import { Platform, AlertController } from 'ionic-angular';
import { InAppBrowser } from '@ionic-native/in-app-browser';
import { Connectivity } from '../connectivity/connectivity';
import { Geolocation } from '@ionic-native/geolocation';
import { Settings } from '../settings/settings';

declare var google : any;

@Injectable()
export class GoogleMaps {
    mapElement: any;
    pleaseConnect: any;
    map: any;
    mapInitialised: boolean = false;
    mapLoaded: any;
    mapLoadedObserver: any;
    currentMarker: any;
    apiKey: string = "123456879";
    form: any;
    pageName: any;
    markers = [];
    indirizzo: string = "";
    marker_pos = [0, 0];
    center_pos = [0, 0];

    infoWindow:any = null;

    constructor(
        public connectivityService: Connectivity,
        public geolocation: Geolocation,
        public alertCtrl: AlertController,
        public settings: Settings,
        private appSettings: Settings,
        private iab: InAppBrowser,
    ) { }

    init(form:any, mapElement: any, pleaseConnect: any, pageName: any): Promise<any> {
        this.center_pos = this.settings.center_pos;
        this.marker_pos = this.settings.marker_pos;
        this.mapElement = mapElement;
        this.pleaseConnect = pleaseConnect;
        this.form = form;
        this.pageName = pageName;
        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(() => {
                            console.log("loaded!!")
                            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&libraries=places';
                    } else {
                        console.log("no api key")
                        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();
                }
                console.log("loaded!!")
                resolve(true);
            }
            this.addConnectivityListeners();
        });
    }

    initMap(): Promise<any> {
        this.infoWindow = new google.maps.InfoWindow({content: ""});
        let parent = this;
        this.mapInitialised = true;
        return new Promise((resolve) => {
            let locationOptions = {timeout: 10000, enableHighAccuracy: true};
            this.geolocation.getCurrentPosition(locationOptions).then((position) => {
                let pos = [position.coords.latitude, position.coords.longitude]
                parent.form.controls.lat.patchValue(pos[0]);
                parent.form.controls.lng.patchValue(pos[1]);
                parent.paintMap(pos,pos);
            }, (err) => {
                let pos = parent.center_pos;
                parent.form.controls.lat.patchValue(pos[0]);
                parent.form.controls.lng.patchValue(pos[1]);
                parent.paintMap(pos,parent.marker_pos);
            });
            resolve(true);
        });
    }

    CenterControl(controlDiv, map) {
        // Set CSS for the control border.
        var controlUI = document.createElement('div');
        controlUI.classList.add('centermap');
        controlUI.style.backgroundColor = '#1a4985';
        controlUI.style.border = 'none';
        controlUI.style.borderRadius = '100px';
        controlUI.style.boxShadow = '0 2px 6px rgba(0,0,0,.3)';
        controlUI.style.cursor = 'pointer';
        controlUI.style.marginBottom = '22px';
        controlUI.style.textAlign = 'center';
        controlUI.title = 'Clicca per centrare la mappa';
        controlDiv.appendChild(controlUI);

        // Set CSS for the control interior.
        var controlText = document.createElement('div');
        controlText.style.color = 'rgb(255,255,255)';
        controlText.style.fontFamily = 'Roboto,Arial,sans-serif';
        controlText.style.fontSize = '16px';
        controlText.style.lineHeight = '0px';
        controlText.style.paddingLeft = '20px';
        controlText.style.paddingRight = '20px';
        controlText.style.paddingBottom = '20px';
        controlText.style.paddingTop = '20px';
        controlText.innerHTML = '<img src="./assets/img/locate.png" style="width:24px;">';
        controlUI.appendChild(controlText);

        // Setup the click event listeners: simply set the map to Chicago.
        let parent = this;
        controlUI.addEventListener('click', function() {
          map.setCenter(new google.maps.LatLng(parent.center_pos[0],parent.center_pos[1]));
        });

      }

    paintMap(latLngCoordsCenter,latLngCoordsMarker): any {
        let latLng = new google.maps.LatLng(latLngCoordsCenter[0], latLngCoordsCenter[1]);
        let mapOptions = {
            center: latLng,
            zoom: 11,
            scrollwheel: false,
            gestureHandling: 'cooperative',
            mapTypeId: google.maps.MapTypeId.ROADMAP
        }
        this.map = new google.maps.Map(this.mapElement, mapOptions);

        var centerControlDiv = document.createElement('div');
        var centerControl = this.CenterControl(centerControlDiv, this.map);

        //centerControlDiv.index = 1;
        //console.log(this.viewCtrl.name)
        if(this.pageName=="DistributoriPage" || this.pageName=="EcosportelliMapPage" || this.pageName=="EcopiazzoleMapPage"){
            //this.map.controls[google.maps.ControlPosition.TOP_CENTER].push(centerControlDiv);
            this.map.controls[google.maps.ControlPosition.BOTTOM_CENTER].push(centerControlDiv);
        }

        let latLngCoords = new google.maps.LatLng(latLngCoordsMarker[0], latLngCoordsMarker[1]);
        let marker = new google.maps.Marker({
            //icon: "img/locateme.png",
            optimized:  false,
            draggable:  true,
            animation:  google.maps.Animation.DROP,
            position:   latLngCoords,
            map:        this.map
        });

        let form = this.form;
        let map = this.map;

        google.maps.event.addListener(marker, "dragend", function() {
            form.controls.lat.patchValue(marker.getPosition().lat());
            form.controls.lng.patchValue(marker.getPosition().lng());
        });

        return(true);
    }

    resizeMap(){
        // console.log("oi",this.map.getCenter())
        // google.maps.event.trigger(this.map, "resize");
        //
        // this.map.setCenter(this.map.getCenter());
    }

    disableMap(): void {
        if(this.pleaseConnect){
            this.pleaseConnect.style.display = "block";
        }
    }

    addMarker(lat: number, lng: number, text: string, id: number, infoWindow: any, icon:string): void {
        //console.log(lat, lng, text, id, infoWindow, icon)
        let latLng = new google.maps.LatLng(lat, lng);
        let marker = new google.maps.Marker({
            map: this.map,
            icon: "./assets/img/"+(icon!=""?icon:"marker_ecosportello.png"),
            //icon: this.settings.serverAddressImg+(icon!=""?icon:"marker_ecosportello.png"),

            animation: google.maps.Animation.DROP,
            position: latLng
        });
        //console.log(marker);
        google.maps.event.addListener(marker,'click', function() {

            if (this.infoWindow) {
                this.infoWindow.close();
            }
            //this.infoWindow = new google.maps.InfoWindow();

            this.infoWindow.setOptions({position:latLng, content:text});
            this.infoWindow.open(this.map, marker);
        });
        this.markers.push(marker);
    }
    addLocationMarker(pos: any, id:number, text: string, icon: string): void {

        console.log(icon);
        let parent = this;
        let latLng = new google.maps.LatLng(pos[0],pos[1]);
        let marker = new google.maps.Marker({
            map: parent.map,
            visible: true,
            icon: "./assets/img/"+(icon!=""?icon:"marker_ecosportello.png"),
            //icon: this.settings.serverAddressImg+(icon!=""?icon:"marker_ecosportello.png"),

            animation: google.maps.Animation.DROP,
            position: latLng
        });

        text += '<br /><button class="infoWindowButton" data-lat="'+pos[0]+'" data-lng="'+pos[1]+'" id="tap_'+id+'"><ion-icon name="car"></ion-icon> Indicazioni stradali </button>';

        let parentInfowindow = this.infoWindow;
        google.maps.event.addListener(marker,'click', function() {
            if (parentInfowindow) {
                parentInfowindow.close();
            }
            parentInfowindow.setOptions({position:latLng, content:text});
            parentInfowindow.open(this.map, marker);
            document.getElementById('tap_'+id).addEventListener('click', (button) => {
                let browser = parent.iab.create('https://maps.apple.com/maps?q='+pos[0]+','+pos[1], '_system'); //For system browser, you'll be prompt to choose your browser if you have more than one
            });
        });

        this.markers.push(marker);
        //console.log(marker);
    }

    geoLocate(address){
        let parent = this;
        if(address!=""){
            var geocoder = new google.maps.Geocoder();
            geocoder.geocode(
                { address: address, componentRestrictions: { country: 'IT' } }, function(results, status) {
                if (status == google.maps.GeocoderStatus.OK) {
                    let pos = [results[0].geometry.location.lat(),results[0].geometry.location.lng()]
                    parent.form.controls.lat.patchValue(pos[0]);
                    parent.form.controls.lng.patchValue(pos[1]);
                    parent.paintMap(pos,pos);
                } else {
                    let alert = this.alertCtrl.create({
                        title: 'Indirizzo non trovato',
                        buttons: ['Ok']
                    });
                    alert.present();
                    parent.form.controls.lat.patchValue(parent.marker_pos[0]);
                    parent.form.controls.lng.patchValue(parent.marker_pos[1]);
                    parent.paintMap(parent.center_pos,parent.marker_pos);
                }
            });
        }else{
            let alert = this.alertCtrl.create({
                title: 'Il campo indirizzo è vuoto',
                buttons: ['Ok']
            });
            alert.present();
            parent.form.controls.lat.patchValue(parent.marker_pos[0]);
            parent.form.controls.lng.patchValue(parent.marker_pos[1]);
            parent.paintMap(parent.center_pos,parent.marker_pos);
        }
    }

    enableMap(): void {
        if(this.pleaseConnect){
            this.pleaseConnect.style.display = "none";
        }
    }

    addConnectivityListeners(): void {
        this.connectivityService.watchOnline().subscribe(() => {
            setTimeout(() => {
                if(typeof(google) === 'undefined' || typeof google.maps === 'undefined'){
                    this.loadGoogleMaps();
                } else {
                    if(!this.mapInitialised){
                        this.initMap();
                    }
                    this.enableMap();
                }
            }, 2000);
        });
        this.connectivityService.watchOffline().subscribe(() => {
            this.disableMap();
        });
    }

    gotoMap(latLng){
        //console.log("click")
        let browser = this.iab.create('https://maps.apple.com/maps?q='+latLng[0]+','+latLng[1], '_system'); //For system browser, you'll be prompt to choose your browser if you have more than one
    }
}

2 个答案:

答案 0 :(得分:0)

很抱歉迟到的回复。你的服务看起来很复杂(对我来说):)。

您应该尝试将其映射到服务的功能(如果这样做)

 ionViewDidLoad() {
    this.initMap();
  }

initMap()函数:

initMap() {
      let mapOptions = {
        center: this.currentPosition,
        zoom: 15,
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        mapTypeControl: false,
        scaleControl: false,
        streetViewControl: false,
        rotateControl: false,
        fullscreenControl: false
      }

      this.map = new google.maps.Map(this.mapElement.nativeElement, mapOptions);
      this.addMarkers();    // Add the markers in this function
  }

我的mapElement是:

@ViewChild('map') mapElement: ElementRef;
HTML中的

<div #map id="map-pick-location">

示例AddMarkers()函数

addMarkers() {
    this.marker = new google.maps.Marker({
      map: this.map,
      animation: google.maps.Animation.DROP,
      draggable: true,
      position: {lat: -0000, lng: -0000} // latitude & longitude
    });
}

希望这对你有帮助!

答案 1 :(得分:0)

使用提供商解决:

google.maps.event.addListenerOnce(this.map, 'idle', function(){
    this.loadMarkers();
});

我从initMap()函数中删除了标记的绘制,并将其移动到map idle listener中。 现在标记出现了,所以这可能是正确的方法

相关问题