干货分享 | 配图版:标准中国地图的绘制
2017年1月,阿里巴巴官方推特在马云和特朗普会面后发表了一条官方推特以此说明中美小企业和消费者之间的贸易机会。细心的网友发现该推特配图(如图1(a)所示)中的中国地图并不是标准的中国地图,缺少了台湾岛及附属岛屿、南海诸岛等部分版图,这一失误迅速引起了舆论关注。此后,阿里巴巴官方微博、推特同步发表声明致歉,并更新了相关配图。
图1 阿里巴巴官方推特先后发布的中美地图
阿里巴巴官方微博称:对不起,我们犯了一个低级错误。在马云和美国当选总统会面之后,我们发布了一张图片,想说明中美小企业和消费者之间的贸易机会和前景。但这张图(如图1(a)所示)我们不仅漏掉了美国的夏威夷和阿拉斯加,也漏掉了我们国家的宝岛台湾。对这个错误我们不做任何辩解,只能立即修正, 并在此向大家深深致歉。与此同时,阿里巴巴官方推特也同步更新了配图(如图1(b)所示)。
可见,中国标准地图的绘制尤为重要,涉及到国家的领土主权。标准的中国地图如图2所示。使用中国地图最常见的问题有四个:
1 中国台湾部分的缺失;
2 南海与九段线的缺失;
3 西藏交界的中印边界划分有误;
4 新疆与西藏交界的中印边界划分有误;
图2. 标准中国地图[1]
中国地图GIS数据的官方数据可以在国家基础地理信息中心的网站(http://nfgis.nsdi.gov.cn)里面可以免费下载。官方公开的数据包括:地图数据,及居住地、交通、河流等辅助数据。地图数据有4个压缩文件:bou1_4m.zip、bou2_4m.zip、bou3_4m.zip和bou4_4m.zip。bou代表边界的意思,数字1~4代表国家、省、市、县的4级行政划分;4m代表比例是400万分之一,这个比例的图形是公开的。每个文件解压缩后含有两类文件:以字母p结尾的表示多边形数据,用来绘制区域;以字母l结尾的文件是线形数据,用来绘制边界。
根据官方提供的中国地图数据bou2_4p.shp,绘制的省级中国地图如图所3(a)示,但是存在的问题是并没有提供中国南海的八段线的线条绘制数据,由于南海诸岛的面积较小,如果不使用八段线标记的话,有时候如果地图展示面积太小的话,南海诸岛就几乎难以辨清。所以笔者在现有地图的基础上,添加八段线的绘制数据,如图3(b)所示。由于南海地区较大,为了减小中国地图的展示面积,同时强调中国陆地主体部分,一般将中国南海连同八段线部分截取成长方块,放置在中国台湾的旁边,如图3(c)所示。
图3. 标准中国地图的八段线演变过程
但是,如果国家基础地理信息中心的GIS地图数据的地市文件bou3_4m.zip中含有polygon文件,那么我们就可以根据上一节的内容绘制省内地市级分布图了。官方恰恰缺少了这个文件,给绘图造成了麻烦。解决方案有两个:一个是另辟蹊径,从非官方的www.gadm.org下载一份shp格式的中国地图来绘制;另一个解决方案是从官方发布的县级地图入手,根据ADCODE99编码适当合并,绘制省内地市分布图,同时利用bou3_4m.zip仅存的边界文件绘制边界。
图4. 不同行政级别的中国地图。
(a) 中国国界地图;(b)中国省级地图;(c)中国市级地图;(d)中国县级地图
其中,每个省市自治区极其附属岛屿都是使用一个多边形表示,每个多边形都对应唯一的ID,编号从1到925(由于部分省份拥有多个附属岛屿。省份中文名(NAME)字段是以GBK编码的ADCODE99是国家基础地理信息中心定义的区域代码,共有6位数字,由省、地市、县各两位代码组成。
核心技能
R语言sf包的st_read()函数和rgdal包提供readOGR()函数可以读入shapefile格式(.shp)的地图数据。地图数据基本可以分为点、线、面三种数据。而R的maptools包readShapePoints()、readShapeLines()和readShapePoly()函数已经弃用(deprecated)。图3(c)带中国南海部分的省级地图具体实现代码如下:
(a) 中国省份分级统计地图
(b) 中国县级分级统计地图
图5. 中国不同级别的统计地图
library(rgdal) #提供readOGR()函数
library(ggplot2)
library(dplyr)
library(RColorBrewer)
dataProjected <- readOGR("./bou2_4m/bou2_4p.shp")
dataProjected@data$id <- rownames(dataProjected@data)
watershedPoints <- fortify(dataProjected)
df_China <- full_join(watershedPoints, dataProjected@data, by = "id")
df_China$class<-rep("Mainland",nrow(df_China))
mydata <- read.csv("Province_Data.csv")
#mydata为33 X 3的表格数据,列名分别为:NAME,province,Value
#.csv数据下载:https://github.com/EasyChart/Original_Data
df_China<-full_join(df_China,mydata,type="full")
#---------------------df_Nanhai:Nanhai Region-----------------------------------
Width<-9
Height<-9
long_Start<-124
lat_Start<-16
df_Nanhai<-df_China[df_China$long>106.55 & df_China$long<123.58,]
df_Nanhai<-df_Nanhai[df_Nanhai$lat>4.61 & df_Nanhai$lat<25.45,]
min_long<-min(df_Nanhai$long, na.rm = TRUE)
min_lat<-min(df_Nanhai$lat, na.rm = TRUE)
max_long<-max(df_Nanhai$long, na.rm = TRUE)
max_lat<-max(df_Nanhai$lat, na.rm = TRUE)
df_Nanhai$long<-(df_Nanhai$long-min_long)/(max_long-min_long)*Width+long_Start
df_Nanhai$lat<-(df_Nanhai$lat-min_lat)/(max_lat-min_lat)*Height+lat_Start
df_Nanhai$class<-rep("NanHai",nrow(df_Nanhai))
df_China<-rbind(df_China,df_Nanhai)
#---------------------df_NanHaiLine:Nanhai Line-----------------------------------
df_NanHaiLine <- read.csv("中国南海九段线.csv")
colnames(df_NanHaiLine)<-c("long","lat","ID")
df_NanHaiLine$long<-(df_NanHaiLine$long-min_long)/(max_long-min_long)*Width+long_Start
df_NanHaiLine$lat<-(df_NanHaiLine$lat-min_lat)/(max_lat-min_lat)*Height+lat_Start
#-----------------------中国省份分级统计地图-----------------------
ggplot()+
geom_polygon(data=df_China, aes(x=long, y=lat, group=interaction(class,group),fill=Value),colour="black",size=0.25)+
#中国地图,包括中国主体部分和长方形方块内的南海诸岛数据
geom_rect(aes(xmin=long_Start, xmax=long_Start+Width+0.3, ymin=lat_Start-0.3, ymax=lat_Start+Height),fill=NA, colour="black",size=0.25)+
#绘制长方形方框
geom_line(data=df_NanHaiLine, aes(x=long, y=lat, group=ID), colour="black", size=1)+
#绘制长方形方框内的中国南海八段线
scale_fill_gradientn(colours = colorRampPalette(rev(brewer.pal(11,'Spectral')))(32))+
coord_cartesian()+
ylim(15,55)+
theme(
legend.position=c(0.15,0.2),
legend.background = element_blank()
)
转载自 EasyCharts,经作者授权转载
文章仅代表作者观点,与本公众号无关,版权归原作者所有
原文标题:配图版:标准中国地图的绘制
排版:鲁嘉颐
责任编辑:李亮
审核:王冠 王波涛 梁龙武
猜你喜欢
2、干货分享 | 地理学精选视频课推荐(含5门国家级精品课),文末更有福利放送!
扫描二维码,关注我们
都是成年人了,要记得告诉地小联你也“在看”哦~👇