基于ApachePOI实现高德POI分类快速导入PostgreSQL数据库实战

基于ApachePOI实现高德POI分类快速导入PostgreSQL数据库实战

目录

前言

一、高德POI分类简介

1、数据表格

2、分类结构

二、从Excel导入到Postgresql

1、Excel解析流程

2、Mybatis批量导入

3、数据入库

三、总结


前言

        在大数据与地理信息深度交融的当下,地理信息系统(GIS)的触角已延伸至各个领域,为行业决策提供精准的空间数据支撑。而 POI(Point of Interest,兴趣点)分类数据,作为 GIS 数据的细分瑰宝,正发挥着独特且关键的作用。高德地图所涵盖的丰富 POI 分类数据,如美食、电影院、酒店、购物场所等,宛如一座有待深度挖掘的宝藏,对商业选址、城市规划、旅游服务等行业有着不可估量的价值。

        以商业领域为例,掌握准确的美食分类 POI 数据,能助力餐饮企业洞察竞争对手分布、分析区域市场潜力,为新店选址提供科学依据;而电影院分类数据则可辅助院线优化布局,甚至为周边配套商业设施的规划提供参考。但目前,要将这些高德 POI 分类数据高效整合到分析系统中并非易事。一方面,高德提供的 POI 分类数据获取往往存在一定限制和规则,开发者需要巧妙设计数据采集策略;另一方面,采集后的数据多存储于 Excel 表格中,格式多样且字段特性各异,要将其批量、快速且准确地导入到数据库,实现与信息系统无缝对接,是一道亟待攻克的技术难关。

        PostgreSQL 凭借其卓越的开源特性和对地理空间数据的强大支持能力,成为众多开发者存储和管理 POI 分类数据的首选数据库。而 ApachePOI 则是 Java 开发领域处理 Excel 文件的得力工具。本实战将聚焦于如何运用 ApachePOI,将高德 POI 分类数据(美食、电影院等类别)从 Excel 快速导入到 PostgreSQL 数据库的全过程。

        在此过程中,我们将深入剖析 Excel 中 POI 分类数据的存储结构特点,针对美食、电影院等不同分类数据字段特性,制定对应的映射规则与转换策略,还将着重探索如何优化导入流程,提升数据导入效率,减少系统资源消耗。通过本次实战,不仅能为开发者揭开高德 POI 分类数据导入的神秘面纱,也为各类基于 POI 分类数据的地理信息系统开发、商业智能分析以及城市规划应用等,铺设一条从数据获取到存储利用的高效路径,助力行业在空间数据赋能下实现精准决策与创新发展。

一、高德POI分类简介

        本节将首先重点介绍高德地图的POI分类信息,在之前的博客中我们设计了用于POI管理的物理表,希望可以用来存储对应的POI分类信息。然后使用数据库脚本的方法对POI分类信息进行录入管理。而对于高德地图而言,其POI的分类是非常详细的,因此这一节我们来详细的解读一下高德的POI分类,让大家对分类信息有进一步的了解,为下一步数据的批量解析入库打下牢固的基础。

1、数据表格

        大家可以从高德的地图开放平台中获取其最新的POI分类的Excel表格,这里我将从官网下载的类型截取一部分给大家参考,数据表格一共有32页太多,这里不进行赘述,需要原始Excel表格的,可以去网站上下载。

        在Excel表格中,一共提供了8个关键信息,分别是:

序号字段名说明
1序号数据的序号,如:1
2NEW_TYPEPOI分类编码,如:010000
3大类POI大类,如:汽车服务
4中类POI中类,如:加油站
5小类POI小类,如:中国石化
6Big CategoryPOI大类英文,如:Auto Service
7Mid  CategoryPOI中类英文,如:Filling Station
8Sub CategoryPOI小类英文,如:Sinopec

         从上面的数据表格和字段信息介绍可以知道,高德地图的POI分类按照类别分成大、中、小分成了三类,同时有对应的英文类别说明。同样的,基于高德地图的POI检索可以从返回接口中看到其对应的POI分类值为:

{ "address": "茶子山路与银杉路交叉口东北60米", "business": { "opentime_today": "17:00-01:00", cost": "61.00", "keytag": "大排档", "rating": "4.5", "business_area": "湘江新区", "tel": "15873178255", "tag": "大排档", "rectag": "大排档", "opentime_week": "周一至周日 17:00-01:00" }, "pcode": "430000", "adcode": "430104", "pname": "湖南省", "cityname": "长沙市", "type": "餐饮服务;中餐厅;中餐厅", "typecode": "050100", "adname": "岳麓区", "citycode": "0731", "navi": { "navi_poiid": "H49F046040_387534", "gridcode": "4212278620" }, "name": "二五八大排档(茶子山路店)", "indoor": { "indoor_map": "0" }, "location": "112.952067,28.241331", "id": "B0FFIK20N1" }

        其中type和typecode分别对应poi分类的类别和poi编码,需要注意的是,调用高德地图返回的POI中,POI分类都是返回到了小类。 

2、分类结构

        在了解了高德地图的POI分类之后,下面我们基于之前设计的数据库物理表和分类信息构建树形的信息,为了方便在后面的查询中可以根据POI的大类、中类、小类来进行查询。就不能直接存储小类,而需要对其分类采取细致的分类管理。在进行树形层次构建时,我们根据编码来进行统一管理:

        这个结构是其编码分类的基础,也是后面的数据程序解析的基础。我们将使用编码来进行三级分类的解析及入库。 在Excel中,很大的大类和种类都是重复的,因此需要在入库时将类别进行去重分类,最终构建一棵完整的POI分类树。

二、从Excel导入到Postgresql

        本节将详细介绍在Java中使用ApachePOI实现从Excel中解析到存储至PostgreSQL中,主要包含两个方面,第一个是如何结合POI分类的规则进行分类解析。第二个方面是如何基于Mybatis实现程序的批量入库。完整的数据处理流程如下:

1、Excel解析流程

        在进行POI的分类进行构建尤其重要,为了防止各层级在构建时出现重复的情况,这里采用LinkedHashMap集合来进行重复判断,在存储集合对象时,将分类编码作为map的key,而具体分类对象作为value。在后续的对象去重判断时,key就是重复的标记。为了实现Excel数据的导入,需要定义一个JavaBean来读取数据,其关键代码如下:

package com.yelang.project.poisubject.poi.domain; import java.io.Serializable; import com.yelang.framework.aspectj.lang.annotation.Excel; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; /** * - 高德POI分类Excel视图对象 * @author 夜郎king */ @Data @AllArgsConstructor @NoArgsConstructor public class AmapPoiCategoryExcelVO implements Serializable{ private static final long serialVersionUID = 2795552725033725828L; @Excel(name = "NEW_TYPE") private String poiType;//高德的POI类 @Excel(name = "大类") private String bigCategory;//中文大类 @Excel(name = "中类") private String midCategory;//中文中类 @Excel(name = "小类") private String subCategory;//中文小类 @Excel(name = "Big Category") private String bigCategoryEn;//英文大类 @Excel(name = "Mid Category") private String midCategoryEn;//英文中类 @Excel(name = "Sub Category") private String subCategoryEn;//英文小类 }

         接下来读取Excel的数据,按照分类对高德POI分类进行层级重建,核心代码如下:

File file = new File(AMAP_POI_FILE); FileInputStream fis = new FileInputStream(file); ExcelUtil<AmapPoiCategoryExcelVO> util = new ExcelUtil<AmapPoiCategoryExcelVO>(AmapPoiCategoryExcelVO.class); List<AmapPoiCategoryExcelVO> dataList = util.importExcel(fis); LinkedHashMap<String,PoiCategory> amapPoiTypeMap = new LinkedHashMap<String, PoiCategory>(); for(AmapPoiCategoryExcelVO poiCategory : dataList) { String type = poiCategory.getPoiType(); String bigCategory = poiCategory.getBigCategory(); String midCategory = poiCategory.getMidCategory(); String subCategory = poiCategory.getSubCategory(); String bigCategoryEn = poiCategory.getBigCategoryEn(); String midCategoryEn = poiCategory.getBigCategoryEn(); String subCategoryEn = poiCategory.getSubCategoryEn(); String bigCategorySno = type.substring(0, 2); String midCategorySno = type.substring(0, 4); //不包含大类,添加到集合中 if(!amapPoiTypeMap.containsKey(bigCategorySno)) { PoiCategory category = new PoiCategory(IdWorker.getId(),101L,"0,100,101",bigCategory,bigCategoryEn,bigCategorySno); amapPoiTypeMap.put(bigCategorySno, category); } //不包含中类,添加到集合中 if(!amapPoiTypeMap.containsKey(midCategorySno)) { String parentKey = midCategorySno.substring(0, 2); PoiCategory parentCategory = amapPoiTypeMap.get(parentKey); String ancestors = parentCategory.getAncestors() + "," + parentCategory.getPkId(); PoiCategory category = new PoiCategory(IdWorker.getId(),parentCategory.getPkId(),ancestors,midCategory,midCategoryEn,midCategorySno); amapPoiTypeMap.put(midCategorySno, category); } //不包含小类,添加到集合中 if(!amapPoiTypeMap.containsKey(type)) { String parentKey = midCategorySno.substring(0, 4); PoiCategory parentCategory = amapPoiTypeMap.get(parentKey); String ancestors = parentCategory.getAncestors() + "," + parentCategory.getPkId(); PoiCategory category = new PoiCategory(IdWorker.getId(),parentCategory.getPkId(),ancestors,subCategory,subCategoryEn,type); amapPoiTypeMap.put(type, category); } }

2、Mybatis批量导入

        基于Mybatis的批量导入,这里介绍基于Xml的批量操作,需要在创建的Mapper.xml文件中定义以下内容:

<insert parameterType="java.util.List"> insert into biz_poi_category ( pk_id,parent_id,category_name,ancestors,order_num,origin_code,category_english_name,platform,status,del_flag,create_time) values <foreach collection="list" item="item" separator=","> ( #{item.pkId},#{item.parentId},#{item.categoryName},#{item.ancestors}, #{item.orderNum},#{item.originCode},#{item.categoryEnglishName},#{item.platform},#{item.status},#{item.delFlag}, now() ) </foreach> </insert>

        在Mapper及业务逻辑层的批量保存方法比较简单,这里提供业务层的一个简单调用示例:

/** * - 批量插入POI目录信息 * @param list */ @Override public void batchInsertPoiCategory(List<PoiCategory> list) { this.poiCategoryMapper.batchInsertPoiCategory(list); }

3、数据入库

        在数据入库之前,需要统一设置数据来源,如标记高德,设置删除标记、数据业务状态、数据创建时间等,这些都是非常重要的,设置公共数据后就可以调用之前提供的批量入库的方法进行插入数据库操作,关键方法如下所示:

List<PoiCategory> categoryData = new ArrayList<PoiCategory>(); for (PoiCategory value : amapPoiTypeMap.values()) { value.setPlatform("gaode"); value.setDelFlag(0); value.setStatus(0); value.setOrderNum(1); value.setCreateTime(DateUtils.getNowDate()); categoryData.add(value); } //数据入库 poiCateGoryService.batchInsertPoiCategory(categoryData); System.out.println("finished...");

        完成以上的操作后就完成了高德POI分类数据的Postgresql数据库导入操作,导入完成后就可以在数据库中查看,如下图所示:

        支持,完全实现基于ApachePoi的高德POI分类数据导入处理操作。 

三、总结

        以上就是本文的主要内容,在本文中我们将深入剖析 Excel 中 POI 分类数据的存储结构特点,针对美食、电影院等不同分类数据字段特性,制定对应的映射规则与转换策略,还将着重探索如何优化导入流程,提升数据导入效率,减少系统资源消耗。通过本次实战,不仅能为开发者揭开高德 POI 分类数据导入的神秘面纱,也为各类基于 POI 分类数据的地理信息系统开发、商业智能分析以及城市规划应用等,铺设一条从数据获取到存储利用的高效路径,助力行业在空间数据赋能下实现精准决策与创新发展。行文仓促,难免有许多不足之处,如有不足,在此恳请各位专家博主在评论区不吝留言指出,不胜感激。

Read more

Spring Boot 消息队列与异步通信

Spring Boot 消息队列与异步通信

Spring Boot 消息队列与异步通信 21.1 学习目标与重点提示 学习目标:掌握Spring Boot消息队列与异步通信的核心概念与使用方法,包括消息队列的定义与特点、Spring Boot与ActiveMQ的集成、Spring Boot与RabbitMQ的集成、Spring Boot与Kafka的集成、Spring Boot异步通信的基本方法、Spring Boot的实际应用场景,学会在实际开发中处理消息队列与异步通信问题。 重点:消息队列的定义与特点、Spring Boot与ActiveMQ的集成、Spring Boot与RabbitMQ的集成、Spring Boot与Kafka的集成、Spring Boot异步通信的基本方法、Spring Boot的实际应用场景。 21.2 消息队列概述 消息队列是Java开发中的重要组件。 21.2.1 消息队列的定义 定义:消息队列是一种异步通信机制,用于在应用程序之间传递消息。 作用: * 实现应用程序之间的异步通信。 * 实现应用程序之间的解耦。 * 提高应用程序的性能。 常见的消息队列: * Activ

By Ne0inhk
【案例实战】鸿蒙分布式智能办公应用的架构设计与性能优化

【案例实战】鸿蒙分布式智能办公应用的架构设计与性能优化

目录 一、项目背景与挑战 项目概述 1.1 面临的技术挑战 二、分布式架构设计 2.1 整体架构概览 2.2 组件化设计 2.3 分布式通信机制 三、性能优化实战 3.1 UI渲染优化 3.1.1 虚拟列表实现 3.1.2 懒加载和预加载策略 3.2 内存管理优化 3.2.1 内存泄漏检测与修复 3.2.2 对象池与资源复用 3.3 启动性能优化 四、鸿蒙开放能力接入 4.1 云开发能力集成

By Ne0inhk
Flutter 组件 flutterw_sidekick_plugin 适配鸿蒙 HarmonyOS 实战:侧翼脚手架扩展,构建工程自动化与环境一致性治理架构

Flutter 组件 flutterw_sidekick_plugin 适配鸿蒙 HarmonyOS 实战:侧翼脚手架扩展,构建工程自动化与环境一致性治理架构

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 组件 flutterw_sidekick_plugin 适配鸿蒙 HarmonyOS 实战:侧翼脚手架扩展,构建工程自动化与环境一致性治理架构 前言 在鸿蒙(OpenHarmony)生态迈向大规模团队协作、涉及多分支并行开发及复杂的 SDK 版本管控的背景下,如何确保每一位开发者的本地构建环境(Flutter/Dart SDK)与生产基准完全对齐,已成为保障项目交付质量的“工程定海神针”。在鸿蒙设备这类强调定制化编译工具链与私有插件依赖的环境下,如果团队缺乏统一的脚手架工具,由于由于本地 SDK 版本的微小代差(如空安全检测差异),极易由于由于“环境不一致”导致代码在不同机器上产生不可预知的编译崩溃。 我们需要一种能够深度集成 Sidekick、支持自定义命令扩展且具备“强制版本锁死”能力的脚手架治理方案。 flutterw_sidekick_plugin 为 Flutter 开发者引入了基于 Sidekick

By Ne0inhk
KingbaseES数据库:兼容 SQL 语法及 Oracle 过程化语言的语法基础

KingbaseES数据库:兼容 SQL 语法及 Oracle 过程化语言的语法基础

KingbaseES数据库:兼容 SQL 语法及 Oracle 过程化语言的语法基础 KingbaseES数据库:兼容 SQL 语法及 Oracle 过程化语言的语法基础,KingbaseES 数据库(Oracle 模式)以内核兼容为基础,实现了涵盖内核、工具和接口的全方位 Oracle 兼容,当前 Oracle 常用能力兼容性达 100%,能助力客户应用无感平滑迁移。在基础能力上,它兼容 SQL 语法、Oracle 过程化语言语法基础,覆盖数据类型、伪列、常用表达式、系统视图、内置函数等多方面;高级能力方面,支持 ROWID、BFILE 等特殊类型,DBLink 访问、物化视图等功能,还兼容客户端编程接口及 Oracle XML/JSON 能力,

By Ne0inhk