我正在使用自定义版本的地图视图(OSMDroid 版本)。我在其中使用自定义图块,我只希望用户能够查看我拥有自定义图块的区域。有没有办法设置边界纬度,所以当他们平移地图时它不会越过这些边界?
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()