El desplazamiento y el zoom de MapView es lento después de agregar muchas superposiciones

Así que he pasado una buena cantidad de tiempo tratando de averiguar cómo acelerar esto, pero estoy fuera de ideas ahora. Tengo una clase, mapPopup en la que se muestra un MapView en toda la pantalla. Hay una matriz de una matriz de GeoPoint en mapPopup , y quiero dibujar líneas entre cada GeoPoint en las 2das dimensiones de la matriz. Ya he logrado esta tarea usando una clase personalizada, mapOverlay , que extiende Overlay , pero el problema que tengo es que una vez que todas las superposiciones de mapa se dibujan, el mapa es extremadamente lento para hacer zoom o pan. Una vez que todas las superposiciones se agregan al mapa, a menudo hay más de 2000, pero son todas muy pequeñas.

Pensando que el mapa funcionaría más rápidamente si hubiera menos superposiciones, dibujé todas las líneas a tres capas separadas en lugar de una superposición separada para cada línea. Esto realmente se tradujo en SLOWER panning y zoom del mapa, así que volví a las muchas pequeñas superposiciones.

Apreciaría algunas descripciones informativas y fáciles de entender de un método que podría emplear para hacer el mapa más rápido. Pseudocódigo o código real para el método potencial también me ayudaría a entender mejor. Mi código se publica a continuación. Una vez más, tenga en cuenta que mis superposiciones y mapa se muestran correctamente; Me gustaría un método que permita una panorámica y un zoom más rápidos.

MapOverlay clase

 public class mapOverlay extends Overlay { private Projection projection; private GeoPoint gp1; private GeoPoint gp2; private int color; public mapOverlay(int color, MapView map, GeoPoint geo1, GeoPoint geo2) { // super(); this.projection = map.getProjection(); this.gp1 = geo1; this.gp2 = geo2; this.color = color; } public void draw(Canvas canvas, MapView mapv, boolean shadow) { super.draw(canvas, mapv, false); Paint mPaint = new Paint(); mPaint.setDither(true); mPaint.setStyle(Paint.Style.FILL_AND_STROKE); mPaint.setStrokeJoin(Paint.Join.ROUND); mPaint.setStrokeCap(Paint.Cap.ROUND); mPaint.setStrokeWidth(4); mPaint.setColor(this.color); Point p1 = new Point(); Point p2 = new Point(); Path path1 = new Path(); projection.toPixels(gp1, p1); projection.toPixels(gp2, p2); path1.moveTo(p1.x, p1.y); path1.lineTo(p2.x, p2.y); canvas.drawPath(path1, mPaint); } } 

MapPopup class

 public class mapPopup extends MapActivity { public String[] trailNames; public String tableName = ""; public int numTrails = 0; public static GeoPoint[][] geoPoints; public int[] colors = new int[] { Color.WHITE, Color.BLUE, Color.CYAN, Color.RED, Color.YELLOW, Color.MAGENTA, Color.GRAY, Color.LTGRAY }; public int[] newColors; // public Bitmap b; public GeoPoint firstP; public void loadMapData(Bitmap b, MapView map, int[] colors, GeoPoint[][] GPAA, int ZoomLevel) { // GPAA holds an array of an array of GeoPoint Log.i("DEBUG", "starting loadMapDataTask"); map.setSatellite(true); MapController mc = map.getController(); mapOverlay[][] mapOverlay = new mapOverlay[GPAA.length][]; Log.i("DEBUG", "length of GPAA is: " + GPAA.length); // i cycles through the first dimension of GPAA for (int i = 0; i < GPAA.length; i++) { GeoPoint[] geoPoints = GPAA[i]; int length = geoPoints.length - 1; mapOverlay[i] = new mapOverlay[length]; // int pointCount = 0; // z cycles through the second dimension of GPAA for (int z = 0; z < length; z++) { mapOverlay[i][z] = new mapOverlay(colors[i], map, geoPoints[pointCount], geoPoints[pointCount + 1]); pointCount++; } } // Actually adds overlays to map List<Overlay> mapOverlays = map.getOverlays(); for (int i = 0; i < mapOverlay.length; i++) { int length = mapOverlay[i].length; Log.i("DEBUG", "Adding map overlays for trail: " + i); Log.i("DEBUG", "Length of mapOverlay[i] is: " + length); for (int z = 0; z < length; z++) { mapOverlays.add(mapOverlay[i][z]); } } mc.animateTo(GPAA[0][0]); mc.setZoom(ZoomLevel); Rect r = new Rect(); map.getDrawingRect(r); map.invalidate(r); } public static class runBGLoad extends AsyncTask<bgLoadParam, Integer, GeoPoint[][]> { public GeoPoint[][] geoPoints; protected GeoPoint[] getGPa(Context context, String name, int ID) { File file = context.getFileStreamPath(name); if (file.exists() == false) { Log.i("DEBUG", "Creating file"); InputStream is; FileOutputStream fos; try { Log.i("DEBUG", "id is " + ID); is = context.getResources().openRawResource(ID); byte[] buffer = new byte[is.available()]; is.read(buffer); fos = context.openFileOutput(name, Context.MODE_PRIVATE); fos.write(buffer); fos.close(); is.close(); } catch (IOException e) { e.printStackTrace(); } } else { Log.i("DEBUG", "File already exists"); } // Log.i("DEBUG", "starting to get geopoints"); List<Location> gpsPoints = XMLParser.getPoints(file); int i = 0; int index = 0; GeoPoint[] geoPoints = new GeoPoint[gpsPoints.size()]; // makes list of gpsPoints into GeoPoint[] ListIterator<Location> it = gpsPoints.listIterator(); while (it.hasNext()) { index = it.nextIndex(); Location loc = gpsPoints.get(index); geoPoints[i] = new GeoPoint((int) (loc.getLatitude() * 1E6), (int) (loc.getLongitude() * 1E6)); it.next(); i++; } return geoPoints; } @Override protected GeoPoint[][] doInBackground(bgLoadParam... params) { Context context = params[0].getContext(); int tNLength = params[0].getTNames().length; geoPoints = new GeoPoint[tNLength][]; for (int i = 0; i < params[0].getTNames().length; i++) { String modName = params[0].getTNames()[i].toLowerCase() .replace(' ', '_'); int identifier = context.getResources().getIdentifier(modName, "raw", context.getPackageName()); geoPoints[i] = getGPa(params[0].getContext(), modName + "_mapfile", identifier); } Log.i("DEBUG", "TEST"); mapPopup.geoPoints = geoPoints; Log.i("DEBUG", "TEST2"); return geoPoints; } @Override protected void onPostExecute(GeoPoint[][] result) { Log.i("DEBUG", "The points are loaded."); mapPopup.geoPoints = result; } } @Override public void onCreate(Bundle savedInstanceState) { Intent intent = getIntent(); String[] extras = intent.getStringArrayExtra("strings"); tableName = extras[1]; numTrails = Integer.parseInt(extras[2]); trailNames = intent.getStringArrayExtra("trailNamesA"); super.onCreate(savedInstanceState); setContentView(R.layout.map_popup_layout); newColors = new int[numTrails]; for (int i = 0; i < numTrails; i++) { newColors[i] = colors[i]; } ViewGroup layout = (ViewGroup) findViewById(R.id.map_popup); TextView[] tVs = new TextView[numTrails]; for (int i = 0; i < numTrails; i++) { LayoutParams params = new RelativeLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); tVs[i] = new TextView(getApplicationContext()); tVs[i].setText(trailNames[i]); tVs[i].setId(i + 700); tVs[i].setTextColor(colors[i]); tVs[i].setBackgroundColor(Color.BLACK); if (i > 0) { params.addRule(RelativeLayout.BELOW, (699 + i)); } layout.addView(tVs[i], params); } } @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); MapView map = (MapView) findViewById(R.id.popupMV); Bitmap b = Bitmap.createBitmap(map.getWidth(), map.getHeight(), Bitmap.Config.RGB_565); try { trailsActivity.mapPreLoad.get(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } loadMapData(b, map, newColors, geoPoints, 17); } @Override protected boolean isRouteDisplayed() { // TODO Auto-generated method stub return false; } } 

Actualmente estoy enfrentando el mismo problema, y ​​acabo de encontrar una solución: evita que las superposiciones dibujen al hacer zoom o panorámica. Eso no es perfecto y todavía estoy buscando una solución mejor, pero al menos el mapa es utilizable sin esperar 5 segundos para cada panorámica o zoom.

Aquí está el código que usé en mi extensión Overlay . No es Java pero C # (usando Monodroid) – pero debe ser fácilmente comprensible.

 public override bool OnTouchEvent (MotionEvent e, Android.GoogleMaps.MapView mapView) { if (e.Action == MotionEventActions.Down) _mustDraw = false; else if (e.Action == MotionEventActions.Up) _mustDraw = true; return base.OnTouchEvent (e, mapView); } public override void Draw (Android.Graphics.Canvas canvas, Android.GoogleMaps.MapView mapView, bool shadow) { if (shadow || !_mustDraw) return; // ... } 

Esa solución funciona para cada acción basada en el mapa de toque, y ahora se ejecuta con una buena velocidad, simplemente falta la aplicación del mismo comportamiento al acercar o alejarse usando controles de zoom incorporados, pero primero tengo que luchar algunos de mis errores antes Haciendo esta parte, volveré sobre esta parte más tarde.

  • Convertir la ubicación en GeoPoint
  • Dibujo sobre otras aplicaciones en Android
  • Superposición transparente GLSurfaceview en la vista existente en android?
  • Cómo agregar vista de superposición sobre otra vista en android?
  • Barra de acción de superposición oscurecida por la barra de estado
  • Implementación de un mapa interior
  • Comportamiento extraño de superposición al ampliar el MapView
  • Captura de captura de pantalla en el teléfono Android durante la reproducción de vídeo y vista previa de la cámara
  • Superposición de vista de aplicación de Android (HUD)
  • Cabeza de chat Haga clic en eventos
  • Mostrar una superposición de "ayuda" en un diseño de Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.