旋转的OpenStreetMap视图 - 如何在Android中实现地图随手指移动方向滑动?

6
我正在使用OSM地图制作一个映射应用程序,在此应用程序中,我根据旅行方向旋转地图,详见Android 旋转 MapView。这种方法运行良好。
然而,目前我还没有找到合适的方法来调整 dispatchTouchEvent 代码以抵消用户在地图上的触控效果(目前当地图旋转90度时,用户的水平滑动会导致地图垂直移动等问题)。示例代码仅提供了模糊提示:
   public boolean dispatchTouchEvent(MotionEvent ev) {
        // TODO: rotate events too
        return super.dispatchTouchEvent(ev);
    }

任何指导都将不胜感激。
还有一件事——是否仍然可以单独定位缩放控件,使它们在地图旋转时不旋转? 我读到getZoomControls()已被弃用。(为什么?)

如果有人知道答案,请帮忙回复。 - Ravi K. Sharma
1个回答

1

我知道现在可能有点晚了,但这可能会对某些人有所帮助...

import org.osmdroid.views.overlay.MyLocationOverlay;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Canvas;
import android.graphics.Matrix ;
import android.hardware.Sensor;
import android.os.BatteryManager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.RelativeLayout;
/**
* Rotate the Map in accordance to the movement of user and always point to North
*
*/
public class RotatingRelativeLayout extends RelativeLayout 
{
    private Matrix mMatrix = new Matrix();
    private float[] mTemp = new float[2]; 
private Context  context;
private static final float SQ2 = 1.414213562373095f;
public RotatingRelativeLayout(final Context pContext,
    final AttributeSet pAttrs)
{
super(pContext, pAttrs);

this.context=pContext;

}

@Override
protected void dispatchDraw(Canvas canvas) {

long  rotateTime = MyLocationOverlay.getTimeOfMovement();
float overlayBearing = MyLocationOverlay.getBearing();//this method returns current      bearing from OSM 
long  currentTime = System.currentTimeMillis();
long  diffTime = currentTime-rotateTime;
/*
 * Here we rotate map in accordance with Compass to point always North
     *  
 */

 if(diffTime >= (40*1000 )){

    //isBearing=false;
    overlayBearing=0;
    canvas.rotate(overlayBearing, getWidth() * 0.5f, getHeight() * 0.5f);

}
else 
/*
 * Rotate Map According to the user movement
 */
canvas.rotate(-overlayBearing, getWidth() * 0.5f, getHeight() * 0.5f);
canvas.getMatrix().invert(mMatrix);
final float w = this.getWidth();
    final float h = this.getHeight();

    final float scaleFactor = (float)(Math.sqrt(h * h + w * w) / Math.min(w, h));
    canvas.scale(scaleFactor, scaleFactor, getWidth() * 0.5f, getHeight() * 0.5f);
    super.dispatchDraw(canvas);
canvas.save(Canvas.MATRIX_SAVE_FLAG);
canvas.restore();

}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {

final int width = getWidth();
final int height = getHeight();
final int count = getChildCount();
for (int i = 0; i < count; i++) {
final View view = getChildAt(i);
final int childWidth = view.getMeasuredWidth();
final int childHeight = view.getMeasuredHeight();
final int childLeft = (width - childWidth) / 2;
final int childTop = (height - childHeight) / 2;

view.layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight);

}

}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

int w = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
int h = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
int sizeSpec;

if (w > h) {

    sizeSpec = MeasureSpec.makeMeasureSpec((int) (w*SQ2), MeasureSpec.EXACTLY);

} 
else {

    sizeSpec = MeasureSpec.makeMeasureSpec((int) (h*SQ2), MeasureSpec.EXACTLY);

}

final int count = getChildCount();

for (int i = 0; i < count; i++) {
 getChildAt(i).measure(sizeSpec, sizeSpec);

}

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

}

@Override
public boolean dispatchTouchEvent(MotionEvent event) {

final float[] temp = mTemp;
temp[0] = event.getX();
temp[1] = event.getY();
mMatrix.mapPoints(temp);
event.setLocation(temp[0], temp[1]);

return super.dispatchTouchEvent(event);

}


    }

现在只需在您的xml中像这样使用相对布局:

<YourPackageName.RotatingRelativeLayout     android:layout_width="fill_parent"  android:layout_height="fill_parent"  android:id="@+id/rotating_layout" android:layout_marginBottom="40dip"/>    

并且可以像这样通过编程添加地图视图:

   // Find target container
    final RelativeLayout rl=(RelativeLayout)mParent.findViewById(R.id.rotating_layout);

    // Create rotator
    mRotator=new RotatingRelativeLayout(mParent, null);

    // Add map to the rotating layout
    // Add rotator to the screen
    rl.addView(mMap,new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT,  LayoutParams.FILL_PARENT));

这里的mParent是上下文。还有一件事,如果你遇到图像像素化问题,你只需要使用它。

    //Paint distortion handling..
p.setFilterBitmap(true);

希望我解释得尽可能清楚...如果您有理解上的问题,请随时提问。
谢谢。

K.Sharma,我尝试了你的代码,它运行得很好。但是我的应用程序地图存在方向不稳定的问题,你能告诉我你是如何处理这个问题的吗?谢谢... - dharan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接