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

news2024/11/24 18:47:23

目录

前言

一、空间表设计

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、生成原始wkt
     String 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循环遍历HashMap
     for (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,E
            String 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,默认参考为4326
    		String 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.coloradmin.cn/o/1833238.html

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

相关文章

安卓实现圆形按钮轮廓以及解决无法更改按钮颜色的问题

1.实现按钮轮廓 在drawable文件新建xml文件 <shape xmlns:android"http://schemas.android.com/apk/res/android"<!--实现圆形-->android:shape"oval"><!--指定内部的填充色--><solid android:color"#FFFFFF"/><!-…

Python网络数据抓取(9):XPath

引言 XPath 是一种用于从 XML 文档中选取特定节点的查询语言。如果你对 XML 文档不太熟悉&#xff0c;XPath 可以帮你完成网页抓取的所有工作。 实战 XML&#xff0c;即扩展标记语言&#xff0c;它与 HTML&#xff0c;也就是我们熟知的超文本标记语言&#xff0c;有相似之处&am…

韩顺平0基础学java——第25天

p509-522 List接口 ArrayList 1.Arraylist 可以加入null&#xff0c;并且多个定什么都能放 2.ArrayRist 和yector其生一致&#xff0c;但A)是成程不安全的源码没有synchronized.优总是效率高 王.Amayeit底层由数数组实现. 阶以变线程的情况下不建议用Arroyst 源码分析 )Arangla…

MyBatisPlus基础学习

一、简介 二、集成MP 三、入门HelloWorld 四、条件构造器EntityWrapper 五、ActiveRecord(活动记录 ) 六、代码生成器 七、插件扩展 八、自定义全局操作 九、公共字段自动填充 十、Oracle主键Sequence 十一、Idea快速开发插件 十二、mybatis-plus实践及架构原理

SSRF学习,刷题

[HNCTF 2022 WEEK2]ez_ssrf 给了一个Apache2的界面&#xff0c;翻译一下 就是一个默认的界面,目录扫描 可以看到flag.php,肯定是不能直接访问得到的&#xff0c;还有index.php&#xff0c;访问这个 可以看到三个参数data,host,port 还有fsockopen() 函数是 PHP 中用于打开一个…

【网络编程】套接字的多种可选项

可以看出&#xff0c;套接字可选项是分层的。IPPROTOIP层可选项是IP协议相关事项IPPROTO TCP层可选项是TCP协议相关的事项&#xff0c;SOLSOCKET层是套接字相关的通用可选项 getsockopt&&setsockopt #include <sys/socket.h> int getsockopt(int sock, int lev…

第2讲:pixi.js 绘制HelloWorld

基于第0讲和第1讲&#xff0c;我们增添了vite.config.ts文件。并配置了其他的http端口。 此时&#xff0c;我们删除掉没用的东西。 删除 conter.ts、typescript.svg 在main.ts中改成如下内容&#xff1a; import {Application, Text} from pixi.js import ./style.css// 指明…

Aeron:Aeron Agent

Aeron Agent 是一个 Java 代理&#xff0c;用于提供 Aeron、Aeron Archive 和 Aeron Cluster 中发生的运行时低级日志信息。这些日志语句包括从高级管理员事件到大容量数据帧事件。 在调试 Archive 和 Cluster 问题时&#xff0c;Aeron Agent 的日志数据尤其有用。 一、Availab…

github国内加速访问有效方法

这里只介绍实测最有效的一种方法&#xff0c;修改主机的Hosts文件&#xff0c;如果访问github网站慢或者根本无法访问的时候可以采用下面方法进行解决。 1、搜索一个IP查询网站 首先百度搜索选择一个IP查询的网站&#xff0c;这里我用下面这个网站&#xff08;如果该网站失效…

shop APP UI

APP和微信小程序不一样&#xff0c; APP的客户端需要两个(一个安卓&#xff0c;一个苹果IOS); APP的服务端需要&#xff08;管理端后台&#xff0c;接口&#xff09;&#xff1b;

分布式理论与设计 三、分布式一致性协议

1.两阶段提交协议&#xff08;2PC&#xff09; 1&#xff09;两阶段提交协议 两阶段提交协议&#xff0c;简称2PC(2 Prepare Commit)&#xff0c;是比较常用的解决分布式事务问题的方式&#xff0c;要么所有参与进程都提交事务&#xff0c;要么都取消事务&#xff0c;即实现A…

Xlua三方库Android编译出错解决办法

Xlua三方库Android编译出错解决办法 最近听老师的热更教程&#xff0c;讲到xlua编译android平台会报错&#xff0c;也是看了老师的博客&#xff0c;按照方法去解决&#xff0c;然而问题并没有解决。应该是因为代码更新或者版本不一样&#xff0c;在此简单记录一下解决过程。 参…

SpringBoot三层架构

目录 一、传统方式 二、三层架构 三、代码拆分 1、dao层 2、service层 3、control层 四、运行结果 一、传统方式 上述代码存在一定的弊端&#xff0c;在进行软件设计和软件开发中提倡单一责任原则&#xff0c;使代码的可读性更强&#xff0c;复杂性更低&#xff0c;可扩展性…

【Linux硬盘数据读取】WIN10访问linux分区解决方案:ext2fsd

<div id"content_views" class"htmledit_views" style"user-select: auto;"><p>尝试ext2explore、Paragon ExtFS都不好用&#xff0c;强烈安利ext2fsd&#xff0c;可读写&#xff0c;很强大</p> 转自&#xff1a;https://blog…

超高清图像生成新SOTA!清华唐杰教授团队提出Inf-DiT:生成4096图像比UNet节省5倍内存。

清华大学唐杰教授团队最近在生成超高清图像方面的新工作&#xff1a;Inf-DiT&#xff0c;通过提出一种单向块注意力机制&#xff0c;能够在推理过程中自适应调整内存开销并处理全局依赖关系。基于此模块&#xff0c;该模型采用了 DiT 结构进行上采样&#xff0c;并开发了一种能…

JMU 数科 数据库与数据仓库期末总结(4)实验设计题

E-R图 实体-关系图 E-R图的组成要素主要包括&#xff1a; 实体&#xff08;Entity&#xff09;&#xff1a;实体代表现实世界中可相互区别的对象或事物&#xff0c;如顾客、订单、产品等。在图中&#xff0c;实体通常用矩形表示&#xff0c;并在矩形内标注实体的名称。 属性…

Java项目:基于SSM框架实现的汽车养护保养管理系统【ssm+B/S架构+源码+数据库+开题+毕业论文+任务书】

一、项目简介 本项目是一套基于SSM框架实现的汽车养护保养管理系统 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界面美观、操作简单、…

VirtualBox 安装UOS统信服务器操作系统

1、准备 1.1安装VirtualBox 由于过程简单&#xff0c;不做赘述&#xff01; 1.2下载UOS服务器版本 下载免费版本即可 服务器与云计算操作系统-统信软件 (uniontech.com)https://uniontech.com/os-serverCloud.html 2、安装 2.1新建虚拟机 2.2选择虚拟机模式&#xff0c;这…

pandas 根据关键词从表格属性进行筛选企业

文章目录 背景实战情况一情况二 背景 最近一段时间在做企业分类的实验&#xff0c;给定一个企业信息表&#xff0c;利用关键词从企业名称和经营范围中筛选相关企业。 情况一&#xff1a;企业名称和经营范围任何一个包含关键词&#xff1b; 情况二&#xff1a;企业名称和经营范…

飞天茅台酒的惊魂五日

“电商百亿补贴修改发货规则”导致黄牛资金压力剧增&#xff0c;资金压力之下部分黄牛择低价甩卖&#xff0c;其他求货的酒行、大酒商则选择观望&#xff0c;价格下行压力最终扩散&#xff0c;造成整个回收市场踩踏&#xff0c;价格急速下跌。 不到半年时间&#xff0c;飞天茅台…