2013-12-13 9 views
20

私の検索では答えが見つかりませんでしたが、いくつかの回答がありますが、私のためには機能しませんでした。LatLngBoundsビルダーで最大ズームレベルを設定してください

私は地図上に2つのマーカーを持っており、カメラを右ズームレベルにズームさせて両方を含むようにするにはLatLngBoundsビルダーを使用しています。 1つのことを除いてすべてが期待どおりに機能します.2つのマーカーが本当に近くにある場合、マップは非常に非常に拡大されていますが、このレベルのズームを持つことは意味がありません。

LatLngBounds.Builder builder = new LatLngBounds.Builder(); 
builder.include(firstMarker.getPosition()); 
builder.include(secondMarker.getPosition()); 
LatLngBounds bounds = builder.build(); 

CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, markerPadding); 

特定のレベルのズームを強制する方法はありますか?その後、カメラはズームしませんか?これにより、マップのズームイン/ズームアウトを避けることができます。基本的に私はズームのレベルとして15.0fを使用しています。ポイントがあまりにも遠すぎる場合は、ズームを両方に合わせたいと思っています。ポイントが近づいている場合は、ズームレベルが15.0fを超えることは望ましくありません。

+0

最後に私はf rom http://stackoverflow.com/questions/15700808/setting-max-zoom-level-in-google-maps-android-api-v2それは妥当な – Alin

+0

Alinの下で私の提案は、あなたが参照している答えに似ています同じ大きな経度差は、測定された緯度に応じて非常に異なる距離(キロメートル)に変換されます。私のアプローチでは、このバリエーションはありません。最小ズームレベルは、赤道または極にマーカーを表示するかどうかにかかわらず、キロメートルで測定された同じ地図対角線によって常に定義されます(o.k.私は知っています、あなたは本当にGoogleマップに極を表示できません)。 – user2808624

+0

私はそれを受け入れることができますので、あなたの答えにコードサンプルを追加してください。 – Alin

答えて

40

私は同じような場合があります。少なくとも2kmの対角線の地図が必要です。 したがって、ビルダーに2つの追加ポイントを追加するだけです。最初の境界の中心から北西に1キロ、中心から南東に1キロ離れた場所です。これらが範囲内にある場合、何も変更されません。それらが元の境界の外にある場合、境界を意味のあるサイズに増加させます。ここで

は、完全なコード例を次に示します。

public LatLngBounds createBoundsWithMinDiagonal(MarkerOptions firstMarker, MarkerOptions secondMarker) { 
    LatLngBounds.Builder builder = new LatLngBounds.Builder(); 
    builder.include(firstMarker.getPosition()); 
    builder.include(secondMarker.getPosition()); 

    LatLngBounds tmpBounds = builder.build(); 
    /** Add 2 points 1000m northEast and southWest of the center. 
    * They increase the bounds only, if they are not already larger 
    * than this. 
    * 1000m on the diagonal translates into about 709m to each direction. */ 
    LatLng center = tmpBounds.getCenter(); 
    LatLng northEast = move(center, 709, 709); 
    LatLng southWest = move(center, -709, -709); 
    builder.include(southWest); 
    builder.include(northEast); 
    return builder.build();  
} 

private static final double EARTHRADIUS = 6366198; 
/** 
* Create a new LatLng which lies toNorth meters north and toEast meters 
* east of startLL 
*/ 
private static LatLng move(LatLng startLL, double toNorth, double toEast) { 
    double lonDiff = meterToLongitude(toEast, startLL.latitude); 
    double latDiff = meterToLatitude(toNorth); 
    return new LatLng(startLL.latitude + latDiff, startLL.longitude 
      + lonDiff); 
} 

private static double meterToLongitude(double meterToEast, double latitude) { 
    double latArc = Math.toRadians(latitude); 
    double radius = Math.cos(latArc) * EARTHRADIUS; 
    double rad = meterToEast/radius; 
    return Math.toDegrees(rad); 
} 


private static double meterToLatitude(double meterToNorth) { 
    double rad = meterToNorth/EARTHRADIUS; 
    return Math.toDegrees(rad); 
} 
+0

また、コードをテストできるようにmeterToLatitude関数を追加してください。 'double latDiff = meterToLatitude(toNorth);のために必要です。ありがとう – Alin

+0

申し訳ありません、それを逃しました。私はもう一度追加します。 – user2808624

+0

ありがとうございました。これは以前のソリューションよりも優れています。私が気付いたのは、距離が大きすぎる可能性があるので、最終的に私のニーズに合うように異なる密度の距離値を設定しました。 – Alin

0

ズームレベルを4.0.30から制限する方法はありませんが、this issueを追跡することができます。

簡単な方法は、この動画のようにズームレベルを強制的に次のようになります。特定のズームレベルに達したときに
http://www.youtube.com/watch?v=-nCZ37HdheYは基本的に彼らはanimateCameraを呼んでいます。

これは、ユーザーによって開始されていない2つのアニメーションがあるため、少し奇妙に見えます。

難しい方法は、自分で数学をすることです。 CameraUpdateFactory.newLatLngZoomLatLngを使用して作業してみてください。これらのポイントと最大ズームポイントの中間点は、ポイントが近づいている場合です。

1

あなたが隠されている地図の断片を作り、そしてあなたのズーム/境界を決定するためにこれを使用して考えられていますか?明らかに計算上最良ではありませんが、おそらく最も簡単で最も正確なソリューションです。たとえば、ポールの近くで0度の経度(あなたが気にしている)の近くで働く数学的な解決策を作ることは複雑です。マップを使用している場合、それはすでにビルドされています。また、既存のマップ上でこのソリューションを使用することもできますが、ユーザーにはバウンスが表示されます。ここで

は、あなたがそれを行うだろう方法は次のとおりです。境界へ

  1. ゴーあなたが
  2. 上で定義されてきたようにmap.getCameraPosition()ズームを使ってズームを取得します。
  3. CameraUpdateFactory.zoomToを使用して15にアウトズームは> 15ズーム(15)
7

もし私がuser2808624によって答えに応じてこのソリューションを実装しますが、計算を行うためにAndroid Maps Utility LibraryからSphericalUtilを使用。

遅刻
final double HEADING_NORTH_EAST = 45; 
final double HEADING_SOUTH_WEST = 215; 
LatLng center = tmpBounds.getCenter(); 
LatLng norhtEast = SphericalUtil.computeOffset(center, 709,HEADING_NORTH_EAST); 
LatLng southWest = SphericalUtil.computeOffset(center, 709,HEADING_SOUTH_WEST); 
2

多分誰かが私が持っていた同じ問題を持っている:私は場所から、ではないLatLngBounds.Builderから境界を受け取っ:

私は見つけることLocation.distanceBetween(...)を使用境界が小さすぎるした後、境界の中央で最小のズームレベルを使用する場合:

if (areBoundsTooSmall(bounds, 300)) { 
    mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(bounds.getCenter(), 17)); 
} else { 
    mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 20)); 
} 

チェック方法がある:

private boolean areBoundsTooSmall(LatLngBounds bounds, int minDistanceInMeter) { 
    float[] result = new float[1]; 
    Location.distanceBetween(bounds.southwest.latitude, bounds.southwest.longitude, bounds.northeast.latitude, bounds.northeast.longitude, result); 
    return result[0] < minDistanceInMeter; 
} 

小さすぎる境界にはズームレベル17の最小値を使用し、メーター300では最小の距離では小さすぎます。必要に応じて数値を調整できます。

2

Googleには、最大/最小ズームレベルを制限するためのAPIが追加されています。

GoogleMap.setMaxZoomPreference() 
GoogleMap.setMinZoomPreference() 
+1

注意:これにより、ユーザーはこれらの制限を超えてズームすることが制限されます。 – DoruChidean

0

クイック修正は次のとおりです。

gMap.setOnMapLoadedCallback(this); 
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, padding); 
gMap.setMaxZoomPreference(10); 
gMap.animateCamera(cu); 


@Override 
public void onMapLoaded() { 
    gMap.resetMinMaxZoomPreference(); 
} 

は、マップが完全にリロードされるまで、それがズームを止めることができることに注意してください。しかし、迅速な修正として、それは動作します。

2

user2808624answerに基づいたはるかに短いバージョンです。

 LatLngBounds bounds = builder.build(); 
     LatLng center = bounds.getCenter(); 
     builder.include(new LatLng(center.latitude-0.001f,center.longitude-0.001f)); 
     builder.include(new LatLng(center.latitude+0.001f,center.longitude+0.001f)); 
     bounds = builder.build(); 

その少しずさんな、しかし、あなたは、シティビューを下回らないために都市ブロック、0.01よりも小さいをズームしないように0.001を使用することができます。唯一の利点は、その余分な4行のコードです。

0

それはただ単純です:user2808624とdvdrleeでの回答から、次の

LatLngBounds.Builder latlngBuilder = new LatLngBounds.Builder(); 

LatLng sydney1 = new LatLng(57.149651, -2.099075); 

LatLng sydney2 = new LatLng(51.621441, -3.943646); 

latlngBuilder.include(sydney1); 
latlngBuilder.include(sydney2); 

googlemap.animateCamera(CameraUpdateFactory.newLatLngBounds(latlngBuilder.build(), 100)); 
0

、私はKotlinに拡張子を書いた:

fun LatLngBounds.Builder.createBoundsWithZoomMaintained(bounds: LatLngBounds) : LatLngBounds { 
    val HEADING_NORTH_EAST = 45.0 //NorthEast angle 
    val HEADING_SOUTH_WEST = 215.0 //SouthWest angle 
    val center = bounds.center 
    val northEast = SphericalUtil.computeOffset(center, 709.0, HEADING_NORTH_EAST) //1000 metres on the diagonal translates to 709 metres on either side. 
    val southWest = SphericalUtil.computeOffset(center, 709.0, HEADING_SOUTH_WEST) 
    this.include(northEast).include(southWest) 
    return this.build() 
} 

これは通常、あなたのUtilsのか、拡張機能ファイルにあるであろう、次のようにどこからでも使用できます:

var bounds = builder.build() //To include all your existing points. 
bounds = builder.createBoundsWithZoomMaintained(bounds) //Updated bounds. 
mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 10)) 
関連する問題