osmand中地图旋转处理

1.首先需要了解一下墨卡托投影。然后了解一下tile slippy做法。参考http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames

通常墨卡托投影坐标系需要转成左上为原点。这就与屏幕坐标系相对应了。

2.需要知道坐标旋转公式。通常坐标旋转公式是

 (1)   x1=(cosθ)dx-(sinθ)dy + x  (逆时针)

        y1=(cosθ)dy+(sinθ)dx + y

  x,y为圆心。

  这个旋转公式是通常的xy坐标系的,即左下点为坐标系原点。且规定逆时针为正方向旋转。

 左下坐标系的顺时针旋转公式为

  (2)  x1=(cosθ)dx+(sinθ)dy + x  (顺时针)

        y1=(cosθ)dy-(sinθ)dx + y

但是屏幕坐标系为左上原点。所以旋转公式正好相反。屏幕坐标系顺时针旋转为公式(1),逆时针旋转为公式(2)

osmand中屏幕坐标对应投影坐标的转换方法如下:

//屏幕Y坐标转tile Y坐标
public
float calcDiffTileY(float dx, float dy) { if(isMapRotateEnabled()){//地图是否旋转 return (-rotateSin * dx + rotateCos * dy) / getTileSize();//屏幕坐标逆时针旋转并除以tile的size(256),转成tile坐标 } else { return dy / getTileSize(); } } public float calcDiffTileX(float dx, float dy) { if(isMapRotateEnabled()){ return (rotateCos * dx + rotateSin * dy) / getTileSize(); } else { return dx / getTileSize(); } } public float calcDiffPixelY(float dTileX, float dTileY) { if(isMapRotateEnabled()){
       //tile坐标顺时针旋转转成像素坐标
return (rotateSin * dTileX + rotateCos * dTileY) * getTileSize(); } else { return dTileY * getTileSize(); } } public float calcDiffPixelX(float dTileX, float dTileY) { if(isMapRotateEnabled()){ return (rotateCos * dTileX - rotateSin * dTileY) * getTileSize(); } else { return dTileX * getTileSize(); } }

gps的方位角为顺时针为正 正北为0,角度范围0~359

参考上图。如果始终要求车头朝向屏幕上方。那么在画图的时候,就需要将tile的坐标系进行逆时针旋转。

也就是屏幕上的点转到tile坐标系中,也需要顺时针旋转。同理,tile坐标若转到屏幕坐标,也需要相对屏幕中心进行逆时针旋转

在osmand中,从GPS取得的方向为相对于正北顺时针为正,传入osmand中时,会取反传入。

 

下面是对于旋转后的两个tile进行是否包含的判断

如图

先将tile2旋转成水平坐标。再相对于tile1进行顺时针旋转。判断tile2的四个顶点坐标是否在tile1的坐标系范围内。

posted @ 2013-05-09 17:51  91yuan  阅读(485)  评论(0编辑  收藏  举报