Math 从一个点在给定半径内均匀地在球体上生成点
我在某个纬度和经度上选择了一个POI兴趣点,我想非常精确地生成一些最多50英尺远的随机点。我不想超过50英尺,但我也希望随机点均匀分布到50英尺 这是我到目前为止看到的,它看起来不错,但它产生的距离太远了 到目前为止,我最好的猜测是,我认为我的许多假设都是基于圆而不是球体Math 从一个点在给定半径内均匀地在球体上生成点,math,gis,trigonometry,Math,Gis,Trigonometry,我在某个纬度和经度上选择了一个POI兴趣点,我想非常精确地生成一些最多50英尺远的随机点。我不想超过50英尺,但我也希望随机点均匀分布到50英尺 这是我到目前为止看到的,它看起来不错,但它产生的距离太远了 到目前为止,我最好的猜测是,我认为我的许多假设都是基于圆而不是球体 x0 = Longitude of POI y0 = Latitude of POI u = Uniformly random number between [0,1) v = Uniformly random number
x0 = Longitude of POI
y0 = Latitude of POI
u = Uniformly random number between [0,1)
v = Uniformly random number between [0,1)
r = 50*0.3048/111,300
r = maximum 50 foot radius distance new point is away from POI
0.3048 is to convert feet to meters
111,300 is to convert meters to degrees for earth
θ (or t) = 2π*v
θ (or t) = Uniformly random rotation around the polar axis
w = r*sqrt(u)
w = Non-uniformly random distance based on polar coordinate system
so points don’t clump near the center.
Δy = w*sin(θ)
Δy = New random delta change to latitude
standard w*sin(θ) for converting from polar to Cartesian coordinates
y1 = y0+Δy
y1 = New random latitude of new point
Δx = w*cos(θ)/cos(y1*π/180)
Δx = New random delta change to longitude
cos(y1*π/180) used to adjust for shrinking east west distances
as you move further away from the equator
x1 = x0+Δx
x1 = New random longitude of new point
为了添加更多的上下文,我在SQL Server内部使用WKID 4326地理坐标系执行此操作,并使用STDistance检查我的工作。刚刚找到了解决方案,我的数学没有任何错误,这是在SQL Server中将浮点转换为VARCHAR时出现的错误,下面我将包含我的固定SQL Server代码。在我之前:
CONVERT(VARCHAR(50),xxx,3)
我有:
CAST(xxx AS VARCHAR(50))
将float转换为varchar时的值只有6个有效数字,因此我需要传递一个format参数。一件非常奇怪的事情是CAST不应该截断,但无论如何它确实截断了!!这可能是SQL Server 2016 RC0中的一个错误
WITH
LoopTable AS (
SELECT 1 AS i
UNION ALL
SELECT i + 1
FROM LoopTable
WHERE
(i + 1) <= 100000
),
InitialPOI AS (
SELECT geography::STPointFromText('POINT(-81.2545 44.1244)',4326) POI
FROM LoopTable
)
SELECT NewPoint.Lat NewLat, NewPoint.Long NewLong, Distance
FROM (
SELECT POI, NewPoint, POI.STDistance(NewPoint)/0.3048 Distance
FROM (
SELECT POI, geography::STPointFromText('POINT('+CONVERT(VARCHAR(50),POI.Long+x,3)+' '+CONVERT(VARCHAR(50),POI.Lat+y,3)+')',4326) NewPoint
FROM (
SELECT POI, w*COS(t)/COS(POI.Lat*PI()/180) x, w*SIN(t) y
FROM (
SELECT POI, 25*0.3048/111300*SQRT(RAND(CHECKSUM(NEWID()))) w, 2*PI()*RAND(CHECKSUM(NEWID())) t
FROM InitialPOI
) i1
) i2
) i3
) i4
OPTION (MAXRECURSION 0)
你可以用我的公式。由于您没有覆盖整个地球,忽略天花板舍入以保持点真正等距离这仍然不是一个完美的解决方案,我得到的点距离高达25.05英尺,这对我来说足够近,但我希望得到一个完美的算法。