2

This is how I would do it manually...

I have these three coordinates:

var coordinateOne   = [-72.642883, 42.201343];
var coordinateTwo   = [-72.639532, 42.200784];
var coordinateThree = [-72.637823, 42.199687];

I've got this map, which is centered on the first coordinate:

var map = new mapboxgl.Map({
  container: 'map',
  style: 'mapbox://styles/mapbox/streets-v8',
  center: coordinateOne,
  zoom: 19
});

I can manually set the bearing so that the next coordinate is (not exactly, but close enough for this example) straight ahead:

map.easeTo({ bearing:109, pitch:60, zoom:19 });

Then I can fly straight ahead to that second coordinate:

map.flyTo({ center:coordinateTwo, zoom: 19 });

Then I can manually set the bearing again, putting the third coordinate straight ahead:

map.easeTo({ bearing:130, pitch:60, zoom:19 });

Then I can fly straight ahead to that third coordinate:

map.flyTo({ center:coordinateThree, zoom: 19 });

Is there a way to calculate that bearing value each time automatically, so that each flyTo is always going straight ahead?


I found this question, which covers this idea in Java. Based on the code there, I came up with the following code that comes close but has more of a perpendicular angle to it as opposed to aligning the next point straight ahead.

function bearing(lat1, lon1, lat2, lon2) {
  var longDiff = lon2 - lon1;
  var y        = Math.sin(longDiff) * Math.cos(lat2);
  var x        = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(longDiff);

  return ( toDegrees( Math.atan2( y, x ) ) + 360 ) % 360;
}

function toDegrees (angle) {
  return angle * (180 / Math.PI);
}
Community
  • 1
  • 1
James Chevalier
  • 10,604
  • 5
  • 48
  • 74

1 Answers1

3

I found that TurfJS includes a bearing measurement, so I am using that.

I put together this function to return the bearing between two points:

function bearingBetween(coordinate1, coordinate2) {
  var point1 = {
    "type": "Feature",
    "geometry": {
      "type": "Point",
      "coordinates": [coordinate1[0], coordinate1[1]]
    }
  };
  var point2 = {
    "type": "Feature",
    "geometry": {
      "type": "Point",
      "coordinates": [coordinate2[0], coordinate2[1]]
    }
  };
  return turf.bearing(point1, point2);
}

I use that in my easeTo line:

map.easeTo({ bearing: bearingBetween(coordinateOne, coordinateTwo), pitch: 60, zoom: 19 });

The code that TurfJS uses to calculate this is in its packages/turf-bearing/index.js file.

James Chevalier
  • 10,604
  • 5
  • 48
  • 74