Я использую настроенную версию карты (версия OSMDroid). Я использую в нем настраиваемые плитки и хочу, чтобы пользователь мог просматривать только ту область, где у меня есть настраиваемые плитки. Есть ли способ установить границу по широте, чтобы при панорамировании карты она не выходила за эти границы?
Ограничение области, в которую пользователь может перейти на Mapview
Ответы (4)
Обновление: я знаю, что это старый вопрос, но теперь в osmdroid есть метод setScrollableAreaLimit(), который поможет вам достичь того, что вы ищете. Также есть методы setMinZoomLevel() и setMaxZoomLevel(), позволяющие легко ограничивать уровни масштабирования.
Исходный ответ:
Пожалуйста, следите за:
http://code.google.com/p/osmdroid/issues/detail?id=209
Патч уже создан и, скорее всего, скоро будет интегрирован.
Это перекрестная публикация из ветки osmdroid. Там теперь указан класс BoundedMapView
, который реализует вышеупомянутый патч.
Для тех, кто использует .jar или иным образом не знаком с патчами, я собрал подкласс MapView, который поддерживает ограничение просмотра пользователем определенной области.
Подробности о том, как его использовать, если это не очевидно, можно найти по адресу http://www.sieswerda.net/2012/08/15/boundedmapview-a-mapview-with-limits/
Вдруг кому поможет....
У меня есть решение, которое я использую, оно работает нормально, но определенно могло бы быть лучше, так как карта может уйти слишком далеко от экрана, прежде чем она отскочит назад! Он использует широту и определяет, где находится карта, я установил 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);
}}
Несколько вещей, которые я должен указать, если вы планируете использовать это:
- Я не даю гарантий, что это сработает в вашей ситуации, и вы должны использовать его только в качестве отправной точки.
- Это будет работать только для областей к северу от экватора (я думаю) из-за того, как я сделал координаты!
- Он работает при «действии» события касания, поэтому он принимает точку, в которой пользователь убирает палец с экрана. Это означает, что когда карта бросается, это совершенно неточно, так как я не мог понять, где карта остановилась, из-за этого я отключил бросание, переопределив событие бросания и ничего не делая в нем... это делает карту немного трясущейся!
Если у кого-то есть лучшие решения или он может улучшить мой код, не стесняйтесь!
Я ищу точно такое же.
Лучше всего добавить оверлей, расширяющий boolean onScroll(...)
. Если это возвращает true, то прокрутка отменяется.
Именно так, как я хочу, за исключением одного: швыряться/щелкать. Тот же подход можно использовать для отмены бросков, хотя вы узнаете об этом только в начале броска.
В идеале вы могли бы слушать метод computeScroll()
и ограничивать (x, y)
прокрутки на основе mScroller.getCurX()
и mScroller.getCurY()
.