问题
DECLARE @orig geography = geography::Point(17, 78, 4326);
Select @orig.STDistance(geography::Point(17.001, 78.00001, 4326))/1000
gives
110.674385214845
function calculateDistance(lat1, lon1, lat2, lon2, units) {
var R = 6371; // Radius of the earth in km
var dLat = deg2rad(lat2 - lat1); // deg2rad below
var dLon = deg2rad(lon2 - lon1);
var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c; // Distance in km
return d;
}
function deg2rad(deg) {
return deg * (Math.PI / 180)
}`
gives 0.11120001099379416 km
difference of 0.6 mtrs
回答1:
The reason is because the Haversine formula you have used above assumes a spherical earth, with a circumference of 6371 km whereas the Geography datatype uses the WGS 84 ellipsoid. The main difference between the two is that in WGS 84 the earth is an oblate spheroid (ie, squashed at the poles) and is assumed to have a circumference of 6378.13 km around the equator, but a circumference of 6356.75 km around the poles. The full equations for calculations using the WGS 84 ellipsoid are quite complex and Haversine is considered a good approximation in most circumstances.
If you look at the introduction to this excellent resource, http://www.movable-type.co.uk/scripts/latlong.html, the author makes this exact point and suggests that the error from ignoring the ellipsoid is about 0.3% on average (yours is around 0.4%). I repeat the author's quote here, just in case the page ever goes down.
All these formulæ are for calculations on the basis of a spherical earth (ignoring ellipsoidal effects) – which is accurate enough* for most purposes… [In fact, the earth is very slightly ellipsoidal; using a spherical model gives errors typically up to 0.3% – see notes for further details].
来源:https://stackoverflow.com/questions/25422857/differences-in-distance-calculated-between-javascript-function-and-sql-server-st