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

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

首先附上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/

如果有问题可进行留言,看到后会尽快进行答复。

发布了87 篇原创文章 · 获赞 248 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/haojiagou/article/details/102684098
今日推荐