JSFiddle - React, Tailwind, and code Playground

by Wolf

HTML

<!DOCTYPE html>
<html>
  <head>
    <title>Loxodromes</title>
  </head>
  <body>
    <div id="map"></div>
    <script
      src="https://maps.googleapis.com/maps/api/js?callback=initMap&libraries=geometry&language=en"
      defer
      ></script>
  </body>
</html>

CSS

/*
 * 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;
  font-family: sans-serif;
}

JavaScript

function initMap() {
  //const origin = new google.maps.LatLng(0, 0);
  const origin = new google.maps.LatLng(-25.363, -145.956);
  var mapOptions = {
    zoom: 2,
    center: {lat: 30, lng: -75},
  };

  var map = new google.maps.Map(document.getElementById('map'), mapOptions);


  var fineLoxo = drawRhumbLine(origin.lat(), origin.lng(), 45, Math.sqrt(2));
  var fineDrawingPath = new google.maps.Polyline({
    path: fineLoxo,
    geodesic: false, // Set to false because loxodrome is not eodesic
    strokeColor: '#FFF',
    strokeOpacity: 1.0,
    strokeWeight: 8
  });
  fineDrawingPath.setMap(map);
  console.log(fineLoxo);

  var brokenLoxoPath = drawRhumbLine(origin.lat(), origin.lng(), 45, 28.28427125);

  var mediumDrawingPath = new google.maps.Polyline({
    path: brokenLoxoPath,
    geodesic: false, // Set to false because loxodrome is not geodesic
    strokeColor: '#F00',
    strokeOpacity: 0.5,
    strokeWeight: 4
  });
  
  mediumDrawingPath.setMap(map);
  console.log(brokenLoxoPath);

  var oneLoxoPath = drawRhumbLine(origin.lat(), origin.lng(), 45, 113.137085);

  var straightDrawingPath = new google.maps.Polyline({
    path: oneLoxoPath,
    geodesic: false, // Set to false because loxodrome is not geodesic
    strokeColor: '#00F',
    strokeOpacity: 0.5,
    strokeWeight: 4
  });
  straightDrawingPath.setMap(map);
  console.log(oneLoxoPath);
}

function drawRhumbLine(startLat, startLng, bearingDegrees, interval) {
  var dots = []

  const bearing = bearingDegrees * Math.PI / 180;
  
  for (let i = 0; i <= 113.137085 / interval; i++) {
    let lat = startLat + i*interval * Math.cos(bearing);
    let lat1 = (lat/2+45)*Math.PI/180;
    let lat0 = (startLat/2+45)*Math.PI/180;
    let dest = {
      lat: lat,
      lng: startLng + (Math.tan(bearing)*180/Math.PI) * Math.log(Math.tan(lat1) / Math.tan(lat0))
    };
    dots.push(dest);
  }
  return dots;
}