mapview のカスタマイズ バージョン (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 つの座標を設定します緯度経度が完全に画面から離れています..そうであれば、途中で跳ね返ります:
マップのマップビューと 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()