0

我有一个 modis hdf 文件,mcd19a2 产品。这些文件是使用正弦投影存储的。然后将图块划分为 1200 x 1200 网格(或者在 1200 x 1200 矩阵中,你可以说)。经度和纬度数据也被存储,但不是在 WG84 纬度/经度值中。它们以米为单位。我想从特定文件中提取 lat 和 on 信息,然后将其转换为 wg84 lat/lon。我正在使用 MATLAB 版本 2021。

这是一个函数,我使用的是“findindex”。问题是瓷砖是在正弦投影中进行的,即它具有不同的左上角和左下角经度值,而从代码中,我得到了相似的值。

我正在使用的文件 MCD19A2.A2021121.h24v06.006.2021124142622.hdf https://drive.google.com/file/d/1g1hnNFIeSef8C17L_6Mq8g0RaJxe1mW1/view?usp=sharing

关于上下纬度/经度的纬度/经度信息如下:

iv ih 0: ll lon ll lat 1: ul lon ul lat 2: ur lon ur lat 3: lr lon lr lat

6 24 63.6095 19.9322 69.0253 30.0331 80.8440 29.9993 74.4929 19.9002

我用来转换的代码;

%Delhi coordinates
% LatLon=[28.8855033,76.837768;28.416234,77.329407]


filename='./MCD19A2.A2021121.h24v06.006.2021124142622.hdf';
proj=1;

% if nargin < 3
%    disp(['Error! three mandatory input arguments are required for this '...
%        'function, please see Function Description for more information']); 
%    return
% end
projType={'Sinusoidal'; 'Global Cylindrical Equal-Area'};

if proj>2
    coordX_idx=0; coordY_idx=0; projType='Wrong projType';
    msgbox(sprintf([' "proj = %d" does not match any acceptable projection '...
        'types, only 1: Sinusoidal, and 2: Cylindrical Equal-Area Scalable '...
        'Earth Grid (EASE) are accepted by this function; '...        
        ' please try again'],proj),...
        'Invalid projection type requested!','Error','modal');
    return     %abort code if mismatch detected
end

% Specify Earth's Equatorial Radius based on the Projection Type:
if proj==1
    R=6371007.181; %Radius of Earth in meters (Sinusoidal)
    %False Easting: 0.0
    %False Northing: 0.0
    %ISin NZone: 86400 (see
    %http://geospatialmethods.org/documents/ppgc/ppgc.html)
elseif proj ==2
    R = 6371228; %m R of Earth (EASE & all spherical projns, no eccent.)
    %All spherical projns, eccentricity should not be specified, and 
    %the default equatorial radius is 6371228 m.
else %more projections to work out:
    R=6378137.0; %R Earth (m), WGS84 ellipsoid (eccentricity: 0.081819190843)
    %All elliptical projtns: eccent. 0.082271673 & R 6378206.4 (defaults).    
end

% Circumference of a circle: %C=pi*d so C=pi*R*2
C=pi*(R*2); %circumference of Earth in Equator (meters)
dist1degree=C/360;%metric distance equivalent to 1 degree in Equator



lambda0=0;
% read HDF EOS file information from the given file:
% http://www.mathworks.com/company/newsletters/digest/nov02/earth_pt3.html
% left-right-top-botton bounds and rows-columns of the HDF file are needed
geoInfo = hdfinfo(filename,'eos');    % HDF file info in EOS mode
xDim=geoInfo.Grid(1).Columns;         % columns of data
yDim=geoInfo.Grid(1).Rows;            % rows of data
ULx0=geoInfo.Grid(1).UpperLeft(1);     % UpperLeft bound X
LRx0=geoInfo.Grid(1).LowerRight(1);    % LowerRight bound X
ULy0=geoInfo.Grid(1).UpperLeft(2);     % UpperLeft bound Y
LRy0=geoInfo.Grid(1).LowerRight(2);    % LowerRight bound Y

% add offset: 
xOffset =0;%offset (false Easting)
yOffset =0;%offset (false Northing)

% reformat UL/LR corners
LRx=abs(LRx0 - ULx0); %let LRx as the largest x in dataset 
LRy=abs(LRy0 - ULy0); %let LRy as the largest y in dataset 
ULx=ULx0 - ULx0;      %turn ULx as origin and let it be 0
ULy=ULy0 - ULy0;      %turn ULy as origin ane let it be 0
%LLy=LRy;              %LLy is the same as LRy (not needed)
%LLx=ULx;              %LLx is the same as ULx (not needed)
%ULx=ULx0;ULy=ULy0;LRx=LRx0;LRy=LRy0; %no change (diagnostic)

% calculate resolution across X and Y:
xRes=(LRx-ULx)/xDim;  %resolution along x (longitude) in meters(positive)
%yRes=(ULy-LLy)/yDim;  %resolution along y (latitude) in meters(negative)
yRes=(LRy-ULy)/yDim;  %resolution along y (latitude) in meters(positive)

% determine where to start searching points x-y; since the coordinates
% start from UL corner of pixel, but we want center of pixel, xRes/2 or
% yRes/2 will be added to the start2look point:
xStartLooking=ULx+xRes/2; %start looking from UL corner 
yStartLooking=ULy+yRes/2; %start looking from UL corner

n=size(LatLon,1);      %number of points to look for
coordX_idx=zeros(n,1); %point's x index in HDF file: initialize to 0
coordY_idx=zeros(n,1); %point's y index in HDF file: initialize to 0
mdist2point=ones(n,1)*(abs(xRes)+abs(yRes))*10;

% start looking for all points based on Lat-Lon coordinates:
for i2=1:n
    phi=LatLon(i2,1);    %latitude coordinate
    lambda=LatLon(i2,2); %longitude coordinate

    
    if proj == 1 % Sinusoidal Projection:
        x=(lambda-lambda0)*cos(phi*pi/180);%lon in Sin proj in local lat
        y=phi;   %latitude in Sin projection
        x=abs(x*dist1degree-ULx0); %valid for north america as in discussion (conclded above equator)
y=abs(y*dist1degree-ULy0); %
%         x=abs(x)*dist1degree-abs(ULx0); %x in m in Global Sin proj (for
%         newzealand, below equator)
%         y=abs(y)*dist1degree-abs(ULy0); %y in m in Global Sin proj
     xMax=180*cos(phi*pi/180); %max longitude in Sin proj in local lat    
     %cLocal=C*(xMax*2)/360; %circumference of Earth in local latitude (m)
     %dist1degLocal = cLocal/360;%metric dist = 1 deg in local lat 
    elseif proj ==2 % EASE projection:
        % Formula (http://nsidc.org/data/ease/ease_grid.html):
        % �r = r0 + R/C * lambda * cos(30)
        % �s = s0 - R/C * sin(phi) / cos(30)
        % �h = cos(phi) / cos(30)
        % �k = cos(30) / cos(phi)
        % r Column coordinate
        % s Row coordinate
        % h Particular scale along meridians
        % k Particular scale along parallels
        % lambda Longitude in radians (lambda*pi/180)
        % phi Latitude in radians (phi*pi/180)
        % R Radius of the Earth = 6371.228 km in Equator
        % C Nominal cell size
        % r0 Map origin column
        % s0 Map origin row
        %Note: true latitude (30) must also be converted to radians
        r0=floor(xDim/2);
        s0=floor(yDim/2);
        r_x = r0 + R/xRes * (lambda*pi/180) * cos(30*pi/180); %x coord in EASE proj
        s_y = s0 - R/yRes * sin(phi*pi/180) / cos(30*pi/180); %y coord in EASE proj
        %h=cos(phi*pi/180)/cos(30*pi/180);%scale along meridians(not needed)
        %k=cos(30*pi/180)/cos(phi*pi/180);%scale along parallels(not needed)
        x=r_x*xRes; % x in Metric scale
        y=s_y*yRes; % y in Metric scale       
    end
    
    % Now search for the nearest pixel to the given coordinates:
    xMetric=x+xOffset;   %x coordinate in meters adjusted for add-offset
    yMetric=y+yOffset;   %y coordinate in meters adjusted for add-offset
    distInitial=(abs(xRes)+abs(yRes))*10; %approx initial dist based on grid res
    pixelX=xStartLooking; %initial pixel x to check the distance
    for i=1:xDim
        pixelY=yStartLooking; %initial pixel y to check the distance
        for j=1:yDim
            sq1=(pixelY-yMetric)^2; % lat part of dist func
            sq2=(pixelX-xMetric)^2; % lon part of dist func
            dFound=sqrt(sq1+sq2);   % distance function   
            sq1fo(i,j)=sq1;
            sq1foww(i,j)=pixelY;
            
            sq2fo(i,j)=sq2;
            sq2foww(i,j)=pixelX;
            dfo(i,j)=dFound; %store distances (diagnostic)
          
            
            if dFound<distInitial
                coordX_idx(i2)=i;   % point's x index in HDF file (returned)
                coordY_idx(i2)=j;   % point's y index in HDF file (returned)
                distInitial=dFound; % replace initial dist with found dist
            end
            pixelY=pixelY+yRes;  % move 1 pixel forward along Lat
        end
        pixelX=pixelX+xRes;      % move 1 pixel forward along Lon
    end
    mdist2point(i2)=distInitial; %distance from given point to its closest  
    %pixel (indexes of which are given in coordX_idx & coordY_idx)
end
% lat_deg= sq1foww+ULx0 ;
% lat_deg1=(sq1foww./dist1degree)+ULx0;
% check_lat=(1200*xRes)+ULx0;

converting back to lat and lon

for i=coordY_idx
    ws_lat=abs((sq2foww-ULy0)./dist1degree);%Lattitude conversion of metres sin proj
                                            % to wsg84 datum coordinate
                                            % system
end
% 
for i=1:xDim
ws_lon=abs((sq1foww1+ULx0)./dist1degree); %longitude conversion from sin proj
factor_lat=cos(ws_lat*pi/180); % to wsg84 datum cooridnate system
factor_lat1=factor_lat.';
ws_lon1=ws_lon./factor_lat1;   % final conversion of lon

end

请建议。如果有任何其他简单的方法可以做到这一点。

4

0 回答 0