Java tutorial
/* * Copyright 2016 CMPUT301F16T10 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package ca.ualberta.cs.drivr; import android.app.AlertDialog; import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.graphics.Color; import android.location.Address; import android.location.Geocoder; import android.location.Location; import android.net.Network; import android.net.Uri; import android.util.Log; import android.widget.Toast; import com.akexorcist.googledirection.DirectionCallback; import com.akexorcist.googledirection.GoogleDirection; import com.akexorcist.googledirection.constant.TransportMode; import com.akexorcist.googledirection.model.Direction; import com.akexorcist.googledirection.model.Step; import com.akexorcist.googledirection.util.DirectionConverter; import com.google.android.gms.location.places.Place; 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.model.BitmapDescriptor; 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; import com.google.android.gms.maps.model.PolylineOptions; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import java.io.IOException; import java.util.ArrayList; import java.util.Calendar; import java.util.List; import java.util.Locale; import java.util.Random; /** * Created by justin on 09/11/16. * * A class for Modifying the google map * * Uses a open source library to assist with polyline route drawing * @see https://github.com/akexorcist/Android-GoogleDirectionLibrary * @see DirectionCallback * */ public class MapController implements DirectionCallback { private GoogleMap map; private Location myLocation; private LatLng destinationLatLng; private LatLng pickupLatlng; private int zoom = 10; private final static float KM = 1000; private Double myLatitude; private Double myLongitude; private Context mContext; private ArrayList<LatLng> markers = new ArrayList<LatLng>(); private LatLng pickup; private UserManager userManager = UserManager.getInstance(); private RequestsListController requestsListController; private static final String TAG = "MainActivity"; private int color = Color.RED; private Marker pickupMarker; private Marker destinationMarker; private Geocoder geocoder; private ArrayList<Marker> pickupArrayList = new ArrayList<Marker>(); private ArrayList<Marker> destinationArrayList = new ArrayList<Marker>(); private GPSTracker gpsTracker; private final String serverKey = "AIzaSyB13lv5FV6dbDRec8NN173qj4HSHuNmPHE"; /** * Instantiates a new map controller. * @param map The google map. * @param context The activities context. */ public MapController(GoogleMap map, Context context) { // Initialize map this.mContext = context; this.map = map; gpsTracker = new GPSTracker(context); // Initialize location myLocation = gpsTracker.getLocation(); myLatitude = myLocation.getLatitude(); myLongitude = myLocation.getLongitude(); geocoder = new Geocoder(mContext); requestsListController = new RequestsListController(userManager); // Zoom map in to current Location zoomToCurrentLocation(); } /** * Adds a Destination Marker to the map. * @param latLng a point on the map. */ public void addDestination(LatLng latLng) { MarkerOptions markerOptions = new MarkerOptions(); markerOptions.position(latLng); markerOptions.title("Destination"); markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN)); markerOptions.draggable(true); destinationMarker = map.addMarker(markerOptions); pickupArrayList.add(destinationMarker); } /** * Zooms the camera angle on the Map to the User Location. */ public void zoomToCurrentLocation() { // Camera map.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(myLatitude, myLongitude), 13)); CameraPosition cameraPosition = new CameraPosition.Builder().target(new LatLng(myLatitude, myLongitude)) // Sets the center of the map to location user .zoom(10) // Sets the zoom .build(); // Creates a CameraPosition from the builder map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition)); } public GoogleMap getMap() { return map; } /** * Adds a Pickup Marker to the map. * @param latLng a point on the map. */ public void addPickUp(LatLng latLng) { MarkerOptions markerOptions = new MarkerOptions(); markerOptions.position(latLng); markerOptions.title("Pickup Location"); markerOptions.draggable(true); markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)); pickupMarker = map.addMarker(markerOptions); pickupArrayList.add(pickupMarker); } /** * Queries a route with google direction api to the map. * @param pickup point on the map. * @param destination pickup on the map. */ public void addRequestOnMap(LatLng pickup, LatLng destination) { this.pickupLatlng = pickup; this.destinationLatLng = destination; GoogleDirection.withServerKey(serverKey).from(pickup).to(destination).transitMode(TransportMode.DRIVING) .execute(this); } /** * After a click on Map adds a marker to the map. * Shows Dialog to confirm pickup and drop off location. * @param mapMarker point on the map. * @param context context from activity. */ public void addPendingRequest(final LatLng mapMarker, final Context context) { if (markers.size() == 0) { new AlertDialog.Builder(context).setTitle("Confirm Pickup Location") .setMessage("Is this the Location you want to be picked up from?") .setPositiveButton("Yes", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { addPickUp(mapMarker); pickup = mapMarker; markers.add(mapMarker); } }).setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { // do nothing } }).show(); } // Pickup Location Already Set Up else if (markers.size() == 1) { new AlertDialog.Builder(context).setTitle("Confirm Destination Location") .setMessage("Is this the Location you want to be dropped off at?") .setPositiveButton("Yes", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { addDestination(mapMarker); //markers.add(mapMarker); markers.clear(); //addRequestOnMap(pickup,mapMarker); if (UserManager.getInstance().getConnectivityManager().getActiveNetworkInfo() == null) { Request request = new Request(); request.setRequestState(RequestState.PENDING); ConcretePlace dest = new ConcretePlace(); dest.setLatLng(destinationLatLng); ConcretePlace start = new ConcretePlace(); start.setLatLng(pickupLatlng); request.setDestinationPlace(dest); request.setSourcePlace(start); request.setRider(UserManager.getInstance().getUser()); // request.set requestsListController.addRequest(request); UserManager.getInstance().notifyObservers(); ElasticSearchController.AddRequest addRequest = new ElasticSearchController.AddRequest(); addRequest.execute(request); } else { createRequest(pickup, mapMarker); } map.clear(); } }).setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { // Do nothing } }).show(); } } /** * Passing in two points, json them to new request activity * @param pickupLatlng LatLng point * @param destinationLatLng LatLng point */ public void createRequest(LatLng pickupLatlng, LatLng destinationLatLng) { ConcretePlace pickupPlace = markerGeocodePlace(pickupLatlng); ConcretePlace destinationPlace = markerGeocodePlace(destinationLatLng); Gson gson = new GsonBuilder().registerTypeAdapter(Uri.class, new UriSerializer()).create(); Intent intent = new Intent(mContext, NewRequestActivity.class).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); String concretePlaceJsonPick = gson.toJson(pickupPlace); String concretePlaceJsonDest = gson.toJson(destinationPlace); intent.putExtra(NewRequestActivity.EXTRA_PLACE, concretePlaceJsonDest); Log.i(TAG, "Place: " + destinationPlace.getName() + ", :" + destinationPlace.getLatLng()); intent.putExtra("PICK_UP", concretePlaceJsonPick); Log.i(TAG, "Place: " + pickupPlace.getName() + ", :" + pickupPlace.getLatLng()); mContext.startActivity(intent); // Request request = new Request(userManager.getUser(), new ConcretePlace(pickupAddress), new ConcretePlace(destinationAddress)); //requestsListController.addRequest(request); } /** * Passing in a point it geocodes it into a concrete place * @param latLng point */ public ConcretePlace markerGeocodePlace(LatLng latLng) { try { List<Address> pickupList = geocoder.getFromLocation(latLng.latitude, latLng.longitude, 1); Address pickupAddress = pickupList.get(0); ConcretePlace pickupPlace = new ConcretePlace(pickupAddress); return pickupPlace; } catch (IOException e) { e.printStackTrace(); return null; } } /** * Passing in a two points, creates a bound and move map to include them on screen * @param pickup point * @param destination point */ public void requestCenter(LatLng pickup, LatLng destination) { LatLngBounds.Builder builder = new LatLngBounds.Builder(); builder.include(pickup); builder.include(destination); final LatLngBounds bounds = builder.build(); final CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngBounds(bounds, 0); final CameraUpdate cameraUpdate1 = CameraUpdateFactory.zoomOut(); map.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() { @Override public void onMapLoaded() { map.moveCamera(cameraUpdate); map.animateCamera(cameraUpdate1); } }); } /** * Queries a route with google direction api to the map * @see <a href="https://github.com/akexorcist/Android-GoogleDirectionLibrary">Android-GoogleDirectionLibrary</a>. */ @Override public void onDirectionSuccess(Direction direction, String rawBody) { if (direction.isOK()) { map.addMarker(new MarkerOptions().position(pickupLatlng).title("Pickup") .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED))); map.addMarker(new MarkerOptions().position(destinationLatLng).title("Destination") .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN))); ArrayList<LatLng> directionPositionList = direction.getRouteList().get(0).getLegList().get(0) .getDirectionPoint(); map.addPolyline(DirectionConverter.createPolyline(mContext, directionPositionList, 3, color)); Random rnd = new Random(); color = Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256)); } } // If marker can't be added to map @Override public void onDirectionFailure(Throwable t) { } }