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

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

首先加入依赖如下:

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

然后,在xml里加入组件:

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

最后,在activity中开始加载map

 		mapView?.maxZoomLevel = 23.0mapView?.minZoomLevel = 0.0mapView?.controller?.setZoom(12.0)//让瓦片适应不同像素密度:默认地图显示的字体小,图片像素高,可设置以下代码,使地图适应不同像素密度,更美观mapView?.isTilesScaledToDpi = true//设置缩放按钮可见val zoomController = mapView?.getZoomController()zoomController?.setVisibility(CustomZoomButtonsController.Visibility.NEVER)mapView?.setMultiTouchControls(true) // 触控放大缩小mapView?.overlayManager?.tilesOverlay?.isEnabled = truemapView?.isSelected = truevar 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}) {@Overridepublic 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 = strval 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的地图功能都实现了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/69595.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android——线程和线程池

线程和线程池 AsyncTaskIntentService线程池ThreadPoolExecutorFixedThreadPoolCachedThreadPoolScheduledExecutorSingleThreadExecutor AsyncTask 使用案例可看Android基础——异步消息处理&#xff0c;需要注意 AsyncTask必须在主线程中加载&#xff0c;在ActivityThread的…

装饰器模式简介

概念&#xff1a; 装饰器模式&#xff08;Decorator Pattern&#xff09;是一种结构型设计模式&#xff0c;允许您在不改变现有对象结构的情况下&#xff0c;动态地将新功能附加到对象上。通过创建一个包装器类来扩展原始类的功能。这个包装器类具有与原始类相同的接口&#x…

对称二叉树(Leetcode 101)

题目 101. 对称二叉树 思路 使用层序遍历&#xff0c;遍历当前层的节点时&#xff0c;如该节点的左&#xff08;右&#xff09;孩子为空&#xff0c;在list中添加null&#xff0c;否则加入左&#xff08;右&#xff09;孩子的值。每遍历完一层则对当前list进行判断&#xff0c…

从零学算法(剑指 Offer 61)

从若干副扑克牌中随机抽 5 张牌&#xff0c;判断是不是一个顺子&#xff0c;即这5张牌是不是连续的。2&#xff5e;10为数字本身&#xff0c;A为1&#xff0c;J为11&#xff0c;Q为12&#xff0c;K为13&#xff0c;而大、小王为 0 &#xff0c;可以看成任意数字。A 不能视为 14…

如何做一个api商品数据接口?

在构建一个API商品数据接口的过程中&#xff0c;我们需要涉及前端开发、后端开发、数据库设计以及API设计等多个方面。以下是一个基本的步骤和代码示例&#xff1a; 第一步&#xff1a;数据库设计 首先&#xff0c;我们需要设计一个数据库来存储商品信息。在这个例子中&#…

Git常用命令用法

参考视频&#xff1a;真的是全能保姆 git、github 保姆级教程入门&#xff0c;工作和协作必备技术&#xff0c;github提交pr - pull request_哔哩哔哩_bilibili 1.Git初始化 首先设置名称和邮箱。然后初始化一下&#xff0c;然后就创建了一个空的Git仓库。 PS D:\golang\oth…

区块链面临六大安全问题 安全测试方案研究迫在眉睫

区块链面临六大安全问题 安全测试方案研究迫在眉睫 近年来&#xff0c;区块链技术逐渐成为热门话题&#xff0c;其应用前景受到各国政府、科研机构和企业公司的高度重视与广泛关注。随着技术的发展&#xff0c;区块链应用与项目层出不穷&#xff0c;但其安全问题不容忽视。近年…

node socket.io

装包&#xff1a; yarn add socket.io node后台&#xff1a; const express require(express) const http require(http) const socket require(socket.io) const { getUserInfoByToken } require(../../utils/light/tools)let app express() const server http.createS…

【C++漂流记】结构体的定义和使用、结构体数组、结构体指针、结构体做函数参数以及结构体中const的使用

结构体&#xff08;struct&#xff09;是C语言中一种重要的数据类型&#xff0c;它由一组不同类型的成员组成。结构体可以用来表示一个复杂的数据结构&#xff0c;比如一个学生的信息、一个员工记录或者一个矩形的尺寸等。 结构体定义后&#xff0c;可以声明结构体变量&#xf…

NCCoE发布“向后量子密码学迁移”项目进展情况说明书

近日&#xff0c;NIST下属的国家网络安全中心&#xff08;NCCoE&#xff09;发布了一份向后量子密码学迁移&#xff08;Migration to Post-Quantum Cryptography&#xff09;项目情况说明书。该文档简要概述了向后量子密码学迁移项目的背景、目标、挑战、好处和工作流程&#x…

【HTML5高级第二篇】WebWorker多线程、EventSource事件推送、History历史操作

文章目录 一、多线程1.1 概述1.2 体会多线程1.3 多线程中数据传递和接收 二、事件推送2.1 概述2.2 onmessage 事件 三、history 一、多线程 1.1 概述 前端JS默认按照单线程去执行&#xff0c;一段时间内只能执行一件事情。举个栗子&#xff1a;比方说古代攻城游戏&#xff0c…

基于LinuxC语言实现的TCP多线程/进程服务器

多进程并发服务器 设计流程 框架一&#xff08;使用信号回收僵尸进程&#xff09; void handler(int sig) {while(waitpid(-1, NULL, WNOHANG) > 0); }int main() {//回收僵尸进程siganl(17, handler);//创建服务器监听套接字 serverserver socket();//给服务器地址信息…

Jenkins自动构建(Gitee)

Gitee简介安装JenkinsCLI https://blog.csdn.net/tongxin_tongmeng/article/details/132632743 安装Gitee jenkins-cli install-plugin gitee:1.2.7 # https://plugins.jenkins.io/gitee/releases获取安装命令(稍作变更) JenkinsURL Dashboard-->配置-->Jenkins Locatio…

ARTS第五周:A - 最大公约数

数字 function gcd(int $x, int $y): int {while($y^$x^$y^$x%$y);return $x; }位运算&#xff1a;异或&#xff1a;gcd(a,b) gcd(b,a mod b) 字符串 <?phpclass Solution {/*** param String $str1* param String $str2* return String*/function gcdOfStrings($str1, …

MySQL 8.0 OCP (1Z0-908) 考点精析-安装与配置考点1:设置系统变量

文章目录 MySQL 8.0 OCP (1Z0-908) 考点精析-安装与配置考点1&#xff1a;设置系统变量系统变量的确认设置系统变量的方法SET命令设置系统变量SET命令语法动态系统变量&#xff08;Dynamic System Variables&#xff09;全局级别变量的设置方法会话级别变量的设置方法系统变量的…

鸿蒙系列-如何使用好 ArkUI 的 @Reusable?

如何使用好 ArkUI 的 Reusable&#xff1f; OpenHarmony 组件复用机制 在ArkUI中&#xff0c;UI显示的内容均为组件&#xff0c;由框架直接提供的称为 系统组件&#xff0c;由开发者定义的称为 自定义组件。 在进行 UI 界面开发时&#xff0c;通常不是简单的将系统组件进行组合…

SpringBoot的测试方案

写完代码后&#xff0c;测试是必不可少的步骤&#xff0c;现在来介绍一下基于SpringBoot的测试方法。 基于SpringBoot框架写完相应功能的Controller之后&#xff0c;然后就可以测试功能是否正常&#xff0c;本博客列举MockMvc和RestTemplate两种方式来测试。 准备代码 实体类…

NIO原理浅析(三)

epoll 首先认识一下epoll的几个基础函数 int s socket(AF_INET, SOCK_STREAM, 0); bind(s, ...); listen(s, ...);int epfd epoll_create(...) epoll_ctl(epfd, ...); //将所有需要监听的socket添加到epfd中while(1) {int n epoll_wait(...);for(接受到数据的socket) {//处…

Kotlin 环境下解决属性初始化问题

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

react使用hook封装一个tab组件

目录 react使用hook封装一个tab组件Tabbar.jsx使用组件效果 react使用hook封装一个tab组件 Tabbar.jsx import PropsTypes from "prop-types"; import React, { useEffect, useState } from react; export default function Tabbar(props) {const { tabData , cur…