package edu.purdue.app.map; import java.util.List; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.MapFragment; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.LatLngBounds; import com.google.android.gms.maps.model.MarkerOptions; import com.google.android.gms.maps.model.PolylineOptions; import android.app.Fragment; import android.content.Context; import android.graphics.Color; import android.graphics.Point; import android.net.ConnectivityManager; import android.os.Bundle; import android.os.Handler; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.widget.RelativeLayout; import edu.purdue.app.R; public class GoogleMapFragment extends MapFragment { private GMapFragmentLoadedListener listener; /** Listener for when the google map is fully loaded */ public interface GMapFragmentLoadedListener { void onGMapLoaded(); } /** Creates the view for the fragment. We just let MapFragment do everything here. */ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return super.onCreateView(inflater, container, savedInstanceState); } /** Called after onCreateView and onCreate when the activity has been fully instantiated. */ public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); // Alert the listener that the gmap is loaded if (listener != null) { listener.onGMapLoaded(); } } /** Sets the listener for when the map is fully loaded. */ public void setGMapFragmentLoadedListener(GMapFragmentLoadedListener l) { this.listener = l; } /** Adds a pin to the map and animates the camera to gracefully show that pin. * @param toLoc The location of the pin you'd like to add * @param label A label to include on the pin * @param direction Pass true if you'd like to include a directions polyline to the location. */ public void addPinToMap(LatLng toLoc, String label, boolean directions) { // Clear the map GoogleMap gmap = getMap(); gmap.clear(); // Add the marker to the map gmap.addMarker(new MarkerOptions() .title(label) .position(toLoc)); // If we want directions, get the polyline for the directions and put it on the map // This is done on its own thread, so it will be put on the map whenever the thread is done executing if (directions) { addDirectionsToMap(toLoc); } // The layout bounds are set to include two LatLng points: // The location of the user and the latlng of the point they selected if (gmap.getMyLocation() != null) { LatLng myloc = new LatLng(gmap.getMyLocation().getLatitude(), gmap.getMyLocation().getLongitude()); if (MapData.isNearPurdue(myloc.latitude, myloc.longitude)) { Point p = new Point(); getActivity().getWindowManager().getDefaultDisplay().getSize(p); LatLngBounds.Builder builder = LatLngBounds.builder(); builder.include(toLoc); builder.include(myloc); gmap.animateCamera(CameraUpdateFactory.newLatLngBounds( builder.build(), p.x, p.y, 175)); } else { // User is not near purdue, so only include the point selected gmap.animateCamera(CameraUpdateFactory.newLatLngZoom(toLoc, MapData.PURDUE_CAMPUS_ZOOM + 0.5f)); } } else { // GPS is not available, so fall back to simpler functionality gmap.animateCamera(CameraUpdateFactory.newLatLngZoom(toLoc, MapData.PURDUE_CAMPUS_ZOOM)); } } /** Synchronously adds a directions polyline to the gmap between the user's current location * and toLoc. The directions are downloaded from the internet, so they are done synchronously and * will appear on the map whenever they're done downloading. * @param toLoc The destination point of the directions polyline */ private void addDirectionsToMap(final LatLng toLoc) { // If GPS is not enabled, just return final GoogleMap gmap = getMap(); if (gmap.getMyLocation() == null) { return; } // gmap can only be accessed on the main UI thread, so get the user's current location here final LatLng myLoc = new LatLng(gmap.getMyLocation().getLatitude(), gmap.getMyLocation().getLongitude()); // Check if they're connected to the internet. If so, then execute the thread to download walking data ConnectivityManager cm = (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE); boolean isNetworkAvailable = cm.getActiveNetworkInfo() != null; if (isNetworkAvailable && cm.getActiveNetworkInfo().isConnected()) { // Execute the thread new Thread(new Runnable() { public void run() { // Download the directions and create an array of latlng points GoogleMapDirections gmd = new GoogleMapDirections(); List<LatLng> dirPoints = gmd.getDirection(gmd.getDocument(myLoc, toLoc, GoogleMapDirections.MODE_WALKING)); final PolylineOptions line = new PolylineOptions().width(3).color(Color.RED); for (LatLng point : dirPoints) { line.add(point); } // Gmap is on the UI thread so we have to post it using a handler Handler mainHandler = new Handler(getActivity().getMainLooper()); mainHandler.post(new Runnable() { public void run() { gmap.addPolyline(line); } }); } }).start(); } } /** Adds a polyline to the map representing a route of latlng points */ public void addRouteToMap(List<LatLng> route) { PolylineOptions line = new PolylineOptions().width(4).color(Color.GREEN); for (LatLng point : route) { line.add(point); } getMap().addPolyline(line); } }