CameraUpdate cu = CameraUpdateFactory.newLatLng(marker.getPosition()) - 转到标记位置,保持当前缩放级别不变 .
CameraUpdate cu = CameraUpdateFactory.newLatLngZoom(marker.getPosition(), 12F) - 转到标记位置,将缩放级别设置为任意选择的值12 .
3
Google Map V2:缩放范围内的MarkerOptions适用于Android Marshmallow 6(API 23,API 24,API 25)的最佳工作解决方案,也适用于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);
11
所以
我需要使用addOnGlobalLayoutListener来获取适当的样本
例如,您的Google Map 位于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
}
});
84
我无法使用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." 错误的另一个解决方案:
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));
}
});
}
}
// 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);
}
0
//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) {
}
12 回答
您应该使用
CameraUpdate
类(可能)执行所有程序化 Map 移动 .为此,首先计算所有标记的边界,如下所示:
然后使用工厂获取运动描述对象:
CameraUpdateFactory
:最后移动 Map :
或者如果你想要一个动画:
就这样 :)
Clarification 1
几乎所有的移动方法都需要
Map
对象通过布局过程 . 您可以使用addOnGlobalLayoutListener
构造等待这种情况发生 . 详细信息可以在对此答案的评论和剩余答案中找到 . 你也可以找到complete code for setting map extent using addOnGlobalLayoutListener here .Clarification 2
一条评论指出,仅将此方法用于一个标记会导致 Map 缩放设置为“奇异”缩放级别(我相信这是给定位置可用的最大缩放级别) . 我认为这是预期的,因为:
LatLngBounds bounds
实例的northeast
属性等于southwest
,这意味着bounds
覆盖的地球部分正好为零 . (这是合乎逻辑的,因为单个标记没有区域 . )通过将
bounds
传递给CameraUpdateFactory.newLatLngBounds
,您基本上要求计算这样的缩放级别bounds
(具有零区域)将覆盖整个 Map 视图 .您实际上可以在一张纸上执行此计算 . 作为答案的理论缩放级别是∞(正无穷大) . 在实践中,
Map
对象不支持此值,因此它被限制为给定位置允许的更合理的最大级别 .另一种说法:
Map
对象如何知道它应该为单个位置选择什么缩放级别?也许最佳值应为20(如果它代表特定地址) . 或者可能是11(如果它代表一个小镇) . 或者可能是6(如果它代表一个国家) . API不是那么聪明,决定取决于你 .因此,您应该只检查
markers
是否只有一个位置,如果是,请使用以下方法之一:CameraUpdate cu = CameraUpdateFactory.newLatLng(marker.getPosition())
- 转到标记位置,保持当前缩放级别不变 .CameraUpdate cu = CameraUpdateFactory.newLatLngZoom(marker.getPosition(), 12F)
- 转到标记位置,将缩放级别设置为任意选择的值12 .Google Map V2:缩放范围内的MarkerOptions适用于Android Marshmallow 6(API 23,API 24,API 25)的最佳工作解决方案,也适用于Xamarin
所以
例如,您的Google Map 位于RelativeLayout内:
我无法使用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."
错误的另一个解决方案:从这段代码中,我在 Map 屏幕上显示具有特定缩放的多个标记 .
//声明变量
//使用可绘制图标添加多个标记点的方法
//用于添加 Map 上可见的多个标记
Note - 这不是原始问题的解决方案 . 这是对所讨论的一个子问题的解决方案above .
解决@andr Clarification 2 -
当边界中只有一个标记并且由于它将缩放级别设置为非常高的级别( level 21 )时,它确实存在问题 . 此时谷歌没有提供任何设置最大缩放级别的方法 . 当有超过1个标记但它们彼此非常接近时,也会发生这种情况 . 然后也会出现同样的问题 .
Solution - 假设您希望 Map 永远不会超过16个缩放级别 . 然后做 -
检查您的缩放级别是否已超过16级(或任何您想要的) -
如果此级别大于16,只有当标记非常少或所有标记彼此非常接近时才会这样,那么只需将缩放级别设置为16,就可以在该特定位置缩小 Map .
这样你就永远不会有@andr很好地解释“奇异”缩放级别的问题 .
这将有助于..从谷歌apis演示
有关清晰的信息,请查看此网址 . https://github.com/googlemaps/android-samples/blob/master/ApiDemos/app/src/main/java/com/example/mapdemo/MarkerDemoActivity.java
我有类似的问题,使用以下代码解决了问题:
CameraUpdateFactory.newLatLngBounds(bounds, 200, 200, 5)
一般来说,我的情况下的位置差异不超过两个邻近城市 .zoom to fit all markers on map google maps v2
使用方法“getCenterCoordinate”获取中心坐标并在CameraPosition中使用 .
我还有另外一种方法可以做同样的事情 . 因此,在屏幕上显示所有标记背后的想法我们需要一个中心lat长和缩放级别 . 这里的函数将为您提供并且需要所有标记的Latlng对象作为输入 .
这个函数返回你可以使用的Pair对象
你可以用-1而不是使用填充来阻挡标记与屏幕边界的距离 .
Show All Markers with Google map
在这些方法中存储所有标记并自动缩放以显示谷歌 Map 中的所有标记 .
http://i64.tinypic.com/2qjybh4.png
http://i63.tinypic.com/flzwus.png
http://i63.tinypic.com/112g5fm.png