怎么自己做網(wǎng)站發(fā)優(yōu)惠券seo搜索引擎優(yōu)化業(yè)務(wù)
目錄
前言
一、坐標(biāo)格式轉(zhuǎn)換
1、數(shù)據(jù)初認(rèn)識(shí)
2、將區(qū)域分割成多個(gè)點(diǎn)
3、數(shù)據(jù)轉(zhuǎn)換
4、數(shù)據(jù)轉(zhuǎn)換調(diào)用
二、WebGIS展示空間位置信息
1、定義底圖
2、Polygon的可視化
3、實(shí)際效果
三、總結(jié)
前言
????????通常而言,海事部門(mén)如海事局,通常會(huì)在所述的管轄區(qū)域內(nèi)進(jìn)行航行管控。比如會(huì)在海面上進(jìn)行采砂作業(yè)、或者是拖帶作業(yè)、人員落水、沉船礙航等作業(yè)需求。這些消息通常會(huì)先由各海域?qū)俚氐暮J戮诌M(jìn)行消息的發(fā)布,可以在他們的官方網(wǎng)站上看到,如以下的信息:
閩航警34/24 ?臺(tái)灣海峽
2024年7月15日至2024年10月15日,每日24小時(shí),在以下四點(diǎn)連線范圍內(nèi)的安全作業(yè)區(qū)進(jìn)行采砂作業(yè),24-12.27N ?118-24.04E ,24-10.25N ?118-26.30E ,24-08.17N ?118-24.05E ,
24-10.19N ?118-21.78E 。無(wú)關(guān)船舶禁止駛?cè)搿?/p>
福建海事局。
????????在圖上的信息中,?其實(shí)就包含一些很重要的時(shí)空信息,比如預(yù)警的時(shí)間是2024年7月15日到10月15日,中間差不多有三個(gè)月的時(shí)間,在這三個(gè)月的時(shí)間內(nèi),是不允許其它的船舶駛?cè)肷鲜龅膮^(qū)域內(nèi)的。作為GIS開(kāi)發(fā)者,我們除了重點(diǎn)關(guān)注預(yù)警的時(shí)間范圍,更關(guān)心的是空間范圍。如果假定是一些商用船舶,我們就可以提取這些空間數(shù)據(jù),在進(jìn)行航線規(guī)劃的時(shí)候,繞開(kāi)這些作業(yè)區(qū)域,不僅能保證航行安全,也是加快作業(yè)效率。關(guān)注新聞的朋友一定知道,一些重要的行動(dòng)需要對(duì)某一些區(qū)域進(jìn)行管控的,也是會(huì)經(jīng)過(guò)地方海事局進(jìn)行公開(kāi)位置,然后在規(guī)定的時(shí)間內(nèi)進(jìn)行。而這些區(qū)域不僅僅是一塊區(qū)域,而是多個(gè)區(qū)域同時(shí)進(jìn)行,從而錘煉不同的隊(duì)伍的實(shí)戰(zhàn)能力。如下圖發(fā)布的航行警告中就包括6個(gè)區(qū)域(即面數(shù)據(jù))。
????????本文即以Leaflet為例,重點(diǎn)講解如何將上述的空間信息轉(zhuǎn)換為可以在地圖上瀏覽的位置信息。首先使用Java語(yǔ)言將上面的涉及的空間坐標(biāo)(度分秒)調(diào)整為常見(jiàn)的經(jīng)緯度坐標(biāo)。然后根據(jù)不同的點(diǎn)連接成多個(gè)面,最后將這些Polygon面數(shù)據(jù)疊加到Leaflet中,從而實(shí)現(xiàn)航行警告中的相關(guān)區(qū)域和地圖的融合。通過(guò)本文,您可以掌握怎么使用Java把度分秒坐標(biāo)轉(zhuǎn)為標(biāo)準(zhǔn)格式,還可以掌握在Leaflet當(dāng)中如何把這些Polygon進(jìn)行空間疊加。
一、坐標(biāo)格式轉(zhuǎn)換
????????其實(shí)度分秒這種格式的坐標(biāo)在日常生活中也是非常常見(jiàn)的,讀起來(lái)也比較順暢。但是通常,我們?cè)赪ebGIS上進(jìn)行位置展示時(shí),還是習(xí)慣于使用經(jīng)緯度格式的坐標(biāo)。因此這里主要講解如何將度分秒的坐標(biāo)轉(zhuǎn)為標(biāo)準(zhǔn)經(jīng)緯度信息。轉(zhuǎn)換它的方法其實(shí)很簡(jiǎn)單,本人比較熟悉Java語(yǔ)言,因此后臺(tái)的轉(zhuǎn)換方法均使用Java編寫(xiě),除了使用Java來(lái)開(kāi)發(fā)這個(gè)功能,其他的編程語(yǔ)言同樣可以實(shí)現(xiàn)。
1、數(shù)據(jù)初認(rèn)識(shí)
????????要想實(shí)現(xiàn)格式的轉(zhuǎn)換,首先我們要對(duì)原文中的格式進(jìn)行解釋??梢钥吹皆谠闹械?#xff0c;它的具體內(nèi)容中包含位置面信息內(nèi)容如下:
區(qū)域一為下列4點(diǎn)連線水域: 25°15′26"N/120°29′20"E,24°50′30"N/120°05′45"E, 25°04′32"N/119°51′22"E,25°28′12"N/120°14′30"E。
區(qū)域二為下列4點(diǎn)連線水域: 26°07′00"N/121°57′00"E,25°30′00"N/121°57′00"E, 25°30′00"N/121°28′00"E,26°07′00"N/121°28′00"E。
區(qū)域三為下列4點(diǎn)連線水域: 25°34′00"N/122°50′00"E,25°03′00"N/122°50′00"E, 25°03′00"N/122°11′00"E,25°34′00"N/122°11′00"E。
區(qū)域四為下列4點(diǎn)連線水域: 22°56′00"N/122°40′00"E,23°38′00"N/122°51′00"E, 23°38′00"N/123°23′00"E,22°56′00"N/123°09′00"E。
區(qū)域五為下列4點(diǎn)連線水域: 21°14′00"N/121°33′00"E,21°33′00"N/121°18′00"E, 21°07′00"N/120°43′00"E,20°48′00"N/120°59′00"E。
區(qū)域六為下列4點(diǎn)連線水域: 22°43′00"N/119°14′00"E,22°10′00"N/119°06′00"E, 21°33′00"N/120°29′00"E,22°09′00"N/120°32′00"E。
????????每個(gè)區(qū)域的都是這種形式的數(shù)據(jù),這也為我們進(jìn)行統(tǒng)一轉(zhuǎn)換提供了有效的數(shù)據(jù)格式的基礎(chǔ)。可以看到,每個(gè)區(qū)域都是一條數(shù)據(jù),不同的點(diǎn)位(point)之間用逗號(hào)分隔,而坐標(biāo)點(diǎn)內(nèi)部使用/來(lái)分割。因此我們要想識(shí)別每一個(gè)區(qū)域的信息,其實(shí)也很簡(jiǎn)單。首先將字符串按逗號(hào)分隔,這樣就可以形成多個(gè)點(diǎn)位的度分秒字符串。然后再分割/字符串,從而得到度分秒的位置。
2、將區(qū)域分割成多個(gè)點(diǎn)
按照前面介紹得分割方法,首先根據(jù)逗號(hào),將目標(biāo)區(qū)域字符串分割成多個(gè)點(diǎn)。關(guān)鍵的代碼如下:
/*** 將四個(gè)點(diǎn)的字符串統(tǒng)一解析為經(jīng)緯度數(shù)組* @param bboxString*/
private static void str2Point(String bboxString) {//將經(jīng)緯度單位中的分改為英文狀態(tài)下的分bboxString = bboxString.replaceAll("′", "\'");String [] points = bboxString.split(",");for (String str : points) {String [] latLon = str2LatLon(str);System.out.println(str + " = (" + latLon[0] + "," +latLon[1] + ")");}
}
????????將經(jīng)緯度單位中的分改為英文狀態(tài)下的分是為了在后續(xù)的解析中進(jìn)行數(shù)據(jù)容錯(cuò)。
3、數(shù)據(jù)轉(zhuǎn)換
????????將點(diǎn)從區(qū)域點(diǎn)字符串提取出來(lái)之后,我們需要將數(shù)據(jù)進(jìn)行提取和轉(zhuǎn)換兩個(gè)步驟。提取是按照/將字符進(jìn)行分割,而轉(zhuǎn)換是將度分秒的數(shù)據(jù)轉(zhuǎn)換為標(biāo)準(zhǔn)的經(jīng)緯度數(shù)據(jù)。關(guān)鍵代碼如下:
/**
* 將單個(gè)度分秒坐標(biāo)轉(zhuǎn)經(jīng)緯度坐標(biāo)數(shù)組
* @param latLonStr
* @return
*/
private static String [] str2LatLon(String latLonStr) {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;return new String[]{newLat,newLon};
}
????????這里還是將經(jīng)緯度轉(zhuǎn)換的方法提供出來(lái),防止大家在第一次看的時(shí)候有所迷糊。
/*** 度分秒轉(zhuǎn)經(jīng)緯度** @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;
}
4、數(shù)據(jù)轉(zhuǎn)換調(diào)用
????????調(diào)用的函數(shù)比較簡(jiǎn)單,這里采用test的測(cè)試用例調(diào)用為例進(jìn)行講解,當(dāng)然這里不限于使用何種方法。
@Test
public void testBoundaryConvert() {/*區(qū)域一為下列4點(diǎn)連線水域: 25°15′26"N/120°29′20"E,24°50′30"N/120°05′45"E,25°04′32"N/119°51′22"E,25°28′12"N/120°14′30"E區(qū)域二為下列4點(diǎn)連線水域: 26°07′00"N/121°57′00"E,25°30′00"N/121°57′00"E,25°30′00"N/121°28′00"E,26°07′00"N/121°28′00"E 區(qū)域三為下列4點(diǎn)連線水域: 25°34′00"N/122°50′00"E,25°03′00"N/122°50′00"E,25°03′00"N/122°11′00"E,25°34′00"N/122°11′00"E 區(qū)域四為下列4點(diǎn)連線水域: 22°56′00"N/122°40′00"E,23°38′00"N/122°51′00"E,23°38′00"N/123°23′00"E,22°56′00"N/123°09′00"E 區(qū)域五為下列4點(diǎn)連線水域: 21°14′00"N/121°33′00"E,21°33′00"N/121°18′00"E,21°07′00"N/120°43′00"E,20°48′00"N/120°59′00"E 區(qū)域六為下列4點(diǎn)連線水域: 22°43′00"N/119°14′00"E,22°10′00"N/119°06′00"E,21°33′00"N/120°29′00"E,22°09′00"N/120°32′00"E */List<String> bboxList = new ArrayList<String>();bboxList.add("25°15′26\"N/120°29′20\"E,24°50′30\"N/120°05′45\"E,25°04′32\"N/119°51′22\"E,25°28′12\"N/120°14′30\"E");//區(qū)域一bboxList.add("26°07′00\"N/121°57′00\"E,25°30′00\"N/121°57′00\"E,25°30′00\"N/121°28′00\"E,26°07′00\"N/121°28′00\"E");//區(qū)域二bboxList.add("25°34′00\"N/122°50′00\"E,25°03′00\"N/122°50′00\"E,25°03′00\"N/122°11′00\"E,25°34′00\"N/122°11′00\"E");//區(qū)域三bboxList.add("22°56′00\"N/122°40′00\"E,23°38′00\"N/122°51′00\"E,23°38′00\"N/123°23′00\"E,22°56′00\"N/123°09′00\"E");//區(qū)域四bboxList.add("21°14′00\"N/121°33′00\"E,21°33′00\"N/121°18′00\"E,21°07′00\"N/120°43′00\"E,20°48′00\"N/120°59′00\"E");//區(qū)域五bboxList.add("22°43′00\"N/119°14′00\"E,22°10′00\"N/119°06′00\"E,21°33′00\"N/120°29′00\"E,22°09′00\"N/120°32′00\"E");//區(qū)域六int index = 1;for(String bbox : bboxList) {System.out.println("區(qū)域"+index+"位置字符串:" + bbox);str2Point(bbox);System.out.println("--------------------------------------------------------------");index ++;}}
????????在控制臺(tái)中執(zhí)行上述代碼之后,可以看到以下結(jié)果,說(shuō)明執(zhí)行成功,同時(shí)數(shù)據(jù)均已成功的轉(zhuǎn)換。
????????解析的數(shù)據(jù)內(nèi)容如下(取其中的一個(gè)點(diǎn)為例):
區(qū)域1位置字符串:25°15′26"N/120°29′20"E,24°50′30"N/120°05′45"E,25°04′32"N/119°51′22"E,25°28′12"N/120°14′30"E
25°15'26"N/120°29'20"E = (25.2572222,120.4888889)
24°50'30"N/120°05'45"E = (24.8416667,120.0958333)
25°04'32"N/119°51'22"E = (25.0755556,119.8561111)
25°28'12"N/120°14'30"E = (25.47,120.2416667)
?????????在經(jīng)過(guò)上述的方法將度分秒坐標(biāo)轉(zhuǎn)換為標(biāo)準(zhǔn)經(jīng)緯度坐標(biāo)后,我們就可以將坐標(biāo)疊加到Leaflet當(dāng)中進(jìn)行空間展示,下一節(jié)來(lái)深入闡述。
二、WebGIS展示空間位置信息
????????當(dāng)我們得到了經(jīng)過(guò)轉(zhuǎn)換過(guò)的空間標(biāo)準(zhǔn)經(jīng)緯度坐標(biāo)信息后,我們就可以將這些空間數(shù)據(jù)轉(zhuǎn)換為面數(shù)據(jù)或者點(diǎn)數(shù)據(jù),然后使用WebGIS框架,比如Leaflet等進(jìn)行信息的幾種展示。
1、定義底圖
????????定義定圖的方法非常簡(jiǎn)單,這里我們直接給出在應(yīng)用程序中使用天地圖的方法,請(qǐng)注意如果在拷貝這里的代碼時(shí),一定要注意替換這里的令牌。
var map = L.map('mapid').setView([23.785345, 120.948486], 7);var tdt_client_key = "473af7dc18cafb6b993616a0ce8e1ead";//天地圖客戶端的keyL.tileLayer('http://t0.tianditu.gov.cn/img_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=' +tdt_client_key, {maxZoom: 18,attribution: 'Map data © <a href="http://www.tianditu.gov.cn/">TianDiTu</a>, <a href="http://www.esri.com/">Esri</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>'
}).addTo(map);//標(biāo)簽
L.tileLayer('http://t1.tianditu.gov.cn/cva_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cva&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk='+ tdt_client_key, {maxZoom: 18
}).addTo(map);
2、Polygon的可視化
????????在定義的基礎(chǔ)的底圖之后,下面將第一節(jié)轉(zhuǎn)換好的所有的坐標(biāo)進(jìn)行Polygon空間展示。關(guān)鍵代碼如下:
var style = {"color":"red","fillColor":"red","weight":2};L.polygon([[25.2572222,120.4888889],[24.8416667,120.0958333],[25.0755556,119.8561111],[25.47,120.2416667]],style).addTo(map).bindPopup("區(qū)域一.");L.polygon([[26.1166667,121.95],[25.5,121.95],[25.5,121.4666667],[26.1166667,121.4666667]],style).addTo(map).bindPopup("區(qū)域二.");L.polygon([[25.5666667,122.8333333],[25.05,122.8333333],[25.05,122.1833333],[25.5666667,122.1833333]],style).addTo(map).bindPopup("區(qū)域三.");L.polygon([[22.9333333,122.6666667],[23.6333333,122.85],[23.6333333,123.3833333],[22.9333333,123.15]],style).addTo(map).bindPopup("區(qū)域四.");L.polygon([[21.2333333,121.55],[21.55,121.3],[21.1166667,120.7166667],[20.8,120.9833333]],style).addTo(map).bindPopup("區(qū)域五.");L.polygon([[22.7166667,119.2333333],[22.1666667,119.1],[21.55,120.4833333],[22.15,120.5333333]],style).addTo(map).bindPopup("區(qū)域六.");
????????請(qǐng)注意,在上述的例子中,我們使用一個(gè)統(tǒng)一的樣式選型,style,它表示展示的Polygon面的顏色和填充顏色都是紅色,如果您想設(shè)置自己喜歡的顏色也是可以的。
3、實(shí)際效果
????????經(jīng)過(guò)上述的兩個(gè)步驟,我們已經(jīng)實(shí)現(xiàn)了地圖對(duì)象的定義和綁定,同時(shí)我們將轉(zhuǎn)換好的坐標(biāo)信息進(jìn)行賦值,讓6個(gè)面在地圖上進(jìn)行可視化。
????????以上的紅色區(qū)域就是我們轉(zhuǎn)換的六個(gè)區(qū)域,不知道大家看了這六個(gè)區(qū)域,有沒(méi)有勾起點(diǎn)啥記憶呢。 這里不多說(shuō),大家可以去相關(guān)網(wǎng)站搜索這個(gè)區(qū)域之前發(fā)生過(guò)什么就大致清楚了。
三、總結(jié)
????????以上就是本文的主要內(nèi)容,本文即以Leaflet為例,重點(diǎn)講解如何將上述的空間信息轉(zhuǎn)換為可以在地圖上瀏覽的位置信息。首先使用Java語(yǔ)言將上面的涉及的空間坐標(biāo)(度分秒)調(diào)整為常見(jiàn)的經(jīng)緯度坐標(biāo)。然后根據(jù)不同的點(diǎn)連接成多個(gè)面,最后將這些Polygon面數(shù)據(jù)疊加到Leaflet中,從而實(shí)現(xiàn)航行警告中的相關(guān)區(qū)域和地圖的融合。通過(guò)本文,您可以掌握怎么使用Java把度分秒坐標(biāo)轉(zhuǎn)為標(biāo)準(zhǔn)格式,還可以掌握在Leaflet當(dāng)中如何把這些Polygon進(jìn)行空間疊加。行文倉(cāng)促,定有不足之處,真誠(chéng)期待各位專家朋友在評(píng)論區(qū)批評(píng)指正,不甚感激。