使用加权多边测量找到未知点
我在地球上有一系列的点(纬度/经度坐标),以及从每个点到未知位置的一系列距离估计值。 我想用多边测量来估计这个未知位置的位置。 从一个简单的例子开始,设想4点和相关距离估计到未知位置的未知点:
纬度,经度,距离估计3元组以下:
p1 = (31.2297, 121.4734, 3335.65)
p2 = (34.539, 69.171, 2477.17)
p3 = (47.907, 106.91, 1719.65)
p4 = (50.43, 80.25, 1242.27)
找到未知点已经在这里解释,并在这里解释一个三角测量的例子。 使用上面的例子,未知位于纬度/经度坐标为:36.989,91.464
我的问题是独特的,因为我正在寻找一种使用权重执行多边测量的方法。 每个距离估计值只是一个估计值; 测量结果不准确,但距离越小测量结果越精确。 我想使用multilatertion,但我想给出与较小距离估计相关的点数,以确定最终答案的“重量”,因为这些较短的估计更准确。 我怎样才能做到这一点? 我正在寻找Python中的解决方案。
回到前面的例子,但是引入了错误,我想再次找到该点的未知位置:
p1 = (31.2297, 121.4734, 4699.15)
p2 = (34.539, 69.171, 2211.97)
p3 = (47.907, 106.91, 1439.75)
p4 = (50.43, 80.25, 1222.07)
虽然这可能不是你正在寻找的东西,但你可以用它作为出发点:
import numpy as np
import scipy.optimize as opt
#Returns the distance from a point to the list of spheres
def calc_distance(point):
return np.power(np.sum(np.power(centers-point,2),axis=1),.5)-rad
#Latitude/longitude to carteisan
def geo2cart(lat,lon):
lat=np.deg2rad(lat)
lon=np.deg2rad(lon)
points=np.vstack((earth_radius*np.cos(lat)*np.cos(lon),
earth_radius*np.cos(lat)*np.sin(lon),
earth_radius*np.sin(lat))).T
return points
#Cartesian to lat/lon
def cart2geo(xyz):
if xyz.ndim==1: xyz=xyz[None,:]
lat=np.arcsin(xyz[:,2]/earth_radius)
lon=np.arctan2(xyz[:,1],xyz[:,0])
return np.rad2deg(lat),np.rad2deg(lon)
#Minimization function.
def minimize(point):
dist= calc_distance(point)
#Here you can change the minimization parameter, here the distances
#from a sphere to a point is divided by its radius for linear weighting.
err=np.linalg.norm(dist/rad)
return err
earth_radius = 6378
p1 = (31.2297, 121.4734, 3335.65)
p2 = (34.539, 69.171, 2477.17)
p3 = (47.907, 106.91, 1719.65)
p4 = (50.43, 80.25, 1242.27)
points = np.vstack((p1,p2,p3,p4))
lat = points[:,0]
lon = points[:,1]
rad = points[:,2]
centers = geo2cart(lat,lon)
out=[]
for x in range(30):
latrand=np.average(lat/rad)*np.random.rand(1)*np.sum(rad)
lonrand=np.average(lon/rad)*np.random.rand(1)*np.sum(rad)
start=geo2cart(latrand,lonrand)
end_pos=opt.fmin_powell(minimize,start)
out.append([cart2geo(end_pos),np.linalg.norm(end_pos-geo2cart(36.989,91464))])
out = sorted(out, key=lambda x: x[1])
print 'Latitude:',out[0][0][0],'Longitude:',out[0][0][1],'Distance:',out[0][1]
我们获得:
First set of points: lat 40.1105092 lon 88.07068701
Second set of points: lat 40.36636421 lon 88.84527729
我确定有更好的方法,但至少你可以玩重量和错误函数来看看会发生什么。 当然有几个严重的问题,一个是你可以卡在当地的最低标准。 有可能是最简单的方法来做到这一点 - 我现在只是看不到它。
只是为了仔细检查这个作品:
p0=np.random.rand(2)*90+20
p1=np.random.rand(2)*-10+20+p0
p2=np.random.rand(2)*-10+20+p0
p3=np.random.rand(2)*-10+20+p0
p4=np.random.rand(2)*-10+20+p0
target=geo2cart(p0[0],p0[1])
points=np.vstack((p1,p2,p3,p4))
lat = points[:,0]
lon = points[:,1]
centers=geo2cart(lat,lon)
#You can change the random at the end to tune the amount of noise
rad = np.power(np.sum(np.power(centers-target,2),axis=1),.5)#+np.random.rand(4)*10
print '------------'
start=geo2cart(np.average(lat),np.average(lon))
end_pos=opt.fmin_powell(minimize,start)
print 'Exact',p0
print 'Start guess',cart2geo(start)
print 'Found',cart2geo(end_pos)
print 'Distance',np.linalg.norm(end_pos-target)
Exact [ 45.21292244 101.85151772]
Start guess (array([ 60.63554123]), array([ 115.08426225]))
Found (array([ 45.21292244]), array([ 101.85151772]))
Distance 5.30420680512e-11
链接地址: http://www.djcxy.com/p/84929.html
上一篇: Finding an unknown point using weighted multilateration