Note that there are some explanatory texts on larger screens.

plurals
  1. POGeospatial coordinates and distance in kilometers
    text
    copied!<p>This is a followup to <a href="https://stackoverflow.com/questions/378281/latlon-distance-heading-latlon">this question</a>.</p> <p>I seem to be stuck on this. Basically, I need to be able to convert back and forth to referring to coordinates either in the standard degree system OR by measuring a distance north from the south pole along the international date line, and then a distance east starting from that point on the date line. To do this (as well as some more general distance-measuring stuff), I have one method for determining the distance between two lat/lon points, and another method that takes a lat/lon point, a heading and a distance, and returns the lat/lon point at the end of that course.</p> <p>Here are the two static methods I've defined:</p> <pre><code>/* Takes two lon/lat pairs and returns the distance between them in kilometers. */ public static double distance (double lat1, double lon1, double lat2, double lon2) { double theta = toRadians(lon1-lon2); lat1 = toRadians(lat1); lon1 = toRadians(lon1); lat2 = toRadians(lat2); lon2 = toRadians(lon2); double dist = sin(lat1)*sin(lat2) + cos(lat1)*cos(lat2)*cos(theta); dist = toDegrees(acos(dist)) * 60 * 1.1515 * 1.609344 * 1000; return dist; } /* endOfCourse takes a lat/lon pair, a heading (in degrees clockwise from north), and a distance (in kilometers), and returns * the lat/lon pair that would be reached by traveling that distance in that direction from the given point. */ public static double[] endOfCourse (double lat1, double lon1, double tc, double dist) { double pi = Math.PI; lat1 = toRadians(lat1); lon1 = toRadians(lon1); tc = toRadians(tc); double dist_radians = toRadians(dist / (60 * 1.1515 * 1.609344 * 1000)); double lat = asin(sin(lat1) * cos(dist_radians) + cos(lat1) * sin(dist_radians) * cos(tc)); double dlon = atan2(sin(tc) * sin(dist_radians) * cos(lat1), cos(dist_radians) - sin(lat1) * sin(lat)); double lon = ((lon1-dlon + pi) % (2*pi)) - pi; double[] endPoint = new double[2]; endPoint[0] = lat; endPoint[1] = lon; return endPoint; } </code></pre> <p>And here's the function I'm using to test it:</p> <pre><code>public static void main(String args[]) throws java.io.IOException, java.io.FileNotFoundException { double distNorth = distance(0.0, 0.0, 72.0, 0.0); double distEast = distance(72.0, 0.0, 72.0, 31.5); double lat1 = endOfCourse(0.0, 0.0, 0.0, distNorth)[0]; double lon1 = endOfCourse(lat1, 0.0, 90.0, distEast)[1]; System.out.println("end at: " + lat1 + " / " + lon1); return; } </code></pre> <p>The "end at" values should be appx. 72.0 / 31.5. But instead I'm getting approximately 1.25 / 0.021.</p> <p>I assume I must be missing something stupid, forgetting to convert units somewhere, or something... Any help would be greatly appreciated!</p> <p><strong>UPDATE 1:</strong></p> <p>I had (correctly) written the distance function to return meters, but wrote kilometers in the comments by mistake ... which of course confused me when I came back to it today. Anyway, now that's fixed, and I've fixed the factoring error in the endOfCourse method, and I also realized I'd forgotten to convert back to degrees from radians in that method too. Anyway: while it appears I'm now getting the correct latitude number (71.99...), the longitude number is way off (I get 3.54 instead of 11.5).</p> <p><strong>UPDATE 2:</strong> I had a typo in the test, as mentioned below. It's now fixed in the code. The longitude number is still, however, wrong: I'm now getting -11.34 instead of 11.5. I think there must be something wrong with these lines:</p> <pre><code>double dlon = atan2(sin(tc) * sin(dist_radians) * cos(lat1), cos(dist_radians) - sin(lat1) * sin(lat)); double lon = ((lon1-dlon + pi) % (2*pi)) - pi; </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload