新浪博客

【转】matlab中地图边界与掩膜(去掉边界外区域)的实现(基于shape文件)

2014-04-10 22:10阅读:
论坛有很多人问到过这个问题,解决这个问题也有助于matlab在地学中的应用,前天LZ花了几个小时看help map的文字(英语要学好啊!!! ),粗略地研究了一下,总算找到了几个有用的函数,现在把函数和做法分享给大家,以下是一张效果图(网格大小的关系,还是有些地方空了多了~):
【转】matlab中地图边界与掩膜(去掉边界外区域)的实现(基于shape文件)
首先是论坛里的一些资源,其实绘制地理类的图形,我一般都推荐用grads、ArcGis(不是很熟悉就不提NCL、surfer和MeteoInfo等等啦,论坛里关于这几个软件的帖子也很多
,不一一举例了)~有关这两个软件底图制作和绘制在论坛里面有很详细的教程,大家可以参考(grads中maskout方法ArcGis底图制作ArcGis站点绘图参考),而有关matlab底图方法,我估计m_map工具箱中会有一些解决方法,但是也不是很熟悉,我就用matlab自带的map工具箱中的函数进行处理了(不清楚各版本有没有装,改天看到工具箱下载的时候我共享一下)。
一、预备知识:
1.地理参考(R):地理参考(具体内容可在help大部分map工具箱中的函数得到)是指定位矩阵用的矩阵,通常为3*2的矩阵,通过公式
[lon lat] = [row col 1] * R(3*2) (具体实例见第三部分中程序框)
对矩阵的行列坐标与经纬度进行转换(也有1*3的形式,有兴趣的朋友可以自己了解一下),是map工具箱处理地理数据的基础;
2.矢量数据:一般矢量数据分为多边形、线和点数据,我们这里采用的shape文件的多边形数据是利用线数据定义边界的,在matlab里shape文件以结构数组的形式保存,其中经纬度信息保存在X与Y属性中;
3.2-D矩阵数据:由行标(row)和列标(col)来表示位置的数据,需要通过坐标系来对数据进行对应进行绘图,常用的绘图参考方式有meshgrid函数生成的参考系和map中的地理参考(R);
4.matlab中NAN(空值)的运算规则:NAN值除赋值外的任何数学运算返回值为NAN,如NAN+1=NAN,NAN*0=NAN
5.在map工具箱中,注意应用部分函数习惯是先引用纬度值,再引用经度值,需要注意分别此类函数。
二、边界线的制作:
1.读取文件:map=shaperead(filename):读取shape文件,这里建议读取多边形文件,通用些。shape文件大陆部分的获取可以由清风提供的网址获取,不过注意边境问题哦~另外要再做气候区或者若干地区的底图,用ArcGis分析工具等都可以做,可以见ArcGis相关教程,这里顺便贡献一个ArcGis的中文帮助网址
2.绘制你所要绘制的图形:这个不多说,要画什么画什么,一般是绘制等值线图,用contour或contourf画,有人也许会问需不需要用contourm画,其实随便,两者的区别是前者用meshgrid生成的坐标系来绘图,后者通过地理参考(R)或者经纬度数据绘图,对matlab来说成图都一样。
3.加入边界线:
hold on
plot(map.X,map.Y,option)
hold off
就是普通的加线了,没什么特别的,option是可选的参数,美化一下绘图而已。
三、掩膜的制作:
1.读取文件,同上1;
2.生成掩膜文件:
R=makerefmat('Rastersize',size(Z),'Latlim',[lat_first lat_last],'Lonlim',[lon_first lon_last]):其中Z是你要绘图的矩阵,Latlim和lonlim两个参数确定你要画全图的经纬度范围。这个函数是在后面转换数据时候用的,它的函数形式不止这一个(见help),但是我选这个用,具体原因大家可以尝试对比一下,因为直接使用定义经纬度起始点和经纬度点密度的方法生成的矩阵会出现少边界点的情况,而如上方式定义地理参考会产生一个缩减量使size(R)=size(Z);
注意:鉴于有朋友提醒,2008版前的matlab中makerefmat可能没有'RasterSize'参数的设置,我试了一下,以下提供上面所用方式与R=makerefmat(x0,y0,dx,dy)通用方式的转换:
转换要点:
1.步长dx、dy由绘图范围和绘图格点总数的比值确定;
2.起始经纬度为绘图范围的左下角经纬度值加上半步长值
例如:
R=makerefmat('RasterSize',size(Z),'Lonlim',[97 107],'Latlim',[21 30])
等价于
R=makerefmat(97+(107-97)/size(Z,1)/2,21+(30-21)/size(Z,2)/2,(107-97)/size(Z,1),(30-21)/size(Z,2))
  1. >> R=makerefmat('RasterSize',size(Z),'Lonlim',[97 107],'Latlim',[21 30])

  2. R =

  3. 0 0.0989
  4. 0.0990 0
  5. 96.9505 20.9505

  6. >> R=makerefmat(97,21,0.1,0.1)

  7. R =

  8. 0 0.1000
  9. 0.1000 0
  10. 96.9000 20.9000

复制代码
MASK=vec2mtx(map.Y,map.X,Z,R,'filled'):产生了一个与绘图矩阵Z同阶的,map多边形区域外赋值为2,多边形边界赋值为1,多边形内赋值为0的矩阵,同样,vec2mtx函数也有其他输入形式,不过会有与上面地理参考生成时同样的问题,具体见help;
最后,将MASK中值>1的区域设置为nan,边界设置为0,掩膜制作完成
3.绘图方法:绘图时绘制矩阵为(Z+MASK),我这里使用的是加法方法,在2中掩膜设置方法改变一下就可以设置乘法方法的掩膜,原理同样是基于NAN与任何数的数学运算结果为NAN。
附上绘制上面那幅图的源程序,其中EOF_used是降水数据EOF的第一向量,gy_locat是站点的站点号和经纬度信息:

  1. [lon lat]=meshgrid([97:0.1:107],[21:0.1:30]);
  2. Z=griddata(gy_locat(:,2),gy_locat(:,3),EOF_used(:,1),lon,lat,'v4');
  3. yunnan=shaperead('D:\myitem\arcgis\yunnan.shp');

  4. R=makerefmat('RasterSize',size(Z),'Lonlim',[97 107],'Latlim',[21 30]);
  5. MASK=vec2mtx(yunnan.Y,yunnan.X,Z,R,'filled');
  6. MASK(find(MASK>1))=nan;
  7. MASK(find(MASK==1))=0;

  8. contourf(lon,lat,Z+MASK,30);
  9. shading flat
  10. colorbar

  11. hold on
  12. plot(yunnan.X,yunnan.Y,'-k','linewidth',3)
  13. hold off

复制代码
不过在绘图过程中shading flat有时候会出现报错信息,这个就不是很清楚原因了,请各路大神指教~不过转换方法本身应该没什么问题。
写在最后:大家要是有什么好的matlab掩膜或者边界线制作的方法都跟上一贴吧,我也学习学习,交流一下。这个是折腾好久才弄出来的,只是map工具箱的冰山一角,希望大家也多有探索精神,利用身边的资源哈~相信matlab在地学绘图中的应用会走得更远。

我的更多文章

下载客户端阅读体验更佳

APP专享