Hello,
I am currently working on a project related to Sentinel-2 aerosol remote sensing retrieval. The project involves using Sentinel-2 data, the Deep Blue algorithm, and the 6S model to perform aerosol retrieval. In the process of establishing the AOD lookup table, I need to obtain the satellite zenith angle and azimuth angle for each pixel in a Sentinel-2 image.
These two pieces of data require the satellite longitude and latitude for calculation.Therefore, I would like to know how to obtain the satellite longitude and latitude of Sentinel-2 through the Sentinel-2 toolbox. Or do you have any other better methods to obtain the two angle images of each pixel?
Here’s how I get longitude and latitude at a pixel in a Sentinel-2 L2A image file.
Every product comes with an MTD_MSIL2A.xml
file that contains the UTM coordinates of the upper left corner of the image denoted as ulx
and uly
.
Each product tile is notionally 100km x 100km but actually has an encompassing margin of 4.9km,
So given a pixel in the image (width x height
) at posX, posY
you can calculate its UTM northing and easting coordinate as:
utm_x = Math.floor( ulx + (posX * 109800)/ width ); // 109800 = 100km + 2 margins of 4900 m
utm_y = Math.floor( uly - (posY * 109800)/ height);
Now you can transform those coordinate into lat, lng using the standard code adapted from Open source PHP function for converting UTM coordinates to latitude and longitude? - Stack Overflow here given in javascript:
function UTM2latlng( northing, easting, zone ) // adapted from https://stackoverflow.com/a/25709233/3507061
{ // zone has postfix N or S for hemisphere - eg 32N or 52S
var FalseNorth = 0. // South or North?
if ( zone.includes('S') ) FalseNorth = 10000000. // South or North?
zone = parseInt( zone );
var d = 0.99960000000000004;
var d1 = 6378137;
var d2 = 0.0066943799999999998;
var d4 = (1 - Math.sqrt(1-d2))/(1 + Math.sqrt(1 - d2));
var d15 = easting - 500000;
var d16 = northing;
var d11 = ((zone - 1) * 6 - 180) + 3;
var d3 = d2/(1 - d2);
var d10 = (d16 - FalseNorth ) / d; // 10000000
var d12 = d10 / (d1 * (1 - d2/4 - (3 * d2 *d2)/64 - (5 * Math.pow(d2,3))/256));
var d14 = d12 + ((3*d4)/2 - (27*Math.pow(d4,3))/32) * Math.sin(2*d12) + ((21*d4*d4)/16 - (55 * Math.pow(d4,4))/32) * Math.sin(4*d12)
+ ((151 * Math.pow(d4,3))/96) * Math.sin(6*d12);
var d13 = d14 * 180 / Math.PI;
var d5 = d1 / Math.sqrt(1 - d2 * Math.sin(d14) * Math.sin(d14));
var d6 = Math.tan(d14)*Math.tan(d14);
var d7 = d3 * Math.cos(d14) * Math.cos(d14);
var d8 = (d1 * (1 - d2))/Math.pow(1-d2*Math.sin(d14)*Math.sin(d14),1.5);
var d9 = d15/(d5 * d);
var d17 = d14 - ((d5 * Math.tan(d14))/d8)*(((d9*d9)/2-(((5 + 3*d6 + 10*d7) - 4*d7*d7-9*d3)*Math.pow(d9,4))/24)
+ (((61 +90*d6 + 298*d7 + 45*d6*d6) - 252*d3 -3 * d7 *d7) * Math.pow(d9,6))/720);
d17 = d17 * 180 / Math.PI;
var d18 = ((d9 - ((1 + 2 * d6 + d7) * Math.pow(d9,3))/6)
+ (((((5 - 2 * d7) + 28*d6) - 3 * d7 * d7) + 8 * d3 + 24 * d6 * d6) * Math.pow(d9,5))/120)/Math.cos(d14);
d18 = d11 + d18 * 180 / Math.PI;
return [ d17, d18 ];
}
where the function returns an array [ d17, d18 ]
where d17
is latitude and d18
longitude.
The calculation of azumith and zenith angles is not as simple as you seem to think. The values are, however, available. See the Sentinel-2 Products Specification Document (S2-PDGS-TAS-DI-PSD-V14.9.pdf): Geometric_Info/Granule_Position provides azimuth and zenith.
The question was about satellite position, not ground pixel position.