Вычисление средней скорости из точек GPS с помощью ChronoUnit - PullRequest
0 голосов
/ 15 марта 2019

Я хочу рассчитать среднюю скорость из двух точечных объектов. Точечный объект содержит метку времени, Longitude, Latitude и elevation.

Я знаю, что мне нужно вычислить количество времени, которое прошло между измерениями для первой и последней точек на треке. Я надеялся использовать для этого тип ChronoUnit - в частности, метод промежуточный, который, как мне кажется, можно вызвать в ChronoUnit.SECONDS для измерения временных интервалов в единицах секунд.

Что у меня есть (в основном заглушка, поэтому запускаются юнит-тесты):

  // Average speed method
    public double averageSpeed() {
        double avgSpeed = 0;
        if (track.size () < 4) {
            throw new GPSException ("Not enough points to compute");
        } else {
            return avgSpeed;
        }
    }

Точки считываются из файла .csv, пример которого можно посмотреть здесь:

Time,Longitude,Latitude,Elevation
2016-02-17T09:34:53Z,-1.536369,53.796796,35.0
2016-02-17T09:35:14Z,-1.536506,53.796819,35.1
2016-02-17T09:35:21Z,-1.536657,53.796798,35.2
2016-02-17T09:35:28Z,-1.536817,53.796783,35.3
2016-02-17T09:35:31Z,-1.536892,53.796711,35.4
2016-02-17T09:35:34Z,-1.536967,53.796623,35.5

У меня вопрос: я хочу знать, как рассчитать и вернуть averageSpeed(), используя для этого тип ChronoUnit, в частности, метод between для измерения временных интервалов в единицах секунд.

Ответы [ 3 ]

0 голосов
/ 15 марта 2019

Как вы, наверное, знаете, средняя скорость - это пройденное расстояние, поделенное на время, которое вы прошли.

Для расчета общего расстояния вам необходимо рассчитать расстояние между попарно точками и суммировать.

Время легче, потому что оно одномерно. Вам просто нужно время между первым и последним пунктом. Например:

    Instant firstTime = Instant.parse("2016-02-17T09:34:53Z");
    Instant lastTime = Instant.parse("2016-02-17T09:35:34Z");
    long totalTime = ChronoUnit.SECONDS.between(firstTime, lastTime);
    System.out.println("Total time: " + totalTime + " seconds");

Общее время: 41 секунда

0 голосов
/ 16 марта 2019

Спасибо за помощь, ребята.Это помогло мне найти собственное решение, которое отлично работает:

 // Average speed method calling totalDistance() to compute
  public double averageSpeed() {
    double tDistance = totalDistance();

    if (track.size() == 0) {
      throw new GPSException("Track is empty.");
    }
    if (track.size() == 1) {
      throw new GPSException("Track only contains a single point.");
    }
    ZonedDateTime t1 = track.get(0).getTime();
    ZonedDateTime t2 = track.get(track.size() - 1).getTime();

    double time = ChronoUnit.SECONDS.between(t1, t2);
    double avgSpeed = tDistance / time;
    return avgSpeed;
  }
}
0 голосов
/ 15 марта 2019

Может быть, загрузить каждую строку в экземпляр класса, подобного этому, и использовать методы distanceFrom () и secondsUntil (), чтобы помочь вам вычислить скорость.

public static class Observation {
    private ZonedDateTime zdt;
    private double lon;
    private double lat;
    private double ele;

    public ZonedDateTime getZdt() {
        return zdt;
    }

    public void setZdt(ZonedDateTime zdt) {
        this.zdt = zdt;
    }

    public double getLon() {
        return lon;
    }

    public void setLon(double lon) {
        this.lon = lon;
    }

    public double getLat() {
        return lat;
    }

    public void setLat(double lat) {
        this.lat = lat;
    }

    public double getEle() {
        return ele;
    }

    public void setEle(double ele) {
        this.ele = ele;
    }

    // /3985899/vychislit-rasstoyanie-mezhdu-dvumya-tochkami-ispolzuya-shirotu-i-dolgotu
    private static double distance(double lat1, double lat2, double lon1, double lon2, double el1, double el2) {
        final int R = 6371; // Radius of the earth

        double latDistance = Math.toRadians(lat2 - lat1);
        double lonDistance = Math.toRadians(lon2 - lon1);
        double a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2) + Math.cos(Math.toRadians(lat1))
                * Math.cos(Math.toRadians(lat2)) * Math.sin(lonDistance / 2) * Math.sin(lonDistance / 2);
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        double distance = R * c * 1000; // convert to meters

        double height = el1 - el2;

        distance = Math.pow(distance, 2) + Math.pow(height, 2);

        return Math.sqrt(distance);
    }

    public double distanceFrom(Observation that) {
        return distance(this.lat, that.lat, this.lon, that.lon, this.ele, that.ele);
    }

    /**
     * Returns the number of seconds from _this_ to _that_
     */
    public long secondsUntil(Observation that) {
        return Duration.between(this.zdt, that.zdt)
                       .getSeconds();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...