Java перемещается под углом между двумя координатами GPS

#java #algorithm #math #trigonometry

#java #алгоритм #математика #тригонометрия

Вопрос:

У меня есть вариант использования, когда мне нужно сгенерировать координаты GPS для покрытия определенной области (отмеченной списком координат GPS).

Итак, мне нужно сгенерировать координаты. У меня протестированы и реализованы следующие функции:

 //determines wether a Waypoint is inside the specified area
public boolean isInsideArea(Waypoint waypoint)

 public double distanceInKmBetweenGPSCoordinates(Waypoint from, Waypoint to)

 public double[] calculateCoordinatesAfterMove(Waypoint waypoint, double dx, double dy)
  

Вот моя наивная реализация того, как генерировать координаты для квадрата (или приблизительно квадрата):

 public static List<drone.Waypoint> addAutoGeneratedWaypoints(List<Waypoint> polygon_lat_long_pairs) {
        List<Waypoint> waypoints = new ArrayList<>();

        AreaTester tester = new GPSPolygonTester(polygon_lat_long_pairs);
        GPSCoordinateCalculator coordinateCalculator = new GPSCoordinateCalculator();
        CustomGPSMapper mapper = new CustomGPSMapper();

        boolean finish = false;
        String mode = "r";
        Waypoint prev = polygon_lat_long_pairs.get(0);
        int count = 0;
        double distanceDown = mapper.distanceInKmBetweenGPSCoordinates(polygon_lat_long_pairs.get(2), polygon_lat_long_pairs.get(3));
        double travelledDown = 0;
        while (!finish) {
            if (mode.equals("r")) {
                double[] nextA = coordinateCalculator.calculateCoordinatesAfterMove(prev.getPosition().getLatitude(), prev.getPosition().getLongitude(), 5.0, 0.0);
                Waypoint next = new DefaultWaypoint(nextA[0], nextA[1]);
                if (tester.isInsideArea(next)) {
                    System.out.println("Waypoint was in area");
                    waypoints.add(next);
                    prev = next;
                } else {
                    System.err.println("Left area, switching position");
                    mode = "l";
                    double[] nextB = coordinateCalculator.calculateCoordinatesAfterMove(prev.getPosition().getLatitude(), prev.getPosition().getLongitude(), 0.0, -3.0);
                    Waypoint next2 = new DefaultWaypoint(nextB[0], nextB[1]);
                    waypoints.add(next2);
                    travelledDown  = mapper.distanceInKmBetweenGPSCoordinates(prev, next);
                    prev = next2;
                }
                count  ;
            } else {
                double[] nextA = coordinateCalculator.calculateCoordinatesAfterMove(prev.getPosition().getLatitude(), prev.getPosition().getLongitude(), -5.0, 0.0);
                Waypoint next = new DefaultWaypoint(nextA[0], nextA[1]);
                if (tester.isInsideArea(next)) {
                    waypoints.add(next);
                    prev = next;
                } else {
                    System.out.println("Left are, switching");
                    mode = "r";
                    double[] nextB = coordinateCalculator.calculateCoordinatesAfterMove(prev.getPosition().getLatitude(), prev.getPosition().getLongitude(), 0.0, -3.0);
                    Waypoint next2 = new DefaultWaypoint(nextB[0], nextB[1]);
                    waypoints.add(next2);
                    travelledDown  = mapper.distanceInKmBetweenGPSCoordinates(prev, next);
                    prev = next2;
                }
                count  ;
            }
            if (travelledDown >= distanceDown) {
                finish = true;
            }
        }

        List<de.dhbw.drone.waypoints.Waypoint> mapped = waypoints.stream().map(p -> new de.dhbw.drone.waypoints.Waypoint(p)).collect(Collectors.toList());
        return mapped;
  

Я останавливаю алгоритм, когда он перемещается по правой / левой стороне квадрата.

Однако я испытываю трудности, если форма отмеченной области не является квадратной и имеет наклонные линии.

Поэтому мне пришлось бы двигаться по азимуту, как показано на этом изображении:

Полет с наклоном

Когда я мог бы добавить этот угол к своему перемещению, я мог бы использовать этот алгоритм для каждой формы области, в результате чего получился следующий путь:

Желаемый путь

Кто-нибудь может мне помочь, как переместить расстояние в метрах под этим конкретным углом и как рассчитать этот угол между двумя координатами GPS и как рассчитать угол после поворота в сторону? (справа налево вместо слева направо и наоборот). Или это можно решить путем вычисления угла (point1, point2) и angle (point2, point1)?

Ответ №1:

Чтобы вычислить азимут от одной координаты к другой и указать точку на заданном расстоянии, вы можете использовать формулы из latlong page ( bearing и destination point разделов)


Вы можете использовать тот же подход, который обычно реализуется при растеризации 2d-полигонов.

Горизонтальные линии изображения непрерывны в памяти, поэтому заполнение горизонтальных линий является наиболее надежным способом.

В вашем случае вы можете использовать, например, линии на постоянной широте.

Отсортируйте вершины вашего земного многоугольника по широте и разделите диапазоны между значениями широты вершин, затем заполните полученные «трапеции» последовательностями точек (пример с плоскостью)

Иногда (сложный многоугольник и т.д.) Было бы проще использовать метод отклонения — генерировать точки сетки в выписанном прямоугольнике и игнорировать те, которые находятся за пределами многоугольника.