安卓使用osmdroid显示谷歌地图、高德地图及离线地图详解

简介: 安卓使用osmdroid显示谷歌地图、高德地图及离线地图详解

最近公司有这个需求,需要能切换不同的地图,并且数据需要互通,如果引入每一个地图的SDK(例如百度地图SDK、高德地图SDK、谷歌地图等)的话apk包就太大了,而且操作数据及操作地图就会变得特别麻烦,所以找到了完全免费及开源的osmdroid。下面先看一下显示效果:

20191022155156349.gif


首先附上osmdroid的Github地址:https://github.com/osmdroid/osmdroid


第一步在app.gradle中添加上依赖:

implementation 'org.osmdroid:osmdroid-android:6.1.0'

第二步在布局中加载MapView:

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

第三步在活动中对MapView进行初始化,再进行一些属性的配置,比如指南针的显示、比例尺的显示、小地图显示等等:


mMapView.setTileSource(Objects.requireNonNull(GoogleTileSource.getOnlineTileSourceBaseByName(mapSource)));
IMapController mapController = mMapView.getController();
        mapController.setZoom(18.0);
        GeoPoint startPoint = new GeoPoint(39.0853958, 117.0994426);
        mapController.setCenter(startPoint);
        this.mLocationOverlay = new MyLocationNewOverlay(new GpsMyLocationProvider(this), mMapView);
        this.mLocationOverlay.enableMyLocation();
        //mMapView.getOverlays().add(this.mLocationOverlay);
        this.mCompassOverlay = new CompassOverlay(this, new InternalCompassOrientationProvider(this), mMapView);
        this.mCompassOverlay.enableCompass();
        mMapView.getOverlays().add(this.mCompassOverlay);
        //缩放按钮
        mMapView.setBuiltInZoomControls(false);
        mMapView.setMultiTouchControls(true);
        //最大缩放比例
        mMapView.setMaxZoomLevel(20.0);
上面代码中的mMapView为MapView,GooleTileSource为自定义的一个类,继承自TileSourceFactory,里面构造了谷歌地图以及高德地图的地图源,所以,mapView的setTileSource方法就是用来切换地图源的。下面放上GooleTileSource类的代码,可直接进行使用:
/**
 * 谷歌、高德等瓦片地图
 *
 * @author jiang zhu on 2019/10/18
 */
public class GoogleTileSource extends TileSourceFactory {
    //谷歌卫星混合
    public static final OnlineTileSourceBase GoogleHybrid = new XYTileSource("Google-Hybrid",
            0, 19, 512, ".png", new String[]{
            "http://mt0.google.cn",
            "http://mt1.google.cn",
            "http://mt2.google.cn",
            "http://mt3.google.cn",
    }) {
        @Override
        public String getTileURLString(long pMapTileIndex) {
            Log.d("url", getBaseUrl() + "/vt/lyrs=y&scale=2&hl=zh-CN&gl=CN&src=app&x=" + MapTileIndex.getX(pMapTileIndex) + "&y=" + MapTileIndex.getY(pMapTileIndex) + "&z=" + MapTileIndex.getZoom(pMapTileIndex));
            return getBaseUrl() + "/vt/lyrs=y&scale=2&hl=zh-CN&gl=CN&src=app&x=" + MapTileIndex.getX(pMapTileIndex) + "&y=" + MapTileIndex.getY(pMapTileIndex) + "&z=" + MapTileIndex.getZoom(pMapTileIndex);
        }
    };
    //谷歌卫星
    public static final OnlineTileSourceBase GoogleSat = new XYTileSource("Google-Sat",
            0, 19, 512, ".png", new String[]{
            "http://mt0.google.cn",
            "http://mt1.google.cn",
            "http://mt2.google.cn",
            "http://mt3.google.cn",
    }) {
        @Override
        public String getTileURLString(long pMapTileIndex) {
            return getBaseUrl() + "/vt/lyrs=s&scale=2&hl=zh-CN&gl=CN&src=app&x=" + MapTileIndex.getX(pMapTileIndex) + "&y=" + MapTileIndex.getY(pMapTileIndex) + "&z=" + MapTileIndex.getZoom(pMapTileIndex);
        }
    };
    //谷歌地图
    public static final OnlineTileSourceBase GoogleRoads = new XYTileSource("Google-Roads",
            0, 18, 512, ".png", new String[]{
            "http://mt0.google.cn",
            "http://mt1.google.cn",
            "http://mt2.google.cn",
            "http://mt3.google.cn",
    }) {
        @Override
        public String getTileURLString(long pMapTileIndex) {
            return getBaseUrl() + "/vt/lyrs=m&scale=2&hl=zh-CN&gl=CN&src=app&x=" + MapTileIndex.getX(pMapTileIndex) + "&y=" + MapTileIndex.getY(pMapTileIndex) + "&z=" + MapTileIndex.getZoom(pMapTileIndex);
        }
    };
    //谷歌地形
    public static final OnlineTileSourceBase GoogleTerrain = new XYTileSource("Google-Terrain",
            0, 16, 512, ".png", new String[]{
            "http://mt0.google.cn",
            "http://mt1.google.cn",
            "http://mt2.google.cn",
            "http://mt3.google.cn",
    }) {
        @Override
        public String getTileURLString(long pMapTileIndex) {
            return getBaseUrl() + "/vt/lyrs=t&scale=2&hl=zh-CN&gl=CN&src=app&x=" + MapTileIndex.getX(pMapTileIndex) + "&y=" + MapTileIndex.getY(pMapTileIndex) + "&z=" + MapTileIndex.getZoom(pMapTileIndex);
        }
    };
    //谷歌地形带标注
    public static final OnlineTileSourceBase GoogleTerrainHybrid = new XYTileSource("Google-Terrain-Hybrid",
            0, 16, 512, ".png", new String[]{
            "http://mt0.google.cn",
            "http://mt1.google.cn",
            "http://mt2.google.cn",
            "http://mt3.google.cn",
    }) {
        @Override
        public String getTileURLString(long pMapTileIndex) {
            return getBaseUrl() + "/vt/lyrs=p&scale=2&hl=zh-CN&gl=CN&src=app&x=" + MapTileIndex.getX(pMapTileIndex) + "&y=" + MapTileIndex.getY(pMapTileIndex) + "&z=" + MapTileIndex.getZoom(pMapTileIndex);
        }
    };
    //高德地图
    public static final OnlineTileSourceBase AutoNaviVector = new XYTileSource("AutoNavi-Vector",
            0, 20, 256, ".png", new String[]{
            "https://wprd01.is.autonavi.com/appmaptile?",
            "https://wprd02.is.autonavi.com/appmaptile?",
            "https://wprd03.is.autonavi.com/appmaptile?",
            "https://wprd04.is.autonavi.com/appmaptile?",
    }) {
        @Override
        public String getTileURLString(long pMapTileIndex) {
            return getBaseUrl() + "x=" + MapTileIndex.getX(pMapTileIndex) + "&y=" + MapTileIndex.getY(pMapTileIndex) + "&z="
                    + MapTileIndex.getZoom(pMapTileIndex) + "&lang=zh_cn&size=1&scl=1&style=7&ltype=7";
        }
    };
}

第四步来实现下离线地图的加载,写一个方法来判断当前是否有网络,若果有直接加载在线地图,否则加载离线地图:

/**
     * 设置地图源
     */
    private void setMapSources() {
        if (NetworkUtils.isConnected()) {
      mMapView.setTileSource(Objects.requireNonNull(GoogleTileSource.getOnlineTileSourceBaseByName(mapSource)));
            }
        } else {
            ToastUtils.showShort("当前无网络,请选择离线地图包");
            if (mMapView.getOverlays().size() <= 0) {
                mapViewOffline();
            }
        }
    }
其中的mapViewOffline方法为加载离线地图的方法,代码如下:
/**
     * 加载离线地图
     */
    public void mapViewOffline() {
        String strFilepath = Environment.getExternalStorageDirectory().getPath() + "/osmdroid/jiang.sqlite";
        File exitFile = new File(strFilepath);
        String fileName = exitFile.getName();
        if (!exitFile.exists()) {
            mMapView.setTileSource(TileSourceFactory.MAPNIK);
        } else {
            fileName = fileName.substring(fileName.lastIndexOf(".") + 1);
            if (ArchiveFileFactory.isFileExtensionRegistered(fileName)) {
                try {
                    OfflineTileProvider tileProvider = new OfflineTileProvider(new SimpleRegisterReceiver(this), new File[]{exitFile});
                    mMapView.setTileProvider(tileProvider);
                    String source = "";
                    IArchiveFile[] archives = tileProvider.getArchives();
                    if (archives.length > 0) {
                        Set<String> tileSources = archives[0].getTileSources();
                        if (!tileSources.isEmpty()) {
                            source = tileSources.iterator().next();
                            mMapView.setTileSource(FileBasedTileSource.getSource(source));
                        } else {
                            mMapView.setTileSource(TileSourceFactory.DEFAULT_TILE_SOURCE);
                        }
                    } else
                        mMapView.setTileSource(TileSourceFactory.DEFAULT_TILE_SOURCE);
                    Toast.makeText(this, "Using " + exitFile.getAbsolutePath() + " " + source, Toast.LENGTH_LONG).show();
                    mMapView.invalidate();
                    return;
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
                Toast.makeText(this, " did not have any files I can open! Try using MOBAC", Toast.LENGTH_LONG).show();
            } else {
                Toast.makeText(this, " dir not found!", Toast.LENGTH_LONG).show();
            }
        }
    }


其中的jiang.sqllite为离线地图资源包,大家可以在官方提供的网站自行下载:https://github.com/osmdroid/osmdroid/blob/master/OSMMapTilePackager/readme.md

先写这么多吧,里面的marker和PolyLine的添加和加载官方文档中都有详细描述:http://osmdroid.github.io/osmdroid/



目录
相关文章
|
4月前
|
API 定位技术 开发工具
Android Studio2021.1.1 高德地图api调用这一篇就够了
Android Studio2021.1.1 高德地图api调用这一篇就够了
|
XML 前端开发 Java
Android MVVM框架搭建(八)高德地图定位、天气查询、BottomSheetDialog
Android MVVM框架搭建(八)高德地图定位、天气查询、BottomSheetDialog
460 0
Android MVVM框架搭建(八)高德地图定位、天气查询、BottomSheetDialog
|
定位技术 开发工具 Android开发
Android 地图导航调用百度地图、高德地图、腾讯地图
Android 地图导航调用百度地图、高德地图、腾讯地图
1158 0
Android 地图导航调用百度地图、高德地图、腾讯地图
|
定位技术 开发工具 Android开发
Android笔记:高德地图-点击获得目的经纬度,根据经纬度获取地址(逆地理编码)
Android笔记:高德地图-点击获得目的经纬度,根据经纬度获取地址(逆地理编码)
501 0
|
定位技术 API
Android----高德地图多个Marker加载网络图片出现图片不显示问题
Android----高德地图多个Marker加载网络图片出现图片不显示问题
451 0
|
定位技术 开发工具 Android开发
Android高德地图SDK设置缩放控件的位置
Android高德地图SDK设置缩放控件的位置
245 0
|
定位技术 Android开发
Android 高德地图获取屏幕中心的经纬度坐标
Android 高德地图获取屏幕中心的经纬度坐标
411 0
|
Java 定位技术 开发工具
Android开发之高德地图实现定位
在应用开发中,地图开发是经常需要使用的“组件”,Google Map虽然有官方教程,无奈用不起来,原因你懂的~~那么国内比较出名的是就是百度地图和高德地图,由于个人喜好,所以选择了高德地图LBS,废话不说,上干货。
2194 1
|
Shell 定位技术 开发工具
Android 接入高德地图SDK模块的优化点点滴滴
起因: 由于在最近接手了一个关于导航的App,发现地图页面跳来跳去实在是卡顿地不行(运行在车载设备上的APP,机器性能实在是有限)。
2166 0
|
定位技术 Android开发 Java
Android 高德地图不显示问题
      很久没有接触高德地图了,今天小菜接到新需求要用到高德地图,具体的方式链到官网上。高德地图官方集成方式,很简单,步骤很清晰。但是,但是,但是,小菜集成之后进入地图显示黑屏,有放大缩小按钮,有高德地图的Logo,就是不显示地图。
2531 0