Google map cluster avec direction

Nous disposons d'une bibliothèque de cartes Google pour afficher plusieurs marqueurs en grappe.

J'ai deux questions:

  • Android Studio ne reconnaît pas les importations Espresso
  • Android TextView: définir la couleur d'arrière-plan de manière dynamique ne fonctionne pas
  • Problème avec le fournisseur OpenGL natif
  • HashMap to ListView
  • Quelle est la meilleure façon d'appeler StartPreview () après la capture d'une image?
  • Accédez au site hôte local dans un appareil Android via wifi
  • 1. Peut-on afficher plusieurs Directions sur la carte Google comme l'image ci-dessous?

    2. Peut-on afficher plusieurs détails de direction dans les marqueurs de cluster?

    Entrez la description de l'image ici

    Cluster est comme ci-dessous:

    Je vais vous donner des exemples: dans le pays Inde, j'ai sauvegarder différentes directions dans mon db.

    comme

    Ahmedabad à delhi

    Delhi à Agra

    Ahmedabad à bombay

    Jaypur à delhi

    Je dois montrer que le cluster des directions ci-dessus dépend du niveau de zoom, lorsque l'utilisateur agrandit la carte Google, au lieu des clusters il y a plusieurs directions montrant sur Google Map.

    Je veux savoir si c'est possible? Si oui, comment?

    2 Solutions collect form web for “Google map cluster avec direction”

    Vous pouvez atteindre votre objectif en utilisant l'API Directions. Vous fournissez le point de départ et le point de fin (il peut être lat / lon ou nom de l'endroit). Un autre champ obligatoire est le mode de déplacement (conduite par défaut).

    Maintenant, les Directions renvoient les sommets qui peuvent être transformés en polyligne puis dessinés sur la carte. Cette réponse le rend très bien et j'utiliserai son code.

    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); } } 

    Ce code ajoute les polylignes à un SparseArray qui détient les polylignes pour chaque niveau de zoom. Toutes les polies sont cachées par défaut et ne sont révélées que lorsqu'un niveau de zoom spécifique est atteint (également à initPolylines ).

    Il y a quelques points à noter ici:

    1. Étant donné que le zoom peut changer de quelques niveaux, on boucle chaque niveau pour cacher / afficher des directions spécifiques.
    2. Les noms de localisation doivent être précis ou ils ne seront pas trouvés et vous pourriez recevoir un tas d'erreurs dans le code (j'ai seulement ajouté un Log.e)
    3. Si vous souhaitez créer des marqueurs à, disons le point de départ et de fin de la direction, vous pouvez utiliser le code suivant pour obtenir les coordonnées:

       List<LatLng> points = mPolylines.valueAt(0).get(0).getPoints(); LatLng start = points.get(0); LatLng end = points.get(points.size()-1); 
    4. Les marqueurs peuvent être ajoutés / supprimés à des niveaux de zoom spécifiques, tout comme il est fait ici avec les polylignes.

    Et voici le code de l'analyseur 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; } } 

    Quelques notes finales:

    • Si vous avez beaucoup de directions, chargez-les à l'intérieur des initPolylines et showPolylines et déchargez-les dans hidePolylines
    • Si les directions que vous souhaitez afficher sur la carte sont constantes, la meilleure façon serait d'utiliser des carreaux avec des polylignes sur des niveaux de zoom spécifiques. Un bon outil gratuit pour cela est Maperitive , il peut exporter les carreaux à autant de niveaux de zoom que vous le souhaitez. Ensuite, vous stockez les carreaux en ligne et utilisez UrlTileProvider pour les afficher sur votre carte.

    Je ne sais pas si j'ai bien compris votre question, mais je vais essayer de répondre de toute façon. Vous pouvez créer plusieurs polylignes et ajouter à la carte à partir de la réponse JSON à partir de Google Maps direction API . De cette façon, vous pouvez ajouter plusieurs itinéraires dans une seule carte.

    Dans la mesure où j'ai compris la deuxième question, vous voulez que le marqueur de cluster donne les détails des itinéraires que vous dessinez. Pour cela, je suppose que vous pouvez regrouper les points renvoyés par l'API et utiliser des clusters de marqueurs personnalisés pour afficher les informations souhaitées.

    J'espère que cela aide

    -Edit- Si vous souhaitez dessiner des itinéraires dans une application Android, vous n'obtenez aucun DirectionRenderer que vous pouvez utiliser. Vous devez rendre les itinéraires à l'aide de Polylines. C'est pourquoi j'ai mentionné la création de polylignes dans la réponse ci-dessus. En réponse à la demande de direction, vous obtenez un JSON contenant plusieurs points de coordonnées qui peuvent être joints en dessinant une polyligne à travers eux. Vous pouvez avoir plusieurs polylignes sur une carte (de n'importe quel point à n'importe quel point). Cas 1: vous voulez 2 itinéraires de Bombay vers Goa, définissez le paramètre alternative comme vrai. Cas 2: vous voulez deux routes différentes, Bangalore à Bombay, Goa à Delhi, faites deux demandes différentes à l'API. Vous obtiendrez deux itinéraires différents et dessinez-les sur la carte.

    Pour votre deuxième question, puisqu'il n'y a pas de clustering intégré pour les routes (polylines), vous devez coder la logique des icônes de cluster qui s'affichent dans la carte. Pour obtenir le niveau de zoom actuel, utilisez ce qui suit.

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

    Pour montrer et cacher des polylignes

     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); } 

    Je ne pouvais trouver aucun moyen dans l'API de masquer l'icône du cluster à l'aide du code. Je suppose qu'il devrait se cacher après un certain niveau de zoom.

    coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.