如何用R繪製地圖中的未定國界(含停火線)

我們在之前推送的《

如何用R語言繪製並填充相對正確的世界地圖

》和《

如何用R語言繪製並填充相對正確的中國地圖

》兩篇文章中曾經提及在用R生成地圖後在送審前需要注意未定國界的繪製問題,我們當時給出的處理建議是在生成高dpi的原圖後用Adobe Illustrator或者Photoshop等專業製圖軟體統一將其修改為未定國界式樣。但作為一個重度強迫症患者,在做完幾期推送後,筆者也一直在琢磨如何在R裡繪製未定國界。筆者曾經以為一勞永逸的方法是申請國家地理資訊公共服務平臺的官方地圖——天地圖tk,然後在QGIS和ArcGIS裡透過WMTS呼叫天地圖的中國地圖和世界地圖的瓦片,下載後將其匯出為shape檔案再用R讀取,但是後續操作極其複雜,且效率和成功率都很低(經常出現無法下載的情況)。作為非GIS專業的學生,這一問題曾經困擾了筆者很長一段時間,直到最近筆者在散步的時候腦海裡突然靈光一現,於是在回到宿舍後開啟電腦查了資料,在此基礎上一試,發現剛才在腦海裡靈光一現的處理方法確實可以有效解決之前的困惑,當即決定寫一篇帖子來與大家分享。在正式行文開始前需要說明兩點:首先,這樣做並不是多此一舉,更不是鑽牛角尖,其現實目的是

更好地繪製出接近自然資源部發布的標準地圖的地圖,以提高含有國界線(行政邊界)地圖的論文/著作在發表/出版前將地圖送審的透過率。其次,本文介紹的方法肯定不是最簡單的,歡迎廣大讀者朋友批評指正。

由於目前市面上出版的中國地圖仍以1989年的國界線為準,因此即便之後中國與周邊國家陸續簽訂了邊界協定,完成了邊界劃定工作,但是有些邊界劃定並未在現行出版的地圖上進行反映或更新,所以我們迄今會看到國內出版的中國地圖(無論是紙質地圖還是電子地圖)在與塔吉克交界處有一段未定國界(如圖1所示):

如何用R繪製地圖中的未定國界(含停火線)

圖1

從本質上來說,在R中實現未定國界的視覺化就是解決多邊形中共享邊(或共享邊中的一部分)的繪製問題,如果我們有現成的共享邊(或共享邊中的一部分)的檔案,則可以在此基礎上快速繪出未定國界(將其設定成虛線或其他非實線的形式即可),這當然是最理想的情況。但如果我們一時間無法拿到這些檔案,則需要綜合利用多種手段,最後再用Adobe Illustrator或Photoshop之類的軟體加以完善。在今天推送的實用技術貼中,我們將給出兩種基本解決方案,分別適合繪製標準中國地圖中的未定國界和其他國家的未定國界。

首先,對於繪製標準中國地圖的未定國界而言,完整透過程式碼處理起來手續比較複雜。因為現行出版地圖中中塔兩國的未定國界只佔中塔全部邊界的一部分,如果全部要用程式碼實現,那麼我們必須從頭到尾弄清楚未定國界的起止範圍。機緣巧合的是,筆者費了很長時間終於找到了未定國界的shp,這樣就為快速實現中塔邊界中未定國界段的繪製奠定了基礎。對此,我們在R中主要用到tidyverse和sf兩個包來完成繪製,具體步驟如下:

# 載入繪製地圖必備的tidyverse和sf兩個包library(tidyverse)library(sf)# 載入中國地圖和未定國界檔案China <- read_sf(“Chinaditu。json”)ChinaUndeterminedBorder <- read_sf(“ChinaUndeterminedBorder”)# 繪製帶有未定國界的標準中國地圖ggplot()+ geom_sf(data = China, colour = “black”, fill = “white”)+ geom_sf(data = ChinaUndeterminedBorder, colour = “white”, linetype = “dotted”)+ coord_sf(crs = “+proj=laea +lat_0=40 +lon_0=104”)+ theme(panel。background = element_blank())

如何用R繪製地圖中的未定國界(含停火線)

圖2

這裡繪製未定國界的原理很簡單,就是利用將交錯顯示的原理,透過將未定國界設色成與其他邊界(黑色)不同的顏色(白色)並設定其形狀為點,疊加到原來的主圖層上即可。

但是如果我們沒有拿到共享邊(部分共享邊)的檔案時該怎麼做呢?下面我們分別以朝鮮韓國兩國以及埃及、蘇丹和南蘇丹三國之間的未定國界為例進行說明。眾所周知,朝韓兩國迄今以軍事停火線(也就是著名的“三八線”)劃定邊界,因此兩國邊界不可以直接按照實線繪製,但是可以參照未定國界的表述方式進行標註,具體步驟如下:

# 載入世界地圖world <- read_sf(“shijieditu”)# 選取世界地圖中的朝鮮和韓國兩國TK <- world %>% filter(country2 %in% c(“South Korea”, “North Korea”))# 重新設定邊界borders <- st_cast(st_geometry(TK), ‘MULTILINESTRING’)border1 <- st_difference(borders[1], borders[2])border2 <- st_difference(borders[2], borders[1])shared <- st_intersection(borders[1], borders[2])# 將兩國的多邊形檔案合併TKnew <- st_union(TK)# 繪製朝鮮韓國及其軍事分界線ggplot()+ geom_sf(data = TKnew, colour = “black”, alpha = 0)+ geom_sf(data = shared, colour = “black”, linetype = “dotted”)+ theme(panel。background = element_blank())

生成的效果如圖3所示:

如何用R繪製地圖中的未定國界(含停火線)

圖3

值得指出的是,上述步驟中最重要的一步就是利用st_union命令將兩個多邊形合併。在完成這一步後,我們也可以按照下面的程式碼(利用ggplot繪圖時層層疊加的原理)達到幾乎同樣甚至是更好的效果(如圖4所示,但也可能存在細微的咬合“錯位”問題):

ggplot()+ geom_sf(data = TKnew, colour = “black”, alpha = 0)+ geom_sf(data = world %>% filter(country2 %in% “South Korea”), colour = “black”, alpha = 0, linetype = “dotted”)+ theme(panel。background = element_blank())

如何用R繪製地圖中的未定國界(含停火線)

圖4

下面我們轉向本文要舉例說明的第三個例子,即蘇丹、南蘇丹和埃及之間的邊界繪製。首先我們將目光投向蘇丹和南蘇丹兩國之間的邊界。2011年,南蘇丹從蘇丹正式獨立,並獲得國際社會的普遍承認,但是兩國之間仍然存在爭議地區,因此邊界當以未定國界表示,繪製步驟和結果如下:

# Sudan and South SudanSSS <- world %>% filter(country2 %in% c(“Sudan”, “South Sudan”))borders <- st_cast(st_geometry(SSS), ‘MULTILINESTRING’)border1 <- st_difference(borders[1], borders[2])border2 <- st_difference(borders[2], borders[1])shared <- st_intersection(borders[1], borders[2])# 將蘇丹和南蘇丹兩國的多邊形檔案合併SSSnew <- st_union(SSS)ggplot()+ geom_sf(data = SSSnew, colour = “black”, alpha = 0)+ geom_sf(data = shared, colour = ‘black’, linetype = “dotted”)+ theme(panel。background = element_blank())

如何用R繪製地圖中的未定國界(含停火線)

圖5

當然這幅地圖上的蘇丹地圖還不是完整的,如下圖所示:它和埃及還存在幾處爭議地區,分別是下圖中的瓦迪哈勒法(Wadi Halfa)尖角和哈拉伊卜(Hala’ib Triangle)三角區,這些因為英國殖民統治導致的兩國之間的領土爭端一直持續至今。此外還有兩國都未提出主權要求的無主地——比爾泰維勒(Bi’r Tawīl)。

如何用R繪製地圖中的未定國界(含停火線)

圖6

圖6底圖來源:

https://zh。wikipedia。org/wiki/%E5%93%88%E6%8B%89%E4%BC%8A%E5%8D%9C%E4%B8%89%E8%A7%92%E5%8C%BA#/media/File:Map_of_Halaib_Triangle-en。png

為了進行比較完整的復原,我們從GADM網站上下載了埃及和蘇丹兩國的地圖作為補充(這裡插句題外話:該網站提供了各個國家和地區比較詳細的行政區劃地圖,

但其中涉及中國的地圖檔案存在嚴重錯誤,如要使用請做必要的修改

),具體步驟和結果如下:

# 讀取從GADM上下載的蘇丹和埃及地圖檔案Sudan <- read_sf(“Sudan”)Egypt <- read_sf(“Egypt”)# 將其疊加到原來的南北蘇丹的邊界圖上ggplot()+ geom_sf(data = world %>% filter(country2 %in% “Egypt”), alpha = 0)+ geom_sf(data = Sudan, linetype = “dotted”, alpha = 0)+ geom_sf(data = SSSnew, colour = “black”, alpha = 0)+ geom_sf(data = Egypt, colour = “black”, alpha = 0, linetype = “dotted”)+ geom_sf(data = shared, colour = “black”, linetype = “dotted”, alpha = 0)+ theme(panel。background = element_blank())

如何用R繪製地圖中的未定國界(含停火線)

圖7

至此我們可以看到爭議地區已經被比較完整地標註出來了。但需要坦誠的是,由於我們還沒有找到兩處爭議領土範圍的精確經緯度,因此依據手頭現有的材料對瓦迪哈勒法尖角以及從比爾泰維勒到哈拉伊卜三角洲的北緯22度線按照未定國界處理比較困難,這裡可以在生成圖片後利用Adobe Illustrator或者Photoshop檔案做靈活處理。當然如果我們有這兩處的精確範圍,則可以參考繪製中國地圖中未定國界的方式透過互動設色的方式加以呈現。

寫到這裡,再跟大家分享一個提高地圖送審透過率的方法,這也是業內人士告訴筆者的。

如果我們寫作的文章/著作中包含的需要送審的地圖只是按照某種指標(如經濟指標、法治指標等)填充設色的中國地圖、各大洲地圖或世界地圖並且我們對各個國家和地區之間行政邊界的把握並不確定時,可以先用R繪製出設色地圖,再將R生成的設色地圖中的顏色透過圖片處理軟體的吸管工具提取出來填充到自然資源部發布的標準地圖底圖中,這樣可以確保各個國家和地區之間行政邊界的繪製完全符合國內出版要求,從而大大提高地圖的過審率。

但是這種方法對需要在地圖上標註包含經緯度的點在內的其他作業時不一定有效(需要考慮投影差異),因此在使用這一方法時需要具體問題具體分析。

最後,我們按照慣例將繪製需要的檔案上傳到網盤

(網盤中是中國地圖的未定國界段以及從GADM上下載的埃及和蘇丹兩國地圖,其中中國地圖和世界地圖檔案可以參考我們在之前推送中上傳的json檔案)

,歡迎大家點選文末“瞭解更多”(提取碼:wdgj)下載使用。我們未來還將陸續推出其他有關資料視覺化的實用技術貼,歡迎各位讀者繼續關注、支援我們。

參考文獻:

[1] 國家測繪地理資訊局地理資訊與地圖司。關於在公開地圖上表示蘇丹和南蘇丹的通知[EB/OL]。2013-03-17。

https://www。zrzyst。cn/gfxwj/327。jhtml

[2] 陸兵。編輯地圖插圖應注意的重點問題[R]。北京:2019

[3] Stackoverflow。The boundary lines between two polygons seems to be different than the outline when plotted using the tmap package[EB/OL]。2019-12-06。

https://stackoverflow。com/questions/59182204/the-boundary-lines-between-two-polygons-seems-to-be-different-than-the-outline-w

[4] 唐繼贊。困擾埃及蘇丹的哈拉伊卜糾紛[J]。瞭望週刊,1992(41):40。

撰文:

楊端程