1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > java百度地图逆地址解析_web前端通过百度地图API批量逆解析地址

java百度地图逆地址解析_web前端通过百度地图API批量逆解析地址

时间:2021-01-06 20:37:36

相关推荐

java百度地图逆地址解析_web前端通过百度地图API批量逆解析地址

前言

最近碰到一个需求,就是将我们系统中要导出一系列的工作数据,这里面有一个需求就是根据工作人员的经纬度去获取他可能的位置。说到这里大家肯定能想到用地图API了,我这里用的是百度地图的API(详情可参考)。然后这里就涉及到一个问题,工作数据是很多条的,但是这里的API很明显就只能一条一条的去请求,那么我们怎么封装能够达到我们的目的呢。

获取百度AK

首先呢,我们想要使用百度地图相关的API的话,肯定是要去注册申请相关的使用资格的,详细的账号申请流程呢,请戳这里,这里面详细介绍了如何注册并申请百度AK,只有拿到了AK,我们在使用相关的API时才会有效,否则是不生效的话,所以大家一定要保证有AK并且是有效的哈。

两种逆地址解析的方法

申请好了AK之后呢,这里有两种使用方法:

一种是直接通过url来进行请求,像是下边这种

http://api./geocoder?location=39.910093,116.403945&output=json&key=你的百度AK

复制代码

这种方法使用的话,大家可以直接把这个url放到axios或者ajax里面,然后他的回调里面返回的就是我们想要的地址等相关信息了。另一种方法就是官网里面介绍的方法:

// 初始化地图,这里的window可能需要从父组件传过来,原理还没弄清楚

var map = new window.BMap.Map("allmap");

// 创建地理编码实例

var myGeo = new window.BMap.Geocoder();

// 根据坐标得到地址描述

myGeo.getLocation(new window.BMap.Point(116.404, 39.915), function(result){

if (result){

console.log('这就是解析之后的地址了',resule.address)

}

})

复制代码注意:用第二种方法的话,我们需要在index.html里面引用我们上面的AK,如下

复制代码

上面的两种方法,都可以达到我们获取地址信息的目的哈。我这里选用的是第二种方法,然后后面我们批量请求的话,也是针对第二种方式来进行改装的。

问题分析

刚开始我的思路是想着,既然这种方法只能够一条一条请求的话,那我就将经纬度构建成一个数组,通过循环调用的方法来给这个数组中的值赋值,代码如下

gpsDatas.forEach((gpsItem)=>{

var map = new window.BMap.Map("allmap");

// 创建地理编码实例

var myGeo = new window.BMap.Geocoder();

// 根据坐标得到地址描述,将每一项的经纬度传入

myGeo.getLocation(new window.BMap.Point(gpsItem.longitude, gpsItem.latitude), function(result:any){

if (result){

// 将返回的值赋给该字段

gpsItem.maybePosition = result.address

}

})

})

// 返回我们要输出的数据

console.log('gpsDatas',gpsDatas)

console.log('gpsDatas[0]',gpsDatas[0].maybePosition)

let a = gpsDatas[0].maybePosition

return gpsDatas

复制代码

如果大家执行到了这里的话,我们就会发现一个很经典的问题,也是我们经常可能会碰到的问题,就是我们可以看到第一个打印出来的gpsDatas数组里面是能够看到我们拿到了我们想要的值,但是第二个打印我们可能就会看到一个undefined了,那么有小伙伴就可能会产生这样一个疑惑了,为什么我明明打印出来看有这个值,但是为什么取不到值呢,这是因为在我们取值的时候,myGeo.getLocation这个异步函数还没有执行完毕,所以取值的时候我们是取不到这个值的,但是因为gpsDatas是一个引用数据类型,所以在异步函数执行完毕后,他会把数据填充到这个数组里面,因为引用地址没有改变,所以我们可以看到数组中的地址已经有值了。

可以这样理解,console输出数据的时候,他输出引用数据类型和基本数据类型是不同的。输出引用类型的话,其实他是输出了一个指针,我们看到的就是指向内存中的一片地址中的数据,所以尽管他是后边异步把数据放上来的,但是因为空间指向没有改变,所以输出的数据其实一直是在改变的,不过是console没有把这一步表现出来而已。

那么很显然,现在这种情况肯定是不满足我们的需求的,那么这里我们就需要将我们的方法就行改装一下了。

最终解决方案

经过前面的分析,我们可知,问题的产生是因为我们是一个循环调用异步函数的问题,循环先走完了,但是异步没有走完,所以导致我们取不出数据,那么大家其实很容易想到Promise,我们可以利用Promise.all,将所有的异步操作一起执行,然后在.then里面获取返回结果。实现如下:

getMaybePositionByLaLo(window,positionDatas){

// 定义一个Promise数组,来将异步操作放进来

let apiDatas = []

positionDatas.forEach((gpsItem)=>{

let apiItem = this.getMapInfo(window,gpsItem)

apiDatas.push(apiItem)

})

// 这里.all会将所有的异步操作一起放在队列中,等待所有异步执行完毕后才会执行.then,这就保证了我们的同步获取数据

return Promise.all(apiDatas)

.then((gpsData)=>{

return gpsData

})

}

// 将单个获取地理位置的方法封装成一个方法

// 这里传入window的目的是,有些地方直接new BMap会报错,需要new window.BMap才可以

getMapInfo(window,gpsItem){

return new Promise((resolve, reject)=>{

var map = new window.BMap.Map("allmap");

// 创建地理编码实例

var myGeo = new window.BMap.Geocoder();

// 根据坐标得到地址描述

myGeo.getLocation(new window.BMap.Point(gpsItem.longitude, gpsItem.latitude), function(result){

if (result){

gpsItem.maybePosition = result.address;

resolve(gpsItem)

}

})

})

}

// 然后我们就可以在页面直接调用了

this.getMaybePositionByLaLo(window,positionDatas)

.then((positionDatas)=>{

// 这里就可以去进行我们的取值赋值操作了

})

复制代码

以上我们就完成了我们的批量改装,其实核心就是对于Promise的应用,如何合理的运用Promise,对于我们以后的开发有着很大的好处,我也是最近才开始发现Promise的好处,之前只是了解,也没有多的去使用,欢迎大家以后一起学习指正。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。