wangzhibo
4 天以前 ae6f40460dcd56af6c5f60ba52c883854c3bac55
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/*  Copyright (C) 2017-2024 Carsten Pfeiffer, José Rebelo, Petr Vaněk
 
    This file is part of Gadgetbridge.
 
    Gadgetbridge is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published
    by the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
 
    Gadgetbridge 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 Affero General Public License for more details.
 
    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.model;
 
import android.location.Location;
 
import androidx.annotation.NonNull;
 
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Comparator;
 
public class GPSCoordinate {
    private final double latitude;
    private final double longitude;
    private final double altitude;
 
    public static final double UNKNOWN_ALTITUDE = -20000d;
 
    public static final int GPS_DECIMAL_DEGREES_SCALE = 6; // precise to 111.132mm at equator: https://en.wikipedia.org/wiki/Decimal_degrees
 
    public GPSCoordinate(double longitude, double latitude, double altitude) {
        this.longitude = longitude;
        this.latitude = latitude;
        this.altitude = altitude;
    }
 
    public GPSCoordinate(double longitude, double latitude) {
        this(longitude, latitude, UNKNOWN_ALTITUDE);
    }
 
    public double getLatitude() {
        return latitude;
    }
 
    public double getLongitude() {
        return longitude;
    }
 
    public double getAltitude() {
        return altitude;
    }
 
    public double getDistance(GPSCoordinate source) {
        final Location end = new Location("end");
        end.setLatitude(this.getLatitude());
        end.setLongitude(this.getLongitude());
 
        final Location start = new Location("start");
        start.setLatitude(source.getLatitude());
        start.setLongitude(source.getLongitude());
 
        return end.distanceTo(start);
    }
 
    public double getAltitudeDifference(GPSCoordinate source) {
        if (this.getAltitude() == UNKNOWN_ALTITUDE)
            return 0;
        if (source.getAltitude() == UNKNOWN_ALTITUDE)
            return 0;
        return this.getAltitude() - source.getAltitude();
    }
 
    public double getAscent(GPSCoordinate source) {
        return Math.max(0, this.getAltitudeDifference(source));
    }
 
    public double getDescent(GPSCoordinate source) {
        return Math.max(0, -this.getAltitudeDifference(source));
    }
 
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
 
        GPSCoordinate that = (GPSCoordinate) o;
 
        if (Double.compare(that.getLatitude(), getLatitude()) != 0) return false;
        if (Double.compare(that.getLongitude(), getLongitude()) != 0) return false;
        return Double.compare(that.getAltitude(), getAltitude()) == 0;
 
    }
 
    @Override
    public int hashCode() {
        int result;
        long temp;
        temp = Double.doubleToLongBits(getLatitude());
        result = (int) (temp ^ (temp >>> 32));
        temp = Double.doubleToLongBits(getLongitude());
        result = 31 * result + (int) (temp ^ (temp >>> 32));
        temp = Double.doubleToLongBits(getAltitude());
        result = 31 * result + (int) (temp ^ (temp >>> 32));
        return result;
    }
 
    private String formatLocation(double value) {
        return new BigDecimal(value).setScale(8, RoundingMode.HALF_UP).toPlainString();
    }
 
    @NonNull
    @Override
    public String toString() {
        return "lon: " + formatLocation(longitude) + ", lat: " + formatLocation(latitude) + ", alt: " + formatLocation(altitude) + "m";
    }
 
    public static class compareLatitude implements Comparator<GPSCoordinate> {
        @Override
        public int compare(GPSCoordinate trkPt1, GPSCoordinate trkPt2) {
            return Double.compare(trkPt1.getLatitude(), trkPt2.getLatitude());
        }
    }
 
    public static class compareLongitude implements Comparator<GPSCoordinate> {
        @Override
        public int compare(GPSCoordinate trkPt1, GPSCoordinate trkPt2) {
            return Double.compare(trkPt1.getLongitude(), trkPt2.getLongitude());
        }
    }
 
    public static class compareElevation implements Comparator<GPSCoordinate> {
        @Override
        public int compare(GPSCoordinate trkPt1, GPSCoordinate trkPt2) {
            return Double.compare(trkPt1.getAltitude(), trkPt2.getAltitude());
        }
    }
 
}