package com.grigowashere.aismap.models; import java.io.Serializable; /** * Модель точки пути судна * Содержит координаты, скорость и время прохождения */ public class VesselPathPoint implements Serializable { private static final long serialVersionUID = 1L; private double longitude; private double latitude; private float speed; // скорость в узлах private long timestamp; // время в миллисекундах public VesselPathPoint() { this.timestamp = System.currentTimeMillis(); } public VesselPathPoint(double longitude, double latitude, float speed) { this.longitude = longitude; this.latitude = latitude; this.speed = speed; this.timestamp = System.currentTimeMillis(); } public VesselPathPoint(double longitude, double latitude, float speed, long timestamp) { this.longitude = longitude; this.latitude = latitude; this.speed = speed; this.timestamp = timestamp; } // Геттеры и сеттеры public double getLongitude() { return longitude; } public void setLongitude(double longitude) { this.longitude = longitude; } public double getLatitude() { return latitude; } public void setLatitude(double latitude) { this.latitude = latitude; } public float getSpeed() { return speed; } public void setSpeed(float speed) { this.speed = speed; } public long getTimestamp() { return timestamp; } public void setTimestamp(long timestamp) { this.timestamp = timestamp; } /** * Вычисляет расстояние до другой точки в метрах */ public double distanceTo(VesselPathPoint other) { if (other == null) return 0; final int R = 6371000; // радиус Земли в метрах double lat1Rad = Math.toRadians(this.latitude); double lat2Rad = Math.toRadians(other.latitude); double deltaLatRad = Math.toRadians(other.latitude - this.latitude); double deltaLonRad = Math.toRadians(other.longitude - this.longitude); double a = Math.sin(deltaLatRad / 2) * Math.sin(deltaLatRad / 2) + Math.cos(lat1Rad) * Math.cos(lat2Rad) * Math.sin(deltaLonRad / 2) * Math.sin(deltaLonRad / 2); double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); return R * c; } /** * Вычисляет время между точками в секундах */ public long timeDifferenceSeconds(VesselPathPoint other) { if (other == null) return 0; return Math.abs(this.timestamp - other.timestamp) / 1000; } @Override public String toString() { return String.format("VesselPathPoint{lon=%.6f, lat=%.6f, speed=%.1f, time=%d}", longitude, latitude, speed, timestamp); } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null || getClass() != obj.getClass()) return false; VesselPathPoint that = (VesselPathPoint) obj; return Double.compare(that.longitude, longitude) == 0 && Double.compare(that.latitude, latitude) == 0 && Float.compare(that.speed, speed) == 0 && timestamp == that.timestamp; } @Override public int hashCode() { int result; long temp; temp = Double.doubleToLongBits(longitude); result = (int) (temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(latitude); result = 31 * result + (int) (temp ^ (temp >>> 32)); result = 31 * result + (speed != 0.0f ? Float.floatToIntBits(speed) : 0); result = 31 * result + (int) (timestamp ^ (timestamp >>> 32)); return result; } }