2016-02-10 5 views
37

Ich möchte den Kompass/Pfeil genau wie die, die wir in AroundMe Mobile App zeigen, die genau auf einen Pin zur Karte entsprechend mit meiner mobilen Position und aktualisieren Sie den Pfeil, wenn ich bewege das Telefon.Animierte Richtungspfeile "aroundMe" Stil mit ngCordova

Ich werde verrückt, genau zu verstehen, wie man das macht, und ich kann keinen Führer oder eine Anleitung finden, die ein wenig es erklären.

Was ich fand, ist eine Online-Lagerfunktion und habe ich eine Richtlinie drum herum:

app.directive('arrow', function() { 

    function bearing(lat1, lng1, lat2, lng2) { 
     var dLon = (lng2 - lng1); 
     var y = Math.sin(dLon) * Math.cos(lat2); 
     var x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLon); 
     var rad = Math.atan2(y, x); 
     var brng = toDeg(rad); 
     return (brng + 360) % 360; 
    } 

    function toRad(deg) { 
     return deg * Math.PI/180; 
    } 

    function toDeg(rad) { 
     return rad * 180/Math.PI; 
    } 

    return { 
    restrict: 'E', 
    link: function (scope, element, attrs) { 
     var arrowAngle = bearing(scope.user.position.lat, scope.user.position.lng, attrs.lat, attrs.lng); 
     element.parent().css('transform', 'rotate(' + arrowAngle + 'deg)'); 
    } 
    }; 

}); 

Es scheint, den Pfeil in eine Richtung zu aktualisieren, aber leider ist es nicht die richtige Richtung, weil es nicht berechnet wird auch die mobile magneticHeading Position.

So habe ich die ngCordova Plugin für Geräte Orientierung die magneticHeading zu bekommen und jetzt weiß ich nicht genau, wie es zu benutzen und wo in der bearing Funktion.

$cordovaDeviceOrientation.getCurrentHeading().then(function(result) { 
    var magneticHeading = result.magneticHeading; 
    var arrowAngle = bearing(scope.user.position.lat, scope.user.position.lng, attrs.lat, attrs.lng, magneticHeading); 
    element.parent().css('transform', 'rotate(' + arrowAngle + 'deg)'); 
    }); 

Ich versuchte es in der return-Anweisung hinzuzufügen:

return (brng - heading) % 360; 

oder:

return (heading - ((brng + 360) % 360)); 

Umsetzung dieser Code mit einem Beobachter ich den Pfeil sehen bewegen, aber nicht in der exakten Position ... Zum Beispiel von meiner Position und dem Pin sollte der Pfeil auf N zeigen und es zeigt auf E.

Immer online suchen Ich kann kein Tutorial/Frage finden, um die Peilung zwischen einer lat/lng point und einer zu finden.

Vielleicht bin ich nah an der Lösung, aber ich kann nicht alleine weitermachen.

Ich habe auch versucht, nach mathematischen Formeln zu suchen, aber selbst da ist ein großer Schmerz zu verstehen und zu implementieren.

Ich hoffe, Sie können helfen.

+0

Ich weiß nicht, ob dies Plunker Ihnen helfen könnten: http://plnkr.co/edit/WC9Kspe54tlod5EOpndD – beaver

+0

@beaver Dank für Ihren Kommentar. Es ist nur mit Breiten- und Längengrad gemacht, nicht mit der mobilen Position ... :( –

+0

Vielleicht [dieser Beitrag] (http://gis.stackexchange.com/questions/29239/calculate-bearing-between-two-decimal- GPS-Koordinaten) könnte Ihnen helfen ... oder [dieser] (http://stackoverflow.com/questions/11415106/issue-with-calcuating-compass-bearing-between-two-gps-coordinates) – beaver

Antwort

1

Es ist schwer, eine klare Antwort auf diese Frage zu geben, da viel von der tatsächlichen grafischen Darstellung abhängt. Zum Beispiel, in welche Richtung zeigen Sie wo rotate(0deg).

Ich kann die Formel erklären, die Sie gefunden haben, die Ihnen helfen könnte, das Problem selbst zu beheben. Der schwierige Teil ist die folgende:

var dLon = (lng2 - lng1); 
    var y = Math.sin(dLon) * Math.cos(lat2); 
    var x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLon); 
    var rad = Math.atan2(y, x); 

Was Sie hier sehen, ist Haversines Formel (https://en.wikipedia.org/wiki/Haversine_formula). Normalerweise könnte man mit zwei Koordinatensätzen genügen und den Winkel zwischen ihnen berechnen. Wenn man mit Längen- und Breitengrad arbeitet, funktioniert das nicht, weil die Erde keine flache Oberfläche ist. Die ersten drei Zeilen sind Haversine und das Ergebnis (x und y) sind Koordinaten auf der unit circle (https://en.wikipedia.org/wiki/Unit_circle)

Der nächste Schritt ist der Winkel von dem Punkt auf diesem Einheitskreis zum Zentrum zu berechnen.Wir können hierfür die arctangant verwenden. Javascript hat eine Hilfsfunktion atan2, die diesen Prozess vereinfacht. Das Ergebnis ist einfach der Winkel Ihres Punktes zum Mittelpunkt des Kreises. Mit anderen Worten, Ihre Position zu Ihrem Punkt von Interesse. Das Ergebnis ist im Bogenmaß und muss in Grad konvertiert werden. (https://en.wikipedia.org/wiki/Atan2)

Eine vereinfachte Version mit einem System flach koordinieren würde wie folgt aussehen:

var deltaX = poi.x - you.x; 
var deltaY = you.y - poi.y; 
var rotation = toDeg(Math.atan2(deltaX, deltaY)); 

bearingElement.css('transform', 'rotate(' + rotation + 'deg)'); 

Wo poi die Point of Interest und you ist Ihre Position.

Um Ihre eigene Rotation zu kompensieren, müssen Sie Ihre eigene Rotation subtrahieren. In dem obigen Beispiel würde das Ergebnis:

var deltaX = poi.x - you.x; 
var deltaY = you.y - poi.y; 
var rotation = toDeg(Math.atan2(deltaX, deltaY)); 

rotation -= you.rotation; 

bearingElement.css('transform', 'rotate(' + rotation + 'deg)'); 

Ich habe ein Plunckr gemacht, in dem Sie ein einfaches flaches Koordinatensystem sehen. Sie können you und die point of interest verschieben und drehen. Der Pfeil in "Sie" zeigt immer auf die poi, auch wenn Sie "Sie" drehen. Denn wir kompensieren unsere eigene Rotation.

https://plnkr.co/edit/OJBGWsdcWp3nAkPk4lpC?p=preview

Hinweis im Plunckr, dass die ‚zero'-Position immer nach Norden ist. Überprüfe deine App, um deine 'Null'-Position zu sehen. Passen Sie es entsprechend an und Ihr Skript wird funktionieren.

hoffe, das hilft :-)