爬取高德地图poi数据

本文介绍了如何爬取高德地图的POI数据,重点是多边形搜索方法,用于获取特定区域的所有poi。首先注册高德地图开发者账号并获取key,然后使用经纬度坐标拾取系统定义目标区域。通过API接口测试获取数据,并针对返回的count属性调整请求策略。当count达到上限时,将区域划分为更小的块进行递归请求。最后,提供代码实现逻辑,包括经纬度类定义、API调用方法以及数据处理。文章还提及了数据量和实际应用的考虑。
摘要由CSDN通过智能技术生成

高德地图搜索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接口有返回数据说明)

api返回数据1

如上图,这里比较重要的一个属性是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()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值