Sto cercando di risolvere un problema con il tracciamento di un percorso da un enorme set (di 100 k +) di punti geografici a un MapView su Android. In primo luogo vorrei dire che ho cercato molto spesso in StackOverflow e non ho trovato una risposta.Il collo di bottiglia del mio codice non è in realtà un disegno su tela, ma il metodo Projection.toPixels(GeoPoint, Point)
o Rect.contains(point.x, point.y)
..sono saltando i punti non visibili sullo schermo e mostra anche solo ogni nesimo punto in base al livello di zoom corrente. Quando la mappa viene ingrandita, voglio visualizzare il percorso più preciso possibile, così salgo zero (o quasi zero) punti, così che quando trovo punti visibili devo chiamare il metodo di proiezione per ogni singolo punto della collezione. Ed è quello che ci vuole davvero molto tempo (non secondi, ma il panning delle mappe non è fluido e non lo sto testando su HTC Wildfire :)). Ho provato a memorizzare i punti calcolati nella cache, ma dal momento che i punti vengono ricalcolati dopo ogni pan/zoom della mappa non ha aiutato affatto .Disegno (filtro) 100k + punta a MapView in Android
ho pensato di utilizzo di un qualche tipo di prugna secca e algoritmo di ricerca, invece di scorrere la matrice, ma ho capito i dati di input non è ordinato (non riesco a buttare via qualsiasi filiale impilati tra due punti invisibili). Questo è possibile risolvere con un ordinamento semplice all'inizio, ma non sono ancora sicuro che anche il conteggio logaritmico delle chiamate getProjection()
e Rect.contains(point.x, point.y)
anziché lineare risolverà il problema delle prestazioni.
Bellow è il mio codice corrente. Per favore aiutami se sai come migliorarlo. Molte grazie!
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);
}
Quindi ho eseguito un po 'di tracciamento e circa l'85% di carico utilizza il metodo 'Projection.toPixels()' Ci deve essere un modo per ottimizzarlo:/ – simekadam
Un altro modo potrebbe essere utilizzare un qualche tipo di mappatura. HashMap con coord come chiave .. Come dividere il mondo in segmenti rettangolari e quindi filtrare quelli in base allo stato corrente di mapView. Quindi prendilo da HashMap e visualizzalo. Ma questo sembra abbastanza complicato :) Pensi che sia possibile? Solo se ha senso o meno .. – simekadam