Saturday, 17 August 2013

Drawing driving route directions between two locations using Google Directions in Google Map Android API V2,

Layout...

main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android">
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/bottom_row_contatiner"/>

<RelativeLayout
   android:id="@+id/bottom_row_contatiner"
   android:layout_height="wrap_content"
   android:layout_width="match_parent"
   android:background="@android:color/background_dark"
   android:layout_alignParentBottom="true"
   >
 
<Button android:id="@+id/calculate_button"
style="@style/wrap_all"
android:text="@string/calculate"
android:background="@drawable/sendbutton"
android:layout_alignParentLeft="true"/>

<LinearLayout android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:layout_centerVertical="true"
   android:layout_toRightOf="@+id/calculate_button"
   android:orientation="horizontal"
   android:gravity="center"
   >
<TextView
   android:id="@+id/cost_textview"
style="@style/textview_center"
android:layout_weight="1"
android:visibility="invisible"
/>

<TextView android:id="@+id/distance_textview"
   style="@style/textview_center"
android:layout_weight="1"
   />
<TextView android:id="@+id/time_textview"
   style="@style/textview_center"
   android:layout_weight="1"
   />

</LinearLayout>
</RelativeLayout>

</RelativeLayout >




MainActivity: 


package com.tulip.maphometest;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import android.app.ProgressDialog;
import android.content.Context;
import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;
import android.support.v4.app.FragmentTransaction;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
import com.actionbarsherlock.widget.SearchView;
import com.actionbarsherlock.widget.SearchView.OnQueryTextListener;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.model.LatLng;
import com.tulip.maphometest.API.BaseLoaderCallbacks;
import com.tulip.maphometest.API.DirectionsSerializer;
import com.tulip.maphometest.API.LegSerializer;
import com.tulip.maphometest.API.RoutesSerializer;
import com.tulip.maphometest.API.StepSerializer;
import com.tulip.maphometest.Utils.Constant;
import com.tulip.maphometest.Utils.Logger;
import com.tulip.maphometest.Utils.Util;
import com.tulip.taxiguestimator.R;

public class MainActivity<start, route> extends SherlockFragmentActivity {
   
protected static final String TAG = MainActivity.class.getSimpleName();

private SearchView searchView;

private BaseLoaderCallbacks<DirectionsSerializer> mLoaderCallbacks;
private Button calculate;
private TextView cost;
private TextView distance;
private TextView time;
private ProgressDialog myDialog;
GoogleMap googleMap;
private String mRegion= "AU";

protected String mState;

@SuppressWarnings("rawtypes")
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
       
        calculate = (Button) findViewById(R.id.calculate_button);
        cost = (TextView) findViewById(R.id.cost_textview);
        distance = (TextView) findViewById(R.id.distance_textview);
        time = (TextView) findViewById(R.id.time_textview);
       
        calculate.setOnClickListener(new CalculateButtonListener());
       
        mLoaderCallbacks = new GoogleMapsLoaderCallbacks(this);
       

       
       
        // Initialize the location fields
   if (getSupportLoaderManager().getLoader(Constant.GOOGLE_MAPS_LOADER_ID)!=null)
        {
        Bundle args = new Bundle();
        args.putString(Constant.URL_KEY, "");
        Util.connectToLoader(getSupportLoaderManager(), Constant.GOOGLE_MAPS_LOADER_ID, args, mLoaderCallbacks);
        }
       
 
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        ft.replace(R.id.map, new TaxiMapFragment(), Constant.TAXI_FRAGMENT_ID);
        ft.commit();

    }




    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        //Create the search view
        searchView = new SearchView(getSupportActionBar().getThemedContext());
        searchView.setQueryHint("Where to?");

        searchView.setOnQueryTextListener(new OnQueryTextListener() {

@Override
public boolean onQueryTextSubmit(String query)
{
LatLng startLocation = getTaxiMapFragment().getStartLocation();

if (mState == null)
{
try
{
Geocoder geo = new Geocoder(MainActivity.this, Locale.getDefault());
Address addy = geo.getFromLocation(startLocation.latitude,
startLocation.longitude, 1).get(0);
mState = addy.getAdminArea();
mRegion = addy.getCountryCode();

query = query.concat(", "  + mState);

} catch (IOException e) {
e.printStackTrace();
}
}
else
{
query = query.concat(", "  + mState);
}

Logger.e(TAG, query);

showProgressDialog();

String url = Util.buildMapsAPIUrl(
startLocation.latitude+","+startLocation.longitude,
query, mRegion);

Bundle args = new Bundle();
       args.putString(Constant.URL_KEY, url);
     
       Util.restartLoader(
        getSupportLoaderManager(),
        Constant.GOOGLE_MAPS_LOADER_ID,
        args,
        mLoaderCallbacks
        );
     
return true;
}

@Override
public boolean onQueryTextChange(String newText) {
return false;
}
});
       
        menu.add("Search")
            .setIcon(R.drawable.abs__ic_search)
            .setActionView(searchView)
            .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
       
        return true;
    }

   
   
   
@Override
public void onDestroy() {
mLoaderCallbacks.onDestroy();
super.onDestroy();
}

private class GoogleMapsLoaderCallbacks extends BaseLoaderCallbacks<DirectionsSerializer>
    {
    public GoogleMapsLoaderCallbacks(Context context) {
super(context);
}

@SuppressWarnings("unchecked")
@Override
protected void LoaderFinishedSuccessfully(DirectionsSerializer response)
{
if (myDialog != null) myDialog.dismiss();

final RoutesSerializer route = response.routes.get(0);
final LegSerializer leg = route.legs.get(0);
//process the data
double tripCost;
if (leg.distance.value>Constant.BASE_FARE_M){
tripCost = Constant.BASE_FARE +
(Constant.COST_PER_M) * (leg.distance.value-Constant.BASE_FARE_M);

//+
//Constant.COST_PER_SECOND * leg.duration.value;

tripCost = Util.round(tripCost, 2);
}
else{
  tripCost = Constant.BASE_FARE;

//+
//Constant.COST_PER_SECOND * leg.duration.value;

tripCost = Util.round(tripCost, 2);

}

List<LatLng> routePolyline = new ArrayList<LatLng>();
for (StepSerializer s : leg.steps)
{
routePolyline.addAll(Util.decodePoints(s.polyline.points));
}

LatLng northeast = new LatLng(route.bounds.northeast.lat, route.bounds.northeast.lng);
LatLng southwest = new LatLng(route.bounds.southwest.lat, route.bounds.southwest.lng);

LatLng endlocation = new LatLng(leg.end_location.lat, leg.end_location.lng);

//update the UI
cost.setText("Rs".concat(String.valueOf(tripCost)));
distance.setText(leg.distance.text);
time.setText(leg.duration.text);

getTaxiMapFragment().drawPolyline(routePolyline);
getTaxiMapFragment().setEndLocation(endlocation);
getTaxiMapFragment().setMapBounds(northeast, southwest);

((InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(searchView.getWindowToken(), 0);

}

@Override
protected void LoaderFailed(DirectionsSerializer response) {
if (myDialog != null) myDialog.dismiss();

Toast.makeText(MainActivity.this, "Error loading data: " + response.status, Toast.LENGTH_SHORT).show();

       cost.requestFocus();

}
    }
   
    private class CalculateButtonListener implements OnClickListener
    {
@Override
public void onClick(View v)
{
LatLng endLocation = getTaxiMapFragment().getEndLocation();
LatLng startLocation = getTaxiMapFragment().getStartLocation();

if (endLocation != null && startLocation != null)
{
String url = Util.buildMapsAPIUrl(
startLocation.latitude+","+startLocation.longitude,
endLocation.latitude+","+endLocation.longitude,
mRegion);

Bundle args = new Bundle();
       args.putString(Constant.URL_KEY, url);
     
       Util.restartLoader(
        getSupportLoaderManager(),
        Constant.GOOGLE_MAPS_LOADER_ID,
        args,
        mLoaderCallbacks
        );

       showProgressDialog();
}
else
{
Toast.makeText(MainActivity.this, "You must have selected a destination to calculate the distance", Toast.LENGTH_SHORT).show();
}
}
    }
   
   
   
   
    private void showProgressDialog ()
    {
    if (myDialog == null)
        {
        myDialog = new ProgressDialog(MainActivity.this);
        myDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
       myDialog.setMessage("Please wait as we retieve the details of your route");
        }
       
        myDialog.show();
    }
   
    @SuppressWarnings("rawtypes")
private TaxiMapFragment getTaxiMapFragment() {
return (TaxiMapFragment) getSupportFragmentManager().findFragmentByTag(Constant.TAXI_FRAGMENT_ID);
}
   
   

   
}



TaxiMapFragment:



package com.tulip.maphometest;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.graphics.Color;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnMapLongClickListener;
import com.google.android.gms.maps.SupportMapFragment;
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;
import com.google.android.gms.maps.model.Polyline;
import com.google.android.gms.maps.model.PolylineOptions;
 

public class TaxiMapFragment<var> extends SupportMapFragment implements LocationListener
{
@SuppressWarnings("unused")
private static final String TAG = TaxiMapFragment.class.getSimpleName();
protected static final LatLng HAMBURG = null;
protected static final LatLng KIEL = null;
private LocationManager locationManager;
private Marker me_marker;
private Marker end_marker;
public LatLng startLocation;
public LatLng endLocation;
private Polyline mCurrentRoute;
private boolean locationFound = false;
GoogleMap googleMap;
ArrayList<LatLng> points;
public LatLng getStartLocation() { return startLocation; }
public LatLng getEndLocation() { return endLocation; }
public void setEndLocation(LatLng endLocation) {
this.endLocation = endLocation;
if (end_marker == null) end_marker = getMap().addMarker(new MarkerOptions().position(endLocation));
else end_marker.setPosition(endLocation);
}
public TaxiMapFragment() {}
@Override
public void onActivityCreated(Bundle savedInstanceState) 
{
super.onActivityCreated(savedInstanceState);
points = new ArrayList<LatLng>();
locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000, 60, this);
Location location = null;
if (savedInstanceState != null) 
{
locationFound = savedInstanceState.getBoolean("locationFound");
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null && locationFound == true) onLocationChanged(location);
}
   getMap().setOnMapLongClickListener(new OnMapLongClickListener() 
   {
@Override
public void onMapLongClick(LatLng touch) 
{
endLocation = touch;
if (end_marker == null) end_marker = getMap().addMarker(new MarkerOptions().position(touch));
else end_marker.setPosition(touch);
end_marker.setTitle("Position");
// Setting the content of the infowindow of the marker
end_marker.setSnippet("Latitude:"+touch.latitude+","+"Longitude:"+touch.longitude);
//
// Marker hamburg =   getMap().addMarker(new MarkerOptions().position(HAMBURG)
//          .title("Hamburg"));
//      Marker kiel =   getMap().addMarker(new MarkerOptions()
//          .position(KIEL)
//          .title("Kiel")
//          .snippet("Kiel is cool")
//          .icon(BitmapDescriptorFactory
//              .fromResource(R.id.icon2 )));
}
});
   getMap().setMyLocationEnabled(true);
// Setting OnClick event listener for the Google Map
/* getMap().setOnMapClickListener(new OnMapClickListener() {
@Override
public void onMapClick(LatLng point) {
// Instantiating the class MarkerOptions to plot marker on the map
MarkerOptions markerOptions = new MarkerOptions();
// Setting latitude and longitude of the marker position
markerOptions.position(point);
// Setting titile of the infowindow of the marker
markerOptions.title("Position");
// Setting the content of the infowindow of the marker
markerOptions.snippet("Latitude:"+point.latitude+","+"Longitude:"+point.longitude);
// Instantiating the class PolylineOptions to plot polyline in the map
PolylineOptions polylineOptions = new PolylineOptions();
// Setting the color of the polyline
polylineOptions.color(Color.BLACK);
// Setting the width of the polyline
polylineOptions.width(3);
// Adding the taped point to the ArrayList 
points.add(point);
// Setting points of polyline
polylineOptions.addAll(points);
// Adding the polyline to the map
getMap().addPolyline(polylineOptions);
// Adding the marker to the map
getMap().addMarker(markerOptions);
}
});*/
/* getMap().setOnMapLongClickListener(new OnMapLongClickListener() {
@Override
public void onMapLongClick(LatLng point) {
// Clearing the markers and polylines in the google map
getMap().clear();
// Empty the array list
points.clear();
}
});*/  
   

   
@Override
public void onSaveInstanceState(Bundle outState) 
{
outState.putBoolean("locationFound", false);
super.onSaveInstanceState(outState);
}
@Override
public void onPause()
{
   super.onPause();
   locationManager.removeUpdates(this);
}
@Override
public void onLocationChanged(final Location location) 
{
if (getMap() != null)
{
double lat = location.getLatitude();
double lng = location.getLongitude();
startLocation = new LatLng(lat, lng);
getMap().moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(), location.getLongitude()), 15));
if (me_marker == null) me_marker = getMap().addMarker(new MarkerOptions().position(startLocation));
else me_marker.setPosition(startLocation);
locationFound  = true;
locationManager.removeUpdates(this);
}
}

@Override
public void onProviderDisabled(String provider) {}

@Override
public void onProviderEnabled(String provider) {}

@Override
public void onStatusChanged(String provider, int status, Bundle extras) {}
public void drawPolyline(final List<LatLng> routePolyline)
{
PolylineOptions options = new PolylineOptions();
options.addAll(routePolyline);
options.color(Color.BLACK);
if (mCurrentRoute == null) mCurrentRoute = getMap().addPolyline(options);
else mCurrentRoute.setPoints(routePolyline);
 
}
public void setMapBounds (final LatLng northEast, final LatLng southWest)
{
final ViewTreeObserver vto = getView().getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
   @SuppressWarnings("deprecation")
@Override
   public void onGlobalLayout() {
   
LatLngBounds bounds = new LatLngBounds(southWest, northEast);
getMap().animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 50));
getView().getViewTreeObserver().removeGlobalOnLayoutListener(this);
   }
});
}
}






1 comment: