限制用户在 Mapview 上可以到达的区域

发布于 2024-10-25 05:34:26 字数 102 浏览 2 评论 0原文

我正在使用地图视图的定制版本(OSMDroid 版本)。 我在其中使用自定义图块,我只希望用户能够查看我拥有自定义图块的区域。 有没有办法设置边界纬度,以便当他们平移地图时不会超出这些边界?

I am using a customised version of the mapview (OSMDroid version).
I am using custom tiles within it and I only want the user to be able to view the area where I have my custom tiles.
Is there a way to set the boundary lat longs so when they pan the map it doesn't go past these boundaries?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

浊酒尽余欢 2024-11-01 05:34:26

更新:我知道这是一个老问题,但 osmdroid 现在有一个 setScrollableAreaLimit() 方法,可以实现您正在寻找的内容。还有 setMinZoomLevel() 和 setMaxZoomLevel() 方法可以轻松限制缩放级别。

原始答案:

请关注:

http ://code.google.com/p/osmdroid/issues/detail?id=209

补丁已经创建,可能很快就会集成。

Update: I know this is an old question, but osmdroid now has a setScrollableAreaLimit() method that will achieve what you are looking for. There is also a setMinZoomLevel() and setMaxZoomLevel() method to easily restrict zoom levels.

Original answer:

Please keep an eye on:

http://code.google.com/p/osmdroid/issues/detail?id=209

A patch has already been created, and will likely be integrated shortly.

花伊自在美 2024-11-01 05:34:26

此内容是从 osmdroid 主题交叉发布的。现在列出了一个 BoundedMapView 类,它实现了前面提到的补丁。

对于那些使用 .jar 或其他不熟悉的人
补丁,我拼凑了一个支持 MapView 的子类
将用户的视野限制在特定区域。

有关如何使用它的详细信息,
如果不明显,可以在以下位置找到
http://www.sieswerda.net/2012 /08/15/boundedmapview-a-mapview-with-limits/

This is cross-posted from the osmdroid thread. There's now lists a BoundedMapView class, which implements the afortementioned patch.

For those of use using the .jar or otherwise not that familiar with
patches, I cobbled together a subclass of MapView that supports
limiting the user's view to a specific area.

Details on how to use it,
if not obvious, can be found at
http://www.sieswerda.net/2012/08/15/boundedmapview-a-mapview-with-limits/

姜生凉生 2024-11-01 05:34:26

万一它对任何人有帮助......

我有一种正在使用的解决方案,它工作正常,但肯定会更好,因为地图在跳回来之前可能会离屏幕太远!
它使用经纬度并计算出地图的位置,我设置了 4 个坐标,它们大约是地图的 4 个角,我发现如果将它们稍微设置到地图中而不是精确地设置角,效果会更好,然后我计算出是否纬度经度已完全离开屏幕..如果是这样,它会弹回一半:

我覆盖了地图视图和地图的 OnTouch 事件

@Override
public boolean onTouchEvent(MotionEvent ev) {
    if (ev.getAction() == MotionEvent.ACTION_UP) {

        // (only works for north of equator)
        // * map right side (lat) can't go past the left (lat) of screen

        // get geopoints of the 4 corners of the screen
        Projection proj = getProjection();
        GeoPoint screenTopLeft = proj.fromPixels(0, 0);
        GeoPoint screenTopRight = proj.fromPixels(getWidth(), 0);
        GeoPoint screenBottomLeft = proj.fromPixels(0, getHeight());

        double screenTopLat = screenTopLeft.getLatitudeE6() / 1E6;
        double screenBottomLat = screenBottomLeft.getLatitudeE6() / 1E6;
        double screenLeftlong = screenTopLeft.getLongitudeE6() / 1E6;
        double screenRightlong = screenTopRight.getLongitudeE6() / 1E6;

        double mapTopLat = BoundsTopLeftCorner.getLatitudeE6() / 1E6;
        double mapBottomLat = BoundsBottomLeftCorner.getLatitudeE6() / 1E6;
        double mapLeftlong = BoundsTopLeftCorner.getLongitudeE6() / 1E6;
        double mapRightlong = BoundsTopRightCorner.getLongitudeE6() / 1E6;

        // screen bottom greater than map top
        // screen top less than map bottom
        // screen right less than map left
        // screen left greater than map right
        boolean movedLeft = false;
        boolean movedRight = false;
        boolean movedUp = false;
        boolean movedDown = false;

        boolean offscreen = false;
        if (screenBottomLat > mapTopLat) {
            movedUp = true;
            offscreen = true;
        }
        if (screenTopLat < mapBottomLat) {
            movedDown = true;
            offscreen = true;
        }
        if (screenRightlong < mapLeftlong) {
            movedLeft = true;
            offscreen = true;
        }
        if (screenLeftlong > mapRightlong) {
            movedRight = true;
            offscreen = true;
        }

        if (offscreen) {
            // work out on which plane it's been moved off screen (lat/lng)

            if (movedLeft || movedRight) {

                double newBottomLat = screenBottomLat;
                double newTopLat = screenTopLat;

                double centralLat = newBottomLat
                        + ((newTopLat - newBottomLat) / 2);
                if (movedRight)
                    this.getController().setCenter(
                            new GeoPoint(centralLat, mapRightlong));
                else
                    this.getController().setCenter(
                            new GeoPoint(centralLat, mapLeftlong));

            }
            if (movedUp || movedDown) {

                // longs will all remain the same
                double newLeftLong = screenLeftlong;
                double newRightLong = screenRightlong;

                double centralLong = (newRightLong + newLeftLong) / 2;

                if (movedUp)
                    this.getController().setCenter(
                            new GeoPoint(mapTopLat, centralLong));

                else
                    this.getController().setCenter(
                            new GeoPoint(mapBottomLat, centralLong));
            }

        }

    }
    return super.onTouchEvent(ev);
}}

如果您正在考虑使用此功能,我应该指出一些事情:

  1. 我不保证它适合您的情况,您应该仅将其作为起点。
  2. 由于我完成坐标的方式,它仅适用于赤道以北的地区(我认为)!
  3. 它适用于触摸事件的“向上操作”,因此它会记录用户将手指从屏幕上移开的点。这意味着当地图投掷时,它是完全不准确的,因为我无法弄清楚地图在哪里停止,因此我通过覆盖投掷事件而不在其中执行任何操作来关闭投掷。这确实使地图有点摇晃!

如果有人有更好的解决方案或可以改进我的代码,请随时!

Incase it helps anyone....

I have sort of a solution that I am using, it works ok, but could definitely be better as the map can go abit too far off the screen before it jumps back!
It uses the lat longs and works out where the map is, I set 4 coordinates which are roughly the 4 corners of the map I have found it works better if you set them slightly into the map rather exactly the corners, I then work out if the lat longs have left the screen completely.. if so it will bounce it halfway back:

I overrode the mapview and the OnTouch event of the map

@Override
public boolean onTouchEvent(MotionEvent ev) {
    if (ev.getAction() == MotionEvent.ACTION_UP) {

        // (only works for north of equator)
        // * map right side (lat) can't go past the left (lat) of screen

        // get geopoints of the 4 corners of the screen
        Projection proj = getProjection();
        GeoPoint screenTopLeft = proj.fromPixels(0, 0);
        GeoPoint screenTopRight = proj.fromPixels(getWidth(), 0);
        GeoPoint screenBottomLeft = proj.fromPixels(0, getHeight());

        double screenTopLat = screenTopLeft.getLatitudeE6() / 1E6;
        double screenBottomLat = screenBottomLeft.getLatitudeE6() / 1E6;
        double screenLeftlong = screenTopLeft.getLongitudeE6() / 1E6;
        double screenRightlong = screenTopRight.getLongitudeE6() / 1E6;

        double mapTopLat = BoundsTopLeftCorner.getLatitudeE6() / 1E6;
        double mapBottomLat = BoundsBottomLeftCorner.getLatitudeE6() / 1E6;
        double mapLeftlong = BoundsTopLeftCorner.getLongitudeE6() / 1E6;
        double mapRightlong = BoundsTopRightCorner.getLongitudeE6() / 1E6;

        // screen bottom greater than map top
        // screen top less than map bottom
        // screen right less than map left
        // screen left greater than map right
        boolean movedLeft = false;
        boolean movedRight = false;
        boolean movedUp = false;
        boolean movedDown = false;

        boolean offscreen = false;
        if (screenBottomLat > mapTopLat) {
            movedUp = true;
            offscreen = true;
        }
        if (screenTopLat < mapBottomLat) {
            movedDown = true;
            offscreen = true;
        }
        if (screenRightlong < mapLeftlong) {
            movedLeft = true;
            offscreen = true;
        }
        if (screenLeftlong > mapRightlong) {
            movedRight = true;
            offscreen = true;
        }

        if (offscreen) {
            // work out on which plane it's been moved off screen (lat/lng)

            if (movedLeft || movedRight) {

                double newBottomLat = screenBottomLat;
                double newTopLat = screenTopLat;

                double centralLat = newBottomLat
                        + ((newTopLat - newBottomLat) / 2);
                if (movedRight)
                    this.getController().setCenter(
                            new GeoPoint(centralLat, mapRightlong));
                else
                    this.getController().setCenter(
                            new GeoPoint(centralLat, mapLeftlong));

            }
            if (movedUp || movedDown) {

                // longs will all remain the same
                double newLeftLong = screenLeftlong;
                double newRightLong = screenRightlong;

                double centralLong = (newRightLong + newLeftLong) / 2;

                if (movedUp)
                    this.getController().setCenter(
                            new GeoPoint(mapTopLat, centralLong));

                else
                    this.getController().setCenter(
                            new GeoPoint(mapBottomLat, centralLong));
            }

        }

    }
    return super.onTouchEvent(ev);
}}

A few things I should point out if you are considering using this:

  1. I make no guarentees that it will work for your situation and you should only use it as a starting point.
  2. It will only work for areas north of the equator (I think) due to the way I've done the coords!
  3. It works on the "action up" of the touch event, so it takes the point where the user takes their finger off the screen. This means when the map flings it's completely inaccurate as I could not work out where the map stopped, because of this I turned off the fling by overriding the fling event and not doing anything in it.. this does make the map a bit jolty!

If anyone has any better solutions or can improve my code please feel free!

离不开的别离 2024-11-01 05:34:26

我正在寻找完全相同的东西。

我最好的方法是添加一个覆盖层,它扩展了 boolean onScroll(...) 。如果返回 true,则滚动被取消。

这正是我想要的,除了一件事:猛击/轻弹。相同的方法可用于取消 fling 事件,尽管您只能在 fling 开始时听到它。

理想情况下,您能够监听computeScroll()方法,并基于mScroller.getCurX限制滚动的(x, y) () 和 mScroller.getCurY()

I'm looking for exactly the same thing.

My best lead is to add an Overlay, which extends boolean onScroll(...). If this returns true, then the scroll is cancelled.

This is exactly how I want it, except for one thing: flinging/flicking. The same approach can be used to cancel fling events, though you only get to hear about it at the start of the fling.

Ideally, you'd be able to listen to the computeScroll() method, and limit the (x, y) of the scroll, based on mScroller.getCurX() and mScroller.getCurY().

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文