compute distance works
[WhereAmI.git] / src / org / average / whereami / LastLocation.java
1 package org.average.whereami;
2
3 import org.average.whereami.CredentialStore;
4
5 import java.lang.Math;
6
7 import com.google.api.client.extensions.android2.AndroidHttp;
8 import com.google.api.client.auth.oauth2.draft10.AccessTokenResponse;
9 import com.google.api.client.googleapis.auth.oauth2.draft10.GoogleAccessProtectedResource;
10 import com.google.api.client.http.HttpResponseException;
11 import com.google.api.client.http.HttpTransport;
12 import com.google.api.client.http.javanet.NetHttpTransport;
13 import com.google.api.client.json.JsonFactory;
14 import com.google.api.client.json.jackson.JacksonFactory;
15 import com.google.api.services.latitude.Latitude;
16 import com.google.api.services.latitude.LatitudeRequest;
17 import com.google.api.services.latitude.model.Location;
18
19 import android.content.Context;
20 import android.content.SharedPreferences;
21 import android.content.res.Resources;
22 import android.util.Log;
23
24 public final class LastLocation extends Oracle {
25
26         final String TAG = getClass().getName();
27
28         private Latitude latitude;
29
30         private String[] loc_names;
31         private String[] loc_lats;
32         private String[] loc_lons;
33         private String[] loc_dists;
34
35         public LastLocation(final Resources res, final CredentialStore store) {
36                 loc_names = res.getStringArray(R.array.loc_names);
37                 loc_lats = res.getStringArray(R.array.loc_lats);
38                 loc_lons = res.getStringArray(R.array.loc_lons);
39                 loc_dists = res.getStringArray(R.array.loc_dists);
40
41                 HttpTransport transport = AndroidHttp.newCompatibleTransport();
42                 JsonFactory jsonFactory = new JacksonFactory();
43                 AccessTokenResponse token = store.read();
44                 Log.v(TAG, "tokens - access: \"" + token.accessToken +
45                         "\", refresh: \"" + token.refreshToken +
46                         "\", client_id: \"" + ClientCredentials.CLIENT_ID +
47                         "\", client_secret: \"" +
48                                         ClientCredentials.CLIENT_SECRET +
49                         "\"");
50                 GoogleAccessProtectedResource accessProtectedResource =
51                         new GoogleAccessProtectedResource(
52                                 token.accessToken,
53                                 transport, jsonFactory,
54                                 ClientCredentials.CLIENT_ID,
55                                 ClientCredentials.CLIENT_SECRET,
56                                 token.refreshToken)
57                                 {
58                                         @Override
59                                         public void onAccessToken(
60                                                         String accessToken) {
61                                                 Log.v(TAG, "Update access token to \"" + accessToken + "\"");
62                                                 store.updateAccessToken(
63                                                         accessToken);
64                                         }
65                                 }
66                                 ;
67                 Latitude.Builder lbldr = Latitude.builder(transport,
68                                                                 jsonFactory);
69                 lbldr.setHttpRequestInitializer(accessProtectedResource);
70                 lbldr.setApplicationName("WhereAmI/1.0");
71                 latitude = lbldr.build();
72         }
73
74         @Override
75         public final String getResult() {
76                 try {
77                         Log.v(TAG, "entering getResult");
78                         Latitude.CurrentLocation.Get request =
79                                 latitude.currentLocation().get();
80                         request.setGranularity("best");
81                         Location cloc = request.execute();
82                         Double lat = Double.parseDouble(
83                                         cloc.getLatitude().toString());
84                         Double lon = Double.parseDouble(
85                                         cloc.getLongitude().toString());
86                         Long tsm = Long.parseLong(
87                                         cloc.getTimestampMs().toString());
88                         return locationMessage(lat, lon, tsm);
89                 } catch (Exception ex) {
90                         Log.v(TAG, "exception in getResult: " + ex);
91                         ex.printStackTrace();
92                         return ex.getMessage();
93                 }
94         }
95
96         private String locationMessage(Double lat, Double lon, Long tsm) {
97                 Log.v(TAG, "entering locationMessage(" + lat +
98                                 "," + lon + "," + tsm + ")");
99                 String locmsg = "<UNSET>";
100                 for (int i = 0; i < loc_names.length; i++) {
101                         Double dist = haversine(lat, lon,
102                                         Double.parseDouble(loc_lats[i]),
103                                         Double.parseDouble(loc_lons[i]));
104                         Log.v(TAG, "Dist from " + loc_names[i] +
105                                 " is " + dist);
106                         if ((loc_dists[i] == "0") ||
107                             (dist < Double.parseDouble(loc_dists[i]))) {
108                                 locmsg = loc_names[i];
109                                 break;
110                         }
111                 }
112                 return locmsg;
113         }
114
115         private Double toRad(Double deg) {
116                 return deg * 3.14159265 / 180;
117         }
118
119         private Double haversine(Double lat1, Double lon1,
120                                 Double lat2, Double lon2) {
121                 Double dlat = toRad(lat2 - lat1);
122                 Double dlon = toRad(lon2 - lon1);
123                 Double a = Math.sin(dlat / 2) * Math.sin(dlat / 2) +
124                         Math.sin(dlon / 2) * Math.sin(dlon / 2) *
125                         Math.cos(toRad(lat1)) * Math.cos(toRad(lat2));
126                 Double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
127                 return 6371 * c;
128         }
129 }