当前位置: 首页 > news >正文

基于Java在高德地图面查询检索中使用WGS84坐标的一种方法-以某商场的POI数据检索为例

前言

        随着移动互联网的飞速发展,基于位置的服务(LBS)需求日益增长,越来越多的应用需要从地图中检索特定区域内的地理信息,例如商业场所、公共服务设施等。商场作为城市商业活动的重要载体,其周边的地理信息对于消费者、商家以及城市规划者都具有重要的参考价值。例如,消费者可以通过检索商场周边的交通设施、餐饮场所等信息,来安排购物和休闲计划;商家则可以分析商场周边的人流量、竞争对手分布等信息,进行市场定位和营销策略的制定;城市规划者也可以借助这些数据,优化城市商业布局和交通规划。

        在高德地图中,POI(Point of Interest,兴趣点)数据是一种重要的地理信息资源,它包含了各种类型的地理实体,如商场、酒店、餐厅、学校等。对于商场的 POI 数据检索,在高德地图中,默认采用的是中国标准的火星坐标系(GCJ-02)。WGS84 坐标系统是一种全球通用的地理坐标系统,具有高精度和广泛的兼容性,能够准确地定位地球表面的任意一点,同时在很多的应用中,空间参考使用的WGS84的坐标系。通过将商场及其周边区域的地理信息可以实现对特定区域内的 POI 数据的高效查询和精准检索。但是需要注意的是,在高德的检索API中,其传入的检索面数据的坐标是高德的。因此如果您的需求是传入WGS84的坐标,那么就需要进行坐标转换后才能作为查询参数传入。

        本文将以某商场的 POI 数据检索为例,深入探讨这一方法的实现过程和应用效果,旨在为相关领域的研究和实践提供参考和借鉴。除了讲解如何实现不同的空间面转换查询,还讲解如何实现对高德地图进行穷举查询。

一、面数据检索简介

        本节将重点对高德地图中的的面检索API进行一个简单的介绍。分别从服务地址、请求参数、响应参数三个方面来进行讲解。

1、服务地址

        多边形区域搜索 API 服务地址

URL

请求方式

https://restapi.amap.com/v5/place/polygon?parameters

GET

        parameters 代表的参数包括必填参数和可选参数。所有参数均使用和号字符(&)进行分隔。下面的列表枚举了这些参数及其使用规则。

2、请求参数

参数名

含义

规则说明

是否必须

缺省值

key

高德Key

用户在高德地图官网 申请 Web 服务 API 类型 Key

必填

polygon

多边形区域

多个坐标对集合,坐标对用"|"分割。多边形为矩形时,可传入左上右下两顶点坐标对;其他情况下首尾坐标对需相同。

必填

keywords

地点关键字

需要被检索的地点文本信息。

只支持一个关键字 ,文本总长度不可超过80字符

可选

types

指定地点类型

地点文本搜索接口支持按照设定的 POI 类型限定地点搜索结果;地点类型与 poi typecode 是同类内容,可以传入多个 poi typecode,相互之间用“|”分隔,内容可以参考 POI 分类码表;地点(POI)列表的排序会按照高德搜索能力进行综合权重排序;

可选

120000(商务住宅)

150000(交通设施服务)

show_fields

返回结果控制

show_fields 用来筛选 response 结果中可选字段。show_fields 的使用需要遵循如下规则:

1、具体可指定返回的字段类请见下方返回结果说明中的“show_fields”内字段类型;

2、多个字段间采用“,”进行分割;

3、show_fields 未设置时,只返回基础信息类内字段。

可选

page_size

当前分页展示的数据条数

page_size 的取值1-25

可选

page_size 默认为10

page_num

请求第几分页

请求第几分页

可选

page_num 默认为1

sig

数字签名

请参考数字签名获取和使用方法

可选

output

返回结果格式类型

默认格式为 json,目前只支持 json 格式;

可选

json

callback

回调函数

callback 值是用户定义的函数名称,此参数只在 output 参数设置为 JSON 时有效。

可选

3、服务示例

https://restapi.amap.com/v5/place/polygon?polygon=116.460988,40.006919|116.48231,40.007381|116.47516,39.99713|116.472596,39.985227|116.45669,39.984989|116.460988,40.006919&keywords=肯德基&types=050301&key=<用户的key>

参数

备注

必选

polygon

多边形区域,多个坐标对集合,坐标对用"|"分割。多边形为矩形时,可传入左上右下两顶点坐标对;其他情况下首尾坐标对需相同

keywords

地点关键字,需要被检索的地点文本信息
只支持一个关键字

可选

types

指定地点类型,地点文本搜索接口支持按照设定的 POI 类型限定地点搜索结果;地点类型与 poi typecode 是同类内容,可以传入多个 poi typecode,相互之间用“|”分隔,内容可以参考 POI 分类码表;地点(POI)列表的排序会按照高德搜索能力进行综合权重排序;

4、返回结果

名称

类型

说明

status

string

本次 API 访问状态,如果成功返回1,如果失败返回0。

info

string

访问状态值的说明,如果成功返回"ok",失败返回错误原因,具体见 错误码说明。

infocode

string

返回状态说明,10000代表正确,详情参阅 info 状态表

count

string

单次请求返回的实际 poi 点的个数

pois

object

返回的 poi 完整集合

poi

单个 poi 内包含的完整返回数据

name

string

poi 名称

id

string

poi 唯一标识

location

string

poi 经纬度

type

string

poi 所属类型

typecode

string

poi 分类编码

pname

string

poi 所属省份

cityname

string

poi 所属城市

adname

string

poi所属区县

address

string

poi 详细地址

pcode

string

poi 所属省份编码

adcode

string

poi 所属区域编码

citycode

string

poi 所属城市编码

注意以下字段如需返回需要通过“show_fields”进行参数类设置。

children

object

设置后返回子 POI 信息

id

string

子 poi 唯一标识

name

string

子 poi 名称

location

string

子 poi 经纬度

address

string

子 poi 详细地址

subtype

string

子 poi 所属类型

typecode

string

子 poi 分类编码

business

object

设置后返回子 POI 信息

business_area

string

poi 所属商圈

tel

string

poi 的联系电话

tag

string

poi 特色内容,目前仅在美食 poi 下返回

rating

string

poi 评分,目前仅在餐饮、酒店、景点、影院类 POI 下返回

cost

string

poi 人均消费,目前仅在餐饮、酒店、景点、影院类 POI 下返回

parking_type

string

停车场类型(地下、地面、路边),目前仅在停车场类 POI 下返回

alias

string

poi 的别名,无别名时不返回

indoor

object

设置后返回室内相关信息

indoor_map

string

是否有室内地图标志,1为有,0为没有

cpid

string

如果当前 POI 为建筑物类 POI,则 cpid 为自身 POI ID;如果当前 POI 为商铺类 POI,则 cpid 为其所在建筑物的 POI ID。

indoor_map 为0时不返回

floor

string

楼层索引,一般会用数字表示,例如8;indoor_map 为0时不返回

truefloor

string

所在楼层,一般会带有字母,例如F8;indoor_map 为0时不返回

navi

object

设置后返回导航位置相关信息

navi_poiid

string

poi 对应的导航引导点坐标。大型面状 POI 的导航引导点,一般为各类出入口,方便结合导航、路线规划等服务使用

entr_location

string

poi 的入口经纬度坐标

exit_location

string

poi 的出口经纬度坐标

gridcode

string

poi 的地理格 id

photos

object

设置后返回 poi 图片相关信息

title

string

poi 的图片介绍

url

string

poi 图片的下载链接

二、面数据检索实践

        介绍完以上的面数据检索API的具体内容之后,下面结合具体的一个商场-以步步高梅溪新天地为例,重点介绍基于梅溪新天地的面数据检索。同时对比使用GCJ-02和WGS84两个不同的坐标参考,最后介绍使用穷举的办法实现面数据的检索。

1、GCJ-02面检索

        关于如何定义API来创建高德地图的请求这里不再进行赘述。为了演示方便,我们使用的数据查询面是直接从高德地图获取的面数据。因此,我们最开始的查询面数据类型是GCJ-02的类型,为了演示WGS84,我们需要将GCJ-02的参考坐标转换为WGS84后,转换办法在下面的内容中给出。

/**
* - 根据兴趣面来搜索范围内的POI数据
* @throws InterruptedException
*/
@Test
public void searchByPolygon() throws InterruptedException {String polygon = "112.859225,28.20061;112.859172,28.20059;112.859117,28.200556;112.859058,28.200503;112.859003,28.200391;112.858739,28.199761;112.858627,28.199041;112.858673,28.198558;112.859401,28.196282;112.859435,28.196228;112.859515,28.196194;112.859594,28.196185;112.859938,28.196191;112.860163,28.196155;112.860421,28.196063;112.860709,28.195926;112.860964,28.195702;112.861103,28.195304;112.861116,28.195285;112.86115,28.195274;112.863672,28.195709;112.863705,28.195727;112.863726,28.195767;112.863732,28.195806;112.863328,28.197513;112.863249,28.19793;112.863134,28.198666;112.863084,28.198923;112.862918,28.19949;112.862647,28.200901;112.862622,28.200931;112.862583,28.200958;112.862531,28.200989;112.862463,28.201008;112.859225,28.20061";polygon = polygon.replaceAll(";", "|");String keywords = "";String types = "080000|060000";String page_size = "25";//String region = "430104";String show_fields = "children,business,indoor,navi,photos";HttpResponse<String> result = null;for(int i = 1;i<= 1;i++) {result = amapSearchService.searchByPolygon(polygon, keywords, types, page_size, String.valueOf(i), show_fields, AMAP_CLIENT_AK);System.out.println(result.getBodyResult());Thread.sleep(3000L);//休眠3000秒}}

        运行以后在IDE的控制台中可以看到有以下的输出,说明按照面检索成功,返回数据如下:

        可以看到,使用GCJ-02的面数据检索返回的数据是准确的,符合我们的查询预期。是所属商场返回的POI数据。

2、WGS84面检索

除了直接使用GCJ-02的这种查询方式,我们更多的场景下需要使用WGS84的坐标,因此我们需要使用将GCJ-02的坐标转换成WGS84,关于如何进行转换,可以查看以下的方法:

private String gcg2wgs82(String source) {StringBuffer wgs84 = new StringBuffer(source.length());String [] AOI_Str_Array = source.split(";");//处理坐标for (int i = 0; i < AOI_Str_Array.length; i++) {String loc = AOI_Str_Array[i];String [] latlon = loc.split(",");double lng = Double.parseDouble(latlon[0]);double lat = Double.parseDouble(latlon[1]);//将高德坐标转换成WGS84坐标double [] gcj284 = CoordinateTransformUtil.gcj02towgs84(lng, lat);wgs84.append(gcj284[0]).append(",").append(gcj284[1]).append("|");}return wgs84.substring(0, wgs84.length()-1);
}

下面是更详细的gcj-02坐标转wgs84点数据的转换方法,

/**
* -GCJ02(火星坐标系)转GPS84
* 
* @param lng 火星坐标系的经度
* @param lat 火星坐标系纬度
* @return WGS84坐标数组
*/
public static double[] gcj02towgs84(double lng, double lat) {if (out_of_china(lng, lat)) {return new double[] { lng, lat };}double dlat = transformlat(lng - 105.0, lat - 35.0);double dlng = transformlng(lng - 105.0, lat - 35.0);double radlat = lat / 180.0 * pi;double magic = Math.sin(radlat);magic = 1 - ee * magic * magic;double sqrtmagic = Math.sqrt(magic);dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * pi);dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * pi);double mglat = lat + dlat;double mglng = lng + dlng;return new double[] { lng * 2 - mglng, lat * 2 - mglat };
}

         与GCJ-02坐标的面检索方法一致,我们将GCJ-02坐标转为WGS84后,再进行检索实验,可以看到以下的数据。

        可以看到,在返回的检索结果数据中。跟之前返回的数据不一致了,熟悉步步高梅溪新天地的朋友应该知道,这些POI兴趣点已经不在指定的商场里面了。 由此我们得出一个结论,就是调用高德的面数据查询中,传入的面数据的坐标类型是GCJ-02,如果传入的是WGS84,其最后的计算结果肯定会偏移,因此要求大家前偏转回来或者直接使用GCJ-02的坐标参考。这个知识点也是本博客的重点。

3、穷举检索实现

        与天地图和百度地图的API不同的是,在高德的数据返回接口中,没有一个明确的总数的概念。而通常在实际业务中,我们需要将所有的数据都进行抓取,在这里我们可以使用穷举的方法来是,简单来讲就是保证调用服务最少调用一次,然后通过返回的当前数据条数有没有大于0,如果大于0,表示当前还有数据,需要继续;否则停止调用。这个翻译成代码如下所示:

HttpResponse<String> result = null;
int scrapingIndex = 1;
int dataCount = 0;
do {result = amapSearchService.searchByPolygon(gcjPolygon, keywords, types, page_size, String.valueOf(scrapingIndex), show_fields, AMAP_CLIENT_AK);System.out.println("使用高德面搜索结果");System.out.println(result.getBodyResult());if(StringUtils.isNotEmpty(result.getBodyResult())) {AmapSearchVO searchVO = gson.fromJson(result.getBodyResult(), AmapSearchVO.class);System.out.println(searchVO.getCount());dataCount = searchVO.getCount();scrapingIndex ++;}Thread.sleep(3000L);//休眠3000秒
} while (dataCount > 0);
System.out.println("一共抓取数据页数:" + scrapingIndex);

        使用的方法就是使用do...while循环,至少保证一次进入,在符合条件的情况下,循环推出。

 运行上面的程序后,可以看到数据被抓取到了,而且还分页了。数据结果如下:

        同时在Eclipse中可以看到以下输出,这句话表示当前的数据检索大约有10页,超过10页基本也就没数据了。

一共抓取数据页数:10

三、总结

        以上就是本文的主要内容,本文将以某商场的 POI 数据检索为例,深入探讨这一方法的实现过程和应用效果,旨在为相关领域的研究和实践提供参考和借鉴。除了讲解如何实现不同的空间面转换查询,还讲解如何实现对高德地图进行穷举查询。Java 作为一种广泛使用的编程语言,具有良好的跨平台性、稳定性和丰富的开发库,为实现基于高德地图的 POI 数据检索提供了强大的技术支持。利用 Java 开发的高德地图 API,可以方便地调用地图服务,实现坐标转换、地图绘制、数据查询等功能。因此,研究基于 Java 在高德地图面查询检索中使用 WGS84 坐标的方法,对于提高商场 POI 数据检索的准确性和效率具有重要的现实意义。通过本文,不仅可以学习高德地图的按面检索API,同时了解了使用不同的坐标参考系的查询结果影响,通过实例对结果进行了简单的说明。行文仓促,定有不足之处,欢迎各位朋友在评论区批评指正,不胜感激。

相关文章:

  • Flutter 中的 async/await 和 Future
  • 全能视频处理工具介绍说明
  • 大语言模型 12 - 从0开始训练GPT 0.25B参数量 MiniMind2 补充 训练开销 训练步骤 知识蒸馏 LoRA等
  • JavaScript 性能优化实战指南
  • 《JVM如何判断一个对象可以被回收?图文详解GC Root算法》
  • 深度解析:Redis 性能优化全方位指南
  • Python操作PDF书签详解 - 添加、修改、提取和删除
  • AI量化交易是什么?它是如何重塑金融世界的?
  • 如何评估开源商城小程序源码的基础防护能力?
  • 蓝桥杯2300 质数拆分
  • 四:操作系统cpu调度之调度算法
  • JVM类加载机制
  • Java设计模式之桥接模式:从入门到精通
  • 1-3V升3.2V升压驱动WT7013
  • 利用ffmpeg截图和生成gif
  • esp32课设记录(四)摩斯密码的实现 并用mqtt上传
  • fnOS手机APP+NAS架构:破解跨地域数据实时访问的内网穿透难题
  • 5月19日笔记
  • lammps后处理:堆垛层错和孪晶的数量统计
  • 03 接口自动化-精通Postman之接口鉴权,接口Mock,接口加解密以及接口签名Sign
  • 财政部:鼓励政策性银行对符合条件的城市更新项目提供支持
  • 俄美元首通话超2小时,普京称愿与乌方共同起草和平备忘录
  • 大巴车高速上撞山致2死2伤,广东肇庆警方通报
  • 美国考虑让移民上真人秀竞逐公民权,制片人称非现实版《饥饿游戏》
  • 有关“普泽会”,俄官方表示:有可能
  • 流失海外79年,两卷战国帛书回归祖国