高德地图搜索poi的api介绍地址
当前想法是爬取目标区域(作者所在小县城)的所有poi数据,存到数据库中作为原始数据,然后供其它系统调用,因为之前爬取过百度地图的poi数据,所以这次工作就驾轻就熟了。
1、首先注册一个高德地图的开发者账号,申请一个绑定Web服务的key,然后把刚注册的开发者账号认证一下: 申请账号、key就不赘述了,去高德地图开发平台很简单就能完成了,将账号认证是为了提高每日访问高德地图api接口的次数限制和并发请求。
2、根据上方api地址里面的介绍,总共分为4中搜索: 关键字搜索:通过用POI的关键字进行条件搜索,例如:肯德基、朝阳公园等;同时支持设置POI类型搜索,例如:银行 周边搜索:在用户传入经纬度坐标点附近,在设定的范围内,按照关键字或POI类型搜索; 多边形搜索:在多边形区域内进行搜索 ID查询:通过POI ID,查询某个POI详情,建议可同输入提示API配合使用
我的目标是某个区域的所有poi,所以选择的第三种:多边形搜索
3、多边形搜索最重要的参数就是polygon-》经纬度坐标对,我在百度地图坐标拾取系统拾取了我的目标区域的经纬度坐标对,如下图:
3步准备工作到这里就差不多结束了,在正式开始码代码之前先做个测试吧,用浏览器直接访问接口看看返回的数据(当然,高德的api接口有返回数据说明)
如上图,这里比较重要的一个属性是count,根据api的介绍count是搜索方案数目(最大值为1000),所以说每次请求都会返回当前所搜所包含的poi个数,而大于1000的poi是没有办法获取到的。那么我如果想查询某个区域的全部数据,可以将这个区域再划分成更小的区域(显然是个递归操作)的集合,然后把这几个可以查到所有poi的区域的所有poi数据结合起来就是我最终需要的数据。可能口述不明朗,可以见下方草图:
好,可以开始撸代码了:
因为,整个调用API的过程都离不开经纬度,所以首先定义一个经纬度描述的类
//矩形块的经纬度标识, 左上角的经纬度 和右下角的经纬度
class RectangleCoordinate {
/**
* 矩形左上角经度
*/
private double x0;
/**
* 矩形左上角纬度
*/
private double y0;
/**
* 矩形右下角经度
*/
private double x1;
/**
* 矩形右下角纬度
*/
private double y1;
public RectangleCoordinate(double x0, double y0, double x1, double y1) {
this.x0 = x0;
this.y0 = y0;
this.x1 = x1;
this.y1 = y1;
}
/**
* [@return](https://my.oschina.net/u/556800) 获取矩形中心线的纬度
*/
public double getAverageY() {
return (y0 + y1) / 2;
}
/**
* [@return](https://my.oschina.net/u/556800) 获取矩形中心线的经度
*/
public double getAverageX() {
return (x0 + x1) / 2;
}
public double getX0() {
return x0;
}
public void setX0(double x0) {
this.x0 = x0;
}
public double getY0() {
return y0;
}
public void setY0(double y0) {
this.y0 = y0;
}
public double getX1() {
return x1;
}
public void setX1(double x1) {
this.x1 = x1;
}
public double getY1() {
return y1;
}
public void setY1(double y1) {
this.y1 = y1;
}
[@Override](https://my.oschina.net/u/1162528)
public String toString() {
return x0 + "," + y0 + "|" + x1 + "," + y1;
}
}`
然后需要一个调用api,获取返回数据的方法,这个方法参数就是矩形块,当然还需要一个页数,即当前方法获取的是某个矩形区域的第X页的数据(每页上线25个poi,默认20个poi)
/**
* @return 获取矩形块的poi数据
*/
private JSONObject getSearchResult(RectangleCoordinate coordinate, int page) {
RestTemplate restTemplate = new RestTemplate();
String url = getRequestGaodeUrl(coordinate,page);
String result = restTemplate.getForObject(url, String.class);
try {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
return JSONObject.parseObject(result);
} catch (Exception e) {
logger.error("an error occurred when getting response of gaode map data for coordinate:[{}]", coordinate.toString());
}
return null;
}
当然,上方已经说过,如果矩形块返回数据count=1000,就说明当前矩形块需要分割,我的想法比较简单,将矩形块按照上方草图,在水平中心和垂直分心分割,1个矩形块就分割成4个小矩形块了,方法如下:
/**
* @return 将矩形4等分成小矩形 然后返回4个 小矩形的经纬度集合
*/
private List<RectangleCoordinate> getSplitRectangleList(RectangleCoordinate coordinate) {
List<RectangleCoordinate> splitRectangleList = new LinkedList<>();
splitRectangleList.add(new RectangleCoordinate(coordinate.getX0()