[android] 모든 마커를 표시하는 Android Map v2 확대
에 10 개의 마커가 있습니다 GoogleMap
. 최대한 확대하고 모든 마커를 계속보고 싶습니다. 이전 버전에서는 이것이 가능 zoomToSpan()
하지만 v2에서는 그렇게하는 방법을 모릅니다. 또한, 볼 필요가있는 원의 반경을 알고 있습니다.
답변
CameraUpdate
모든 프로그래밍 방식의 맵 이동을 수행 하려면 클래스를 사용해야합니다 .
이렇게하려면 먼저 모든 마커의 경계를 다음과 같이 계산하십시오.
LatLngBounds.Builder builder = new LatLngBounds.Builder();
for (Marker marker : markers) {
builder.include(marker.getPosition());
}
LatLngBounds bounds = builder.build();
그런 다음 팩토리를 사용하여 이동 설명 오브젝트를 확보하십시오 CameraUpdateFactory
.
int padding = 0; // offset from edges of the map in pixels
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, padding);
마지막으로지도를 이동하십시오.
googleMap.moveCamera(cu);
또는 애니메이션을 원한다면 :
googleMap.animateCamera(cu);
그게 다야 🙂
설명 1
거의 모든 이동 방법에는 Map
객체가 레이아웃 프로세스를 통과해야합니다. addOnGlobalLayoutListener
구문을 사용하여이 문제가 발생할 때까지 기다릴 수 있습니다 . 자세한 내용은이 답변에 대한 의견과 나머지 답변에 나와 있습니다. here를 사용하여 맵 범위를 설정하기위한 전체 코드를addOnGlobalLayoutListener
찾을 수도 있습니다 .
설명 2
한 의견에서는이 방법을 하나의 마커에만 사용하면지도 확대 / 축소가 “기괴한”확대 / 축소 수준 (주어진 위치에서 사용 가능한 최대 확대 / 축소 수준)으로 설정됩니다. 나는 이것이 다음과 같은 이유로 예상된다고 생각한다.
LatLngBounds bounds
인스턴스 것이다northeast
동일한 특성southwest
이 적용 지구의 영역의 부분 즉,bounds
정확히 제로이다. (단일 마커에는 면적이 없으므로 논리적입니다.)- 전달하여
bounds
에CameraUpdateFactory.newLatLngBounds
당신은 본질적으로되도록 줌 레벨의 계산 요청bounds
(제로 영역을 갖는) 전체지도보기를 다룰 것입니다. - 실제로이 계산은 한 장의 종이에서 수행 할 수 있습니다. 정답 인 이론적 줌 레벨은 + ∞ (양의 무한대)입니다. 실제로
Map
객체는이 값을 지원하지 않으므로 주어진 위치에 허용되는보다 합리적인 최대 수준으로 고정됩니다.
그것을 넣는 또 다른 방법 : Map
객체가 단일 위치에 대해 어떤 줌 레벨을 선택 해야하는지 알 수 있습니까? 최적의 값은 20이어야합니다 (특정 주소를 나타내는 경우). 아니면 11 일 수도 있습니다 (도시를 나타내는 경우). 또는 6 (국가를 대표하는 경우). API는 현명하지 않으며 결정은 당신에게 달려 있습니다.
따라서 markers
위치가 하나만 있는지 확인 하고 있으면 다음 중 하나를 사용하십시오.
CameraUpdate cu = CameraUpdateFactory.newLatLng(marker.getPosition())
-마커 위치로 이동하여 현재 확대 / 축소 수준을 그대로 둡니다.CameraUpdate cu = CameraUpdateFactory.newLatLngZoom(marker.getPosition(), 12F)
-마커 위치로 이동하여 줌 레벨을 임의로 선택된 값 12로 설정하십시오.
답변
구글 맵 V2
다음 솔루션은 Android Marshmallow 6 (API 23, API 24, API 25, API 26, API 27, API 28)에서 작동합니다. Xamarin에서도 작동합니다.
LatLngBounds.Builder builder = new LatLngBounds.Builder();
//the include method will calculate the min and max bound.
builder.include(marker1.getPosition());
builder.include(marker2.getPosition());
builder.include(marker3.getPosition());
builder.include(marker4.getPosition());
LatLngBounds bounds = builder.build();
int width = getResources().getDisplayMetrics().widthPixels;
int height = getResources().getDisplayMetrics().heightPixels;
int padding = (int) (width * 0.10); // offset from edges of the map 10% of screen
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, width, height, padding);
mMap.animateCamera(cu);
답변
그래서
적절한 샘플을 얻으려면 addOnGlobalLayoutListener를 사용해야했습니다.
예를 들어 Google지도는 RelativeLayout에 있습니다.
RelativeLayout mapLayout = (RelativeLayout)findViewById(R.id.map_layout);
mapLayout.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
//and write code, which you can see in answer above
}
});
답변
onGlobalLayoutlistener를 사용할 수 없으므로 "Map size can't be 0. Most likely, layout has not yet occured for the map view. Either wait until layout has occurred or use newLatLngBounds(LatLngBounds, int, int, int) which allows you to specify the map's dimensions."
오류 를 방지하는 또 다른 솔루션이 있습니다
.
mMap.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() {
@Override
public void onMapLoaded() {
mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(builder.build(), 15));
}
});
답변
나를 위해 잘 작동합니다.
이 코드에서지도 화면에 특정 확대 / 축소로 여러 개의 마커를 표시하고 있습니다.
// 선언 된 변수
private LatLngBounds bounds;
private LatLngBounds.Builder builder;
// 드로어 블 아이콘으로 여러 마커 포인트를 추가하는 방법
private void drawMarker(LatLng point, String text) {
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(point).title(text).icon(BitmapDescriptorFactory.fromResource(R.drawable.icon));
mMap.addMarker(markerOptions);
builder.include(markerOptions.getPosition());
}
//지도에서 여러 개의 마커를 볼 수 있도록 추가
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
builder = new LatLngBounds.Builder();
for (int i = 0; i < locationList.size(); i++) {
drawMarker(new LatLng(Double.parseDouble(locationList.get(i).getLatitude()), Double.parseDouble(locationList.get(i).getLongitude())), locationList.get(i).getNo());
}
bounds = builder.build();
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, 0);
mMap.animateCamera(cu);
답변
참고 -이것은 원래 질문에 대한 해결책이 아닙니다. 이것은 위에서 설명한 하위 문제 중 하나에 대한 솔루션입니다 입니다.
솔루션 @andr하는 명확한 설명이 –
바운드에 마커가 하나만있을 때 문제가되고 줌 레벨이 매우 높은 수준 ( 레벨 21 )으로 설정됩니다. Google은 현재 최대 줌 레벨을 설정하는 방법을 제공하지 않습니다. 마커가 둘 이상 있지만 모두 서로 매우 가까운 경우에도 발생할 수 있습니다. 그런 다음 동일한 문제가 발생합니다.
해결책 -지도가 16 배 줌 레벨을 넘지 않기를 원한다고 가정하십시오. 그런 다음-
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, padding);
mMap.moveCamera(cu);
확대 / 축소 수준이 16 단계 (또는 원하는 수준)를 초과했는지 확인하십시오.
float currentZoom = mMap.getCameraPosition().zoom;
이 수준이 16보다 크면 마커가 매우 적거나 모든 마커가 서로 매우 근접한 경우에만 확대 수준을 16으로 설정하여 해당 특정 위치에서 맵을 축소하면됩니다.
mMap.moveCamera(CameraUpdateFactory.zoomTo(16));
이렇게하면 @andr도 “기괴한”줌 레벨 문제를 잘 설명하지 못할 것입니다.
답변
이것은 도움이 될 것입니다 .. 구글 API 데모에서
private List<Marker> markerList = new ArrayList<>();
Marker marker = mGoogleMap.addMarker(new MarkerOptions().position(geoLatLng)
.title(title));
markerList.add(marker);
// Pan to see all markers in view.
// Cannot zoom to bounds until the map has a size.
final View mapView = getSupportFragmentManager().findFragmentById(R.id.map).getView();
if (mapView!=null) {
if (mapView.getViewTreeObserver().isAlive()) {
mapView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@SuppressWarnings("deprecation") // We use the new method when supported
@SuppressLint("NewApi") // We check which build version we are using.
@Override
public void onGlobalLayout() {
//Calculate the markers to get their position
LatLngBounds.Builder b = new LatLngBounds.Builder();
for (Marker m : markerList) {
b.include(m.getPosition());
}
// also include current location to include in the view
b.include(new LatLng(mLocation.getLatitude(),mLocation.getLongitude()));
LatLngBounds bounds = b.build();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
mapView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
} else {
mapView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 50));
}
});
}
}
명확한 정보를 원하시면이 URL을보십시오.
https://github.com/googlemaps/android-samples/blob/master/ApiDemos/app/src/main/java/com/example/mapdemo/MarkerDemoActivity.java