Android Mapview слишком медленно выполняет панорамирование и масштабирование
Я разработал GPS
приложение, в котором я записываю пользовательские корни и показываю его на карте....... но панорамирование на карте при просмотре моего маршрута мучительно медленное, карта реагирует пальцем как минимум на 4 или 5 секунд пойло......
Я переопределил onDraw()
метод и рисование линий, чтобы показать маршруты...... есть ли лучший способ сделать это так, чтобы панорамирование стало быстрее, чем в "MyTracks"
...........
Спасибо всем..... Пратап С.
4 ответа
Я должен был сделать что-то подобное. Моя попытка в настоящее время делает следующее в onDraw (упрощено для удобства чтения - обработка ошибок и т. Д. Исключена):
if ((bmap == null) || (lastZoom != mapv.getLatitudeSpan()))
{
// bitmap is null - so we haven't previously drawn the path, OR
// the map has been zoomed in/out, so we're gonna re-draw it anyway
// (alternatively, I could have tried scaling the bitmap... might
// be worth investigating if that is more efficient)
Projection proj = mapv.getProjection();
// store zoom level for comparing in the next onDraw
lastZoom = mapv.getLatitudeSpan();
// draw a path of all of the points in my route
GeoPoint start = routePoints.get(0);
Point startPt = new Point();
proj.toPixels(start, startPt);
Path path = new Path();
path.moveTo(startPt.x, startPt.y);
Point nxtPt;
for (GeoPoint nextPoint : routePoints)
{
nxtPt = new Point();
proj.toPixels(nextPoint, nxtPt);
path.lineTo(nxtPt.x, nxtPt.y);
}
// create a new bitmap, the size of the map view
bmap = Bitmap.createBitmap(mapv.getWidth(), mapv.getHeight(), Bitmap.Config.ARGB_8888);
// create an off-screen canvas to prepare new bitmap, and draw path on to it
Canvas offscreencanvas = new Canvas(bmap);
offscreencanvas.drawPath(path, mPaint);
// draw the bitmap of the path onto my map view's canvas
canvas.drawBitmap(bmap, 0, 0, null);
// make a note of where we put the bitmap, so we know how much we
// we need to move it by if the user pans the map
mapStartPosition = proj.fromPixels(0, 0);
}
else
{
// as we're in onDraw, we think the user has panned/moved the map
// if we're in here, the zoom level hasn't changed, and
// we've already got a bitmap with a drawing of the route path
Projection proj = mapv.getProjection();
// where has the mapview been panned to?
Point offsetPt = new Point();
proj.toPixels(mapStartPosition, offsetPt);
// draw the bitmap in the new correct location
canvas.drawBitmap(bmap, offsetPt.x, offsetPt.y, null);
}
Это еще не идеально... например, путь заканчивается в неправильном месте сразу после масштабирования - перемещается в правильное место, как только пользователь начинает панорамирование.
Но это начало - и намного более эффективное, чем перерисовка пути при каждом вызове onDraw
Надеюсь это поможет!
Комментарий к ответу Далелана от 7 мая: я использовал ваше решение для уменьшения нагрузки при рисовании, но немного его изменил:
- создается новое растровое изображение, если центр карты, уровень масштабирования изменились или не существует старого растрового изображения.
После масштабирования маршрут помещается в правильное положение. Кажется, что масштабирование не закончено полностью, когда обнаружен измененный уровень масштабирования.
Я использовал таймер, который изменяет центр карты на 10 после задержки в 600 мсек после изменения уровня масштабирования. При изменении центра карты вызывается метод draw и создается новое растровое изображение. Маршрут тогда размещен правильно. Это уродливая работа вокруг. У кого-нибудь есть лучшее решение?
private void panAfterZoom(MapView mv, long delay){
timer = new java.util.Timer("drawtimer", true);
mapView=mv;
task = new java.util.TimerTask() {
public void run() {
GeoPoint center=mapView.getMapCenter();
GeoPoint point=new GeoPoint(center.getLatitudeE6()+10, center.getLongitudeE6());
MapController contr=mapView.getController();
contr.setCenter(point);
timer.cancel();
}
};
timer.schedule(task, delay);
}
Это вызывается в методе рисования как: pabAfterZoom (mapView, 600);
Bost
Моя благодарность Далелану, чье предложение выше помогло мне улучшить мой маршрут. Я хотел бы поделиться улучшением, которое решает проблему с окончанием пути в неправильном месте после изменения масштаба.
Основная причина проблемы: методы mapview.getLatitudeSpan(), а также методы mapview.getZoomLevel() возвращают значения, не принимая во внимание прогрессивное изменение масштаба карты (анимация) между значениями масштабирования.
Решение: метод mapview.getProjection(). FromPixels(x,y) учитывает этот прогрессивный вариант, так что вы можете построить из него ваш getLatitudeSpan () или getLongitudeSpan(), и маршрут всегда будет отображаться правильно.
Ниже приведен предлагаемый код с внесенными изменениями:
**int lonSpanNew = mapv.getProjection().fromPixels(0,mapv.getHeight()/2).getLongitudeE6() - mapv.getProjection().fromPixels(mapv.getWidth(),mapview.getHeight()/2).getLongitudeE6();**
if ((bmap == null) || (lastZoom != **lonSpanNew** ))
{
// bitmap is null - so we haven't previously drawn the path, OR
// the map has been zoomed in/out, so we're gonna re-draw it anyway
// (alternatively, I could have tried scaling the bitmap... might
// be worth investigating if that is more efficient)
Projection proj = mapv.getProjection();
// store zoom level for comparing in the next onDraw
lastZoom = **lonSpanNew**;
// draw a path of all of the points in my route
GeoPoint start = routePoints.get(0);
Point startPt = new Point();
proj.toPixels(start, startPt);
Path path = new Path();
path.moveTo(startPt.x, startPt.y);
Point nxtPt;
for (GeoPoint nextPoint : routePoints)
{
nxtPt = new Point();
proj.toPixels(nextPoint, nxtPt);
path.lineTo(nxtPt.x, nxtPt.y);
}
// create a new bitmap, the size of the map view
bmap = Bitmap.createBitmap(mapv.getWidth(), mapv.getHeight(), Bitmap.Config.ARGB_8888);
// create an off-screen canvas to prepare new bitmap, and draw path on to it
Canvas offscreencanvas = new Canvas(bmap);
offscreencanvas.drawPath(path, mPaint);
// draw the bitmap of the path onto my map view's canvas
canvas.drawBitmap(bmap, 0, 0, null);
// make a note of where we put the bitmap, so we know how much we
// we need to move it by if the user pans the map
mapStartPosition = proj.fromPixels(0, 0);
}
else
{
// as we're in onDraw, we think the user has panned/moved the map
// if we're in here, the zoom level hasn't changed, and
// we've already got a bitmap with a drawing of the route path
Projection proj = mapv.getProjection();
// where has the mapview been panned to?
Point offsetPt = new Point();
proj.toPixels(mapStartPosition, offsetPt);
// draw the bitmap in the new correct location
canvas.drawBitmap(bmap, offsetPt.x, offsetPt.y, null);
}
Надеюсь, это поможет. С уважением, Луис
Переопределение onDraw будет единственным способом. Как вы рисуете дорожки, может быть, это можно сделать более эффективным?