基于Java的度分秒坐标转纯经纬度坐标的漂亮国基地信息管理

目录

前言

一、空间表设计

1、物理表结构

二、后台数据管理

1、数据去重

2、去重的具体实现

3、度分秒数据格式转换

4、具体的转换方法

5、新增界面的实现

三、数据管理界面

总结


前言

        众所周知,漂亮国在全球范围内部署了大量的基地,用以维持其打击能力。这里无意于讨论这些部署的事情。只是作为一个GIS开发者,使用地理信息的视角来看看其到底分布在全球的哪些地方,在之前的博客中,我们曾经介绍了使用Java去解析KMZ和KML数据,这份数据就是其它博主分享的漂亮国海外基地的分布情况。这是一份数据源,同时我们在某度百科上也能找到一些公开的资料,上面公布了一些国内或者海外基地的坐标信息。

        要想实现在WebGIS中直观的显示这些位置,首先要解决数据的管理问题。之前我们在使用GDAL的KMZ数据解析中,通过在数据中查看具体的数据可以看到。其提供的数据中,应该是有重复的。我们采用基地名称和位置wkt字符串作为分组查询,可以发现有很多的数据的条数是大于2的。因此可以判定出是有数据的重复,因此要求我们对入库的数据进行去重。同时由于在互联网上公开的数据中,有一些位置信息是以度分秒的形式给出的。对于常见的坐标,我们都是采用纯数字的经纬度来展示的。那么怎么将度分秒的位置信息转换成常见的经纬度信息呢?

        这就是本文的由来,本文将以java语言为例,详细介绍如何管理漂亮国的基地信息。为下一步全球的空间可视化打下坚实的基础,首先介绍如何对数据进行去重处理,然后介绍在java当中如何进行度分秒位置的转换,最后结合实现原型进行详细的说明。通过本文,您可以掌握如何管理这些矢量数据,同时知道如何进行空间数据的去重,还可以掌握如何进行度分秒数据的转换,欢迎品鉴。

一、空间表设计

        这里着重介绍空间表的设计与实现,让大家了解空间表的设计。这里直接分享表的物理结构,通过SQL语句直接分享给大家,如果大家感兴趣也可以进行实践。

1、物理表结构

        闲言少叙,这里将设计的表字段信息以sql语句的形式提供出来,供大家参考,表中的字段,大家可以根据实际情况进行增减。

        物理表结构的sql语句如下(如果您想在本地记性测试,请一定要安装postgis扩展,否则空间数据类型将无法创建):

CREATE TABLE "public"."biz_usa_military_base" ("id" int8 NOT NULL,"en_name" varchar(255) COLLATE "pg_catalog"."default" NOT NULL,"en_desc" varchar(1024) COLLATE "pg_catalog"."default","cn_name" varchar(255) COLLATE "pg_catalog"."default","remark" varchar(255) COLLATE "pg_catalog"."default","geom" "public"."geometry","create_by" varchar(64) COLLATE "pg_catalog"."default","create_time" timestamp(6),"update_by" varchar(64) COLLATE "pg_catalog"."default","update_time" timestamp(6),"type" int4,"en_country" varchar(255) COLLATE "pg_catalog"."default","cn_country" varchar(255) COLLATE "pg_catalog"."default","en_city" varchar(255) COLLATE "pg_catalog"."default","cn_city" varchar(255) COLLATE "pg_catalog"."default",CONSTRAINT "pk_biz_usa_military_topics" PRIMARY KEY ("id")
);
CREATE INDEX "idx_biz_usa_military_base_geom" ON "public"."biz_usa_military_base" USING gist ("geom" "public"."gist_geometry_ops_2d"
);
COMMENT ON COLUMN "public"."biz_usa_military_base"."id" IS '主键';
COMMENT ON COLUMN "public"."biz_usa_military_base"."en_name" IS '英文名称';
COMMENT ON COLUMN "public"."biz_usa_military_base"."en_desc" IS '英文描述';
COMMENT ON COLUMN "public"."biz_usa_military_base"."cn_name" IS '英文名称';
COMMENT ON COLUMN "public"."biz_usa_military_base"."remark" IS '备注';
COMMENT ON COLUMN "public"."biz_usa_military_base"."geom" IS '空间信息';
COMMENT ON COLUMN "public"."biz_usa_military_base"."create_by" IS '创建人';
COMMENT ON COLUMN "public"."biz_usa_military_base"."create_time" IS '创建时间';
COMMENT ON COLUMN "public"."biz_usa_military_base"."update_by" IS '更新人';
COMMENT ON COLUMN "public"."biz_usa_military_base"."update_time" IS '更新时间';
COMMENT ON COLUMN "public"."biz_usa_military_base"."type" IS '基地类型,1海外 0 本土';
COMMENT ON COLUMN "public"."biz_usa_military_base"."en_country" IS '部署国家英文名';
COMMENT ON COLUMN "public"."biz_usa_military_base"."cn_country" IS '部署国家中文名';
COMMENT ON COLUMN "public"."biz_usa_military_base"."en_city" IS '部署城市英文名';
COMMENT ON COLUMN "public"."biz_usa_military_base"."cn_city" IS '部署城市中文名';
COMMENT ON TABLE "public"."biz_usa_military_base" IS '美军军事基地信息表';

         在设计好上述的空间数据表之后,我们就将表在PostGIS数据库中进行新建,确保没有报错。下面再来进行后台去重识别和信息转换的工作。

二、后台数据管理

        后台数据的管理比较简单,这里不涉及复杂的逻辑,首先解析KMZ的数据,这部分的内容不再赘述,仅提供如何进行数据去重的处理。然后如何进行经纬度不同数据格式的转换,因此将数据同步成同一个标准。

1、数据去重

        在之前的数据处理过程当中,我们将所有的基地信息都读取出来,然后统一放到一个List集合当中,最后调用MP的批量插入接口实现数据的批量插入。但是这样的数据是很容易重复的。查询数据是否重复的sql语句如下,我们采用的机制就是根据英文名称来进行检索,我们在筛选数据时,着重检查基地的英文名和位置信息是否一致,如果这两个完全一致,那么我们认为就是同一个基地,是需要将数据进行去除的。


select id,en_name,cn_name,st_asgeojson(geom) from biz_usa_military_base order by st_asgeojson(geom);

        上面的数据由于我已经处理过了,因此已经将重复的数据都已经全部去掉了。默认情况下,是有蛮多重复的数据。在实际项目中,我们怎么解决这种重复数据呢?一般可以有两种思路。第一种就是循环插入,这样在插入前做一次重复查询,如果数据已经存在了就不再插入。这样做的效率是比较低的,因为没插一次还要去数据库中查询数据是否存在,消耗的时间是比较大。既然这种方式不太好,那么第二种方式就是在批量插入,但是要求是必须要在批量的集合中进行去重,这样从源头上就解决了重复插入的问题。

2、去重的具体实现

        为了实现去重,我们这里选用LinkedHashMap来进行处理,选这个数据结构是因为LinkedHashMap可以实现有序性,数据会按照读取的顺序添加到集合当中。同时基于HashMap的特性可以实现重复数据的处理,map的key我们选用字符串来处理,由基地的名称+空间的WKT字符串,这样子虽然长点,但是可以进行重复的校验。在map的结构当中,如果key是重复的话,会以最后的一次put为准,这样就实现我们的去重。代码实现就更加简单了:

Map<String,UsaMilitaryBase> linkedHashMap = new LinkedHashMap<String, UsaMilitaryBase>();
for(int i=0; i<featureCount; i++){Feature feature = layer.GetFeature(i);if(null == feature) continue;String enName = feature.GetFieldAsString("Name");UsaMilitaryBase base = new UsaMilitaryBase();Geometry geom = feature.GetGeometryRef();//step 1、生成原始wktString wkt = geom.ExportToWkt();wkt = "SRID=" + srid +";" + wkt;//拼接srid,实现动态写入linkedHashMap.put(enName + wkt, base);
}

        然后通过这种方式得到的map就是实现了去重之后的数据集合。当然,如果想实现批量插入,就需要循环map,将map的value取出来,然后添加到List中,再调用MP的批量插入的接口。

if(linkedHashMap.size() >0) {// 使用for-each循环遍历HashMapfor (Map.Entry<String, UsaMilitaryBase> entry : linkedHashMap.entrySet()) {dataList.add(entry.getValue());}usaMilitaryBaseService.saveBatch(dataList, 300);//批量插入,每300条提交一次事务
}

3、度分秒数据格式转换

        在空间数据展示中,度分秒也是一种非常常见的格式,因此很多地方也是以度分秒的形式来进行展示的。其中,我们在某度上看到的漂亮国基地信息都是以度分秒的形式展示的,如下所示:

        其数据的表达方式都是:

华盛顿州:
序号 基地名称、经纬度
1、 陆军刘易斯堡 47° 4'57.21"N 122°35'2.78"W
2、 惠德贝岛海军航空站 48°20'42.49"N 122°39'51.71"W
3、 埃弗雷特海军基地 47°59'20.32"N 122°13'12.91"W
4、 普吉海峡海军造船厂 47°33'41.32"N 122°37'56.17"W

         像这些数据怎么保存到数据库中,怎么进行wkt类型的转换呢?这里分享java的实现方式。

4、具体的转换方法

        关于如何将度分秒的数据进行转换,网上有很多例子。我也是参考了别人的代码,但是很多代码其实没有将清楚,比如南纬和西经的数据处理方法,也就是会有负数的情况出现。如果按照正常的计算逻辑,则会出现位置错误。下面分享在网友的基础之上改造的可以带符号的经纬度转换方法。在后台的控制器中增加以下代码:

@RequiresPermissions("mt:usabase:add")
@Log(title = "美军军事基地", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(UsaMilitaryBase militaraBase,String latLonStr){if(StringUtils.isNotEmpty(latLonStr)) {//String lat1 = "34°49'36.28\"N 95°57'33.18\"W";String lat = latLonStr.split(" ")[0];String lon = latLonStr.split(" ")[1];String latSuffix = lat.substring(lat.length() -1 );//取出纬度后缀N,S	String lonSuffix = lon.substring(lon.length() -1 );//取出纬度后缀W,EString newLat = String.valueOf(LatLngUtil.dfm2LatLng(lat.substring(0,lat.length() -1 )));String newLon = String.valueOf(LatLngUtil.dfm2LatLng(lon.substring(0,lon.length() -1 )));newLat = latSuffix.equalsIgnoreCase("S") ?  "-" + newLat : newLat;newLon = lonSuffix.equalsIgnoreCase("W") ?  "-" + newLon : newLon;//构造wkt,默认参考为4326String geom = "SRID=" + 4326 + ";POINT (" + newLon + " " + newLat + ")";militaraBase.setGeom(geom);}return toAjax(mbaseService.insertEntity(militaraBase));
}

        需要注意的是,在数据中,要解析出数据中的南纬和西经,也就是S和W,如果位置后面是这两个字符,需要将结果转换成负数即可。处理具体转换的代码如下,我整理成了一个工具类:

/*** 度分秒转经纬度** @param dms 116°25'7.85"* @return 116.418847*/
public static double dfm2LatLng(String dms) {if (dms == null) return 0;try {dms = dms.replace(" ", "");String[] str2 = dms.split("°");if (str2.length < 2) return 0;int d = Integer.parseInt(str2[0]);String[] str3 = str2[1].split("\'");if (str3.length < 2) return 0;int f = Integer.parseInt(str3[0]);String str4 = str3[1].substring(0, str3[1].length() - 1);double m = Double.parseDouble(str4);double fen = f + (m / 60);double du = (fen / 60) + Math.abs(d);if (d < 0) du = -du;return Double.parseDouble(String.format("%.7f", du));} catch (Exception e) {e.printStackTrace();}return 0;}

5、新增界面的实现

        这里简单分享新增界面的实现,界面实现采用Thymeleaf,并不是流行的vue,喜欢vue的可以自己自行改造哈。将度分秒信息一次性传给后台,后台使用上面展示的add方法接收参数,然后调用转换逻辑。

<div class="form-group">    <label class="col-sm-3 control-label">位置(度分秒):</label><div class="col-sm-8"><input name="latLonStr" class="form-control" type="text" required></div>
</div>

三、数据管理界面

        本节将重点讲解数据管理界面以及功能介绍。

        列表管理界面实现数据的查询展示,展示基地的英文名称、中文名称,数据的创建时间,支持按照基地的中英文名称进行查询。

         新增基地信息页面,请注意在位置这里,输入度分秒格式的数据,同时输入基地的中英文名称、所在国家的中英文名称,所在城市的中英文名称。输入完毕后,点击确定即可。

        信息编辑页面,与新建的窗口界面不同的是,新增界面可以输入位置坐标信息,而修改暂时不提供这个功能(技术上没有问题,只是从业务上禁止修改)。 

总结

        以上就是本文的主要内容,本文将以java语言为例,详细介绍如何管理漂亮国的基地信息。为下一步全球的空间可视化打下坚实的基础,首先介绍如何对数据进行去重处理,然后介绍在java当中如何进行度分秒位置的转换,最后结合实现原型进行详细的说明。通过本文,您可以掌握如何管理这些矢量数据,同时知道如何进行空间数据的去重,还可以掌握如何进行度分秒数据的转换,欢迎感兴趣的朋友互相交流。行文仓促,难免有不足之处,欢迎朋友们在评论区批评指正,不慎感谢。

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

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

相关文章

Unity OpenCVForUnity 安装和第一个案例详解 <一>

目录 一、资源简介 二、安装使用 1.下载案例Demo 2.移动StreamingAssets文件夹 3.添加场景 三、今日案例 1.案例Texture2DToMat Example 2.什么是Mat&#xff1f; 3.如何把Texture2D变成Mat &#xff08;1&#xff09;.初始化Mat &#xff08;2&#xff09;.Cv_…

Bagging与Boosting的应用与优势

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f4a5;&#x1f4a5;个人主页&#xff1a;奋斗的小羊 &#x1f4a5;&#x1f4a5;所属专栏&#xff1a;C语言 &#x1f680;本系列文章为个人学习…

【最全面最优质的PyTorch学习资源】

纯 PyTorch 资源 PyTorch 博客 https://pytorch.org/blog/ PyTorch 文档 https://pytorch.org/docs PyTorch 性能调优指南 https://pytorch.org/tutorials/recipes/recipes/tuning_guide.html# PyTorch Recipes https://pytorch.org/tutorials/recipes/recipes_index.h…

项目管理进阶之EVM(挣值管理)

前言 项目管理进阶系列&#xff0c;终于有时间更新啦&#xff01;&#xff01;&#xff01;欢迎持续关注哦~ 上一节博主重点讲了一个环&#xff1a;PDCA&#xff0c;无论各行各业&#xff0c;上到航空航天、下到种地种菜&#xff0c;都离不开对质量的监督和改进。这个环既是一…

MyBatis 关于查询语句上配置的详细内容

1. MyBatis 关于查询语句上配置的详细内容 文章目录 1. MyBatis 关于查询语句上配置的详细内容2. 准备工作3. SQL查询结果&#xff0c;返回为POJO实体类型4. SQL查询结果&#xff0c;返回为List<POJO\> 集合类型5. SQL查询结果&#xff0c;返回为Map 集合6. SQL查询结果&…

洗地机性价比高的是哪一款?行内人告诉你

在浏览前&#xff0c;希望您轻触屏幕上方的“关注”按钮&#xff0c;让我后续为您带来更多实用且精彩的内容&#xff0c;感谢您的支持&#xff01; 洗地机作为现在的流行清洁工具&#xff0c;它的魅力之处在于&#xff1a;性价比极高&#xff0c;大多数家庭无需花费过多就能把…

IPNV6写法

黄色---一致 红色---取消 V4中的第二列用于分片 V6可以使用扩展首部实现 蓝色--替代 1、服务类型--扩展表 2、报头长度---有效负载长度 3、TTL--跳数限制 4、协议号---下一个头…

英伟达开源 3400 亿参数模型;苹果 iOS 18 紧急 SOS 新增实时视频功能丨 RTE 开发者日报 Vol.225

开发者朋友们大家好&#xff1a; 这里是 「RTE 开发者日报」 &#xff0c;每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE&#xff08;Real-Time Engagement&#xff09; 领域内「有话题的新闻」、「有态度的观点」、「有意思的数据」、「有思考的文章」、「…

力扣172. 阶乘后的零

Problem: 172. 阶乘后的零 文章目录 题目描述思路及解法复杂度Code 题目描述 思路及解法 1.要使得末尾出现0&#xff0c;则乘式中必须出现因子2与5&#xff1b; 2.而由于对于一个数的阶乘&#xff0c;易知因子2的个数是大于因子5的个数&#xff08;因为只要出现偶数则可以分解出…

vscode c++ 开发环境配置

今天各位同学已经安装了mingw环境&#xff0c;但部分同学vscode开发环境又问题&#xff0c;究其原因&#xff0c;还是vscode 编译环境配置错误&#xff0c;有问题的同学 按如下步骤处理&#xff1a; 1、卸载相关插件&#xff0c;特别是中文插件&#xff0c;原因是暂时回避中文…

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 字符串筛选排序(100分) - 三语言AC题解(Python/Java/Cpp)

&#x1f36d; 大家好这里是清隆学长 &#xff0c;一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 &#x1f4bb; ACM银牌&#x1f948;| 多次AK大厂笔试 &#xff5c; 编程一对一辅导 &#x1f44f; 感谢大家的订阅➕ 和 喜欢&#x1f497; &#x1f…

深浅拷贝以及正则表达式(python)

浅拷贝和深拷贝&#xff1a; 浅拷贝&#xff1a; copy函数是浅拷贝&#xff0c;支队可变类型的第一层对象进行拷贝&#xff0c;对拷贝的对象开辟显得内存空间进行存储&#xff0c;不会拷贝对象内部的子对象 不可变类型的浅拷贝示例&#xff1a; 浅拷贝不会对不可变类型进行…

虚拟机使用桥接模式网络配置

1、获取本机的网络详细信息 windowr 输入cmd 使用ipconfig -all 一样即可 在自己的虚拟机中设置网络 虚拟机中的ip ---------192.168.36.*&#xff0c;不要跟自己的本机ip冲突 网关-----------192.168.36.254 一样即可 dns -----------一样即可&#xff0c;我多写了几个&am…

Node-red win11安装

文章目录 前言一、安装node.js和npm二、安装Node-red三、 运行Node-red 前言 Node-RED 是一种编程工具&#xff0c;用于以新颖有趣的方式将硬件设备、API 和在线服务连接在一起。 它提供了一个基于浏览器的编辑器&#xff0c;只需单击一下即可将调色板中的各种节点轻松连接在…

多视图变换矩阵与SLAM位姿估计中的地图点投影的几何约束

定义 projective transform 相机成像模型如下&#xff0c;从世界坐标系中的点到图像中的映射关系由一个矩阵 M M M施加在齐次坐标上&#xff0c;即&#xff1a; p K [ R ∣ t ] P M P pK\left[\begin{array}{ll} R \ | \ t \end{array}\right] PM P pK[R ∣ t​]PMP 其中…

Linux驱动开发-01配置开发环境

一、配置网络环境 使用桥接网卡时 Ubuntu 就是使用一个真实的网卡 &#xff1a;开发板的网线也连接到这个真实的网卡上&#xff0c;这样 Windows 、 Ubuntu 、开发板就都可以用过这个网卡互通了。 NAT 网卡&#xff1a; Ubuntu 通过它上网&#xff0c;只要 Windows 能上网&…

STM32中ADC在cubemx基础配置界面介绍

ADCx的引脚,对应的不同I/O口&#xff0c;可以复用。 Temperature :温度传感器通道。 Vrefint :内部参照电压。 Conversion Trigger: 转换触发器。 IN0 至 IN15,是1ADC1的16个外部通道。本示例中输出连接的是ADC2的IN5通道&#xff0c;所以只勾选IN5.Temperature Sensor Cha…

检索增强生成(RAG)的挑战与优化措施

如何理解检索增强生成&#xff08;RAG&#xff09; 简单来说&#xff0c;RAG就是让LLM通过外部知识源获取额外信息&#xff0c;从而生成更准确、更符合上下文的答案&#xff0c;并减少错误信息&#xff08;或称为“幻觉”&#xff09;的产生。 我们都知道&#xff0c;最先进的…

C# Winform Datagridview控件使用和详解

DataGridView 是一种以表格形式显示数据的控件&#xff0c;由Rows(行)&#xff0c;Columns(列)&#xff0c;Cells(单元格)构成。本实例将综合利用DataGridView的属性和事件&#xff0c;展示不同的表格风格数据和操作。包含&#xff1a; 添加Datagridview行&#xff0c;列数据设…

Vector | Graph:蚂蚁首个开源Graph RAG框架设计解读

作者&#xff1a;范志东 检索增强生成&#xff08;RAG&#xff1a;Retrieval Augmented Generation&#xff09;技术旨在把信息检索与大模型结合&#xff0c;以缓解大模型推理“幻觉”的问题。近来关于RAG的研究如火如荼&#xff0c;支持RAG的开源框架也层出不穷&#xff0c;并…