Estoy tratando de resolver un problema con el trazado de una ruta de enorme (100k +) conjunto de GeoPoints a un MapView en Android. En primer lugar, me gustaría decir que he buscado mucho en StackOverflow y que no he encontrado una respuesta. El cuello de botella de mi código no está realmente en el lienzo, pero Projection.toPixels(GeoPoint, Point)
o Rect.contains(point.x, point.y)
método ... Estoy omitiendo puntos no visibles en la pantalla y también muestra solo cada enésimo punto según el nivel de zoom actual. Cuando se acerca el mapa, quiero mostrar la ruta más precisa posible, por lo que omito cero (o casi cero) puntos, de modo que cuando encuentre puntos visibles, necesito llamar al método de proyección para cada punto de la colección. Y eso es lo que realmente lleva mucho tiempo (no segundos, pero el paneo del mapa no es fluido y no lo estoy probando en HTC Wildfire :)). Traté de almacenar en caché los puntos calculados, pero dado que los puntos se vuelven a calcular después de cada desplazamiento/acercamiento del mapa, no han ayudado en absoluto al .Dibujo (filtrado) 100k + puntos a MapView en Android
Pensé en el uso de algún tipo de algoritmo de poda y búsqueda en lugar de iterar la matriz, pero calculé que los datos de entrada no están ordenados (no puedo tirar ninguna rama apilada entre dos puntos invisibles). Eso podría ser posible resolver con un simple tipo al principio, pero todavía no estoy seguro de que ni siquiera el recuento logarítmico de getProjection()
y Rect.contains(point.x, point.y)
llamadas en lugar de lineal resolvería el problema de rendimiento.
Bellow es mi código actual. Por favor, ayúdame si sabes cómo mejorar esto. ¡Muchas gracias!
public void drawPath(MapView mv, Canvas canvas) {
displayed = false;
tmpPath.reset();
int zoomLevel = mapView.getZoomLevel();
int skippedPoints = (int) Math.pow(2, (Math.max((19 - zoomLevel), 0)));
int mPointsSize = mPoints.size();
int mPointsLastIndex = mPointsSize - 1;
int stop = mPointsLastIndex - skippedPoints;
mapView.getDrawingRect(currentMapBoundsRect);
Projection projection = mv.getProjection();
for (int i = 0; i < mPointsSize; i += skippedPoints) {
if (i > stop) {
break;
}
//HERE IS THE PROBLEM I THINK - THIS METHOD AND THE IF CONDITION BELOW
projection.toPixels(mPoints.get(i), point);
if (currentMapBoundsRect.contains(point.x, point.y)) {
if (!displayed) {
Point tmpPoint = new Point();
projection.toPixels(mPoints.get(Math.max(i - 1, 0)),
tmpPoint);
tmpPath.moveTo(tmpPoint.x, tmpPoint.y);
tmpPath.lineTo(point.x, point.y);
displayed = true;
} else {
tmpPath.lineTo(point.x, point.y);
}
} else if (displayed) {
tmpPath.lineTo(point.x, point.y);
displayed = false;
}
}
canvas.drawPath(tmpPath, this.pathPaint);
}
Así que he realizado un seguimiento y aproximadamente el 85% de carga toma el método 'Projection.toPixels()' ... Debe haber una forma de optimizar eso:/ – simekadam
Otra forma podría ser usar algún tipo de mapeo..Me gusta HashMap con coordenadas como clave. Como dividir el mundo en segmentos rectangulares y luego filtrarlos según el estado de vista de mapa actual. A continuación, tómelo de HashMap y despliegue. Pero esto se ve bastante complicado :) ¿Crees que es posible? Solo si tiene sentido o no ... – simekadam