osmdroid地图

来源:互联网 发布:开淘宝店铺小技巧 编辑:程序博客网 时间:2024/05/14 19:06

1.简介

osmdroid是一个开源的地图填充器,全称是 open street map ,至于droid我个人认为应该是安卓版的后缀吧。

在网络上找了很多资料,大多是加载在线地图的,加载离线地图的很少,所以把代码记录一下。

2.初始化

1.在布局中添加地图控件

<org.osmdroid.views.MapView    android:id="@+id/map_view"    android:layout_width="match_parent"    android:layout_height="match_parent"/>

2.初始化地图

        MapView map_view = (MapView) findViewById(R.id.map_view);        //设置地图是可点击的        map_view.setClickable(true);        //显示地图下方的缩放按钮        map_view.setBuiltInZoomControls(true);        mMapController = map_view.getController();        //设置初始化缩放级别        mMapController.setZoom(8);        //设置当前最大缩放级别        map_view.setMaxZoomLevel(8);        //添加比例尺        ScaleBarOverlay scaleBar = new ScaleBarOverlay(context);        map_view.getOverlays().add(scaleBar);        //初始化放大缩小控制器        initZoomController();        //设置中心点        mMapController.setCenter(new GeoPoint(34.5063810566, 122.9272579323));    /**     * 初始化放大缩小的处理 -- 对放大缩小方法进行监听     */    private void initZoomController() {        Field f = null;        try {            f = map_view.getClass().getDeclaredField("mZoomController");//通过反射找到缩放的控制器            f.setAccessible(true);            Log.d(TAG, "zoomControllerClass--" + f.getGenericType().toString());            System.out.println("反射类中所有的方法");            Method[] fm = Class.forName("android.widget.ZoomButtonsController").getMethods();            for (int i = 0; i < fm.length; i++) {                if (fm[i].getName().equals("setOnZoomListener")) {                    fm[i].setAccessible(true);                    fm[i].invoke((ZoomButtonsController) f.get(map_view), new ZoomButtonsController.OnZoomListener() {                        @Override                        public void onVisibilityChanged(boolean b) {                        }                        @Override                        public void onZoom(boolean b) {                            if (b) {                                map_view.getController().zoomIn();                            } else {                                map_view.getController().zoomOut();                            }                            zoom();//自己要处理的方法                        }                    });                }                System.out.println("fm:" + fm[i].getName() + "____"                        + fm[i].getReturnType().getName());            }        } catch (NoSuchFieldException e) {            e.printStackTrace();        } catch (InvocationTargetException e) {            e.printStackTrace();        } catch (IllegalAccessException e) {            e.printStackTrace();        } catch (ClassNotFoundException e) {            e.printStackTrace();        }    }

3.对地图进行操作

1 加载离线地图

    /**     * 离线地图文件--离线地图在内存卡中的位置,如果随机可以遍历文件,不过时间可能会稍微慢一些     */    public static File OSMDROID_PATH = new File("/storage/sdcard1/osmdroid");    /**     * 查找离线地图--在有网络的情况下会加载谷歌地图     */    private void findOfflineMap() {        ThreadPoolManager.getInstance().execute(new Runnable() {            @Override            public void run() {                //指定地图加载提供器                registerReceiver = new SimpleRegisterReceiver(context);                final TileWriter tileWriter = new TileWriter();                fileSystemProvider = new MapTileFilesystemProvider(registerReceiver, null);                // Create an archive file modular tile provider                fileArchiveProvider = new MapTileFileArchiveProvider(registerReceiver, null, findArchiveFiles());                // Create a download modular tile provider                final NetworkAvailabliltyCheck networkAvailabliltyCheck = new NetworkAvailabliltyCheck(context);                final MapTileDownloader downloaderProvider = new MapTileDownloader(null, tileWriter, networkAvailabliltyCheck);                DisplayMetrics dm = getResources().getDisplayMetrics();                //google卫星图                float mDensity = dm.density;                if (mDensity > 1.5)                    mDensity = 1.5f;                String url1 = "http://mt1.google.cn/vt/lyrs=y&hl=zh-CN&gl=cn&scale=" + mDensity;                String url2 = "http://mt2.google.cn/vt/lyrs=y&hl=zh-CN&gl=cn&scale=" + mDensity;                String url3 = "http://mt3.google.cn/vt/lyrs=y&hl=zh-CN&gl=cn&scale=" + mDensity;//含路网                ms_googleSatellite = new GoogleMapsTileSource("GoogleMap", null, 1, 19, (int) (256 * dm.density), ".jpg",new String[]{url1, url2, url3});                // Create a custom tile provider array with the custom tile source and  the custom tile providers                tileProviderArray = new MapTileProviderArray(ms_googleSatellite, registerReceiver,                        new MapTileModuleProviderBase[]{fileSystemProvider, fileArchiveProvider, downloaderProvider});                map_view.getTileProvider().clearTileCache();//      Log.d("tag", "清理tile缓存........");                map_view.setTileProvider(tileProviderArray);                map_view.setTileSource(ms_googleSatellite);                map_view.setTilesScaledToDpi(false);//重要            }        });    }

GoogleMapsTileSource.java

    public class GoogleMapsTileSource extends OnlineTileSourceBase/* implements IStyledTileSource<Integer> */{        public GoogleMapsTileSource(String aName, string aResourceId,                             int aZoomMinLevel, int aZoomMaxLevel, int aTileSizePixels,                             String aImageFilenameEnding, String[] aBaseUrl) {          super(aName, aZoomMinLevel, aZoomMaxLevel, aTileSizePixels,                aImageFilenameEnding, aBaseUrl);        }       @Override       public String getTileURLString(MapTile aTile) {          return getBaseUrl() + "&x=" + aTile.getX() + "&y=" + aTile.getY() + "&z=" + aTile.getZoomLevel();        }    } 

2 向地图中添加图片

    /**     * 添加图片     * @param point     * @return     */    private Overlay addImg(ArrowPoint point) {        ArrayList<OverlayItem> items = new ArrayList<OverlayItem>();        Drawable drawable = this.getResources().getDrawable(                point.imgResource);        OverlayItem item = new OverlayItem("", "", point.geoPoint);        item.setMarker(drawable);        items.add(item);        CustomMarker marker = new CustomMarker(items,                new ItemizedIconOverlay.OnItemGestureListener<OverlayItem>() {                    @Override                    public boolean onItemSingleTapUp(final int index,                                                     final OverlayItem item) {                        return true;                    }                    @Override                    public boolean onItemLongPress(final int index,                                                   final OverlayItem item) {                        return false;                    }                }, map_view.getResourceProxy());        map_view.getOverlays().add(marker);        map_view.invalidate();        return marker;    }

在地图中添加图片

3 在地图中添加实线区域

    /**     * 添加实线区域     */    private Overlay addFullArea(List<GeoPoint> pointList, int color) {        PathOverlay myPath = new PathOverlay(color, this);        Paint paint = new Paint();        paint.reset();        paint.setStyle(Paint.Style.STROKE);        paint.setStrokeWidth(3);        paint.setColor(color);//        paint.setAntiAlias(true);        paint.setPathEffect(null);        myPath.setPaint(paint);        for (GeoPoint geoPoint : pointList) {            myPath.addPoint(geoPoint);        }        map_view.getOverlays().add(myPath);        map_view.invalidate();        return myPath;    }

4 在地图中添加虚线区域

    /**     * 添加虚线区域     */    private Overlay addDottedArea(List<GeoPoint> pointList) {        PathOverlay myPath = new PathOverlay(Color.RED, this);        PathEffect effect = null;        //虚线        effect = getDottedLine(30, 30);        Paint paint = new Paint();        paint.reset();        paint.setStyle(Paint.Style.STROKE);        paint.setStrokeWidth(3);        paint.setColor(Color.RED);//        paint.setAntiAlias(true);        paint.setPathEffect(effect);        myPath.setPaint(paint);        for (GeoPoint geoPoint : pointList) {            myPath.addPoint(geoPoint);        }        map_view.getOverlays().add(myPath);        return myPath;    }     /**     * 获取虚线     * @param lineLength     * @param space     * @return     */    private PathEffect getDottedLine(int lineLength, int space) {        //虚线        DashPathEffect pee = new DashPathEffect(new float[]{lineLength, space}, 0);        return pee;    }

在地图中添加虚线区域

5 在地图中添加T型区域

在地图中添加T型区域

 /**     * 添加T型虚线区域     * 点从右向左添加时T型向内     */    private Overlay addTShapeArea(List<GeoPoint> pointList) {        PathOverlay myPath = new PathOverlay(Color.RED, this);        PathEffect effect = null;        //T型虚线        effect = getTShape(15, 20);        Paint paint = new Paint();        paint.reset();        paint.setStyle(Paint.Style.STROKE);        paint.setStrokeWidth(3);        paint.setColor(Color.RED);//        paint.setAntiAlias(true);        paint.setPathEffect(effect);        myPath.setPaint(paint);        for (GeoPoint geoPoint : pointList) {            myPath.addPoint(geoPoint);        }        map_view.getOverlays().add(myPath);        return myPath;    }    /**     * 获取T型虚线     * @param lineLength     * @param space     * @return     */    private PathEffect getTShape(int lineLength, int space) {        //T型虚线        TShaped(lineLength);        PathDashPathEffect pe = new PathDashPathEffect(tShaped, space, 0, PathDashPathEffect.Style.MORPH);        return pe;    }     /**     * 画T型虚线中的一个T     * @param length T的长度     */    private void TShaped(float length) {        tShaped = new Path();        float dis1 = (float) ((length / 2) / Math.tan((54f / 180) * Math.PI));        tShaped.moveTo(length / 2 - length / 10, 0);        tShaped.lineTo(length / 2 + length / 10, 0);        tShaped.lineTo(length / 2 + length / 10, dis1);        tShaped.lineTo(length, dis1);        tShaped.lineTo(length, dis1 + length / 5);        tShaped.lineTo(0, dis1 + length / 5);        tShaped.lineTo(0, dis1);        tShaped.lineTo(length / 2 - length / 10, dis1);        tShaped.lineTo(length / 2 - length / 10, 0);    }

T的大小都是自定义的,在最后一个方法中,当前是将大小定死了,如果需要,可以在此基础上修改。

6 箭头的画法

再附加一个根据经纬度值和角度,画箭头的方法

private List<Overlay> tidalChartLineList; private List<GeoPoint> tidalChartPointList;    /**     * 箭头     * @param geoPoint 中心点     * @param degree 角度     * @param length 长度     */    private void addArrows(GeoPoint geoPoint,double degree,double length) {        try {            double lineX = length * Math.sin(degree * Math.PI / 180);            double lineY = length * Math.cos(degree * Math.PI / 180);            GeoPoint latlng2 = new GeoPoint(geoPoint.getLatitude() + lineY, geoPoint.getLongitude() + lineX);            double tempLine = length * 3 / 4 * Math.cos(15 * Math.PI / 180);            GeoPoint latlng3 = new GeoPoint(geoPoint.getLatitude() + (tempLine * Math.sin((90 - degree + 15) * Math.PI / 180)),                    geoPoint.getLongitude() + (tempLine * Math.cos((90 - degree + 15) * Math.PI / 180)));            GeoPoint latlng4 = new GeoPoint(geoPoint.getLatitude() + (tempLine * Math.sin((90 - degree - 15) * Math.PI / 180)),                    geoPoint.getLongitude() + (tempLine * Math.cos((90 - degree - 15) * Math.PI / 180)));            List<GeoPoint> latLngPolygon = new ArrayList<GeoPoint>();            latLngPolygon.add(geoPoint);            latLngPolygon.add(latlng2);            latLngPolygon.add(latlng3);            latLngPolygon.add(latlng2);            latLngPolygon.add(latlng4);            tidalChartPointList.add(geoPoint);            tidalChartLineList.add(addFullArea(latLngPolygon, 0xFFFF0000));        } catch (Exception e) {            e.printStackTrace();        }    }
2 0