google javascript angularjs google-maps ionic-framework ngcordova

javascript - ionic google maps



Flechas direccionales animadas estilo "aroundMe" usando ngCordova (1)

Deseo crear la brújula / flecha exactamente como la que vemos en AroundMe Mobile App que apunta exactamente a un alfiler en el mapa de acuerdo con mi posición móvil y actualizar la flecha cuando muevo el teléfono.

Me estoy volviendo loco para entender exactamente cómo hacer eso y no puedo encontrar ninguna guía o tutorial que lo explique un poco.

Lo que encontré en línea es una función de rodamientos y creé una directiva a su alrededor:

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)''); } }; });

Parece actualizar la flecha en una dirección, pero desafortunadamente no es la dirección correcta, ya que no se calcula utilizando la posición del cabezal magneticHeading móvil.

Así que agregué el complemento ngCordova para la orientación del dispositivo para obtener el ngCordova magneticHeading y ahora no sé exactamente cómo usarlo y en qué parte de la función de bearing .

$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)''); });

Traté de agregarlo en la declaración de devolución:

return (brng - heading) % 360;

o:

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

Implementando este código con un observador, veo que la flecha se mueve pero no en la posición exacta ... Por ejemplo, desde mi posición y el pin, la flecha debe apuntar a N y apunta a E.

Siempre buscando en línea No puedo encontrar ningún tutorial / pregunta para encontrar la orientación entre un lat/lng point magnetingHeading y un magnetingHeading .

Tal vez estoy cerca de la solución, pero no puedo avanzar solo.

También traté de buscar fórmulas matemáticas, pero incluso existe un gran dolor para comprenderlas e implementarlas.

Espero que puedas ayudar.


Es difícil dar una respuesta simple a esta pregunta porque mucho depende de la representación gráfica real. Por ejemplo, en qué dirección rotate(0deg) dónde rotate(0deg) .

Puedo explicarle la fórmula que ha encontrado, que podría ayudarlo a resolver el problema usted mismo. La parte difícil es la siguiente:

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);

Lo que ves aquí es la fórmula de Haversines ( https://en.wikipedia.org/wiki/Haversine_formula ). Normalmente uno podría ser suficiente con dos conjuntos de coordenadas y calcular el ángulo entre ellos. Al trabajar con latitud y longitud, esto no funcionará porque la tierra no es una superficie plana. Las tres primeras líneas son Haversine y el resultado ( x e y ) son coordenadas en el unit circle ( https://en.wikipedia.org/wiki/Unit_circle )

El siguiente paso es calcular el ángulo desde el punto en este círculo unitario hacia el centro. Podemos usar el arctangant para esto. Javascript tiene una función auxiliar atan2 que simplifica este proceso. El resultado es simple el ángulo de su punto hacia el centro del círculo. En otras palabras, su posición hacia su punto de interés. El resultado está en radianes y debe convertirse a grados. ( https://en.wikipedia.org/wiki/Atan2 )

Una versión simplificada con un sistema de coordenadas planas se vería así:

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)'');

Donde poi es el punto de interés y you es su posición.

Para compensar su propia rotación, necesita restar su propia rotación. En la muestra anterior, el resultado sería:

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)'');

He hecho un Plunckr en el que puedes ver un simple sistema de coordenadas planas. Puede moverlo y rotarlo a you y al point of interest . La flecha dentro de "usted" siempre apuntará hacia el poi , incluso si gira "usted". Esto se debe a que compensamos nuestra propia rotación.

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

Tenga en cuenta en el Plunckr que la posición ''cero'' siempre está al norte. Verifica tu aplicación para ver tu posición "cero". Ajústelo en consecuencia y su script funcionará.

Espero que esto ayude :-)