fr.ird.observe.dto.GPSPoint Maven / Gradle / Ivy
Show all versions of common-dto Show documentation
package fr.ird.observe.dto;
/*
* #%L
* ObServe Toolkit :: Common Dto
* %%
* Copyright (C) 2017 - 2020 IRD, Ultreia.io
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* .
* #L%
*/
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.nuiton.util.DateUtil;
import java.io.Serializable;
import java.util.Date;
public class GPSPoint implements Serializable {
private static final long serialVersionUID = 1L;
/** Logger. */
private static final Logger log = LogManager.getLogger(GPSPoint.class);
private static final double MILE_TO_KM = 1.852;
private static final double EARTH_RADIUS = 3958.75;
/** le rayon de la terre en kilomètres */
public static final int R = 6378;
protected Float latitude;
protected Float longitude;
protected Float vitesse;
protected Date time;
public static GPSPoint newPoint(Date routeDay, Date activityTime, float activityLatitude, float activityLongitude) {
Date currentTime = DateUtil.getDateAndTime(routeDay, activityTime, false, false);
GPSPoint gpsPoint = new GPSPoint();
gpsPoint.setTime(currentTime);
gpsPoint.setLatitude(activityLatitude);
gpsPoint.setLongitude(activityLongitude);
return gpsPoint;
}
public Integer getQuadrant() {
return CoordinateHelper.getQuadrant(longitude, latitude);
}
private boolean isSameLocation(GPSPoint point) {
float latitude = getLatitude() == null ? 0f : getLatitude();
float longitude = getLongitude() == null ? 0f : getLongitude();
float latitude1 = point.getLatitude() == null ? 0f : point.getLatitude();
float longitude1 = point.getLongitude() == null ? 0f : point.getLongitude();
return latitude == latitude1 && longitude == longitude1;
}
public Float getLatitude() {
return latitude;
}
public void setLatitude(Float latitude) {
this.latitude = latitude;
}
public Float getLongitude() {
return longitude;
}
public void setLongitude(Float longitude) {
this.longitude = longitude;
}
public Float getVitesse() {
return vitesse;
}
public void setVitesse(Float vitesse) {
this.vitesse = vitesse;
}
public Date getTime() {
return time;
}
public void setTime(Date time) {
this.time = time;
}
/**
* Calcule la distance entre deux points (en kilometres).
*
* Il s'agit d'une approxiation utilisant la méthode d'orthodromie.
*
* http://fr.wikipedia.org/wiki/Orthodromie
*
* d = R * arccos(cos(lat1) * cos(lat2) *cos(long2 - long1) + sin(lat1)
* *sin(lat2))
*
* @param p1 le second point
* @return la distance calculée entre les deux points en kilometres.
*/
public double getDistanceInKm(GPSPoint p1) {
return getDistanceInMile(p1) * MILE_TO_KM;
}
/**
* Calcule la distance entre deux points (en miles nautique).
*
* Il s'agit d'une approxiation utilisant la méthode d'orthodromie.
*
* http://fr.wikipedia.org/wiki/Orthodromie
*
* d = R * arccos(cos(lat1) * cos(lat2) *cos(long2 - long1) + sin(lat1)
* *sin(lat2))
*
* @param p1 le second point
* @return la distance calculée entre les deux points en noeud.
*/
private double getDistanceInMile(GPSPoint p1) {
double d;
if (isSameLocation(p1)) {
// same location : so distance is null for sure
// We use this limit case, otherwise in next computation, tmp
// value can be more than 1 (1.00000000002) and Math.acos(tmp)
// then is NaN
d = 0d;
} else {
double lat1 = latitude;
double lng1 = longitude;
double lat2 = p1.getLatitude();
double lng2 = p1.getLongitude();
// double earthRadius = 3958.75;
double dLat = Math.toRadians(lat2 - lat1);
double dLng = Math.toRadians(lng2 - lng1);
double sindLat = Math.sin(dLat / 2);
double sindLng = Math.sin(dLng / 2);
double a = Math.pow(sindLat, 2) + Math.pow(sindLng, 2)
* Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2));
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
d = EARTH_RADIUS * c;
}
return d;
}
/**
* Calcule la vitesse entre deux points (en noeud).
*
* @param p1 le second point
* @return la vitesse calculée entre les deux points en noeud.
*/
public float getSpeed(GPSPoint p1) {
if (time.after(p1.getTime())) {
if (log.isWarnEnabled()) {
log.warn("Le point " + this + " est chronologiquement après le point " + p1 + " impossible de calculer une vitesse.");
}
return 0;
}
// la distance en miles nautique
double d = getDistanceInMile(p1);
// le temps en heure
float delay = (float) getDelay(p1) / (1000 * 60 * 60);
// la vitesse en noeud
double speed = d / delay;
return (float) speed;
}
/**
* Calcule le temps écoulé entre deux points (en millisecondes).
*
* @param p1 le second point
* @return le temps écoulé entre les deux points en millisecondes.
*/
private long getDelay(GPSPoint p1) {
long d0 = getTime().getTime();
long d1 = p1.getTime().getTime();
return d1 - d0;
}
}