Android使用osmdroid加载在线地图,离线地图以及各种填坑姿势

最近开发需要加载地图,包括离线瓦片和在线地图,因为百度和高德要掏钱并且不支持加载自己的瓦片,想着有没有开源的替代呢?发现了osmdroid这个开源库可以加载地图,但是关于开发资料中文少的可怜,有关博客都是互相抄,找不到有用的信息,于是我狠下心看了遍源码,然后开始了填坑之旅。

首先加入依赖如下:

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

然后,在xml里加入组件:

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

最后,在activity中开始加载map

 		mapView?.maxZoomLevel = 23.0
        mapView?.minZoomLevel = 0.0
        mapView?.controller?.setZoom(12.0)
        //让瓦片适应不同像素密度:默认地图显示的字体小,图片像素高,可设置以下代码,使地图适应不同像素密度,更美观
        mapView?.isTilesScaledToDpi = true
        //设置缩放按钮可见
        val zoomController = mapView?.getZoomController()
        zoomController?.setVisibility(CustomZoomButtonsController.Visibility.NEVER)
        mapView?.setMultiTouchControls(true) // 触控放大缩小
        mapView?.overlayManager?.tilesOverlay?.isEnabled = true
        mapView?.isSelected = true
        var dm = resources.displayMetrics
        //指南针
        var mCompassOverlay = CompassOverlay(
            this, InternalCompassOrientationProvider(this),
            mapView
        )
        mCompassOverlay.enableCompass()
        mapView?.getOverlays()?.add(mCompassOverlay)
        //比例尺配置
        var mScaleBarOverlay = ScaleBarOverlay(mapView)
        mScaleBarOverlay.setScaleBarOffset(dm.widthPixels / 2, 10)
        mapView?.getOverlays()?.add(mScaleBarOverlay)
        mapView?.overlays?.add(mScaleBarOverlay)
        //定位
        var mLocationOverlay = MyLocationNewOverlay(GpsMyLocationProvider(this), mapView)
        mapView?.overlays?.add(mLocationOverlay)
        mLocationOverlay.enableMyLocation()
        //地图移动到该点
        var startPoint = GeoPoint(GeoPoint(34.360284, 108.859602))
        mapView?.controller?.setCenter(startPoint)

        mapView?.setUseDataConnection(true)
        mapView?.setTileSource(tianDiTuCiaTileSource)

其中,tianDiTuCiaTileSource是地图的在线资源,我用的是天地图,也可以换成别的,只要url配置正确就可以。如下:

 static  String  wz = "tianditu.gov.cn/img_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&tk=自己申请的token";
 	//影像地图 _W是墨卡托投影  _c是国家2000的坐标系
    public static OnlineTileSourceBase tianDiTuImgTileSource = new XYTileSource("Tian Di Tu Img", 1, 18, 256, "",
            new String[]{
    
    "https://t0." + wz,
                    "https://t1." + wz,
                    "https://t2." + wz,
                    "https://t3." + wz,
                    "https://t4." + wz,
                    "https://t5." + wz,
                    "https://t6." + wz,
                    "https://t7." + wz
            }) {
    
    
        @Override
        public String getTileURLString(final long pMapTileIndex) {
    
    
            Log.d("url", getBaseUrl() + "&TILEROW=" + MapTileIndex.getY(pMapTileIndex) + "&TILECOL=" + MapTileIndex.getX(pMapTileIndex)
                    + "&TILEMATRIX=" + MapTileIndex.getZoom(pMapTileIndex));
            return getBaseUrl() + "&TILEROW=" + MapTileIndex.getY(pMapTileIndex) + "&TILECOL=" + MapTileIndex.getX(pMapTileIndex)
                    + "&TILEMATRIX=" + MapTileIndex.getZoom(pMapTileIndex);
        }
    };

把上面地址中的token换成自己申请的,就可以了

至此,在线地图就加载出来了。

接下来,我们来加载离线瓦片。

离线瓦片的格式有很多种,osm也支持好多,这里我用的是.zip瓦片文件,解压开里面是一张一张的图片,然后osm地图会根据你缩放的大小和坐标,找到对应的图片进行显示。废话不多说,代码是最好的老师,代码下:

fun mapViewOtherData(mapView: MapView, str: String) {
    
    
		//str是离线瓦片.zip的路径,Android10以上,如果路径没有权限,下面会报错。所以我的做法是,先把zip复制到自己的包名下的私有目录,然后随便进行操作
        val strFilepath = str
        val exitFile = File(strFilepath)

        if (!exitFile.exists()) {
    
     //文件不存在,用默认网络的

        } else {
    
     //文件存在
            try {
    
    
            	//source 是zip解压后文件夹的名称,我zip文件名字和里面文件夹一样,所以代码这么写
                val source = exitFile.name.substring(0, exitFile.name.lastIndexOf("."))
                val archives = arrayOfNulls<IArchiveFile>(1)
                archives[0] = ArchiveFileFactory.getArchiveFile(exitFile)
                val customTiles = CustomTileSource(
                    source,
                    12,
                    23,
                    256,
                    ".png",
                )
                val providers = arrayOfNulls<MapTileModuleProviderBase>(1)
                providers[0] = MapTileFileArchiveProvider(
                    SimpleRegisterReceiver(this),
                    customTiles,
                    archives
                )

                val tileProvider = MapTileProviderArray(
                    customTiles,
                    SimpleRegisterReceiver(this), providers
                )
                var tilesOverlay = TilesOverlay(tileProvider, this)
                tilesOverlay.setLoadingBackgroundColor(Color.TRANSPARENT)
                mapView.getOverlayManager()?.add(tilesOverlay)
                return
            } catch (ex: Exception) {
    
    
                ex.printStackTrace()
            }
            Toast.makeText(
                this,
                " did not have any files I can open!",
                Toast.LENGTH_LONG
            ).show()
        }

    }

上面代码CustomTileSource是自定义的一个加载类,如下:

public class CustomTileSource extends BitmapTileSourceBase {
    
    
    public CustomTileSource(String aName, int aZoomMinLevel, int aZoomMaxLevel, int aTileSizePixels, String aImageFilenameEnding) {
    
    
        super(aName, aZoomMinLevel, aZoomMaxLevel, aTileSizePixels, aImageFilenameEnding);
    }
}

至此,osm离线瓦片也加载出来了。

osmdroid加载地图,确实很强大,官方的demo也有,但是demo里面没有加载zip的例子(吐槽一下,添加marker,画点线面的例子都有,就是没有zip),所以费了好大的功夫才把zip给加载出来。所以,记录一下。

到现在,在线地图,离线地图瓦片都加载出来了,osmdroid的地图功能都实现了。

猜你喜欢

转载自blog.csdn.net/gemgaozhen/article/details/132498311
今日推荐