I am trying to overlay duplicate segments of polylines on a map via javascript. I am using latlon.js and geo.js from here

The idea is that a user can input the distance they have travelled and when the map is refreshed, a second multipolyline will be added. To calculate the the point which represents where the user currently is, I am using a known previous location and known 'next location' to calculate a bearing between the two and then using that bearing, combined with the distance the user has travelled to calculate where they are now, before finally creating a new polyline based on that data.

The problem is that this new polyline is drawn incorrectly on my map and I don't understand why. You can see the problem at [removed]. Log in as User2/pass2 and then select 'challenges' from the nav bar. The most relevant code from map.js follows. I am using leaflet maps.

  var userDistance = GymloopChallenge.user_distance;
  var lastPoint;
  var comparisonArr = []; //used to calculate bearing
  if (userDistance <= dist1) {
      comparisonArr = [rioLL,laLL];
      distToAdd = Math.abs(userDistance);
      userPoly = [];
      lastPoint = rioLL;
      console.log('if 1');

  } else if(userDistance >= dist1 && userDistance <= dist2 ) {
      comparisonArr = [laLL,nyLL];
      distToAdd = Math.abs(dist2 - userDistance);
      userPoly = [line5];
      lastPoint = laLL;
      console.log('if 2');
  } else if (userDistance > dist2 && userDistance <= dist3) {
      comparisonArr = [nyLL,lonLL];
      distToAdd = Math.abs(userDistance - dist3);
      userPoly = [line5, line1];
      lastPoint = nyLL;
      console.log('if 3');
  } else if (userDistance > dist3 && userDistance <= dist4) {
      comparisonArr = [lonLL,sydLL];
      distToAdd = Math.abs(userDistance - dist4);
      userPoly = [line5,line1,line2];
      lastPoint = lonLL;
      console.log('if 4');
  } else if (userDistance > dist4 && userDistance <= dist5) {
      comparisonArr = [sydLL,tokLL];
      distToAdd = Math.abs(userDistance - dist5);
      userPoly = [line5,line1,line2,line3];
      lastPoint = sydLL;
      console.log('if 5');

console.log("Distance to add: "+ distToAdd)
//console.log("COmparison array: "+comparisonArr);
  var bearing = comparisonArr[0].finalBearingTo(comparisonArr[1]);
  var userLocation = lastPoint.destinationPoint(bearing, distToAdd);

  userLineStartPoint = new L.LatLng(lastPoint._lat,lastPoint._lon );
  userLocationMapPoint = new L.LatLng(userLocation._lat,userLocation._lon );
  userPoly.push(new Array(userLineStartPoint ,userLocationMapPoint));
    var userPolyline = new L.MultiPolyline(userPoly, {
      color: 'red',
      weight: 3,
      opacity: 0.8


It looks like you're using the wrong functions in latlon.js because your map is in a Mercator projection.

With this type of projection, straight lines of constant bearing are called rhumb lines, or loxodromes. These lines are great for navigating because you set a bearing and head in that direction, but it isn't the shortest path. For that you'd need a great circle, which will appear curved on a Mercator projection (think missile tracks in the movie War Games).

Because you're only dealing with a simple representation of a journey between world cities, and straight lines are easy to draw, you need to use loxodromic calculations. Luckily latlon.js provides just the functions you need: rhumbDistanceTo(), rhumbBearingTo(), and rhumbDestinationPoint(), which should be drop-in replacements for the functions you are already using.

If you wanted great-circle distances, look at the code for the first example on the Movable Type page. But I would argue this is harder for your average user to grasp because actual distances don't have a linear relationship to projected distances.

  • You are an absolute legend sir! I had an inkling it might be something like that but didn't know enough about GIS data to figure this out. Thanks so much! This has made my day. – codecowboy Oct 25 '11 at 16:09
  • I also need to animate the polyline I am adding if you have any suggestions for doing that! – codecowboy Oct 25 '11 at 16:31
  • Sadly JavaScript isn't my strong suit, so you may need to ask on stackoverflow if no one else here can answer. – MerseyViking Oct 25 '11 at 16:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.