android google map中使用mapView适应多个地图标识

来源:未知 责任编辑:智问网络 发表时间:2013-11-12 17:12 点击:

遇到一个需求,在地图中标识多个地点(全国范围),地点的gps放到一个xml文件中,以便随时修改。要求是地图要尽可能详细,但是得把所有地点包括在内。
做法如下:
1、先得到数据的最大和最小经纬度,计算出数据的中心点(也是经纬度);
2、把地图的zoom level默认一个比较大的值,如19或20之类的。这样的话肯定是有很多地点是没有显示在mapView上的,然后再逐渐减少level的值,以显示所有的地点。
    过程很清晰,看起来没什么问题,得出主要代码如下:
Java代码 
public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.main); 
        comList = this.getComList();//获取摄像头数据 
        mapView = (MapView) findViewById(R.id.MapView01); 
        mapView.setStreetView(true); 
        mapView.setEnabled(true); 
        mapView.setClickable(true); 
        mapView.setBuiltInZoomControls(true); // 设置地图支持缩放 
         
        System.out.println("长和宽:"+mapView.getHeight()+","+mapView.getWidth()); 
        mapController = (MapController)mapView.getController(); 
//      locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);// 位置管理器 
 
        // 设置地图中心点 
        Double lat1 = (min_y + max_y) / 2 * 1E6; 
        Double lng1 = (min_x + max_x) / 2 * 1E6; 
        System.out.println("中心点:"+lat1+","+lng1); 
        GeoPoint geoPoint = new GeoPoint(lat1.intValue(), lng1.intValue()); 
        mapController.setCenter(geoPoint); 
        mapController.setZoom(16); 
         
        ... 
 
        Drawable defaultMarker = getResources().getDrawable(R.drawable.arrow); 
        Drawable activeMarker = getResources().getDrawable(R.drawable.icon); 
        defaultMarker.setBounds(0, 0, defaultMarker.getMinimumWidth(), 
                defaultMarker.getMinimumHeight()); 
        PositionsOverlay posOverlay = new PositionsOverlay(defaultMarker, 
                comList, activeMarker,this); 
        List<Overlay> overlays = getMapView().getOverlays(); 
        overlays.add(posOverlay); 
         
         
        //根据左上角来判断 
        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纬度 
 
        // System.out.println("缩放前中心点: "+mapView.getMapCenter()); 
        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; 
 
        } 
        while (max_y > pix_lat) {// 数据中最大纬度如果大于屏幕所对应的最小纬度(出界),则缩小地图,让数据显示到屏幕中 
            System.out.println("缩小地图2"); 
            mapController.setZoom(mapView.getZoomLevel() - 1); 
            pix_lat = mapView.getProjection().fromPixels(0, 0) 
                    .getLatitudeE6() / 1E6; 
        } 


运行结果,后台狂刷:
Java代码 
08-18 07:47:00.076: INFO/System.out(437): 缩小地图1:121.1004,121.145444 
08-18 07:47:00.076: INFO/System.out(437): 缩小地图1:121.1004,121.145444 
08-18 07:47:00.076: INFO/System.out(437): 缩小地图1:121.1004,121.145444 
08-18 07:47:00.076: INFO/System.out(437): 缩小地图1:121.1004,121.145444 
08-18 07:47:00.076: INFO/System.out(437): 缩小地图1:121.1004,121.145444 
08-18 07:47:00.076: INFO/System.out(437): 缩小地图1:121.1004,121.145444 


将左上角换成右下角,发现取不到mapView的宽和高。。。
上网找了下,说法如下:
Java代码 
A common mistake made by new Android developers is to use 
the width and height of a view inside its constructor. When 
a view’s constructor is called, Android doesn’t know yet how 
big the view will be, so the sizes are set to zero. The real sizes 
are calculated during the layout stage, which occurs after 
construction but before anything is drawn. You can use the 
onSizeChanged( )method to be notified of the values when they 
are known, or you can use the getWidth( ) and getHeight( )methods 
later, such as in the onDraw( ) method 

http://www.coderanch.com/t/435390/Android/Mobile/screen-size-at-run-time
要等开始布局时才能得到宽和高等特性?这么说的话使用
Java代码 
pix_lng = mapView.getProjection().fromPixels(0, 0) 
                    .getLongitudeE6() / 1E6; 

也是没意义的了。。。
这样的话只能等mapView渲染完毕才能处理了.
本来想使用mapView的draw方法来处理,但是无从下手(继承mapView类来重写draw方法?),只好写了个线程,监听mapView是否完成(完成的话height和width都不会等0了),然后把刚才那段代码放到线程里,成功了。。。
新线程代码:

Java代码 
public void run() { 
        while (mapView.getHeight() == 0) { 
            System.out.println("mapView等于0,mapView还没渲染完毕"); 
            try { 
                Thread.currentThread().sleep(100); 
            } 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纬度 
 
            // System.out.println("缩放前中心点: "+mapView.getMapCenter()); 
            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; 
 
            } 
            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()); 
        } 
    } 

刚才那段代码改成:
Java代码 
public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.main); 
        comList = this.getComList();//获取摄像头数据 
        mapView = (MapView) findViewById(R.id.MapView01); 
        mapView.setStreetView(true); 
        mapView.setEnabled(true); 
        mapView.setClickable(true); 
        mapView.setBuiltInZoomControls(true); // 设置地图支持缩放 
         
        System.out.println("长和宽:"+mapView.getHeight()+","+mapView.getWidth()); 
        mapController = (MapController)mapView.getController(); 
//      locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);// 位置管理器 
 
        // 设置地图中心点 
        Double lat1 = (min_y + max_y) / 2 * 1E6; 
        Double lng1 = (min_x + max_x) / 2 * 1E6; 
        System.out.println("中心点:"+lat1+","+lng1); 
        GeoPoint geoPoint = new GeoPoint(lat1.intValue(), lng1.intValue()); 
        mapController.setCenter(geoPoint); 
        mapController.setZoom(16); 
         
        ... 
 
        Drawable defaultMarker = getResources().getDrawable(R.drawable.arrow); 
        Drawable activeMarker = getResources().getDrawable(R.drawable.icon); 
        defaultMarker.setBounds(0, 0, defaultMarker.getMinimumWidth(), 
                defaultMarker.getMinimumHeight()); 
        PositionsOverlay posOverlay = new PositionsOverlay(defaultMarker, 
                comList, activeMarker,this); 
        List<Overlay> overlays = getMapView().getOverlays(); 
        overlays.add(posOverlay); 
         
         
        //启动新的线程来监视mapView是否渲染完毕,渲染完毕则开始调整mapView的缩放水平以适合全部数据 
        SelfAdaptionMapView cv = new SelfAdaptionMapView(mapView,max_x,min_y,min_x,max_y); 
        new Thread(cv).start(); 

    发表评论
    请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
    用户名: 验证码:点击我更换图片
    最新评论 更多>>

    推荐热点

    • Android 完全退出程序
    • 原创:Android应用开发-Andorid歌词秀,含源码
    • android 屏幕保护
    • Android手机软件汉化教程---第四课 dex文件汉化
    • 众多Android 开源项目推荐,给力工作给力学习
    • Android Audio代码分析4
    • Android得到已安装的应用程序信息!
    • Android开发者指南(29) —— USB Host and Accessory
    • Android成长的幕后推手:工程师鲁宾
    网站首页 - 友情链接 - 网站地图 - TAG标签 - RSS订阅 - 内容搜索
    Copyright © 2008-2015 计算机技术学习交流网. 版权所有

    豫ICP备11007008号-1