Find the accurate street view on Google Maps URL without relying on computeheading

I've implemented the computeHeading code from a previous answer by Geocodezip, which is mostly effective but has some minor issues that are not related to Geocodezip. The resulting value from computeHeading is stored in the "heading" variable, which determines the position of the heading view for Google Maps Street View as shown below:

var heading = google.maps.geometry.spherical.computeHeading(panorama.getPosition(), marker.getPosition());
  panorama.setPov({
  heading: heading,
  zoom: 1,
  pitch: 0
});
});

However, this approach is not always accurate. My goal is to extract the heading value from Google Maps URLs and assign it to the "heading" variable. I can extract the heading value, parse it from an XML file, and display the result in an info window on a functional map. If you copy and paste the code below, you can observe this process working correctly, but the Point Of View (POV) is slightly off due to the computeHeading method. When I attempt to assign the value of the "NEWHEADING" variable to "heading", it fails to read the value, causing the POV to default to north (0). I have tried reorganizing the code flow without success.

I have validated this code using JSHint, JSLint, and console debugging.

No existing examples demonstrate this concept, as I have searched through Google extensively with no results beyond page 30. All other examples rely on computeHeading, which I wish to avoid. Instead, I want to use the value of the NEWHEADING variable extracted from parsed XML data to determine the correct Street View POV. I hope this explanation is clear, and any assistance or suggestions would be greatly appreciated.

<html>
<head>
<style>
#map {
  height: 400px;
  width: 700px;
  margin: 0px;
  padding: 0px
}
</style>

<script src="http://maps.google.com/maps/api/js?v=3&libraries=visualization,places,geometry" type="text/javascript"></script>
<script type="text/javascript">

// JavaScript code goes here

</script>
</head>

<body>
<div style="border: 2px solid #3872ac;" id="map"></div>
<div id="side_bar"></div>
<p>Additional content can go here.</p>
<a href="#">Link example</a>
</body>
</html>

Answer №1

Pass the desired heading into the createMarker function and use that input instead of calculating it using the street view panorama location and the "looked at" location.

function createMarker(point, map, infoWindow, html, CompanyName, heading) {
    var marker = new google.maps.Marker({
        position: point,
        map: map,
        title: CompanyName
    });
    google.maps.event.addListener(marker, 'click', function () {
        panorama = map.getStreetView();
        panorama.setPosition(marker.getPosition());
        google.maps.event.addListenerOnce(panorama, 'status_changed', function () {
            panorama.setPov({
                heading: heading,
                zoom: 1,
                pitch: 0
            });
        });
        infoWindow.setContent(html);
        infoWindow.open(map, marker);
    });
    bounds.extend(point);
    gmarkers.push(marker);
    side_bar_html += '<a href="javascript:myclick(' + (gmarkers.length - 1) + ')">' + CompanyName + '<\/a><br>';
    return marker;
}

working fiddle

code snippet:

var side_bar_html = "";
var gmarkers = [];
var myLatlng = new google.maps.LatLng(21.13962399, -86.8928956);
var panorama;
var myOptions = {
  zoom: 14,
  center: myLatlng,
  mapTypeId: google.maps.MapTypeId.ROADMAP
};

function myclick(i) {
  google.maps.event.trigger(gmarkers[i], "click");
}
var infoWindow = new google.maps.InfoWindow();
var bounds = new google.maps.LatLngBounds();

function createMarker(point, map, infoWindow, html, CompanyName, heading) {
  var marker = new google.maps.Marker({
    position: point,
    map: map,
    title: CompanyName
  });
  google.maps.event.addListener(marker, 'click', function() {
    panorama = map.getStreetView();
    panorama.setPosition(marker.getPosition());
    google.maps.event.addListenerOnce(panorama, 'status_changed', function() {
      panorama.setPov({
        heading: heading,
        zoom: 1,
        pitch: 0
      });
    });
    infoWindow.setContent(html);
    infoWindow.open(map, marker);
  });
  bounds.extend(point);
  gmarkers.push(marker);
  side_bar_html += '<a href="javascript:myclick(' + (gmarkers.length - 1) + ')">' + CompanyName + '<\/a><br>';
  return marker;
}

function initialize() {
  var map = new google.maps.Map(document.getElementById("map"), myOptions);

  var xmlDoc = xmlParse(xmlStr);
  var markers = xmlDoc.getElementsByTagName("marker");
  for (var i = 0; i < markers.length; i++) {
    var CompanyName = markers[i].getAttribute("CompanyName");
    var CompanyDescription = markers[i].getAttribute("CompanyDescription");
    var CompanyTelephone = markers[i].getAttribute("CompanyTelephone");
    var NEWHEADING = parseFloat(markers[i].getAttribute("StreetView"));
    var point = new google.maps.LatLng(
      parseFloat(markers[i].getAttribute("lat")),
      parseFloat(markers[i].getAttribute("lng")));
    var html = "<H3>" + CompanyName + "</H3>" + CompanyDescription + "<BR>Tel: " + CompanyTelephone + "<BR><B>New Heading: " + NEWHEADING + "</B><BR>";
    html += '<br /><input type="button" onclick="toggleStreetView();" value="See Street View" />';
    var marker = createMarker(point, map, infoWindow, html, CompanyName, NEWHEADING);
  }
  document.getElementById("side_bar").innerHTML = side_bar_html;
  map.fitBounds(bounds);
}
google.maps.event.addDomListener(window, 'load', initialize);

function toggleStreetView() {
  var toggle = panorama.getVisible();
  if (toggle === false) {
    panorama.setVisible(true);
  } else {
    panorama.setVisible(false);
  }
}

function xmlParse(str) {
  if (typeof ActiveXObject != 'undefined' && typeof GetObject != 'undefined') {
    var doc = new ActiveXObject('Microsoft.XMLDOM');
    doc.loadXML(str);
    return doc;
  }

  if (typeof DOMParser != 'undefined') {
    return (new DOMParser()).parseFromString(str, 'text/xml');
  }

  return createElement('div', null);
}
var xmlStr = '<?xml version="1.0" encoding="UTF-8"?><markers><marker CompanyName="MCDONALDS" CompanyDescription="Tasty Hamburgers To Go" lat="21.141406" lng="-86.83339" StreetView="15.26" CompanyTelephone="01 998 893 6767"/><marker CompanyName="LITTLE CAESARS" CompanyDescription="Best Pizzas Anywhere" lat="21.161016" lng="-86.850647" StreetView="233.56" CompanyTelephone="01 998 893 6767"/><marker CompanyName="VIPS" CompanyDescription="Tasty Food" lat="21.113087" lng="-86.838704" StreetView="320.13" CompanyTelephone="+52 998 843 6666"/></markers>';
#map {
  height: 400px;
  width: 700px;
  margin: 0px;
  padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div style="border: 2px solid #3872ac;" id="map"></div>
<div id="side_bar"></div>
<p>Below are the real Streetview URL's with the same HEADING values that are passed to the variable "NEWHEADING"</p> <a href="https://www.google.com.mx/maps/@21.141406,-86.83339,3a,75y,15.26h,90t/data=!3m4!1e1!3m2!1scugaDFoU9Zhym3_IwhMKgQ!2e0!4m2!3m1!1s0x0:0xfde8520f397fad4b!6m1!1e1">McDonalds</a>;

<BR>
<a href="https://www.google.com/maps/@21.161016,-86.850647,3a,75y,233.56h,90t/data=!3m4!1e1!3m2!1sjODIp985qSnPK1noHruiCw!2e0!4m2!3m1!1s0x0:0xc90acf0749a704b!6m1!1e1">Caesars Pizza</a>;

<BR> <a href="https://www.google.com.mx/maps/@21.113087,-86.838704,3a,75y,320.13h,96.48t/data=!3m4!1e1!3m2!1sZWlO1UlMwAuqAL0zEYY_zQ!2e0!6m1!1e1">Vips</a>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Moving Rows Between AgGrids

Experimenting with the example provided in this link (Dragging Multiple Records Between Grids) within my React application: https://www.ag-grid.com/react-data-grid/row-dragging-to-grid/ I have some inquiries; How can I retrieve the selected rows for the ...

Attempting to execute a code snippet using Express framework on the local server at port 3000

Having some trouble with my initial attempt at a basic application. The Scraper.js file successfully scrapes a URL and outputs the array to the document object when executed in the console. Now, I want to set up an Express server to run the script whenever ...

Dynamic resizing navigation with JQUERY

I have successfully created a navigation menu that dynamically resizes each list item to fit the entire width of the menu using JavaScript. $(function() { changeWidth(500); function changeWidth(menuWidth){ var menuItems = $('#menu l ...

How can I restrict the number of characters per line in a textarea using javascript or jQuery?

Is there a method to control the number of characters per line in a textarea? For example, on lines 1-3 of the textarea, only 20 characters can be entered, while on subsequent lines, up to 50 characters are allowed. The current structure of the textarea l ...

Ensuring all ajax calls have completed before proceeding using selenium webdriverjs

In my attempt to create a function that can wait for all active (jQuery) ajax calls to complete in a Selenium WebdriverJS test environment, I am faced with challenges. My current approach involves integrating the following components: Implementing WebDri ...

What is the process for displaying all indexes of a Mongo Collection using MongoDB Node native?

I am curious about how to retrieve all indexes from a specific collection in mongodb. I've tried using listIndexes, indexes, and indexInformation, but these methods only return empty values (arrays and objects). However, when I run db.getCollection(&a ...

What is the best way to assign a value to process.env within an npm script?

After creating a new Vue app (using Vite) with npm init vue@latest and selecting Playwright for e2e tests, the configuration file was generated with a field for setting headless mode: const config: PlaywrightTestConfig = { // ... use: { // ... ...

A guide to effortlessly converting Any[] to CustomType for seamless IntelliSense access to Properties within Angular/Typescript

Our Angular service interacts with the backend to retrieve data and display it on the UI. export interface UserDataResponse { id: number; userName: string; } AngularService_Method1() { return this.http.get<UserDataResponse[]>(this.appUrl + "/Ap ...

The browser encountered an issue trying to load a resource from a directory with multiple nested levels

I've stumbled upon an unusual issue. Here is a snapshot from the inspector tools. The browser is unable to load certain resources even though they do exist. When I try to access the URL in another tab, the resource loads successfully. URLs in the i ...

Issue with loading Babel preset in a monorepo setup

I'm working with a monorepo setup using Lerna and it's structured as follows: monorepo |-- server |-- package1 |-- package2 All packages in the repo make use of Babel. After installing all 3 projects, yarn copied all the required @babe ...

Ways to emphasize an HTML element when clicked with the mouse

Can JavaScript be used to create code that highlights the borders of the HTML element where the mouse pointer is placed or clicked, similar to Firebug, but without needing a browser extension and solely relying on JavaScript? If this is possible, how can ...

Modifying inner content without altering CSS styling

Inside this div, there is a paragraph: This is the HTML code: <div id="header"><p>Header</p></div> This is the CSS code: #header p { color: darkgray; font-size: 15px; Whenever a button is clicked, the innerHTML gets updated: H ...

Display exclusively the chosen option from the dropdown menu

I am facing an issue with the select input on my webpage. Whenever I try to print the page, it prints all the options of the select instead of just the one that is selected. Can someone please guide me on how to modify it so that only the selected option ...

Stopping multiple queries in Node.js can be achieved by using proper error handling

Upon verifying the existence of the name, the program continues to the subsequent query and proceeds with inserting data, which results in an error due to multiple responses being sent. How can I modify it to halt execution after checking if (results.row ...

Firebase has flagged the Google Authentication process with a message stating: Entry denied: The request made by this application

I have connected my domain to Firebase authentication and granted authorization for authentication access. If you want to test it out, feel free to visit this link signInWithPopup(auth, provider) .then((result) => { // This provides a Google Acc ...

Issues have arisen with Google Maps functionality following the API integration, resulting in a blank grey

I am experiencing an issue with Google Maps where it is displaying a grey box or sometimes showing nothing/white. I have tried various solutions found online but none of them have worked for me. Does anyone have a solution? I even attempted to change the ...

the `req.body` method fetches an object with a property named `json

Having an issue with accessing data from req.body in my form created with JS { 'object Object': '' } //when using JSON.stringify: { '{"A":"a","B":"b","C":"c"}': &apo ...

Update the headers of the axios.create instance that is exported by Axios

I have a single api.js file that exports an instance of axios.create() by default: import axios from 'axios' import Cookies from 'js-cookie' const api = axios.create({ baseURL: process.env.VUE_APP_API_URL, timeout: 10000, headers ...

Angular: Exploring the differences between $rootScope variable and event handling

I have a dilemma with an app that handles user logins. As is common in many apps, I need to alter the header once the user logs in. The main file (index.html) utilizes ng-include to incorporate the header.html I've come across two potential solution ...

What is the best way to save a file retrieved from the server through an Ajax request?

I've implemented a download feature in my application. When a user clicks a button, it triggers an ajax call to generate a CSV file with all the displayed information for download. Although I have successfully created the CSV file on the server-side, ...