我正在尝试使用Ionic2构建应用程序,该应用程序允许用户通过Google Street View Static API加载StreetViewPanorama对象。加载 View 后,用户应该能够以他们选择的任何方式(远离原始位置,缩放等)来操纵街道 View 。完成此任务后,用户将捕获最终街道 View 的静态图像。
当我 try catch 新街景位置的照片时,我遇到了麻烦。我正在尝试使用Google的documentation on static image generation to achieve this。不幸的是,创建对象后,我无法引用Panorama对象的属性。我对Java语言还比较陌生,所以请耐心等待。
要生成街景全景图,我运行以下功能(从底部的initMap()开始):

 /**
  * Creates the map options for panorama generation. This includes adjusting the coordinate
  * position of a user to the nearest available street view. Following creation of the settings,
  * it generates the street view on a user's device.
  *
  * @param userLocation a JSON object whose keys are 'lat' and 'lng' and whose values are
  *                     the corresponding latitude and longitude respectively
  */
  generatePanorama(userLocation): void {
    var streetviewService = new google.maps.StreetViewService;
    streetviewService.getPanorama({
      location: userLocation,
      preference: google.maps.StreetViewPreference.NEAREST,
      radius: 100},
      function(result, status) {
        console.log("Adjusted latitude: ", result.location.latLng.lat(),
                    "\nAdjusted longitude: ", result.location.latLng.lng());
        new google.maps.StreetViewPanorama(document.getElementById('street-view'), {
          position: result.location.latLng,
          pov: {heading: 165, pitch: 0},
          zoom: 1
        });
      });
  }


  /**
  * Uses a device's native geolocation capabilities to get the user's current position
  *
  * @return a JSON object whose keys are 'lat' and 'lng' and whose calues are the corresponding
  *         latitude and longitude respectively
  */
  getLocation(callback): void {
    Geolocation.getCurrentPosition().then((position) => {
      console.log("Latitude: ", position.coords.latitude, "\nLongitude: ", position.coords.longitude);
      callback({lat: position.coords.latitude, lng: position.coords.longitude});
    }).catch((error) => {
      console.log('Error getting location', error);
    });
  }

 /**
  * Initialize a Google Street View Panorama image
  */
  initMap(): void {
    this.getLocation(this.generatePanorama);
  }
我正在使用代码创建全景图,如上所示,
new google.maps.StreetViewPanorama(document.getElementById('street-view'), {
      position: result.location.latLng,
      pov: {heading: 165, pitch: 0},
      zoom: 1
    });
我无法将此对象分配给实例变量以在以下两个函数中使用:
 /**
  * Generates a URL to query the Google Maps API for a static image of a location
  *
  * @param lat the latitude of the static image to query
  * @param lng the longitude of the static image to query
  * @param heading indicates the compass heading of the camera
  * @param pitch specifies the up or down angle of the camera relative to the street
  * @return a string that is the URL of a statically generated image of a location
  */
  generateStaticMapsURL(lat, lng, heading, pitch): string {
    var url = "https://maps.googleapis.com/maps/api/streetview?size=600x300&location=";
    url += lat + "," + lng;
    url += "&heading=" + heading;
    url += "&pitch=" + pitch;
    url += "&key=SECRET_KEY";
    return url;
  }

  openShareModal() {
    console.log("Final Latitude: ", this.panorama.getPosition().lat());
    console.log("Final Longitude: ", this.panorama.getPosition().lng());
    console.log("Final Heading:", this.panorama.getPov().heading);
    console.log("Final Heading:", this.panorama.getPov().pitch);
    let myModal = this.modalCtrl.create(ShareModalPage);
    myModal.present();
  }
当我尝试直接或通过辅助函数将对象分配给实例变量时,我得到了UnhandledPromiseRejectionWarning,但没有任何效果。那么创建后如何从街景对象中准确地提取诸如位置,方向和倾斜度之类的信息呢?
感谢您的帮助!
更新1:该程序当前可以正常运行。我分配了一个panorama: any;的实例变量,然后尝试使用以下函数和赋值来更新该变量。
/**
  * Creates the map options for panorama generation. This includes adjusting the coordinate
  * position of a user to the nearest available street view. Following creation of the settings,
  * it generates the street view on a user's device.
  *
  * @param userLocation a JSON object whose keys are 'lat' and 'lng' and whose values are
  *                     the corresponding latitude and longitude respectively
  */
  generatePanorama(userLocation): void {
    var streetviewService = new google.maps.StreetViewService;
    streetviewService.getPanorama({
      location: userLocation,
      preference: google.maps.StreetViewPreference.NEAREST,
      radius: 100},
      function(result, status) {
        console.log("Adjusted latitude: ", result.location.latLng.lat(),
                    "\nAdjusted longitude: ", result.location.latLng.lng());
        this.panorama = new google.maps.StreetViewPanorama(document.getElementById('street-view'), {
          position: result.location.latLng,
          pov: {heading: 165, pitch: 0},
          zoom: 1
        });
      });
  }
当我这样做并随后尝试在另一个函数中使用panorama变量时,似乎认为panorama是一个空变量。此外,全景图根本不会加载!这是我尝试在其中使用Panorama变量的第二个函数。
openShareModal() {
    console.log("Final Latitude: ", this.panorama.getPosition().lat());
    console.log("Final Longitude: ", this.panorama.getPosition().lng());
    console.log("Final Heading:", this.panorama.getPov().heading);
    console.log("Final Heading:", this.panorama.getPov().pitch);
    let myModal = this.modalCtrl.create(ShareModalPage);
    myModal.present();
  }
更新2:发布我的代码的全部内容以寻求帮助。
import { Component, ViewChild } from '@angular/core';
import { IonicPage, NavController, NavParams, ViewController, ModalController } from 'ionic-angular';
import { ShareModalPage } from '../share-modal/share-modal';
import { Geolocation } from 'ionic-native';
declare var google;

/**
 * Generated class for the StreetViewModalPage page.
 *
 * See https://ionicframework.com/docs/components/#navigation for more info on
 * Ionic pages and navigation.
 */

@IonicPage()
@Component({
  selector: 'page-street-view-modal',
  templateUrl: 'street-view-modal.html',
})

export class StreetViewModalPage {

  @ViewChild('map') mapElement;
  map: any;
  panorama: any;

  constructor(public navCtrl: NavController, public navParams: NavParams,
              public viewCtrl: ViewController, public modalCtrl: ModalController) {}

  ionViewDidLoad() {
    console.log('ionViewDidLoad StreetViewModalPage');
    this.initMap();
  }


  /**
  * Creates the map options for panorama generation. This includes adjusting the coordinate
  * position of a user to the nearest available street view. Following creation of the settings,
  * it generates the street view on a user's device.
  *
  * @param userLocation a JSON object whose keys are 'lat' and 'lng' and whose values are
  *                     the corresponding latitude and longitude respectively
  */
  generatePanorama(userLocation): void {
    var streetviewService = new google.maps.StreetViewService;
    streetviewService.getPanorama({
      location: userLocation,
      preference: google.maps.StreetViewPreference.NEAREST,
      radius: 100},
      function(result, status) {
        console.log("Adjusted latitude: ", result.location.latLng.lat(),
                    "\nAdjusted longitude: ", result.location.latLng.lng());
        this.panorama = new google.maps.StreetViewPanorama(document.getElementById('street-view'), {
          position: result.location.latLng,
          pov: {heading: 165, pitch: 0},
          zoom: 1
        });
      });
  }


  /**
  * Uses a device's native geolocation capabilities to get the user's current position
  *
  * @return a JSON object whose keys are 'lat' and 'lng' and whose calues are the corresponding
  *         latitude and longitude respectively
  */
  getLocation(callback): void {
    Geolocation.getCurrentPosition().then((position) => {
      console.log("Latitude: ", position.coords.latitude, "\nLongitude: ", position.coords.longitude);
      callback({lat: position.coords.latitude, lng: position.coords.longitude});
    }).catch((error) => {
      console.log('Error getting location', error);
    });
  }

  /**
  * Initialize a Google Street View Panorama image
  */
  initMap(): void {
    this.getLocation(this.generatePanorama);
  }

  /**
  * Generates a URL to query the Google Maps API for a static image of a location
  *
  * @param lat the latitude of the static image to query
  * @param lng the longitude of the static image to query
  * @param heading indicates the compass heading of the camera
  * @param pitch specifies the up or down angle of the camera relative to the street
  * @return a string that is the URL of a statically generated image of a location
  */
  generateStaticMapsURL(lat, lng, heading, pitch): string {
    var url = "https://maps.googleapis.com/maps/api/streetview?size=600x300&location=";
    url += lat + "," + lng;
    url += "&heading=" + heading;
    url += "&pitch=" + pitch;
    url += "&key=XXXXXXXXXXXX"; // TODO : Make private
    return url;
  }

  openShareModal() {
    console.log("Final Latitude: ", this.panorama.getPosition().lat());
    console.log("Final Longitude: ", this.panorama.getPosition().lng());
    console.log("Final Heading:", this.panorama.getPov().heading);
    console.log("Final Heading:", this.panorama.getPov().pitch);
    let myModal = this.modalCtrl.create(ShareModalPage);
    myModal.present();
  }

}
以及相应的HTML ...
<ion-content>
   <div #map id="street-view" style="height:100%; width:100%;"></div>
   <button ion-button style="position: absolute; top: 5px; right: 5px; z-index: 1;" (click)="openShareModal()" large><ion-icon name="camera"></ion-icon></button>
</ion-content>

最佳答案

我认为this.panorama为空的原因是因为您要创建它的范围。

我正在打电话,所以我无法真正输入代码,但是尝试在generatePanorama刚好在方法开始时添加const self = this;,当您分配this.panorama时,请替换为self.panorama = ...

请让我知道是否可行。我会尽快尝试,看看是否就足够了。

这就是我在说的

/**
  * Creates the map options for panorama generation. This includes adjusting the coordinate
  * position of a user to the nearest available street view. Following creation of the settings,
  * it generates the street view on a user's device.
  *
  * @param userLocation a JSON object whose keys are 'lat' and 'lng' and whose values are
  *                     the corresponding latitude and longitude respectively
  */
  generatePanorama(userLocation): void {
    var self = this;
    var streetviewService = new google.maps.StreetViewService;
    streetviewService.getPanorama({
      location: userLocation,
      preference: google.maps.StreetViewPreference.NEAREST,
      radius: 100},
      function(result, status) {
        console.log("Adjusted latitude: ", result.location.latLng.lat(),
                    "\nAdjusted longitude: ", result.location.latLng.lng());
        self.panorama = new google.maps.StreetViewPanorama(document.getElementById('street-view'), {
          position: result.location.latLng,
          pov: {heading: 165, pitch: 0},
          zoom: 1
        });
      });
  }


更新-工作示例

class StackTest {
	constructor() {
    this.initMap();
    // This next line is very important to keep the scope.
    this.openShareModal = this.openShareModal.bind(this);
    // This next line should be defined by ionic itself so it won't be needed
    document.getElementById('open').addEventListener('click', this.openShareModal);
  }

  generatePanorama(userLocation) {
    var self = this;
    var streetviewService = new google.maps.StreetViewService;
    streetviewService.getPanorama({
      location: userLocation,
      preference: google.maps.StreetViewPreference.NEAREST,
      radius: 100},
      function(result, status) {
        console.log("Adjusted latitude: ", result.location.latLng.lat(),
                    "\nAdjusted longitude: ", result.location.latLng.lng());
        self.panorama = new google.maps.StreetViewPanorama(document.getElementById('pano'), {
          position: result.location.latLng,
          pov: {heading: 165, pitch: 0},
          zoom: 1
        });
        self.bindEvents();
      });
  }

  bindEvents() {
  	var self = this;
    this.panorama.addListener('pano_changed', function() {
        var panoCell = document.getElementById('pano-cell');
        panoCell.innerHTML = self.panorama.getPano();
    });

    this.panorama.addListener('links_changed', function() {
        var linksTable = document.getElementById('links_table');
        while (linksTable.hasChildNodes()) {
          linksTable.removeChild(linksTable.lastChild);
        }
        var links = self.panorama.getLinks();
        for (var i in links) {
          var row = document.createElement('tr');
          linksTable.appendChild(row);
          var labelCell = document.createElement('td');
          labelCell.innerHTML = '<b>Link: ' + i + '</b>';
          var valueCell = document.createElement('td');
          valueCell.innerHTML = links[i].description;
          linksTable.appendChild(labelCell);
          linksTable.appendChild(valueCell);
        }
    });

    this.panorama.addListener('position_changed', function() {
        var positionCell = document.getElementById('position-cell');
        positionCell.firstChild.nodeValue = self.panorama.getPosition() + '';
    });

    this.panorama.addListener('pov_changed', function() {
        var headingCell = document.getElementById('heading-cell');
        var pitchCell = document.getElementById('pitch-cell');
        headingCell.firstChild.nodeValue = self.panorama.getPov().heading + '';
        pitchCell.firstChild.nodeValue = self.panorama.getPov().pitch + '';
    });
  }

  getLocation(callback) {
  	callback({lat: 37.869, lng: -122.255});
  }

  initMap() {
    this.getLocation(this.generatePanorama.bind(this));
  }

  openShareModal() {
    console.log("Final Latitude: ", this.panorama.getPosition().lat());
    console.log("Final Longitude: ", this.panorama.getPosition().lng());
    console.log("Final Heading:", this.panorama.getPov().heading);
    console.log("Final Heading:", this.panorama.getPov().pitch);
    alert('If you see this alert this.panorama was defined :)');
    /* let myModal = this.modalCtrl.create(ShareModalPage); */
    /* myModal.present() */;
  }
}

function instantiateTheClass() {
	new StackTest();
}
/* Always set the map height explicitly to define the size of the div
 * element that contains the map. */
#map {
  height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html, body {
  height: 100%;
  margin: 0;
  padding: 0;
}
#open {
  position: absolute;
  top: 0;
  right: 0;
}
#floating-panel {
  position: absolute;
  top: 10px;
  left: 25%;
  z-index: 5;
  background-color: #fff;
  padding: 5px;
  border: 1px solid #999;
  text-align: center;
  font-family: 'Roboto','sans-serif';
  line-height: 30px;
  padding-left: 10px;
}
#pano {
  width: 50%;
  height: 100%;
  float: left;
}
#floating-panel {
  width: 45%;
  height: 100%;
  float: right;
  text-align: left;
  overflow: auto;
  position: static;
  border: 0px solid #999;
}
<div id="pano"></div>
<button id="open">Open modal</button>
<div id="floating-panel">
<table>
  <tr>
    <td><b>Position</b></td><td id="position-cell">&nbsp;</td>
  </tr>
  <tr>
    <td><b>POV Heading</b></td><td id="heading-cell">270</td>
  </tr>
  <tr>
    <td><b>POV Pitch</b></td><td id="pitch-cell">0.0</td>
  </tr>
  <tr>
    <td><b>Pano ID</b></td><td id="pano-cell">&nbsp;</td>
  </tr>
  <table id="links_table"></table>
</table>
</div>
<!-- Replace the value of the key parameter with your own API key. -->
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAH1G2yf7g4br8sQehvB7C1IfBh8EIaAVE&callback=instantiateTheClass">
</script>

10-06 12:14