source: other-projects/tipple-android/trunk/src/org/greenstone/android/tipple/TippleLocationListener.java@ 23977

Last change on this file since 23977 was 23977, checked in by davidb, 13 years ago

Initial set of files for the Tipple project, to be run on an Android device

File size: 9.4 KB
Line 
1package org.greenstone.android.tipple;
2
3import java.io.File;
4import java.text.DecimalFormat;
5import java.util.ArrayList;
6import java.util.HashMap;
7import java.util.HashSet;
8import java.util.Set;
9
10import org.greenstone.android.tipple.TipLocation;
11
12import org.mapsforge.android.maps.ArrayItemizedMarkerOverlay;
13import org.mapsforge.android.maps.CircleOverlay;
14import org.mapsforge.android.maps.GeoPoint;
15import org.mapsforge.android.maps.MapController;
16import org.mapsforge.android.maps.MapView;
17import org.mapsforge.android.maps.OverlayMarkerItem;
18import org.mapsforge.android.maps.OverlayTextAudioItem;
19import org.mapsforge.android.maps.Projection;
20
21import android.app.Activity;
22import android.content.Context;
23import android.graphics.Color;
24import android.graphics.Paint;
25import android.graphics.Point;
26import android.graphics.drawable.Drawable;
27import android.location.Location;
28import android.location.LocationListener;
29import android.media.MediaPlayer;
30import android.os.Bundle;
31import android.os.Vibrator;
32
33import android.widget.TextView;
34
35public class TippleLocationListener implements LocationListener
36{
37 public static Location lastKnownLocation = null;
38
39 protected ArrayList<TipLocation> locations_;
40
41 protected Activity activity_;
42 protected MapView map_view_;
43 protected TextView text_view_;
44 protected TipLocationManager tip_location_manager_;
45
46 protected MapController map_controller_;
47 protected CircleOverlay here_overlay_;
48 protected ArrayItemizedMarkerOverlay highlight_marker_overlay_;
49
50 protected Vibrator vibrator_;
51
52 protected Set<TipLocation> curr_locations_;
53 protected Set<TipLocation> prev_locations_;
54 HashMap<Integer,OverlayMarkerItem> highlight_marker_hash_;
55
56
57 public TippleLocationListener(Activity activity, MapView map_view,TextView text_view,
58 TipLocationManager place_location_manager,
59 ArrayList<TipLocation> locations)
60 {
61 activity_ = activity;
62 map_view_ = map_view;
63 text_view_ = text_view;
64
65 tip_location_manager_ = place_location_manager;
66 locations_ = locations;
67
68 // location aware
69 Paint circleFillPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
70 circleFillPaint.setStyle(Paint.Style.FILL);
71 circleFillPaint.setColor(Color.GREEN);
72 circleFillPaint.setAlpha(64);
73
74 Paint circleOutlinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
75 circleOutlinePaint.setStyle(Paint.Style.STROKE);
76 circleOutlinePaint.setColor(Color.GREEN);
77 circleOutlinePaint.setAlpha(128);
78 circleOutlinePaint.setStrokeWidth(3);
79 here_overlay_ = new CircleOverlay(circleFillPaint, circleOutlinePaint);
80 map_view_.getOverlays().add(here_overlay_);
81
82 Drawable highlightMarker = activity_.getResources().getDrawable(R.drawable.markerhighlight);
83 highlight_marker_overlay_ = new ArrayItemizedMarkerOverlay(highlightMarker,activity);
84 map_view_.getOverlays().add(highlight_marker_overlay_);
85
86 vibrator_ = (Vibrator) activity
87 .getSystemService(Context.VIBRATOR_SERVICE);
88
89 curr_locations_ = new HashSet<TipLocation>();
90 prev_locations_ = new HashSet<TipLocation>();
91 highlight_marker_hash_ = new HashMap<Integer,OverlayMarkerItem>();
92
93 }
94
95 boolean checking_location_ = false;
96
97 synchronized protected boolean getLock()
98 {
99 if (!checking_location_) {
100 checking_location_ = true;
101 }
102
103 return checking_location_;
104 }
105
106 synchronized protected void freeLock()
107 {
108 checking_location_ = false;
109 }
110
111 protected double pointDistance(Point place_point, Point here_point)
112 {
113 double delta_x = place_point.x - here_point.x;
114 double delta_y = place_point.y - here_point.y;
115 double pixel_distance = Math.sqrt((delta_x * delta_x) + (delta_y * delta_y));
116
117 return pixel_distance;
118 }
119
120 Point lastLoggedPoint_ = null;
121
122 protected void updateActiveLocations(Location loc)
123 {
124 // Find out if the current GPS location lies within the boundaries
125 // of any of the tour locations
126 Projection projection = map_view_.getProjection();
127 byte zoom_level = map_view_.getZoomLevel();
128 // byte zoom_level = 10; // work at a reasonable level of scale
129
130 float in_out_gap_meters = 3.0f;
131 float in_out_gap_pixels
132 = projection.metersToPixels(in_out_gap_meters, zoom_level);
133
134 double here_latitude = loc.getLatitude();
135 double here_longitude = loc.getLongitude();
136 GeoPoint here_geopoint = new GeoPoint(here_latitude, here_longitude);
137 Point here_point = projection.toPoint(here_geopoint, null,zoom_level);
138
139 if (lastLoggedPoint_==null) {
140 lastLoggedPoint_ = here_point;
141 TippleActivity.log.optMessage("GPS Location Reading");
142 }
143 else {
144 float far_enough_meters = 3.0f; // 3 meters
145 float far_enough_pixels = projection.metersToPixels(far_enough_meters, zoom_level);
146 if (pointDistance(here_point,lastLoggedPoint_)>far_enough_pixels) {
147 TippleActivity.log.optMessage("GPS Location Reading");
148 }
149 }
150
151 for (int i=0; i<locations_.size(); i++) {
152
153 TipLocation place = locations_.get(i);
154
155 double place_latitude = place.getLatitude();
156 double place_longitude = place.getLongitude();
157 double radius_meters = place.getRadiusKM() * 1000.0;
158
159 GeoPoint place_geopoint = new GeoPoint(place_latitude,place_longitude);
160 Point place_point = projection.toPoint(place_geopoint, null,zoom_level);
161
162 float radius_pixel_distance = projection.metersToPixels((float) radius_meters, zoom_level);
163
164 double delta_x = place_point.x - here_point.x;
165 double delta_y = place_point.y - here_point.y;
166 double pixel_distance = Math.sqrt((delta_x * delta_x) + (delta_y * delta_y));
167
168 double outside_pixel_distance = radius_pixel_distance + in_out_gap_pixels;
169 double inside_pixel_distance = radius_pixel_distance;
170
171 if (pixel_distance <= inside_pixel_distance) {
172
173 if (!curr_locations_.contains(place)) {
174 // User has entered new location on tour
175
176 curr_locations_.add(place);
177 vibrator_.vibrate(1000);
178 Bundle bundle = new Bundle();
179 bundle.putString("placeName", place.getTitle());
180
181 boolean visited_previously = prev_locations_.contains(place);
182 tip_location_manager_.textToSpeechToLocation(place,visited_previously);
183
184 OverlayTextAudioItem here_marker_item
185 = (OverlayTextAudioItem) TipLocationManager.itemizedMarkerOverlayArrayList.get(i);
186
187 GeoPoint dm_geopoint = here_marker_item.getPoint();
188 String title = here_marker_item.getTitle();
189
190 //itemized_overlay.onTap(i);
191
192 OverlayMarkerItem highlight_marker_item = new OverlayMarkerItem(dm_geopoint,title);
193 highlight_marker_hash_.put(i,highlight_marker_item);
194 highlight_marker_overlay_.addOverlay(highlight_marker_item);
195
196
197 try {
198 // Cue up audio alert
199 String audio_dir = TippleActivity.audioDirectory;
200 File alert_file = new File(audio_dir, "BeepMorseSonar.wav");
201 String alert_filename = alert_file.getAbsolutePath();
202
203 MediaPlayer mp = new MediaPlayer();
204 mp.setDataSource(alert_filename);
205 mp.prepare();
206 mp.start();
207 }
208 catch (Exception e) {
209 System.err.println("Failed to play audio alert for active GPS location");
210 e.printStackTrace();
211 }
212
213 // Now record the fact we've been here
214 prev_locations_.add(place);
215
216 }
217
218 }
219
220 else if (pixel_distance >= outside_pixel_distance) {
221
222 if (curr_locations_.contains(place)) {
223 curr_locations_.remove(place);
224
225 // TipLocationManager.itemizedMarkerOverlay.unTap();
226
227 OverlayMarkerItem highlight_marker_item = highlight_marker_hash_.remove(i);
228 highlight_marker_overlay_.removeOverlay(highlight_marker_item);
229 }
230 }
231 }
232 }
233 @Override
234 public void onLocationChanged(Location loc)
235 {
236 if (loc != null) {
237
238 //System.err.println("TipLocationListener::onLocationChaged -- start");
239 lastKnownLocation = loc;
240
241 if (getLock()) {
242 updateActiveLocations(loc);
243 freeLock();
244 }
245
246 DecimalFormat truncPlaces = new DecimalFormat("0.0000000000");
247 double longitude = loc.getLongitude();
248 double latitude = loc.getLatitude();
249
250 String trunc_long = truncPlaces.format(longitude);
251 String trunc_lat = truncPlaces.format(latitude);
252
253 String text_mess = "(Long,Lat): (" + trunc_long + "," + trunc_lat + ")";
254 text_view_.setText(text_mess);
255
256 // location aware
257 GeoPoint point = new GeoPoint(latitude, longitude);
258 here_overlay_.setCircleData(point, loc.getAccuracy());
259
260 // Use the following line if you want to map to auto center on the GPS location
261 boolean centre_on_gps_loc = TippleActivity.sharedPreferences.getBoolean("centreOnGPSLoc", false);
262 if (centre_on_gps_loc) {
263 MapController map_controller = map_view_.getController();
264 if (map_controller != null) {
265 map_controller.setCenter(point);
266 }
267 }
268
269 //System.err.println("TipLocationListener::onLocationChaged -- finished");
270 }
271 }
272
273 @Override
274 public void onProviderDisabled(String provider)
275 {
276 // TODO Auto-generated method stub
277 System.err.println("TipLocationListener::onProviderDisabled()");
278 }
279
280 @Override
281 public void onProviderEnabled(String provider)
282 {
283 // TODO Auto-generated method stub
284 System.err.println("TipLocationListener::onProviderEnabled()");
285
286 }
287
288 @Override
289 public void onStatusChanged(String provider, int status, Bundle extras)
290 {
291 // TODO Auto-generated method stub
292 System.err.println("TipLocationListener::onStatusChanged()");
293
294 }
295
296}
Note: See TracBrowser for help on using the repository browser.