“南海明珠”-黄岩岛(民主礁)领海基线WebGIS绘制实战

news2024/11/17 13:21:33

目录

前言

一、关于岛屿的基点位置

1、领海基点

二、基点坐标的转换

1、最底层的左边转换

2、单个经纬度坐标点转换

3、完整的转换

三、基于天地图进行WebGIS展示

1、领海基点的可视化

2、重要城市距离计算 

四、总结


前言

        南海明珠黄岩岛,这座位于南海的美丽岛礁,犹如一颗璀璨的明珠,在波涛汹涌的大海中闪耀着独特的光芒。它不仅拥有丰富的渔业资源和潜在的矿产宝藏,同时承载着深厚的历史文化底蕴和重大的战略意义。从历史的长河中溯源,中国对黄岩岛的发现、命名与开发利用可以追溯到遥远的古代。数百年前,中国的渔民就已在黄岩岛周边海域捕鱼作业,他们凭借着勇敢与智慧,在这片蓝色的家园上辛勤耕耘,留下了无数生活的印记与文化传承。古籍记载中,黄岩岛亦有着明确的归属记录。

        从地理上看,黄岩岛位于北纬15°13′48″至15°05′24″,东经117°40′12″至117°52′00″,距西沙群岛的主岛永兴岛约600公里。它是一个略呈三角形的环礁,环礁包围着一浅湖,水色清绿,和礁外深海蓝黑水色不同。

        上图来源:黄岩岛,在哪里?它为什么对我们这么重要。 

        在这篇博客中来看一下黄岩岛的自然条件。黄岩岛发育在3500米深的海盆上,是南海中沙群岛中唯一露出水面的岛屿,四周为距水面半米到3米之间的环形礁盘。东南端有一个宽400米的通道与外海相连,高潮位水深9米,低潮位水深6米,中型渔船和小型舰艇可由此进入。

        上图是在我国的天地图上的黄岩岛高清影像,像不像一颗璀璨的珍珠。黄岩岛海域环境质量优,珊瑚礁生态系统健康。调查共记录造礁石珊瑚12科34属109种,为有调查记录以来物种多样性记录最丰富的一次,活造礁石珊瑚的平均覆盖度为28.6%,造礁石珊瑚幼体补充量较高。 

         今天博客带大家来看看国家的天地图上的黄岩岛遥感影像,用WebGIS的方式来看我们的南海明珠。博文首先介绍了领海基线坐标,同时讲述如何使用Java将领海基点的坐标转换成熟悉的经纬坐标,然后调用天地图使用Leaflet展示这些坐标点,最后再分析从岛上到我国及菲律宾的直线距离。通过文本,大家不仅可以领略国家的大好河山,也掌握如何进行WebGIS的开发,比如坐标点展示和距离求解等。言归正传,下面进入正题。

一、关于岛屿的基点位置

        中国南海风光旖旎。美丽的黄岩岛伴随着潮起潮落,呈现出不同的景色。潮起时碧波荡漾,如一颗明珠镶嵌在南海上;潮落时礁石连片,像山川交汇于茫茫碧野。近瞰中国黄岩岛的壮丽风光,体验潮平南海阔,浩荡见碧波的绝美景致。这里我们根据相关平台的公开内容,先简单介绍黄岩岛的相关位置。

1、领海基点

        我们在相关平台上均可以查询得到黄岩岛的领海基点信息,如下图所示:

        领海基点一共包含15个点,这里直接摘录出来,供大家参考。 

1.黄岩岛1  北纬15°08.1′  东经117°50.9′
2.黄岩岛2  北纬15°07.4′  东经117°50.8′
3.黄岩岛3  北纬15°07.0′  东经117°50.6′
4.黄岩岛4  北纬15°06.6′  东经117°50.2′
5.黄岩岛5  北纬15°06.1′  东经117°49.5′
6.黄岩岛6  北纬15°06.3′  东经117°44.2′
7.黄岩岛7  北纬15°07.3′  东经117°43.1′
8.黄岩岛8  北纬15°12.7′  东经117°42.6′
9.黄岩岛9  北纬15°13.1′  东经117°42.8′
10.黄岩岛10  北纬15°13.4′  东经117°43.3′
11.黄岩岛11  北纬15°13.5′  东经117°43.9′
12.黄岩岛12  北纬15°13.5′  东经117°44.4′
13.黄岩岛13  北纬15°09.6′  东经117°49.7′
14.黄岩岛14  北纬15°09.0′  东经117°50.4′
15.黄岩岛15  北纬15°08.5′  东经117°50.8′
16.黄岩岛1  北纬15°08.1′  东经117°50.9′

        大家可以看到,这些基点的位置坐标格式是度分的格式,没有秒。则也是经纬度的一种表达形式。众所周知,想要把这些数据转换成经纬度坐标,进而在地图上进行展示,还是需要一定的转换的。因此下面我们来讲一讲如何进行度分的坐标转为经纬度的坐标。

二、基点坐标的转换

        对于将度分的坐标转换成经纬度的坐标,本身是比较简单的。下面以Java为例,讲解如何在Java中实现度分坐标到经纬度坐标的转换。

1、最底层的左边转换

        其实不管东经还是西经,南纬还是北纬,最终都是要进行转换的。而在上述的坐标中没有秒,因此我们只需要定义一个实现度和分的计算即可。关键代码如下:

/**
 * -度分转经纬度
 *
 * @param dms 116°25'
 * @return 116.418847
 */
public static double df2LatLng2(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("′");
      double f = Double.parseDouble(str3[0]);
      double du = (f / 60) + Math.abs(d);
      if (d < 0) du = -du;
      return Double.parseDouble(String.format("%.7f", du));
   } catch (Exception e) {
        e.printStackTrace();
   }
   return 0;
}

2、单个经纬度坐标点转换

        基于上述的单个经度或者纬度的转换方法,我们需要实现传入一个坐标点,实现坐标点的转换。在一次方法调用中,需要同时转换经度和纬度。同时,为了在地图上正确的展示出位置,我们还需要进行正数或者负数的判断,比如西经或者南纬就应该在求解的值前加一个负号才能正确展示位置。坐标点的转换方法如下所示:

/**
* 	将单个度分秒坐标转经纬度坐标数组,如北纬15°08.1′,东经117°50.9′
* @param latLonStr
* @return
*/
private static String [] str2LatLon2(String latLonStr) {
	String [] latLon = latLonStr.split(",");
	String lat = latLon[0];
    String lon = latLon[1];
    String latSuffix = lat.substring(0,2);//取出纬度前缀,如南纬、北纬
    String lonSuffix = lon.substring(0,2);//取出经度前缀,如东经、西经
    String newLat = String.valueOf(LatLngUtil.df2LatLng2(lat.substring(2)));
    String newLon = String.valueOf(LatLngUtil.df2LatLng2(lon.substring(2)));
    newLat = latSuffix.equalsIgnoreCase("南纬") ?  "-" + newLat : newLat;
    newLon = lonSuffix.equalsIgnoreCase("西经") ?  "-" + newLon : newLon;
    return new String[]{newLat,newLon};
}

        这里主要是一个坐标的读取和单位的计算等,代码比较简单,不进行赘述。

3、完整的转换

        这里我们对所有的基点坐标位置进行转换,得到符合我们要求的经纬度坐标。调用代码如下所示:

   

@Test
public void convertHuangyandaoRange() {
	List<String> huangyan = new ArrayList<String>();
	huangyan.add("北纬15°08.1′,东经117°50.9′");//黄岩岛1
	huangyan.add("北纬15°07.4′,东经117°50.8′");//黄岩岛2
	huangyan.add("北纬15°07.0′,东经117°50.6′");//黄岩岛3
	huangyan.add("北纬15°06.6′,东经117°50.2′");//黄岩岛4
	huangyan.add("北纬15°06.1′,东经117°49.5′");//黄岩岛5
	huangyan.add("北纬15°06.3′,东经117°44.2′");//黄岩岛6
	huangyan.add("北纬15°07.3′,东经117°43.1′");//黄岩岛7
	huangyan.add("北纬15°12.7′,东经117°42.6′");//黄岩岛8
	huangyan.add("北纬15°13.1′,东经117°42.8′");//黄岩岛9
	huangyan.add("北纬15°13.4′,东经117°43.3′");//黄岩岛10
	huangyan.add("北纬15°13.5′,东经117°43.9′");//黄岩岛11
	huangyan.add("北纬15°13.5′,东经117°44.4′");//黄岩岛12
	huangyan.add("北纬15°09.6′,东经117°49.7′");//黄岩岛13
	huangyan.add("北纬15°09.0′,东经117°50.4′");//黄岩岛14
	huangyan.add("北纬15°08.5′,东经117°50.8′");//黄岩岛15
	int index = 1;
	for(String latlonStr : huangyan) {
		System.out.println("黄岩岛"+index+"坐标:" + latlonStr);
		String [] latLon = str2LatLon2(latlonStr);
		System.out.println(latlonStr + " = (" + latLon[0] + "," +latLon[1] + ")");
		System.out.println("----------------------------------------------------------");
		index ++;
	}
}

           在控制台可以看到经过转换的经纬度领海基点位置如下:

黄岩岛1坐标:北纬15°08.1′,东经117°50.9′
北纬15°08.1′,东经117°50.9′ = (15.135,117.8483333)
--------------------------------------------------------------
黄岩岛2坐标:北纬15°07.4′,东经117°50.8′
北纬15°07.4′,东经117°50.8′ = (15.1233333,117.8466667)
--------------------------------------------------------------
黄岩岛3坐标:北纬15°07.0′,东经117°50.6′
北纬15°07.0′,东经117°50.6′ = (15.1166667,117.8433333)
--------------------------------------------------------------
黄岩岛4坐标:北纬15°06.6′,东经117°50.2′
北纬15°06.6′,东经117°50.2′ = (15.11,117.8366667)
--------------------------------------------------------------
黄岩岛5坐标:北纬15°06.1′,东经117°49.5′
北纬15°06.1′,东经117°49.5′ = (15.1016667,117.825)
--------------------------------------------------------------
黄岩岛6坐标:北纬15°06.3′,东经117°44.2′
北纬15°06.3′,东经117°44.2′ = (15.105,117.7366667)
--------------------------------------------------------------
黄岩岛7坐标:北纬15°07.3′,东经117°43.1′
北纬15°07.3′,东经117°43.1′ = (15.1216667,117.7183333)
--------------------------------------------------------------
黄岩岛8坐标:北纬15°12.7′,东经117°42.6′
北纬15°12.7′,东经117°42.6′ = (15.2116667,117.71)
--------------------------------------------------------------
黄岩岛9坐标:北纬15°13.1′,东经117°42.8′
北纬15°13.1′,东经117°42.8′ = (15.2183333,117.7133333)
--------------------------------------------------------------
黄岩岛10坐标:北纬15°13.4′,东经117°43.3′
北纬15°13.4′,东经117°43.3′ = (15.2233333,117.7216667)
--------------------------------------------------------------
黄岩岛11坐标:北纬15°13.5′,东经117°43.9′
北纬15°13.5′,东经117°43.9′ = (15.225,117.7316667)
--------------------------------------------------------------
黄岩岛12坐标:北纬15°13.5′,东经117°44.4′
北纬15°13.5′,东经117°44.4′ = (15.225,117.74)
--------------------------------------------------------------
黄岩岛13坐标:北纬15°09.6′,东经117°49.7′
北纬15°09.6′,东经117°49.7′ = (15.16,117.8283333)
--------------------------------------------------------------
黄岩岛14坐标:北纬15°09.0′,东经117°50.4′
北纬15°09.0′,东经117°50.4′ = (15.15,117.84)
--------------------------------------------------------------
黄岩岛15坐标:北纬15°08.5′,东经117°50.8′
北纬15°08.5′,东经117°50.8′ = (15.1416667,117.8466667)
--------------------------------------------------------------

        这些坐标将在下一节的WebGIS系统展示中用到。

三、基于天地图进行WebGIS展示

        在线影像底图,我们可以采用国家天地图,在天地图影像中可以看到有相关的数据。因此这里以天地图为例,详细说明如何进行WebGIS的可视化展示。关于如何引用天地图的底图,C站有很多的资料,我的个人博客中也有具体的介绍。这里不再进行赘述。

1、领海基点的可视化

        根据上一节转换出来的领海基点数据,我们首先使用Leaflet来逐一绘制。首先将上面的坐标点定义到数组中。

// leaflet 的坐标是纬度、经度
var huangyandao = [
	[15.135,117.8483333],
	[15.1233333,117.8466667],
	[15.1166667,117.8433333],
	[15.11,117.8366667],
	[15.1016667,117.825],
	[15.105,117.7366667],
	[15.1216667,117.7183333],
	[15.2116667,117.71],
	[15.2183333,117.7133333],
	[15.2233333,117.7216667],
	[15.225,117.7316667],
	[15.225,117.74],
	[15.16,117.8283333],
	[15.15,117.84],
	[15.1416667,117.8466667]
];

for (let i = 0; i < huangyandao.length; i++) {
	//构造Leaflet的位置
	let latlng = L.latLng(huangyandao[i][0], huangyandao[i][1]);
	var content = "黄岩岛"+i;
	var title = content;
	let c = L.circleMarker(latlng, {
		radius: 5,
		labelStyle: {
			text: title,
			rotation: 0,
			scale: 1,
			zIndex: 10,
			font: "14px Microsoft YaHei",
			fillStyle: "red",
			textBaseline: "top" ,
			minZoom: 9
		}
	}).addTo(map);
	c.bindPopup(content);
}

        来看一下将领海基点在天地图中标注的实际效果,如下图所示:

        在图中可以很明显的看到,领海基点已经正确的展示出来。 我们可以将这些点连成一个面,然后进行展示,展示代码如下:。

L.polygon([huangyandao],style).addTo(map).bindPopup("南海明珠黄岩岛.");

2、重要城市距离计算 

        有了基点和面以后,我们还可以计算从基点到一些重要城市的距离。首先,我们先选取一些重点城市及其的经纬度坐标信息。这里分别选取三沙市、三亚市、海口市还有马尼拉这几个城市。城市位置如下:

var targetCity = [
	{"lat":16.828203,"lon":112.339325,"name":"三沙市","country":"china"},
	{"lat":18.198044,"lon":109.511719,"name":"三亚市","country":"china"},
	{"lat":20.014645,"lon":110.203857,"name":"海口市","country":"china"},
	{"lat":20.643066,"lon":116.850586,"name":"东沙群岛","country":"china"},
	{"lat":15.146369,"lon":120.050354,"name":"菲律宾卡邦岸","country":"Philippines"},
	{"lat":14.599531,"lon":121.014404,"name":"菲律宾马尼拉","country":"Philippines"}
];

function getDistance(latlng1,latlng2){
	var _distance = parseFloat(L.latLng(latlng1).distanceTo(L.latLng(latlng2))) / 1000.0;
	return _distance.toFixed(2) + "公里";
}

for(var j = 0;j< targetCity.length;j++){
	var index = targetCity[j].country == "china" ? 7 : 0;
	var color = targetCity[j].country == "china" ? "#fe57a1" : "green";
	//添加矢量数据
	var p = L.polyline([[huangyandao[index],[targetCity[j].lat,targetCity[j].lon]]], {
			labelStyle: {
				text: targetCity[j].name + ":" + getDistance(huangyandao[index],[targetCity[j].lat, targetCity[j].lon]),
				zIndex: 0,
				collisionFlg: false,
				font: "15px sans-serif",
				textAlign:'end',
				fillStyle: color
			},
			color: color
	}).addTo(map);
}

        来看一下实际的地图展示效果:

        从上图中可以很直观的看到黄岩岛到不同城市的距离。祖国幅员辽阔,此刻有了具象化。

四、总结

        以上就是本文的主要内容,博文首先介绍了领海基线坐标,同时讲述如何使用Java将领海基点的坐标转换成熟悉的经纬坐标,然后调用天地图使用Leaflet展示这些坐标点,最后再分析从岛上到我国及菲律宾的直线距离。通过文本,大家不仅可以领略国家的大好河山,也掌握如何进行WebGIS的开发,比如坐标点展示和距离求解等。行文仓促,定有许多不足之处,在此恳请各位专家博主在评论区留下真知灼见,不慎荣幸。

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

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

相关文章

19.UE5道具掉落

2-21 道具掉落&#xff0c;回血、回蓝、升级提升伤害_哔哩哔哩_bilibili 目录 1.道具的创建&#xff0c;道具功能的实现 2.随机掉落 1.道具的创建&#xff0c;道具功能的实现 新建Actor蓝图&#xff0c;并命名为道具总类&#xff0c;添加一个Niagara粒子组件和一个碰撞箱bo…

Cartographer激光雷达slam -20241116

Cartographer Cartographer代码结构 cartographer&#xff1a;负责处理来自雷达、IMU和里程计的数据并基于这些数据进行地图的构建&#xff0c;是cartographer理论的底层实现cartographer_ros&#xff1a;基于ros的通信机制获取传感器的数据并将它们转换成cartographer中定义…

node.js学习笔记-Window下MongoDB数据库安装(二)

一、介绍 MongoDB 是一个基于分布式文件存储的开源数据库系统&#xff0c;在当前的软件开发和数据存储领域中应用广泛&#xff0c;以下是对 MongoDB 的详细介绍&#xff1a; 文档型数据库&#xff1a;MongoDB 以 BSON&#xff08;Binary JSON&#xff09;格式存储数据&#x…

STM32G4的数模转换器(DAC)的应用

目录 概述 1 DAC模块介绍 2 STM32Cube配置参数 2.1 参数配置 2.2 项目架构 3 代码实现 3.1 接口函数 3.2 功能函数 3.3 波形源代码 4 DAC功能测试 4.1 测试方法介绍 4.2 波形测试 概述 本文主要介绍如何使用STM32G4的DAC模块功能&#xff0c;笔者使用STM32Cube工具…

【论文复现】轻松利用自适应特征融合实现去雾

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀ 智慧医疗 介绍创新点网络结构特征提取阶段自适应融合阶段图像重建阶段上下文增强模块CEM特征融合模块AFM 结果分析 提示 论文题目&#xff1…

常用在汽车PKE无钥匙进入系统的高度集成SOC芯片:CSM2433

CSM2433是一款集成2.4GHz频段发射器、125KHz接收器和8位RISC&#xff08;精简指令集&#xff09;MCU的SOC芯片&#xff0c;用在汽车PKE无钥匙进入系统里。 什么是汽车PKE无钥匙进入系统&#xff1f; 无钥匙进入系统具有无钥匙进入并且启动的功能&#xff0c;英文名称是PKE&…

《TCP/IP网络编程》学习笔记 | Chapter 11:进程间通信

《TCP/IP网络编程》学习笔记 | Chapter 11&#xff1a;进程间通信 《TCP/IP网络编程》学习笔记 | Chapter 11&#xff1a;进程间通信进程间通信的基本概念通过管道实现进程间通信通过管道进行进程间双向通信 运用进程间通信习题&#xff08;1&#xff09;什么是进程间通信&…

计算机网络各层设备总结归纳(更新ing)

计算机网络按照OSI&#xff08;开放式系统互联&#xff09;模型分为七层&#xff0c;每一层都有其特定的功能和对应的网络设备。以下是各层对应的设备&#xff1a; 1. 物理层&#xff08;Physical Layer) 设备&#xff1a;中继器&#xff08;Repeater&#xff09;、集线器…

在kile 5中一个新工程的创建

这两天博主学习到了在kile5中创建一个工程&#xff0c;当然博主不会忘了小伙伴们的&#xff0c;这就和你们分享。 本次创建以STM32F103C8为例 创建过程&#xff1a; 1首先创建文件 名字随意&#xff0c;但也不要太随意&#xff0c;因为是外国软件&#xff0c;所以多少对中文…

AI写作(十)发展趋势与展望(10/10)

一、AI 写作的崛起之势 在当今科技飞速发展的时代&#xff0c;AI 写作如同一颗耀眼的新星&#xff0c;迅速崛起并在多个领域展现出强大的力量。 随着人工智能技术的不断进步&#xff0c;AI 写作在内容创作领域发挥着越来越重要的作用。据统计&#xff0c;目前已有众多企业开始…

Javascript垃圾回收机制-运行机制(大厂内部培训版本)

前言 计算机基本组成&#xff1a; 我们编写的软件首先读取到内存&#xff0c;用于提供给 CPU 进行运算处理。 内存的读取和释放&#xff0c;决定了程序性能。 冯诺依曼结构 解释和编译 这两个概念怎么理解呢。 编译相当于事先已经完成了可以直接用。好比去饭店吃饭点完上…

大数据技术之Hive:还是SQL好用

虽说 MapReduce 简化了大数据编程的难度&#xff0c;但是如果每来一个需求都要写一个 MapReduce 代码&#xff0c;那岂不是太麻烦了。尤其是在全民“CRM”的2000年代&#xff0c;对于像数据分析师已经习惯使用SQL进行分析和统计的工程师&#xff0c;让他们去 MapReduce 编程还是…

使用 Grafana api 查询 Datasource 数据

一、使用grafana 的api 接口 官方API 二、生成Api key 点击 Administration -》Users and accss -》Service accounts 进入页面 点击Add service account 创建 service account 点击Add service account token 点击 Generate token , 就可以生成 api key 了 三、进入grafana…

OceanBase 闪回查询

前言 在OB中&#xff0c;drop表可以通过 回收站 或者 以往的备份恢复来还原单表。当delete数据时&#xff0c;由于delete操作的对象不会进入回收站&#xff0c;此时需要通过闪回查询功能查看delete的数据&#xff0c;以便后续恢复 本次实验版本为 OceanBase 4.2.1.8&#xff0…

vue2 动态路由的实现

概述 一般情况下&#xff0c;路由都是前端约定好的&#xff0c;但是每当项目发布上线&#xff0c;或者客户需求新的页面的时候&#xff0c;都需要做出路由改变。这样运维就可以现场支持&#xff0c;方便做出可操作的中户中台&#xff0c;来管理我们的中心项目登录及权限&#x…

华为云前台展示公网访问需要购买EIP,EIP流量走向

华为云前台网络&#xff08;VPC,安全组&#xff0c;EIP&#xff09; 1.EIP网段是从哪里划分的&#xff1f; 管理员在后台Service_OM已设置 Service_OM-网络资源-外部网络-创建外部网络基本信息&#xff1a;配置参数&#xff1a;*名称 public*网络类型 LOCAL 不带标签 类似开…

树状数组+概率论,ABC380G - Another Shuffle Window

目录 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 二、解题报告 1、思路分析 2、复杂度 3、代码详解 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 G - Another Shuffle Window 二、解题报告 1、思路分析 不难用树状数组计…

LSTM(长短期记忆网络)详解

1️⃣ LSTM介绍 标准的RNN存在梯度消失和梯度爆炸问题&#xff0c;无法捕捉长期依赖关系。那么如何理解这个长期依赖关系呢&#xff1f; 例如&#xff0c;有一个语言模型基于先前的词来预测下一个词&#xff0c;我们有一句话 “the clouds are in the sky”&#xff0c;基于&…

麒麟nginx配置

一、配置负载均衡 配置麒麟的yum源 vim /etc/yum.repos.d/kylin_aarch64.repo Copy 删除原来内容&#xff0c;写入如下yum源 [ks10-adv-os] name Kylin Linux Advanced Server 10 - Os baseurl http://update.cs2c.com.cn:8080/NS/V10/V10SP2/os/adv/lic/base/aarch64/ …

AI工业大模型报告:体系架构、关键技术与典型应用

研究意义 随着新一代人工智能的发展, 大模型&#xff08;如 GPT-4o 等&#xff09;凭借大规模训练数据、网络参数和算 力涌现出强大的生成能力、泛化能力和自然交互能力, 展现出改变工业世界的巨大潜力. 尽管大模型 已在自然语言等多个领域取得突破性进展, 但其在工业应用中的…