studio - medir distancias google maps android
Encuentra la distancia entre dos puntos en el mapa usando Google Map API V2 (15)
Estoy usando google map api v2 en mi aplicación para Android, puedo mostrar el mapa y ponerle marcadores, pero ahora estoy atascado con el problema en el que necesito encontrar la distancia entre dos marcadores o puntos colocados en el mapa , Ya revisé los documentos pero no encontré nada útil en este caso.
Si alguien sabe cómo resolver esto, por favor ayudame.
Gracias
@salman khan, lo que Usman Kurd sugirió es perfecto. Lo único que encontré que se puede corregir es que "Para google maps v2 usamos la clase LatLng . A continuación, se muestra el código de Usman Kurd que se puede usar para Google Maps v2. Lo comprobé que funcionaba perfectamente.
public double CalculationByDistance(LatLng StartP, LatLng EndP) {
int Radius=6371;//radius of earth in Km
double lat1 = StartP.latitude;
double lat2 = EndP.latitude;
double lon1 = StartP.longitude;
double lon2 = EndP.longitude;
double dLat = Math.toRadians(lat2-lat1);
double dLon = Math.toRadians(lon2-lon1);
double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
Math.sin(dLon/2) * Math.sin(dLon/2);
double c = 2 * Math.asin(Math.sqrt(a));
double valueResult= Radius*c;
double km=valueResult/1;
DecimalFormat newFormat = new DecimalFormat("####");
int kmInDec = Integer.valueOf(newFormat.format(km));
double meter=valueResult%1000;
int meterInDec= Integer.valueOf(newFormat.format(meter));
Log.i("Radius Value",""+valueResult+" KM "+kmInDec+" Meter "+meterInDec);
return Radius * c;
}
En Google Map API V2
, tiene objetos LatLng
, por lo que no puede usar distanceTo
(todavía).
A continuación, puede utilizar el siguiente código considerando oldPosition y newPosition son objetos LatLng
:
// The computed distance is stored in results[0].
//If results has length 2 or greater, the initial bearing is stored in results[1].
//If results has length 3 or greater, the final bearing is stored in results[2].
float[] results = new float[1];
Location.distanceBetween(oldPosition.latitude, oldPosition.longitude,
newPosition.latitude, newPosition.longitude, results);
Para obtener más información sobre la clase Location
, consulte este enlace
En la aplicación Android google maps hay una manera muy fácil de encontrar la distancia entre 2 ubicaciones, para hacerlo, siga los siguientes sencillos pasos:
cuando abre la aplicación, vaya a "su línea de tiempo" desde el menú desplegable en la esquina superior izquierda.
una vez que se abra el nuevo windwo, elija entre las configuraciones en su menú superior derecho y elija "agregar lugar".
- agregue sus lugares y asígneles el nombre de lilke, punto 1, punto 2 o cualquier nombre fácil de recordar.
- una vez que se agreguen sus lugares y se marquen, regrese a la ventana principal en su aplicación de google.
- haga clic en el círculo azul con la flecha en la parte inferior derecha.
- se abrirá un nuevo windwo y se puede ver en la parte superior hay dos campos de texto en los que puede agregar su "ubicación" y "ubicación de distancia".
- haga clic en cualquier campo de texto y escriba su ubicación guardada en el punto 3.
- haga clic en el otro campo de texto y agregue su próxima ubicación guardada.
- Al hacerlo, google maps calculará la distancia entre las dos ubicaciones y le mostrará el camino azul en el mapa.
Buena suerte
Esta es una vieja pregunta con viejas respuestas. Quiero resaltar una forma actualizada de calcular la distancia entre dos puntos. Por ahora, deberíamos estar familiarizados con la clase de utilidad, "SphericalUtil". Puedes recuperar la distancia usando eso.
double distance = SphericalUtil.computeDistanceBetween(origin, dest);
La distancia entre dos geocoordenadas se puede encontrar utilizando la fórmula de Haversine . Esta fórmula es efectiva para calcular la distancia en un cuerpo esférico, es decir, la tierra en nuestro caso.
Llego tarde, pero dado que este es uno de los mejores resultados en la búsqueda de Google para el tema, lo compartiré de otra manera:
Utilice un trazador de líneas único con la clase de utilidad Googles SphericalUtil
SphericalUtil.computeDistanceBetween(latLngFrom, latLngTo)
Necesitará las clases de utilidad:
https://developers.google.com/maps/documentation/android-api/utility/
Simplemente puede incluirlos en su proyecto usando gradle:
compile ''com.google.maps.android:android-maps-utils:0.4+''
Puede usar el siguiente método que le dará un resultado preciso
public double CalculationByDistance(LatLng StartP, LatLng EndP) {
int Radius = 6371;// radius of earth in Km
double lat1 = StartP.latitude;
double lat2 = EndP.latitude;
double lon1 = StartP.longitude;
double lon2 = EndP.longitude;
double dLat = Math.toRadians(lat2 - lat1);
double dLon = Math.toRadians(lon2 - lon1);
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
+ Math.cos(Math.toRadians(lat1))
* Math.cos(Math.toRadians(lat2)) * Math.sin(dLon / 2)
* Math.sin(dLon / 2);
double c = 2 * Math.asin(Math.sqrt(a));
double valueResult = Radius * c;
double km = valueResult / 1;
DecimalFormat newFormat = new DecimalFormat("####");
int kmInDec = Integer.valueOf(newFormat.format(km));
double meter = valueResult % 1000;
int meterInDec = Integer.valueOf(newFormat.format(meter));
Log.i("Radius Value", "" + valueResult + " KM " + kmInDec
+ " Meter " + meterInDec);
return Radius * c;
}
Todas estas respuestas te darán la distancia en línea recta. Si necesita obtener la distancia por carretera, debe analizar el JSON que Google le envía de vuelta después de llamar a su servicio. Puedes usar este método:
public String getDistance(final double lat1, final double lon1, final double lat2, final double lon2){
String parsedDistance;
String response;
Thread thread=new Thread(new Runnable() {
@Override
public void run() {
try {
URL url = new URL("http://maps.googleapis.com/maps/api/directions/json?origin=" + lat1 + "," + lon1 + "&destination=" + lat2 + "," + lon2 + "&sensor=false&units=metric&mode=driving");
final HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
InputStream in = new BufferedInputStream(conn.getInputStream());
response = org.apache.commons.io.IOUtils.toString(in, "UTF-8");
JSONObject jsonObject = new JSONObject(response);
JSONArray array = jsonObject.getJSONArray("routes");
JSONObject routes = array.getJSONObject(0);
JSONArray legs = routes.getJSONArray("legs");
JSONObject steps = legs.getJSONObject(0);
JSONObject distance = steps.getJSONObject("distance");
parsedDistance=distance.getString("text");
} catch (ProtocolException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
});
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
return parsedDistance;
}
lat1 y lon1 son coordenadas de origen, lat2 y lon2 son coordenadas de destino.
función simple util para calcular la distancia entre dos geopoints:
public static long getDistanceMeters(double lat1, double lng1, double lat2, double lng2) {
double l1 = toRadians(lat1);
double l2 = toRadians(lat2);
double g1 = toRadians(lng1);
double g2 = toRadians(lng2);
double dist = acos(sin(l1) * sin(l2) + cos(l1) * cos(l2) * cos(g1 - g2));
if(dist < 0) {
dist = dist + Math.PI;
}
return Math.round(dist * 6378100);
}
para obtener distancia entre dos puntos prueba este código ...
public static float GetDistanceFromCurrentPosition(double lat1,double lng1, double lat2, double lng2)
{
double earthRadius = 3958.75;
double dLat = Math.toRadians(lat2 - lat1);
double dLng = Math.toRadians(lng2 - lng1);
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
+ Math.cos(Math.toRadians(lat1))
* Math.cos(Math.toRadians(lat2)) * Math.sin(dLng / 2)
* Math.sin(dLng / 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
double dist = earthRadius * c;
int meterConversion = 1609;
return new Float(dist * meterConversion).floatValue();
}
prueba esto
double distance;
Location locationA = new Location("");
locationA.setLatitude(main_Latitude);
locationA.setLongitude(main_Longitude);
Location locationB = new Location("");
locationB.setLatitude(sub_Latitude);
locationB.setLongitude(sub_Longitude);
distance = locationA.distanceTo(locationB)/1000;
kmeter.setText(String.valueOf(distance));
Toast.makeText(getApplicationContext(), ""+distance, Toast.LENGTH_LONG).show();double distance;
puedes usar esta función Lo he usado en mi proyecto.
public String getDistance(LatLng my_latlong, LatLng frnd_latlong) {
Location l1 = new Location("One");
l1.setLatitude(my_latlong.latitude);
l1.setLongitude(my_latlong.longitude);
Location l2 = new Location("Two");
l2.setLatitude(frnd_latlong.latitude);
l2.setLongitude(frnd_latlong.longitude);
float distance = l1.distanceTo(l2);
String dist = distance + " M";
if (distance > 1000.0f) {
distance = distance / 1000.0f;
dist = distance + " KM";
}
return dist;
}
Debes usar la ubicación de Android
Tu puedes hacer:
location1.distanceTo(location2);
Y también:
float[] results = new float[1];
Location.distanceBetween(latLongA.latitude, latLongA.longitude,
latLongB.latitude, latLongB.longitude,
results);
Y obtendrá la distancia en metros entre location1 y location2 en metros. Y entre latLongA ant latLongB.
Usando la ubicación
ESTE ES EL CÓDIGO FÁCIL Y PERFECTO PARA LA DURACIÓN Y LA DISTANCIA
Paso 1; (agrégalo y sincronízalo en tu gradle)
compile ''com.android.volley:volley:1.0.0''
Paso 2: (escribe esto en tu método desencadenante)
public void clicked(View view) throws JSONException { JSONObject locationJsonObject = new JSONObject(); locationJsonObject.put("origin", "54.406505,18.67708"); locationJsonObject.put("destination", "54.446251,18.570993"); LatlngCalc(locationJsonObject); }
Paso 3: (Copia y pega en tu clase)
private void LatlngCalc(JSONObject locationJsonObject) throws JSONException { RequestQueue queue = Volley.newRequestQueue(MainActivity.this); String url = "http://maps.googleapis.com/maps/api/distancematrix/" + "json?origins=" + locationJsonObject.getString("origin") + "&destinations=" + locationJsonObject.getString("destination") + "&mode=driving&" + "language=en-EN&sensor=false"; StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() { @Override public void onResponse(String response) { mTextView.setText("Response is: " + response.substring(0, 500)); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { mTextView.setText("That didn''t work!"); } }); queue.add(stringRequest); }
public class GoogleDirection {
public final static String MODE_DRIVING = "driving";
public final static String MODE_WALKING = "walking";
public final static String MODE_BICYCLING = "bicycling";
public final static String STATUS_OK = "OK";
public final static String STATUS_NOT_FOUND = "NOT_FOUND";
public final static String STATUS_ZERO_RESULTS = "ZERO_RESULTS";
public final static String STATUS_MAX_WAYPOINTS_EXCEEDED = "MAX_WAYPOINTS_EXCEEDED";
public final static String STATUS_INVALID_REQUEST = "INVALID_REQUEST";
public final static String STATUS_OVER_QUERY_LIMIT = "OVER_QUERY_LIMIT";
public final static String STATUS_REQUEST_DENIED = "REQUEST_DENIED";
public final static String STATUS_UNKNOWN_ERROR = "UNKNOWN_ERROR";
public final static int SPEED_VERY_FAST = 1;
public final static int SPEED_FAST = 2;
public final static int SPEED_NORMAL = 3;
public final static int SPEED_SLOW = 4;
public final static int SPEED_VERY_SLOW = 5;
private OnDirectionResponseListener mDirectionListener = null;
private OnAnimateListener mAnimateListener = null;
private boolean isLogging = false;
private LatLng animateMarkerPosition = null;
private LatLng beginPosition = null;
private LatLng endPosition = null;
private ArrayList<LatLng> animatePositionList = null;
private Marker animateMarker = null;
private Polyline animateLine = null;
private GoogleMap gm = null;
private int step = -1;
private int animateSpeed = -1;
private int zoom = -1;
private double animateDistance = -1;
private double animateCamera = -1;
private double totalAnimateDistance = 0;
private boolean cameraLock = false;
private boolean drawMarker = false;
private boolean drawLine = false;
private boolean flatMarker = false;
private boolean isCameraTilt = false;
private boolean isCameraZoom = false;
private boolean isAnimated = false;
private Context mContext = null;
public GoogleDirection(Context context) {
mContext = context;
}
public String request(LatLng start, LatLng end, String mode) {
final String url = "http://maps.googleapis.com/maps/api/directions/xml?"
+ "origin=" + start.latitude + "," + start.longitude
+ "&destination=" + end.latitude + "," + end.longitude
+ "&sensor=false&units=metric&mode=" + mode;
if(isLogging)
Log.i("GoogleDirection", "URL : " + url);
new RequestTask().execute(new String[]{ url });
return url;
}
private class RequestTask extends AsyncTask<String, Void, Document> {
protected Document doInBackground(String... url) {
try {
HttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpPost httpPost = new HttpPost(url[0]);
HttpResponse response = httpClient.execute(httpPost, localContext);
InputStream in = response.getEntity().getContent();
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
return builder.parse(in);
} catch (IOException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(Document doc) {
super.onPostExecute(doc);
if(mDirectionListener != null)
mDirectionListener.onResponse(getStatus(doc), doc, GoogleDirection.this);
}
private String getStatus(Document doc) {
NodeList nl1 = doc.getElementsByTagName("status");
Node node1 = nl1.item(0);
if(isLogging)
Log.i("GoogleDirection", "Status : " + node1.getTextContent());
return node1.getTextContent();
}
}
public void setLogging(boolean state) {
isLogging = state;
}
public String getStatus(Document doc) {
NodeList nl1 = doc.getElementsByTagName("status");
Node node1 = nl1.item(0);
if(isLogging)
Log.i("GoogleDirection", "Status : " + node1.getTextContent());
return node1.getTextContent();
}
public String[] getDurationText(Document doc) {
NodeList nl1 = doc.getElementsByTagName("duration");
String[] arr_str = new String[nl1.getLength() - 1];
for(int i = 0 ; i < nl1.getLength() - 1 ; i++) {
Node node1 = nl1.item(i);
NodeList nl2 = node1.getChildNodes();
Node node2 = nl2.item(getNodeIndex(nl2, "text"));
arr_str[i] = node2.getTextContent();
if(isLogging)
Log.i("GoogleDirection", "DurationText : " + node2.getTextContent());
}
return arr_str;
}
public int[] getDurationValue(Document doc) {
NodeList nl1 = doc.getElementsByTagName("duration");
int[] arr_int = new int[nl1.getLength() - 1];
for(int i = 0 ; i < nl1.getLength() - 1 ; i++) {
Node node1 = nl1.item(i);
NodeList nl2 = node1.getChildNodes();
Node node2 = nl2.item(getNodeIndex(nl2, "value"));
arr_int[i] = Integer.parseInt(node2.getTextContent());
if(isLogging)
Log.i("GoogleDirection", "Duration : " + node2.getTextContent());
}
return arr_int;
}
public String getTotalDurationText(Document doc) {
NodeList nl1 = doc.getElementsByTagName("duration");
Node node1 = nl1.item(nl1.getLength() - 1);
NodeList nl2 = node1.getChildNodes();
Node node2 = nl2.item(getNodeIndex(nl2, "text"));
if(isLogging)
Log.i("GoogleDirection", "TotalDuration : " + node2.getTextContent());
return node2.getTextContent();
}
public int getTotalDurationValue(Document doc) {
NodeList nl1 = doc.getElementsByTagName("duration");
Node node1 = nl1.item(nl1.getLength() - 1);
NodeList nl2 = node1.getChildNodes();
Node node2 = nl2.item(getNodeIndex(nl2, "value"));
if(isLogging)
Log.i("GoogleDirection", "TotalDuration : " + node2.getTextContent());
return Integer.parseInt(node2.getTextContent());
}
public String[] getDistanceText(Document doc) {
NodeList nl1 = doc.getElementsByTagName("distance");
String[] arr_str = new String[nl1.getLength() - 1];
for(int i = 0 ; i < nl1.getLength() - 1 ; i++) {
Node node1 = nl1.item(i);
NodeList nl2 = node1.getChildNodes();
Node node2 = nl2.item(getNodeIndex(nl2, "text"));
arr_str[i] = node2.getTextContent();
if(isLogging)
Log.i("GoogleDirection", "DurationText : " + node2.getTextContent());
}
return arr_str;
}
public int[] getDistanceValue(Document doc) {
NodeList nl1 = doc.getElementsByTagName("distance");
int[] arr_int = new int[nl1.getLength() - 1];
for(int i = 0 ; i < nl1.getLength() - 1 ; i++) {
Node node1 = nl1.item(i);
NodeList nl2 = node1.getChildNodes();
Node node2 = nl2.item(getNodeIndex(nl2, "value"));
arr_int[i] = Integer.parseInt(node2.getTextContent());
if(isLogging)
Log.i("GoogleDirection", "Duration : " + node2.getTextContent());
}
return arr_int;
}
public String getTotalDistanceText(Document doc) {
NodeList nl1 = doc.getElementsByTagName("distance");
Node node1 = nl1.item(nl1.getLength() - 1);
NodeList nl2 = node1.getChildNodes();
Node node2 = nl2.item(getNodeIndex(nl2, "text"));
if(isLogging)
Log.i("GoogleDirection", "TotalDuration : " + node2.getTextContent());
return node2.getTextContent();
}
public int getTotalDistanceValue(Document doc) {
NodeList nl1 = doc.getElementsByTagName("distance");
Node node1 = nl1.item(nl1.getLength() - 1);
NodeList nl2 = node1.getChildNodes();
Node node2 = nl2.item(getNodeIndex(nl2, "value"));
if(isLogging)
Log.i("GoogleDirection", "TotalDuration : " + node2.getTextContent());
return Integer.parseInt(node2.getTextContent());
}
public String getStartAddress(Document doc) {
NodeList nl1 = doc.getElementsByTagName("start_address");
Node node1 = nl1.item(0);
if(isLogging)
Log.i("GoogleDirection", "StartAddress : " + node1.getTextContent());
return node1.getTextContent();
}
public String getEndAddress(Document doc) {
NodeList nl1 = doc.getElementsByTagName("end_address");
Node node1 = nl1.item(0);
if(isLogging)
Log.i("GoogleDirection", "StartAddress : " + node1.getTextContent());
return node1.getTextContent();
}
public String getCopyRights(Document doc) {
NodeList nl1 = doc.getElementsByTagName("copyrights");
Node node1 = nl1.item(0);
if(isLogging)
Log.i("GoogleDirection", "CopyRights : " + node1.getTextContent());
return node1.getTextContent();
}
public ArrayList<LatLng> getDirection(Document doc) {
NodeList nl1, nl2, nl3;
ArrayList<LatLng> listGeopoints = new ArrayList<LatLng>();
nl1 = doc.getElementsByTagName("step");
if (nl1.getLength() > 0) {
for (int i = 0; i < nl1.getLength(); i++) {
Node node1 = nl1.item(i);
nl2 = node1.getChildNodes();
Node locationNode = nl2.item(getNodeIndex(nl2, "start_location"));
nl3 = locationNode.getChildNodes();
Node latNode = nl3.item(getNodeIndex(nl3, "lat"));
double lat = Double.parseDouble(latNode.getTextContent());
Node lngNode = nl3.item(getNodeIndex(nl3, "lng"));
double lng = Double.parseDouble(lngNode.getTextContent());
listGeopoints.add(new LatLng(lat, lng));
locationNode = nl2.item(getNodeIndex(nl2, "polyline"));
nl3 = locationNode.getChildNodes();
latNode = nl3.item(getNodeIndex(nl3, "points"));
ArrayList<LatLng> arr = decodePoly(latNode.getTextContent());
for(int j = 0 ; j < arr.size() ; j++) {
listGeopoints.add(new LatLng(arr.get(j).latitude
, arr.get(j).longitude));
}
locationNode = nl2.item(getNodeIndex(nl2, "end_location"));
nl3 = locationNode.getChildNodes();
latNode = nl3.item(getNodeIndex(nl3, "lat"));
lat = Double.parseDouble(latNode.getTextContent());
lngNode = nl3.item(getNodeIndex(nl3, "lng"));
lng = Double.parseDouble(lngNode.getTextContent());
listGeopoints.add(new LatLng(lat, lng));
}
}
return listGeopoints;
}
public ArrayList<LatLng> getSection(Document doc) {
NodeList nl1, nl2, nl3;
ArrayList<LatLng> listGeopoints = new ArrayList<LatLng>();
nl1 = doc.getElementsByTagName("step");
if (nl1.getLength() > 0) {
for (int i = 0; i < nl1.getLength(); i++) {
Node node1 = nl1.item(i);
nl2 = node1.getChildNodes();
Node locationNode = nl2.item(getNodeIndex(nl2, "end_location"));
nl3 = locationNode.getChildNodes();
Node latNode = nl3.item(getNodeIndex(nl3, "lat"));
double lat = Double.parseDouble(latNode.getTextContent());
Node lngNode = nl3.item(getNodeIndex(nl3, "lng"));
double lng = Double.parseDouble(lngNode.getTextContent());
listGeopoints.add(new LatLng(lat, lng));
}
}
return listGeopoints;
}
public PolylineOptions getPolyline(Document doc, int width, int color) {
ArrayList<LatLng> arr_pos = getDirection(doc);
PolylineOptions rectLine = new PolylineOptions().width(dpToPx(width)).color(color);
for(int i = 0 ; i < arr_pos.size() ; i++)
rectLine.add(arr_pos.get(i));
return rectLine;
}
private int getNodeIndex(NodeList nl, String nodename) {
for(int i = 0 ; i < nl.getLength() ; i++) {
if(nl.item(i).getNodeName().equals(nodename))
return i;
}
return -1;
}
private ArrayList<LatLng> decodePoly(String encoded) {
ArrayList<LatLng> poly = new ArrayList<LatLng>();
int index = 0, len = encoded.length();
int lat = 0, lng = 0;
while (index < len) {
int b, shift = 0, result = 0;
do {
b = encoded.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lat += dlat;
shift = 0;
result = 0;
do {
b = encoded.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lng += dlng;
LatLng position = new LatLng((double)lat / 1E5, (double)lng / 1E5);
poly.add(position);
}
return poly;
}
private int dpToPx(int dp) {
DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics();
int px = Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
return px;
}
public void setOnDirectionResponseListener(OnDirectionResponseListener listener) {
mDirectionListener = listener;
}
public void setOnAnimateListener(OnAnimateListener listener) {
mAnimateListener = listener;
}
public interface OnDirectionResponseListener {
public void onResponse(String status, Document doc, GoogleDirection gd);
}
public interface OnAnimateListener {
public void onFinish();
public void onStart();
public void onProgress(int progress, int total);
}
public void animateDirection(GoogleMap gm, ArrayList<LatLng> direction, int speed
, boolean cameraLock, boolean isCameraTilt, boolean isCameraZoom
, boolean drawMarker, MarkerOptions mo, boolean flatMarker
, boolean drawLine, PolylineOptions po) {
if(direction.size() > 1) {
isAnimated = true;
animatePositionList = direction;
animateSpeed = speed;
this.drawMarker = drawMarker;
this.drawLine = drawLine;
this.flatMarker = flatMarker;
this.isCameraTilt = isCameraTilt;
this.isCameraZoom = isCameraZoom;
step = 0;
this.cameraLock = cameraLock;
this.gm = gm;
setCameraUpdateSpeed(speed);
beginPosition = animatePositionList.get(step);
endPosition = animatePositionList.get(step + 1);
animateMarkerPosition = beginPosition;
if(mAnimateListener != null)
mAnimateListener.onProgress(step, animatePositionList.size());
if(cameraLock) {
float bearing = getBearing(beginPosition, endPosition);
CameraPosition.Builder cameraBuilder = new CameraPosition.Builder()
.target(animateMarkerPosition).bearing(bearing);
if(isCameraTilt)
cameraBuilder.tilt(90);
else
cameraBuilder.tilt(gm.getCameraPosition().tilt);
if(isCameraZoom)
cameraBuilder.zoom(zoom);
else
cameraBuilder.zoom(gm.getCameraPosition().zoom);
CameraPosition cameraPosition = cameraBuilder.build();
gm.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
}
if(drawMarker) {
if(mo != null)
animateMarker = gm.addMarker(mo.position(beginPosition));
else
animateMarker = gm.addMarker(new MarkerOptions().position(beginPosition));
if(flatMarker) {
animateMarker.setFlat(true);
float rotation = getBearing(animateMarkerPosition, endPosition) + 180;
animateMarker.setRotation(rotation);
}
}
if(drawLine) {
if(po != null)
animateLine = gm.addPolyline(po.add(beginPosition)
.add(beginPosition).add(endPosition)
.width(dpToPx((int)po.getWidth())));
else
animateLine = gm.addPolyline(new PolylineOptions()
.width(dpToPx(5)));
}
new Handler().postDelayed(r, speed);
if(mAnimateListener != null)
mAnimateListener.onStart();
}
}
public void cancelAnimated() {
isAnimated = false;
}
public boolean isAnimated() {
return isAnimated;
}
private Runnable r = new Runnable() {
public void run() {
animateMarkerPosition = getNewPosition(animateMarkerPosition, endPosition);
if(drawMarker)
animateMarker.setPosition(animateMarkerPosition);
if(drawLine) {
List<LatLng> points = animateLine.getPoints();
points.add(animateMarkerPosition);
animateLine.setPoints(points);
}
if((animateMarkerPosition.latitude == endPosition.latitude
&& animateMarkerPosition.longitude == endPosition.longitude)) {
if(step == animatePositionList.size() - 2) {
isAnimated = false;
totalAnimateDistance = 0;
if(mAnimateListener != null)
mAnimateListener.onFinish();
} else {
step++;
beginPosition = animatePositionList.get(step);
endPosition = animatePositionList.get(step + 1);
animateMarkerPosition = beginPosition;
if(flatMarker && step + 3 < animatePositionList.size() - 1) {
float rotation = getBearing(animateMarkerPosition, animatePositionList.get(step + 3)) + 180;
animateMarker.setRotation(rotation);
}
if(mAnimateListener != null)
mAnimateListener.onProgress(step, animatePositionList.size());
}
}
if(cameraLock && (totalAnimateDistance > animateCamera || !isAnimated)) {
totalAnimateDistance = 0;
float bearing = getBearing(beginPosition, endPosition);
CameraPosition.Builder cameraBuilder = new CameraPosition.Builder()
.target(animateMarkerPosition).bearing(bearing);
if(isCameraTilt)
cameraBuilder.tilt(90);
else
cameraBuilder.tilt(gm.getCameraPosition().tilt);
if(isCameraZoom)
cameraBuilder.zoom(zoom);
else
cameraBuilder.zoom(gm.getCameraPosition().zoom);
CameraPosition cameraPosition = cameraBuilder.build();
gm.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
}
if(isAnimated) {
new Handler().postDelayed(r, animateSpeed);
}
}
};
public Marker getAnimateMarker() {
return animateMarker;
}
public Polyline getAnimatePolyline() {
return animateLine;
}
private LatLng getNewPosition(LatLng begin, LatLng end) {
double lat = Math.abs(begin.latitude - end.latitude);
double lng = Math.abs(begin.longitude - end.longitude);
double dis = Math.sqrt(Math.pow(lat, 2) + Math.pow(lng, 2));
if(dis >= animateDistance) {
double angle = -1;
if(begin.latitude <= end.latitude && begin.longitude <= end.longitude)
angle = Math.toDegrees(Math.atan(lng / lat));
else if(begin.latitude > end.latitude && begin.longitude <= end.longitude)
angle = (90 - Math.toDegrees(Math.atan(lng / lat))) + 90;
else if(begin.latitude > end.latitude && begin.longitude > end.longitude)
angle = Math.toDegrees(Math.atan(lng / lat)) + 180;
else if(begin.latitude <= end.latitude && begin.longitude > end.longitude)
angle = (90 - Math.toDegrees(Math.atan(lng / lat))) + 270;
double x = Math.cos(Math.toRadians(angle)) * animateDistance;
double y = Math.sin(Math.toRadians(angle)) * animateDistance;
totalAnimateDistance += animateDistance;
double finalLat = begin.latitude + x;
double finalLng = begin.longitude + y;
return new LatLng(finalLat, finalLng);
} else {
return end;
}
}
private float getBearing(LatLng begin, LatLng end) {
double lat = Math.abs(begin.latitude - end.latitude);
double lng = Math.abs(begin.longitude - end.longitude);
if(begin.latitude < end.latitude && begin.longitude < end.longitude)
return (float)(Math.toDegrees(Math.atan(lng / lat)));
else if(begin.latitude >= end.latitude && begin.longitude < end.longitude)
return (float)((90 - Math.toDegrees(Math.atan(lng / lat))) + 90);
else if(begin.latitude >= end.latitude && begin.longitude >= end.longitude)
return (float)(Math.toDegrees(Math.atan(lng / lat)) + 180);
else if(begin.latitude < end.latitude && begin.longitude >= end.longitude)
return (float)((90 - Math.toDegrees(Math.atan(lng / lat))) + 270);
return -1;
}
public void setCameraUpdateSpeed(int speed) {
if(speed == SPEED_VERY_SLOW) {
animateDistance = 0.000005;
animateSpeed = 20;
animateCamera = 0.0004;
zoom = 19;
} else if(speed == SPEED_SLOW) {
animateDistance = 0.00001;
animateSpeed = 20;
animateCamera = 0.0008;
zoom = 18;
} else if(speed == SPEED_NORMAL) {
animateDistance = 0.00005;
animateSpeed = 20;
animateCamera = 0.002;
zoom = 16;
} else if(speed == SPEED_FAST) {
animateDistance = 0.0001;
animateSpeed = 20;
animateCamera = 0.004;
zoom = 15;
} else if(speed == SPEED_VERY_FAST) {
animateDistance = 0.0005;
animateSpeed = 20;
animateCamera = 0.004;
zoom = 13;
} else {
animateDistance = 0.00005;
animateSpeed = 20;
animateCamera = 0.002;
zoom = 16;
}
}
}
//Actividad principal
public class MapActivity extends ActionBarActivity {
GoogleMap map = null;
GoogleDirection gd;
LatLng start,end;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
start = new LatLng(13.744246499553903, 100.53428772836924);
end = new LatLng(13.751279688694071, 100.54316081106663);
map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
map.animateCamera(CameraUpdateFactory.newLatLngZoom(start, 15));
gd = new GoogleDirection(this);
gd.setOnDirectionResponseListener(new GoogleDirection.OnDirectionResponseListener() {
public void onResponse(String status, Document doc, GoogleDirection gd) {
Toast.makeText(getApplicationContext(), status, Toast.LENGTH_SHORT).show();
gd.animateDirection(map, gd.getDirection(doc), GoogleDirection.SPEED_FAST
, true, true, true, false, null, false, true, new PolylineOptions().width(8).color(Color.RED));
map.addMarker(new MarkerOptions().position(start)
.icon(BitmapDescriptorFactory.fromResource(R.drawable.markera)));
map.addMarker(new MarkerOptions().position(end)
.icon(BitmapDescriptorFactory.fromResource(R.drawable.markerb)));
String TotalDistance = gd.getTotalDistanceText(doc);
String TotalDuration = gd.getTotalDurationText(doc);
}
});
gd.request(start, end, GoogleDirection.MODE_DRIVING);
}
}