OSDN Git Service

gpx file
[tokyorunners/tokyorunners.git] / src / net / kazhik / android / tokyorunners / MapMode.java
1 package net.kazhik.android.tokyorunners;\r
2 \r
3 import java.text.SimpleDateFormat;\r
4 import java.util.ArrayList;\r
5 import java.util.Date;\r
6 import java.util.List;\r
7 \r
8 import android.app.AlertDialog;\r
9 import android.app.Dialog;\r
10 import android.content.BroadcastReceiver;\r
11 import android.content.Context;\r
12 import android.content.DialogInterface;\r
13 import android.content.Intent;\r
14 import android.content.IntentFilter;\r
15 import android.content.SharedPreferences;\r
16 import android.graphics.Canvas;\r
17 import android.graphics.Color;\r
18 import android.graphics.Paint;\r
19 import android.graphics.Path;\r
20 import android.graphics.Point;\r
21 import android.graphics.drawable.Drawable;\r
22 import android.os.Bundle;\r
23 import android.preference.PreferenceManager;\r
24 import android.util.Log;\r
25 import android.view.KeyEvent;\r
26 import android.view.Menu;\r
27 import android.view.MenuItem;\r
28 import android.view.View;\r
29 import android.view.View.OnLongClickListener;\r
30 import android.widget.Toast;\r
31 \r
32 import com.google.android.maps.GeoPoint;\r
33 import com.google.android.maps.ItemizedOverlay;\r
34 import com.google.android.maps.MapActivity;\r
35 import com.google.android.maps.MapController;\r
36 import com.google.android.maps.MapView;\r
37 import com.google.android.maps.MyLocationOverlay;\r
38 import com.google.android.maps.Overlay;\r
39 import com.google.android.maps.OverlayItem;\r
40 import com.google.android.maps.Projection;\r
41 \r
42 public class MapMode extends MapActivity {\r
43 \r
44         private MapController m_controller;\r
45         private List<Overlay> m_mapOverlays;\r
46         private SplitPoints m_overlaySplitpoints;\r
47         private GeoPoint m_prevPoint = null;\r
48         private long m_startTime = 0;\r
49 \r
50         public class RunningRoute extends Overlay {\r
51 \r
52                 private GeoPoint m_start;\r
53                 private GeoPoint m_end;\r
54 \r
55                 public RunningRoute(GeoPoint ptStart, GeoPoint ptEnd) {\r
56                         m_start = ptStart;\r
57                         m_end = ptEnd;\r
58                 }\r
59 \r
60                 @Override\r
61                 public void draw(Canvas canvas, MapView mapView, boolean shadow) {\r
62                         super.draw(canvas, mapView, shadow);\r
63 \r
64                         if (!shadow) {\r
65                                 Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);\r
66                                 paint.setStyle(Paint.Style.STROKE);\r
67                                 paint.setAntiAlias(true);\r
68                                 paint.setStrokeWidth(3);\r
69                                 paint.setColor(Color.YELLOW);\r
70 \r
71                                 Path path = new Path();\r
72                                 Projection projection = mapView.getProjection();\r
73                                 Point pxStart = projection.toPixels(m_start, null);\r
74                                 Point pxEnd = projection.toPixels(m_end, null);\r
75                                 path.moveTo(pxStart.x, pxStart.y);\r
76                                 path.lineTo(pxEnd.x, pxEnd.y);\r
77 \r
78                                 canvas.drawPath(path, paint);\r
79                         }\r
80                 }\r
81         }\r
82 \r
83         private class SplitPoints extends ItemizedOverlay<OverlayItem> {\r
84 \r
85                 private ArrayList<OverlayItem> m_splitpoints = new ArrayList<OverlayItem>();\r
86 \r
87                 public SplitPoints(Drawable defaultMarker) {\r
88                         super(boundCenterBottom(defaultMarker));\r
89                 }\r
90 \r
91                 public void addSplitpoint(OverlayItem overlay) {\r
92                         m_splitpoints.add(overlay);\r
93                         populate();\r
94                 }\r
95 \r
96                 @Override\r
97                 protected OverlayItem createItem(int idx) {\r
98 //                      Log.d(this.getClass().getName(), "createItem(): index: " + idx);\r
99                         return m_splitpoints.get(idx);\r
100                 }\r
101 \r
102                 public void clearItem() {\r
103                         m_splitpoints.clear();\r
104                 }\r
105                 \r
106                 @Override\r
107                 public int size() {\r
108                         return m_splitpoints.size();\r
109                 }\r
110 \r
111                 @Override\r
112                 protected boolean onTap(int i) {\r
113                         Log.d(this.getClass().getName(), "onTap(): index: " + i);\r
114                         if (m_splitpoints.size() > 0) {\r
115                                 Toast.makeText(MapMode.this, m_splitpoints.get(i).getSnippet(),\r
116                                                 Toast.LENGTH_LONG).show();\r
117                         }\r
118                         return true;\r
119                 }\r
120 \r
121                 public void draw(Canvas canvas, MapView mapview, boolean shadow) {\r
122                         super.draw(canvas, mapview, shadow);\r
123 \r
124                 }\r
125         }\r
126 \r
127 \r
128         private BroadcastReceiver m_runningRecordReceiver = new BroadcastReceiver() {\r
129                 @Override\r
130                 public void onReceive(Context context, Intent intent) {\r
131                         String action = intent.getAction();\r
132                         if (action.equals("NewRunningRecord")) {\r
133                                 long recordDate = intent.getLongExtra("RunningRecord", 0);\r
134 \r
135                                 Record rec = TokyoRunners.getRecord(recordDate);\r
136 \r
137                                 if (rec == null) {\r
138                                         ExLog.put("No record: " + recordDate);\r
139                                         return;\r
140                                 }\r
141                                 \r
142                                 GeoPoint gp = new GeoPoint(rec.getLatitudeE6(), rec\r
143                                                 .getLongitudeE6());\r
144                                 m_controller.animateTo(gp);\r
145 \r
146                                 // Route\r
147                                 if (m_prevPoint != null) {\r
148                                         RunningRoute route = new RunningRoute(m_prevPoint, gp);\r
149                                         m_mapOverlays.add(route);\r
150                                 }\r
151                                 // Split point\r
152                                 if (rec.getName().length() > 0) {\r
153                                         drawSplitPoint(gp, rec.getName(), rec.getDate());\r
154                                 }\r
155                                 m_prevPoint = gp;\r
156                         }\r
157 \r
158                 }\r
159         };\r
160 \r
161         @Override\r
162         protected boolean isRouteDisplayed() {\r
163                 return false;\r
164         }\r
165 \r
166         @Override\r
167         public void onResume() {\r
168                 Log.d(this.getClass().getName(), "onResume()");\r
169                 super.onResume();\r
170                 IntentFilter filter = new IntentFilter();\r
171                 filter.addAction("NewRunningRecord");\r
172 \r
173                 registerReceiver(m_runningRecordReceiver, filter);\r
174 \r
175                 // 履歴が読み込まれた場合は再描画\r
176                 Record rec = TokyoRunners.getRecord(m_startTime);\r
177                 if (rec == null) {\r
178                         MapView mapView = (MapView) findViewById(R.id.mapview);\r
179                         drawOverlays(mapView);\r
180                 }\r
181 \r
182 \r
183         }\r
184 \r
185         @Override\r
186         public void onPause() {\r
187                 super.onPause();\r
188 \r
189                 unregisterReceiver(m_runningRecordReceiver);\r
190         }\r
191 \r
192         @Override\r
193         public void onCreate(Bundle savedInstanceState) {\r
194                 super.onCreate(savedInstanceState);\r
195 \r
196                 setContentView(R.layout.map);\r
197 \r
198                 MapView mapView = (MapView) findViewById(R.id.mapview);\r
199                 mapView.setBuiltInZoomControls(true);\r
200 \r
201                 m_controller = mapView.getController();\r
202                 m_controller.setZoom(16);\r
203 \r
204                 m_mapOverlays = mapView.getOverlays();\r
205 \r
206                 Drawable runner = getResources().getDrawable(R.drawable.runner);\r
207                 m_overlaySplitpoints = new SplitPoints(runner);\r
208 \r
209                 drawOverlays(mapView);\r
210         }\r
211         \r
212         private void drawOverlays(MapView mapView) {\r
213                 \r
214                 m_mapOverlays.clear();\r
215                 \r
216                 MyLocationOverlay myLocationOverlay = new MyLocationOverlay(this, mapView);\r
217                 myLocationOverlay.enableMyLocation();\r
218 \r
219                 m_mapOverlays.add(myLocationOverlay);\r
220 \r
221                 m_overlaySplitpoints.clearItem();\r
222                 \r
223                 long recTime = 0;\r
224                 Record rec;\r
225                 while ((rec = TokyoRunners.getNextRecord(recTime)) != null) {\r
226                         if (rec.hasLocation()) {\r
227                                 GeoPoint gp = new GeoPoint(rec.getLatitudeE6(), rec\r
228                                                 .getLongitudeE6());\r
229                                 if (m_prevPoint != null) {\r
230                                         RunningRoute route = new RunningRoute(m_prevPoint, gp);\r
231                                         m_mapOverlays.add(route);\r
232                                 }\r
233                                 m_prevPoint = gp;\r
234 \r
235                                 if (rec.getName().length() > 0) {\r
236                                         drawSplitPoint(gp, rec.getName(), rec.getDate());\r
237                                 }\r
238                         }\r
239                         recTime = rec.getDate().getTime();\r
240                         if (m_startTime == 0) {\r
241                                 m_startTime = recTime;\r
242                         }\r
243                 }\r
244                 \r
245         }\r
246 \r
247         private void drawSplitPoint(GeoPoint gp, String pointName, Date recDate) {\r
248                 SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");\r
249                 String snippet = pointName + "[" + formatter.format(recDate) + "]";\r
250                 OverlayItem ovItem = new OverlayItem(gp, "", snippet);\r
251                 m_overlaySplitpoints.addSplitpoint(ovItem);\r
252                 if (m_overlaySplitpoints.size() == 1) {\r
253                         m_mapOverlays.add(m_overlaySplitpoints);\r
254                 }\r
255         }\r
256 \r
257         public boolean onKeyDown(int keyCode, KeyEvent event) {\r
258                 Log.d(this.getClass().getName(), "onKeyDown():" + keyCode);\r
259                 if (keyCode == KeyEvent.KEYCODE_BACK) {\r
260                         showDialog(Constants.DIALOG_EXIT_ID);\r
261                         return true;\r
262                 }\r
263 \r
264                 return super.onKeyDown(keyCode, event);\r
265 \r
266         }\r
267 \r
268         @Override\r
269         public Dialog onCreateDialog(int id) {\r
270 \r
271                 AlertDialog.Builder builder = new AlertDialog.Builder(this);\r
272                 switch (id) {\r
273                 case Constants.DIALOG_EXIT_ID:\r
274                         builder.setTitle(R.string.dialog_exit_title);\r
275                         builder.setMessage(R.string.dialog_exit_message);\r
276                         builder.setPositiveButton(R.string.dialog_yes,\r
277                                         new DialogInterface.OnClickListener() {\r
278                                                 @Override\r
279                                                 public void onClick(DialogInterface dialog, int which) {\r
280                                                         finish();\r
281 \r
282                                                 }\r
283                                         });\r
284                         builder.setNegativeButton(R.string.dialog_no,\r
285                                         new DialogInterface.OnClickListener() {\r
286                                                 @Override\r
287                                                 public void onClick(DialogInterface dialog, int which) {\r
288                                                         dialog.cancel();\r
289 \r
290                                                 }\r
291                                         });\r
292 \r
293                         break;\r
294                 default:\r
295                         break;\r
296                 }\r
297 \r
298                 AlertDialog alertDialog = builder.create();\r
299                 return alertDialog;\r
300         }\r
301 \r
302         @Override\r
303         public boolean onOptionsItemSelected(MenuItem item) {\r
304                 Intent intent;\r
305                 switch (item.getItemId()) {\r
306                 case Constants.MENU_SETTING:\r
307                         intent = new Intent(this, Config.class);\r
308                         intent.setAction(Intent.ACTION_VIEW);\r
309                         startActivity(intent);\r
310                         break;\r
311                 default:\r
312                         break;\r
313                 }\r
314                 return false;\r
315         }\r
316 \r
317 }\r