Ограничение области, в которую пользователь может перейти на Mapview

Я использую настроенную версию карты (версия OSMDroid). Я использую в нем настраиваемые плитки и хочу, чтобы пользователь мог просматривать только ту область, где у меня есть настраиваемые плитки. Есть ли способ установить границу по широте, чтобы при панорамировании карты она не выходила за эти границы?


person Bex    schedule 23.03.2011    source источник


Ответы (4)


Обновление: я знаю, что это старый вопрос, но теперь в osmdroid есть метод setScrollableAreaLimit(), который поможет вам достичь того, что вы ищете. Также есть методы setMinZoomLevel() и setMaxZoomLevel(), позволяющие легко ограничивать уровни масштабирования.

Исходный ответ:

Пожалуйста, следите за:

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

Патч уже создан и, скорее всего, скоро будет интегрирован.

person kurtzmarc    schedule 27.06.2011

Это перекрестная публикация из ветки osmdroid. Там теперь указан класс BoundedMapView, который реализует вышеупомянутый патч.

Для тех, кто использует .jar или иным образом не знаком с патчами, я собрал подкласс MapView, который поддерживает ограничение просмотра пользователем определенной области.

Подробности о том, как его использовать, если это не очевидно, можно найти по адресу http://www.sieswerda.net/2012/08/15/boundedmapview-a-mapview-with-limits/

person quietmint    schedule 28.08.2012

Вдруг кому поможет....

У меня есть решение, которое я использую, оно работает нормально, но определенно могло бы быть лучше, так как карта может уйти слишком далеко от экрана, прежде чем она отскочит назад! Он использует широту и определяет, где находится карта, я установил 4 координаты, которые примерно соответствуют 4 углам карты. Я обнаружил, что это работает лучше, если вы установите их немного в карту, а точно в углы, затем я работаю, если lat longs полностью покинули экран.. если это так, он отскочит на полпути назад:

Я переопределил представление карты и событие 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. Он работает при «действии» события касания, поэтому он принимает точку, в которой пользователь убирает палец с экрана. Это означает, что когда карта бросается, это совершенно неточно, так как я не мог понять, где карта остановилась, из-за этого я отключил бросание, переопределив событие бросания и ничего не делая в нем... это делает карту немного трясущейся!

Если у кого-то есть лучшие решения или он может улучшить мой код, не стесняйтесь!

person Bex    schedule 06.06.2011

Я ищу точно такое же.

Лучше всего добавить оверлей, расширяющий boolean onScroll(...). Если это возвращает true, то прокрутка отменяется.

Именно так, как я хочу, за исключением одного: швыряться/щелкать. Тот же подход можно использовать для отмены бросков, хотя вы узнаете об этом только в начале броска.

В идеале вы могли бы слушать метод computeScroll() и ограничивать (x, y) прокрутки на основе mScroller.getCurX() и mScroller.getCurY().

person jamesh    schedule 19.04.2011
comment
@Kevin, кто-то, по-видимому, создал ветку проекта, которая включает в себя ограничивающие рамки, но я не смог попробовать ее, поскольку использую более старую версию проекта и не мог обновить ее или решить, как интегрировать ее с моей собственной версией. .. Я придумал решение ниже - person Bex; 06.06.2011