android google地图添加标记并根据标记的地理情况确定缩放大小

    今天做地图模块的编码,遇到根据地图图层添加地理标记并将所有标记都显示在地图上的问题,首先我们知道,地图很大,手机的屏幕却很小,所以我们只能通过缩放来实现地图的的查看。但是标记的地理位置是随意的,并不一定都能显示出来,所以为了控制标记全部显示,我们必须根据标记的实际情况来控制地图的缩放程度。首先必须确定一个中心点,然后设置一个比较大的缩放级别,然后根据屏幕得出最大的经纬度,与标记的最大经纬度进行比较,如果标记在范围内则不用修改缩放,如果标记的结果不在屏幕范围内则应该对地图进行缩小。对地图的缩放控制应该放到线程里,因为必须保证mapView渲染结束后才能得到地图屏幕所对应的经纬度范围。

       以下是代码。

public class MapMsgActivity extends MapActivity implements ILbsActivity{

private MapView mapView;;
private View popView;
static final int INITIAL_ZOOM_LEVEL = 12;
private View msgView;
// static int INITIAL_LATITUDE = 25040255;
// static int INITIAL_LONGITUDE = 121512377;
static double INITIAL_LATITUDE = 39;
static double INITIAL_LONGITUDE = 121.44;
private List<Overlay> mapOverlays;
private Drawable drawable;
private HelloItemizedOverlay itemizedOverlay;
private double friendLatitude;
private double friendLongitude;
@Override
protected void onCreate(Bundle icicle) {
// TODO Auto-generated method stub
super.onCreate(icicle);
popView = View.inflate(this, R.layout.popview, null);
setContentView(R.layout.map);
mapView = (MapView) findViewById(R.id.mapview);
mapView.addView(popView, new MapView.LayoutParams(
MapView.LayoutParams.WRAP_CONTENT,
MapView.LayoutParams.WRAP_CONTENT, null,
MapView.LayoutParams.BOTTOM_CENTER));
popView.setVisibility(View.GONE);
msgView = findViewById(R.id.r2_bottom);
msgView.setVisibility(View.VISIBLE);
mapView.setBuiltInZoomControls(true);
Intent intent = getIntent();
Bundle bundle = intent.getExtras();
friendLatitude = bundle.getDouble("latitude");
friendLongitude = bundle.getDouble("longitude");
double centerLat = (friendLatitude+INITIAL_LATITUDE)/2* 1E6;
double centerLont = (friendLongitude+friendLongitude)/2* 1E6;
//设定Zoom大小和地图的中心点
MapController mc = mapView.getController();
mc.setZoom(INITIAL_ZOOM_LEVEL);
System.out.println("Latitude:"+(int)(INITIAL_LATITUDE * 1E6));
System.out.println("Longtitude:"+(int)(INITIAL_LONGITUDE* 1E6));
mc.setCenter(new GeoPoint((int)(centerLat),(int)(centerLont)));
//贴上标记
mapOverlays = mapView.getOverlays();
drawable = this.getResources().getDrawable(R.drawable.appicon);
itemizedOverlay = new HelloItemizedOverlay(drawable);
itemizedOverlay.setOnFocusChangeListener(onFocusChangeListener);
GeoPoint point = new GeoPoint((int)(INITIAL_LATITUDE * 1E6),(int)(INITIAL_LONGITUDE* 1E6));
OverlayItem overlayitem = new OverlayItem(point, "我的位置", "我的位置介绍");
itemizedOverlay.addOverlay(overlayitem);

GeoPoint fpoint = new GeoPoint((int)(friendLatitude * 1E6),(int)(friendLongitude* 1E6));
OverlayItem foverlayitem = new OverlayItem(fpoint, bundle.getString("friendname"), bundle.getString("introduce"));
itemizedOverlay.addOverlay(foverlayitem);
mapOverlays.add(itemizedOverlay);
//handler.post(updateThread);
new Thread(updateThread).start();
}
//创建Handler对象
Handler handler = new Handler();
//新建一个线程对象
Runnable updateThread = new Runnable(){
//将要执行的操作写在线程对象的run方法当中
public void run(){
while(mapView.getHeight() == 0)
{
System.out.println("mapView等于0,mapView还没渲染完毕");
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException e){e.printStackTrace();}
}
if(mapView.getHeight()!=0){
/*
 * 使用setZoom来让数据标签自适应屏幕
  */
//根据左上角来判断
Projection proj = mapView.getProjection();
MapController mapController = mapView.getController();
GeoPoint geoFromPix = proj.fromPixels(0,0);
double pix_lng = geoFromPix.getLongitudeE6()/1E6;// 左上角屏幕像素转换成的gps经度
double pix_lat = geoFromPix.getLatitudeE6()/1E6;// 左上角屏幕像素转换成的gps纬度
double min_x=getMin(INITIAL_LONGITUDE,friendLongitude);
System.out.println("min_x:"+min_x);
System.out.println("pix_lng:"+pix_lng);
while (min_x < pix_lng) {// 数据中最小经度如果小于屏幕所对应的最小经度(出界),则缩小地图,让数据显示到屏幕中
System.out.println("缩小地图1:" + min_x + "," + pix_lng);
mapController.setZoom(mapView.getZoomLevel()- 1);
pix_lng = mapView.getProjection().fromPixels(0,0).getLongitudeE6()/1E6;
pix_lat = mapView.getProjection().fromPixels(0,0).getLatitudeE6() /1E6;
}
double max_y=getMin(INITIAL_LATITUDE,friendLatitude);
System.out.println("max_y:"+max_y);
System.out.println("pix_lat:"+pix_lat);
while(max_y > pix_lat) {// 数据中最大纬度如果大于屏幕所对应的最小纬度(出界),则缩小地图,让数据显示到屏幕中
System.out.println("缩小地图2");
mapController.setZoom(mapView.getZoomLevel() - 1);
pix_lat = mapView.getProjection().fromPixels(0,0).getLatitudeE6()/1E6;
}
System.out.println("mapView的值:"+mapView.getHeight());
}
//调用Handler的postDelayed()方法
//这个方法的作用是:将要执行的线程对象放入到队列当中,待时间结束后,运行制定的线程对象
//第一个参数是Runnable类型:将要执行的线程对象
//第二个参数是long类型:延迟的时间,以毫秒为单位
//handler.postDelayed(updateThread, 1000);
}
};
private final ItemizedOverlay.OnFocusChangeListener onFocusChangeListener = new ItemizedOverlay.OnFocusChangeListener() {

@Override
public void onFocusChanged(ItemizedOverlay overlay, OverlayItem newFocus)
{
// 创建气泡窗口
if (popView != null) {
popView.setVisibility(View.GONE);
}
if (newFocus != null) {

MapView.LayoutParams geoLP = (MapView.LayoutParams) popView
.getLayoutParams();
geoLP.point = newFocus.getPoint();// 这行用于popView的定位
TextView title = (TextView) popView
.findViewById(R.id.map_bubbleTitle);
title.setText(newFocus.getTitle());

TextView desc = (TextView) popView
.findViewById(R.id.map_bubbleText);
if (newFocus.getSnippet() == null
|| newFocus.getSnippet().length() == 0) {
desc.setVisibility(View.GONE);
} else {
desc.setVisibility(View.VISIBLE);
desc.setText(newFocus.getSnippet());
}
mapView.updateViewLayout(popView, geoLP);
popView.setVisibility(View.VISIBLE);
}
}
};
@Override
protected boolean isRouteDisplayed() {
// TODO Auto-generated method stub
return false;
}

@Override
public void init() {
// TODO Auto-generated method stub

}

@Override
public void refresh(Object... param) {
// TODO Auto-generated method stub

}
public double getMin(double num1,double num2)
{
if(num1<num2)
return num2;
else
return num1;
}

}

效果图附上

原文地址:https://www.cnblogs.com/rainbowhjj/p/2826803.html