2015-04-03 3 views
-2

Я пытаюсь реализовать функцию, которая даст мне местоположение GEO (Lat, Long) с учетом 3 опорных точек GEO и радиуса от каждой точки.Формула для триангуляции (3 ссылки + расстояния)

Сигнатура функции Я ищу это:

public static GeoLocation Triangle(GeoLocation pos1, double r1, GeoLocation pos2, 
            double r2, GeoLocation pos3, double r3) 

В качестве примера, 3 друзья встречаются где-то секрет. Каждый может рассказать мне, где он живет (GeoLocation = lat, long) и как далеко они встречаются из своего дома (r = радиус). Учитывая 3 таких ориентира (из всех трех друзей), у меня должна быть достаточная информация, чтобы рассчитать эту секретную точку встречи как географическую локацию.

Эта проблема очень похожа на проблему с мобильными/башнями, где вы триангулируете мобильный телефон, измеряя отдельные уровни сигнала от нескольких башен.

Я пытался найти формулы онлайн уже довольно давно, поэтому я размещаю свой вопрос здесь, в разделе «Переполнение стека».

Буду признателен, если вы могли бы помочь мне заполнить формулу (метод треугольника) - Спасибо.

код, который я до сих пор:

public class GeoLocation 
{ 
    private double _latitude; 
    private double _longitude; 

    public GeoLocation(double latitude, double longitude) 
    { 
     this._latitude = latitude; 
     this._longitude = longitude; 
    } 

    //Tested and working! 
    public double DistanceToKm(GeoLocation loc) 
    { 
     double lat1, lon1, lat2, lon2; 
     lat1 = this._latitude; 
     lon1 = this._longitude; 
     lat2 = loc._latitude; 
     lon2 = loc._longitude; 
     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; 
    } 
} 

код, который я думаю, что не нужно, но для чего это стоит:

public static Coords ToCoord(GeoLocation pos) 
{ 
    var x = Math.Cos(pos._longitude) * Math.Cos(pos._latitude); 
    var y = Math.Sin(pos._longitude) * Math.Cos(pos._latitude); 
    var z = Math.Sin(pos._latitude); 
    return new Coords(x,y,z); 
} 

class Coords 
{ 
    public double x; 
    public double y; 
    public double z; 

    public Coords(double x, double y, double z) 
    { 
     this.x = x; 
     this.y = y; 
     this.z = z; 
    } 
} 
+0

Привет @roryap. Это не вопрос работы. Я попытался найти формулу онлайн, но не смог. Я также пытался получить его сам, без успеха. Я могу сказать вам, что формула не проста (у меня есть степень в B.Science/Physics и еще в B.Engineering). Это не 2D-пространство, это трехмерная проблема, связанная с широтой и долготой. Я вообще не считаю ваш комментарий конструктивным. Пожалуйста, прочтите мой полный вопрос. – z0mbi3

+0

Святое дерьмо. Как далеко от места встречи живут эти люди !? –

+0

Приблизительно в 50 милях вы получаете довольно неточные значения, если вы предполагаете двумерную карту. Кроме того, формулы не работают тогда, вы должны добавить дельта-ошибку, иначе вы не получите решение. Это усложняет задачу. – z0mbi3

ответ

0

Кажется, это решение после того, как все.

https://gis.stackexchange.com/questions/66/trilateration-using-3-latitude-and-longitude-points-and-3-distances

... гораздо сложнее, чем геометрия школы @DrKoch

Вот решение Python:

yC = earthR *(math.cos(math.radians(LatC)) * math.sin(math.radians(LonC))) 
zC = earthR *(math.sin(math.radians(LatC))) 

P1 = array([xA, yA, zA]) 
P2 = array([xB, yB, zB]) 
P3 = array([xC, yC, zC]) 

#from wikipedia 
#transform to get circle 1 at origin 
#transform to get circle 2 on x axis 
ex = (P2 - P1)/(numpy.linalg.norm(P2 - P1)) 
i = dot(ex, P3 - P1) 
ey = (P3 - P1 - i*ex)/(numpy.linalg.norm(P3 - P1 - i*ex)) 
ez = numpy.cross(ex,ey) 
d = numpy.linalg.norm(P2 - P1) 
j = dot(ey, P3 - P1) 

#from wikipedia 
#plug and chug using above values 
x = (pow(DistA,2) - pow(DistB,2) + pow(d,2))/(2*d) 
y = ((pow(DistA,2) - pow(DistC,2) + pow(i,2) + pow(j,2))/(2*j)) - ((i/j)*x) 

# only one case shown here 
z = sqrt(pow(DistA,2) - pow(x,2) - pow(y,2)) 

#triPt is an array with ECEF x,y,z of trilateration point 
triPt = P1 + x*ex + y*ey + z*ez 

#convert back to lat/long from ECEF 
#convert to degrees 
lat = math.degrees(math.asin(triPt[2]/earthR)) 
lon = math.degrees(math.atan2(triPt[1],triPt[0])) 

print lat, lon` 
Смежные вопросы