Asked  7 Months ago    Answers:  5   Viewed   28 times

My question is very straightforward.

I need the heading value to know how to target the POV.

sv.getPanoramaByLocation() in this case returns a data variable containing the heading of both the arrows in which direction you can go further.

However it doesn't give me the heading value for which way to look at the building. However it is possible to use a marker in streetview to target your building! example

Can anyone help me with this? I can make whatever dump you people want.

 Answers

91

Geocode the address of the building you want to "look at". Use the geometry library computeHeading(from:LatLng, to:LatLng) function to calculate the heading between the StreetView location and the building.

(assumes that the geocoder returns a "rooftop" geocode)

example (Statue of Liberty)

another option, use the directions service:

related question: Request main road StreetView panoramas instead of back alleys from API

code snippet that uses the directions service to get a location on the road to use for street view "camera" location (works better now that you can get "interior" streetview locations returned):

var map;
var berkeley = new google.maps.LatLng(37.869085, -122.254775);
var sv = new google.maps.StreetViewService();
var geocoder = new google.maps.Geocoder();
var directionsService = new google.maps.DirectionsService();
var panorama;
var myLatLng;
var address = "525 Beacon St. Boston, MA";

function initialize() {

  panorama = new google.maps.StreetViewPanorama(document.getElementById("pano"));


  directionsService.route({
    origin: address,
    destination: address,
    travelMode: google.maps.TravelMode.DRIVING
  }, function(response, status) {
    if (status == google.maps.DirectionsStatus.OK) {
      // myLatLng = response.routes[0].legs[0].start_location;
      sv.getPanoramaByLocation(response.routes[0].legs[0].start_location, 50, processSVData);

      var marker = new google.maps.Marker({
      position: response.routes[0].legs[0].start_location,
      map: map,
      title: "Directions"
    });
      map.setCenter(myLatLng);

} else document.getElementById('info').innerHTML += "status:"+status+"<br>";
  });

  geocoder.geocode({
    'address': address
  }, geocoderCallback);
  
  // Set up the map
  var myOptions = {
    zoom: 15
  };

  map = new google.maps.Map(document.getElementById('map_canvas'),
    myOptions);
}
google.maps.event.addDomListener(window, 'load', initialize);

function processSVData(data, status) {
  if (status == google.maps.StreetViewStatus.OK) {

    panorama.setPano(data.location.pano);
    var camera = new google.maps.Marker({
      position: data.location.latLng,
      map: map,
      draggable: true,
      title: "camera"
    });
    var heading = google.maps.geometry.spherical.computeHeading(data.location.latLng, myLatLng);
    document.getElementById('info').innerHTML += "heading:"+heading+"<br>"
    + "location: "+myLatLng.toUrlValue(6)+"<br>"
    + "camera:"+data.location.latLng.toUrlValue(6)+"<br>";
    
    
    // alert(data.location.latLng+":"+myLatLng+":"+heading);
    panorama.setPov({
      heading: heading,
      pitch: 0,
      zoom: 1
    });
    panorama.setVisible(true);
  } else {
    alert("Street View data not found for this location.");
  }
}

function geocoderCallback(results, status) {
  if (status == google.maps.GeocoderStatus.OK) {
    myLatLng = results[0].geometry.location;
    map.setCenter(myLatLng);
    if (results[0].geometry.viewport) map.fitBounds(results[0].geometry.viewport);
    else if (results[0].geometry.bounds) map.fitBounds(results[0].geometry.bounds);
    else map.setZoom(15);
    var marker = new google.maps.Marker({
      position: myLatLng,
      map: map,
      title: address
    });    

  } else {
    alert("Geocode was not successful for the following reason: " + status);
  }
};
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}
#map_canvas {
  height: 100%;
}
<script src="http://maps.googleapis.com/maps/api/js?libraries=geometry"></script>

<div id="pano" style="width: 425px; height: 400px;float:left"></div>
<div id="info"></div>

<div id="map_canvas" style="width: 425px; height: 400px;float:left"></div>
<div id="map_center"></div>
<div id="streetview_pov"></div>
Wednesday, March 31, 2021
 
eek
answered 7 Months ago
eek
70

Ok, I figured it out.

I used the code from my question to get the coordinates of the address --

<?php

// FUNCTION TO CONVERT ADDRESSES INTO COORDINATES
function getCoordinates($address){

$address = str_replace(" ", "+", $address); // replace all the white space with "+" sign to match with google search pattern

$url = "https://maps.googleapis.com/maps/api/geocode/json?address=$address&key=YOUR_TOKEN_KEY";

$response = file_get_contents($url);

$json = json_decode($response,TRUE); //generate array object from the response from the web

return ($json['results'][0]['geometry']['location']['lat'].",".$json['results'][0]['geometry']['location']['lng']);
}

// THIS GETS MY TOP TERM FROM MY CUSTOM TAXONOMY I.E. NEW YORK, NY
$terms = wp_get_post_terms(get_the_ID(), 'city-type');
if ( ! empty( $terms ) && ! is_wp_error( $terms ) ){
     foreach ( $terms as $term ) {
 if ($term->parent == 0) //check for parent terms only

// $ADD IS FROM MY CUSTOM FIELD FOR THE ADDRESS I.E. 1460 BROADWAY
     $the_address = getCoordinates($add, $term->name);    
     }
  }; ?>

Then I simply used the following google embed code (replace token key with your own) ---

<iframe width="100%" height="350" frameborder="0" style="border:0"
src="https://www.google.com/maps/embed/v1/streetview?location=<?php echo $the_address; ?>&heading=165&pitch=0&key=YOUR-TOKEN-KEY" allowfullscreen></iframe>

That's for adding the street view map, I wanted both though so what I did was create two divs, one for each map and then just use click functions to show/hide them --

jQuery(document).ready(function(){
    $("#sv-link").click(function(){
        $("#rv-box").slideToggle("fast");
$("#sv-box").slideToggle();
});
$("#rv-link").click(function(){
        $("#sv-box").slideToggle("fast");
$("#rv-box").slideToggle();
});

});

I know it's probably not the best solution and I can probably dig deeper but this is all I needed. I did run into a issue with a couple addresses that had multiple images/perspectives for one location. I'm trying to figure that out, times square footlocker using the address 1460 broadway, is a perfect example.

Besides that it seems to work fine.

Google Maps

Wednesday, March 31, 2021
 
koenHuybrechts
answered 7 Months ago
43

Keys are now required. Sites that were active before June 22, 2016 without keys are "grandfathered" and will continue to work without keys (at least for now). New sites will require a key.

Saturday, August 7, 2021
 
Mashhadi
answered 3 Months ago
91

gcloud app deploy is the preferred way when using gcloud. If you download the stand alone Google App Engine SDK, then you will have appcfg.py available.

https://cloud.google.com/sdk/gcloud/reference/app/deploy

Saturday, August 28, 2021
 
NathanOliver
answered 2 Months ago
91

Set your circle so it is centered on the position of where you want the marker. It is 20x20, so center it at 10,10:

function Label(opt_options) {
  this.setValues(opt_options);
  var div = this.div_ = document.createElement('div');
  div.style.cssText = 'width: 20px; height: 20px; border-radius: 100%; position: absolute;' +
    'background-color: #8dc73f; ';
};

//

Label.prototype.draw = function() {
  var projection = this.getProjection();
  var position = projection.fromLatLngToDivPixel(this.get('position'));

  var div = this.div_;
  div.style.left = position.x - 10 + 'px';
  div.style.top = position.y - 10 + 'px';
  div.style.display = 'block';
};

Then set the anchor appropriately (at its center as well so it can rotate and still be in the center of the circle).

goldStar = {
  path: 'M57.996 -29.483q0 1.836 -1.332 3.24l-2.7 2.7q-1.368 1.368 -3.276 1.368 -1.944 0 -3.24 -1.368l-10.584 -10.548v25.344q0 1.872 -1.35 3.042t-3.258 1.17h-4.608q-1.908 0 -3.258 -1.17t-1.35 -3.042v-25.344l-10.584 10.548q-1.296 1.368 -3.24 1.368t-3.24 -1.368l-2.7 -2.7q-1.368 -1.368 -1.368 -3.24 0 -1.908 1.368 -3.276l23.436 -23.436q1.26 -1.332 3.24 -1.332 1.944 0 3.276 1.332l23.436 23.436q1.332 1.404 1.332 3.276z',
  fillColor: 'red',
  fillOpacity: 5,
  scale: 0.2,
  strokeWeight: 0,
  rotation: 190,
  anchor: new google.maps.Point(30,-30)
};

related questions:

  • Change marker icon options in google maps
  • Centering google maps SymbolPath on LatLon

proof of concept fiddle

code snippet:

function initialize() {
  var latLng = new google.maps.LatLng(40, -100),
    map = new google.maps.Map(document.getElementById('map_canvas'), {
      zoom: 15,
      center: latLng,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    }),
    goldStar = {
      path: 'M57.996 -29.483q0 1.836 -1.332 3.24l-2.7 2.7q-1.368 1.368 -3.276 1.368 -1.944 0 -3.24 -1.368l-10.584 -10.548v25.344q0 1.872 -1.35 3.042t-3.258 1.17h-4.608q-1.908 0 -3.258 -1.17t-1.35 -3.042v-25.344l-10.584 10.548q-1.296 1.368 -3.24 1.368t-3.24 -1.368l-2.7 -2.7q-1.368 -1.368 -1.368 -3.24 0 -1.908 1.368 -3.276l23.436 -23.436q1.26 -1.332 3.24 -1.332 1.944 0 3.276 1.332l23.436 23.436q1.332 1.404 1.332 3.276z',
      fillColor: 'red',
      fillOpacity: 5,
      scale: 0.2,
      strokeWeight: 0,
      rotation: 190,
      anchor: new google.maps.Point(30, -30)
    };

  var marker = new google.maps.Marker({
    position: latLng,
    map: map,
    icon: goldStar,

  });

  var label = new Label({
    map: map
  });

  label.bindTo('position', marker, 'position');
  label.bindTo('text', marker, 'position');
  var rotation = 190;
  setInterval(function() {
    rotation += 20;
    goldStar.rotation = rotation;
    marker.setIcon(goldStar);
  }, 1000);
};


function Label(opt_options) {
  this.setValues(opt_options);
  var div = this.div_ = document.createElement('div');
  div.style.cssText = 'width: 20px; height: 20px; border-radius: 100%; position: absolute;' +
    'background-color: #8dc73f; ';
};

Label.prototype = new google.maps.OverlayView;
Label.prototype.onAdd = function() {
  var pane = this.getPanes().overlayLayer;
  pane.appendChild(this.div_);
};

Label.prototype.draw = function() {
  var projection = this.getProjection();
  var position = projection.fromLatLngToDivPixel(this.get('position'));

  var div = this.div_;
  div.style.left = position.x - 10 + 'px';
  div.style.top = position.y - 10 + 'px';
  div.style.display = 'block';
};

google.maps.event.addDomListener(window, "load", initialize);
html,
body,
#map_canvas {
  height: 100%;
  width: 100%;
  margin: 0px;
  padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="map_canvas"></div>
Wednesday, September 1, 2021
 
James Kovacs
answered 2 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share