地图距离计算,显然,地球是个曲面,不能简单地通过勾股定理计算,需要考虑到地球的半径。
MySQL版本
DROP FUNCTION IF EXISTS getDistance; -- create a function CREATE FUNCTION getDistance ( lon1 DOUBLE (10, 5), lat1 DOUBLE (10, 5), lon2 DOUBLE (10, 5), lat2 DOUBLE (10, 5) ) RETURNS DOUBLE (16, 8) BEGIN DECLARE sa2 DOUBLE (16, 8); DECLARE sb2 DOUBLE (16, 8); SET lat1 = lat1 * PI() / 180.0; SET lat2 = lat2 * PI() / 180.0; SET sa2 = sin((lat1 - lat2) / 2.0); SET sb2 = sin( ((lon1 - lon2) * PI() / 180.0) / 2.0 ); RETURN 2 * 6367000 * asin( sqrt( sa2 * sa2 + cos(lat1) * cos(lat2) * sb2 * sb2 ) ); -- 测试 END SELECT getDistance ( 114.415686, 38.045362, 114.518596, 38.049113 );
JavaScript版本
// 距离计算 function Utils() { /** * 获取两个点之间的距离 * @param lat1 a点坐标经度 * @param lng1 a点坐标维度 * @param lat2 b点坐标经度 * @param lng2 b点坐标维度 * @returns {number} */ function getDistance(lat1, lng1, lat2, lng2) { let radLat1 = lat1 * Math.PI / 180.0; let radLat2 = lat2 * Math.PI / 180.0; let a = radLat1 - radLat2; let b = lng1 * Math.PI / 180.0 - lng2 * Math.PI / 180.0; let s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2))); s = s * 6378.137;// 地球半径; s = Math.round(s * 10000) / 10000; return s; } /** * * 获取两个点之间的距离 * @param a a点 * @param b b点 * @returns {number} */ function getPointDistance(a, b) { return getDistance(a[0], a[1], b[0], b[1]); } /** * 获取坐标数组的长度 * * @param coordinates * @returns {number} */ function getCoordinatesDistance(coordinates) { let res = 0; if (Array.isArray(coordinates) && coordinates.length > 1) { for (var i = 0, len = coordinates.length - 1; i < len; i++) { var a = coordinates[i], b = coordinates[i + 1]; res += getPointDistance(a, b); } } return res; } /** * 获取GeoJSON的长度 * @param json * @returns {number} */ function getJsonDistance(json) { try { return getCoordinatesDistance(json.features.geometry.coordinates); } catch (e) { console.log(e); return 0; } } return { getDistance: getDistance, getPointDistance: getPointDistance, getCoordinatesDistance: getCoordinatesDistance, getJsonDistance: getJsonDistance } }