Changeset 18460
- Timestamp:
- 08/22/14 08:52:44 (11 years ago)
- Location:
- issm/trunk-jpl/src/m/coordsystems
- Files:
-
- 1 added
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk-jpl/src/m/coordsystems/utm2ll.m
r6341 r18460 1 function [Lat,Lon] = utm2ll(xx,yy,utmzone) 2 % ------------------------------------------------------------------------- 3 % [Lat,Lon] = utm2ll(x,y,utmzone) 1 function [lat,lon]=utm2ll(x,y,f,datum,varargin) 2 %UTM2LL UTM to Lat/Lon coordinates precise conversion. 3 % [LAT,LON]=UTM2LL(X,Y,ZONE) converts UTM coordinates X,Y (in meters) 4 % defined in the UTM ZONE (integer) to latitude LAT and longitude LON 5 % (in degrees). Default datum is WGS84. 4 6 % 5 % Description: Function to convert vectors of UTM coordinates into Lat/Lon vectors (WGS84).6 % Some code has been extracted from UTMIP.m function by Gabriel Ruiz Martinez.7 % X and Y can be scalars, vectors or matrix. Outputs LAT and LON will 8 % have the same size as inputs. 7 9 % 8 % Inputs:on) 9 % -3.485713 7.801235 -119.955246 -17.759537 -94.799019 121.640266 10 % For southern hemisphere points, use negative zone -ZONE. 10 11 % 11 % Example 2: If you need Lat/Lon coordinates in Degrees, Minutes and Seconds 12 % [Lat, Lon]=utm2ll(x,y,utmzone); 13 % LatDMS=dms2mat(deg2dms(Lat)) 14 %LatDMS = 15 % 40.00 18.00 55.55 16 % 46.00 17.00 2.01 17 % 37.00 34.00 40.17 18 % 28.00 38.00 44.33 19 % 38.00 51.00 19.96 20 % 25.00 3.00 42.41 21 % LonDMS=dms2mat(deg2dms(Lon)) 22 %LonDMS = 23 % -3.00 29.00 8.61 24 % 7.00 48.00 4.40 25 % -119.00 57.00 18.93 26 % -17.00 45.00 34.33 27 % -94.00 47.00 56.47 28 % 121.00 38.00 24.96 12 % UTM2LL(X,Y,ZONE,DATUM) uses specific DATUM for conversion. DATUM can be 13 % a string in the following list: 14 % 'wgs84': World Geodetic System 1984 (default) 15 % 'nad27': North American Datum 1927 16 % 'clk66': Clarke 1866 17 % 'nad83': North American Datum 1983 18 % 'grs80': Geodetic Reference System 1980 19 % 'int24': International 1924 / Hayford 1909 20 % or DATUM can be a 2-element vector [A,F] where A is semimajor axis (in 21 % meters) and F is flattening of the user-defined ellipsoid. 29 22 % 30 % Author: 31 % Rafael Palacios 32 % Universidad Pontificia Comillas 33 % Madrid, Spain 34 % Version: Apr/06, Jun/06, Aug/06 35 % Aug/06: corrected m-Lint warnings 36 %------------------------------------------------------------------------- 23 % Notice: 24 % - UTM2LL does not perform cross-datum conversion. 25 % - precision is near a millimeter. 26 % 27 % 28 % Reference: 29 % I.G.N., Projection cartographique Mercator Transverse: Algorithmes, 30 % Notes Techniques NT/G 76, janvier 1995. 31 % 32 % Author: Francois Beauducel, <beauducel@ipgp.fr> 33 % Created: 2001-08-23 34 % Updated: 2014-04-20 37 35 38 % Argument checking 36 % Copyright (c) 2001-2014, François Beauducel, covered by BSD License. 37 % All rights reserved. 39 38 % 40 error(nargchk(3, 3, nargin)); %3 arguments required 41 n1=length(xx); 42 n2=length(yy); 43 n3=size(utmzone,1); 44 if (n1~=n2 || n1~=n3) 45 error('x,y and utmzone vectors should have the same number or rows'); 46 end 47 c=size(utmzone,2); 48 if (c~=4) 49 error('utmzone should be a vector of strings like "30 T"'); 39 % Redistribution and use in source and binary forms, with or without 40 % modification, are permitted provided that the following conditions are 41 % met: 42 % 43 % * Redistributions of source code must retain the above copyright 44 % notice, this list of conditions and the following disclaimer. 45 % * Redistributions in binary form must reproduce the above copyright 46 % notice, this list of conditions and the following disclaimer in 47 % the documentation and/or other materials provided with the distribution 48 % 49 % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 50 % AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 51 % IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 52 % ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 53 % LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 54 % CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 55 % SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 56 % INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 57 % CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 58 % ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 59 % POSSIBILITY OF SUCH DAMAGE. 60 61 % Available datums 62 datums = [ ... 63 { 'wgs84', 6378137.0, 298.257223563 }; 64 { 'nad83', 6378137.0, 298.257222101 }; 65 { 'grs80', 6378137.0, 298.257222101 }; 66 { 'nad27', 6378206.4, 294.978698214 }; 67 { 'int24', 6378388.0, 297.000000000 }; 68 { 'clk66', 6378206.4, 294.978698214 }; 69 ]; 70 71 if nargin < 3 72 error('Not enough input arguments.') 50 73 end 51 74 52 % Memory pre-allocation 53 % 54 Lat=zeros(n1,1); 55 Lon=zeros(n1,1); 75 if all([numel(x),numel(y)] > 1) && any(size(x) ~= size(y)) 76 error('X and Y must be the same size or scalars.') 77 end 56 78 57 % Main Loop 58 % 59 for i=1:n1 60 if (utmzone(i,4)>'X' || utmzone(i,4)<'C') 61 fprintf('utm2ll: Warning utmzone should be a vector of strings like "30 T", not "30 t"\n'); 79 if ~isnumeric(f) || ~isscalar(f) || f ~= round(f) 80 error('ZONE must be a scalar integer.') 81 end 82 83 if nargin < 4 84 datum = 'wgs84'; 85 end 86 87 if ischar(datum) 88 if ~any(strcmpi(datum,datums(:,1))) 89 error('Unkown DATUM name "%s"',datum); 62 90 end 63 if (utmzone(i,4)>'M') 64 hemis='N'; % Northern hemisphere 65 else 66 hemis='S'; 91 k = find(strcmpi(datum,datums(:,1))); 92 A1 = datums{k,2}; 93 F1 = datums{k,3}; 94 else 95 if numel(datum) ~= 2 96 error('User defined DATUM must be a vector [A,F].'); 67 97 end 98 A1 = datum(1); 99 F1 = datum(2); 100 end 68 101 69 x=xx(i); 70 y=yy(i); 71 zone=str2double(utmzone(i,1:2)); 102 % constants 103 D0 = 180/pi; % conversion rad to deg 104 maxiter = 100; % maximum iteration for latitude computation 105 eps = 1e-11; % minimum residue for latitude computation 72 106 73 sa = 6378137.000000 ; sb = 6356752.314245; 107 K0 = 0.9996; % UTM scale factor 108 X0 = 500000; % UTM false East (m) 109 Y0 = 1e7*(f < 0); % UTM false North (m) 110 P0 = 0; % UTM origin latitude (rad) 111 L0 = (6*abs(f) - 183)/D0; % UTM origin longitude (rad) 112 E1 = sqrt((A1^2 - (A1*(1 - 1/F1))^2)/A1^2); % ellpsoid excentricity 113 N = K0*A1; 74 114 75 % e = ( ( ( sa ^ 2 ) - ( sb ^ 2 ) ) ^ 0.5 ) / sa; 76 e2 = ( ( ( sa ^ 2 ) - ( sb ^ 2 ) ) ^ 0.5 ) / sb; 77 e2cuadrada = e2 ^ 2; 78 c = ( sa ^ 2 ) / sb; 79 % alpha = ( sa - sb ) / sa; %f 80 % ablandamiento = 1 / alpha; % 1/f 115 % computing parameters for Mercator Transverse projection 116 C = coef(E1,0); 117 YS = Y0 - N*(C(1)*P0 + C(2)*sin(2*P0) + C(3)*sin(4*P0) + C(4)*sin(6*P0) + C(5)*sin(8*P0)); 81 118 82 X = x - 500000; 119 C = coef(E1,1); 120 zt = complex((y - YS)/N/C(1),(x - X0)/N/C(1)); 121 z = zt - C(2)*sin(2*zt) - C(3)*sin(4*zt) - C(4)*sin(6*zt) - C(5)*sin(8*zt); 122 L = real(z); 123 LS = imag(z); 83 124 84 if hemis == 'S' || hemis == 's' 85 Y = y - 10000000; 86 else 87 Y = y; 88 end 125 l = L0 + atan(sinh(LS)./cos(L)); 126 p = asin(sin(L)./cosh(LS)); 89 127 90 S = ( ( zone * 6 ) - 183 ); 91 lat = Y / ( 6366197.724 * 0.9996 ); 92 v = ( c / ( ( 1 + ( e2cuadrada * ( cos(lat) ) ^ 2 ) ) ) ^ 0.5 ) * 0.9996; 93 a = X / v; 94 a1 = sin( 2 * lat ); 95 a2 = a1 * ( cos(lat) ) ^ 2; 96 j2 = lat + ( a1 / 2 ); 97 j4 = ( ( 3 * j2 ) + a2 ) / 4; 98 j6 = ( ( 5 * j4 ) + ( a2 * ( cos(lat) ) ^ 2) ) / 3; 99 alfa = ( 3 / 4 ) * e2cuadrada; 100 beta = ( 5 / 3 ) * alfa ^ 2; 101 gama = ( 35 / 27 ) * alfa ^ 3; 102 Bm = 0.9996 * c * ( lat - alfa * j2 + beta * j4 - gama * j6 ); 103 b = ( Y - Bm ) / v; 104 Epsi = ( ( e2cuadrada * a^ 2 ) / 2 ) * ( cos(lat) )^ 2; 105 Eps = a * ( 1 - ( Epsi / 3 ) ); 106 nab = ( b * ( 1 - Epsi ) ) + lat; 107 senoheps = ( exp(Eps) - exp(-Eps) ) / 2; 108 Delt = atan(senoheps / (cos(nab) ) ); 109 TaO = atan(cos(Delt) * tan(nab)); 110 longitude = (Delt *(180 / pi ) ) + S; 111 latitude = ( lat + ( 1 + e2cuadrada* (cos(lat)^ 2) - ( 3 / 2 ) * e2cuadrada * sin(lat) * cos(lat) * ( TaO - lat ) ) * ( TaO - lat ) ) * ... 112 (180 / pi); 128 L = log(tan(pi/4 + p/2)); 113 129 114 Lat(i)=latitude; 115 Lon(i)=longitude; 130 % calculates latitude from the isometric latitude 131 p = 2*atan(exp(L)) - pi/2; 132 p0 = NaN; 133 n = 0; 134 while any(isnan(p0) | abs(p - p0) > eps) & n < maxiter 135 p0 = p; 136 es = E1*sin(p0); 137 p = 2*atan(((1 + es)./(1 - es)).^(E1/2).*exp(L)) - pi/2; 138 n = n + 1; 139 end 116 140 141 if nargout < 2 142 lat = D0*[p(:),l(:)]; 143 else 144 lat = p*D0; 145 lon = l*D0; 117 146 end 147 148 149 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 150 function c = coef(e,m) 151 %COEF Projection coefficients 152 % COEF(E,M) returns a vector of 5 coefficients from: 153 % E = first ellipsoid excentricity 154 % M = 0 for transverse mercator 155 % M = 1 for transverse mercator reverse coefficients 156 % M = 2 for merdian arc 157 158 159 if nargin < 2 160 m = 0; 161 end 162 163 switch m 164 case 0 165 c0 = [-175/16384, 0, -5/256, 0, -3/64, 0, -1/4, 0, 1; 166 -105/4096, 0, -45/1024, 0, -3/32, 0, -3/8, 0, 0; 167 525/16384, 0, 45/1024, 0, 15/256, 0, 0, 0, 0; 168 -175/12288, 0, -35/3072, 0, 0, 0, 0, 0, 0; 169 315/131072, 0, 0, 0, 0, 0, 0, 0, 0]; 170 171 case 1 172 c0 = [-175/16384, 0, -5/256, 0, -3/64, 0, -1/4, 0, 1; 173 1/61440, 0, 7/2048, 0, 1/48, 0, 1/8, 0, 0; 174 559/368640, 0, 3/1280, 0, 1/768, 0, 0, 0, 0; 175 283/430080, 0, 17/30720, 0, 0, 0, 0, 0, 0; 176 4397/41287680, 0, 0, 0, 0, 0, 0, 0, 0]; 177 178 case 2 179 c0 = [-175/16384, 0, -5/256, 0, -3/64, 0, -1/4, 0, 1; 180 -901/184320, 0, -9/1024, 0, -1/96, 0, 1/8, 0, 0; 181 -311/737280, 0, 17/5120, 0, 13/768, 0, 0, 0, 0; 182 899/430080, 0, 61/15360, 0, 0, 0, 0, 0, 0; 183 49561/41287680, 0, 0, 0, 0, 0, 0, 0, 0]; 184 185 end 186 c = zeros(size(c0,1),1); 187 188 for i = 1:size(c0,1) 189 c(i) = polyval(c0(i,:),e); 190 end
Note:
See TracChangeset
for help on using the changeset viewer.