前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Android Osmdroid + 天地图 (二)

Android Osmdroid + 天地图 (二)

作者头像
晨曦_LLW
发布于 2024-11-28 05:42:37
发布于 2024-11-28 05:42:37
26300
代码可运行
举报
运行总次数:0
代码可运行

前言

  上一篇中我们显示了地图,但是还不够,不满足基本的使用情况,本篇中继续进行功能使用上的完善。

正文

  本文中要实现定位和地图的交互功能,还有一些体验上的功能,首先我们先实现定位功能,意思就是一打开地图就定位到当前所在的位置。

一、定位监听

  Android实际上有自带的定位监听,位置准不准两说,起码是有的,下面我们来使用一下,在MainActivity中增加如下代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    private val TAG = "MainActivity"
    // 是否定位
    private var isLocation = false
    // 定位管理器
    private lateinit var locationManager: LocationManager

一个用于打印、一个用于控制是否定位,locationManager我们就在onCreate()函数中进行实例化,如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
        // 创建位置管理器实例
        locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager

代码位置如下图所示

然后实现一个Android原生的定位监听,代码如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    private val locationListener = LocationListener { location -> // 处理位置变化
        val latitude = location.latitude
        val longitude = location.longitude
        Log.d(TAG, "onLocationChanged: $latitude, $longitude")
    }

然后我们可以写一个开始和停止定位的函数,代码如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    private var isLocation = false
    
    private fun startLocation() {
        if (!isLocation){
	        // 注册位置监听器
            locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0f, locationListener)
            isLocation = !isLocation
        }
    }

    private fun stopLocation() {
        if (isLocation) {
            // 停止位置更新
            locationManager.removeUpdates(locationListener)
            isLocation = !isLocation
        }
    }

你可能会发现,这行locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0f, locationListener)代码报错,我们看看源码是怎么样的

这里告诉我们调用这个方法需要在请求了定位权限之后,否则就会闪退,不信你可以试试看,而我们现在明显已经是获取了权限了,那么我们也可以增加一个注解,点击这一行,Alt + Enter,出现弹窗。

选择标注的这一项,则会在方法上方添加一个注解:@SuppressLint("MissingPermission"),这并不是最好的方式,但是省事,只要你满足那个前提,那就不会有问题,最后我们在initMap()函数中调用startLocation(),如下图所示

同时我们在定位监听回调中调用stopLocation(),如下图所示

下面我们运行一下看看是否会触发定位,看看控制台是否会打印经纬度。

打印了出来,这证明定位监听是有效的,下面我们需要改变地图中心。

二、改变地图中心

在MainActivity中增加一个函数,代码如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    /**
     * 修改地图中心点
     */
    private fun changeMapCenter(geoPoint: GeoPoint) {
        Log.d(TAG, "changeMapCenter: $geoPoint")
        binding.mapView.apply {
            controller.apply {
                setZoom(14.0)
                setCenter(geoPoint)
            }
        }
    }

当调用changeMapCenter时,打印一下然后通过地图控制器修改缩放比例和地图中心,接下来就在定位监听中回调中调用changeMapCenter(),如下图所示:

下面运行一下,注意定位可能会有点慢,请耐心等待,只要定位成功了地图肯定会改变的,我们通过日志确认一下:

虽然我们改变了地图中心,但是没有标识,都不知道是哪里,下面就添加一个Marker。

三、添加Marker

首先在MainActivity中声明一个变量

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    // 标记
    private var mMarker: Marker? = null

然后我们修改changeMapCenter()函数,添加代码如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
            if (mMarker != null) {
                overlays.remove(mMarker)
            }
            mMarker = Marker(this).apply {
                title = "Marker"
                position = geoPoint
            }
            // 添加标点
            overlays.add(mMarker)

添加位置如下图所示:

此时你再运行一下就能看到一个标点了,我就不贴图了,容易暴露位置被Gank。

四、地图点击

下面我们来做一个地图点击事件,地图点击是在OverlayManager上完成的,我们回到initMap()函数,增加如下代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
            // 覆盖管理器配置
            overlayManager.apply {
                tilesOverlay.isEnabled = true
                add(object : Overlay() {
                    override fun onSingleTapConfirmed(e: MotionEvent?, mapView: MapView?): Boolean {
                        Log.d(TAG, "onSingleTapConfirmed")
                        return super.onSingleTapConfirmed(e, mapView)
                    }
                })
            }

添加位置如下图所示:

从上述代码来看,我们启用地图上的图块叠加层,并添加一个新的叠加层,该叠加层在单击时打印日志,下面运行一下随便点击,看看控制台是否有日志打印。

出现了日志说明点击有效果,实际上还有一个方法,如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	override fun onSingleTapUp(e: MotionEvent?, mapView: MapView?): Boolean {
		Log.d(TAG, "onSingleTapUp")
		return super.onSingleTapUp(e, mapView)
	}

  这个函数也是单击,只不过我在测试的时候,同时打印时发现,每次点击这两个都会触发,而onSingleTapConfirmed()是最后触发的,所以就用onSingleTapConfirmed()了。现在点击生效之后,我们需要在点击之后改变地图位置,那么就可以调用changeMapCenter()函数,但是它需要传入一个GeoPoint对象,因此我们需要通过mapView去得到这个对象所需要的值,也就是经纬度,下面我们在onSingleTapConfirmed()回调中,增加如下所示代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	// 获取投影对象后进行坐标转换再切换地图中心位置
		mapView?.projection?.let { proj ->
		val geoPoint = proj.fromPixels(e!!.x.toInt(), e.y.toInt()) as GeoPoint
		Log.d(TAG, "onSingleTapConfirmed: 切换地图中心位置")
		changeMapCenter(geoPoint)
	}

添加位置如下图所示:

这段代码的含义通过上面的注释应该都清楚了,再通俗一点,就是点击屏幕的像素进行x,y坐标的转换,下面再运行一下看看会怎么样?

看到这个日志地图就已经切换成功了。

五、其他配置

地图上还有一些其他的配置,比如我们可以显示缩放控件。

① 缩放控件

通过zoomController去控制显示的状态。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	zoomController.setVisibility(Visibility.SHOW_AND_FADEOUT)

比如这里我们设置为SHOW_AND_FADEOUT,就是淡入淡出,当你点击触摸屏幕时就会在底部出现,不触摸屏幕3.5s后控件消失,还有两个属性是ALWAYS, NEVER,很好理解就是总是显示和从不显示的意思,我们之前的代码中是设置从不显示的,你可以改成SHOW_AND_FADEOUT

② Marker更换图标

我们可以通过marker的属性去更改图标,首先我们画一个图标,在drawable下新建一个ic_marker.xml文件,代码如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="48dp"
    android:height="48dp"
    android:tint="#5AD3E5"
    android:viewportWidth="24"
    android:viewportHeight="24">

    <path
        android:fillColor="@android:color/white"
        android:pathData="M12,2L12,2C8.13,2 5,5.13 5,9c0,1.74 0.5,3.37 1.41,4.84c0.95,1.54 2.2,2.86 3.16,4.4c0.47,0.75 0.81,1.45 1.17,2.26C11,21.05 11.21,22 12,22h0c0.79,0 1,-0.95 1.25,-1.5c0.37,-0.81 0.7,-1.51 1.17,-2.26c0.96,-1.53 2.21,-2.85 3.16,-4.4C18.5,12.37 19,10.74 19,9C19,5.13 15.87,2 12,2zM12,11.75c-1.38,0 -2.5,-1.12 -2.5,-2.5s1.12,-2.5 2.5,-2.5s2.5,1.12 2.5,2.5S13.38,11.75 12,11.75z" />

</vector>

然后通过一行代码去设置,如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	icon = ContextCompat.getDrawable(this@MainActivity, R.drawable.ic_marker)

位置如下图所示:

这样我们就替换掉了默认的那个Marker图标。

③ 添加比例尺

在地图上添加比例尺,在initMap()中,添加代码如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	add(ScaleBarOverlay(binding.mapView).apply {
		setAlignBottom(true) // 底部对齐
		setScaleBarOffset(100, 10) // 设置偏移量
	})

添加位置如下图所示:

这里的setAlignBottom()设置显示在屏幕底部,还有两个方法:setCentred()、setAlignRight(),根据方法名可以知道是什么意思,自行测试。

④ 添加指南针

添加指南针

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	// 添加指南针
	add(CompassOverlay(this@MainActivity, binding.mapView).apply {
		enableCompass()
	})                

添加位置如下图所示:

⑤ 添加经纬度网格线

添加 显示纬度/经度网格线

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	// 添加经纬度网格线
	add(LatLonGridlineOverlay2())

添加位置如下图所示:

⑥ 启用旋转手势

启用旋转手势需要配置地图和增加叠加层,地图上设置:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	setMultiTouchControls(true)

添加叠加层

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	// 启用旋转手势
	add(RotationGestureOverlay(binding.mapView).apply { isEnabled = true })

添加位置如下图所示:

⑦ 添加小地图

通过小地图叠加层添加,根据屏幕的宽高 / 4设置小地图的宽高,并且设置小地图瓦片资源,代码如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	add(MinimapOverlay(this@MainActivity, binding.mapView.tileRequestCompleteHandler).apply {
		val dm = resources.displayMetrics
		width = dm.widthPixels / 4
		height = dm.heightPixels / 4
		// 设置小地图资源
		setTileSource(Config.TDTCIA_W)
	})

添加位置如下图所示:

运行效果如下图所示:

六、源码

如果对你有所帮助的话,不妨欢迎StarFork

源码地址:OpenMap

APK下载地址:OpenMap1.0.apk

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-11-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Android Osmdroid + 天地图 (一)
  Osmdroid是一款完全开源的地图基本操作SDK,我们可以通过这个SDK去加一些地图API,比如腾讯、百度、高德、Google等等。天地图API也是一个地图服务提供商,不过之前还是提供Android的地图SDK的,现在就只提供了API服务了,那么为什么我们会想到这个天地图API呢?因为贫穷,贫穷使我们相遇,如果你是个人项目不上架的那种我推荐你使用高德、百度、腾讯3家,但如果你要上架的话就涉及到一个可能会被宰的问题了,这3家商业授权都是5万一年,那不是开玩笑的,如果你的应用不是主导地图的话,完全犯不上去使用,下面我们进入正文去使用天地图API,效果图如下所示:
晨曦_LLW
2024/11/28
5920
Android Osmdroid + 天地图 (一)
Google Map
上一章介绍了如何使用Android的GPS来获取设备的定位信息,但这种方式得到的定位信息只不过是一些数字的经度、纬度值,如果这些经度、纬度值不能以更加形象、直观的方式显示出来,对于大部分普通用户而言,这些数据几乎没有任何价值。要想让这些经纬度值“派上”用场,就需要用到本章中介绍到的Google Map服务。在本章中我们首先对Google Map进行简单的介绍,然后介绍Android中进行Google Map开发需要的准备工作,最后通过一系列的案例讲解了在Android中进行Google Map开发的方法及技巧。
张哥编程
2024/12/17
2470
Google Map
Android平台GPS系统的应用开发
第一部分、前述: Android作为Google移动互联网战略的重要组成部分,将进一步推进“随时随地为每个人提供信息”这一企业目标的实现。Google的目标是让移动通信不依赖于设备,甚至是平台。出于这个目的,Android将完善而不是替代Google长期以来推行的移动发展战略:通过与全球各地的手机制造商和移动运营商成为合作伙伴,开发既实用又有吸引力的移动服务,并推广这些产品。 随着城市化的进展和家用轿车的普及.原本根遥远的全球卫星定位系统(Global Position System.6Ps)的使用越来越多
庞小明
2018/03/07
4.5K0
Android平台GPS系统的应用开发
Android 天气APP(二十四)地图天气(上)自动定位和地图点击定位
之前也看过和风天气自己做的APP,主页面的地图点击之后,定位到某一个点,然后查看这个地方的天气,实际思路还是通过区县来查询天气的,只不过,加上了地图就比较的直观,看起来也会觉得很上档次,所以我也决定做一个这样的功能。 这篇文章实现的效果图如下:
晨曦_LLW
2020/09/25
2.1K0
Android 高德地图API(详细步骤+源码)三
实际开发中都会对地图的点击和长按做处理,比如点击某一个地方获取经纬度,下面来操作一下吧。
晨曦_LLW
2021/02/24
3.9K0
Android 高德地图API(详细步骤+源码)三
Android Google Maps
  在国内你选择的SDK可以是高德、百度、腾讯等,但在国外,你首选肯定是谷歌,因此要进行Google地图的开发你首先要解决下面三个问题
晨曦_LLW
2024/11/28
2310
Android Google Maps
Android 高德地图API(详细步骤+源码)二
我删除了TextView,改变了外部的父布局,进入到MainActivity中。按照下图进行改变,你可以将无用的代码删除掉。
晨曦_LLW
2021/02/20
3.5K0
Android 高德地图API(详细步骤+源码)二
用百度地图API打造方便自己使用的手机地图
有钱人咱就不说了,因为偶是个穷银……因为穷,所以去年买的Huawei C8650+到现在还在上岗,对于没有钱买好的配置的手机的童鞋来说,类似于百度,谷歌,高德等商家的地图在自己的机器上跑起来确实是有点勉为其难,为了能够用上手机的地图,并不怎么大,最近闲来无事,就动起了这方面的脑筋,结果就是用百度地图API开发一个自己想要的功能的地图……
牛老师讲GIS
2018/10/23
2.9K0
用百度地图API打造方便自己使用的手机地图
在viewPager里使用高德地图
因为viewpager的预加载机制,使得联网应用会多出内存以及网络的使用量,同时,在viewpager下使用高德地图,也会因此出现各种莫名其妙的问题,因此,需要使用懒加载的手段。 实现懒加载,只需继承fragment类然后重写与界面显示相关的方法即可。
用户1665735
2019/02/19
2.3K0
Android 高德地图API(详细步骤+源码)四
首先要搞清楚什么是路线规划,比如有两个地点,A和B。从A到B有多种方路线和交通工具可以选择,这就是路线规划。
晨曦_LLW
2021/03/04
3.5K0
Android 高德地图API(详细步骤+源码)四
15.百度地图
旧SDK: 旧key申请网页:http://developer.baidu.com/map/android-mobile-apply-key.htm 添加jar包,可以直接将sample程序中的jar包拷进来 用法: public interface ConstantValue { String KEY = "1A4A4ABEFBEECD8C17DEE880C4EA69B9607020B5"; } <com.baidu.mapapi.map.MapView android:id
六月的雨
2018/05/14
7620
Android MVVM框架搭建(八)高德地图定位、天气查询、BottomSheetDialog
  在上一篇文章中完成了对个人用户信息的修改,同时讲述了对弹窗数据的处理,权限的使用,本文将在App中接入一个地图SDK,同时完成天气的查询,完成后的效果如下图所示:
晨曦_LLW
2021/12/27
1.9K0
Android MVVM框架搭建(八)高德地图定位、天气查询、BottomSheetDialog
Android 百度地图SDK 自动定位、标记定位
如果是你满意的那样,我们就可以开始写了,首先创建一个名为MapDemo的项目。 打开AndroidManifest.xml,复制你的包名
晨曦_LLW
2022/05/10
2.5K1
Android 百度地图SDK 自动定位、标记定位
Arcgis API for Android之GPS定位
先说说写这篇文章的原因吧,在群内讨论的过程中,有人提到了定位的问题,刚好,自己以前在做相关工作的时候做过相关的东西,所以就总结一下,给大家共享出来,由于本人水平有限,bug是在所难免,还望有更高的高人批评指正。废话不多说,直接进入主题。
牛老师讲GIS
2018/10/23
9530
Arcgis For Android之GPS定位实现
翻开以前做的东西,看了看,很多从逻辑上比较乱,对之做了修改,完成后实现的效果为: MapActivity源代码如下: package com.lzugis.map; import java.io.File; import java.util.Iterator; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.location.Gps
牛老师讲GIS
2018/10/23
1.8K0
安卓—项目中插入百度地图sdk
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/116586.html原文链接:https://javaforall.cn
全栈程序员站长
2022/07/07
8900
Android开发笔记(一百零三)地图与定位SDK
国内常用的地图SDK就是百度和高德了,二者的用法大同小异,可按照官网上的开发指南一步步来。下面是我在集成地图SDK时遇到的问题说明: 1、点击基本地图功能选项,不能打开地图,弹出“key验证出错!请在AndroidManifest.xml文件中检查key设置的”的红色字提示。查看日志提示“galaxy lib host missing meta-data,make sure you know the right way to integrate galaxy” 该问题是因为key值对应的签名与app打包用的签名不一致。app在开发时与发布时有两个不同的签名,开发时用的是ADT默认签名,查看默认签名的SHA1值可依次选择“Window”->“Preferences”->“Android”->“Build  SHA1 fingerprint”。app发布时的签名是密钥文件的签名,查看发布签名的SHA1值可依次选择“File”->“Export”->“Export Android Application”->“Next”后选择密钥文件并输入密码与app输出路径->在“Certificate fingerprints”下查看SHA1值。 2、百度地图SDK3.6及以上版本找不到overlayutil包。 这是因为新版SDK的jar包不再包含这部分源码,得到官方demo的src目录下获取源码加入到开发者自己的工程中,源码路径为:BaiduMap_AndroidMapSDK_v3.7.1_Sample\BaiduMapsApiDemo\src\com\baidu\mapapi 3、在一个工程中同时包含了百度地图和高德地图的sdk,编译时报错“Found duplicate file for APK: assets/lineDashTexture.png”。 这是因为百度和高德的sdk,其jar包存在同名文件“assets/lineDashTexture.png”,所以无法通过编译。即百度sdk与高德sdk是互斥的,不能同时存在于同个工程中,必须分开来使用。
aqi00
2019/01/18
1.7K0
位置定位(LocationManager)
LocationManager是Android 提供的Location 服务,来获得当前的位置信息和卫星信息。
李小白是一只喵
2020/06/11
2.6K0
位置定位(LocationManager)
《移动互联网技术》第九章 感知与多媒体: 了解质感设计的基本原则和设计方法
《移动互联网技术》课程是软件工程、电子信息等专业的专业课,主要介绍移动互联网系统及应用开发技术。课程内容主要包括移动互联网概述、无线网络技术、无线定位技术、Android应用开发和移动应用项目实践等五个部分。移动互联网概述主要介绍移动互联网的概况和发展,以及移动计算的特点。无线网络技术部分主要介绍移动通信网络(包括2G/3G/4G/5G技术)、无线传感器网络、Ad hoc网络、各种移动通信协议,以及移动IP技术。无线定位技术部分主要介绍无线定位的基本原理、定位方法、定位业务、数据采集等相关技术。Android应用开发部分主要介绍移动应用的开发环境、应用开发框架和各种功能组件以及常用的开发工具。移动应用项目实践部分主要介绍移动应用开发过程、移动应用客户端开发、以及应用开发实例。 课程的教学培养目标如下: 1.培养学生综合运用多门课程知识以解决工程领域问题的能力,能够理解各种移动通信方法,完成移动定位算法的设计。 2.培养学生移动应用编程能力,能够编写Andorid应用的主要功能模块,并掌握移动应用的开发流程。 3. 培养工程实践能力和创新能力。  通过本课程的学习应达到以下目的: 1.掌握移动互联网的基本概念和原理; 2.掌握移动应用系统的设计原则; 3.掌握Android应用软件的基本编程方法; 4.能正确使用常用的移动应用开发工具和测试工具。
猫头虎
2024/04/08
1460
百度地图开发1
最近自己想研究下地图,本来想研究google Map,但是申请API key比较坑爹,于是从百度地图入手,其实他们的用法都差不多,本篇文章就带领大家在自己的Android项目中加入百度地图的功能,接下
xiangzhihong
2018/01/29
1.8K0
百度地图开发1
推荐阅读
相关推荐
Android Osmdroid + 天地图 (一)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验