【问题标题】:panning not working correctly in mapView在 mapView 中平移无法正常工作
【发布时间】:2014-07-17 20:55:00
【问题描述】:

我有 mapView 并以编程方式处理触摸事件。

问题是:如果mapview是ZoomOut到最大,平移会很小很慢,符合mapView是ZoomIn,平移会更大更快。换句话说:zoomIN 越大,平移运动越大。

如何使平移移动不相应缩放,所以每次移动地图时,无论缩放级别如何,它都会移动相同的距离?

这是我的安卓客户端

private double savedTouchedX = -1;
private double savedTouchedY = -1;
....

mapView.setOnTouchListener(new MapView.OnTouchListener() {

    @Override
    public boolean onTouch(View arg0, MotionEvent event) {
        int action = event.getAction();

         switch(action)
         {
            case MotionEvent.ACTION_DOWN:
                savedTouchedX = event.getX();
                savedTouchedY = event.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                doPanning(event, mapView);
                break;
            case MotionEvent.ACTION_UP:
                doPanning(event, mapView);
                savedTouchedX = -1;
                savedTouchedY = -1;
                break;
            default:
                break;
         }
         return true;
    }
});

....

//move mapView
private boolean doPanning(MotionEvent e, MapView mapView)
{
if(savedTouchedX >= 0 && savedTouchedY >= 0)
{
    IGeoPoint mapCenter = mapView.getMapCenter();
    GeoPoint panToCenter = new GeoPoint((int)(mapCenter.getLatitudeE6() + (e.getY() - savedTouchedY) * 1E5),
    (int)(mapCenter.getLongitudeE6() - (e.getX() - savedTouchedX) * 1E5));
    mapView.getController().setCenter(panToCenter);
}
savedTouchedX = e.getX();
savedTouchedY = e.getY();
return true;
}

【问题讨论】:

    标签: android android-mapview osmdroid android-framelayout touch-event


    【解决方案1】:

    基于 TouchEvent,以编程方式移动地图

    yourFrameLayout.setOnTouchListener(new OnTouchListener() {
    
        @Override
        public boolean onTouch(View v , MotionEvent event) {
            return gestureDetector.onTouchEvent(event);
        }
    });
    
    SimpleOnGestureListener listener = new SimpleOnGestureListener() {
        @Override
        public boolean onFling(MotionEvent e1 , MotionEvent e2 , float velocityX , float velocityY) {
    
            float Xdirection = e1.getX() - e2.getX();
            float Ydirection = e1.getY() - e2.getY();
    
            //TODO- Do some calculations & change the maps lat & lon. 
            // Also consider zoom level while calculating.
    
            final double newLat = (getOldLat - (moveSomeLatBasedOnXDirection)));
            final double newLon = (getOldLon - (moveSomeLatBasedOnYDirection)));
    
            CameraUpdate center = CameraUpdateFactory.newLatLng(new LatLng( newLat, newLon));
    
            map.moveCamera(center);
    
    
            return super.onFling(e1, e2, velocityX, velocityY);
        };
    
    };
    GestureDetector gestureDetector = new GestureDetector(getActivity(), listener);
    

    【讨论】:

    • 现在我正在使用这个代码,它可以工作,但前提是上面的图像不可见,但如果我用图像覆盖 mapview,它就不起作用:m = MotionEvent.obtain(226707,226707,2/*ACTION_MOVE*/,x,y,0); runOnUiThread(new Runnable() { public void run() {memecontentView.dispatchTouchEvent(m);} }); 有没有即使地图视图不可见,如何使相同的代码工作?还是唯一的方法是以编程方式移动地图视图?
    • 我得到了它的工作,我更新了我的代码。 @VenomVendor 你如何使平移移动不相应地缩放,所以每次移动地图时,无论缩放级别如何,它都会移动相同的距离?
    • @user3805972 不确定,我没试过。但你可以。
    【解决方案2】:

    这会隐藏您的视图。并禁用触摸它。其实这就是你所需要的。

     memecontentView.setVisibility(View.GONE);
    

    这个节目视图。

    memecontentView.setVisibility(View.VISIBLE);
    memecontentView.bringToFront();
    

    移动到另一个布局

    public void moveView(View view,ViewGroup destination) {
        ((ViewGroup)view.getParent()).removeView(view);
         //Also you can set LayoutParams here
         destination.addView(src);
         destination.getChildAt(destination.indexOf(src)).bringToFront();
    }
    

    用法:

    moveView(mapView,yourFrameLayout);
    

    【讨论】:

    • 谢谢,但我的问题不是如何隐藏内容。我的问题是:如何移动mapView,即使它在frameLayout中被上部图像隐藏。如果地图没有隐藏,我的代码会处理触摸事件,但我需要的是修改背景中的图像跨度>
    • 我的意思是:我在客户端有一个地图视图,我将它发送到服务器。 mapview 不应该仅在服务器中的客户端中可见,这就是为什么我用图像覆盖它,但 mapview 应该能够对来自服务器的返回触摸事件做出反应。换句话说,我需要将地图视图渲染为背景中的图像并将其发送到服务器。问题是,如果我覆盖 mapview,它就不会移动。所以我的问题是如何移动后台的地图视图?
    【解决方案3】:

    “我需要用另一张图片覆盖地图”

    => 不完全确定了解其他图像的行为方式。

    如果您将其设置为OSMBonusPack GroundOverlay,它将被绘制在地图上方。地图将对所有事件(平移、缩放)做出反应,并且上面的图像也将根据地图移动而移动。

    如果上面的图像不应该随着地图移动而移动,那么您可以实现一个新的(但非常简单的)叠加层,将您的图像绘制在地图视图上的固定位置。它的draw方法应该是:

    @Override protected void draw(Canvas c, MapView mapView, boolean shadow) {
      if (shadow)
        return;
      canvas.drawBitmap(myImage, screenX, screenY, null);
    }
    

    【讨论】:

    • 我的意思是:我在客户端有一个地图视图,我将它发送到服务器。 mapview 不应该仅在服务器中的客户端中可见,这就是为什么我用图像覆盖它,但 mapview 应该能够对来自服务器的返回触摸事件做出反应。换句话说,我需要将地图视图渲染为背景中的图像并将其发送到服务器。问题是,如果我覆盖 mapview,它就不会移动。所以我的问题是如何移动后台的地图视图?
    • 现在我正在使用这个代码,它可以工作,但前提是上面的图像不可见,但如果我用图像覆盖地图视图,它就不起作用:m = MotionEvent.obtain(226707,226707,2/*ACTION_MOVE*/,x,y,0); runOnUiThread(new Runnable() { public void run() { memecontentView.dispatchTouchEvent(m); } });
    • 好的,我明白了。所以我的第二个建议应该有效:您可以使用新的自定义叠加层隐藏您的地图,正如我所描述的。地图仍将对事件作出反应。顺便说一句,您可以将事件直接发送到 mapView,而不是 memecontentView?
    • 我得到了它的工作,我更新了我的代码。 @MKer 你如何使平移移动不相应地缩放,所以每次移动地图时,无论缩放级别如何,它都会移动相同的距离?
    • 基于服务器上构建的事件移动客户端地图将不可靠。两边屏幕分辨率一样吗?方向一致?如果您想要可靠的东西,只需从服务器发送到客户端:地图中心和缩放级别。易于获取,易于设置(即使地图被隐藏),100% 可靠。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-18
    • 2017-06-24
    相关资源
    最近更新 更多