空間直角座標轉換成大地座標matlab代碼(附精度)

在實際生產中,通常需要進行空間直角座標和大地座標之間的相互轉換。精度估計是大地測量數據處理的一項內容,而目前使用的的座標轉換軟件中一般都沒有提供空間直角座標與大地座標之間轉換的精度。其中,空間直角座標至大地座標的轉換常用的迭代法可以表示爲:
在這裏插入圖片描述
在文章《空間直角座標與大地座標的精度關係式_徐思達》中,作者論通過誤差傳播律推導了由空間直角座標轉到大地座標的精度,分析了嚴密公式和簡便公式的精度轉換結果的差異,發現兩者只有微小差異,所以可以用簡便公式。根據其提供的公式,用matlab編寫程序實現。

function [llh, sigmallh ] = xyz2llh222(xyz,sigmaxyz)
%
%     ... Transform from x,y,z to lat,lon,h
%   精度公式爲  《空間直角座標與大地座標的精度關係式_徐思達》一文中的簡便公式
%

deg2rad = pi/180;
a = 6378137;
f = 1/298.257223563;%扁率 
e2 = 2*f - f*f;%第一偏心率
rou=180*3600/pi;

[junk,num] = size(xyz);

for i = 1:num,
   p = sqrt(xyz(1:2,i)'*xyz(1:2,i));
   r = sqrt(xyz(:,i)'*xyz(:,i));
   lon = atan2(xyz(2,i),xyz(1,i));
%
%     ... First iteration on lat and h
%            - assumes h = 0
%
   lat = atan2(xyz(3,i)/p,(1-e2));
   n = a/sqrt((1 - e2*sin(lat)^2));
   m = (a*(1-e2))/sqrt((1 - e2*sin(lat)^2));
   h = p/cos(lat) - n;
   %%%以下公式爲參考文獻中的簡便公式
   jian1 = (m+h)^2;
   jian2 = ((n+h)*cos(lat))^2;
   sigx2 = sigmaxyz(1,i)^2;
   sigy2 = sigmaxyz(2,i)^2;
   sigz2 = sigmaxyz(3,i)^2;
   
   siglat =(sin(lat)*cos(lon))^2/jian1*sigx2+(sin(lat)*sin(lon))^2/jian1*sigy2+cos(lat)^2/jian1*sigz2;
   sigmalat=rou*sqrt(siglat);        
   siglon=sin(lon)^2/jian2*sigx2+cos(lon)^2/jian2*sigy2;
   sigmalon=rou*sqrt(siglon);
   sigh=(cos(lat)*cos(lon))^2*sigx2+(cos(lat)*sin(lon))^2*sigy2+sin(lat)^2*sigz2;
   sigmah=sqrt(sigh);
%
%        ... Iterate until h converges (should be quick since h << n)
%
   oldh = -1e9;
   iter = 0;
   num = xyz(3,i)/p;
   while abs(h - oldh) > 0.0001,
      iter = iter + 1;
      oldh = h;
      den = 1 - e2*n/(n+h);
      lat = atan2(num,den);
      n = a/sqrt((1 - e2*sin(lat)^2));
      h = p/cos(lat) - n;
   end
%
   llh(1,i) = lat/deg2rad;
   llh(2,i) = lon/deg2rad;
   llh(3,i) = h;
   sigmallh(1,i) = sigmalat;
   sigmallh(2,i) = sigmalon;
   sigmallh(3,i) = sigmah;
   
end

可以用下面的代碼實現讀取時間序列文件,完成轉換,並將轉換後的經緯度級精度寫入指定路徑下的新文件中:

clear
file='..\data_xyz\XCNG.xyz';
fid = fopen(file, 'r');  %以只讀的方式打開文件
if (fid  == -1 )
    disp(strcat('Error opening file ', file)); 
else
    c = textscan(fid, '%f %f %f %f %f %f %f %f %f %f %f %f'); % 讀取文件
    fclose(fid);
    yr=c{1};  %第一列爲年份
    mt=c{2};  %第二列爲月份
    dy=c{3};  %第三列爲天數
    
    tm=decyear(yr,mt,dy);

    timeseries.time = tm;
    timeseries.year = yr;
    timeseries.month= mt;
    timeseries.day  = dy;
    ndates = length(timeseries.time);
    t_init = timeseries.time(1);

    timeseries.xyz = zeros(3,ndates);
    timeseries.xyz(1,:) = c{4}';%4 5 6列爲xyz座標
    timeseries.xyz(2,:) = c{5}';
    timeseries.xyz(3,:) = c{6}';
    timeseries.sigmaxyz(1,:)  = c{7}';  %7 8 9列爲精度
    timeseries.sigmaxyz(2,:)  = c{8}';
    timeseries.sigmaxyz(3,:)  = c{9}';
    [timeseries.llh,timeseries.sigmallh] = xyz2llh222(timeseries.xyz,timeseries.sigmaxyz);% 把xyz轉化成經緯度
    timeseries.llh=timeseries.llh';
    timeseries.sigmallh=timeseries.sigmallh';
    
    %生成llh文件
    path_file=file(1:3);
   site=file(13:16);%根據前面的file路徑來 如果前面變動 則此處也需要變動
   paths=[path_file 'llhfile\'];
   pathfile=[paths site];
   name=[pathfile '.llh'];
   fid = fopen(name, 'wt');
   for i = 1:ndates
       fprintf(fid,'%f %f %f %f %f %f %f\n',timeseries.time(i),timeseries.llh(i,1),...
          timeseries.llh(i,2),timeseries.llh(i,3),timeseries.sigmallh(i,1),...
          timeseries.sigmallh(i,2),timeseries.sigmallh(i,3));
   end
   fclose(fid); 
end
    

參考文獻:徐思達, 賈國憲, 王麗紅,等. 空間直角座標與大地座標的精度關係式[J]. 北京測繪, 2018.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章