osmand中矢量数据地图绘制
代码版本为1.0.0.
参考MapVectorLayer.java
重载了Layer的onDraw
public void onDraw(Canvas canvas, RectF latLonBounds, RectF tilesRect, DrawSettings drawSettings) { if (!visible) { return; } if (!isVectorDataVisible() && tileLayer != null) { tileLayer.drawTileMap(canvas, tilesRect); resourceManager.getRenderer().interruptLoadingMap(); } else { if (!view.isZooming()) { pixRect.set(0, 0, view.getWidth(), view.getHeight()); updateRotatedTileBox(); if (resourceManager.updateRenderedMapNeeded(rotatedTileBox, drawSettings)) { // pixRect.set(-view.getWidth(), -view.getHeight() / 2, 2 * view.getWidth(), 3 * view.getHeight() / 2); pixRect.set(-view.getWidth() / 3, -view.getHeight() / 4, 4 * view.getWidth() / 3, 5 * view.getHeight() / 4); updateRotatedTileBox(); resourceManager.updateRendererMap(rotatedTileBox); } } MapRenderRepositories renderer = resourceManager.getRenderer(); drawRenderedMap(canvas, renderer.getBitmap(), renderer.getBitmapLocation()); drawRenderedMap(canvas, renderer.getPrevBitmap(), renderer.getPrevBmpLocation()); } }
在onDraw中。具体的描画是调用的两次drawRenderedMap
共有两个bitmap。renderer.getBitmap()用于保存当前描绘内容,renderer.getPrevBitmap()用于保存之前状态的描绘内容。
通过这两个bitmap,来完成挪动地图的效果及zoom的效果。
分析一下bitmap的贴图算法
private boolean drawRenderedMap(Canvas canvas, Bitmap bmp, RotatedTileBox bmpLoc) { boolean shown = false; if (bmp != null && bmpLoc != null) { float rot = bmpLoc.getRotate();//取得图片的选择角度 float mult = (float) MapUtils.getPowZoom(view.getZoom() - bmpLoc.getZoom());//view的zoom与bmp的zoom间的缩放倍数 float fmult = (float) MapUtils.getPowZoom(view.getFloatZoom() - bmpLoc.getZoom());//缩放动画中的过渡float zoom float tx = view.getXTile() / mult;//将view的tile坐标转到bmp的tile坐标 float ty = view.getYTile() / mult; float dleftX1 = bmpLoc.getLeftTileX() - tx;//取得图片左上与屏幕中心的差值距离 float dtopY1 = bmpLoc.getTopTileY() - ty; float ts = view.getSourceTileSize() * fmult;//tile size进行缩放 float cos = bmpLoc.getRotateCos(); float sin = bmpLoc.getRotateSin(); float x1 = MapUtils.calcDiffPixelX(sin, cos, dleftX1, dtopY1, ts) + view.getCenterPointX();//计算屏幕坐标 float y1 = MapUtils.calcDiffPixelY(sin, cos, dleftX1, dtopY1, ts) + view.getCenterPointY(); canvas.rotate(-rot, view.getCenterPointX(), view.getCenterPointY());//将画布反向旋转。这是在父控件中canvas会rotate一个角度。这里做一个旋转的差值校正
//设置贴图位置 destImage.set(x1, y1, x1 + bmpLoc.getTileWidth() * ts, y1 + bmpLoc.getTileHeight() * ts); if(!bmp.isRecycled()){ canvas.drawBitmap(bmp, null, destImage, paintImg); shown = true; } canvas.rotate(rot, view.getCenterPointX(), view.getCenterPointY()); } return shown; }