Android 지도 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
건설하다.자세한 내용은 이 답변에 대한 설명과 나머지 답변에서 확인할 수 있습니다.여기를 사용하여 지도 범위를 설정하는 전체 코드를 찾을 수도 있습니다.
명확화 2
한 의견에서는 이 방법을 하나의 마커에만 사용하면 지도 확대/축소 수준이 "이상한" 확대/축소 수준(지정된 위치에서 사용할 수 있는 최대 확대/축소 수준)으로 설정된다는 점에 주목합니다.예상되는 이유는 다음과 같습니다.
- 그
LatLngBounds bounds
예를 들면,northeast
동등한 재산.southwest
이것으로 덮인 지구의 면적 부분을 의미합니다.bounds
정확하게 0입니다. (단일 마커에는 영역이 없으므로 논리적입니다.) - 지나감
bounds
로.CameraUpdateFactory.newLatLngBounds
당신은 본질적으로 그러한 줌 레벨의 계산을 요청합니다.bounds
(영역이 0인 경우) 전체 지도 보기를 포함합니다. - 실제로 종이 한 장에 대해 이 계산을 수행할 수 있습니다.정답인 이론적 확대/축소 수준은 +∞(양의 무한대)입니다.실제로는
Map
개체가 이 값을 지원하지 않으므로 지정된 위치에 허용되는 보다 합리적인 최대 수준으로 고정됩니다.
다른 말로 표현하자면: 어떻게 그럴 수 있습니까?Map
개체가 단일 위치에 대해 어떤 확대/축소 수준을 선택해야 하는지 알고 있습니까?최적 값은 20이어야 합니다(특정 주소를 나타내는 경우).또는 11(마을을 나타내는 경우)일 수도 있습니다.또는 6(국가를 나타내는 경우)일 수 있습니다.API는 그렇게 똑똑하지 않으며 결정은 당신에게 달려 있습니다.
그래서, 당신은 단순히 확인해야 합니다.markers
에는 위치가 하나만 있으며 위치가 있는 경우 다음 중 하나를 사용합니다.
CameraUpdate cu = CameraUpdateFactory.newLatLng(marker.getPosition())
마커 위치로 이동하고 현재 확대/축소 수준을 그대로 유지합니다.CameraUpdate cu = CameraUpdateFactory.newLatLngZoom(marker.getPosition(), 12F)
마커 위치로 이동하여 줌 레벨을 임의로 선택한 값 12로 설정합니다.
Google 지도 V2
다음 솔루션은 Android Mashmallow 6(API 23, API 24, API 25, API 26, API 27, API 28)에서 작동합니다.사마린에서도 작동합니다.
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);
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));
}
});
그렇게
적절한 샘플을 얻으려면 addOnGlobalLayoutListener를 사용해야 했습니다.
예를 들어 Google 지도는 상대 레이아웃 내부에 있습니다.
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
}
});
나는 잘 작동합니다.
이 코드에서 지도 화면에 여러 개의 마커를 특정 확대/축소하여 표시합니다.
선언 변수
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 명확화 2에 대한 해결책 -
범위에 마커가 하나만 있고 이로 인해 확대/축소 수준이 매우 높은 수준(레벨 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도 "이상한" 확대/축소 수준에 대해 잘 설명할 수 없습니다.
이것은 도움이 될 것입니다.구글 아피스 데모에서.
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
Google 지도에서 모든 마커 표시
이 방법에서는 모든 마커를 저장하고 자동으로 확대/축소하여 모든 마커를 Google 지도에 표시합니다.
// Declare the Markers List.
List<MarkerOptions> markerList;
private BitmapDescriptor vnrPoint,banPoint;
public void storeAllMarkers()
{
markerList=new ArrayList<>();
markerList.removeAll(markerList);
// latitude and longitude of Virudhunagar
double latitude1=9.587209;
double longitude1=77.951431;
vnrPoint=BitmapDescriptorFactory.fromResource(R.drawable.location_icon_1);
LatLng vnr = new LatLng(latitude1, longitude1);
MarkerOptions vnrMarker = new MarkerOptions();
vnrMarker.position(vnr);
vnrMarker.icon(vnrPoint);
markerList.add(vnrMarker);
// latitude and longitude of Bengaluru
double latitude2=12.972442;
double longitude2=77.580643;
banPoint=BitmapDescriptorFactory.fromResource(R.drawable.location_icon_2);
LatLng ban = new LatLng(latitude2, longitude2);
MarkerOptions bengalureMarker = new MarkerOptions();
bengalureMarker.position(ban);
bengalureMarker.icon(banPoint);
markerList.add(bengalureMarker);
// You can add any numbers of MarkerOptions like this.
showAllMarkers();
}
public void showAllMarkers()
{
LatLngBounds.Builder builder = new LatLngBounds.Builder();
for (MarkerOptions m : markerList) {
builder.include(m.getPosition());
}
LatLngBounds bounds = builder.build();
int width = getResources().getDisplayMetrics().widthPixels;
int height = getResources().getDisplayMetrics().heightPixels;
int padding = (int) (width * 0.30);
// Zoom and animate the google map to show all markers
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, width, height, padding);
googleMap.animateCamera(cu);
}
비슷한 문제가 있었는데 다음 코드를 사용하여 문제를 해결했습니다.
CameraUpdateFactory.newLatLngBounds(bounds, 200, 200, 5)
일반적으로 제 경우의 위치 차이는 두 개의 이웃 도시 이상이 아닙니다.
지도의 모든 마커에 맞게 확대/축소 Google 지도 v2
저는 이와 같은 일을 하는 다른 방법이 하나 더 있습니다. 그래서 화면에 모든 마커를 표시하기 위한 아이디어 뒤에는 긴 시간과 줌 레벨의 중앙이 필요합니다.여기에 당신에게 둘 다를 제공하고 모든 마커의 Latlng 객체를 입력으로 필요로 하는 기능이 있습니다.
public Pair<LatLng, Integer> getCenterWithZoomLevel(LatLng... l) {
float max = 0;
if (l == null || l.length == 0) {
return null;
}
LatLngBounds.Builder b = new LatLngBounds.Builder();
for (int count = 0; count < l.length; count++) {
if (l[count] == null) {
continue;
}
b.include(l[count]);
}
LatLng center = b.build().getCenter();
float distance = 0;
for (int count = 0; count < l.length; count++) {
if (l[count] == null) {
continue;
}
distance = distance(center, l[count]);
if (distance > max) {
max = distance;
}
}
double scale = max / 1000;
int zoom = ((int) (16 - Math.log(scale) / Math.log(2)));
return new Pair<LatLng, Integer>(center, zoom);
}
이 함수는 다음과 같이 사용할 수 있는 Pair 개체를 반환합니다.
쌍 = getCenterWithZoomLevel(l1,l2,l3...); mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(쌍.첫 번째, 쌍).둘째));
화면 경계에서 마커를 멀리하기 위해 패딩을 사용하는 대신 -1로 확대/축소를 조정할 수 있습니다.
코틀린에서 조각을 사용하여 여러 마커를 보여주는 것과 같은 문제를 해결했습니다.
먼저 마커 목록을 선언합니다.
private lateinit var markers: MutableList<Marker>
Framework의 oncreate 메서드에서 초기화합니다.
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
//initialize markers list
markers = mutableListOf()
return inflater.inflate(R.layout.fragment_driver_map, container, false)
}
OnMapReadyCallback에서 마커 목록에 마커 추가
private val callback = OnMapReadyCallback { googleMap ->
map = googleMap
markers.add(
map.addMarker(
MarkerOptions().position(riderLatLng)
.title("Driver")
.snippet("Driver")
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED))))
markers.add(
map.addMarker(
MarkerOptions().position(driverLatLng)
.title("Driver")
.snippet("Driver")
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN))))
아직 콜백 중입니다.
//create builder
val builder = LatLngBounds.builder()
//loop through the markers list
for (marker in markers) {
builder.include(marker.position)
}
//create a bound
val bounds = builder.build()
//set a 200 pixels padding from the edge of the screen
val cu = CameraUpdateFactory.newLatLngBounds(bounds,200)
//move and animate the camera
map.moveCamera(cu)
//animate camera by providing zoom and duration args, callBack set to null
map.animateCamera(CameraUpdateFactory.zoomTo(10f), 2000, null)
메리 코딩 친구들
중심 좌표를 가져와 카메라 위치에서 사용하려면 "getCenter Coordinate" 방법을 사용합니다.
private void setUpMap() {
mMap.setMyLocationEnabled(true);
mMap.getUiSettings().setScrollGesturesEnabled(true);
mMap.getUiSettings().setTiltGesturesEnabled(true);
mMap.getUiSettings().setRotateGesturesEnabled(true);
clientMarker = mMap.addMarker(new MarkerOptions()
.position(new LatLng(Double.valueOf(-12.1024174), Double.valueOf(-77.0262274)))
.icon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_taxi))
);
clientMarker = mMap.addMarker(new MarkerOptions()
.position(new LatLng(Double.valueOf(-12.1024637), Double.valueOf(-77.0242617)))
.icon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_location))
);
camPos = new CameraPosition.Builder()
.target(getCenterCoordinate())
.zoom(17)
.build();
camUpd3 = CameraUpdateFactory.newCameraPosition(camPos);
mMap.animateCamera(camUpd3);
}
public LatLng getCenterCoordinate(){
LatLngBounds.Builder builder = new LatLngBounds.Builder();
builder.include(new LatLng(Double.valueOf(-12.1024174), Double.valueOf(-77.0262274)));
builder.include(new LatLng(Double.valueOf(-12.1024637), Double.valueOf(-77.0242617)));
LatLngBounds bounds = builder.build();
return bounds.getCenter();
}
//For adding a marker in Google map
MarkerOptions mp = new MarkerOptions();
mp.position(new LatLng(Double.parseDouble(latitude), Double.parseDouble(longitude)));
mp.snippet(strAddress);
map.addMarker(mp);
try {
b = new LatLngBounds.Builder();
if (MapDetailsList.list != null && MapDetailsList.list.size() > 0) {
for (int i = 0; i < MapDetailsList.list.size(); i++) {
b.include(new LatLng(Double.parseDouble(MapDetailsList.list.get(i).getLatitude()),
Double.parseDouble(MapDetailsList.list.get(i).getLongitude())));
}
LatLngBounds bounds = b.build();
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
int width = displayMetrics.widthPixels;
int height = displayMetrics.heightPixels;
// Change the padding as per needed
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, width-200, height-200, 5);
// map.setCenter(bounds.getCenter());
map.animateCamera(cu);
}
} catch (Exception e) {
}
http://i64.tinypic.com/2qjybh4.png
http://i63.tinypic.com/flzwus.png
http://i63.tinypic.com/112g5fm.png
언급URL : https://stackoverflow.com/questions/14828217/android-map-v2-zoom-to-show-all-the-markers
'programing' 카테고리의 다른 글
스프링 부트 @다른 모듈에서 자동 배선된 빈 (0) | 2023.07.27 |
---|---|
파일 생성을 위해 BLOB를 Ajax를 통해 전달 (0) | 2023.07.27 |
프로그래밍 방식으로 뷰에 패딩 추가 (0) | 2023.07.27 |
입력 값이 배열에 있는지 확인하는 방법(Powershell) (0) | 2023.07.27 |
편집 텍스트 내의 그리기 테이블에서 클릭 이벤트 처리 (0) | 2023.07.27 |