SpringBoot拉取高德行政区域数据

SpringBoot拉取高德行政区域数据

一、账号申请

1.整体流程

行政区域文档:https://lbs.amap.com/api/webservice/guide/api/district
整体流程可参考:https://lbs.amap.com/api/webservice/guide/create-project/get-key
在这里插入图片描述

2.注册账号

注册地址:https://console.amap.com/dev/id/phone
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.创建应用

地址:https://console.amap.com/dev/key/app
在这里插入图片描述

4.申请key

在这里插入图片描述
请勾选web服务
在这里插入图片描述
在这里插入图片描述

二、核心代码

核心代码如下

  • 目前使用spring定时任务去拉取数据
  • 五级行政区域:国家、省、市、区、街道
  • 包括上下级关系、行政区划代码、经纬度信息
package com.qiangesoft.district.gaode;

import com.qiangesoft.district.entity.SysArea;
import com.qiangesoft.district.gaode.constant.RegionLevelEnum;
import com.qiangesoft.district.gaode.model.District;
import com.qiangesoft.district.gaode.model.DistrictConstant;
import com.qiangesoft.district.gaode.model.GaoDeDistrictResult;
import com.qiangesoft.district.service.ISysAreaService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 区域数据
 *
 * @author qiangesoft
 * @date 2023-07-18
 */
@Slf4j
@Component
public class AreaTask {

    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private ISysAreaService sysAreaService;

    /**
     * 每天10点执行一次
     */
    @Scheduled(cron = "0 0 10 * * ?")
    public void pullArea() {
        log.info("Update area data begin==================>");
        long startTime = System.currentTimeMillis();

        StringBuilder sendUrl = new StringBuilder(DistrictConstant.DISTRICT_URL)
                .append("?key=").append(GaoDeApi.KEY_VALUE)
                .append("&keywords=").append(DistrictConstant.ZQ_KEYWORD_VALUE)
                .append("&subdistrict=4&extensions=base");
        ResponseEntity<GaoDeDistrictResult> responseEntity = restTemplate.getForEntity(sendUrl.toString(), GaoDeDistrictResult.class);
        // 请求异常,可能由于网络等原因
        HttpStatus statusCode = responseEntity.getStatusCode();
        if (!HttpStatus.OK.equals(statusCode)) {
            log.info("Request for Gaode interface error");
            return;
        }

        // 请求失败
        GaoDeDistrictResult gaoDeDistrictResult = responseEntity.getBody();
        String status = gaoDeDistrictResult.getStatus();
        if (!status.equals(GaoDeApi.SUCCESS)) {
            log.info("Request for Gaode interface failed");
            return;
        }

        // 请求无数据
        List<District> districts = gaoDeDistrictResult.getDistricts();
        if (CollectionUtils.isEmpty(districts)) {
            log.info("Request for Gaode interface no data");
            return;
        }

        // 保存数据
        this.saveData(districts, null);

        long endTime = System.currentTimeMillis();
        log.info("spend time:" + (endTime - startTime));
        log.info("Update area data end<==================");
    }

    /**
     * 保存数据
     *
     * @param districts
     * @param parentId
     */
    private void saveData(List<District> districts, Long parentId) {
        if (CollectionUtils.isEmpty(districts)) {
            return;
        }

        // 排序
        districts.sort(Comparator.comparing(District::getAdcode));
        // 国家一级特殊处理
        if (parentId == null) {
            districts = districts.stream().filter(e -> RegionLevelEnum.COUNTRY.getCode().equals(e.getLevel())).collect(Collectors.toList());
        }

        // 执行保存
        List<SysArea> areaList = new ArrayList<>();
        for (District district : districts) {
            SysArea sysArea = new SysArea();
            sysArea.setCode(district.getAdcode());
            sysArea.setAreaCode(district.getCitycode().toString());
            sysArea.setName(district.getName());
            sysArea.setFullName(district.getName());
            sysArea.setSortValue(1);
            String center2 = district.getCenter();
            if (StringUtils.isNotBlank(center2)) {
                String[] split = center2.split(",");
                sysArea.setLongitude(split[0]);
                sysArea.setLatitude(split[1]);
            }
            String level = RegionLevelEnum.getCodeByDes(district.getLevel());
            sysArea.setLevel(level);
            sysArea.setDelFlag(false);
            sysArea.setParentId(parentId);
            areaList.add(sysArea);
        }
        sysAreaService.saveBatch(areaList);

        // 下级
        for (int i = 0; i < districts.size(); i++) {
            District district = districts.get(i);
            List<District> children = district.getDistricts();
            if (!CollectionUtils.isEmpty(children)) {
                this.saveData(children, areaList.get(i).getId());
            }
        }
    }

}
package com.qiangesoft.district.gaode.model;

import java.util.Arrays;
import java.util.List;

/**
 * 行政区划常量
 *
 * @author qiangesoft
 * @date 2023-08-10
 */
public class DistrictConstant {
    /**
     * 行政区划接口地址
     */
    public static final String DISTRICT_URL = "https://restapi.amap.com/v3/config/district";

    /**
     * key
     */
    public static final String KEY = "key";

    /**
     * 搜索关键词支持:行政区名称、citycode、adcode
     */
    public static final String KEYWORDS = "keywords";

    /**
     * 子级行政区
     * 可选值:0、1、2、3等数字,并以此类推
     * 0:不返回下级行政区;
     * 1:返回下一级行政区;
     * 2:返回下两级行政区;
     * 3:返回下三级行政区;
     */
    public static final String SUBDISTRICT = "subdistrict";

    /**
     * 需要第几页数据
     */
    public static final String PAGE = "page";

    /**
     * 最外层返回数据个数
     */
    public static final String OFFSET = "offset";

    /**
     * 此项控制行政区信息中返回行政区边界坐标点; 可选值:base、all;
     * base:不返回行政区边界坐标点;
     * all:只返回当前查询district的边界值,不返回子节点的边界值;
     */
    public static final String EXTENSIONS = "extensions";

    /**
     * 按照指定行政区划进行过滤,填入后则只返回该省/直辖市信息
     * 填入adcode,为了保证数据的正确,强烈建议填入此参数
     */
    public static final String FILTER = "filter";

    /**
     * callback值是用户定义的函数名称,此参数只在output=JSON时有效
     */
    public static final String CALLBACK = "callback";

    /**
     * 可选值:JSON,XML
     */
    public static final String OUTPUT = "output";

    /**
     * 省份关键字列表
     */
    public static final List<String> ZQ_KEYWORD_VALUE = Arrays.asList("中华人民共和国");
    public static final List<String> KEYWORDS_VALUE = Arrays.asList("河北省", "山西省", "辽宁省", "吉林省", "黑龙江省", "江苏省", "浙江省", "安徽省", "福建省",
            "江西省", "山东省", "河南省", "湖北省", "湖南省", "广东省", "海南省", "四川省", "贵州省", "云南省", "陕西省", "甘肃省", "青海省", "台湾省",
            "内蒙古自治区", "广西壮族自治区", "西藏自治区", "宁夏回族自治区", "新疆维吾尔自治区", "北京市", "天津市", "上海市", "重庆市", "香港特别行政区", "澳门特别行政区");

    /**
     * 香港澳门台湾特殊处理
     */
    public static final List<String> TSKEYWORDS_VALUE = Arrays.asList("台湾省", "香港特别行政区", "澳门特别行政区");
}


package com.qiangesoft.district.gaode;

/**
 * 高德API
 *
 * @author qiangesoft
 * @date 2023-07-18
 */
public class GaoDeApi {
    /**
     * 成功标志
     */
    public static final String SUCCESS = "1";

    /**
     * 请求key
     */
    public static final String KEY_VALUE = "eea81fd695ceeda7bdab6d3e98ecc2ed";
}

package com.qiangesoft.district.gaode.model;

import lombok.Data;

import java.util.List;

/**
 * 高德数据结果
 *
 * @author qiangesoft
 * @date 2023-07-18
 */
@Data
public class GaoDeDistrictResult {
    /**
     * 返回结果状态值
     */
    private String status;
    /**
     * 返回状态说明
     */
    private String info;
    /**
     * 状态码
     */
    private String infocode;
    /**
     * 查询个数
     */
    private String count;
    /**
     * 建议结果列表
     */
    private Suggestion suggestion;
    /**
     * 区域信息
     */
    private List<District> districts;

}
package com.qiangesoft.district.gaode.model;

import lombok.Data;

import java.util.List;

/**
 * 行政区信息
 *
 * @author qiangesoft
 * @date 2023-07-18
 */
@Data
public class District {
    /**
     * 城市编码
     */
    private Object citycode;
    /**
     * 区域编码
     */
    private String adcode;
    /**
     * 行政区名称
     */
    private String name;
    /**
     * 行政区边界坐标点
     */
    private String polyline;
    /**
     * 区域中心点
     */
    private String center;
    /**
     * 行政区划级别
     * country:国家
     * province:省份(直辖市会在province和city显示)
     * city:市(直辖市会在province和city显示)
     * district:区县
     * street:街道
     */
    private String level;
    /**
     * 下级区域
     */
    private List<District> districts;
}
package com.qiangesoft.district.entity;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.io.Serializable;
import java.util.Date;

/**
 * 地区对象 sys_area
 *
 * @author qiangesoft
 * @date 2023-04-25
 */
@Data
@EqualsAndHashCode(callSuper = false)
public class SysArea implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * id
     */
    private Long id;

    /**
     * 行政级别
     */
    @TableField(value = "level_")
    private String level;

    /**
     * 父ID
     */
    private Long parentId;

    /**
     * 行政区划代码
     */
    private String code;

    /**
     * 区号
     */
    private String areaCode;

    /**
     * 名称
     */
    private String name;

    /**
     * 全名
     */
    private String fullName;

    /**
     * 排序
     */
    private Integer sortValue;

    /**
     * 经度
     */
    private String longitude;

    /**
     * 维度
     */
    private String latitude;

    /**
     * 删除标志
     */
    private Boolean delFlag;

    /**
     * 创建时间
     */
    @TableField(fill = FieldFill.INSERT)
    private Date createTime;

    /**
     * 创建人
     */
    @TableField(fill = FieldFill.INSERT)
    private Long createBy;

    /**
     * 更新时间
     */
    @TableField(fill = FieldFill.UPDATE)
    private Date updateTime;

    /**
     * 更新人
     */
    @TableField(fill = FieldFill.UPDATE)
    private Long updateBy;
}

三、源码仓库

源码地址:https://gitee.com/qiangesoft/boot-business/tree/master/boot-business-district

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/364005.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

揭秘2023年全球软件架构师峰会:引领未来的技术潮流与PPT宝藏!

随着科技的不断进步和创新&#xff0c;全球软件架构师峰会&#xff08;ArchSummit深圳站&#xff09;作为国际知名的技术交流盛会&#xff0c;再次吸引了全球顶尖的软件架构师和技术领袖齐聚一堂。 本次峰会不仅展示了最前沿的技术动态&#xff0c;更为参与者带来了极具价值的…

202415读书笔记|《鲸鱼安慰了大海》——我不知道你爱不爱我 湖水想被青山拥在怀里

202415读书笔记|《鲸鱼安慰了大海》——我不知道你爱不爱我 湖水想被青山拥在怀里 辑一 我们一起站在山坡上开花辑二 野花唱歌给自己听辑三 星空给我留了位置后记 《鲸鱼安慰了大海》作者燕七&#xff0c;是在一个关注的友友那里知道的这本书&#xff0c;决定读下去&#xff0c…

C++(17.5)——list模拟实现扩展

在上篇文章中&#xff0c;实现了的大部分功能以及部分迭代器。本片文章将对剩下的功能进行补充。 1. const迭代器&#xff1a; 对于上篇文章中实现的迭代器只能使用于非类型的对象。对于类型的遍历&#xff0c;则需要额外编写类型的迭代器。例如对于下面的场景&#xff1a; …

Yolo v8 入门学习之采用 coco128 数据集进行图片检测测试

示例入门代码 from ultralytics import YOLO import cv2 import matplotlib.pyplot as plt import matplotlib.image as mpimgdef test():# Create a new YOLO model from scratchmodel YOLO(yolov8n.yaml)# Load a pretrained YOLO model (recommended for training)model …

在Windows系统中执行DOS命令

目录 一、用菜单的形式进入DOS窗口 二、通过IE浏览器访问DOS窗口 三、复制、粘贴命令行 四、设置窗口风格 1.颜色 2.字体 3.布局 4.选项 五、Windows系统命令行 由于Windows系统彻底脱离了DOS操作系统&#xff0c;所以无法直接进入DOS环境&#xff0c;只能通过第三方软…

从零开始 Linux(一):基础介绍与常用指令总结

从零开始 Linux 01. 概念理解 1.1 什么是 Linux&#xff1f; Linux 是一个开源免费的 操作系统&#xff0c;具有很好的稳定性、安全性&#xff0c;且有很强的处理高并发的能力 Linux 的应用场景&#xff1a; 可以在 Linux 下开发项目&#xff0c;比如 JavaEE、大数据、Python…

css多行文本擦拭效果

<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>多行文本擦拭效果</title><style>* …

QT SQL

QT SQL模块提供数据库编程的支持&#xff0c;支持多种常见的数据库&#xff1a;MySQL\Oracle\MS SQL Server\SQLite等。SQL模块包含多个类&#xff0c;可以实现&#xff1a;数据库连接、SQL语句执行、数据获取与界面显示 等功能。数据 与 界面间用Model\View架构。 一、 二、Q…

网络服务综合实验项目

目录 实验要求 运行环境 基础配置 业务需求 实验步骤 一、基础配置 1.1、配置静态IP 1.1.1、 在192.168.159.130中配置 1.1.2、 在192.168.159.131中配置 ​编辑 1.2、修改主机名及hosts映射 1.2.1、在192.168.159.130中配置 1.2.2、 编辑配置hosts文件 1.2.3、重启…

用的到的linux-文件移动-Day2

前言&#xff1a; 在上一节&#xff0c;我们复习了cd大法和创建生成文件和文件夹的方法&#xff0c;介绍了一些“偷懒”&#xff08;高效&#xff09;的小技巧&#xff0c;本节&#xff0c;我们一起来探讨下&#xff0c;我们对文件移动操作时有哪些可以偷懒的小技巧~ 一、复制…

社科院与杜兰大学金融管理硕士项目——金融硕士学位证书有多重要呢

随着金融行业的快速发展&#xff0c;金融管理硕士项目逐渐成为越来越多人追求高学历和提升职业竞争力的选择。其中&#xff0c;社科院与杜兰大学合作的金融管理硕士项目备受关注。然而&#xff0c;对于很多人来说&#xff0c;花费大量的时间和金钱去攻读一个硕士学位是否值得呢…

前端开发实战基础——模块

文章目录 概要模块标识符模块依赖模块加载入口 CommonJS语法单例 AMD语法 UMD核心语法 ES6模块化模块标签及定义模块导出和导入命名导出和导入默认导出和导入命名导出和默认导出混用 模块行为 小结 概要 模块化&#xff0c;就是将代码拆分成独立的块&#xff0c;各自在代码块中…

小白初探|神经网络与深度学习

一、学习背景 由于工作的原因&#xff0c;需要开展人工智能相关的研究&#xff0c;虽然不用参与实际研发&#xff0c;但在项目实施过程中发现&#xff0c;人工智能的项目和普通程序开发项目不一样&#xff0c;门槛比较高&#xff0c;没有相关基础没法搞清楚人力、财力如何投入&…

Linux实验记录:使用Apache的虚拟主机功能

前言&#xff1a; 本文是一篇关于Linux系统初学者的实验记录。 参考书籍&#xff1a;《Linux就该这么学》 实验环境&#xff1a; VmwareWorkStation 17——虚拟机软件 RedHatEnterpriseLinux[RHEL]8——红帽操作系统 正文&#xff1a; 目录 前言&#xff1a; 正文&…

每日一道Java面试题:说一说Java中的泛型?

写在开头 今天的每日一道Java面试题聊的是Java中的泛型&#xff0c;泛型在面试的时候偶尔会被提及&#xff0c;频率不是特别高&#xff0c;但在日后的开发工作中&#xff0c;却是是个高频词汇&#xff0c;因此&#xff0c;我们有必要去认真的学习它。 泛型的定义 什么是泛型…

2024年1月的论文推荐

又到月底了&#xff0c;在月初推荐论文的基础上又整理了10篇推荐阅读的论文 1、MosaicBERT https://mosaicbert.github.io/ 一种用于快速预训练的双向编码器。MosaicBERT是针对快速预训练优化的自定义BERT架构。主要架构修改:FlashAttention, ALiBi&#xff0c;门控线性单元…

(八)MySQL事务和SQL优化

事务&#xff08;Transaction&#xff09;&#xff1a; 是数据库内最小且不可再分的单元。通常一个事务对应一个完整的业务(例如银行账户转账业务&#xff0c;该业务就是一个最小的工作单元)。一个完整的业务由批量的DML语句&#xff08;INSERT 、UPDATE、DELETE&#xff09;共…

pinctrl子系统与gpio子系统实验-通过应用程序测试Led驱动程序

一. 简介 前面几篇文章基本完成了 Led驱动代码&#xff0c;前面通过加载驱动模块也测试了 驱动程序。 这里通过运行应用程序&#xff0c;通过应用程序调用 Led驱动程序&#xff0c;从而驱动 打开或者关闭 Led灯。 二. 通过应用程序测试Led驱动程序 1. 驱动代码实现 gpiole…

【Qt】—— 项⽬⽂件解析

目录 &#xff08;一&#xff09;.pro⽂件解析 &#xff08;二&#xff09;widget.h⽂件解析 &#xff08;三&#xff09;main.cpp⽂件解析 &#xff08;四&#xff09;widget.cpp⽂件解析 &#xff08;五&#xff09;widget.ui⽂件解析 &#xff08;一&#xff09;.pro⽂…

Sg5032can(晶体振荡器spxo)规格书

SG5032CAN是爱普生推出的一款小体积尺寸5.0x3.2mm石英晶体振蒎器&#xff0c;四脚贴片晶振&#xff0c;输出频率范围为4MHz~72MHz,电源电压1.8V ~ 3.3V&#xff0c;支持CMOS输出&#xff0c;具有超小型&#xff0c;轻薄型&#xff0c;高精度&#xff0c;高性能&#xff0c;高品…