“南海明珠”-黄岩岛(民主礁)领海基线WebGIS绘制实战
目录
前言
一、关于岛屿的基点位置
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的开发,比如坐标点展示和距离求解等。行文仓促,定有许多不足之处,在此恳请各位专家博主在评论区留下真知灼见,不慎荣幸。