6

Ho una semplice vista stradale lavorando per farmi vedere una vista sulla strada dato un indirizzo:Utilizzando google street view con un marker, come faccio a puntare il POV su un marker?

var geocoder = new google.maps.Geocoder(); 
var address = "344 Laguna Dr, Milpitas, CA 95035"; 
geocoder.geocode({ 'address': address}, 
    function(results, status) { 
     //alert (results); 
    if (status == google.maps.GeocoderStatus.OK) { 
     //alert(results[0].geometry.location); 
     myStreetView = new google.maps.StreetViewPanorama(document.getElementById("map_canvas")); 
     myStreetView.setPosition(results[0].geometry.location); 
     var marker = new google.maps.Marker({ 
      position: results[0].geometry.location, 
      map: myStreetView, 
      title:address 
     }); 
     //alert ("yay"); 
    } else { 
     alert("Geocode was not successful for the following reason: " + status); 
    } 
}); 

Come potete vedere, aggiungo un marker per l'indirizzo sulla vista stradale. La mia domanda è, la vista della strada è rivolta a nord, e il marcatore è a sud. Per un indirizzo non specifico, come faccio a designare che la vista strada dovrebbe puntare al marker dell'indirizzo invece di puntare verso nord di default?

risposta

3

Verificare this sample. Anche se è per V2, puoi riutilizzare il codice. Fondamentalmente, dovrai chiamare computeAngle (markerLatLng, streetviewPanoLatLng) e impostare l'imbardata del pano di Street View sul valore restituito.

function computeAngle(endLatLng, startLatLng) { 
    var DEGREE_PER_RADIAN = 57.2957795; 
    var RADIAN_PER_DEGREE = 0.017453; 

    var dlat = endLatLng.lat() - startLatLng.lat(); 
    var dlng = endLatLng.lng() - startLatLng.lng(); 
    // We multiply dlng with cos(endLat), since the two points are very closeby, 
    // so we assume their cos values are approximately equal. 
    var yaw = Math.atan2(dlng * Math.cos(endLatLng.lat() * RADIAN_PER_DEGREE), dlat) 
     * DEGREE_PER_RADIAN; 
    return wrapAngle(yaw); 
} 

function wrapAngle(angle) { 
    if (angle >= 360) { 
    angle -= 360; 
    } else if (angle < 0) { 
    angle += 360; 
    } 
    return angle; 
} 
+1

Avere stesso problema qui. Questa risposta funziona nell'esempio collegato, ma non risolve il problema dell'OP. Sia il marker che il panorama sono impostati esattamente nella stessa posizione ('results [0] .geometry.location'), quindi' computeAngle' restituisce sempre '0'. Tuttavia, nel panorama attuale, il marcatore viene visualizzato non esattamente dove si trova la fotocamera (che si trova in mezzo alla strada), ma su un lato della strada, contro un edificio reale. – GSerg

+0

Questo è stato anche chiesto qui: http://groups.google.com/group/google-maps-js-api-v3/browse_thread/thread/8495741b6dc238bb?pli = 1 con una risposta che punta a un esempio funzionante su: http://geoapis.appspot.com/agdnZW9hcGlzchMLEgtFeGFtcGxlQ29kZRjRiQIM – jjrv

4

La ragione di ciò è che il POV vista stradale è, per default la direzione del camion stava affrontando quando l'immagine è stata scattata (vai figura). È necessario ottenere la posizione del camion e la posizione della casa e calcolare una "direzione" dalla prima posizione alla seconda, quindi impostare la posizione della vista stradale su quella del camion con la direzione appena calcolata:

// adrloc=target address 
// svwloc=street-view truck location 
svwService.getPanoramaByLocation(adrloc,svwdst,function(dta,sts) { 
    if(sts==google.maps.StreetViewStatus.OK) { 
     var svwloc=dta.location.latLng; 
     var svwhdg=google.maps.geometry.spherical.computeHeading(svwloc,adrloc); 
     var svwmap=avwMap.getStreetView(); 
     svwmap.setPosition(svwloc); 
     svwmap.setPov({ heading: svwhdg, pitch: 0 }); 
     svwMarker=new google.maps.Marker({ map:svwmap, position: adrloc }); 
     svwmap.setVisible(true); 
     } 
    else { 
     ... 
     } 

un altro trucco/trappola usando vista stradale è che è necessario ottenere la vista stradale più vicino a te indirizzo ripetutamente chiamando getPanoramaByLocation con una distanza crescente fino a quando si sono o successo o raggiungere una certa distanza massima. Ho risolvere questo utilizzando questo codice:

var SVW_MAX=100; // maximum street-view distance in meters 
var SVW_INC=10; // increment street-view distance in meters 
var svwService=new google.maps.StreetViewService(); // street view service 
var svwMarker=null; // street view marker 

// NOTE: avwMap is the aerial view map, code not shown 
... 
resolveStreetView(avwMap.getCenter(),SVW_INC); 
... 

var resolveStreetView=function(adrloc,svwdst) { 
    svwService.getPanoramaByLocation(adrloc,svwdst,function(dta,sts) { 
     if(sts==google.maps.StreetViewStatus.OK) { 
      var svwloc=dta.location.latLng; 
      var svwhdg=google.maps.geometry.spherical.computeHeading(svwloc,adrloc); 
      var svwmap=avwMap.getStreetView(); 
      svwmap.setPosition(svwloc); 
      svwmap.setPov({ heading: svwhdg, pitch: 0 }); 
      svwMarker=new google.maps.Marker({ map:svwmap, position: adrloc }); 
      svwmap.setVisible(true); 
      } 
     else if(svwdst<SVW_MAX) { 
      resolveStreetView(adrloc,svwdst+SVW_INC); 
      } 
     }); 
    } 
2

semplice esempio in base al largo il tuo codice:

  1. ottenere la posizione di guardare (utilizzando il geocoder)
  2. ottenere la posizione del StreetViewPanorama (utilizzando il metodo getLocation() una volta modificato il suo stato, l'alternativa sarebbe utilizzare i risultati del metodo getPosition()).
  3. utilizzare il metodo computeHeading di geometry library per calcolare l'intestazione dalla telecamera all'indirizzo.
  4. imposta tale intestazione utilizzando il metodo setPov().
  5. ritardo in modo che l'indicatore si posiziona nel punto corretto (rimuovendo questo lascia il segno nell'angolo in alto a sinistra). Non necessario se non si utilizzano i marcatori.
function geocodeAddress() { 
    var address = "344 Laguna Dr, Milpitas, CA 95035"; 
    geocoder.geocode({ 
    'address': address 
    }, function(results, status) { 
    //alert (results); 
    if (status == google.maps.GeocoderStatus.OK) { 
     //alert(results[0].geometry.location); 
     myStreetView = new google.maps.StreetViewPanorama(document.getElementById("map_canvas")); 
     myStreetView.setPosition(results[0].geometry.location); 
     google.maps.event.addListenerOnce(myStreetView, 'status_changed', function() { 
     var heading = google.maps.geometry.spherical.computeHeading(myStreetView.getLocation().latLng, results[0].geometry.location); 
     myStreetView.setPov({ 
      heading: heading, 
      pitch: 0 
     }); 
     setTimeout(function() { 
      marker = new google.maps.Marker({ 
      position: results[0].geometry.location, 
      map: myStreetView, 
      title: address 
      }); 
      if (marker && marker.setMap) marker.setMap(myStreetView); 
     }, 500); 
     }); 

    } else { 
     alert("Geocode was not successful for the following reason: " + status); 
    } 
    }); 
    google.maps.event.addDomListener(document.getElementById('geoBtn'), 'click', geocodeAddress); 
} 

working fiddle

codice funzionante frammento:

var geocoder = new google.maps.Geocoder(); 
 
var myStreetView = null; 
 
var marker = null; 
 

 
function geocodeAddress() { 
 
    // var address = "344 Laguna Dr, Milpitas, CA 95035"; 
 
    var address = document.getElementById('address').value; 
 
    geocoder.geocode({ 
 
    'address': address 
 
    }, function(results, status) { 
 
    //alert (results); 
 
    if (status == google.maps.GeocoderStatus.OK) { 
 
     //alert(results[0].geometry.location); 
 
     myStreetView = new google.maps.StreetViewPanorama(document.getElementById("map_canvas")); 
 
     myStreetView.setPosition(results[0].geometry.location); 
 
     google.maps.event.addListenerOnce(myStreetView, 'status_changed', function() { 
 
     var heading = google.maps.geometry.spherical.computeHeading(myStreetView.getLocation().latLng, results[0].geometry.location); 
 
     myStreetView.setPov({ 
 
      heading: heading, 
 
      pitch: 0 
 
     }); 
 
     setTimeout(function() { 
 
      marker = new google.maps.Marker({ 
 
      position: results[0].geometry.location, 
 
      map: myStreetView, 
 
      title: address 
 
      }); 
 
      if (marker && marker.setMap) marker.setMap(myStreetView); 
 
     }, 500); 
 
     }); 
 

 
    } else { 
 
     alert("Geocode was not successful for the following reason: " + status); 
 
    } 
 
    }); 
 
    google.maps.event.addDomListener(document.getElementById('geoBtn'), 'click', geocodeAddress); 
 
} 
 
google.maps.event.addDomListener(window, 'load', geocodeAddress);
html, 
 
body, 
 
#map_canvas { 
 
    height: 100%; 
 
    width: 100%; 
 
}
<script src="http://maps.google.com/maps/api/js?libraries=geometry"></script> 
 
<input id="address" type="text" value="344 Laguna Dr, Milpitas, CA 95035" /> 
 
<input id="geoBtn" type="button" value="Go" /> 
 
<div id="map_canvas"></div>

+0

Grazie, per lo più ha funzionato per me, tranne che per entrambi gli argomenti di 'geometry.spherical.computeHeading' devono essere istanze di' LatLng '. 'myStreetView.getLocation(). latLng' restituisce un'istanza' LatLng', ma devi anche creare una nuova istanza dalla tua posizione, 'new google.maps.LatLng (results [0] .geometry.location)'. – Vito

+0

'risultati [0] .geometry.location' è già un oggetto' google.maps.LatLng' – geocodezip

+0

Sì hai ragione, se stai usando la libreria di geocoder per ottenere la posizione restituisce un LatLng. Stavo colpendo direttamente l'endpoint geocode api quando ho scritto quel commento, ma da allora sono passato all'utilizzo del geocoder. – Vito

Problemi correlati