SpringBoot拉取高德行政区域数据

news2024/11/16 7:41:47

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

js padEnd方法介绍笔记

padEnd() 是 JavaScript 字符串的方法之一&#xff0c;它用于在当前字符串的末尾添加指定数量的字符&#xff0c;直到字符串达到指定的长度。 padEnd() 方法接受两个参数&#xff1a; 目标长度和要添加的填充字符。 如果当前字符串的长度已经等于或超过目标长度&#xff0c;则不…

你应该仅仅把useMemo作为性能优化的手段

文章概叙 本文主要通过几个简单的例子&#xff0c;讲解下useMemo这个hook&#xff0c;给诸君参考&#xff0c;也是给我自己做一个记录 关于useMemo useMemo是一个React Hook&#xff0c;它在每次重新渲染的时候能够缓存计算的结果。 相比于其他很常用的hook&#xff0c;如u…

LPC804开发(7.SPI使用)

1.前言 原本说写ADC&#xff0c;但是考虑到6已经给了串口&#xff0c;算了算了&#xff0c;还是把SPI和IIC放到7和8吧。整体用下来感觉NXP的协议比ST和TI开发的完善的&#xff0c;都可以走硬件&#xff0c;比较完善的底层开发&#xff0c;没有硬伤&#xff0c;那么接下来我们来…

教你一招轻松把模糊的照片变高清

亲爱的朋友们&#xff0c;你们是否也曾经遇到过这样的问题——精心拍摄的照片或珍藏已久的图片突然变得模糊不清&#xff0c;让人心情郁闷&#xff1f;别担心&#xff0c;我发现了解决这个问题的秘诀&#xff01;借助一些专业的图片修复工具&#xff0c;那些模糊的瞬间可以重新…

react实现滚动到顶部组件

新建ScrollToTop.js import React, { useState, useEffect } from react; import ./ScrollToTop.css;function ScrollToTop() {const [isVisible, setIsVisible] useState(true);// Show button when page is scorlled upto given distanceconst toggleVisibility () > {…

一分钟在SpringBoot项目中使用EMQ

先展示最终的结果: 生产者端: RestController RequiredArgsConstructor public class TestController {private final MqttProducer mqttProducer;GetMapping("/test")public String test() {User build User.builder().age(100).sex(1).address("世界潍坊渤…

Wireshark网络协议分析 - UDP协议

在我的博客阅读本文 文章目录 1. 基础2. 实战2.1. 用Go写一个简单的UDP服务器与客户端2.2. Wireshark抓包分析 3. UDP与TCP的区别4. 参考资料 1. 基础 UDP包的数据结构&#xff1a; 2. 实战 2.1. 用Go写一个简单的UDP服务器与客户端 我们这里使用Golang写了一个简单的9830端…

docker由浅入深

一、什么是docker docker 顾名思义就是轮船的意思&#xff0c;轮船我们知道是通过集装箱运载货物的东西&#xff0c;那么docker其实也是类似的东西&#xff0c;只是装载的是虚拟的运行程序罢了。其中集装箱在docker里面被称为container&#xff08;后面以容器称之&#xff09;…

林浩然的Python奇遇记:从小白到科学界的编程魔法师

林浩然的Python奇遇记&#xff1a;从小白到科学界的编程魔法师 Lin Haoran’s Python Adventure: From Novice to Programming Sorcerer in the Scientific Realm 在那个平凡的午后&#xff0c;我们的主角林浩然——一个对编程一窍不通但对世界充满好奇的物理学大二学生&#x…

qiankun子应用静态资源404问题有效解决(遇到了http请求静态文件404、css文件引用图片无法显示、svg图片转换成 base64无法显示等问题)

在&#x1f449;&#x1f3fb; qiankun微前端部署&#x1f448;&#x1f3fb;这个部署方式的前提下&#xff0c;遇到的问题并解决问题的过程 >> 问题现象 通过http请求本地的静态json文件404 css中部分引入的图片无法显示 >> 最开始的解决方式 在&#x1f449;…

Linux第36步_创建正点原子的TF-A工作区

创建正点原子的TF-A工作区&#xff0c;目的是想查看正点原子的设备树文件“stm32mp157d-atk.dts”和设备树头文件“stm32mp157d-atk.dtsi”&#xff0c;了解设备树是什么样子&#xff0c;为后期基于“ST公司的源码”创建自己的设备树提供参考&#xff0c;同时也是为了学习移植u…

飞桨大模型分布式训练技术

今天我为大家介绍飞桨大模型分布式训练技术&#xff0c;内容分为以下几个部分&#xff1a; 首先&#xff0c;我会介绍大模型训练面临的重点难题&#xff1b;然后&#xff0c;为大家介绍飞桨在大模型训练领域的特色分布式训练技术和优化方案&#xff1b;最后&#xff0c;伴随着…

NeRF:神经辐射场复杂场景的新视图合成技术

NeRF&#xff1a;神经辐射场复杂场景的新视图合成技术 NeRF&#xff1a;神经辐射场复杂场景的新视图合成技术项目背景与意义如何运行&#xff1f;快速开始更多数据集 预训练模型方法与实现结语服务 NeRF&#xff1a;神经辐射场复杂场景的新视图合成技术 在计算机视觉领域&…

工业物联网网关如何实现工业设备的远程运维?-天拓四方

随着工业4.0和智能制造的快速发展&#xff0c;工业设备的远程运维已经成为提高企业生产效率和降低运营成本的重要手段。工业物联网网关作为这一过程中的关键组件&#xff0c;发挥着不可或缺的作用。本文将重点探讨工业物联网网关如何实现工业设备的远程运维&#xff0c;并结合实…

网络和Linux网络_15(IO多路转接)reactor编程_服务器+相关笔试题

目录 1. reactor的服务器 1.1 Sock.hpp 1.2 加协议分割报文 1.3 序列化和反序列化 Protocol.hpp main.cc Epoll.hpp TcpServer.hpp 2. 相关笔试题 答案及解析 本篇完。 1. reactor的服务器 Log.hpp和以前一样&#xff0c;因为下面要写ET模式所以Sock.hpp加了一个把…

[Python] 什么是集成算法,什么是随机森林?随机森林分类器(RandomForestClassifier)及其使用案例

什么是集成算法&#xff1f; 集成算法是一种机器学习方法&#xff0c;它将多个基本的学习算法&#xff08;也称为弱学习器&#xff09;组合在一起&#xff0c;形成一个更强大的预测模型。集成算法通过对基本模型的预测进行加权平均或多数投票等方式&#xff0c;来产生最终的预…

【Leetcode】两数之和

目录 题目&#xff1a; 解法1&#xff1a;暴力双for 1.想到的第一种方法两for循环解 复杂度分析 解法2&#xff1a;hash表 总结&#xff1a; 笔记&#xff1a; 题目&#xff1a; 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标…

简单区间DP

文章目录 什么是区间DpAcWing 282. 石子合并题意分析思路解析状态表示状态计算 CODE需要注意的问题 什么是区间Dp 区间Dp指的是某些问题可以用区间来划分解决。 AcWing 282. 石子合并 题目链接&#xff1a;穿梭时间的画面的钟 题意分析 从一排石子中选择相邻的两堆进行合并…

2024-01-25 力扣高频SQL50题目1193每月交易

1.1193每月交易 1 count可以这样用。。 COUNT(IF(state approved, 1, NULL)) AS approved_count 如果 COUNT(if(state approved,1,0))&#xff0c;这里变成0&#xff0c;就不对了。因为count计数时候&#xff0c;只要里面不是null&#xff0c;就会算进去。 sum(if(state …

(学习日记)2024.01.27

写在前面&#xff1a; 由于时间的不足与学习的碎片化&#xff0c;写博客变得有些奢侈。 但是对于记录学习&#xff08;忘了以后能快速复习&#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位&#xff0c;以时间为顺序&#xff0c;仅仅将博客当做一个知识学习的目录&a…