現在、Googleマップを使用してアプリの開発に取り組んでいますAndroid API v2。私のコードは次のとおりです。
LatLngBuilder.Builder builder = LatLngBounds.builder();
for(Marker m : markers){
builder.include(m.getPosition());
}
LatLngBounds bounds = builder.build();
map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 10);
このコードは正常に機能していますが、ズームレベルが17.0fに達したらアニメーションを停止します。 Map APIには、ズームレベルを制御するためのそのようなメソッドがないようです。誰もこの問題を解決するためのアイデアを知っていますか?
Google Maps APIの最近の pdate には、必要な機能が導入されています。
GoogleMap.setMaxZoomPreference()
GoogleMap.setMinZoomPreference()
それでも、アニメーションの再生は妨げられません。
Google Maps APIに直接的な解決策は見つかりませんでした。この問題の潜在的な解決策は、 OnCameraChangeイベント をリッスンすることです。このイベントがトリガーされ、ズームレベルが最大ズームレベルを超えるたびに、 animateCamera() を呼び出すことができます。 =。結果のコードは次のようになります。
@Override
public void onCameraChange(CameraPosition position) {
float maxZoom = 17.0f;
if (position.zoom > maxZoom)
map_.animateCamera(CameraUpdateFactory.zoomTo(maxZoom));
}
From Android doc: https://developers.google.com/maps/documentation/Android-api/views
You may find it useful to set a prefered minimum and/or maximum zoom level. For example, this is useful to control the user's experience if your app shows a defined area around a point of interest, or if you're using a custom tile overlay with a limited set of zoom levels.
private GoogleMap mMap;
// Set a preference for minimum and maximum zoom.
mMap.setMinZoomPreference(6.0f);
mMap.setMaxZoomPreference(14.0f);
以下は対応するJava Arvisのソリューションのコードで、私にとってはうまくいきました。
private LatLngBounds adjustBoundsForMaxZoomLevel(LatLngBounds bounds) {
LatLng sw = bounds.southwest;
LatLng ne = bounds.northeast;
double deltaLat = Math.abs(sw.latitude - ne.latitude);
double deltaLon = Math.abs(sw.longitude - ne.longitude);
final double zoomN = 0.005; // minimum zoom coefficient
if (deltaLat < zoomN) {
sw = new LatLng(sw.latitude - (zoomN - deltaLat / 2), sw.longitude);
ne = new LatLng(ne.latitude + (zoomN - deltaLat / 2), ne.longitude);
bounds = new LatLngBounds(sw, ne);
}
else if (deltaLon < zoomN) {
sw = new LatLng(sw.latitude, sw.longitude - (zoomN - deltaLon / 2));
ne = new LatLng(ne.latitude, ne.longitude + (zoomN - deltaLon / 2));
bounds = new LatLngBounds(sw, ne);
}
return bounds;
}
Arvisソリューションと同じですが、 Location
's [distanceBetween()
]( http://developer.Android.com/reference/Android/location /Location.html#distanceBetween(double 、double、double、double、float []))メソッドを使用して、ポイント間の距離を計算します。
@Override
public void zoomToMarkers(Set<Marker> markers) {
LatLngBounds.Builder builder = new LatLngBounds.Builder();
for (Marker marker : markers) {
builder.include(marker.getPosition());
}
LatLngBounds bounds = builder.build();
// Calculate distance between northeast and southwest
float[] results = new float[1];
Android.location.Location.distanceBetween(bounds.northeast.latitude, bounds.northeast.longitude,
bounds.southwest.latitude, bounds.southwest.longitude, results);
CameraUpdate cu = null;
if (results[0] < 1000) { // distance is less than 1 km -> set to zoom level 15
cu = CameraUpdateFactory.newLatLngZoom(bounds.getCenter(), 15);
} else {
int padding = 50; // offset from edges of the map in pixels
cu = CameraUpdateFactory.newLatLngBounds(bounds, padding);
}
if (cu != null) {
mMap.moveCamera(cu);
}
}
カメラをアニメートする前に、境界のSWおよびNEポイントが近すぎないかどうかを確認し、必要に応じて境界を調整できます。
...
LatLngBounds bounds = builder.Build();
var sw = bounds.Southwest;
var ne = bounds.Northeast;
var deltaLat = Math.Abs(sw.Latitude - ne.Latitude);
var deltaLon = Math.Abs(sw.Longitude - ne.Longitude);
const double zoomN = 0.005; // set whatever zoom coefficient you need!!!
if (deltaLat < zoomN) {
sw.Latitude = sw.Latitude - (zoomN - deltaLat / 2);
ne.Latitude = ne.Latitude + (zoomN - deltaLat / 2);
bounds = new LatLngBounds(sw, ne);
}
else if (deltaLon < zoomN) {
sw.Longitude = sw.Longitude - (zoomN - deltaLon / 2);
ne.Longitude = ne.Longitude + (zoomN - deltaLon / 2);
bounds = new LatLngBounds(sw, ne);
}
map.animateCamera(CameraUpdateFactory.NewLatLngBounds(bounds, 10);
追伸私の例はXamarinのC#ですが、Java用に簡単に調整できます
これは、使用しているinclude(position)
の- APIリファレンス からのものです。
「境界の構築のためにこの点を含みます。境界は、この点を含むように最小限の方法で拡張されます。より正確には、境界を東方向と西方向の両方に拡張することを検討します。そして、2つのうち小さい方を選択します。両方の方向が同じサイズのLatLngBoundsになる場合、これはそれを東方向に拡張します。」
マップは、forループに追加するすべてのマーカーを表示できるようになるまでズームアウトします。
17にズームアウトするだけでマーカーを表示したい場合は、最初にズームレベル17にアニメートし、次にその境界を取得してからマーカーを追加します。
@Override
public void onCameraChange(CameraPosition camPos) {
if (camPos.zoom < 17 && mCurrentLoc != null) {
// set zoom 17 and disable zoom gestures so map can't be zoomed out
// all the way
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(position,17));
mMap.getUiSettings().setZoomGesturesEnabled(false);
}
if (camPos.zoom >= 17) {
mMap.getUiSettings().setZoomGesturesEnabled(true);
}
LatLngBounds visibleBounds = mMap.getProjection().getVisibleRegion().latLngBounds;
//add the markers
@kasimirのアプローチでは、緯度または経度のいずれかで最小度数を設定し、少し読みにくいと感じました。そのため、緯度の最小値を設定するように調整しました。これはもう少し読みやすいと感じました。
private LatLngBounds adjustBoundsForMinimumLatitudeDegrees(LatLngBounds bounds, double minLatitudeDegrees) {
LatLng sw = bounds.southwest;
LatLng ne = bounds.northeast;
double visibleLatitudeDegrees = Math.abs(sw.latitude - ne.latitude);
if (visibleLatitudeDegrees < minLatitudeDegrees) {
LatLng center = bounds.getCenter();
sw = new LatLng(center.latitude - (minLatitudeDegrees / 2), sw.longitude);
ne = new LatLng(center.latitude + (minLatitudeDegrees / 2), ne.longitude);
bounds = new LatLngBounds(sw, ne);
}
return bounds;
}
これがうまくいくかどうかはわかりませんが、試してみてください
map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);
それが役に立てば幸い
_com.google.Android.gms:play-services-maps:9.4.0
_を使用すると、最小/最大ズームを簡単に設定できます。 GoogleMap.setMinZoomPreference()
およびGoogleMap.setMaxZoomPreference()
を使用すると、希望する最小および/または最大ズームレベルを設定できます。 こちら を参照してください。
マップの拡大機能を直接制限することはできませんが、このような同じ機能を取得しようとすることはできます。
map.setOnCameraChangeListenerを追加します
final float maxZoom = 10.0f;
@Override
public void onCameraChange(CameraPosition position) {
if (position.zoom > maxZoom)
map.animateCamera(CameraUpdateFactory.zoomTo(maxZoom));
}
map.setMinZoomPreference(floatValue);
新しいGoogleマップ9.8
com.google.Android.gms:play-services-maps:9.8.0
これは私がやった方法です
googleMap.setOnCameraMoveListener(new GoogleMap.OnCameraMoveListener() {
@Override
public void onCameraMove() {
Log.d(App.TAG, "onCameraMove");
CameraPosition position = googleMap.getCameraPosition();
float maxZoom = 9.0f;
if (position.zoom > maxZoom) {
googleMap.setMinZoomPreference(maxZoom);
}
Log.d(App.TAG, "position.zoom = " + position.zoom);
}
});
最終的には、独自のボタンを作成し、デフォルトのボタンを無効にして、完全に制御できるようにします。
ボタンを配置するレイアウトで次のようなもの:
<LinearLayout
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:orientation="vertical"
Android:layout_gravity="bottom"
Android:layout_alignParentRight="true"
Android:layout_alignParentBottom="true">
<Button
Android:id="@+id/bzoomin"
Android:layout_width="55dp"
Android:layout_height="55dp"
Android:gravity="center"
Android:textSize="28sp"
Android:text="+" />
<Button
Android:id="@+id/bzoomout"
Android:layout_width="55dp"
Android:layout_height="55dp"
Android:gravity="center"
Android:textSize="23sp"
Android:text="—" />
</LinearLayout>
次に、これをデフォルトのボタンを無効にして新しいボタンを設定するコードで:
map.getUiSettings().setZoomControlsEnabled(false);
// setup zoom control buttons
Button zoomout = (Button) findViewById(R.id.bzoomout);
zoomout.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
if(map.getCameraPosition().zoom >= 8.0f){
// Zoom like normal
map.animateCamera(CameraUpdateFactory.zoomOut());
}else{
// Do whatever you want if user went too far
Messages.toast_short(MapsActivity.this, "Maximum zoom out level reached");
}
}
});
Button zoomin = (Button) findViewById(R.id.bzoomin);
zoomin.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (map.getCameraPosition().zoom <= 14.0f) {
// Zoom like normal
map.animateCamera(CameraUpdateFactory.zoomIn());
} else {
// Do whatever you want if user went too far
Messages.toast_short(MapsActivity.this, "Maximum zoom in level reached");
}
}
});