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; }

 

posted @ 2013-05-10 10:28  91yuan  阅读(510)  评论(0编辑  收藏  举报