source: other-projects/tipple-android/tipple-ar/tipple-standalone-hpg/src/org/greenstone/android/tipple/base/TipLocationManager.java@ 26528

Last change on this file since 26528 was 26528, checked in by davidb, 11 years ago

Code developed by the Tipple-AR Smoke and Mirrors team, based on the main tipple trunk

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