/** ** Copyright (c) 2010 Ushahidi Inc ** All rights reserved ** Contact: team@ushahidi.com ** Website: http://www.ushahidi.com ** ** GNU Lesser General Public License Usage ** This file may be used under the terms of the GNU Lesser ** General Public License version 3 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 3 requirements ** will be met: http://www.gnu.org/licenses/lgpl.html. ** ** ** If you have questions regarding the use of this file, please contact ** Ushahidi developers at team@ushahidi.com. ** **/ package com.ushahidi.android.app; import java.util.ArrayList; import java.util.List; import android.app.AlertDialog; import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.database.Cursor; import android.graphics.drawable.Drawable; import android.location.Geocoder; import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.view.ContextMenu; import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.Window; import com.google.android.maps.GeoPoint; import com.google.android.maps.MapActivity; import com.google.android.maps.MapView; import com.google.android.maps.OverlayItem; import com.ushahidi.android.app.checkin.CheckinActivity; import com.ushahidi.android.app.data.Database; import com.ushahidi.android.app.data.IncidentsData; import com.ushahidi.android.app.util.ApiUtils; import com.ushahidi.android.app.util.Util; public class IncidentMap extends MapActivity { private MapView mapView = null; private static final int HOME = Menu.FIRST + 1; private static final int LIST_INCIDENT = Menu.FIRST + 2; private static final int INCIDENT_ADD = Menu.FIRST + 3; private static final int INCIDENT_REFRESH = Menu.FIRST + 4; private static final int SETTINGS = Menu.FIRST + 5; private static final int ABOUT = Menu.FIRST + 6; private static final int GOTOHOME = 0; private static final int ADD_INCIDENTS = 1; private static final int LIST_INCIDENTS = 2; private static final int REQUEST_CODE_SETTINGS = 1; private static final int REQUEST_CODE_ABOUT = 2; private static final int DIALOG_MESSAGE = 0; private static double latitude; private static double longitude; public static Geocoder gc; private List<IncidentsData> mNewIncidents; private List<IncidentsData> mOldIncidents; private Handler mHandler; private Bundle extras; private int id; private String reportLatitude; private String reportLongitude; private String reportTitle; // private String reportDescription; private String reportCategory; private String reportDate; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); setContentView(R.layout.incident_map); mapView = (MapView) findViewById(R.id.map); Preferences.loadSettings(this); mOldIncidents = new ArrayList<IncidentsData>(); mNewIncidents = new ArrayList<IncidentsData>(); mNewIncidents = showIncidents(getString(R.string.all_categories)); mHandler = new Handler(); Bundle incidents = getIntent().getExtras(); if (incidents != null) { extras = incidents.getBundle("report"); id = extras.getInt("id"); reportTitle = extras.getString("title"); // reportDescription = extras.getString("desc"); reportCategory = extras.getString("category"); reportDate = extras.getString("date"); reportLatitude = extras.getString("latitude"); reportLongitude = extras.getString("longitude"); } if (mNewIncidents.size() > 0) { if (id > 0) { if (!Preferences.deploymentLatitude.equals("0.0") && !Preferences.deploymentLatitude.equals("0.0")) { IncidentMap.latitude = Double .parseDouble(Preferences.deploymentLatitude); IncidentMap.longitude = Double .parseDouble(Preferences.deploymentLongitude); } else { IncidentMap.latitude = Double.parseDouble(reportLatitude); IncidentMap.longitude = Double.parseDouble(reportLongitude); } } else { if (!Preferences.deploymentLatitude.equals("0.0") && !Preferences.deploymentLatitude.equals("0.0")) { IncidentMap.latitude = Double .parseDouble(Preferences.deploymentLatitude); IncidentMap.longitude = Double .parseDouble(Preferences.deploymentLongitude); } else { IncidentMap.latitude = Double.parseDouble(mNewIncidents .get(0).getIncidentLocLatitude()); IncidentMap.longitude = Double.parseDouble(mNewIncidents .get(0).getIncidentLocLongitude()); } } mapView.getController().setCenter( getPoint(IncidentMap.latitude, IncidentMap.longitude)); mapView.getController().setZoom(10); mapView.setBuiltInZoomControls(true); mHandler.post(mMarkersOnMap); } else { Util.showToast(IncidentMap.this, R.string.no_reports); } } /** * add marker to the map */ private void populateMap() { Drawable marker = getResources().getDrawable(R.drawable.map_marker_red); marker.setBounds(0, 0, marker.getIntrinsicWidth(), marker.getIntrinsicHeight()); mapView.getOverlays().add(new SitesOverlay(marker, mapView)); } public void onAddReport(View v) { Preferences.loadSettings(IncidentMap.this); if (Preferences.isCheckinEnabled == 1) { Intent checkinActivityIntent = new Intent().setClass( IncidentMap.this, CheckinActivity.class); startActivity(checkinActivityIntent); setResult(RESULT_OK); } else { Intent intent = new Intent(IncidentMap.this, IncidentAdd.class); startActivityForResult(intent, 0); setResult(RESULT_OK); } } // put this stuff in a seperate thread final Runnable mMarkersOnMap = new Runnable() { public void run() { populateMap(); } }; @Override protected boolean isRouteDisplayed() { return (false); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_I) { // Zoom not closer than possible mapView.getController().zoomIn(); return true; } else if (keyCode == KeyEvent.KEYCODE_O) { // Zoom not farer than possible mapView.getController().zoomOut(); return true; } else if (keyCode == KeyEvent.KEYCODE_T) { // Switch to satellite view mapView.setSatellite(true); return true; } else if (keyCode == KeyEvent.KEYCODE_M) { // Switch to satellite view mapView.setSatellite(false); return true; } return super.onKeyDown(keyCode, event); } // get incidents from the db public List<IncidentsData> showIncidents(String by) { Cursor cursor; String title; String description; String location; String categories; String thumbnail; String image; if (by.equals(getString(R.string.all_categories))) cursor = MainApplication.mDb.fetchAllIncidents(); else cursor = MainApplication.mDb.fetchIncidentsByCategories(by); if (cursor.moveToFirst()) { int idIndex = cursor.getColumnIndexOrThrow(Database.INCIDENT_ID); int titleIndex = cursor .getColumnIndexOrThrow(Database.INCIDENT_TITLE); int dateIndex = cursor .getColumnIndexOrThrow(Database.INCIDENT_DATE); int verifiedIndex = cursor .getColumnIndexOrThrow(Database.INCIDENT_VERIFIED); int locationIndex = cursor .getColumnIndexOrThrow(Database.INCIDENT_LOC_NAME); int descIndex = cursor .getColumnIndexOrThrow(Database.INCIDENT_DESC); int categoryIndex = cursor .getColumnIndexOrThrow(Database.INCIDENT_CATEGORIES); int mediaIndex = cursor .getColumnIndexOrThrow(Database.INCIDENT_MEDIA); int imageIndex = cursor.getColumnIndex(Database.INCIDENT_IMAGE); int latitudeIndex = cursor .getColumnIndexOrThrow(Database.INCIDENT_LOC_LATITUDE); int longitudeIndex = cursor .getColumnIndexOrThrow(Database.INCIDENT_LOC_LONGITUDE); do { IncidentsData incidentData = new IncidentsData(); mOldIncidents.add(incidentData); int id = Util.toInt(cursor.getString(idIndex)); incidentData.setIncidentId(id); title = Util.capitalizeString(cursor.getString(titleIndex)); incidentData.setIncidentTitle(title); description = cursor.getString(descIndex); incidentData.setIncidentDesc(description); categories = cursor.getString(categoryIndex); incidentData.setIncidentCategories(categories); location = cursor.getString(locationIndex); incidentData.setIncidentLocLongitude(location); Util.joinString(getString(R.string.report_date), cursor.getString(dateIndex)); incidentData.setIncidentDate(cursor.getString(dateIndex)); thumbnail = cursor.getString(mediaIndex); incidentData.setIncidentThumbnail(thumbnail); image = cursor.getString(imageIndex); incidentData.setIncidentImage(image); incidentData.setIncidentVerified(Util.toInt(cursor .getString(verifiedIndex))); incidentData.setIncidentLocLatitude(cursor .getString(latitudeIndex)); incidentData.setIncidentLocLongitude(cursor .getString(longitudeIndex)); } while (cursor.moveToNext()); } cursor.close(); return mOldIncidents; } /** * Restart the receiving, when we are back on line. */ @Override public void onResume() { super.onResume(); if (mNewIncidents.size() == 0) { mHandler.post(mMarkersOnMap); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) { super.onActivityResult(requestCode, resultCode, intent); } // menu stuff @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { populateMenu(menu); } @Override public boolean onCreateOptionsMenu(Menu menu) { populateMenu(menu); return (super.onCreateOptionsMenu(menu)); } @Override public boolean onOptionsItemSelected(MenuItem item) { // applyMenuChoice(item); return (applyMenuChoice(item) || super.onOptionsItemSelected(item)); } @Override public boolean onContextItemSelected(MenuItem item) { return (applyMenuChoice(item) || super.onContextItemSelected(item)); } protected Dialog onCreateDialog(int id, String message, String title) { switch (id) { case DIALOG_MESSAGE: { AlertDialog dialog = (new AlertDialog.Builder(this)).create(); dialog.setTitle(title); dialog.setMessage(message); dialog.setButton2(getString(R.string.btn_ok), new Dialog.OnClickListener() { public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); dialog.setCancelable(false); return dialog; } } return null; } private void populateMenu(Menu menu) { MenuItem i; i = menu.add(Menu.NONE, HOME, Menu.NONE, R.string.menu_home); i.setIcon(R.drawable.menu_home); i = menu.add(Menu.NONE, INCIDENT_ADD, Menu.NONE, R.string.incident_menu_add); i.setIcon(R.drawable.menu_add); i = menu.add(Menu.NONE, LIST_INCIDENT, Menu.NONE, R.string.incident_list); i.setIcon(R.drawable.menu_list); i = menu.add(Menu.NONE, INCIDENT_REFRESH, Menu.NONE, R.string.incident_menu_refresh); i.setIcon(R.drawable.menu_refresh); i = menu.add(Menu.NONE, SETTINGS, Menu.NONE, R.string.menu_settings); i.setIcon(R.drawable.menu_settings); i = menu.add(Menu.NONE, ABOUT, Menu.NONE, R.string.menu_about); i.setIcon(R.drawable.menu_about); } // thread class private class ReportsTask extends AsyncTask<Void, Void, Integer> { protected Integer status; protected Context appContext; @Override protected void onPreExecute() { setProgressBarIndeterminateVisibility(true); } @Override protected Integer doInBackground(Void... params) { status = ApiUtils.processReports(appContext); return status; } @Override protected void onPostExecute(Integer result) { if (result == 4) { Util.showToast(appContext, R.string.internet_connection); } else if (result == 0) { mNewIncidents = showIncidents(getString(R.string.all_categories)); populateMap(); setProgressBarIndeterminateVisibility(false); } } } private boolean applyMenuChoice(MenuItem item) { Intent intent; switch (item.getItemId()) { case HOME: intent = new Intent(IncidentMap.this, Dashboard.class); startActivityForResult(intent, GOTOHOME); return true; case INCIDENT_REFRESH: ReportsTask reportsTask = new ReportsTask(); reportsTask.appContext = this; reportsTask.execute(); return (true); case LIST_INCIDENT: extras = new Bundle(); extras.putInt("tab_index", 0); intent = new Intent(IncidentMap.this, IncidentTab.class); intent.putExtra("tab", extras); startActivityForResult(intent, LIST_INCIDENTS); return (true); case INCIDENT_ADD: intent = new Intent(IncidentMap.this, IncidentAdd.class); startActivityForResult(intent, ADD_INCIDENTS); return (true); case ABOUT: intent = new Intent(IncidentMap.this, About.class); startActivityForResult(intent, REQUEST_CODE_ABOUT); setResult(RESULT_OK); return true; case SETTINGS: intent = new Intent(IncidentMap.this, Settings.class); // Make it a subactivity so we know when it returns startActivityForResult(intent, REQUEST_CODE_SETTINGS); return (true); } return false; } public GeoPoint getPoint(double lat, double lon) { return (new GeoPoint((int) (lat * 1000000.0), (int) (lon * 1000000.0))); } private class SitesOverlay extends MapItemizedOverlay<OverlayItem> { private ArrayList<OverlayItem> items = new ArrayList<OverlayItem>(); public SitesOverlay(Drawable marker, MapView mapView) { super(boundCenterBottom(marker), mapView, IncidentMap.this, mNewIncidents, extras); mapView.getContext(); if (id > 0) { IncidentMap.latitude = Double.parseDouble(reportLatitude); IncidentMap.longitude = Double.parseDouble(reportLongitude); /* * items.add(new OverlayItem(getPoint(IncidentMap.latitude, * IncidentMap.longitude), reportTitle, * Util.limitString(reportDescription, 30))); */ items.add(new OverlayItem(getPoint(IncidentMap.latitude, IncidentMap.longitude), reportTitle, reportCategory + " / " + reportDate)); } else { for (IncidentsData incidentData : mNewIncidents) { IncidentMap.latitude = Double.parseDouble(incidentData .getIncidentLocLatitude()); IncidentMap.longitude = Double.parseDouble(incidentData .getIncidentLocLongitude()); /* * items.add(new OverlayItem( getPoint(IncidentMap.latitude, * IncidentMap.longitude), incidentData .getIncidentTitle(), * Util.limitString( incidentData.getIncidentDesc(), 30))); */ items.add(new OverlayItem(getPoint(IncidentMap.latitude, IncidentMap.longitude), incidentData .getIncidentTitle(), incidentData .getIncidentCategories() + " / " + incidentData.getIncidentDate())); } } populate(); } @Override protected OverlayItem createItem(int i) { return items.get(i); } @Override protected boolean onBalloonTap(int i) { return true; } @Override public int size() { return (items.size()); } } }