1 |
/**
|
2 |
* aagtl Advanced Geocaching Tool for Android
|
3 |
* loosely based on agtl by Daniel Fett <fett@danielfett.de>
|
4 |
* Copyright (C) 2010 - 2012 Zoff.cc <aagtl@work.zoff.cc>
|
5 |
*
|
6 |
* This program is free software; you can redistribute it and/or
|
7 |
* modify it under the terms of the GNU General Public License
|
8 |
* version 2 as published by the Free Software Foundation.
|
9 |
*
|
10 |
* This program is distributed in the hope that it will be useful,
|
11 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13 |
* GNU General Public License for more details.
|
14 |
*
|
15 |
* You should have received a copy of the GNU General Public License
|
16 |
* along with this program; if not, write to the
|
17 |
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
18 |
* Boston, MA 02110-1301, USA.
|
19 |
*/
|
20 |
|
21 |
package com.zoffcc.applications.aagtl;
|
22 |
|
23 |
public class Coordinate
|
24 |
{
|
25 |
int RADIUS_EARTH = 6371000;
|
26 |
int FORMAT_D = 0;
|
27 |
int FORMAT_DM = 1;
|
28 |
|
29 |
public double lat;
|
30 |
public double lon;
|
31 |
|
32 |
public static class coords_d_m_m
|
33 |
{
|
34 |
public boolean lat_plus_minus = true; // true = +, false = -
|
35 |
public String lat_sign = "+";
|
36 |
public int lat_deg = 0;
|
37 |
public int lat_min = 0;
|
38 |
public int lat_min_fractions = 0;
|
39 |
|
40 |
public boolean lon_plus_minus = true; // true = +, false = -
|
41 |
public String lon_sign = "+";
|
42 |
public int lon_deg = 0;
|
43 |
public int lon_min = 0;
|
44 |
public int lon_min_fractions = 0;
|
45 |
}
|
46 |
|
47 |
public Coordinate(double lat1, double lon1)
|
48 |
{
|
49 |
this.lat = lat1;
|
50 |
this.lon = lon1;
|
51 |
}
|
52 |
|
53 |
public static Coordinate dm_m_to_d(coords_d_m_m in)
|
54 |
{
|
55 |
Coordinate ret = new Coordinate(0, 0);
|
56 |
|
57 |
ret.lat = (double) in.lat_deg + ((double) in.lat_min / (double) 60) + (((double) in.lat_min_fractions / (double) 60) / (double) 1000);
|
58 |
if (!in.lat_plus_minus)
|
59 |
{
|
60 |
ret.lat = -ret.lat;
|
61 |
}
|
62 |
|
63 |
//System.out.println("lat=" + ret.lat);
|
64 |
//System.out.println("lat_d_m_m=" + in.lat_sign + "" + in.lat_deg + "° " + in.lat_min + "." + in.lat_min_fractions);
|
65 |
|
66 |
ret.lon = (double) in.lon_deg + ((double) in.lon_min / (double) 60) + (((double) in.lon_min_fractions / (double) 60) / (double) 1000);
|
67 |
if (!in.lon_plus_minus)
|
68 |
{
|
69 |
ret.lon = -ret.lon;
|
70 |
}
|
71 |
|
72 |
//System.out.println("lon=" + ret.lon);
|
73 |
//System.out.println("lon_d_m_m=" + in.lon_sign + "" + in.lon_deg + "° " + in.lon_min + "." + in.lon_min_fractions);
|
74 |
return ret;
|
75 |
}
|
76 |
|
77 |
public static Coordinate parse_coord_string(String in)
|
78 |
{
|
79 |
Coordinate c_ = new Coordinate(0, 0);
|
80 |
|
81 |
try
|
82 |
{
|
83 |
coords_d_m_m t = new coords_d_m_m();
|
84 |
// X lat X lon
|
85 |
// N 48° 12.134 E 016° 21.629
|
86 |
String lat = in.split("[EWew]", 2)[0].trim();
|
87 |
t.lat_plus_minus = letter_to_sign(lat.substring(0, 1));
|
88 |
lat = lat.substring(1).trim();
|
89 |
t.lat_deg = Integer.parseInt(lat.split("°", 2)[0]);
|
90 |
t.lat_min = Integer.parseInt(lat.split("°", 2)[1].split("\\.", 2)[0].trim());
|
91 |
t.lat_min_fractions = Integer.parseInt(lat.split("°", 2)[1].split("\\.", 2)[1].trim());
|
92 |
|
93 |
String lon = in.split("[EWew]", 2)[1].trim();
|
94 |
if ((in.contains("E")) || (in.contains("e")))
|
95 |
{
|
96 |
t.lon_plus_minus = letter_to_sign("E");
|
97 |
}
|
98 |
else
|
99 |
{
|
100 |
t.lon_plus_minus = letter_to_sign("W");
|
101 |
}
|
102 |
lon = lon.substring(1).trim();
|
103 |
t.lon_deg = Integer.parseInt(lon.split("°", 2)[0]);
|
104 |
t.lon_min = Integer.parseInt(lon.split("°", 2)[1].split("\\.", 2)[0].trim());
|
105 |
t.lon_min_fractions = Integer.parseInt(lon.split("°", 2)[1].split("\\.", 2)[1].trim());
|
106 |
|
107 |
c_ = Coordinate.dm_m_to_d(t);
|
108 |
}
|
109 |
catch (Exception e)
|
110 |
{
|
111 |
// some parse error
|
112 |
e.printStackTrace();
|
113 |
return null;
|
114 |
}
|
115 |
|
116 |
return c_;
|
117 |
}
|
118 |
|
119 |
public static Boolean letter_to_sign(String letter)
|
120 |
{
|
121 |
if (letter.equalsIgnoreCase("n"))
|
122 |
{
|
123 |
// N = +
|
124 |
return true;
|
125 |
}
|
126 |
else if (letter.equalsIgnoreCase("s"))
|
127 |
{
|
128 |
// S = -
|
129 |
return false;
|
130 |
}
|
131 |
else if (letter.equalsIgnoreCase("e"))
|
132 |
{
|
133 |
// E = +
|
134 |
return true;
|
135 |
}
|
136 |
//else if (letter.equalsIgnoreCase("w"))
|
137 |
//{
|
138 |
// // W = -
|
139 |
//}
|
140 |
// W = -
|
141 |
return false;
|
142 |
}
|
143 |
|
144 |
public coords_d_m_m d_to_dm_m()
|
145 |
{
|
146 |
coords_d_m_m ret = new coords_d_m_m();
|
147 |
|
148 |
ret.lat_deg = (int) Math.abs(this.lat); // before the "."
|
149 |
ret.lat_min = (int) (((double) Math.abs(this.lat) - (double) ret.lat_deg) * (double) 60);
|
150 |
ret.lat_min_fractions = (int) (((((double) Math.abs(this.lat) - (double) ret.lat_deg) * (double) 60) - (double) ret.lat_min) * 1000);
|
151 |
if (this.lat >= 0)
|
152 |
{
|
153 |
ret.lat_sign = "+";
|
154 |
ret.lat_plus_minus = true;
|
155 |
}
|
156 |
else
|
157 |
{
|
158 |
ret.lat_sign = "-";
|
159 |
ret.lat_plus_minus = false;
|
160 |
}
|
161 |
//System.out.println("lat=" + this.lat);
|
162 |
//System.out.println("lat_d_m_m=" + ret.lat_sign + "" + ret.lat_deg + "° " + ret.lat_min + "." + ret.lat_min_fractions);
|
163 |
|
164 |
ret.lon_deg = (int) Math.abs(this.lon); // before the "."
|
165 |
ret.lon_min = (int) (((double) Math.abs(this.lon) - (double) ret.lon_deg) * (double) 60);
|
166 |
ret.lon_min_fractions = (int) (((((double) Math.abs(this.lon) - (double) ret.lon_deg) * (double) 60) - (double) ret.lon_min) * 1000);
|
167 |
if (this.lon >= 0)
|
168 |
{
|
169 |
ret.lon_sign = "+";
|
170 |
ret.lon_plus_minus = true;
|
171 |
}
|
172 |
else
|
173 |
{
|
174 |
ret.lon_sign = "-";
|
175 |
ret.lon_plus_minus = false;
|
176 |
}
|
177 |
//System.out.println("lon=" + this.lon);
|
178 |
//System.out.println("lon_d_m_m=" + ret.lon_sign + "" + ret.lon_deg + "° " + ret.lon_min + "." + ret.lon_min_fractions);
|
179 |
|
180 |
return ret;
|
181 |
}
|
182 |
|
183 |
public double distance_to(Coordinate target)
|
184 |
{
|
185 |
double dlat = Math.pow(Math.sin(Math.toRadians(target.lat - this.lat) / 2), 2);
|
186 |
double dlon = Math.pow(Math.sin(Math.toRadians(target.lon - this.lon) / 2), 2);
|
187 |
double a = dlat + Math.cos(Math.toRadians(this.lat)) * Math.cos(Math.toRadians(target.lat)) * dlon;
|
188 |
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
|
189 |
return this.RADIUS_EARTH * c;
|
190 |
|
191 |
/*
|
192 |
*
|
193 |
*
|
194 |
* def distance_to_manual (src, target):
|
195 |
* dlat = math.pow(math.sin(math.radians(target.lat-src.lat) / 2), 2)
|
196 |
* dlon = math.pow(math.sin(math.radians(target.lon-src.lon) / 2), 2)
|
197 |
* a = dlat + math.cos(math.radians(src.lat)) * math.cos(math.radians(target.lat)) * dlon;
|
198 |
* c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a));
|
199 |
* return Coordinate.RADIUS_EARTH * c;
|
200 |
* distance_to = distance_to_manual
|
201 |
*/
|
202 |
|
203 |
}
|
204 |
|
205 |
public double bearing_to(Coordinate target)
|
206 |
{
|
207 |
double lat1 = Math.toRadians(this.lat);
|
208 |
double lat2 = Math.toRadians(target.lat);
|
209 |
|
210 |
double dlon = Math.toRadians(target.lon - this.lon);
|
211 |
double y = Math.sin(dlon) * Math.cos(lat2);
|
212 |
double x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(dlon);
|
213 |
double bearing = Math.toDegrees(Math.atan2(y, x));
|
214 |
|
215 |
return (360 + bearing) % 360;
|
216 |
}
|
217 |
}
|