Получить координаты экрана по конкретному местоположению и долготе (андроид)

У меня есть приложение дополненной реальности, в которой я хранил информацию, такую ​​как метро, ​​автозаправочные станции, достопримечательности и т. Д. С соответствующей широтой и долготой.

Теперь, в соответствии с ориентацией устройства, я бы показал маркер для каждого сайта в виде камеры на устройстве. Подобно Layar и Wikitude.

Это займет три дня без остановки и не нашел никого, кто мог бы объяснить, как решить эту проблему.

Поскольку информация по этой теме очень скудная, и я недавно решил эту проблему на iPhone, я думал, что поделюсь своим методом для тех, кто может заставить его работать с Android (в этом ответе нет ничего конкретного для iPhone, кроме функций Math Sin, cos и fmod, которые можно найти в java.lang.Math). Это шаги, которые я предпринял:

  • Получите свой собственный lat / lon и текущий курс компаса (lat1, lon1 и заголовок). На iPhone, CLLocation возвращает их в градусах, но для этих вычислений они ДОЛЖНЫ быть в радианах (т.е. умножать на PI / 180)
  • Получить лат / lon точек интереса (POI) в радианах (lat2 и lon2).
  • Рассчитайте расстояние между lat1 / lon1 и lat2 / lon2, используя формулу, найденную здесь: http://www.movable-type.co.uk/scripts/latlong.html
  • Вычислите угол к lat2 / lon2 по отношению к северу. Это также описано в ссылке выше, но у меня было немного проблем с тем, чтобы это работало, вот код C для этого:

    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;

  • Используя стандартную тригонометрию, я вычисляю x и y. Помните, что эти координаты находятся в трехмерном пространстве, поэтому мы еще не закончили здесь, потому что вам все равно придется сопоставлять их с 2D:

    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

  • Наконец, используя формулу прогноза, вы можете рассчитать экран x (я не делал y, потому что это не было необходимо для моего проекта, но вам нужно было бы получить данные ускорителя и выяснить, перпендикулярно ли устройству к земле). Формула проекции находится здесь (прокрутите до самого низа): http://membres.multimania.fr/amycoders/tutorials/3dbasics.html

    double screenX = (x * 256) / z

Теперь вы можете использовать эту координату x для перемещения изображения или маркера на экране. Вспомните несколько моментов:

  • Все должно быть в радианах
  • Угол от вас к POI по отношению к северу – это угловые точки – currentHeading

(По какой-то причине я не могу правильно форматировать код на этом компьютере, поэтому, если кто-то хочет отредактировать этот ответ, не стесняйтесь).