Grupo de mapas de Google con dirección

Tenemos una biblioteca de mapas de Google para mostrar múltiples marcadores en el clúster.

Tengo dos preguntas:

1. ¿Podemos mostrar múltiples direcciones en el mapa de Google como imagen abajo?

2. ¿Podemos mostrar múltiples detalles de dirección en los marcadores de clúster?

Introduzca aquí la descripción de la imagen

Cluster es como a continuación:

Te voy a dar ejemplos: para el país India tengo guardar diferentes direcciones en mi db.

me gusta

Ahmedabad a delhi

Delhi a Agra

Ahmedabad para bombay

Jaypur a delhi

Tengo que mostrar el clúster de direcciones anteriores dependen del nivel de zoom, cuando el usuario zoom Google mapa, en lugar de los clústeres hay múltiples direcciones que muestran en Google Map.

Quiero saber si es posible? En caso afirmativo, ¿cómo?

Puede alcanzar su objetivo utilizando la API de direcciones. Suministra el punto de partida y el punto final (puede ser lat / lon o nombre del lugar). Otro campo requerido es el modo de viaje (conducir por defecto).

Ahora las direcciones devuelven los vértices que pueden ser transformados en una polilínea y dibujados en el mapa. Esta respuesta que hace bastante bien y voy a estar usando su código.

package com.example.simon.maps; import java.util.ArrayList; import java.util.List; import org.w3c.dom.Document; 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.CameraPosition; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.Polyline; import com.google.android.gms.maps.model.PolylineOptions; import android.graphics.Color; import android.os.Bundle; import android.os.StrictMode; import android.support.v4.app.FragmentActivity; import android.util.Log; import android.util.SparseArray; /** * Created by Simon on 2014 Jul 25. */ public class MainActivity extends FragmentActivity { final static String TAG = "MainActivity"; GoogleMap mMap; GMapV2Direction md; int mZoomLevel; final float STARTING_ZOOM = 5.0f; // List of polylines for each zoom level SparseArray<List<Polyline>> mPolylines = new SparseArray<List<Polyline>>(); public class direction { String start, end; int zoomLevel; direction(String pStart, String pEnd, int pZoomLevel) { start = pStart; end = pEnd; zoomLevel = pZoomLevel; } } public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (android.os.Build.VERSION.SDK_INT > 9) { StrictMode.ThreadPolicy p = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(p); } md = new GMapV2Direction(); mMap = ((MapFragment)getFragmentManager().findFragmentById(R.id.map)).getMap(); List<direction> directions = new ArrayList<direction>(); directions.add(new direction("Ahmedabad,Gujarat,India", "delhi,India", 4)); directions.add(new direction("Ahmedabad,Gujarat,India","Bombay,Maharashtra,India", 4)); directions.add(new direction("Jeypore,Odisha,India", "delhi,India", 5)); for (MainActivity.direction direction : directions) { // Query Document doc = md.getDocument(direction.start, direction.end); // Parse the xml if (doc == null) { Log.e(TAG, "Failed to get the route from " + direction.start + " to " + direction.end); continue; } // Get points ArrayList<LatLng> directionPoint = md.getDirection(doc); // Convert vertexes to a polyline PolylineOptions rectLine = new PolylineOptions().width(3).color(Color.RED); for (LatLng aDirectionPoint : directionPoint) { rectLine.add(aDirectionPoint); } // Add poly to the map addPolyline(rectLine, direction.zoomLevel); } // Get the starting point of the first direction LatLng start = mPolylines.valueAt(0).get(0).getPoints().get(0); mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(start, STARTING_ZOOM), 1000, null); // Set the initial zoom level and show the necessary polylines mZoomLevel = (int) STARTING_ZOOM; initPolylines(mZoomLevel); // Listen for the camera zoom level changes mMap.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() { @Override public void onCameraChange(CameraPosition cameraPosition) { // Note that because we are casting the zoomLevel to int, // it will be considered as changed only when it reaches // a new integer when rounded (eg 5.0, 6.0 etc.) int newZoomLevel = (int) cameraPosition.zoom; if (newZoomLevel != mZoomLevel) { Log.d(TAG, "New zoom level: " + newZoomLevel); // Loop all the changed zoom levels // Eg zoomed-out from 15 to 13, then hide [14, 15] if (newZoomLevel < mZoomLevel) { // Zoomed out for (int i=1; i<=mZoomLevel-newZoomLevel; i++) hidePolylines(mPolylines.get(newZoomLevel+i)); } else { // Zoomed-in for (int i=1; i<=newZoomLevel-mZoomLevel; i++) showPolylines(mPolylines.get(mZoomLevel + i)); } mZoomLevel = newZoomLevel; } } }); } private void addPolyline(PolylineOptions polyOpts, int zoomLevel) { List<Polyline> polylines = mPolylines.get(zoomLevel); // Create polyline list for this zoom level, if it still doesn't exist if (polylines == null) { polylines = new ArrayList<Polyline>(); mPolylines.put(zoomLevel, polylines); } // Append a new item to this poly list Polyline polyline = mMap.addPolyline(polyOpts); polyline.setVisible(false); polylines.add(polyline); } private void initPolylines(int zoomLevel) { for(int i=0; i<mPolylines.size(); i++) { // Loop until zoom level is reached if (mPolylines.keyAt(i) > zoomLevel) break; showPolylines(mPolylines.get(mPolylines.keyAt(i))); } } private void showPolylines(List<Polyline> polylines) { if (polylines != null) for (Polyline polyline : polylines) polyline.setVisible(true); } private void hidePolylines(List<Polyline> polylines) { if (polylines != null) for (Polyline polyline : polylines) polyline.setVisible(false); } } 

Este código agrega las polilíneas a un SparseArray que contiene las polilíneas para cada nivel de zoom. Todas las polias están ocultas por defecto y se revelan sólo cuando se alcanza un nivel de zoom específico (también en initPolylines ).

Hay algunas cosas a tener en cuenta aquí:

  1. Debido a que el zoom puede cambiar por unos pocos niveles a la vez, hacemos un bucle en cada nivel para ocultar / mostrar instrucciones específicas.
  2. Los nombres de ubicación deben ser precisos o no se encontrarán y es posible que reciba un montón de errores en el código (sólo he agregado un Log.e)
  3. Si desea crear marcadores en, digamos el punto inicial y final de la dirección, puede utilizar el siguiente código para obtener las coordenadas:

     List<LatLng> points = mPolylines.valueAt(0).get(0).getPoints(); LatLng start = points.get(0); LatLng end = points.get(points.size()-1); 
  4. Los marcadores se pueden agregar / quitar en niveles de zoom específicos, como se hace aquí con las polilíneas.

Y aquí está el código del analizador xml (GMapV2Direction):

 package com.example.simon.maps; import java.io.InputStream; import java.util.ArrayList; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import com.google.android.gms.maps.model.LatLng; public class GMapV2Direction { public GMapV2Direction() { } public Document getDocument(String start, String end) { String url = "http://maps.googleapis.com/maps/api/directions/xml?" + "origin="+start+"&destination="+end+"&units=metric&mode=driving"; try { HttpClient httpClient = new DefaultHttpClient(); HttpContext localContext = new BasicHttpContext(); HttpPost httpPost = new HttpPost(url); HttpResponse response = httpClient.execute(httpPost, localContext); InputStream in = response.getEntity().getContent(); DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); return builder.parse(in); } catch (Exception e) { e.printStackTrace(); } return null; } 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 (LatLng anArr : arr) { listGeopoints.add(new LatLng(anArr.latitude, anArr.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; } 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; } } 

Algunas notas finales:

  • Si tienes un montón de instrucciones cargarlos dentro de initPolylines y showPolylines y descargarlos en hidePolylines
  • Si las direcciones que desea mostrar en el mapa son constantes, la mejor manera sería usar azulejos con polilíneas en niveles de zoom específicos. Una buena herramienta gratuita para que sea Maperitive , puede exportar los azulejos a tantos niveles de zoom como desee. A continuación, almacenar las baldosas en línea y utilizar UrlTileProvider para mostrarlos en su mapa.

No sé si he entendido su pregunta correctamente, pero voy a tratar de responder de todos modos. Puede crear múltiples polilíneas y agregar al mapa de la respuesta JSON de la API de dirección de google maps . De esta manera puede agregar varias rutas en un solo mapa.

Por lo que he entendido la segunda pregunta, desea que el marcador de cluster para dar detalles de las rutas que está dibujando. Para eso, supongo que puedes agrupar los puntos devueltos por la API y usar clústeres de marcadores personalizados para mostrar la información que deseas.

Espero eso ayude

-Editar- Si quieres dibujar rutas en una aplicación para Android, no obtienes ningún DirectionRenderer que puedas usar. Necesita representar las rutas utilizando polilíneas. Es por eso que he mencionado la creación de polilíneas en la respuesta anterior. Como respuesta a la solicitud de dirección, se obtiene un JSON que contiene varios puntos de coordenadas que se pueden unir dibujando una polilínea a través de ellos. Puede tener varias polilíneas en un mapa (desde cualquier punto hasta cualquier punto). Caso 1: desea 2 rutas de Bombay a Goa, establezca el parámetro alternativas a true. Caso 2: desea dos rutas diferentes, Bangalore a Bombay, Goa a Delhi, hacer dos solicitudes diferentes a la API. Obtendrás dos rutas diferentes y dibujarlas en el mapa.

Para su segunda pregunta, ya que no hay agrupación inbuilt para rutas (polilíneas), tiene que codificar la lógica de los iconos de cluster que aparecen en el mapa. Para obtener el nivel de zoom actual, utilice lo siguiente.

 GoogleMap map; float zoom = map.getCameraPosition().zoom; 

Para mostrar y ocultar polilíneas

 Polyline line = map.addPolyline(new PolylineOptions() .add(new LatLng(51.5, -0.1), new LatLng(40.7, -74.0)) // multiple points that you get from the response of directions API .width(5) .color(Color.RED)); //your logic for visibility if(zoom<=5){ line.setVisible(true); } 

No pude encontrar ninguna forma en la API para ocultar el icono de clúster utilizando código. Supongo que debería ocultarse después de cierto nivel de zoom.

  • Cómo enfocar el marcador de Google por marcador de título?
  • Android Studio - No se puede volver a cargar la lista de AVD (d: skin)
  • Google Maps Mobile SDK para empresas vs. API de Google Maps para Android
  • Cómo dibujar una ruta utilizando diferentes valores long lat?
  • Hacer algo cuando estoy dentro del radio del círculo
  • Extraño error "java.io.IOException: EOF" en Android
  • GetMap () devuelve null en Android con Google Maps API v2
  • Dibuja el camino de GoogleMap con 9patch
  • Cómo agregar animaciones personalizadas en Google Map V3 Marker cuando suelto cada marcador uno por uno?
  • Uso de la biblioteca de Google Places en la aplicación nativa de Android
  • Multiple MapActivitys en la pila
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.