Bildschirmkoordinaten nach Ort und Länge abrufen (Android)

8

Ich habe eine Augmented-Reality-Anwendung, in der ich Informationen wie U-Bahn, Tankstellen, Orte von Interesse usw. mit dem entsprechenden Längen- und Breitengrad gespeichert habe.

Nun würde ich je nach Ausrichtung des Geräts eine Markierung für jeden Standort in der Kameraansicht des Geräts anzeigen. Ähnlich wie Layar und Wikitude.

Es dauert drei Tage, ohne anzuhalten und hat niemanden gefunden, der erklärt, wie man dieses Problem löst.

    
Adrià Carro 15.03.2011, 16:24
quelle

1 Antwort

7

Da die Informationen zu diesem Thema sehr spärlich sind und ich dieses Problem kürzlich auf dem iPhone gelöst habe, dachte ich, ich würde meine Methode für jeden freigeben, der es mit Android arbeiten lässt (es gibt in dieser Antwort nichts wirklich Spezifisches außer für die Math-Funktionen sin, cos und fmod, die in java.lang.Math zu finden sind. Dies sind die Schritte, die ich unternommen habe:

  • Erhalte dein eigenes lat / lon und deinen aktuellen Kompasskurs (lat1, lon1 und heading). Auf dem iPhone gibt CLLocation diese in Grad zurück, aber für diese Berechnungen müssen im Bogenmaß sein (d. H. Mit PI / 180 multiplizieren)
  • Erhalten Sie Längen- und Breitengrade von Sonderzielen (POI) im Bogenmaß (lat2 und lon2).
  • Berechnen Sie den Abstand zwischen lat1 / lon1 und lat2 / lon2 anhand der folgenden Formel: Ссылка
  • Berechne Winkel zu lat2 / lon2 in Bezug auf Norden. Dies ist auch in dem obigen Link beschrieben, aber ich hatte ein wenig Mühe, dies zum Laufen zu bringen, hier ist C-Code dafür:

    double latDelta = (lat2 - lat1);
    double lonDelta = (lon2 - lon1);
    double y = sin(lonDelta) * cos(lat2);
    double x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2)* cos(lonDelta);
    double angle = atan2(y, x); //not finished here yet
    double headingDeg = compass.currentHeading;
    double angleDeg = angle * 180/PI;
    double heading = headingDeg*PI/180;
    angle = fmod(angleDeg + 360, 360) * PI/180; //normalize to 0 to 360 (instead of -180 to 180), then convert back to radians
    angleDeg = angle * 180/PI;

  • Unter Verwendung der Standard-Trigonometrie berechne ich x und y. Denken Sie daran, diese Koordinaten befinden sich im 3D-Raum, daher sind wir hier noch nicht fertig, da Sie sie immer noch auf 2D abbilden müssen:

    x = sin(angle-heading) * distance;
    z = cos(angle-heading) * distance; //typically, z faces into the screen, but in our 2D map, it is a y-coordinate, as if you are looking from the bottom down on the world, like Google Maps

  • Schließlich können Sie mithilfe der Projektionsformel den Bildschirm x berechnen (ich habe y nicht ausgeführt, weil dies für mein Projekt nicht erforderlich war, aber Sie müssten die Beschleunigungsdaten abrufen und herausfinden, ob das Gerät senkrecht zum Boden steht ). Die Projektionsformel finden Sie hier (blättern Sie ganz nach unten): Ссылка

    double screenX = (x * 256) / z

Jetzt können Sie diese x-Koordinate verwenden, um ein Bild oder eine Markierung auf Ihrem Bildschirm zu verschieben. Denken Sie an einige Punkte:

  • Alles muss im Bogenmaß sein
  • Der Winkel von Ihnen zum POI relativ zu Norden ist angleBeteweenPoints - currentHeading

(Aus irgendeinem Grund kann ich den Code auf diesem Computer nicht richtig formatieren, also wenn jemand diese Antwort bearbeiten möchte, fühle dich frei).

    
Mirkules 08.04.2011, 15:28
quelle