Utilize the Google Maps API to align an SVG symbol with the direction of an aircraft's

I have been struggling to update the rotation of the Google Maps API SVG aircraft symbol to display the correct heading as it moves. Although it initially loads with the correct heading, I can't seem to figure out how to dynamically update it. I've spent two days trying and failing miserably. I thought simply adding rotation: getTrueHeading would do the trick but no such luck.

The only way I managed to get close to what I want is by including the planeSymbol instance and marker instance inside the

setInterval(function() {}, 3000); 

function at the bottom, but this results in duplicating the aircraft icon and seems highly inefficient.

I admit that the code below is not of great quality, so please excuse its shortcomings – I am still learning JavaScript.

If anyone could provide assistance, I would greatly appreciate it.

Answer №1

Extract the heading information from the DOM just like you would with coordinates, and apply it to adjust the rotation property of the icon.

// Obtain the heading value from the DOM
var gettrueHeadingEl = document.getElementById('trueHeading');
getTrueHeading = parseFloat(gettrueHeadingEl.innerHTML);

// Update the rotation property of the icon
marker.setPosition(new google.maps.LatLng(getLat, getLong));
var newIcon = marker.getIcon()
newIcon.rotation = getTrueHeading;
marker.setIcon(newIcon);

Check out the demo fiddle for a visual representation of this concept.

Sample code snippet:

function initMap() {

  var getLatEl = document.getElementById('latitude');
  getLat = parseFloat(getLatEl.innerHTML);

  var getLongEl = document.getElementById('longitude');
  getLong = parseFloat(getLongEl.innerHTML);

  var gettrueHeadingEl = document.getElementById('trueHeading');
  getTrueHeading = parseFloat(gettrueHeadingEl.innerHTML);

  if (isNaN(getLat) == true && isNaN(getLong) == true) {

    // Display default location      
    var usersLocation = {
      lat: 33.949484,
      lng: -118.430566
    };
    var map = new google.maps.Map(document.getElementById('map'), {
      zoom: 3,
      center: usersLocation,
      mapTypeId: google.maps.MapTypeId.TERRAIN
    });
    var image = 'assets/images/icons/aircraft_marker_map_none_16x16.png';

  } else if (isNaN(getLat) == false && isNaN(getLong) == false) {

    // Show flight sim location
    var usersLocation = {
      lat: getLat,
      lng: getLong
    };
    var map = new google.maps.Map(document.getElementById('map'), {
      zoom: 8,
      center: usersLocation,
      mapTypeId: google.maps.MapTypeId.TERRAIN
    });
    var image = 'assets/images/icons/aircraft_marker_map_16x16.png';

  }

  var planeSymbol = {
    path: 'M362.985,430.724l-10.248,51.234l62.332,57.969l-3.293,26.145 l-71.345-23.599l-2.001,13.069l-2.057-13.529l-71.278,22.928l-5.762-23.984l64.097-59.271l-8.913-51.359l0.858-114.43 l-21.945-11.338l-189.358,88.76l-1.18-32.262l213.344-180.08l0.875-107.436l7.973-32.005l7.642-12.054l7.377-3.958l9.238,3.65 l6.367,14.925l7.369,30.363v106.375l211.592,182.082l-1.496,32.247l-188.479-90.61l-21.616,10.087l-0.094,115.684',
    scale: 0.0333,
    strokeOpacity: 1,
    color: 'black',
    strokeWeight: 1,
    rotation: getTrueHeading,
    anchor: new google.maps.Point(400, 400)
  };


  var marker = new google.maps.Marker({
    id: "player",
    position: usersLocation,
    map: map,
    title: 'Username',
    icon: planeSymbol

  });

  //
  var polyline = new google.maps.Polyline({
      map: map,
      path: []
    })
    // Move players aircraft
  setInterval(function() {

    var getLatEl = document.getElementById('latitude');
    getLat = parseFloat(getLatEl.innerHTML);
    var getLongEl = document.getElementById('longitude');
    getLong = parseFloat(getLongEl.innerHTML);
    var gettrueHeadingEl = document.getElementById('trueHeading');
    getTrueHeading = parseFloat(gettrueHeadingEl.innerHTML);

    var planeSymbol = {
      path: 'M362.985,430.724l-10.248,51.234l62.332,57.969l-3.293,26.145 l-71.345-23.599l-2.001,13.069l-2.057-13.529l-71.278,22.928l-5.762-23.984l64.097-59.271l-8.913-51.359l0.858-114.43 l-21.945-11.338l-189.358,88.76l-1.18-32.262l213.344-180.08l0.875-107.436l7.973-32.005l7.642-12.054l7.377-3.958l9.238,3.65 l6.367,14.925l7.369,30.363v106.375l211.592,182.082l-1.496,32.247l-188.479-90.61l-21.616,10.087l-0.094,115.684',
      scale: 0.0333,
      strokeOpacity: 1,
      color: 'black',
      strokeWeight: 1,
      rotation: getTrueHeading,
      anchor: new google.maps.Point(400, 400)

    };

    if (marker && marker.setPosition) {
      marker.setPosition(new google.maps.LatLng(getLat, getLong));
      var newIcon = marker.getIcon()
      newIcon.rotation = getTrueHeading;
      marker.setIcon(newIcon);
      polyline.getPath().push(marker.getPosition());
    } else {
      marker = new google.maps.Marker({
        position: usersLocation,
        map: map,
        title: 'Username',
        icon: planeSymbol

      });
    }
    map.panTo(new google.maps.LatLng(getLat, getLong));

  }, 3000);


  marker.setMap(map);
  //  moveAircraft(map, marker);

}
var angle = 0;

function simulateMovement() {
  angle += 1;
  var newPt = google.maps.geometry.spherical.computeOffset(new google.maps.LatLng(42, -72), 100000, angle);
  document.getElementById('latitude').innerHTML = newPt.lat();
  document.getElementById('longitude').innerHTML = newPt.lng();
  var heading = angle + 90;
  document.getElementById('trueHeading').innerHTML = heading;
}
setInterval(simulateMovement, 1000);
google.maps.event.addDomListener(window, "load", initMap);
html,
body,
#map {
  height: 100%;
  width: 100%;
  margin: 0px;
  padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="latitude">42</div>
<div id="longitude">-72</div>
<div id="trueHeading">90</div>
<div id="map"></div>

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

Guide to transmitting a "token" to an "API" using "React"

As a novice developer, I am facing a challenge. When users log in to our website, a JWT is created. I need to then pass this token to the API on button click. If the backend call is successful, the API response should be displayed. If not, it should show ...

`Zooming and scrolling feature within a masked image`

I'm struggling to achieve a scrolling zoom effect similar to the website mentioned below, but I can't seem to get it to fully zoom. Additionally, when I try to zoom in on a clipped shape or text while scrolling, the entire div ends up scrolling ...

Passing properties from the parent component to the child component in Vue3JS using TypeScript

Today marks my inaugural experience with VueJS, as we delve into a class project utilizing TypeScript. The task at hand is to transfer the attributes of the tabsData variable from the parent component (the view) to the child (the view component). Allow me ...

Is it possible to use Javascript to retrieve a variable from a remote PHP file?

I am trying to retrieve a variable from a remote PHP file using JavaScript in my phonegap application. The same origin policy doesn't apply here, so I believe I need to use JSON/AJAX for this task. However, I have been unable to find any tutorials tha ...

What is the best method for sending a PHP variable to an AJAX request?

I am working with three files - my main PHP file, functions.php, and my JS file. My challenge is to pass a PHP variable to JavaScript. Below is a snippet from my MAIN PHP FILE: function ccss_show_tag_recipes() { //PHP code here } Next, here's t ...

Is there a Wordpress floating bar similar to the one seen on 9gag?

After browsing through some posts on stackoverflow, I noticed that my website is not responding as expected. You can check out my site here: To troubleshoot, you can examine the source code and utilize Firebug to inspect the css and javascript being used ...

Sending back numerous information in the catch block

Recently, I was testing out the fetch API and encountered an issue with logging a fetch error. I tried catching the error and logging it within the catch block. Strangely, even when I added additional console.log statements in the catch block, they would ...

I constantly encounter the error message "Unable to access properties of undefined (reading 'map')"

I am in the process of using Nextjs 13 for developing my front end and I have a requirement to fetch a .json file from a URL and utilize it to populate my website through server side rendering. However, I keep encountering an error saying "Cannot read prop ...

Troubleshooting issue with jest expect.any() failing to work with a custom class following migration from JavaScript to TypeScript

I recently made the switch to TypeScript in my project, and now some of my Jest tests are failing. It appears that the next function below is no longer being called with an AppError object, but with an Error object instead. Previously, the assertion expec ...

Tips for resolving the issue of "Unable to assign property '_DT_CellIndex' to undefined in Jquery Datatable"

<?php if(mysqli_num_rows($result)>0) {?> <table class="table table-striped" id="example" align="center"> <tr> <thead> <th style=&quo ...

Tips for capturing the dx dy SVG attribute using CSS

Seeking advice on the most effective way to access the dx dy SVG attribute in CSS. If this is not feasible, what would be the best approach in JavaScript? ...

jquery global variable not working as expected

I'm having trouble making some variables global outside the jQuery function. I've tried using 'var' to declare them first and then assigning values, but when I try to log() them at the end, I get undefined. var lat, lon; $.get('ip ...

Is there a way to convert a button into clickable text that performs the same function as the original button?

Seeking a solution to transform a button into clickable text with the same functionality. Explored resources like Google, StackOverFlow, and Youtube for answers. This is the current code snippet representing the button: <button onclick="mainApp.l ...

What is the best way to verify async actions that update the UI in my React Native application?

Currently, my setup involves utilizing jest alongside @testing-library/react-native. Below is a snippet of code: Upon clicking a button, a function is dispatched: onPress(_, dispatch) { dispatch(getUserAddresses()); }, This dispatched functi ...

Tips for resolving the 'route.search' bug in Express.js

I recently started working on a basic Express app (with Node) and I am in the initial setup phase. However, I have encountered an error that is proving to be quite challenging to resolve. Despite my attempts to search for solutions online and browse throu ...

Setting the Content-Type of a JavaScript file within a NodeJS application

I am facing an issue with opening a js-file on my NodeJS server, as it always specifies the .js file with a Content-Type of "text/html." My objective is to send user-input from an html form to a JavaScript file for performing calculations and later genera ...

Is it possible to turn off GPU rasterization for a particular SVG element in Google Chrome?

There is a peculiar issue with the SVG graphic displayed on my webpage. On some computers, the complex linearGradient filling a Rect does not display all the Stops correctly, while on other computers it appears fine. I discovered that if I disable "GPU ra ...

Cannot find JS variable after loop has completed

I am struggling to understand why the value of my variable is not changing in my function. Here is my code snippet: var count = function(datain){ let temparr = [], countobj = {}; $.each(datain, function(key, val) { console.log(temparr); cou ...

Enhancing Angular Directives with Dynamic Templates upon Data Loading

I am facing an issue with a directive that is receiving data from an api call. While the directive itself functions properly, the problem seems to be occurring because the directive loads before the api call is complete. As a result, instead of the expecte ...

How can you leverage Symfony to iterate through a JSON array efficiently?

After selecting a user, I am attempting to display a list of contracts. To achieve this, I have written the following query: /** * @param $firstname * @param $lastname * @return mixed * @throws DBALException */ public function getListPerUser($firs ...