最近公司有这个需求,需要能切换不同的地图,并且数据需要互通,如果引入每一个地图的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.MapViewandroid: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",}) {@Overridepublic 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",}) {@Overridepublic 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",}) {@Overridepublic 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",}) {@Overridepublic 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",}) {@Overridepublic 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?",}) {@Overridepublic 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);}} elsemMapView.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/

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

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

  1. android导航地图下载,悠悠导航离线地图下载-悠悠导航地图 安卓版v5.3.8-PC6安卓网...

    悠悠导航:悠悠导航致力于精准的导航,新更新版本支持留下足迹功能,记下你走过的路,全程陪伴你的生活.增加了地图指南针,让你即使在野外也不会迷失方向.是一个很不错的导航软件 功能介绍 悠悠导航,最好的手机 ...

  2. php离线地图,如何发布百度离线地图及二次开发API

    相关教程: 1.说明 离线地图开发环境支持谷歌地图.百度地图.高德地图等等所有常用地图类型,支持在局域网内的地图部署.二次开发. 2.实现 第一步:下载安装离线地图开发环境 下载安装好之后,启动软件, ...

  3. 我的世界服务器积分系统,我的世界PVP地图生命积分板系统原理详解

    我的世界PVP地图生命积分板系统原理详解由小编给大家带来,希望这篇我的世界PVP地图生命积分板系统原理详解,能够帮助到各位正在玩我的世界的玩家朋友们! 我的世界PVP地图生命积分板系统原理详解 大家去 ...

  4. python比例图_python在地图上画比例的实例详解

    现在用python画图已经难不倒一直跟小编学习的小伙伴们了,甚至有的小伙伴画图比小编还要厉害.为此小编还偷偷下了一番功夫,画图这种事情,细节上的完善肯定能让图片更加好看.所以小编知道大家会画地图,但是 ...

  5. 百度离线地图API2.0 百度离线地图api,已经修改源码

    百度离线地图API2.0 百度离线地图api,已经修改源码,绕过服务端验证,除了路书等需要服务端数据支持的功能外,其余功能已经全部实现,包括常用的:地图示例.地图控件添加.覆盖物添加.信息窗口展示等等 ...

  6. 百度地图根据经纬度计算距离php,详解js根据百度地图提供经纬度计算两点距离...

    正常在使用百度地图时,我们可以通过BMap的实例对象提供的方法计算距离: var map = new BMap.Map('map_canvas'); map.getDistance(point1 ,p ...

  7. 我的世界怎么修改服务器刷怪率,《我的世界》地图刷怪率变高方法详解

    <我的世界>地图刷怪率变高方法详解 2014-04-14 17:08:01来源:互联网编辑:评论(0) <我的世界>地图刷怪率变高方法详解​ 首先来看看地图的刷怪原理: 怪物能 ...

  8. Android 高仿百度地图的LBS服务——离线地图篇 Part 2 (v 3.1.1)

    一.前言 转载请标明出处:http://blog.csdn.net/wlwlwlwl015/article/details/41492031 这一篇blog写的真心不容易,我只想说我这种菜鸟去高仿百度 ...

  9. 我的世界java版区块显示_我的世界手游区块显示指令分享:区块玩法操作详解[多图]...

    我的世界手游区块是一个独特的机制,很多玩家对于区块是什么不太了解,区块显示指令以及区块的产生不是很熟悉,为了帮助到大家,今天小编就为大家带来我的世界手游区块显示指令分享:区块玩法操作详解的内容,希望大 ...

最新文章

  1. 构造 ---- 最小没出现过的数(逆向构造) D. Replace by MEX
  2. 注册app短信验证平台_短信验证码平台能免费测试吗?怎么测试?
  3. python运行非常慢的解决-提升Python程序运行效率的6个方法
  4. 公安计算机专业就业前景,公安视听技术专业毕业后干什么
  5. 如何判断一个变量是数组还是对象
  6. vue对象深拷贝_JS 对象的深拷贝和浅拷贝
  7. LSTM背后的数学原理
  8. 安全运维 - Windows系统攻击回溯
  9. 【深度学习基础-02】概念学习-例子3则
  10. ps 计算机 性能设置,电脑运行PS软件太卡?6大设置提高你的PS运行速度
  11. 联机带AI版3D桌球游戏源码
  12. 移动内部疯传的11篇VoLTE学习笔记,看懂了你也是技术大神(二)
  13. centos格式化优盘命令_centos 格式化分区
  14. 鼠标点击事件对象的clientX、pageX、offsetX、screenX、x
  15. 数据库课程设计-员工信息管理系统(基于python和MySQL实现)
  16. Unity3D WebGL部署
  17. python遇到天猫反爬虫_selenium 淘宝登入反爬虫解决方案(亲测有效)
  18. 单片机寻迹小车ppt_基于单片机循迹小车的设计.doc
  19. python爬取pbf格式的矢量瓦片并转换为shp使用
  20. pandas 小技巧——用指定列的“非空值”值去填充另一列的“空值”

热门文章

  1. 通讯录(动态版本)--C语言
  2. 网络工程师:第五阶段通信技术
  3. 服务器配置(测试服务器)
  4. 【解决】手动删除卡巴斯基
  5. 人工智能-机器学习人工神经网络
  6. Vue3中Element-Plus的el-upload清空上传文件(最简单明了)
  7. ABAP校验时间日期格式
  8. 哪里买充电宝便宜?货真价实的充电宝推荐
  9. 路平石模具在公路建设中具体的应用介绍
  10. Unity UGUI Text 首行缩进,空白字符