package com.proyecto.mimapa;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.os.AsyncTask;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.widget.Toast;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptor;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.PolylineOptions;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private static final int LOCATION_REQUEST = 500;
ArrayList <LatLng> listPoints;
private GoogleMap mMap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
listPoints = new ArrayList<>();
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mMap.getUiSettings().setZoomControlsEnabled(true);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_REQUEST);
return;
}
mMap.setMyLocationEnabled(true);
mMap.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {
@Override
public void onMapLongClick(LatLng latLng) {
//Reseteamos el marcador cuando encontremos dos puntos dibujados
if(listPoints.size()==2){
listPoints.clear();
mMap.clear();
}
//Guardamos la primera seleccion del punto
listPoints.add(latLng);
//Creamos el marcador
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
if(listPoints.size()==1){
//agregamos el primer marcador al mapa
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
}else {
//Agregamos el segundo marcador al mapa
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
}
mMap.addMarker(markerOptions);
//TODO: codigo de direcciones que se obtendra del requerimiento
if(listPoints.size()==2){
//Creamos la ruta que se obtiene del 1er marcador a el 2do marcador
String url = getRequestUrl(listPoints.get(0), listPoints.get(1));
TaskRequestDirections taskRequestDirections = new TaskRequestDirections();
taskRequestDirections.execute(url);
}
}
});
}
private String getRequestUrl(LatLng origen, LatLng destino) {
//Valor de Origen
String str_orig = "origin=" + origen.latitude + ", " + origen.longitude;
//Valor de Destino
String str_dest = "destination=" + destino.latitude + ", " + destino.longitude;
//Fijamos el valor de habilitación al sensor
String sensor = "sensor=false";
//Modo para encontrar la dirección
String mode = "mode=driving";
//Construimos los parametros completos
String param = str_orig + "&" + str_dest + "&" + sensor + "&" + mode;
//Salida de lo diseñado (Format)
String output = "json";
//Creamos la dirección de petición
String url = "https://maps.googleapis.com/maps/api/directions/" + output + "?" + param;
return url;
}
private String requestDirection(String reqUrl)throws IOException{
String responseString = "";
InputStream inputStream = null;
HttpURLConnection httpURLConnection = null;
try{
URL url = new URL(reqUrl);
httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.connect();
//Obtenemos el resultado que se desea
inputStream = httpURLConnection.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
StringBuffer stringBuffer = new StringBuffer();
String line ="";
while((line= bufferedReader.readLine())!= null){
stringBuffer.append(line);
}
responseString = stringBuffer.toString();
bufferedReader.close();
inputStreamReader.close();
}catch (Exception e){
e.printStackTrace();
}finally {
if(inputStream != null){
inputStream.close();
}
httpURLConnection.disconnect();
}
return responseString;
}
@SuppressLint("MissingPermission")
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode){
case LOCATION_REQUEST:
if(grantResults.length>0 && grantResults[0]==PackageManager.PERMISSION_GRANTED){
mMap.setMyLocationEnabled(true);
}
break;
}
}
public class TaskRequestDirections extends AsyncTask<String, Void, String>{
@Override
protected String doInBackground(String... strings) {
String responseString="";
try {
responseString = requestDirection(strings[0]);
} catch (IOException e) {
e.printStackTrace();
}
return responseString;
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
//Transformamos el json aqui
TaskParser taskParser = new TaskParser();
taskParser.execute(s);
}
}
public class TaskParser extends AsyncTask<String, Void, List<List<HashMap<String, String>>>>{
@Override
protected List<List<HashMap<String, String>>> doInBackground(String... strings) {
JSONObject jsonObject=null;
List<List<HashMap<String, String>>> routes = null;
try{
jsonObject = new JSONObject(strings[0]);
DirectionsParser directionsParser = new DirectionsParser();
routes = directionsParser.parse(jsonObject);
} catch (JSONException e) {
e.printStackTrace();
}
return routes;
}
@Override
protected void onPostExecute(List<List<HashMap<String, String>>> lists) {
//obtenemos la lista de enrutamiento y la mostramos en el mapa
ArrayList points = null;
PolylineOptions polylineOptions = null;
for (List<HashMap<String, String>> path : lists) {
points = new ArrayList();
polylineOptions = new PolylineOptions();
for (HashMap<String, String> point : path) {
double lat = Double.parseDouble(point.get("lat"));
double lon = Double.parseDouble(point.get("lon"));
points.add(new LatLng(lat, lon));
// points.add(new LatLng(1.3,1.6));
}
polylineOptions.addAll(points);
polylineOptions.width(15);
polylineOptions.color(Color.BLUE);
polylineOptions.geodesic(true);
}
if(polylineOptions != null){
mMap.addPolyline(polylineOptions);
}else{
Toast.makeText(getApplicationContext(), "Dirección no Encontrada", Toast.LENGTH_SHORT).show();
}
}
}
}