-
Notifications
You must be signed in to change notification settings - Fork 227
Formula for meridian distance in geography #421
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Formula for meridian distance in geography #421
Conversation
| // meridian segment | ||
| else if (math::equals(lon1, lon2)) | ||
| { | ||
| result.azimuth = c0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The azimuth can also be pi in this case if lat2 < lat1. Maybe also -pi if lon2 < lon1, so very close to each other, idk.
| CT cos_dlon; | ||
| CT sin_dlon; | ||
| CT cos_lat1; | ||
| CT cos_lat2; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These variables are not initialized which is wrong by itself but even worse later thay're used for azimuth and quantities calculation. Something meaningful is assigned to them only if ! math::equals(lon1, lon2) so uninitialized variables may be used below. Or am I missing something?
In general I think it is desireable to define and initialize variabels at once, if that'd require to redesign the algorithm/formula then maybe this would be the way to go?
|
Regarding the modified andoyer formula. Is this modification formula-specific so other formulas should be modified in a different way or could it be applied also to thomas and vincenty so extracted outside the formula? Aside from the above. What do you think about first checking if Shouldn't the optimization also kick in when |
|
The code of modified andoyer formula is prototype and mostly for testing. As stated above I propose to apply the new formula of series expansion for all distance formulas (andoyer, thomas, vincenty) with the corresponding order (i.e. 1,2,3 resp.). In this way, both modified andoyer and iteration method are redundant w.r.t. experiments above, so they can be dropped. What do you think? One way for doing this is inside the distance strategy, i.e. if |
|
Yes, the results of new formula of series expansion looks good and the performance is improved. It seems that the resutls of Vincenty's are more close to series expansion order 4, so maybe this is the correct order? It's hard to compare both since Vincenty's is iterative. Have you checked Karney's? Yes, I agree that both formulas shouldn't be mixed and that the strategy is a good place to check the longitudes and call either of these formulas. Also I think that we shouldn't add additional template parameter defining order of the series but simply use the default one internally. Though interestingly enough (assuming you agreed about using order 4 for vincenty) the orders would be the same as the ones used with other series in intersection and area strategies (https://github.com/boostorg/geometry/blob/develop/include/boost/geometry/strategies/geographic/parameters.hpp#L100). However here it's only and optimization, not the core. Side note, the "full" check for the meridian arc could look like this ( |
|
As far as I understand, Karney's (i.e. geographiclib) distance computation is Vincenty plus a method for nearly antipodal points. I activated the meridian distance computation on distance strategy as a special case. For the mapping between formulas (andoyer, thomas, vincenty) and orders of series I used the existing ones i.e. andoyer --> 1, thomas --> 2, vincenty --> 4. It seems that the results of meridian distance are very similar to the general formulas' results. There is one exception though: nearly antipodal points. In that case there is a (large) difference in results since the new formula produce accurate results for that case while formulas like andoyer results with low accuracy. That is, given two nearly antipodal points the distance strategy for andoyer will return a different result than the andoyer's formula. Cf. test cases that are commented out; these are failing. I see two simple directions here: either leave the code as is and change the unit tests in order not to fail, or keep the old distance strategy without using the meridian formula and use the new formula explicitly whenever needed e.g. in pt-box distance. Of course, we can discuss more involved solutions but I think this will eventually end up in implementing accurate solutions for nearly antipodal points, which is not the focus of this PL. Apart from the inconsistency in the result from strategy vs. formula, there is also an issue when computing distances using for example the distance function. Consider the case of two nearly antipodal points on the meridian and compare it with the case where one of two points is moved slightly away from the meridian. In the later case the original formula will be used by the distance function and there will be a "jump" in the distance result. However, even in the current code the user would experience a "jump" when computing distances for nearly antipodal points, cf. #426 |
|
Thanks, I'm ok with altering the test results for now and in the long run implement proper solution for antipodal areas. |
|
Following up on handling the case of nearly antipodal points which lie outside the meridian, I think a similar solution could be devised i.e. check if the points are antipodal in the distance strategy ( Also, as far as I understand, Karney's solution seems to be using a modified algorithm, which is not identical to Vincenty. It also performs some preprocessing, such as arranging the latitudes, longitudes in a canonical form, and treats points as being on the meridian or the equator if they are close to it (these points are then treated as a special case). @vissarion Can you please confirm if the solution above works well for nearly antipodal points that lie on the meridian? If so, I should focus on the general case of Karney's solution i.e. when the geodesic is neither meridional or equatorial. As a starting point, I'm thinking of adding a check for antipodal points which calls the modified algorithm (a dummy function for now). From what I understand, Karney's solution makes use of the longitudinal difference for determining if the points are antipodes. @vissarion, @awulkiew - If you have further suggestions regarding how the solution should be structured, please let me know. |
|
@adl1995 This formula works well for meridian nearly antipodal points. However, your solution should be consistent for both cases of meridian and non-meridian antipodal points. That is, one should not experience changes in accuracy when moving from a point on meridian to a nearby not on meridian. |
This PR implements and tests formulas for computing distance on a meridian of the ellipsoid, i.e. the length of an elliptic arc. This is a special case and should be faster than general distance computation. Apart from the special case it is useful for distance point-box and box-box.
Methods tested:
Some experimental results:
haversine formula (sph), andoyer (and), altered andoyer (andm), thomas (thom), vincenty (vinc), iterative method (iter), series expansion of order $k (eli$k)
lat1=0, lat2=.1
lat1=0, lat2=1
lat1=0, lat2=82
lat1=70, lat2=80
Concluding remarks:
The iterative method is efficient for small segments and becomes very slow as the segment grows. The series expansion is faster than altered andoyer. For order 1 the new formula is a bit less than 2x faster than andoyer for computing meridian distance while keeps the same accuracy.
Proposal:
Use the new series expansion for meridian distance of order 1,2,3 for formulas of andoyer, thomas, vincenty respectively.
---EDIT---
All above times are produced in debug mode, the following table is release: