gov.wa.wsdot.android.wsdot.ui.TrafficMapActivity.java Source code

Java tutorial

Introduction

Here is the source code for gov.wa.wsdot.android.wsdot.ui.TrafficMapActivity.java

Source

/*
 * Copyright (c) 2014 Washington State Department of Transportation
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
 *
 */

package gov.wa.wsdot.android.wsdot.ui;

import gov.wa.wsdot.android.wsdot.R;
import gov.wa.wsdot.android.wsdot.service.CamerasSyncService;
import gov.wa.wsdot.android.wsdot.service.HighwayAlertsSyncService;
import gov.wa.wsdot.android.wsdot.shared.CameraItem;
import gov.wa.wsdot.android.wsdot.shared.HighwayAlertsItem;
import gov.wa.wsdot.android.wsdot.shared.LatLonItem;
import gov.wa.wsdot.android.wsdot.ui.map.CamerasOverlay;
import gov.wa.wsdot.android.wsdot.ui.map.HighwayAlertsOverlay;
import gov.wa.wsdot.android.wsdot.util.AnalyticsUtils;
import gov.wa.wsdot.android.wsdot.util.UIUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.location.Location;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.Window;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks;
import com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.location.LocationClient;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnCameraChangeListener;
import com.google.android.gms.maps.GoogleMap.OnMarkerClickListener;
import com.google.android.gms.maps.GoogleMap.OnMyLocationButtonClickListener;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

public class TrafficMapActivity extends ActionBarActivity implements OnMarkerClickListener, ConnectionCallbacks,
        OnConnectionFailedListener, OnMyLocationButtonClickListener, OnCameraChangeListener {

    private static final String TAG = TrafficMapActivity.class.getSimpleName();

    private GoogleMap map;
    private LocationClient locationClient;

    private HighwayAlertsOverlay alertsOverlay = null;
    private CamerasOverlay camerasOverlay = null;
    private List<CameraItem> cameras = new ArrayList<CameraItem>();
    private List<HighwayAlertsItem> alerts = new ArrayList<HighwayAlertsItem>();
    private HashMap<Marker, String> markers = new HashMap<Marker, String>();
    boolean showCameras;
    private ArrayList<LatLonItem> seattleArea = new ArrayList<LatLonItem>();

    static final private int MENU_ITEM_SEATTLE_ALERTS = Menu.FIRST;
    static final private int MENU_ITEM_EXPRESS_LANES = Menu.FIRST + 1;

    private CamerasSyncReceiver mCamerasReceiver;
    private HighwayAlertsSyncReceiver mHighwayAlertsSyncReceiver;
    private Intent camerasIntent;
    private Intent alertsIntent;
    private static AsyncTask<Void, Void, Void> mCamerasOverlayTask = null;
    private static AsyncTask<Void, Void, Void> mHighwayAlertsOverlayTask = null;
    private LatLngBounds bounds;
    private double latitude;
    private double longitude;
    private int zoom;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        supportRequestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
        setContentView(R.layout.map);

        AnalyticsUtils.getInstance(this).trackPageView("/Traffic Map");

        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        // Setup bounding box for Seattle area.
        seattleArea.add(new LatLonItem(48.01749, -122.46185));
        seattleArea.add(new LatLonItem(48.01565, -121.86584));
        seattleArea.add(new LatLonItem(47.27737, -121.86310));
        seattleArea.add(new LatLonItem(47.28109, -122.45911));

        // Initialize AsyncTask
        mCamerasOverlayTask = new CamerasOverlayTask();
        mHighwayAlertsOverlayTask = new HighwayAlertsOverlayTask();

        // Check preferences and set defaults if none set
        SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
        showCameras = settings.getBoolean("KEY_SHOW_CAMERAS", true);
        latitude = Double.parseDouble(settings.getString("KEY_TRAFFICMAP_LAT", "47.5990"));
        longitude = Double.parseDouble(settings.getString("KEY_TRAFFICMAP_LON", "-122.3350"));
        zoom = settings.getInt("KEY_TRAFFICMAP_ZOOM", 12);

        // Set up Service Intents.
        camerasIntent = new Intent(this, CamerasSyncService.class);
        alertsIntent = new Intent(this, HighwayAlertsSyncService.class);
    }

    @Override
    protected void onResume() {
        super.onResume();

        prepareMap();
        setupLocationClientIfNeeded();

        int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);

        if (ConnectionResult.SUCCESS == resultCode) {
            locationClient.connect();
        } else {
            Toast.makeText(this, "Google Play services not available", Toast.LENGTH_SHORT).show();
        }

        IntentFilter camerasFilter = new IntentFilter("gov.wa.wsdot.android.wsdot.intent.action.CAMERAS_RESPONSE");
        camerasFilter.addCategory(Intent.CATEGORY_DEFAULT);
        mCamerasReceiver = new CamerasSyncReceiver();
        registerReceiver(mCamerasReceiver, camerasFilter);

        IntentFilter alertsFilter = new IntentFilter(
                "gov.wa.wsdot.android.wsdot.intent.action.HIGHWAY_ALERTS_RESPONSE");
        alertsFilter.addCategory(Intent.CATEGORY_DEFAULT);
        mHighwayAlertsSyncReceiver = new HighwayAlertsSyncReceiver();
        registerReceiver(mHighwayAlertsSyncReceiver, alertsFilter);
    }

    public void prepareMap() {
        if (map == null) {
            map = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.mapview)).getMap();

            if (map != null) {
                map.setMapType(GoogleMap.MAP_TYPE_NORMAL);
                map.getUiSettings().setCompassEnabled(true);
                map.getUiSettings().setZoomControlsEnabled(true);
                map.getUiSettings().setMyLocationButtonEnabled(true);
                map.setTrafficEnabled(true);
                map.setMyLocationEnabled(true);
                map.setOnMyLocationButtonClickListener(this);
                map.setOnMarkerClickListener(this);
                map.setOnCameraChangeListener(this);

                LatLng latLng = new LatLng(latitude, longitude);
                map.moveCamera(CameraUpdateFactory.newLatLng(latLng));
                map.animateCamera(CameraUpdateFactory.zoomTo(zoom));
            }
        }
    }

    public void onCameraChange(CameraPosition cameraPosition) {
        setSupportProgressBarIndeterminateVisibility(true);
        startService(camerasIntent);
        startService(alertsIntent);
    }

    private void setupLocationClientIfNeeded() {
        if (locationClient == null) {
            locationClient = new LocationClient(this, this, // ConnectionCallbacks
                    this); // OnConnectionFailedListener
        }
    }

    public boolean onMarkerClick(Marker marker) {
        Bundle b = new Bundle();
        Intent intent = new Intent();

        if (markers.get(marker).equalsIgnoreCase("camera")) {
            intent = new Intent(this, CameraActivity.class);
            b.putInt("id", Integer.parseInt(marker.getSnippet()));
            intent.putExtras(b);
            TrafficMapActivity.this.startActivity(intent);
        } else if (markers.get(marker).equalsIgnoreCase("alert")) {
            intent = new Intent(this, HighwayAlertDetailsActivity.class);
            b.putString("id", marker.getSnippet());
            intent.putExtras(b);
            TrafficMapActivity.this.startActivity(intent);
        }

        return true;
    }

    @Override
    protected void onPause() {
        super.onPause();

        if (locationClient != null) {
            locationClient.disconnect();
        }

        this.unregisterReceiver(mCamerasReceiver);
        this.unregisterReceiver(mHighwayAlertsSyncReceiver);

        // Save last map location and zoom level.
        SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
        SharedPreferences.Editor editor = settings.edit();

        try {
            editor.putString("KEY_TRAFFICMAP_LAT",
                    String.valueOf(map.getProjection().getVisibleRegion().latLngBounds.getCenter().latitude));
            editor.putString("KEY_TRAFFICMAP_LON",
                    String.valueOf(map.getProjection().getVisibleRegion().latLngBounds.getCenter().longitude));
            editor.putInt("KEY_TRAFFICMAP_ZOOM", (int) map.getCameraPosition().zoom);
        } catch (NullPointerException e) {
            Log.e(TAG, "Error getting map bounds. Setting defaults to Seattle instead.");
            editor.putString("KEY_TRAFFICMAP_LAT", "47.5990");
            editor.putString("KEY_TRAFFICMAP_LON", "-122.3350");
            editor.putInt("KEY_TRAFFICMAP_ZOOM", 12);
        }

        editor.commit();
    }

    public class CamerasSyncReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            String responseString = intent.getStringExtra("responseString");

            if (responseString != null) {
                if (responseString.equals("OK") || responseString.equals("NOP")) {
                    // We've got cameras, now add them.
                    if (mCamerasOverlayTask.getStatus() == AsyncTask.Status.FINISHED) {
                        mCamerasOverlayTask = new CamerasOverlayTask().execute();
                    } else if (mCamerasOverlayTask.getStatus() == AsyncTask.Status.PENDING) {
                        mCamerasOverlayTask.execute();
                    }
                } else {
                    Log.e("CameraDownloadReceiver", responseString);
                }
            }
        }
    }

    public class HighwayAlertsSyncReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            String responseString = intent.getStringExtra("responseString");

            if (responseString != null) {
                if (responseString.equals("OK") || responseString.equals("NOP")) {
                    // We've got alerts, now add them.
                    if (mHighwayAlertsOverlayTask.getStatus() == AsyncTask.Status.FINISHED) {
                        mHighwayAlertsOverlayTask = new HighwayAlertsOverlayTask().execute();
                    } else if (mHighwayAlertsOverlayTask.getStatus() == AsyncTask.Status.PENDING) {
                        mHighwayAlertsOverlayTask.execute();
                    }
                } else {
                    Log.e("HighwayAlertsSyncReceiver", responseString);
                    /*
                    if (!UIUtils.isNetworkAvailable(context)) {
                       responseString = getString(R.string.no_connection);
                    }
                    Toast.makeText(context, responseString, Toast.LENGTH_LONG).show();
                    */
                }
            }
        }
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        menu.clear();
        getMenuInflater().inflate(R.menu.traffic, menu);

        if (showCameras) {
            menu.getItem(0).setTitle("Hide Cameras");
        } else {
            menu.getItem(0).setTitle("Show Cameras");
        }

        /**
         * Check if current location is within a lat/lon bounding box surrounding
         * the greater Seattle area.
         */
        try {
            LatLng center = map.getCameraPosition().target;

            if (inPolygon(seattleArea, center.latitude, center.longitude)) {
                MenuItem menuItem_Alerts = menu.add(0, MENU_ITEM_SEATTLE_ALERTS, menu.size(), "Seattle Alerts")
                        .setIcon(R.drawable.ic_menu_alerts);

                MenuItemCompat.setShowAsAction(menuItem_Alerts,
                        MenuItemCompat.SHOW_AS_ACTION_IF_ROOM | MenuItemCompat.SHOW_AS_ACTION_WITH_TEXT);

                MenuItem menuItem_Lanes = menu.add(0, MENU_ITEM_EXPRESS_LANES, menu.size(), "Express Lanes");
                MenuItemCompat.setShowAsAction(menuItem_Lanes, MenuItemCompat.SHOW_AS_ACTION_NEVER);
            }

        } catch (NullPointerException e) {
            Log.e(TAG, "Error getting LatLng center");
        }

        return super.onPrepareOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {

        case android.R.id.home:
            finish();
            return true;
        case R.id.toggle_cameras:
            toggleCameras(item);
            return true;
        case R.id.travel_times:
            Intent timesIntent = new Intent(this, TravelTimesActivity.class);
            startActivity(timesIntent);
            return true;
        case R.id.goto_bellingham:
            AnalyticsUtils.getInstance(this).trackPageView("/Traffic Map/GoTo Location/Bellingham");
            goToLocation("Bellingham Traffic", 48.756302, -122.46151, 12);
            UIUtils.refreshActionBarMenu(this);
            return true;
        case R.id.goto_chehalis:
            AnalyticsUtils.getInstance(this).trackPageView("/Traffic Map/GoTo Location/Chehalis");
            goToLocation("Chelalis Traffic", 46.635529, -122.937698, 11);
            UIUtils.refreshActionBarMenu(this);
            return true;
        case R.id.goto_hoodcanal:
            AnalyticsUtils.getInstance(this).trackPageView("/Traffic Map/GoTo Location/Hood Canal");
            goToLocation("Hood Canal Traffic", 47.85268, -122.628365, 13);
            UIUtils.refreshActionBarMenu(this);
            return true;
        case R.id.goto_mtvernon:
            AnalyticsUtils.getInstance(this).trackPageView("/Traffic Map/GoTo Location/Mt Vernon");
            goToLocation("Mt Vernon Traffic", 48.420657, -122.334824, 13);
            UIUtils.refreshActionBarMenu(this);
            return true;
        case R.id.goto_stanwood:
            AnalyticsUtils.getInstance(this).trackPageView("/Traffic Map/GoTo Location/Stanwood");
            goToLocation("Stanwood Traffic", 48.22959, -122.34581, 13);
            UIUtils.refreshActionBarMenu(this);
            return true;
        case R.id.goto_monroe:
            AnalyticsUtils.getInstance(this).trackPageView("/Traffic Map/GoTo Location/Monroe");
            goToLocation("Monroe Traffic", 47.859476, -121.972446, 14);
            UIUtils.refreshActionBarMenu(this);
            return true;
        case R.id.goto_sultan:
            AnalyticsUtils.getInstance(this).trackPageView("/Traffic Map/GoTo Location/Sultan");
            goToLocation("Sultan Traffic", 47.86034, -121.812286, 13);
            UIUtils.refreshActionBarMenu(this);
            return true;
        case R.id.goto_olympia:
            AnalyticsUtils.getInstance(this).trackPageView("/Traffic Map/GoTo Location/Olympia");
            goToLocation("Olympia Traffic", 47.021461, -122.899933, 13);
            UIUtils.refreshActionBarMenu(this);
            return true;
        case R.id.goto_seattle:
            AnalyticsUtils.getInstance(this).trackPageView("/Traffic Map/GoTo Location/Seattle");
            goToLocation("Seattle Area Traffic", 47.5990, -122.3350, 12);
            UIUtils.refreshActionBarMenu(this);
            return true;
        case R.id.goto_spokane:
            AnalyticsUtils.getInstance(this).trackPageView("/Traffic Map/GoTo Location/Spokane");
            goToLocation("Spokane Area Traffic", 47.658566, -117.425995, 12);
            UIUtils.refreshActionBarMenu(this);
            return true;
        case R.id.goto_tacoma:
            AnalyticsUtils.getInstance(this).trackPageView("/Traffic Map/GoTo Location/Tacoma");
            goToLocation("Tacoma Traffic", 47.206275, -122.46254, 12);
            UIUtils.refreshActionBarMenu(this);
            return true;
        case R.id.goto_vancouver:
            AnalyticsUtils.getInstance(this).trackPageView("/Traffic Map/GoTo Location/Vancouver");
            goToLocation("Vancouver Area Traffic", 45.639968, -122.610512, 11);
            UIUtils.refreshActionBarMenu(this);
            return true;
        case R.id.goto_wenatchee:
            AnalyticsUtils.getInstance(this).trackPageView("/Traffic Map/GoTo Location/Wenatchee");
            goToLocation("Wenatchee Traffic", 47.435867, -120.309563, 12);
            UIUtils.refreshActionBarMenu(this);
            return true;
        case R.id.goto_snoqualmiepass:
            AnalyticsUtils.getInstance(this).trackPageView("/Traffic Map/GoTo Location/Snoqualmie Pass");
            goToLocation("Snoqualmie Pass Traffic", 47.404481, -121.4232569, 12);
            UIUtils.refreshActionBarMenu(this);
            return true;
        case R.id.goto_tricities:
            AnalyticsUtils.getInstance(this).trackPageView("/Traffic Map/GoTo Location/Tri-Cities");
            goToLocation("Tri-Cities Traffic", 46.2503607, -119.2063781, 11);
            UIUtils.refreshActionBarMenu(this);
            return true;
        case R.id.goto_yakima:
            AnalyticsUtils.getInstance(this).trackPageView("/Traffic Map/GoTo Location/Yakima");
            goToLocation("Yakima Traffic", 46.6063273, -120.4886952, 11);
            UIUtils.refreshActionBarMenu(this);
            return true;
        case MENU_ITEM_SEATTLE_ALERTS:
            Intent alertsIntent = new Intent(this, SeattleTrafficAlertsActivity.class);
            startActivity(alertsIntent);
            return true;
        case MENU_ITEM_EXPRESS_LANES:
            Intent expressIntent = new Intent(this, SeattleExpressLanesActivity.class);
            startActivity(expressIntent);
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    private void toggleCameras(MenuItem item) {
        if (showCameras) {
            AnalyticsUtils.getInstance(this).trackPageView("/Traffic Map/Hide Cameras");

            for (Entry<Marker, String> entry : markers.entrySet()) {
                Marker key = entry.getKey();
                String value = entry.getValue();

                if (value.equalsIgnoreCase("camera")) {
                    key.setVisible(false);
                }
            }

            item.setTitle("Show Cameras");
            showCameras = false;
        } else {
            AnalyticsUtils.getInstance(this).trackPageView("/Traffic Map/Show Cameras");

            for (Entry<Marker, String> entry : markers.entrySet()) {
                Marker key = entry.getKey();
                String value = entry.getValue();

                if (value.equalsIgnoreCase("camera")) {
                    key.setVisible(true);
                }
            }

            item.setTitle("Hide Cameras");
            showCameras = true;
        }

        // Save camera display preference
        SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
        SharedPreferences.Editor editor = settings.edit();
        editor.putBoolean("KEY_SHOW_CAMERAS", showCameras);
        editor.commit();
    }

    public void goToLocation(String title, double latitude, double longitude, int zoomLevel) {
        LatLng latLng = new LatLng(latitude, longitude);
        map.moveCamera(CameraUpdateFactory.newLatLng(latLng));
        map.animateCamera(CameraUpdateFactory.zoomTo(zoomLevel));
    }

    /**
     * Iterate through collection of LatLon objects in arrayList and see
     * if passed latitude and longitude point is within the collection.
     */
    public boolean inPolygon(ArrayList<LatLonItem> points, double latitude, double longitude) {
        int j = points.size() - 1;
        double lat = latitude;
        double lon = longitude;
        boolean inPoly = false;

        for (int i = 0; i < points.size(); i++) {
            if ((points.get(i).getLongitude() < lon && points.get(j).getLongitude() >= lon)
                    || (points.get(j).getLongitude() < lon && points.get(i).getLongitude() >= lon)) {
                if (points.get(i).getLatitude() + (lon - points.get(i).getLongitude())
                        / (points.get(j).getLongitude() - points.get(i).getLongitude())
                        * (points.get(j).getLatitude() - points.get(i).getLatitude()) < lat) {
                    inPoly = !inPoly;
                }
            }
            j = i;
        }
        return inPoly;
    }

    class CamerasOverlayTask extends AsyncTask<Void, Void, Void> {

        @Override
        public void onPreExecute() {
            setSupportProgressBarIndeterminateVisibility(true);

            camerasOverlay = null;
            bounds = map.getProjection().getVisibleRegion().latLngBounds;
        }

        @Override
        public Void doInBackground(Void... unused) {
            camerasOverlay = new CamerasOverlay(TrafficMapActivity.this, bounds, null);

            return null;
        }

        @Override
        public void onPostExecute(Void unused) {
            Iterator<Entry<Marker, String>> iter = markers.entrySet().iterator();
            while (iter.hasNext()) {
                Map.Entry<Marker, String> entry = iter.next();
                if (entry.getValue().equalsIgnoreCase("camera")) {
                    entry.getKey().remove();
                    iter.remove();
                }
            }
            cameras.clear();
            cameras = camerasOverlay.getCameraMarkers();

            if (cameras != null) {
                if (cameras.size() != 0) {
                    for (int i = 0; i < cameras.size(); i++) {
                        LatLng latLng = new LatLng(cameras.get(i).getLatitude(), cameras.get(i).getLongitude());
                        Marker marker = map.addMarker(new MarkerOptions().position(latLng)
                                .title(cameras.get(i).getTitle()).snippet(cameras.get(i).getCameraId().toString())
                                .icon(BitmapDescriptorFactory.fromResource(cameras.get(i).getCameraIcon()))
                                .visible(showCameras));

                        markers.put(marker, "camera");
                    }
                }
            }

            setSupportProgressBarIndeterminateVisibility(false);
        }
    }

    class HighwayAlertsOverlayTask extends AsyncTask<Void, Void, Void> {

        @Override
        public void onPreExecute() {
            setSupportProgressBarIndeterminateVisibility(true);

            alertsOverlay = null;
            bounds = map.getProjection().getVisibleRegion().latLngBounds;
        }

        @Override
        public Void doInBackground(Void... unused) {
            alertsOverlay = new HighwayAlertsOverlay(TrafficMapActivity.this, bounds);

            return null;
        }

        @Override
        public void onPostExecute(Void unused) {
            Iterator<Entry<Marker, String>> iter = markers.entrySet().iterator();
            while (iter.hasNext()) {
                Map.Entry<Marker, String> entry = iter.next();
                if (entry.getValue().equalsIgnoreCase("alert")) {
                    entry.getKey().remove();
                    iter.remove();
                }
            }
            alerts.clear();
            alerts = alertsOverlay.getAlertMarkers();

            if (alerts != null) {
                if (alerts.size() != 0) {
                    for (int i = 0; i < alerts.size(); i++) {
                        LatLng latLng = new LatLng(alerts.get(i).getStartLatitude(),
                                alerts.get(i).getStartLongitude());
                        Marker marker = map.addMarker(new MarkerOptions().position(latLng)
                                .title(alerts.get(i).getEventCategory()).snippet(alerts.get(i).getAlertId())
                                .icon(BitmapDescriptorFactory.fromResource(alerts.get(i).getCategoryIcon()))
                                .visible(true));

                        markers.put(marker, "alert");
                    }
                }
            }

            setSupportProgressBarIndeterminateVisibility(false);
        }
    }

    public boolean onMyLocationButtonClick() {
        Log.i(TAG, "Last Location: " + locationClient.getLastLocation());
        if (locationClient.getLastLocation() == null) {
            Toast.makeText(this, "Waiting for location...", Toast.LENGTH_SHORT).show();
        } else {
            Location location = locationClient.getLastLocation();
            LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
            CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, 12);
            map.animateCamera(cameraUpdate);
        }

        return true;
    }

    /*
     * Called by Location Services if the attempt to
     * Location Services fails.
     */
    public void onConnectionFailed(ConnectionResult arg0) {
        // TODO Auto-generated method stub
    }

    /*
     * Called by Location Services when the request to connect the
     * client finishes successfully. At this point, you can
     * request the current location or start periodic updates
     */
    public void onConnected(Bundle arg0) {
        // TODO Auto-generated method stub
    }

    /*
     * Called by Location Services if the connection to the
     * location client drops because of an error.
     */
    public void onDisconnected() {
        // TODO Auto-generated method stub
    }

}