source: other-projects/tipple-android/trunk-restructured/workspace/tipple-lib/src/org/greenstone/android/tipple/base/TipLocationManager.java@ 24807

Last change on this file since 24807 was 24807, checked in by davidb, 12 years ago

Reloating base files into 'base' package

  • Property svn:executable set to *
File size: 14.4 KB
Line 
1package org.greenstone.android.tipple.base;
2
3import java.io.File;
4import java.io.FileInputStream;
5import java.util.ArrayList;
6import java.util.HashMap;
7import java.util.List;
8
9import javax.xml.parsers.SAXParser;
10import javax.xml.parsers.SAXParserFactory;
11
12import org.greenstone.android.tipple.R;
13import org.mapsforge.android.maps.ArrayItemizedTextAudioOverlay;
14import org.mapsforge.android.maps.CirclesOverlay;
15import org.mapsforge.android.maps.GeoPoint;
16import org.mapsforge.android.maps.MapView;
17import org.mapsforge.android.maps.Overlay;
18import org.mapsforge.android.maps.OverlayItem;
19import org.mapsforge.android.maps.OverlayTextAudioItem;
20import org.mapsforge.android.maps.RouteOverlayResetable;
21import org.xml.sax.InputSource;
22import org.xml.sax.XMLReader;
23
24import android.app.Activity;
25import android.graphics.Color;
26import android.graphics.DashPathEffect;
27import android.graphics.Paint;
28import android.graphics.drawable.Drawable;
29import android.speech.tts.TextToSpeech;
30import android.speech.tts.TextToSpeech.OnUtteranceCompletedListener;
31import android.util.Log;
32
33public class TipLocationManager
34{
35 Activity activity_;
36 AudioPlayerView audio_player_view_;
37 TextToSpeech tts_;
38
39 public static CirclesOverlay circlesOverlay=null;
40 public static ArrayItemizedTextAudioOverlay itemizedMarkerOverlay;
41 public static ArrayList<OverlayItem> itemizedMarkerOverlayArrayList;
42 public static ArrayList<GeoPoint> circlesOverlayGeoPoints;
43 public static ArrayList<Integer> circlesOverlayRadii;
44
45 public static RouteOverlayResetable routeOverlay=null;
46 public static ArrayItemizedTextAudioOverlay routeMarkerOverlay;
47 public static GeoPoint[] routeOverlayArray;
48
49 public static ArrayList<OverlayItem> routeMarkerOverlayArrayList;
50
51 public static String prevVisitedFilename;
52
53 TipLocationManager(Activity activity, AudioPlayerView audio_player_view,
54 TextToSpeech tts)
55 {
56 activity_ = activity;
57 audio_player_view_ = audio_player_view;
58 tts_ = tts;
59
60
61
62 }
63
64 protected void createLogRouteLocationsOverlay(MapView mapView,ArrayList<TipLocation> locations)
65 {
66 Paint fillPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
67 fillPaint.setStyle(Paint.Style.STROKE);
68 fillPaint.setColor(Color.BLUE);
69 fillPaint.setAlpha(160);
70 fillPaint.setStrokeWidth(7);
71 fillPaint.setStrokeCap(Paint.Cap.BUTT);
72 fillPaint.setStrokeJoin(Paint.Join.ROUND);
73 fillPaint.setPathEffect(new DashPathEffect(new float[] { 20, 20 }, 0));
74
75 Paint outlinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
76 outlinePaint.setStyle(Paint.Style.STROKE);
77 outlinePaint.setColor(Color.BLUE);
78 outlinePaint.setAlpha(96);
79 outlinePaint.setStrokeWidth(7);
80 outlinePaint.setStrokeCap(Paint.Cap.BUTT);
81 outlinePaint.setStrokeJoin(Paint.Join.ROUND);
82
83 Drawable defaultMarker = activity_.getResources().getDrawable(R.drawable.routemarker);
84
85 if (routeOverlay==null) {
86 routeOverlay = new RouteOverlayResetable(fillPaint, outlinePaint);
87 routeMarkerOverlay = new ArrayItemizedTextAudioOverlay(defaultMarker,activity_,tts_);
88 routeMarkerOverlayArrayList = new ArrayList<OverlayItem>();
89
90 }
91 // This one needs to be done again, incase it is of a different size
92 routeOverlayArray = new GeoPoint[locations.size()];
93
94 for (int i=0; i<locations.size(); i++) {
95 TipLocation location = locations.get(i);
96 double latitude = location.getLatitude();
97 double longitude = location.getLongitude();
98 String title = location.getTitle();
99 String text = location.getText();
100 String tts_text = location.getTTSText();
101 GeoPoint geoPoint = new GeoPoint(latitude,longitude);
102
103 routeOverlayArray[i] = geoPoint;
104
105 if (title.startsWith("Manual")) {
106 // ItemizedOverlay => display marker with text for info pop-up window
107 OverlayTextAudioItem overlayItem = new OverlayTextAudioItem(geoPoint, title, text, tts_text);
108
109 //routeMarkerOverlay.addOverlay(overlayItem);
110 routeMarkerOverlayArrayList.add(overlayItem);
111 }
112 }
113
114 //routeOverlay.setRouteData(routeOverlayArray);
115
116 // Only add in if not already present
117 List<Overlay> overlays = mapView.getOverlays();
118 if (!overlays.contains(routeOverlay)) {
119 overlays.add(routeOverlay);
120 }
121 if (!overlays.contains(routeMarkerOverlay)) {
122 overlays.add(routeMarkerOverlay);
123 }
124 }
125
126 protected void addLogRouteLocations(MapView mapView)
127 {
128 for (int i=0; i<routeMarkerOverlayArrayList.size(); i++) {
129
130 OverlayItem overlay_item = routeMarkerOverlayArrayList.get(i);
131 routeMarkerOverlay.addOverlay(overlay_item);
132 }
133
134 routeOverlay.setRouteData(routeOverlayArray);
135
136 mapView.invalidate();
137
138 }
139
140 protected void removeLogRouteLocations(MapView mapView)
141 {
142 for (int i=0; i<routeMarkerOverlayArrayList.size(); i++) {
143
144 OverlayItem overlay_item = routeMarkerOverlayArrayList.get(i);
145 routeMarkerOverlay.removeOverlay(overlay_item);
146
147 }
148
149 routeOverlay.reset();
150
151 mapView.invalidate();
152 }
153
154 protected void createTourLocationsOverlay(MapView mapView, ArrayList<TipLocation> locations)
155 {
156 Paint circleFillPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
157 circleFillPaint.setStyle(Paint.Style.FILL);
158 circleFillPaint.setColor(Color.BLUE);
159 circleFillPaint.setAlpha(64);
160
161 Paint circleOutlinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
162 circleOutlinePaint.setStyle(Paint.Style.STROKE);
163 circleOutlinePaint.setColor(Color.BLUE);
164 circleOutlinePaint.setAlpha(128);
165 circleOutlinePaint.setStrokeWidth(3);
166
167 Drawable defaultMarker = activity_.getResources().getDrawable(R.drawable.marker);
168
169 if (circlesOverlay==null) {
170 circlesOverlay = new CirclesOverlay(circleFillPaint, circleOutlinePaint);
171 circlesOverlayGeoPoints = new ArrayList<GeoPoint>();
172 circlesOverlayRadii = new ArrayList<Integer>();
173
174 itemizedMarkerOverlay = new ArrayItemizedTextAudioOverlay(defaultMarker,activity_,tts_);
175 itemizedMarkerOverlayArrayList = new ArrayList<OverlayItem>();
176 }
177
178 for (int i=0; i<locations.size(); i++) {
179 TipLocation location = locations.get(i);
180 double latitude = location.getLatitude();
181 double longitude = location.getLongitude();
182 int radius = (int)Math.round(1000.0 * location.getRadiusKM());
183 String title = location.getTitle();
184 String text = location.getText();
185 String tts_text = location.getTTSText();
186 GeoPoint geoPoint = new GeoPoint(latitude,longitude);
187
188 // CirclesOverlay => Highlight location with a circle showing catchment radius
189 //circlesOverlay.addCircleData(geoPoint, radius);
190 circlesOverlayGeoPoints.add(geoPoint);
191 circlesOverlayRadii.add(radius);
192
193 // ItemizedOverlay => display marker with text for info pop-up window
194 OverlayTextAudioItem overlayItem = new OverlayTextAudioItem(geoPoint, title, text, tts_text);
195
196 //itemizedMarkerOverlay.addOverlay(overlayItem);
197 itemizedMarkerOverlayArrayList.add(overlayItem);
198 }
199
200 // Only add in if not already present
201 List<Overlay> overlays = mapView.getOverlays();
202 if (!overlays.contains(itemizedMarkerOverlay)) {
203 overlays.add(itemizedMarkerOverlay);
204 }
205 if (!overlays.contains(circlesOverlay)) {
206 overlays.add(circlesOverlay);
207 }
208 }
209
210
211 protected void addTourLocations(MapView mapView)
212 {
213 for (int i=0; i<itemizedMarkerOverlayArrayList.size(); i++) {
214
215 OverlayItem overlay_item = itemizedMarkerOverlayArrayList.get(i);
216 itemizedMarkerOverlay.addOverlay(overlay_item);
217
218 GeoPoint geo_point = circlesOverlayGeoPoints.get(i);
219 int radius = circlesOverlayRadii.get(i);
220 circlesOverlay.addCircleData(geo_point, radius);
221 }
222
223 mapView.invalidate();
224 }
225
226 protected void removeTourLocations(MapView mapView)
227 {
228 for (int i=0; i<itemizedMarkerOverlayArrayList.size(); i++) {
229
230 OverlayItem overlay_item = itemizedMarkerOverlayArrayList.get(i);
231 itemizedMarkerOverlay.removeOverlay(overlay_item);
232 }
233
234 circlesOverlay.reset();
235
236 mapView.invalidate();
237
238 }
239
240 protected ArrayList<HashMap<String,String>> parseXMLToHashMapArrayList(String xml_filename,String lock_on_element)
241 {
242 ArrayList<HashMap<String,String>> hashmap_list = null;
243
244 try {
245
246 // set up XML parser
247 SAXParserFactory spf = SAXParserFactory.newInstance();
248 SAXParser sp = spf.newSAXParser();
249 XMLReader xr = sp.getXMLReader();
250
251 // Create handler that maps XML Tags within <Location> to a hashmap
252 XMLToHashmapHandler xmlTourHandler = new XMLToHashmapHandler(lock_on_element);
253 xr.setContentHandler(xmlTourHandler);
254
255 File tour_file = new File(xml_filename);
256 FileInputStream fis = new FileInputStream(tour_file);
257
258 InputSource is = new InputSource(fis);
259 xr.parse(is);
260
261 // get the HashMap List that results from parsing the file
262 hashmap_list = xmlTourHandler.getHashmapList();
263
264
265 } catch (Exception e) {
266 e.printStackTrace();
267 }
268
269 return hashmap_list;
270 }
271 public ArrayList<TipLocation> loadTour(String tour_filename)
272 {
273 ArrayList<HashMap<String,String>> location_hashmap_list
274 = parseXMLToHashMapArrayList(tour_filename,"Location");
275
276 if (location_hashmap_list != null) {
277 Log.d("TippleActivity::loadTour()", "XML Tour File Parsed");
278 }
279
280 ArrayList<TipLocation> locations = new ArrayList<TipLocation>();
281
282 for (int i=0; i<location_hashmap_list.size(); i++) {
283 HashMap<String,String> location_hashmap = location_hashmap_list.get(i);
284
285 TipLocation location = new TipLocation(location_hashmap);
286 locations.add(location);
287 }
288
289 return locations;
290 }
291
292 protected ArrayList<TipLocation> loadUserTrail(String log_filename)
293 {
294 ArrayList<HashMap<String,String>> logentry_hashmap_list
295 = parseXMLToHashMapArrayList(log_filename,"LogEntry");
296
297 ArrayList<TipLocation> locations = new ArrayList<TipLocation>();
298
299 if (logentry_hashmap_list != null) {
300 Log.d("TippleActivity::loadUserTrail()", "XML User Activity Log File Parsed");
301
302
303 for (int i=0; i<logentry_hashmap_list.size(); i++) {
304 HashMap<String,String> logentry_hashmap = logentry_hashmap_list.get(i);
305
306 HashMap<String,String> location_hashmap = new HashMap<String,String>();
307 location_hashmap.put("longitude",logentry_hashmap.get("longitude"));
308 location_hashmap.put("latitude",logentry_hashmap.get("latitude"));
309 location_hashmap.put("radius",logentry_hashmap.get("accuracy"));
310 location_hashmap.put("title",logentry_hashmap.get("action"));
311 location_hashmap.put("text",logentry_hashmap.get("message"));
312
313 TipLocation location = new TipLocation(location_hashmap);
314 locations.add(location);
315 }
316 }
317
318 return locations;
319 }
320
321
322 protected String SyncSynthesizeToFile(String text, String id, String root_utterance)
323 {
324 String audio_dir = TippleActivity.audioDirectory;
325 File tts_file = new File(audio_dir, id+"-"+root_utterance+"-TTS.wav");
326 String tts_filename = tts_file.getAbsolutePath();
327
328 if (tts_file.exists()) {
329 // already synthesized this
330 return tts_filename;
331 }
332
333 // Rendering the supplied text of the id+utterance derived WAV file
334 HashMap<String, String> hashRender = new HashMap<String, String>();
335 hashRender.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, text);
336
337 String UTTERANCE = root_utterance+"-utterance";
338
339 hashRender.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, UTTERANCE);
340 UtteranceWaitListener listener = new UtteranceWaitListener(UTTERANCE);
341 tts_.setOnUtteranceCompletedListener(listener);
342
343 tts_.synthesizeToFile(text, hashRender, tts_filename);
344
345 try {
346 listener.waitForComplete();
347 }
348 catch (Exception e) {
349 e.printStackTrace();
350 return null;
351 }
352
353 return tts_filename;
354 }
355
356 boolean genPrevVisited = true;
357
358 public boolean textToSpeechToLocation(TipLocation tip_location, boolean visited_previously)
359 {
360 if (genPrevVisited) {
361 prevVisitedFilename = SyncSynthesizeToFile("Previously visited.","Previously-visited","cue");
362 System.err.println("** Prev visisted file = " + prevVisitedFilename);
363 genPrevVisited = false;
364 }
365
366 String title = tip_location.getTitle();
367 String text = tip_location.getText();
368 String id = tip_location.getID();
369
370 String title_filename = SyncSynthesizeToFile(title,id,"title");
371 String text_filename = SyncSynthesizeToFile(text,id,"text");
372
373 if ((title_filename!=null) && (text_filename!=null)) {
374 String audio_dir = TippleActivity.audioDirectory;
375 File ding_file = new File(audio_dir, "DingExtended.wav");
376 String ding_filename = ding_file.getAbsolutePath();
377
378 if (audio_player_view_.addAudio(id)) {
379 TippleActivity.log.optMessage("Queue Audio",title);
380 audio_player_view_.queueAudio(title_filename,id,title,visited_previously);
381 audio_player_view_.queueAudio(text_filename,id,text);
382 audio_player_view_.queueAudio(ding_filename,id,"[Audio Bing]");
383
384 audio_player_view_.updateTextViewIfHeadIsNewLocation();
385 }
386 }
387
388 return true;
389 }
390
391
392 public static void stopOverlayThreads()
393 {
394 if (circlesOverlay!=null) {
395 circlesOverlay.stop();
396 circlesOverlay = null;
397 }
398
399 if (itemizedMarkerOverlay!=null) {
400 itemizedMarkerOverlay.stop();
401 itemizedMarkerOverlay = null;
402 }
403
404 if (routeOverlay!=null) {
405 routeOverlay.stop();
406 routeOverlay = null;
407 }
408
409 if (routeMarkerOverlay!=null) {
410 routeMarkerOverlay.stop();
411 routeMarkerOverlay = null;
412 }
413 }
414 private static class UtteranceWaitListener implements OnUtteranceCompletedListener {
415 private boolean mIsComplete = false;
416 private final String mExpectedUtterance;
417
418 public UtteranceWaitListener(String expectedUtteranceId) {
419 mExpectedUtterance = expectedUtteranceId;
420 }
421
422 public void onUtteranceCompleted(String utteranceId) {
423 if (mExpectedUtterance.equals(utteranceId)) {
424 synchronized(this) {
425 mIsComplete = true;
426 notify();
427 }
428 }
429 }
430
431 public boolean waitForComplete() throws InterruptedException {
432 if (mIsComplete) {
433 return true;
434 }
435
436 synchronized (this) {
437 int TTS_SPEECH_MAX_WAIT_TIME = 5* 1000;
438 wait(TTS_SPEECH_MAX_WAIT_TIME);
439 return mIsComplete;
440 }
441 }
442
443 }
444}
Note: See TracBrowser for help on using the repository browser.