使用Matlab从.shp文件中提取浙江省内的气象站点

14 篇文章 8 订阅

1.要求

以浙江省为例,从全国气象站中获取浙江省内的气象站。

2.数据格式

2.1 stations.txt

2014年全国45330个气象站数据

第一列是站点编号,第二列是站点经度,第三列是站点纬度,第四列的站点海拔。

data = importdata('stations.txt');

在工作区可以发现data是一个45330*4的矩阵,说明全国有45330个站点(本文使用的气象站点数据是2014年的)。

2.2 浙江省.shp

浙江省shapefile文件包括浙江省shp、shx、dbf文件

map = shaperead('浙江省.shp');

双击工作区中的map变量,可以查看其内部信息如下:

map是一个结构体数组,其中每个数组元素map(i)均包含4个成员变量Geometry、BoundingBox、X、Y。例如,可以使用map(2).BoundingBox获取得到

这里简单介绍一下,map结构体数组将浙江省划分成了90个多边形(Polygon),BoundingBox表示每个多边形的经纬度上下限,即能完全包裹该多边形的最小矩形。

通过搜索90个BoudingBox,可以初步确定能框选浙江省的最小矩形[最大经度 最小经度 最大纬度 最小纬度]。

箭头标注的点也属于浙江省范围(不排除上面有气象站)

3.提取站点

3.1 初步筛选

因此,我们可以由这个矩形进行初步过滤,得到在矩形框内的所有站点,之后再对每个站点进行判断,判断其是否在浙江省内。

station = importdata('stations.txt');
map = shaperead('浙江省.shp');
bound = [map.BoundingBox];% 将90个矩阵合并为一个矩阵
lon = bound(:,1:2:end);   % 取出矩阵的奇数列,即包含经度的列
lat = bound(:,2:2:end);   % 取出矩阵的偶数列,即包含纬度的列
% [min, max] = bounds(a) 返回一维向量a中的最小值和最大值
% b(:)将一个n行*m列的矩阵b转换为n*m行的一维列向量
[lon_min, lon_max] = bounds(lon(:));
[lat_min, lat_max] = bounds(lat(:));
% index1 经度不在矩形范围内的站点索引
index1 = station(:,2) > lon_max | station(:,2) < lon_min;
% index2 纬度不在矩形范围内的站点索引
index2 = station(:,3) > lat_max | station(:,3) < lat_min;
% 将这些站点从矩阵中去除
station(index1|index2,:)=[];

3.2 精确查找

这里介绍一下inpolygon这个函数:

in = inpolygon(xq,yq,xv,yv) 返回 in,以指明 xq 和 yq 所指定的查询点是否在 xv 和 yv 定义的多边形区域的边缘内部或边缘上

在边缘内部或边缘上则 in = 1, 在多边形外部则 in = 0

map结构体中的X和Y用来描述一个多边形区域,相当于上述的xv和yv。因此,我们只需要把站点的经纬度(xq,yq)带入到函数中,逐个判断其是否在多边形内即可。

index = [];                % 记录不在浙江省内的站点索引
for i = 1:length(station)  % 遍历所有站点
    flag = 0;              % 初始化标记为0,表示当前站点不在浙江省内
    for j = 1:length(map)  % 遍历所有多边形
        % 判断该站点是否在该多边形内
        if inpolygon(station(i,2),station(i,3),map(j).X,map(j).Y)
            flag = 1;      % 在多边形内,更新flag=1,表示当前站点在浙江省内
            break;         % 结束循环
        end
    end
    if ~flag               % 站点不在浙江省内
        index = [index; i];% 记录下站点的索引
    end
end
station(index,:)=[];       % 通过站点索引,删除不在浙江省内的站点

最后得到2014年的2205个浙江省内的站点信息数据。

4. 推广

function station = getStationsOfArea(fileMap, fileStation)
%% 作者微信:qczsbwjzjn
%% 时间:2021.04.22
map = shaperead(fileMap);          % 读取shp文件
station = importdata(fileStation); % 读取站点文件
%% 初步缩小范围
bound = [map.BoundingBox];% 将所有BoundingBox矩阵合并为一个矩阵
lon = bound(:,1:2:end);   % 取出矩阵的奇数列,即包含经度的列
lat = bound(:,2:2:end);   % 取出矩阵的偶数列,即包含纬度的列
% [min, max] = bounds(a) 返回一维向量a中的最小值和最大值
% a(:)将一个n行*m列的矩阵a转换为n*m行的一维列向量
[lon_min, lon_max] = bounds(lon(:));
[lat_min, lat_max] = bounds(lat(:));
% index1 经度不在矩形范围内的站点索引
index1 = station(:,2) > lon_max | station(:,2) < lon_min;
% index2 纬度不在矩形范围内的站点索引
index2 = station(:,3) > lat_max | station(:,3) < lat_min;
% 将这些站点从矩阵中去除
station(index1|index2,:) = [];
%% 精确查找
index = [];                % 记录不在map内的站点索引
for i = 1:length(station)  % 遍历所有站点
    flag = 0;              % 初始化标记为0,表示当前站点不在map内
    for j = 1:length(map)  % 遍历所有多边形
        % 判断该站点是否在该多边形内
        if inpolygon(station(i,2),station(i,3),map(j).X,map(j).Y)
            flag = 1;      % 在多边形内,更新flag=1,表示当前站点在map内
            break;         % 结束循环
        end
    end
    if ~flag               % 站点不在map内
        index = [index; i];% 记录下站点的索引
    end
end
station(index,:) = [];     % 通过站点索引,删除不在map内的站点
end

通过调用函数station = getStationsOfArea(fileMap, fileStation)获取任意.shp区域内的站点

% 作者微信:qczsbwjzjn
% 调用样例
station = getStationsOfArea('浙江省.shp', 'stations.txt');

提供文件demo(含浙江省.shp文件,stations.txt文件,getStationsOfArea.m文件, demo.m文件)下载链接

  • 10
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
你可以按照以下步骤使用 MATLAB 对 HDF5 文件进行裁剪: 1. 读取.shp文件使用 `shaperead` 函数读取 .shp 文件,获取裁剪范围的边界坐标。 2. 打开HDF5文件使用 `h5info` 函数打开 HDF5 文件,获取文件的数据集信息。 3. 获取数据集的坐标范围:使用 `h5readatt` 函数或 `h5read` 函数获取数据集的经纬度范围。 4. 计算裁剪范围:根据步骤1和步骤3获取的坐标范围,计算出裁剪范围的经纬度范围。 5. 裁剪HDF5文件使用 `h5read` 函数读取数据集的数据,然后根据计算出的裁剪范围,使用 MATLAB 的索引功能对数据进行裁剪。 下面是一个简单的示例代码,其 `filename` 是 HDF5 文件路径,`shpfile` 是 .shp 文件路径,`datasetname` 是 HDF5 文件的数据集名称: ``` % 读取.shp文件 S = shaperead(shpfile); x = [S.X]; % 获取边界坐标的经度 y = [S.Y]; % 获取边界坐标的纬度 % 打开HDF5文件 info = h5info(filename); dataset = info.Groups(1).Datasets(1); data = h5read(filename, dataset.Name); % 获取数据集的坐标范围 lat_range = h5readatt(filename, dataset.Name, 'lat_range'); lon_range = h5readatt(filename, dataset.Name, 'lon_range'); % 计算裁剪范围 lat_min = min(y); lat_max = max(y); lon_min = min(x); lon_max = max(x); % 裁剪HDF5文件 lat_idx = find(lat_range >= lat_min & lat_range <= lat_max); lon_idx = find(lon_range >= lon_min & lon_range <= lon_max); cropped_data = data(lat_idx, lon_idx); ``` 注意,这只是一个简单的示例,实际操作可能需要进行更多的数据处理和错误处理。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Toblerone_Wind

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值