先看VBA版本
Const EarthRadius = 6378.137Function Rad(d) Rad = d * Application.WorksheetFunction.Pi / 180#End FunctionFunction Distance(Lon1, Lat1, Lon2, Lat2) Dim RadLat1 As Double Dim RadLat2 As Double Dim a As Double Dim b As Double Dim s As Double RadLat1 = Rad(Lat1) RadLat2 = Rad(Lat2) a = RadLat1 - RadLat2 b = Rad(Lon1) - Rad(Lon2) s = 2 * Application.WorksheetFunction.Asin(Sqr(Sin(a / 2) ^ 2 + Cos(RadLat1) * Cos(RadLat2) * (Sin(b / 2) ^ 2))) s = s * EarthRadius Distance = sEnd Function
看下图这个操作,感慨万千,老泪纵横
R语言版本,2年前照抄上述VBA代码
#Chao.wen.li#自定义距离函数 单位是 米CaculatDistance Distance CheckErrortry ( { Lon1as.numeric(Lon1) Lat1as.numeric(Lat1) Lon2as.numeric(Lon2) Lat2as.numeric(Lat2) RadLat1 180 RadLat2 180 a b 180 - (Lon2*pi)/ s 2 * asin(sqrt(sin(a / s 6378.137 Distance 1000 } ) if("try-error" %in% class(CheckError)) { return(NA) } else { return(Distance) } }CaculatDistance(116.640001,40.30929,116.638562,40.310109)
后来 看书看多了,借用轮子,改进版
library(geosphere)library(magrittr)distm(c(116.640001,40.30929),c(116.638562,40.310109)) %>% as.character()
Python版本
# -*- coding: utf-8 -*-#pip install geopyfrom geopy.distance import geodesicprint(geodesic((40.30929,116.640001), (40.310109,116.638562)).m)
MS SQL 版本
SET QUOTED_IDENTIFIER ON GOSET ANSI_NULLS ON GOCREATE FUNCTION [DBO].[GETDISTANCE] (@LATBEGIN REAL, @LNGBEGIN REAL, @LATEND REAL, @LNGEND REAL) RETURNS FLOAT ASBEGIN DECLARE @DISTANCE REAL DECLARE @EARTH_RADIUS REAL SET @EARTH_RADIUS = 6378.137 DECLARE @RADLATBEGIN REAL, @RADLATEND REAL, @RADLATDIFF REAL, @RADLNGDIFF REAL SET @RADLATBEGIN = @LATBEGIN *PI()/ 180.0 SET @RADLATEND = @LATEND *PI()/ 180.0 SET @RADLATDIFF = @RADLATBEGIN - @RADLATEND SET @RADLNGDIFF = @LNGBEGIN *PI()/ 180.0 - @LNGEND *PI()/ 180.0 SET @DISTANCE = 2 *ASIN( SQRT( POWER(SIN(@RADLATDIFF / 2), 2)+COS(@RADLATBEGIN)*COS(@RADLATEND) *POWER(SIN(@RADLNGDIFF / 2), 2) ) ) SET @DISTANCE = @DISTANCE * @EARTH_RADIUS RETURN @DISTANCEENDGOSET QUOTED_IDENTIFIER OFF GOSET ANSI_NULLS ON GO
有缘千里来相会
END.