diff --git a/dev/gallery/Aqua_orbits/remotes_sat_tracks/index.html b/dev/gallery/Aqua_orbits/remotes_sat_tracks/index.html index 362c60c..c5b0e88 100644 --- a/dev/gallery/Aqua_orbits/remotes_sat_tracks/index.html +++ b/dev/gallery/Aqua_orbits/remotes_sat_tracks/index.html @@ -30,4 +30,4 @@ julia> Dsc[2].header -`AQUA_MODIS.20210902T133501.L2.SST.NRT.nc`

Download a Neptune Notebook here

+`AQUA_MODIS.20210902T133501.L2.SST.NRT.nc`

Download a Neptune Notebook here

diff --git a/dev/gallery/Aqua_sst/remotes_L2_SST/index.html b/dev/gallery/Aqua_sst/remotes_L2_SST/index.html index 15d3320..67b1c1f 100644 --- a/dev/gallery/Aqua_sst/remotes_L2_SST/index.html +++ b/dev/gallery/Aqua_sst/remotes_L2_SST/index.html @@ -7,4 +7,4 @@ # Display it imshow(G, proj=:guess, coast=true, dpi=200)

Note that since we used a grid step 0f 0.01 for the interpolation and this value is very close to the MODIS maximum spatial resolution, the left and right regions have beam spacings 2 to 5 times this and show many little holes. Do not confuse these little holes with the larger ones that are caused by cloud coverage. So we will recalculate the grid at increments of ~2 km and over the region that has the higher data density.

# Recompue at a inc=0.02 and over a sub-region
 G = grid_at_sensor("C:/v/AQUA_MODIS.20210805T131001.L2.SST.NRT.nc", "sst", region=(-13,10,33.8,44.5), inc=0.02);
# Make a nicer image with illumination.
-imshow(G, proj=:guess, coast=true, shade=true, title="Sea Surace Temperature", colorbar=true)

Download a Neptune Notebook here

+imshow(G, proj=:guess, coast=true, shade=true, title="Sea Surace Temperature", colorbar=true)

Download a Neptune Notebook here

diff --git a/dev/gallery/HLS/cloud-native-hls-data/index.html b/dev/gallery/HLS/cloud-native-hls-data/index.html index 49cac18..86c900a 100644 --- a/dev/gallery/HLS/cloud-native-hls-data/index.html +++ b/dev/gallery/HLS/cloud-native-hls-data/index.html @@ -331,4 +331,4 @@ # Get the permutation vector p that puts time[p] in sorted order p = sortperm(time); eviFiles = eviFiles[p]; # Sort the file names in ascending time order -time = time[p]; # and the time too.

Save all EVI estimations in a netCDF 3d (a cube) file

stackgrids(eviFiles, time, z_unit="unix", save="evi_cube.nc")

Interpolate along all layers at a point with coordinates x = 580740; y = 4418042

D = grdinterpolate("evi_cube.nc", pt=(580740,4418042));

Now, plot the time series showing the distribution of EVI values for our farm field.

imshow(D, par=(TIME_SYSTEM="UNIX",), coltypes=:t)
+time = time[p]; # and the time too.

Save all EVI estimations in a netCDF 3d (a cube) file

stackgrids(eviFiles, time, z_unit="unix", save="evi_cube.nc")

Interpolate along all layers at a point with coordinates x = 580740; y = 4418042

D = grdinterpolate("evi_cube.nc", pt=(580740,4418042));

Now, plot the time series showing the distribution of EVI values for our farm field.

imshow(D, par=(TIME_SYSTEM="UNIX",), coltypes=:t)
diff --git a/dev/gallery/L8cube_img/remotes_L8_cube_img/index.html b/dev/gallery/L8cube_img/remotes_L8_cube_img/index.html index 372b0a6..5d732d3 100644 --- a/dev/gallery/L8cube_img/remotes_L8_cube_img/index.html +++ b/dev/gallery/L8cube_img/remotes_L8_cube_img/index.html @@ -15,4 +15,4 @@ imshow(Btoa_img)

Now we are going to do the same for all Red, Green and Blue bands and compose the in a truecolor image. Repeating, we are going to compute the radiance at the top of atmosphere, retain only the data inside the parts of the histogram where it is more concentrated and create a true color image. To compute the radiance TOA we can do it all at once with the dn2radiance applied to the cube and, like before, create the RGB image with truecolor

cube_toa_rad = dn2radiance("c:/v/LC08_L1TP_20210525_02_cube.tiff");
 Irgb_toa = truecolor(cube_toa_rad);
 imshow(Irgb_toa)

Hm, yes, very nice but it looks very much like the one obtained directly with the digital numbers. Indeed, it does but let us zoom in.

grdimage(Irgb, region=(502380,514200,4311630,4321420), figsize=8, frame=:bare)
-grdimage!(Irgb_toa, figsize=8, projection=:linear, xshift=8, frame=:bare, show=true)

We can now clearly see that the image on the right, the one made the radiance TOA, has an higher contrast than the one made with data without any corrections.

+grdimage!(Irgb_toa, figsize=8, projection=:linear, xshift=8, frame=:bare, show=true)

We can now clearly see that the image on the right, the one made the radiance TOA, has an higher contrast than the one made with data without any corrections.

diff --git a/dev/gallery/L8cube_ndvi/remotes_L8_NDVI/index.html b/dev/gallery/L8cube_ndvi/remotes_L8_NDVI/index.html index 384ab0d..1297576 100644 --- a/dev/gallery/L8cube_ndvi/remotes_L8_NDVI/index.html +++ b/dev/gallery/L8cube_ndvi/remotes_L8_NDVI/index.html @@ -20,4 +20,4 @@ image_alpha!(Irgb, alpha_band=mask_inv, burn=1); gmtwrite("rgb_inv_masked.tiff", Irgb)

Plot the green vegetation that passed the NDVI threshold test and the other part, side by side.

grdimage("rgb_masked.tiff", region=(502380,514200,4311630,4321420), figsize=8, frame=:bare)
-grdimage!("rgb_inv_masked.tiff", figsize=8, projection=:linear, xshift=8, frame=:bare, show=true)

As we can see only the greenest part, the one that is probably more irrigated considering that all the river and cannals margins were retained, was extracted with the condition NDVI > 0.4. Off course, using different threshold values would lead to slightly different results.

+grdimage!("rgb_inv_masked.tiff", figsize=8, projection=:linear, xshift=8, frame=:bare, show=true)

As we can see only the greenest part, the one that is probably more irrigated considering that all the river and cannals margins were retained, was extracted with the condition NDVI > 0.4. Off course, using different threshold values would lead to slightly different results.

diff --git a/dev/index.html b/dev/index.html index 95a556b..2f51689 100644 --- a/dev/index.html +++ b/dev/index.html @@ -1,21 +1,34 @@ -Index · RemoteS.jl

RemoteS

Index

Functions

RemoteS.classifyMethod
I = classify(cube::GItype, model; class_names::Union{String, Vector{String}}="") -> GMTimage
  • cube: The cube wtih band data to classify.
  • model: The trained model obtained from the train_raster function.
  • class_names: A vector of strings with the class names to be used in the categorical colorbar or a comma separated single with those class names. The number of class names must match the number used when training the model with train_raster.
source
RemoteS.classifyMethod
I = classify(cube::GItype, train::Union{Vector{<:GMTdataset}, String}) -> GMTimage
  • cube: The cube wtih band data to classify.
  • train: A vector of GMTdatasets or a file name of one containing the polygons used to train the model. NOTE: The individual datasets MUST have associated an attribute called "class" containing the class name as a string. This can be achieved for text data in the form of a GMT multi-segment file (one where segments are separated by the '>' symbol) if the multi-segment separator line contains the text $Attrib(class=name)$

Returns an image with the classification results where each class name was assigned a different integer number. That colorized image can plotted with $viz(I, colorbar=true)$.

source
RemoteS.clgMethod
CLG = clg(green, redEdge3; kw...)

or

CLG = clg(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)

Green cholorphyl index. Wu et al 2012.

CLG = (redEdge3)/(green)-1

source
RemoteS.clip_orbitsMethod
clip_orbits(track, BoundingBox::Vector{<:Real})

Clips the orbits that are contained inside a rectangular geographical region

  • track: A GMTdataset or a Mx2 matrix with the orbits [lon, lat] position. This is normally calculated with the sat_tracks function.
  • BoundingBox: A vector the region limits made up with [lonmin, lonmax, latmin, latmax]

Returns a GMTdataset vector with the chunks of tracks that cross inside the BoundingBox region.

#Example Suppose orb holds orbits computed with sat_tracks() during 2 days, clip them inside the 20W-10E, 30N-45N window

D = clip_orbits(orb, [-20, 10, 30, 50]);
source
RemoteS.clreMethod
CLRE = clre(redEdge1, redEdge3; kw...)

or

CLRE = clre(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)

RedEdge cholorphyl index. Clevers and Gitelson 2013.

CLRE = (redEdge3)/(redEdge1)-1

source
RemoteS.cutcubeMethod
cutcube(names=String[], bands=Int[], template="", region=nothing, extension=".TIF", description=String[], mtl="", sentinel2=0, save="")

Cut a 3D cube out of a Landsat/Sentinel scene within a subregion region and a selection of bands.

  • names: (optional) A vector with the individual bands full file name
  • bands: When names is not provided give a vector of integers corresponding to the choosen bands. This works well for Landsat and most of Sentinel bands. However, in later case, there are also bands that contain characters, for example band 8A. In this case bands should be a vector of strings including the extension. e.g. ["02.jp2", "8A.jp2"]
  • template: Goes together with the bands option. They are both composed a template * band[n] to recreate the full file name of each band.
  • region Is the region to extract and must contain the extracting region limits as [W, E, S, N] or a GMT style -R string (without the leading "-R").
  • extension: In case the bands is numeric but file extensions are not "*.TIF" (case insensitive), use the extension passed by this option.
  • description: A vector of strings (as many as bands) with a description for each band. If not provided and the file is recognized as a Landasat 8, band description is added automatically, otherwise we build one with the bands file names. This info will saved if data is written to a file.
  • mtl: If reading from Landsat and the MTL file is not automatically found (you get an error) use this option to pass the full name of the MTL file.
  • sentinel2: ESA is just unconsistent and names change with time and band numbers can have character (e.g. 8A) hence we need help to recognize Sentinel files so the known description can be assigned. Use sentinel=10, or =20 or =60 to indicate Sentinel files at those resolutions.
  • save: The file name where to save the output. If not provided, a GMTimage is returned.

Return: nothing if the result is written in file or a GMTimage otherwise.

Examples

# Cut a Landsat 8 scene for a small region (in UTM) and return a GMTimage with 3 bands in UInt16.
+Index · RemoteS.jl

RemoteS

Index

Functions

RemoteS.classifyMethod
I = classify(cube::GItype, model; class_names::Union{String, Vector{String}}="") -> GMTimage
  • cube: The cube wtih band data to classify.
  • model: The trained model obtained from the train_raster function.
  • class_names: A vector of strings with the class names to be used in the categorical colorbar or a comma separated single with those class names. The number of class names must match the number used when training the model with train_raster.
source
RemoteS.classifyMethod
I = classify(cube::GItype, train::Union{Vector{<:GMTdataset}, String}) -> GMTimage
  • cube: The cube wtih band data to classify.
  • train: A vector of GMTdatasets or a file name of one containing the polygons used to train the model. NOTE: The individual datasets MUST have associated an attribute called "class" containing the class name as a string. This can be achieved for text data in the form of a GMT multi-segment file (one where segments are separated by the '>' symbol) if the multi-segment separator line contains the text $Attrib(class=name)$

Returns an image with the classification results where each class name was assigned a different integer number. That colorized image can plotted with $viz(I, colorbar=true)$.

source
RemoteS.clgMethod
CLG = clg(green, redEdge3; kw...)

or

CLG = clg(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)

Green cholorphyl index. Wu et al 2012.

CLG = (redEdge3)/(green)-1

source
RemoteS.clip_orbitsMethod
clip_orbits(track, BoundingBox::Vector{<:Real})

Clips the orbits that are contained inside a rectangular geographical region

  • track: A GMTdataset or a Mx2 matrix with the orbits [lon, lat] position. This is normally calculated with the sat_tracks function.
  • BoundingBox: A vector the region limits made up with [lonmin, lonmax, latmin, latmax]

Returns a GMTdataset vector with the chunks of tracks that cross inside the BoundingBox region.

#Example Suppose orb holds orbits computed with sat_tracks() during 2 days, clip them inside the 20W-10E, 30N-45N window

D = clip_orbits(orb, [-20, 10, 30, 50]);
source
RemoteS.clreMethod
CLRE = clre(redEdge1, redEdge3; kw...)

or

CLRE = clre(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)

RedEdge cholorphyl index. Clevers and Gitelson 2013.

CLRE = (redEdge3)/(redEdge1)-1

source
RemoteS.cutcubeMethod
cutcube(names=String[], bands=Int[], template="", region=nothing, extension=".TIF", description=String[], mtl="", sentinel2=0, save="")

Cut a 3D cube out of a Landsat/Sentinel scene within a subregion region and a selection of bands.

  • names: (optional) A vector with the individual bands full file name
  • bands: When names is not provided give a vector of integers corresponding to the choosen bands. This works well for Landsat and most of Sentinel bands. However, in later case, there are also bands that contain characters, for example band 8A. In this case bands should be a vector of strings including the extension. e.g. ["02.jp2", "8A.jp2"]
  • template: Goes together with the bands option. They are both composed a template * band[n] to recreate the full file name of each band.
  • region Is the region to extract and must contain the extracting region limits as [W, E, S, N] or a GMT style -R string (without the leading "-R").
  • extension: In case the bands is numeric but file extensions are not "*.TIF" (case insensitive), use the extension passed by this option.
  • description: A vector of strings (as many as bands) with a description for each band. If not provided and the file is recognized as a Landasat 8, band description is added automatically, otherwise we build one with the bands file names. This info will saved if data is written to a file.
  • mtl: If reading from Landsat and the MTL file is not automatically found (you get an error) use this option to pass the full name of the MTL file.
  • sentinel2: ESA is just unconsistent and names change with time and band numbers can have character (e.g. 8A) hence we need help to recognize Sentinel files so the known description can be assigned. Use sentinel=10, or =20 or =60 to indicate Sentinel files at those resolutions.
  • save: The file name where to save the output. If not provided, a GMTimage is returned.

Return: nothing if the result is written in file or a GMTimage otherwise.

Examples

# Cut a Landsat 8 scene for a small region (in UTM) and return a GMTimage with 3 bands in UInt16.
 temp = "C:\SIG_AnaliseDadosSatelite\SIG_ADS\DadosEx2\LC82040332015145LGN00\LC82040332015145LGN00_B";
 cube = cutcube(bands=[2,3,4], template=temp, region=[479670,492720,4282230,4294500])
 
 # The same example as above but save the data in a GeoTIFF disk file and use a string for `region`
-cutcube(bands=[2,3,4], template=temp, region="479670/492720/4282230/4294500", save="landsat_cube.tif")
source
RemoteS.dn2radianceMethod
R = dn2radiance(fname::String, [band::Int, bandname::String, mtl::String, save::String])

Computes the radiance at TopOfAtmosphere of a Landsat 8 file

  • fname: The name of either a $LANDSAT_PRODUCT_ID$ geotiff band, or the name of a cube file created with the cutcube function. In the first case, if the companion $...MTL.txt$ file is not in the same directory as fname one can still pass it via the mtl=path-to-MTL-file option. In the second case it is mandatory to use one of the following two options.
  • band: cubes created with cutcube assign descriptions starting with "Band 1 ..." an so on the other bands. So when band is used we search for the band named "Band N", where N = band.
  • bandname: When we know the common designation of a band, for example "Green", or any part of a band description, for example "NIR", we can use that info to create a bandname string that will be matched against the cube's bands descriptions. We can use the reportbands function to see the bands description.
  • save: The file name where to save the output. If not provided, a GMTgrid is returned.

Returns a Float32 GMTgrid

Example:

Compute the radiance TOA of Band 2 file.

R = dn2radiance("LC08_L1TP_204033_20210525_20210529_02_T1_B2.TIF")
source
RemoteS.dn2reflectanceMethod
R = dn2reflectance(fname::String, [band::Int, bandname::String, mtl::String, save::String])

Computes the TopOfAtmosphere planetary reflectance of a Landsat8 file

  • fname: The name of either a $LANDSAT_PRODUCT_ID$ geotiff band, or the name of a cube file created with the cutcube function. In the first case, if the companion $...MTL.txt$ file is not in the same directory as fname one can still pass it via the mtl=path-to-MTL-file option. In the second case it is mandatory to use one of the following two options.
  • band: cubes created with cutcube assign descriptions starting with "Band 1 ..." an so on the other bands. So when band is used we search for the band named "Band N", where N = band.
  • bandname: When we know the common designation of a band, for example "Green", or any part of a band description, for example "NIR", we can use that info to create a bandname string that will be matched against the cube's bands descriptions. We can use the reportbands function to see the bands description.
  • save: The file name where to save the output. If not provided, a GMTgrid is returned.

Returns a Float32 GMTgrid

Example:

Compute the reflectance TOA of Red Band stored in a cube

R = dn2reflectance(cube, bandname="red")
source
RemoteS.dn2temperatureMethod
R = dn2temperature(fname::String; band::Int=0, mtl::String="", save::String)

Computes the brigthness temperature of Landasat8 termal band (10 or 11)

  • fname: The name of either a $LANDSAT_PRODUCT_ID$ geotiff band, or the name of a cube file created with the cutcube function. In the first case, if the companion $...MTL.txt$ file is not in the same directory as fname one can still pass it via the mtl=path-to-MTL-file option. In the second case it is mandatory to use one of the following two options.
  • band: cubes created with cutcube assign descriptions starting with "Band 1 ..." an so on the other bands. So when band is used we search for the band named "Band N", where N = band.
  • bandname: When we know the common designation of a band, for example "Green", or any part of a band description, for example "NIR", we can use that info to create a bandname string that will be matched against the cube's bands descriptions. We can use the reportbands function to see the bands description.
  • save: The file name where to save the output. If not provided, a GMTgrid is returned.

Returns a Float32 GMTgrid

Example:

Compute the brightness temperature of Band 10 stored in a cube

T = dn2temperature(cube, band=10)
source
RemoteS.eviMethod
EVI = evi(blue, red, nir; kw...)

or

EVI = evi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)

Enhanced vegetation index. Huete et al 1990

EVI = G * ((nir - red) / (nir + C1 * red - C2 * blue + Levi)); C1, C2, G, Levi = 6.0, 7.5, 2.5, 1.

  • The first form accepts inputs as matrices, or file names of the data bands.
  • The second form is more versatile but also more complex to describe.
    • cube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.
    • bands: cubes created with cutcube assign descriptions starting with "Band1 ..." an so on the other bands. So when bands is used we search for bands named "Band'band[k]'", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.
    • layers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.
    • bandnames: When we know the common designation of a band, for example "Green", or any part of a band description, for example "NIR", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.
  • kwargs:
    • threshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN
    • classes: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.
    • mask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise
    • save: Use save="file_name.ext" to save the result in a disk file. File format is picked from file extension.

If none of bands, layers or bandnames is provided, we use the default band names shown in the first form.

See also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.

Returns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.

source
RemoteS.evi2Method
EVI2 = evi2(red, nir; kw...)

or

EVI2 = evi2(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)

Two-band Enhanced vegetation index. Jiang et al 2008

EVI2 = G * ((nir - red) / (nir + 2.4 * red ))

  • The first form accepts inputs as matrices, or file names of the data bands.
  • The second form is more versatile but also more complex to describe.
    • cube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.
    • bands: cubes created with cutcube assign descriptions starting with "Band1 ..." an so on the other bands. So when bands is used we search for bands named "Band'band[k]'", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.
    • layers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.
    • bandnames: When we know the common designation of a band, for example "Green", or any part of a band description, for example "NIR", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.
  • kwargs:
    • threshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN
    • classes: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.
    • mask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise
    • save: Use save="file_name.ext" to save the result in a disk file. File format is picked from file extension.

If none of bands, layers or bandnames is provided, we use the default band names shown in the first form.

See also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.

Returns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.

source
RemoteS.findscenesMethod
findscenes(lon::Real, lat::Real; kwargs...)

Find the names of the scenes that cover the location point lon, lat in the period determined by the dates and satellite set via kwargs.

  • day: Search only on the day time part of the orbits.
  • night: Search only on the night time part of the orbits.
  • oc: For the AQUA or TERRA satellites pick only the chlorophyl content scenes.
  • sst: For the AQUA or TERRA satellites pick only the Sae Surface Temperature content scenes.
  • sat, SAT or satellite: Name of the satellite to use; choose from (string or symbols) :TERRA, :AQUA
  • start: A DateTime object or a string convertable to a DateTime with DateTime(start) specifying the start of the looking period. If omited, current time in UTC will be used.
  • duration: Length of time for which the scenes are searched. The duration is expected in days and can be a negative number, meaning we'll look that span days from start.
  • stop: As alternative to duration provide the end date for the serch. Same conditions as start
  • tle or TLE: a file name with the TLE data for a specific satellite and period. It can also be a two elements string vector with the first and second lines of the TLE file.

Returns

A string vector with the scene names

Example:

Find the AQUA scenes with chlorophyl-a (oceancolor) that cover the point (-8, 36) in the two days before "2021-09-07T17:00:00" Note, this will be accurate for the month of September 2021. For other dates it needs an updated TLE.

tle1 = "1 27424U 02022A   21245.83760660  .00000135  00000-0  39999-4 0  9997";
+cutcube(bands=[2,3,4], template=temp, region="479670/492720/4282230/4294500", save="landsat_cube.tif")
source
RemoteS.dn2radianceMethod
R = dn2radiance(fname::String, [band::Int, bandname::String, mtl::String, save::String])

Computes the radiance at TopOfAtmosphere of a Landsat 8 file

  • fname: The name of either a $LANDSAT_PRODUCT_ID$ geotiff band, or the name of a cube file created with the cutcube function. In the first case, if the companion $...MTL.txt$ file is not in the same directory as fname one can still pass it via the mtl=path-to-MTL-file option. In the second case it is mandatory to use one of the following two options.
  • band: cubes created with cutcube assign descriptions starting with "Band 1 ..." an so on the other bands. So when band is used we search for the band named "Band N", where N = band.
  • bandname: When we know the common designation of a band, for example "Green", or any part of a band description, for example "NIR", we can use that info to create a bandname string that will be matched against the cube's bands descriptions. We can use the reportbands function to see the bands description.
  • save: The file name where to save the output. If not provided, a GMTgrid is returned.

Returns a Float32 GMTgrid

Example:

Compute the radiance TOA of Band 2 file.

R = dn2radiance("LC08_L1TP_204033_20210525_20210529_02_T1_B2.TIF")
source
RemoteS.dn2reflectanceMethod
R = dn2reflectance(fname::String, [band::Int, bandname::String, mtl::String, save::String])

Computes the TopOfAtmosphere planetary reflectance of a Landsat8 file

  • fname: The name of either a $LANDSAT_PRODUCT_ID$ geotiff band, or the name of a cube file created with the cutcube function. In the first case, if the companion $...MTL.txt$ file is not in the same directory as fname one can still pass it via the mtl=path-to-MTL-file option. In the second case it is mandatory to use one of the following two options.
  • band: cubes created with cutcube assign descriptions starting with "Band 1 ..." an so on the other bands. So when band is used we search for the band named "Band N", where N = band.
  • bandname: When we know the common designation of a band, for example "Green", or any part of a band description, for example "NIR", we can use that info to create a bandname string that will be matched against the cube's bands descriptions. We can use the reportbands function to see the bands description.
  • save: The file name where to save the output. If not provided, a GMTgrid is returned.

Returns a Float32 GMTgrid

Example:

Compute the reflectance TOA of Red Band stored in a cube

R = dn2reflectance(cube, bandname="red")
source
RemoteS.dn2temperatureMethod
R = dn2temperature(fname::String; band::Int=0, mtl::String="", save::String)

Computes the brigthness temperature of Landasat8 termal band (10 or 11)

  • fname: The name of either a $LANDSAT_PRODUCT_ID$ geotiff band, or the name of a cube file created with the cutcube function. In the first case, if the companion $...MTL.txt$ file is not in the same directory as fname one can still pass it via the mtl=path-to-MTL-file option. In the second case it is mandatory to use one of the following two options.
  • band: cubes created with cutcube assign descriptions starting with "Band 1 ..." an so on the other bands. So when band is used we search for the band named "Band N", where N = band.
  • bandname: When we know the common designation of a band, for example "Green", or any part of a band description, for example "NIR", we can use that info to create a bandname string that will be matched against the cube's bands descriptions. We can use the reportbands function to see the bands description.
  • save: The file name where to save the output. If not provided, a GMTgrid is returned.

Returns a Float32 GMTgrid

Example:

Compute the brightness temperature of Band 10 stored in a cube

T = dn2temperature(cube, band=10)
source
RemoteS.eviMethod
EVI = evi(blue, red, nir; kw...)

or

EVI = evi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)

Enhanced vegetation index. Huete et al 1990

EVI = G * ((nir - red) / (nir + C1 * red - C2 * blue + Levi)); C1, C2, G, Levi = 6.0, 7.5, 2.5, 1.

  • The first form accepts inputs as matrices, or file names of the data bands.
  • The last form is more versatile but also more complex to describe.
    • cube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.
    • bands: cubes created with cutcube assign descriptions starting with "Band1 ..." an so on the other bands. So when bands is used we search for bands named "Band'band[k]'", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.
    • layers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.
    • bandnames: When we know the common designation of a band, for example "Green", or any part of a band description, for example "NIR", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.

Kwargs

  • threshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN
  • classes: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.
  • mask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise
  • save: Use save="file_name.ext" to save the result in a disk file. File format is picked from file extension.
  • order | bands_order | rgb: For the $GLI$, $TGI$ and $VARI$ (RGB) indices, we allow to reorder the bands and change the expected RGB order. Pass in a string, or symbol, with the color order. For example, order=:rbg
will swap the green and blue components making the result index identify the _reds_ instead of the _greens_.
+Not good for vegetation indices, but potentially useful for other purposes.

If none of bands, layers or bandnames is provided, we use the default band names shown in the first form.

See also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.

Returns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.

source
RemoteS.evi2Method
EVI2 = evi2(red, nir; kw...)

or

EVI2 = evi2(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)

Two-band Enhanced vegetation index. Jiang et al 2008

EVI2 = G * ((nir - red) / (nir + 2.4 * red ))

  • The first form accepts inputs as matrices, or file names of the data bands.
  • The last form is more versatile but also more complex to describe.
    • cube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.
    • bands: cubes created with cutcube assign descriptions starting with "Band1 ..." an so on the other bands. So when bands is used we search for bands named "Band'band[k]'", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.
    • layers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.
    • bandnames: When we know the common designation of a band, for example "Green", or any part of a band description, for example "NIR", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.

Kwargs

  • threshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN
  • classes: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.
  • mask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise
  • save: Use save="file_name.ext" to save the result in a disk file. File format is picked from file extension.
  • order | bands_order | rgb: For the $GLI$, $TGI$ and $VARI$ (RGB) indices, we allow to reorder the bands and change the expected RGB order. Pass in a string, or symbol, with the color order. For example, order=:rbg
will swap the green and blue components making the result index identify the _reds_ instead of the _greens_.
+Not good for vegetation indices, but potentially useful for other purposes.

If none of bands, layers or bandnames is provided, we use the default band names shown in the first form.

See also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.

Returns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.

source
RemoteS.findscenesMethod
findscenes(lon::Real, lat::Real; kwargs...)

Find the names of the scenes that cover the location point lon, lat in the period determined by the dates and satellite set via kwargs.

  • day: Search only on the day time part of the orbits.
  • night: Search only on the night time part of the orbits.
  • oc: For the AQUA or TERRA satellites pick only the chlorophyl content scenes.
  • sst: For the AQUA or TERRA satellites pick only the Sae Surface Temperature content scenes.
  • sat, SAT or satellite: Name of the satellite to use; choose from (string or symbols) :TERRA, :AQUA
  • start: A DateTime object or a string convertable to a DateTime with DateTime(start) specifying the start of the looking period. If omited, current time in UTC will be used.
  • duration: Length of time for which the scenes are searched. The duration is expected in days and can be a negative number, meaning we'll look that span days from start.
  • stop: As alternative to duration provide the end date for the serch. Same conditions as start
  • tle or TLE: a file name with the TLE data for a specific satellite and period. It can also be a two elements string vector with the first and second lines of the TLE file.

Returns

A string vector with the scene names

Example:

Find the AQUA scenes with chlorophyl-a (oceancolor) that cover the point (-8, 36) in the two days before "2021-09-07T17:00:00" Note, this will be accurate for the month of September 2021. For other dates it needs an updated TLE.

tle1 = "1 27424U 02022A   21245.83760660  .00000135  00000-0  39999-4 0  9997";
 tle2 = "2 27424  98.2123 186.0654 0002229  67.6025 313.3829 14.57107527 28342";
 findscenes(-8,36, start="2021-09-07T17:00:00", sat=:aqua, day=true, duration=-2, oc=1, tle=[tle1, tle2])
 
 2-element Vector{String}:
 "A2021251125500.L2_LAC_OC.nc"
-"A2021252134000.L2_LAC_OC.nc"
source
RemoteS.gliMethod
GLI = gli(red, green, blue; kw...)

or (here fname is a .png or .jpg file name)

GLI = gli(fname::String; kw...)

or

GLI = gli(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)

Green Leaf Index. Louhaichi, M., Borman, M.M., Johnson, D.E., 2001.

GLI = (2green - red - blue) / (2green + red + blue)

  • The first form accepts inputs as matrices, or file names of the data bands.
  • The second form is more versatile but also more complex to describe.
    • cube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.
    • bands: cubes created with cutcube assign descriptions starting with "Band1 ..." an so on the other bands. So when bands is used we search for bands named "Band'band[k]'", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.
    • layers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.
    • bandnames: When we know the common designation of a band, for example "Green", or any part of a band description, for example "NIR", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.
  • kwargs:
    • threshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN
    • classes: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.
    • mask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise
    • save: Use save="file_name.ext" to save the result in a disk file. File format is picked from file extension.

If none of bands, layers or bandnames is provided, we use the default band names shown in the first form.

See also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.

Returns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.

source
RemoteS.gndviMethod
GNDVI = gndvi(green, nir; kw...)

or

GNDVI = gndvi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)

green Normalized diff vegetation index: more sensitive to cholorphyll than ndvi. Gitelson, A., and M. Merzlyak

GNDVI = (nir - green) / (nir + green)

  • The first form accepts inputs as matrices, or file names of the data bands.
  • The second form is more versatile but also more complex to describe.
    • cube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.
    • bands: cubes created with cutcube assign descriptions starting with "Band1 ..." an so on the other bands. So when bands is used we search for bands named "Band'band[k]'", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.
    • layers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.
    • bandnames: When we know the common designation of a band, for example "Green", or any part of a band description, for example "NIR", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.
  • kwargs:
    • threshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN
    • classes: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.
    • mask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise
    • save: Use save="file_name.ext" to save the result in a disk file. File format is picked from file extension.

If none of bands, layers or bandnames is provided, we use the default band names shown in the first form.

See also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.

Returns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.

source
RemoteS.grid_at_sensorFunction
G = grid_at_sensor(fname::String, sds_name::String=""; V::Bool=false, kw...)

Read one of those netCDF files that are not regular grids but have instead the coordinates in the LONGITUDE and LATITUDE arrays. MODIS L2 files are a good example of this. Data in theses files are not layed down on a regular grid and we must interpolate to get one. Normally the lon and lat arrays are called $longitude$ and $latitude$ and these it's what is seek for by default. But files exist that pretend to comply to CF but use other names. In this case, use the kwargs xarray & yarray to pass in the variable names. For example: xarray="XLONG", yarray="XLAT" The other fundamental info to pass in is the name of the array to be read/interpolated. We do that via the sds_name arg.

  • band: In simpler cases the variable to be interpolated lays down on a 2D array but it is also possible that it is stored in a 3D array. If that is the case, use the keyword 'band' to select a band (ex: 'band=2') Bands are numbered from 1.

  • region | limits, inc | increment | spacing and search_radius: The interpolation is done so far with $nearneighbor$ Both the region (-R) and increment (-I) are estimated from data but they can be set with region and inc kwargs as well. One can also set the $nearneighbor$ serach radius with option search_radius. The defaul is to set search_radius equal to two times the average increment.

  • quality: For MODIS data we can select the quality flag to filter by data quality. By default the best quality (=0) is used, but one can select another with the quality=val kwarg. Positive 'val' values select data of quality <= quality, whilst negative 'val' values select only data with quality >= abs(val). This allows for example to extract only the cloud coverage.

  • t_srs or target_proj: Some polar grids come with $longitude$, $latitude$ (or just $lon$, $lat$) arrays in geographical coordinates. There must be an (obscure) reason for this but the practical result is messy because coordinate spacings are highly variable preventing any decent guess. In these cases it is useful to reproject the data before griding. For that purpose use the t_srs or target_proj option to tell the program to do a coordinate conversion before gridding. t_srs should then be a proj4 string with the destiny projection system.

  • nodata: Sometimes datasets use other than NaN to represent nodata but they don't specify it in the netCDF attributes (e.g. the NSIDC products). This option allows to fix this (i.e nodata=-9999) Note that this is automatically set for the NSIDC products.

  • nointerp: Means to not do any nearneighbor interpolation but needs that region has been set.

  • NSIDC_N and NSIDC_S: Set the s_srs, region, nointerp, nodata appropriate to read the See Ice NSIDC https://nsidc.org/data/polar-stereo/ps_grids.html grids.

  • dataset or xyz: If instead of calculating a grid (returned as a GMTgrid type) user wants the x,y,z data intself, use the keywords dataset, or xyz and the output will be in a GMTdataset (i.e. use dataset=true).

To inquire just the list of available arrays use list=true or gdalinfo=true to get the full file info.

Examples:
+"A2021252134000.L2_LAC_OC.nc"
source
RemoteS.gliMethod
GLI = gli(red, green, blue; kw...)

or (here fname is a .png or .jpg file name)

GLI = gli(fname::String; kw...)

or

GLI = gli(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)

Green Leaf Index. Louhaichi, M., Borman, M.M., Johnson, D.E., 2001.

GLI = (2green - red - blue) / (2green + red + blue)

  • The first form accepts inputs as matrices, or file names of the data bands.
  • The last form is more versatile but also more complex to describe.
    • cube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.
    • bands: cubes created with cutcube assign descriptions starting with "Band1 ..." an so on the other bands. So when bands is used we search for bands named "Band'band[k]'", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.
    • layers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.
    • bandnames: When we know the common designation of a band, for example "Green", or any part of a band description, for example "NIR", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.

Kwargs

  • threshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN
  • classes: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.
  • mask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise
  • save: Use save="file_name.ext" to save the result in a disk file. File format is picked from file extension.
  • order | bands_order | rgb: For the $GLI$, $TGI$ and $VARI$ (RGB) indices, we allow to reorder the bands and change the expected RGB order. Pass in a string, or symbol, with the color order. For example, order=:rbg
will swap the green and blue components making the result index identify the _reds_ instead of the _greens_.
+Not good for vegetation indices, but potentially useful for other purposes.

If none of bands, layers or bandnames is provided, we use the default band names shown in the first form.

See also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.

Returns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.

source
RemoteS.gndviMethod
GNDVI = gndvi(green, nir; kw...)

or

GNDVI = gndvi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)

green Normalized diff vegetation index: more sensitive to cholorphyll than ndvi. Gitelson, A., and M. Merzlyak

GNDVI = (nir - green) / (nir + green)

  • The first form accepts inputs as matrices, or file names of the data bands.
  • The last form is more versatile but also more complex to describe.
    • cube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.
    • bands: cubes created with cutcube assign descriptions starting with "Band1 ..." an so on the other bands. So when bands is used we search for bands named "Band'band[k]'", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.
    • layers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.
    • bandnames: When we know the common designation of a band, for example "Green", or any part of a band description, for example "NIR", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.

Kwargs

  • threshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN
  • classes: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.
  • mask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise
  • save: Use save="file_name.ext" to save the result in a disk file. File format is picked from file extension.
  • order | bands_order | rgb: For the $GLI$, $TGI$ and $VARI$ (RGB) indices, we allow to reorder the bands and change the expected RGB order. Pass in a string, or symbol, with the color order. For example, order=:rbg
will swap the green and blue components making the result index identify the _reds_ instead of the _greens_.
+Not good for vegetation indices, but potentially useful for other purposes.

If none of bands, layers or bandnames is provided, we use the default band names shown in the first form.

See also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.

Returns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.

source
RemoteS.grid_at_sensorFunction
G = grid_at_sensor(fname::String, sds_name::String=""; V::Bool=false, kw...)

Read one of those netCDF files that are not regular grids but have instead the coordinates in the LONGITUDE and LATITUDE arrays. MODIS L2 files are a good example of this. Data in theses files are not layed down on a regular grid and we must interpolate to get one. Normally the lon and lat arrays are called $longitude$ and $latitude$ and these it's what is seek for by default. But files exist that pretend to comply to CF but use other names. In this case, use the kwargs xarray & yarray to pass in the variable names. For example: xarray="XLONG", yarray="XLAT" The other fundamental info to pass in is the name of the array to be read/interpolated. We do that via the sds_name arg.

  • band: In simpler cases the variable to be interpolated lays down on a 2D array but it is also possible that it is stored in a 3D array. If that is the case, use the keyword 'band' to select a band (ex: 'band=2') Bands are numbered from 1.

  • region | limits, inc | increment | spacing and search_radius: The interpolation is done so far with $nearneighbor$ Both the region (-R) and increment (-I) are estimated from data but they can be set with region and inc kwargs as well. One can also set the $nearneighbor$ serach radius with option search_radius. The defaul is to set search_radius equal to two times the average increment.

  • quality: For MODIS data we can select the quality flag to filter by data quality. By default the best quality (=0) is used, but one can select another with the quality=val kwarg. Positive 'val' values select data of quality <= quality, whilst negative 'val' values select only data with quality >= abs(val). This allows for example to extract only the cloud coverage.

  • t_srs or target_proj: Some polar grids come with $longitude$, $latitude$ (or just $lon$, $lat$) arrays in geographical coordinates. There must be an (obscure) reason for this but the practical result is messy because coordinate spacings are highly variable preventing any decent guess. In these cases it is useful to reproject the data before griding. For that purpose use the t_srs or target_proj option to tell the program to do a coordinate conversion before gridding. t_srs should then be a proj4 string with the destiny projection system.

  • nodata: Sometimes datasets use other than NaN to represent nodata but they don't specify it in the netCDF attributes (e.g. the NSIDC products). This option allows to fix this (i.e nodata=-9999) Note that this is automatically set for the NSIDC products.

  • nointerp: Means to not do any nearneighbor interpolation but needs that region has been set.

  • NSIDC_N and NSIDC_S: Set the s_srs, region, nointerp, nodata appropriate to read the See Ice NSIDC https://nsidc.org/data/polar-stereo/ps_grids.html grids.

  • dataset or xyz: If instead of calculating a grid (returned as a GMTgrid type) user wants the x,y,z data intself, use the keywords dataset, or xyz and the output will be in a GMTdataset (i.e. use dataset=true).

To inquire just the list of available arrays use list=true or gdalinfo=true to get the full file info.

Examples:
 
 G = grid_at_sensor("AQUA_MODIS.20020717T135006.L2.SST.nc", "sst", V=true);
 
 G = grid_at_sensor("TXx-narr-annual-timavg.nc", "T2MAX", xarray="XLONG", yarray="XLAT", V=true);
 
-G = grid_at_sensor("RDEFT4_20101021.nc", "sea_ice_thickness", NSIDC_N=true);
source
RemoteS.mcariMethod
MCARI = mcari(green, red, redEdge1; kw...)

or

MCARI = mcari(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)

Modified Chlorophyll Absorption ratio index. Daughtery et al. 2000

MCARI = (redEdge1 - red - 0.2 * (redEdge1 - green)) * (redEdge1 / red)

(Sentinel-2 Band 5 (VNIR), Band 4 (Red) and Band 3 (Green)).

source
RemoteS.mndwiMethod
MNDWI = mndwi(green, swir2; kw...)

or

MNDWI = mndwi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)

Modified Normalised Difference Water Index. Xu2006

MNDWI = (green-swir2) / (green+swir2)

  • The first form accepts inputs as matrices, or file names of the data bands.
  • The second form is more versatile but also more complex to describe.
    • cube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.
    • bands: cubes created with cutcube assign descriptions starting with "Band1 ..." an so on the other bands. So when bands is used we search for bands named "Band'band[k]'", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.
    • layers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.
    • bandnames: When we know the common designation of a band, for example "Green", or any part of a band description, for example "NIR", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.
  • kwargs:
    • threshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN
    • classes: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.
    • mask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise
    • save: Use save="file_name.ext" to save the result in a disk file. File format is picked from file extension.

If none of bands, layers or bandnames is provided, we use the default band names shown in the first form.

See also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.

Returns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.

source
RemoteS.msaviMethod
MSAVI = msavi(red, nir; kw...)

or

MSAVI = msavi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)

Modified soil adjusted vegetation index. Qi 1994

MSAVI = nir + 0.5 - (0.5 * sqrt(pow(2.0 * nir + 1.0, 2) - 8.0 * (nir - (2.0 * red))))

  • The first form accepts inputs as matrices, or file names of the data bands.
  • The second form is more versatile but also more complex to describe.
    • cube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.
    • bands: cubes created with cutcube assign descriptions starting with "Band1 ..." an so on the other bands. So when bands is used we search for bands named "Band'band[k]'", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.
    • layers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.
    • bandnames: When we know the common designation of a band, for example "Green", or any part of a band description, for example "NIR", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.
  • kwargs:
    • threshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN
    • classes: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.
    • mask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise
    • save: Use save="file_name.ext" to save the result in a disk file. File format is picked from file extension.

If none of bands, layers or bandnames is provided, we use the default band names shown in the first form.

See also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.

Returns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.

source
RemoteS.mtciMethod
MTCI = mtci(red, redEdge1, redEdge2; kw...)

Meris Terrestrial Chlorophyll Index. Clevers and Gitelson 2013, Dash and Curran 2004

MTCI = (redEdge2-redEdge1) / (redEdge1-red)

source
RemoteS.nbriMethod
NBRI = nbri(nir, swir3; kw...)

or

NBRI = nbri(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)

Normalised Burn Ratio Index. Garcia 1991

NBRI = (nir - swir2) / (nir + swir2)

source
RemoteS.ndrei1Method
NDREI1 = ndrei1(redEdge1, redEdge2; kw...)

Normalized difference red edge index. Gitelson and Merzlyak 1994

NDREI1 = (redEdge2 - redEdge1) / (redEdge2 + redEdge1)

source
RemoteS.ndrei2Method
NDREI2 = ndrei2(redEdge1, redEdge3; kw...)

or

NDREI2 = ndrei2(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)

Normalized difference red edge index 2. Barnes et al 2000

NDREI2 = (redEdge3 - redEdge1) / (redEdge3 + redEdge1)

source
RemoteS.ndviMethod
NDVI = ndvi(red, nir; kw...)

or

NDVI = ndvi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)

Compute the NDVI vegetation index. Input can be either the bands file names, or GMTimage objects with the band's data.

NDVI = (nir - red) / (nir + red)

  • The first form accepts inputs as matrices, or file names of the data bands.
  • The second form is more versatile but also more complex to describe.
    • cube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.
    • bands: cubes created with cutcube assign descriptions starting with "Band1 ..." an so on the other bands. So when bands is used we search for bands named "Band'band[k]'", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.
    • layers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.
    • bandnames: When we know the common designation of a band, for example "Green", or any part of a band description, for example "NIR", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.
  • kwargs:
    • threshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN
    • classes: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.
    • mask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise
    • save: Use save="file_name.ext" to save the result in a disk file. File format is picked from file extension.

If none of bands, layers or bandnames is provided, we use the default band names shown in the first form.

See also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.

Returns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.

source
RemoteS.ndwiMethod
NDWI = ndwi(green, nir; kw...)

or

NDWI = ndwi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)

Normalized difference water index. McFeeters 1996. NDWI => (green - nir)/(green + nir)

NDWI = (green - nir)/(green + nir)

  • The first form accepts inputs as matrices, or file names of the data bands.
  • The second form is more versatile but also more complex to describe.
    • cube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.
    • bands: cubes created with cutcube assign descriptions starting with "Band1 ..." an so on the other bands. So when bands is used we search for bands named "Band'band[k]'", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.
    • layers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.
    • bandnames: When we know the common designation of a band, for example "Green", or any part of a band description, for example "NIR", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.
  • kwargs:
    • threshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN
    • classes: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.
    • mask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise
    • save: Use save="file_name.ext" to save the result in a disk file. File format is picked from file extension.

If none of bands, layers or bandnames is provided, we use the default band names shown in the first form.

See also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.

Returns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.

source
RemoteS.ndwi2Method
NDWI2 = ndwi2(nir, swir2; kw...)

or

NDWI2 = ndwi2(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)

Normalized difference water index. Gao 1996, Chen 2005 (also known as Normalized Difference Moisture Index NDBI and LSWI)

NDWI2 = (nir - swir2)/(nir + swir2)

  • The first form accepts inputs as matrices, or file names of the data bands.
  • The second form is more versatile but also more complex to describe.
    • cube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.
    • bands: cubes created with cutcube assign descriptions starting with "Band1 ..." an so on the other bands. So when bands is used we search for bands named "Band'band[k]'", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.
    • layers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.
    • bandnames: When we know the common designation of a band, for example "Green", or any part of a band description, for example "NIR", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.
  • kwargs:
    • threshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN
    • classes: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.
    • mask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise
    • save: Use save="file_name.ext" to save the result in a disk file. File format is picked from file extension.

If none of bands, layers or bandnames is provided, we use the default band names shown in the first form.

See also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.

Returns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.

source
RemoteS.reflectance_surfMethod
R = reflectance_surf(fname::String, [band::Int, bandname::String, mtl::String, save::String])

Computes the radiance-at-surface of Landsat8 band using the COST model.

  • fname: The name of either a $LANDSAT_PRODUCT_ID$ geotiff band, or the name of a cube file created with the cutcube function. In the first case, if the companion $...MTL.txt$ file is not in the same directory as fname one can still pass it via the mtl=path-to-MTL-file option. In the second case it is mandatory to use one of the following two options.
  • band: cubes created with cutcube assign descriptions starting with "Band 1 ..." an so on the other bands. So when band is used we search for the band named "Band N", where N = band.
  • bandname: When we know the common designation of a band, for example "Green", or any part of a band description, for example "NIR", we can use that info to create a bandname string that will be matched against the cube's bands descriptions. We can use the reportbands function to see the bands description.
  • save: The file name where to save the output. If not provided, a GMTgrid is returned.

Returns a Float32 GMTgrid

source
RemoteS.reportbandsMethod
reportbands(in; [layers=Int[]])

or

reportbands(in, layer;)

Report the Bands description of the in input argument. This can be a GMTimage, a GMTgrid or a file name (a String) of a 'cube' file. Normally one made with the cutcube function. When the use conditions of this function are not met, either a warning or an error message (if too deep to be caught as a warning) will be issued.

  • layers: When this optional parameter is used, report the description of the bands in the vector layers
  • layer: A scalar with a unique band number. Alternative form to reportbands(in, layers=[layer])

Returns a string vector.

source
RemoteS.sat_scenesMethod

satscenes(track, satname::String)

Compute polygons delimiting AQUA and TERRA scenes.

  • trac: Is an orbit computed with sat_tracks at steps of 1 minute (crucial)
  • sat_name: The satellite name. At this time only AQUA and TERRA are allowed.

Returns a GMTdataset vector with the polygons and the scene names in the dataset header field.

Example

Imagine that orb was obtained with

orb = sat_tracks(tle=[tle1; tle2], start=DateTime("2021-09-02T13:30:00"), stop=DateTime("2021-09-02T13:40:00"), step="1m");

The scenes limits (two) are computed with:

Dscenes = sat_scenes(orb, "AQUA");
source
RemoteS.sat_tracksMethod
sat_tracks(; geocentric::Bool=false, tiles::Bool=false, position::Bool=false, kwargs...)

Compute satellite tracks using the TLE, or Two Line Elements set, a data format that contains information about the orbit at a specific epoch of an Earth-orbiting object. It can also calculate polygons arround the scene extents of AQUA and TERRA satellites as well as create the scene names, which provides a mean to direct download that data.

  • start: A DateTime object or a string convertable to a DateTime with DateTime(start) specifying the start of the orbit calculation. If omited, current time in UTC will be used.
  • duration: Length of time for which the orbit is calculated. Accepts duration in days, hours, minutes or seconds. The default is minutes (100 minutes). To use other units use a string with the value appended with 'D', 'h', 'm' or 's'. e.g. duration="55m" to compute orbit 55 minutes from start
  • step or inc or dt: The time interval at which to compute locations along the orbit. The default unit here is seconds (30 sec) but minutes can be used as well by appending 'm'. e.g. step="1m"
  • stop: As alternative to duration provide the end date for the orbit. Same conditions as start
  • position: Computes only first location at the start time. Boolean, use position=true
  • geocentric: Boolean to controls if output is lon,lat,alt,time (the default) or ECEF coordinates + time.
  • tle or TLE: a file name with the TLE data for a specific satellite and period. It can also be a two elements string vector with the first and second lines of the TLE file.
  • tiles: Compute the scene limits and file names for some satellites. Currently AQUA only.
  • sat, SAT or satellite: Name of the satellite to use; choose from (string or symbols) :TERRA, :AQUA. Use only with the tiles option.

Returns

A GMTdataset with the orbit or the scene polygons

Example:

Compute ~one orbit of the AQUA satellite starting at current local time. Note, this will be accurate for the month of September 2021. For other dates it needs an updated TLE.

tle1 = "1 27424U 02022A   21245.83760660  .00000135  00000-0  39999-4 0  9997";
+G = grid_at_sensor("RDEFT4_20101021.nc", "sea_ice_thickness", NSIDC_N=true);
source
RemoteS.mcariMethod
MCARI = mcari(green, red, redEdge1; kw...)

or

MCARI = mcari(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)

Modified Chlorophyll Absorption ratio index. Daughtery et al. 2000

MCARI = (redEdge1 - red - 0.2 * (redEdge1 - green)) * (redEdge1 / red)

(Sentinel-2 Band 5 (VNIR), Band 4 (Red) and Band 3 (Green)).

source
RemoteS.mndwiMethod
MNDWI = mndwi(green, swir2; kw...)

or

MNDWI = mndwi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)

Modified Normalised Difference Water Index. Xu2006

MNDWI = (green-swir2) / (green+swir2)

  • The first form accepts inputs as matrices, or file names of the data bands.
  • The last form is more versatile but also more complex to describe.
    • cube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.
    • bands: cubes created with cutcube assign descriptions starting with "Band1 ..." an so on the other bands. So when bands is used we search for bands named "Band'band[k]'", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.
    • layers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.
    • bandnames: When we know the common designation of a band, for example "Green", or any part of a band description, for example "NIR", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.

Kwargs

  • threshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN
  • classes: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.
  • mask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise
  • save: Use save="file_name.ext" to save the result in a disk file. File format is picked from file extension.
  • order | bands_order | rgb: For the $GLI$, $TGI$ and $VARI$ (RGB) indices, we allow to reorder the bands and change the expected RGB order. Pass in a string, or symbol, with the color order. For example, order=:rbg
will swap the green and blue components making the result index identify the _reds_ instead of the _greens_.
+Not good for vegetation indices, but potentially useful for other purposes.

If none of bands, layers or bandnames is provided, we use the default band names shown in the first form.

See also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.

Returns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.

source
RemoteS.msaviMethod
MSAVI = msavi(red, nir; kw...)

or

MSAVI = msavi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)

Modified soil adjusted vegetation index. Qi 1994

MSAVI = nir + 0.5 - (0.5 * sqrt(pow(2.0 * nir + 1.0, 2) - 8.0 * (nir - (2.0 * red))))

  • The first form accepts inputs as matrices, or file names of the data bands.
  • The last form is more versatile but also more complex to describe.
    • cube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.
    • bands: cubes created with cutcube assign descriptions starting with "Band1 ..." an so on the other bands. So when bands is used we search for bands named "Band'band[k]'", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.
    • layers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.
    • bandnames: When we know the common designation of a band, for example "Green", or any part of a band description, for example "NIR", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.

Kwargs

  • threshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN
  • classes: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.
  • mask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise
  • save: Use save="file_name.ext" to save the result in a disk file. File format is picked from file extension.
  • order | bands_order | rgb: For the $GLI$, $TGI$ and $VARI$ (RGB) indices, we allow to reorder the bands and change the expected RGB order. Pass in a string, or symbol, with the color order. For example, order=:rbg
will swap the green and blue components making the result index identify the _reds_ instead of the _greens_.
+Not good for vegetation indices, but potentially useful for other purposes.

If none of bands, layers or bandnames is provided, we use the default band names shown in the first form.

See also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.

Returns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.

source
RemoteS.mtciMethod
MTCI = mtci(red, redEdge1, redEdge2; kw...)

Meris Terrestrial Chlorophyll Index. Clevers and Gitelson 2013, Dash and Curran 2004

MTCI = (redEdge2-redEdge1) / (redEdge1-red)

source
RemoteS.nbriMethod
NBRI = nbri(nir, swir3; kw...)

or

NBRI = nbri(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)

Normalised Burn Ratio Index. Garcia 1991

NBRI = (nir - swir2) / (nir + swir2)

source
RemoteS.ndrei1Method
NDREI1 = ndrei1(redEdge1, redEdge2; kw...)

Normalized difference red edge index. Gitelson and Merzlyak 1994

NDREI1 = (redEdge2 - redEdge1) / (redEdge2 + redEdge1)

source
RemoteS.ndrei2Method
NDREI2 = ndrei2(redEdge1, redEdge3; kw...)

or

NDREI2 = ndrei2(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)

Normalized difference red edge index 2. Barnes et al 2000

NDREI2 = (redEdge3 - redEdge1) / (redEdge3 + redEdge1)

source
RemoteS.ndviMethod
NDVI = ndvi(red, nir; kw...)

or

NDVI = ndvi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)

Compute the NDVI vegetation index. Input can be either the bands file names, or GMTimage objects with the band's data.

NDVI = (nir - red) / (nir + red)

  • The first form accepts inputs as matrices, or file names of the data bands.
  • The last form is more versatile but also more complex to describe.
    • cube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.
    • bands: cubes created with cutcube assign descriptions starting with "Band1 ..." an so on the other bands. So when bands is used we search for bands named "Band'band[k]'", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.
    • layers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.
    • bandnames: When we know the common designation of a band, for example "Green", or any part of a band description, for example "NIR", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.

Kwargs

  • threshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN
  • classes: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.
  • mask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise
  • save: Use save="file_name.ext" to save the result in a disk file. File format is picked from file extension.
  • order | bands_order | rgb: For the $GLI$, $TGI$ and $VARI$ (RGB) indices, we allow to reorder the bands and change the expected RGB order. Pass in a string, or symbol, with the color order. For example, order=:rbg
will swap the green and blue components making the result index identify the _reds_ instead of the _greens_.
+Not good for vegetation indices, but potentially useful for other purposes.

If none of bands, layers or bandnames is provided, we use the default band names shown in the first form.

See also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.

Returns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.

source
RemoteS.ndwiMethod
NDWI = ndwi(green, nir; kw...)

or

NDWI = ndwi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)

Normalized difference water index. McFeeters 1996. NDWI => (green - nir)/(green + nir)

NDWI = (green - nir)/(green + nir)

  • The first form accepts inputs as matrices, or file names of the data bands.
  • The last form is more versatile but also more complex to describe.
    • cube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.
    • bands: cubes created with cutcube assign descriptions starting with "Band1 ..." an so on the other bands. So when bands is used we search for bands named "Band'band[k]'", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.
    • layers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.
    • bandnames: When we know the common designation of a band, for example "Green", or any part of a band description, for example "NIR", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.

Kwargs

  • threshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN
  • classes: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.
  • mask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise
  • save: Use save="file_name.ext" to save the result in a disk file. File format is picked from file extension.
  • order | bands_order | rgb: For the $GLI$, $TGI$ and $VARI$ (RGB) indices, we allow to reorder the bands and change the expected RGB order. Pass in a string, or symbol, with the color order. For example, order=:rbg
will swap the green and blue components making the result index identify the _reds_ instead of the _greens_.
+Not good for vegetation indices, but potentially useful for other purposes.

If none of bands, layers or bandnames is provided, we use the default band names shown in the first form.

See also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.

Returns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.

source
RemoteS.ndwi2Method
NDWI2 = ndwi2(nir, swir2; kw...)

or

NDWI2 = ndwi2(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)

Normalized difference water index. Gao 1996, Chen 2005 (also known as Normalized Difference Moisture Index NDBI and LSWI)

NDWI2 = (nir - swir2)/(nir + swir2)

  • The first form accepts inputs as matrices, or file names of the data bands.
  • The last form is more versatile but also more complex to describe.
    • cube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.
    • bands: cubes created with cutcube assign descriptions starting with "Band1 ..." an so on the other bands. So when bands is used we search for bands named "Band'band[k]'", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.
    • layers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.
    • bandnames: When we know the common designation of a band, for example "Green", or any part of a band description, for example "NIR", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.

Kwargs

  • threshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN
  • classes: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.
  • mask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise
  • save: Use save="file_name.ext" to save the result in a disk file. File format is picked from file extension.
  • order | bands_order | rgb: For the $GLI$, $TGI$ and $VARI$ (RGB) indices, we allow to reorder the bands and change the expected RGB order. Pass in a string, or symbol, with the color order. For example, order=:rbg
will swap the green and blue components making the result index identify the _reds_ instead of the _greens_.
+Not good for vegetation indices, but potentially useful for other purposes.

If none of bands, layers or bandnames is provided, we use the default band names shown in the first form.

See also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.

Returns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.

source
RemoteS.reflectance_surfMethod
R = reflectance_surf(fname::String, [band::Int, bandname::String, mtl::String, save::String])

Computes the radiance-at-surface of Landsat8 band using the COST model.

  • fname: The name of either a $LANDSAT_PRODUCT_ID$ geotiff band, or the name of a cube file created with the cutcube function. In the first case, if the companion $...MTL.txt$ file is not in the same directory as fname one can still pass it via the mtl=path-to-MTL-file option. In the second case it is mandatory to use one of the following two options.
  • band: cubes created with cutcube assign descriptions starting with "Band 1 ..." an so on the other bands. So when band is used we search for the band named "Band N", where N = band.
  • bandname: When we know the common designation of a band, for example "Green", or any part of a band description, for example "NIR", we can use that info to create a bandname string that will be matched against the cube's bands descriptions. We can use the reportbands function to see the bands description.
  • save: The file name where to save the output. If not provided, a GMTgrid is returned.

Returns a Float32 GMTgrid

source
RemoteS.reportbandsMethod
reportbands(in; [layers=Int[]])

or

reportbands(in, layer;)

Report the Bands description of the in input argument. This can be a GMTimage, a GMTgrid or a file name (a String) of a 'cube' file. Normally one made with the cutcube function. When the use conditions of this function are not met, either a warning or an error message (if too deep to be caught as a warning) will be issued.

  • layers: When this optional parameter is used, report the description of the bands in the vector layers
  • layer: A scalar with a unique band number. Alternative form to reportbands(in, layers=[layer])

Returns a string vector.

source
RemoteS.sat_scenesMethod

satscenes(track, satname::String)

Compute polygons delimiting AQUA and TERRA scenes.

  • trac: Is an orbit computed with sat_tracks at steps of 1 minute (crucial)
  • sat_name: The satellite name. At this time only AQUA and TERRA are allowed.

Returns a GMTdataset vector with the polygons and the scene names in the dataset header field.

Example

Imagine that orb was obtained with

orb = sat_tracks(tle=[tle1; tle2], start=DateTime("2021-09-02T13:30:00"), stop=DateTime("2021-09-02T13:40:00"), step="1m");

The scenes limits (two) are computed with:

Dscenes = sat_scenes(orb, "AQUA");
source
RemoteS.sat_tracksMethod
sat_tracks(; geocentric::Bool=false, tiles::Bool=false, position::Bool=false, kwargs...)

Compute satellite tracks using the TLE, or Two Line Elements set, a data format that contains information about the orbit at a specific epoch of an Earth-orbiting object. It can also calculate polygons arround the scene extents of AQUA and TERRA satellites as well as create the scene names, which provides a mean to direct download that data.

  • start: A DateTime object or a string convertable to a DateTime with DateTime(start) specifying the start of the orbit calculation. If omited, current time in UTC will be used.
  • duration: Length of time for which the orbit is calculated. Accepts duration in days, hours, minutes or seconds. The default is minutes (100 minutes). To use other units use a string with the value appended with 'D', 'h', 'm' or 's'. e.g. duration="55m" to compute orbit 55 minutes from start
  • step or inc or dt: The time interval at which to compute locations along the orbit. The default unit here is seconds (30 sec) but minutes can be used as well by appending 'm'. e.g. step="1m"
  • stop: As alternative to duration provide the end date for the orbit. Same conditions as start
  • position: Computes only first location at the start time. Boolean, use position=true
  • geocentric: Boolean to controls if output is lon,lat,alt,time (the default) or ECEF coordinates + time.
  • tle or TLE: a file name with the TLE data for a specific satellite and period. It can also be a two elements string vector with the first and second lines of the TLE file.
  • tiles: Compute the scene limits and file names for some satellites. Currently AQUA only.
  • sat, SAT or satellite: Name of the satellite to use; choose from (string or symbols) :TERRA, :AQUA. Use only with the tiles option.

Returns

A GMTdataset with the orbit or the scene polygons

Example:

Compute ~one orbit of the AQUA satellite starting at current local time. Note, this will be accurate for the month of September 2021. For other dates it needs an updated TLE.

tle1 = "1 27424U 02022A   21245.83760660  .00000135  00000-0  39999-4 0  9997";
 tle2 = "2 27424  98.2123 186.0654 0002229  67.6025 313.3829 14.57107527 28342";
-orb = sat_tracks(tle=[tle1; tle2], duration=100);

and the orbit track can be visualized with

imshow(orb,  proj=:Robinson, region=:global, coast=true)

WARNING: This function depends on the SatelliteToolbox extension that is not loaded by default. Load it with:

  • $using RemoteS, SatelliteToolboxTle, SatelliteToolboxPropagators, SatelliteToolboxTransformations$
source
RemoteS.satviMethod
SATVI = satvi(red, swir2, swir3; kw...)

or

SATVI = satvi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)

Soil adjusted total vegetation index. Marsett 2006

SATVI = ((swir1 - red) / (swir1 + red + L)) * (1.0 + L) - (swir2 / 2.0)

source
RemoteS.saviMethod
SAVI = savi(red, nir; kw...)

or

SAVI = savi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)

Soil adjusted vegetation index. Huete 1988

SAVI = (nir - red) * (1.0 + L) / (nir + red + L)

  • The first form accepts inputs as matrices, or file names of the data bands.
  • The second form is more versatile but also more complex to describe.
    • cube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.
    • bands: cubes created with cutcube assign descriptions starting with "Band1 ..." an so on the other bands. So when bands is used we search for bands named "Band'band[k]'", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.
    • layers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.
    • bandnames: When we know the common designation of a band, for example "Green", or any part of a band description, for example "NIR", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.
  • kwargs:
    • threshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN
    • classes: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.
    • mask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise
    • save: Use save="file_name.ext" to save the result in a disk file. File format is picked from file extension.

If none of bands, layers or bandnames is provided, we use the default band names shown in the first form.

See also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.

Returns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.

source
RemoteS.slaviMethod
SLAVI = slavi(red, nir, swir2; kw...)

or

SLAVI = slavi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)

Specific Leaf Area Vegetation Index. Lymburger 2000

SLAVI = nir / (red + swir2)

  • The first form accepts inputs as matrices, or file names of the data bands.
  • The second form is more versatile but also more complex to describe.
    • cube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.
    • bands: cubes created with cutcube assign descriptions starting with "Band1 ..." an so on the other bands. So when bands is used we search for bands named "Band'band[k]'", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.
    • layers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.
    • bandnames: When we know the common designation of a band, for example "Green", or any part of a band description, for example "NIR", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.
  • kwargs:
    • threshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN
    • classes: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.
    • mask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise
    • save: Use save="file_name.ext" to save the result in a disk file. File format is picked from file extension.

If none of bands, layers or bandnames is provided, we use the default band names shown in the first form.

See also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.

Returns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.

source
RemoteS.subcubeMethod
subcube(cube::String; bands=Int[], bandnames=String[], layers=Int[])

Extracts a subcube from cube with the layers in the bands vector, case in which we will search for bands named "Band band[k]", or those whose names correspond (even partially and case insensitive) to the descriptions in bandnames string vector. This means that the options bands and bandnames can only be used in 'cubes' with bands description. The layers option blindly extract the cube planes listed in the layer vector.

Returns a GMTimage

subcube(cube::Union{GMT.GMTimage{UInt16, 3}, AbstractArray{<:AbstractFloat, 3}}; bands=Int[], bandnames=String[], layers=Int[])

Does the same but from an already in memory cube. Returns a type equal to the input type. No views, a data copy.

Example

Extracts the Red, Green and Blue layers from a Landsat 8 cube created with cutcube

Irgb = subcube("LC08__cube.tiff", bandnames = ["red", "green", "blue"])
source
RemoteS.tgiMethod
TGI = tgi(red, green, blue; kw...)

or (here fname is a .png or .jpg file name)

TGI = tgi(fname::String; kw...)

or

TGI = tgi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)

Triangular Greenness Index. Hunt et al. 2013

TGI = green - 0.39 * red - 0.61 * blue

  • The first form accepts inputs as matrices, or file names of the data bands.
  • The second form is more versatile but also more complex to describe.
    • cube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.
    • bands: cubes created with cutcube assign descriptions starting with "Band1 ..." an so on the other bands. So when bands is used we search for bands named "Band'band[k]'", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.
    • layers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.
    • bandnames: When we know the common designation of a band, for example "Green", or any part of a band description, for example "NIR", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.
  • kwargs:
    • threshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN
    • classes: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.
    • mask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise
    • save: Use save="file_name.ext" to save the result in a disk file. File format is picked from file extension.

If none of bands, layers or bandnames is provided, we use the default band names shown in the first form.

See also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.

Returns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.

source
RemoteS.train_rasterMethod
model, classes = train_raster(cube::GItype, train::Union{Vector{<:GMTdataset}, String}; np::Int=0, density=0.1)
  • cube: The cube wtih band data to classify.
  • train: A vector of GMTdatasets or a file name of one containing the polygons used to train the model. NOTE: The individual datasets MUST have associated an attribute called "class" containing the class name as a string. This can be achieved for text data in the form of a GMT multi-segment file (one where segments are separated by the '>' symbol) if the multi-segment separator line contains the text $Attrib(class=name)$
  • np: Number of points per polygon to be determined by $randinpolygon$
  • density: Alternative to np. See also the help of the $randinpolygon$ function.

Returns the trained model and the class names.

source
RemoteS.truecolorMethod
Irgb = truecolor(bndR, bndG, bndB)

Take three Landsat8/Sentinel2 UINT16 GMTimages or the file names of those bands and compose an RGB true color image applying automatic histogram stretching.

Return an UInt8 RGB GMTimage

Irgb = truecolor(cube::GMTImage, bands::Vector{Int})

Make an RGB composition of the 3 bands passed in the vector 'bands' from the layers in the multi-layered GMTimage cube

Return an auto-stretched UInt8 RGB GMTimage

Irgb = truecolor(cube::String, [bands::Vector{Int}], [bandnames::Vector{String}], [raw=false])

Make an RGB composition of 3 bands from the cube file holding a UInt16 multi-layered array (often created with cutcube) The band selection can be made with bands vector, case in which we will search for bands named "Band[k]" or where the bands description contain the contents of bandnames. If none of bands or bandnames is used we search for a made up bandnames=["red", "green", "blue"].

Return an auto-stretched UInt8 RGB GMTimage OR a GMTimage{UInt16,3} if the raw option is set to true.

Irgb = truecolor(cube::GMTgrid, [bands|layers::Vector{Int}], [bandnames::Vector{String}], [type=UInt8])

Make an RGB composition of 3 bands from the cube file holding a Float32 multi-layered array. The band selection can be made with bands vector, case in which we will search for bands named "Band[k]" or where the bands description contain the contents of bandnames. If none of bands or bandnames is used we search for a made up bandnames=["red", "green", "blue"].

By default we scale the bands to 0-255. Use type=UInt16 to scale the bands to 0-65535`. Note that this will matter only for the guessing of the good limits to perform the histogram stretching.

Example:

Make an RGB composite from data in the cube file "LC08__cube.tiff"

I = truecolor("LC08__cube.tiff");
source
RemoteS.variMethod
VARI = vari(red, green, blue; kw...)

or (here fname is a .png or .jpg file name)

VARI = vari(fname::String; kw...)

or

VARI = vari(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)

Visible Atmospherically Resistant Index. Gitelson, A.A., Kaufman, Y.J., Stark, R., Rundquist, D., 2002

VARI = (green - red) / (green + red - blue)

  • The first form accepts inputs as matrices, or file names of the data bands.
  • The second form is more versatile but also more complex to describe.
    • cube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.
    • bands: cubes created with cutcube assign descriptions starting with "Band1 ..." an so on the other bands. So when bands is used we search for bands named "Band'band[k]'", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.
    • layers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.
    • bandnames: When we know the common designation of a band, for example "Green", or any part of a band description, for example "NIR", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.
  • kwargs:
    • threshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN
    • classes: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.
    • mask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise
    • save: Use save="file_name.ext" to save the result in a disk file. File format is picked from file extension.

If none of bands, layers or bandnames is provided, we use the default band names shown in the first form.

See also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.

Returns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.

source
RemoteS.RemoteSModule

Package to perform operations with satellite data. Easy to use in computing true color images with automatic contrast stretch, many spectral indices and processing of MODIS L2 files.

source
RemoteS.classification_probaMethod
I = classification_proba(cube::GItype, model; class_number=1) -> GMTimage

Returns an image with the assigned probabilities when classifying the class number class_number

  • cube: The cube wtih band data to classify
  • model: is the model obtained from the train_raster function
  • class_number: is the class number to be classified
source
RemoteS.read_mtlFunction

readmtl(bandname::String, mtl::String=""; get_full=false)

Use the band_name of a Landsat8 band to find the MTL file with the scene parameters at which that band belongs and read the params needed to compute Brightness temperature, radiance at top of atmosphere, etc. If the MTL file does not lieve next to the band file, send its name via the mtl argument.

The get_full option makes this function return a tring with contents of the MTL file or nothing if the MTL file is not found.

Returns a tuple with:

(band=band, radmul=radmul, radadd=radadd, radmax=radmax, reflectmul=reflectmul, reflectadd=reflectadd, reflectmax=reflectmax, sunazim=sunazim, sunelev=sunelev, sundis=sunazim, K1=K1, K2=K2)

or a string with MTL contents (or nothing if MTL file is not found)

source
+orb = sat_tracks(tle=[tle1; tle2], duration=100);

and the orbit track can be visualized with

imshow(orb,  proj=:Robinson, region=:global, coast=true)

WARNING: This function depends on the SatelliteToolbox extension that is not loaded by default. Load it with:

  • $using RemoteS, SatelliteToolboxTle, SatelliteToolboxPropagators, SatelliteToolboxTransformations$
source
RemoteS.satviMethod
SATVI = satvi(red, swir2, swir3; kw...)

or

SATVI = satvi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)

Soil adjusted total vegetation index. Marsett 2006

SATVI = ((swir1 - red) / (swir1 + red + L)) * (1.0 + L) - (swir2 / 2.0)

source
RemoteS.saviMethod
SAVI = savi(red, nir; kw...)

or

SAVI = savi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)

Soil adjusted vegetation index. Huete 1988

SAVI = (nir - red) * (1.0 + L) / (nir + red + L)

  • The first form accepts inputs as matrices, or file names of the data bands.
  • The last form is more versatile but also more complex to describe.
    • cube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.
    • bands: cubes created with cutcube assign descriptions starting with "Band1 ..." an so on the other bands. So when bands is used we search for bands named "Band'band[k]'", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.
    • layers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.
    • bandnames: When we know the common designation of a band, for example "Green", or any part of a band description, for example "NIR", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.

Kwargs

  • threshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN
  • classes: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.
  • mask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise
  • save: Use save="file_name.ext" to save the result in a disk file. File format is picked from file extension.
  • order | bands_order | rgb: For the $GLI$, $TGI$ and $VARI$ (RGB) indices, we allow to reorder the bands and change the expected RGB order. Pass in a string, or symbol, with the color order. For example, order=:rbg
will swap the green and blue components making the result index identify the _reds_ instead of the _greens_.
+Not good for vegetation indices, but potentially useful for other purposes.

If none of bands, layers or bandnames is provided, we use the default band names shown in the first form.

See also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.

Returns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.

source
RemoteS.slaviMethod
SLAVI = slavi(red, nir, swir2; kw...)

or

SLAVI = slavi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)

Specific Leaf Area Vegetation Index. Lymburger 2000

SLAVI = nir / (red + swir2)

  • The first form accepts inputs as matrices, or file names of the data bands.
  • The last form is more versatile but also more complex to describe.
    • cube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.
    • bands: cubes created with cutcube assign descriptions starting with "Band1 ..." an so on the other bands. So when bands is used we search for bands named "Band'band[k]'", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.
    • layers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.
    • bandnames: When we know the common designation of a band, for example "Green", or any part of a band description, for example "NIR", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.

Kwargs

  • threshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN
  • classes: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.
  • mask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise
  • save: Use save="file_name.ext" to save the result in a disk file. File format is picked from file extension.
  • order | bands_order | rgb: For the $GLI$, $TGI$ and $VARI$ (RGB) indices, we allow to reorder the bands and change the expected RGB order. Pass in a string, or symbol, with the color order. For example, order=:rbg
will swap the green and blue components making the result index identify the _reds_ instead of the _greens_.
+Not good for vegetation indices, but potentially useful for other purposes.

If none of bands, layers or bandnames is provided, we use the default band names shown in the first form.

See also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.

Returns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.

source
RemoteS.subcubeMethod
subcube(cube::String; bands=Int[], bandnames=String[], layers=Int[])

Extracts a subcube from cube with the layers in the bands vector, case in which we will search for bands named "Band band[k]", or those whose names correspond (even partially and case insensitive) to the descriptions in bandnames string vector. This means that the options bands and bandnames can only be used in 'cubes' with bands description. The layers option blindly extract the cube planes listed in the layer vector.

Returns a GMTimage

subcube(cube::Union{GMT.GMTimage{UInt16, 3}, AbstractArray{<:AbstractFloat, 3}}; bands=Int[], bandnames=String[], layers=Int[])

Does the same but from an already in memory cube. Returns a type equal to the input type. No views, a data copy.

Example

Extracts the Red, Green and Blue layers from a Landsat 8 cube created with cutcube

Irgb = subcube("LC08__cube.tiff", bandnames = ["red", "green", "blue"])
source
RemoteS.tgiMethod
TGI = tgi(red, green, blue; kw...)

or (here fname is a .png or .jpg file name)

TGI = tgi(fname::String; kw...)

or

TGI = tgi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)

Triangular Greenness Index. Hunt et al. 2013

TGI = green - 0.39 * red - 0.61 * blue

  • The first form accepts inputs as matrices, or file names of the data bands.
  • The last form is more versatile but also more complex to describe.
    • cube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.
    • bands: cubes created with cutcube assign descriptions starting with "Band1 ..." an so on the other bands. So when bands is used we search for bands named "Band'band[k]'", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.
    • layers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.
    • bandnames: When we know the common designation of a band, for example "Green", or any part of a band description, for example "NIR", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.

Kwargs

  • threshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN
  • classes: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.
  • mask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise
  • save: Use save="file_name.ext" to save the result in a disk file. File format is picked from file extension.
  • order | bands_order | rgb: For the $GLI$, $TGI$ and $VARI$ (RGB) indices, we allow to reorder the bands and change the expected RGB order. Pass in a string, or symbol, with the color order. For example, order=:rbg
will swap the green and blue components making the result index identify the _reds_ instead of the _greens_.
+Not good for vegetation indices, but potentially useful for other purposes.

If none of bands, layers or bandnames is provided, we use the default band names shown in the first form.

See also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.

Returns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.

source
RemoteS.train_rasterMethod
model, classes = train_raster(cube::GItype, train::Union{Vector{<:GMTdataset}, String}; np::Int=0, density=0.1)
  • cube: The cube wtih band data to classify.
  • train: A vector of GMTdatasets or a file name of one containing the polygons used to train the model. NOTE: The individual datasets MUST have associated an attribute called "class" containing the class name as a string. This can be achieved for text data in the form of a GMT multi-segment file (one where segments are separated by the '>' symbol) if the multi-segment separator line contains the text $Attrib(class=name)$
  • np: Number of points per polygon to be determined by $randinpolygon$
  • density: Alternative to np. See also the help of the $randinpolygon$ function.

Returns the trained model and the class names.

source
RemoteS.truecolorMethod
Irgb = truecolor(bndR, bndG, bndB)

Take three Landsat8/Sentinel2 UINT16 GMTimages or the file names of those bands and compose an RGB true color image applying automatic histogram stretching.

Return an UInt8 RGB GMTimage

Irgb = truecolor(cube::GMTImage, bands::Vector{Int})

Make an RGB composition of the 3 bands passed in the vector 'bands' from the layers in the multi-layered GMTimage cube

Return an auto-stretched UInt8 RGB GMTimage

Irgb = truecolor(cube::String, [bands::Vector{Int}], [bandnames::Vector{String}], [raw=false])

Make an RGB composition of 3 bands from the cube file holding a UInt16 multi-layered array (often created with cutcube) The band selection can be made with bands vector, case in which we will search for bands named "Band[k]" or where the bands description contain the contents of bandnames. If none of bands or bandnames is used we search for a made up bandnames=["red", "green", "blue"].

Return an auto-stretched UInt8 RGB GMTimage OR a GMTimage{UInt16,3} if the raw option is set to true.

Irgb = truecolor(cube::GMTgrid, [bands|layers::Vector{Int}], [bandnames::Vector{String}], [type=UInt8])

Make an RGB composition of 3 bands from the cube file holding a Float32 multi-layered array. The band selection can be made with bands vector, case in which we will search for bands named "Band[k]" or where the bands description contain the contents of bandnames. If none of bands or bandnames is used we search for a made up bandnames=["red", "green", "blue"].

By default we scale the bands to 0-255. Use type=UInt16 to scale the bands to 0-65535`. Note that this will matter only for the guessing of the good limits to perform the histogram stretching.

Example:

Make an RGB composite from data in the cube file "LC08__cube.tiff"

I = truecolor("LC08__cube.tiff");
source
RemoteS.variMethod
VARI = vari(red, green, blue; kw...)

or (here fname is a .png or .jpg file name)

VARI = vari(fname::String; kw...)

or

VARI = vari(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)

Visible Atmospherically Resistant Index. Gitelson, A.A., Kaufman, Y.J., Stark, R., Rundquist, D., 2002

VARI = (green - red) / (green + red - blue)

  • The first form accepts inputs as matrices, or file names of the data bands.
  • The last form is more versatile but also more complex to describe.
    • cube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.
    • bands: cubes created with cutcube assign descriptions starting with "Band1 ..." an so on the other bands. So when bands is used we search for bands named "Band'band[k]'", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.
    • layers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.
    • bandnames: When we know the common designation of a band, for example "Green", or any part of a band description, for example "NIR", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.

Kwargs

  • threshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN
  • classes: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.
  • mask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise
  • save: Use save="file_name.ext" to save the result in a disk file. File format is picked from file extension.
  • order | bands_order | rgb: For the $GLI$, $TGI$ and $VARI$ (RGB) indices, we allow to reorder the bands and change the expected RGB order. Pass in a string, or symbol, with the color order. For example, order=:rbg
will swap the green and blue components making the result index identify the _reds_ instead of the _greens_.
+Not good for vegetation indices, but potentially useful for other purposes.

If none of bands, layers or bandnames is provided, we use the default band names shown in the first form.

See also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.

Returns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.

source
RemoteS.RemoteSModule

Package to perform operations with satellite data. Easy to use in computing true color images with automatic contrast stretch, many spectral indices and processing of MODIS L2 files.

source
RemoteS.classification_probaMethod
I = classification_proba(cube::GItype, model; class_number=1) -> GMTimage

Returns an image with the assigned probabilities when classifying the class number class_number

  • cube: The cube wtih band data to classify
  • model: is the model obtained from the train_raster function
  • class_number: is the class number to be classified
source
RemoteS.read_mtlFunction

readmtl(bandname::String, mtl::String=""; get_full=false)

Use the band_name of a Landsat8 band to find the MTL file with the scene parameters at which that band belongs and read the params needed to compute Brightness temperature, radiance at top of atmosphere, etc. If the MTL file does not lieve next to the band file, send its name via the mtl argument.

The get_full option makes this function return a tring with contents of the MTL file or nothing if the MTL file is not found.

Returns a tuple with:

(band=band, radmul=radmul, radadd=radadd, radmax=radmax, reflectmul=reflectmul, reflectadd=reflectadd, reflectmax=reflectmax, sunazim=sunazim, sunelev=sunelev, sundis=sunazim, K1=K1, K2=K2)

or a string with MTL contents (or nothing if MTL file is not found)

source
diff --git a/dev/search/index.html b/dev/search/index.html index 1d07528..6aa04ca 100644 --- a/dev/search/index.html +++ b/dev/search/index.html @@ -1,2 +1,2 @@ -Search · RemoteS.jl

Loading search...

    +Search · RemoteS.jl

    Loading search...

      diff --git a/dev/search_index.js b/dev/search_index.js index 4a16089..183615d 100644 --- a/dev/search_index.js +++ b/dev/search_index.js @@ -1,3 +1,3 @@ var documenterSearchIndex = {"docs": -[{"location":"gallery/HLS/cloud-native-hls-data/#Getting-Started-with-Cloud-Native-HLS-Data-in-Julia:-1","page":"Cloud-Native HLS dat","title":"Getting Started with Cloud-Native HLS Data in Julia:","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Extracting an EVI Time Series from Harmonized Landsat-8 Sentinel-2 (HLS) data in the Cloud using CMR's SpatioTemporal Asset Catalog (CMR-STAC). This tutorial demonstrates how to work with the HLS Landsat 8 (HLSL30.015) and Sentinel-2 (HLSS30.015) data products.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#NOTE:-This-tutorial-is-adapted-from-[Getting-Started-with-Cloud-Native-HLS-Data-in-Python](https://lpdaac.usgs.gov/resources/e-learning/getting-started-cloud-native-hls-data-python/)-1","page":"Cloud-Native HLS dat","title":"NOTE: This tutorial is adapted from Getting Started with Cloud-Native HLS Data in Python","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#.-Importing-packages-1","page":"Cloud-Native HLS dat","title":"1. Importing packages","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"using HTTP, JSON, GMT, RemoteS\n\nr = HTTP.request(\"GET\", \"https://cmr.earthdata.nasa.gov/stac/\");\nstac_response = JSON.parse(String(r.body));","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#.-Navigating-the-CMR-STAC-API-1","page":"Cloud-Native HLS dat","title":"2. Navigating the CMR-STAC API","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"What is STAC?","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"STAC is a specification that provides a common language for interpreting geospatial information in order to standardize indexing and discovering data.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Four STAC Specifications:","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"STAC API\nSTAC Catalog\nSTAC Collection\nSTAC Item","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#STAC-Catalog:-Contains-a-JSON-file-of-links-that-organize-all-of-the-collections-available.-1","page":"Cloud-Native HLS dat","title":"STAC Catalog: Contains a JSON file of links that organize all of the collections available.","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#Search-for-LP-DAAC-Catalogs,-and-print-the-information-contained-in-the-Catalog-that-we-will-be-using-today,-LPCLOUD-1","page":"Cloud-Native HLS dat","title":"Search for LP DAAC Catalogs, and print the information contained in the Catalog that we will be using today, LPCLOUD","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"stac_lp = [s for s in stac_response[\"links\"] if occursin(\"LP\", s[\"title\"])]\n\n# LPCLOUD is the STAC catalog we will be using and exploring today\nhr = [s for s in stac_lp if s[\"title\"] == \"LPCLOUD\"][1][\"href\"];\nr = HTTP.request(\"GET\", hr);\nlp_cloud = JSON.parse(String(r.body));","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#Print-the-links-contained-in-the-LP-CLOUD-STAC-Catalog-1","page":"Cloud-Native HLS dat","title":"Print the links contained in the LP CLOUD STAC Catalog","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"lp_links = lp_cloud[\"links\"];\n\nfor l in lp_links\n try\n println(l[\"href\"], \" is the \", l[\"title\"])\n catch\n println(l[\"href\"])\n end\nend","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"https://cmr.earthdata.nasa.gov/stac/LPCLOUD is the Provider catalog\nhttps://cmr.earthdata.nasa.gov/stac/ is the Root catalog\nhttps://cmr.earthdata.nasa.gov/stac/LPCLOUD/collections is the Provider Collections\nhttps://cmr.earthdata.nasa.gov/stac/LPCLOUD/search is the Provider Item Search\nhttps://cmr.earthdata.nasa.gov/stac/LPCLOUD/search is the Provider Item Search\nhttps://cmr.earthdata.nasa.gov/stac/LPCLOUD/conformance is the Conformance Classes\nhttps://api.stacspec.org/v1.0.0-beta.1/openapi.yaml is the OpenAPI Doc\nhttps://api.stacspec.org/v1.0.0-beta.1/index.html is the HTML documentation\nhttps://cmr.earthdata.nasa.gov/stac/LPCLOUD/collections/ASTGTM.v003\nhttps://cmr.earthdata.nasa.gov/stac/LPCLOUD/collections/HLSL30.v2.0\nhttps://cmr.earthdata.nasa.gov/stac/LPCLOUD/collections/HLSL30.v1.5\nhttps://cmr.earthdata.nasa.gov/stac/LPCLOUD/collections/HLSS30.v1.5\nhttps://cmr.earthdata.nasa.gov/stac/LPCLOUD/collections/HLSS30.v2.0","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#.-STAC-Collection:-Extension-of-STAC-Catalog-containing-additional-information-that-describe-the-STAC-Items-in-that-Collection.-1","page":"Cloud-Native HLS dat","title":"3. STAC Collection: Extension of STAC Catalog containing additional information that describe the STAC Items in that Collection.","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#Get-a-response-from-the-LPCLOUD-Collection-and-print-the-information-included-in-the-response.-1","page":"Cloud-Native HLS dat","title":"Get a response from the LPCLOUD Collection and print the information included in the response.","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Set collections endpoint to variable\nlp_collections = [l[\"href\"] for l in lp_links if l[\"rel\"] == \"collections\"][1];\n\n# Call collections endpoint\nr = HTTP.request(\"GET\", lp_collections);\ncollections_response = JSON.parse(String(r.body));\n\nprintln(\"This collection contains $(collections_response[\"description\"]) ($(length(collections_response[\"collections\"])) available)\")","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"This collection contains All collections provided by LPCLOUD (5 available)","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#As-of-October-3,-2021,-there-are-five-collections-available,-and-more-will-be-added-in-the-future.-1","page":"Cloud-Native HLS dat","title":"As of October 3, 2021, there are five collections available, and more will be added in the future.","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#Print-out-one-of-the-collections:-1","page":"Cloud-Native HLS dat","title":"Print out one of the collections:","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"collections = collections_response[\"collections\"];\ncollections[2]","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Dict{String, Any} with 8 entries:\n \"links\" => Any[Dict{String, Any}(\"rel\"=>\"self\", \"href\"=>\"https://cmr.e…\n \"id\" => \"HLSL30.v2.0\"\n \"stac_version\" => \"1.0.0\"\n \"title\" => \"HLS Landsat Operational Land Imager Surface Reflectance an…\n \"license\" => \"not-provided\"\n \"type\" => \"Collection\"\n \"description\" => \"The Harmonized Landsat and Sentinel-2 (HLS) project provid…\n \"extent\" => Dict{String, Any}(\"spatial\"=>Dict{String, Any}(\"bbox\"=>Any[…","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#In-CMR,-id-is-used-to-query-by-a-specific-product,-so-be-sure-to-save-the-ID-for-the-HLS-S30-and-L30-V1.5-products-below:-1","page":"Cloud-Native HLS dat","title":"In CMR, id is used to query by a specific product, so be sure to save the ID for the HLS S30 and L30 V1.5 products below:","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Search available collections for HLS and print them out\nhls_collections = [c for c in collections if contains(c[\"title\"], \"HLS\")];\n\n[println(\"$(h[\"title\"]) has ID (shortname) of: $(h[\"id\"])\") for h in hls_collections]","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"HLS Landsat Operational Land Imager Surface Reflectance and TOA Brightness Daily Global 30m v2.0 has ID (shortname) of: HLSL30.v2.0\nHLS Operational Land Imager Surface Reflectance and TOA Brightness Daily Global 30 m V1.5 has ID (shortname) of: HLSL30.v1.5\nHLS Sentinel-2 Multi-spectral Instrument Surface Reflectance Daily Global 30 m V1.5 has ID (shortname) of: HLSS30.v1.5\nHLS Sentinel-2 Multi-spectral Instrument Surface Reflectance Daily Global 30m v2.0 has ID (shortname) of: HLSS30.v2.0\n\n4-element Vector{Nothing}:\n nothing\n nothing\n nothing\n nothing","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Note that the id shortname is in the format: productshortname.vVVV (where VVV = product version)","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#Explore-the-attributes-contained-in-the-HLSS30-Collection.-1","page":"Cloud-Native HLS dat","title":"Explore the attributes contained in the HLSS30 Collection.","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Grab HLSS30 collection\ns30 = [h for h in hls_collections if h[\"id\"] == \"HLSS30.v1.5\"][1];\n\n# Check out the extent of this collection\nfor k in keys(s30[\"extent\"]) println(k, \" : \", s30[\"extent\"][k]) end","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"spatial : Dict{String, Any}(\"bbox\" => Any[Any[-180, -90, 180, 90]])\ntemporal : Dict{String, Any}(\"interval\" => Any[Any[\"2015-12-01T00:00:00.000Z\", nothing]])","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#So-here-we-can-see-that-the-extent-is-global,-and-can-also-see-the-temporal-range–where-None-means-on-going-or-to-present.-1","page":"Cloud-Native HLS dat","title":"So here we can see that the extent is global, and can also see the temporal range–where None means on-going or to present.","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"println(\"HLS S30 Start Date is: $(s30[\"extent\"][\"temporal\"][\"interval\"][1][1])\")","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"HLS S30 Start Date is: 2015-12-01T00:00:00.000Z","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#Next,-explore-the-attributes-of-the-HLSL30-collection.-1","page":"Cloud-Native HLS dat","title":"Next, explore the attributes of the HLSL30 collection.","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Above, notice that the L30 product has a different start date than the S30 product.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#.-STAC-Item:-Represents-data-and-metadata-assets-that-are-spatiotemporally-coincident-1","page":"Cloud-Native HLS dat","title":"4. STAC Item: Represents data and metadata assets that are spatiotemporally coincident","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#Query-the-HLSS30-collection-for-items-and-return-the-first-item-in-the-collection.-1","page":"Cloud-Native HLS dat","title":"Query the HLSS30 collection for items and return the first item in the collection.","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Go through all links in the collection and return the link containing the items endpoint\n\n# Set items endpoint to variable\ns30_items = [s[\"href\"] for s in s30[\"links\"] if s[\"rel\"] == \"items\"][1]","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"\"https://cmr.earthdata.nasa.gov/stac/LPCLOUD/collections/HLSS30.v1.5/items\"","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Call items endpoint\nr = HTTP.request(\"GET\", s30_items);\ns30_items_response = JSON.parse(String(r.body));\n\ns30_item = s30_items_response[\"features\"][1]","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Dict{String, Any} with 10 entries:\n \"links\" => Any[Dict{String, Any}(\"rel\"=>\"self\", \"href\"=>\"https://cm…\n \"stac_extensions\" => Any[\"https://stac-extensions.github.io/eo/v1.0.0/schema.…\n \"geometry\" => Dict{String, Any}(\"coordinates\"=>Any[Any[Any[40.9215, 19…\n \"id\" => \"HLS.S30.T37QGC.2016228T074942.v1.5\"\n \"stac_version\" => \"1.0.0\"\n \"properties\" => Dict{String, Any}(\"datetime\"=>\"2016-08-15T08:00:59.720Z\"…\n \"bbox\" => Any[40.9089, 19.7977, 41.1665, 20.7895]\n \"type\" => \"Feature\"\n \"assets\" => Dict{String, Any}(\"B8A\"=>Dict{String, Any}(\"href\"=>\"http…\n \"collection\" => \"HLSS30.v1.5\"","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#STAC-metadata-provides-valuable-information-on-the-item,-including-a-unique-ID,-when-it-was-acquired,-the-location-of-the-observation,-and-a-cloud-cover-assessment.-1","page":"Cloud-Native HLS dat","title":"STAC metadata provides valuable information on the item, including a unique ID, when it was acquired, the location of the observation, and a cloud cover assessment.","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Print metadata attributes from this observation\nprintln(\"The ID for this item is: $(s30_item[\"id\"])\")\nprintln(\"It was acquired on: $(s30_item[\"properties\"][\"datetime\"]))\")\nprintln(\"over: $(s30_item[\"bbox\"]) (Lower Left, Upper Right corner coordinates)\")\nprintln(\"It contains $(length(s30_item[\"assets\"])) assets\")\nprintln(\"and is $(s30_item[\"properties\"][\"eo:cloud_cover\"])% cloudy.\")","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"The ID for this item is: HLS.S30.T37QGC.2016228T074942.v1.5\nIt was acquired on: 2016-08-15T08:00:59.720Z)\nover: Any[40.908869, 19.797714, 41.166492, 20.789487] (Lower Left, Upper Right corner coordinates)\nIt contains 20 assets\nand is 4% cloudy.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#Print-out-the-ten-items-and-the-percent-cloud-cover–we-will-use-this-to-decidewhich-item-to-visualize-in-the-next-section.-1","page":"Cloud-Native HLS dat","title":"Print out the ten items and the percent cloud cover–we will use this to decidewhich item to visualize in the next section.","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#Using-the-information-printed-above,-set-the-item_index-below-to-whichever-observation-is-the-least-cloudy-above.-1","page":"Cloud-Native HLS dat","title":"Using the information printed above, set the item_index below to whichever observation is the least cloudy above.","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"item_index = 2;\n\n# Grab the next item in the list\ns30_item = s30_items_response[\"features\"][item_index];\n\nprintln(\"The ID for this item is: $(s30_item[\"id\"])\")\nprintln(\"It was acquired on: $(s30_item[\"properties\"][\"datetime\"])\")\nprintln(\"over: $(s30_item[\"bbox\"]) (Lower Left, Upper Right corner coordinates)\")\nprintln(\"It contains $(length(s30_item[\"assets\"])) assets\")\nprintln(\"and is $(s30_item[\"properties\"][\"eo:cloud_cover\"])% cloudy.\")","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"The ID for this item is: HLS.S30.T37QEE.2016228T074942.v1.5\nIt was acquired on: 2016-08-15T08:00:59.720Z\nover: Any[38.999805, 21.611674, 40.068079, 22.607038] (Lower Left, Upper Right corner coordinates)\nIt contains 20 assets\nand is 0% cloudy.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#Print-out-the-names-of-all-of-the-assets-included-in-this-item.-1","page":"Cloud-Native HLS dat","title":"Print out the names of all of the assets included in this item.","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"println(\"The following assets are available for download:\")\nkeys(s30_item[\"assets\"])","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"The following assets are available for download:\n\nKeySet for a Dict{String, Any} with 20 entries. Keys:\n \"B8A\"\n \"SZA\"\n \"B07\"\n \"B05\"\n \"B02\"\n \"B06\"\n \"B08\"\n \"B01\"\n \"B09\"\n \"Fmask\"\n \"VZA\"\n \"B10\"\n \"browse\"\n \"B03\"\n \"B04\"\n \"VAA\"\n \"metadata\"\n \"SAA\"\n \"B11\"\n \"B12\"","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#Notice-that-each-HLS-item-includes-a-browse-image.-Read-the-browse-file-into-memory-and-visualize-the-HLS-acquisition.-1","page":"Cloud-Native HLS dat","title":"Notice that each HLS item includes a browse image. Read the browse file into memory and visualize the HLS acquisition.","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"s30_item[\"assets\"][\"browse\"]","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Dict{String, Any} with 3 entries:\n \"href\" => \"https://data.lpdaac.earthdatacloud.nasa.gov/lp-prod-public/HLSS30…\n \"title\" => \"Download HLS.S30.T37QEE.2016228T074942.v1.5.jpg\"\n \"type\" => \"image/jpeg\"","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"img = gmtread(s30_item[\"assets\"][\"browse\"][\"href\"]);\nimshow(img)","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#Congrats!-You-have-pulled-your-first-HLS-asset-from-the-cloud-using-STAC!-1","page":"Cloud-Native HLS dat","title":"Congrats! You have pulled your first HLS asset from the cloud using STAC!","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#.-CMR-STAC-API:-Searching-for-Items-1","page":"Cloud-Native HLS dat","title":"3. CMR-STAC API: Searching for Items","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"In this section, instead of simply navigating through the structure of a STAC Catalog, use the search endpoint to query the API by region of interest and time period of interest.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#.1-Spatial-Querying-via-Bounding-Box-1","page":"Cloud-Native HLS dat","title":"3.1 Spatial Querying via Bounding Box","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"The search endpoint is one of the links found in the LPCLOUD STAC Catalog, which can be leveraged to retrieve STAC Items that match the submitted query parameters.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Grab the search endpoint for the LPCLOUD STAC Catalog and send a POST request to retrieve items.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Define the search endpoint\nlp_search = [l[\"href\"] for l in lp_links if l[\"rel\"] == \"search\"][1]\n\n# Set up a dictionary that will be used to POST requests to the search endpoint\nparams = Dict();","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"r = HTTP.request(\"POST\", lp_search);\nsearch_response = JSON.parse(String(r.body));\n\n\"$(length(search_response[\"features\"])) items found\"","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"\"10 items found\"","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"If we just call the search endpoint directly, it will default to returning the first 10 granules. Below, set a limit to return the first 100 matching items. Additional information on the spec for adding parameters to a search query can be found at:","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"https://github.com/radiantearth/stac-api-spec/tree/master/item-search#query-parameters-and-fields.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Add in a limit parameter to retrieve 100 items at a time.\nlim = 100;\nparams[\"limit\"] = lim;","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Above, we have added the limit as a parameter to the dictionary that we will post to the search endpoint to submit our request for data. As we keep moving forward in the tutorial, we will continue adding parameters to the params dictionary.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# send POST request to retrieve first 100 items in the STAC collection\nr = HTTP.post(lp_search, [\"Content-Type\" => \"application/json\"], JSON.json(params));\nsearch_response = JSON.parse(String(r.body));\n\n\"$(length(search_response[\"features\"])) items found\"","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"\"100 items found\"","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Load in the spatial region of interest for our use case using GMT. You will need to have downloaded the Field_Boundary.geojson from the repo, and it must be stored in the current working directory in order to continue. If you are still encountering issues, you can add the entire filepath to the file (ex: D = gmtread(\\\"C:/Username/HLS-Tutorial/Field_Boundary.geojson\\\") and try again.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Since the output is a vector of GMTdataset and all data is in first element\nD = gdalread(\"c:/v/Field_Boundary.geojson\")[1];","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Plot the geometry of the farm field boundaries.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"imshow(D, projection=:guess)","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"The farm field used in this example use case is located northwest of Chico, CA.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Now, add the bounding box of the region of interest to the CMR-STAC API Search query using the bbox parameter.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Compute the polygon bounding cordinates\nbb = gmtinfo(D, C=1)[1];\n\nbbox = \"$(bb[1]),$(bb[3]),$(bb[2]),$(bb[4])\";","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"params[\"bbox\"] = bbox;\nparams","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Dict{Any, Any} with 2 entries:\n \"bbox\" => \"-122.0622682571411,39.897234301806,-122.04918980598451,39.9130938…\n \"limit\" => 100","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Send POST request with bbox included\nr = HTTP.post(lp_search, [\"Content-Type\" => \"application/json\"], JSON.json(params));\nsearch_response = JSON.parse(String(r.body));\n\n\"$(length(search_response[\"features\"])) items found\"","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"\"100 items found\"","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#.2-Temporal-Querying-1","page":"Cloud-Native HLS dat","title":"3.2 Temporal Querying","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Finally, you can narrow your search to a specific time period of interest using the datetime parameter. Here we have set the time period of interest from September 2020 through March 2021. Additional information on setting temporal searches can be found in the NASA CMR Documentation.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Define start time period / end time period\ndate_time = \"2020-09-01T00:00:00Z/2021-03-31T23:59:59Z\";\n\nparams[\"datetime\"] = date_time\nparams","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Dict{Any, Any} with 3 entries:\n \"datetime\" => \"2020-09-01T00:00:00Z/2021-03-31T23:59:59Z\"\n \"bbox\" => \"-122.0622682571411,39.897234301806,-122.04918980598451,39.9130…\n \"limit\" => 100","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Send POST request with datetime included\nr = HTTP.post(lp_search, [\"Content-Type\" => \"application/json\"], JSON.json(params))\nsearch_response = JSON.parse(String(r.body));\n\n\"$(length(search_response[\"features\"])) items found\"","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"\"100 items found\"","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"params","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Dict{Any, Any} with 3 entries:\n \"datetime\" => \"2020-09-01T00:00:00Z/2021-03-31T23:59:59Z\"\n \"bbox\" => \"-122.0622682571411,39.897234301806,-122.04918980598451,39.9130…\n \"limit\" => 100","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#As-of-October-4,-2021,-the-HLS-Operational-Land-Imager-Surface-Reflectance-and-TOA-Brightness-(HLSL30)-product-has-been-provisionally-released,-and-this-tutorial-has-been-updated-to-show-how-to-combine-observations-from-both-products-into-a-time-series.-1","page":"Cloud-Native HLS dat","title":"As of October 4, 2021, the HLS Operational Land Imager Surface Reflectance and TOA Brightness (HLSL30) product has been provisionally released, and this tutorial has been updated to show how to combine observations from both products into a time series.","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Next, add the shortname for the HLSS30 v1.5 product (HLSS30.v1.5) to the params dictionary, and query the CMR-STAC LPCLOUD search endpoint for just HLSS30 items.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"s30_id = \"HLSS30.v1.5\"\nparams[\"collections\"] = [s30_id];","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Search for the HLSS30 items of interest:\n# Send POST request with collection included\nr = HTTP.post(lp_search, [\"Content-Type\" => \"application/json\"], JSON.json(params))\ns30_items = JSON.parse(String(r.body))[\"features\"];\nlength(s30_items)","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"61","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Append the HLSL30 V1.5 Product shortname (ID) to the list under the collections parameter.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"l30_id = \"HLSL30.v1.5\";\nappend!(params[\"collections\"], [l30_id])\nparams","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Dict{Any, Any} with 4 entries:\n \"datetime\" => \"2020-09-01T00:00:00Z/2021-03-31T23:59:59Z\"\n \"collections\" => [\"HLSS30.v1.5\", \"HLSL30.v1.5\"]\n \"bbox\" => \"-122.0622682571411,39.897234301806,-122.04918980598451,39.9…\n \"limit\" => 100","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#The-collections-parameter-is-a-list-and-can-include-multiple-product-collection-short-names.-1","page":"Cloud-Native HLS dat","title":"The collections parameter is a list and can include multiple product collection short names.","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Search for the HLSS30 and HLSL30 items of interest:\n# Send POST request with S30 and L30 collections included\nr = HTTP.post(lp_search, [\"Content-Type\" => \"application/json\"], JSON.json(params))\nhls_items = JSON.parse(String(r.body))[\"features\"];\nlength(hls_items)","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"68","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#.-Extracting-HLS-COGs-from-the-Cloud-1","page":"Cloud-Native HLS dat","title":"4. Extracting HLS COGs from the Cloud","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"In this section, configure gdal and rasterio to use vsicurl to access the cloud assets that we are interested in, and read them directly into memory without needing to download the files.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# GDAL configurations used to successfully access LP DAAC Cloud Assets via vsicurl \nset_config_option(\"GDAL_HTTP_COOKIEFILE\", joinpath(tempdir(), \"cookies.txt\"))\nset_config_option(\"GDAL_HTTP_COOKIEJAR\", joinpath(tempdir(), \"cookies.txt\"))\nset_config_option(\"GDAL_DISABLE_READDIR_ON_OPEN\",\"YES\")\nset_config_option(\"CPL_VSIL_CURL_ALLOWED_EXTENSIONS\",\"TIF\")\nset_config_option(\"CPL_VSIL_CURL_USE_HEAD\",\"FALSE\")\nset_config_option(\"GDAL_HTTP_UNSAFESSL\", \"YES\")","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#.1-Subset-by-Band-1","page":"Cloud-Native HLS dat","title":"4.1 Subset by Band","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"View the contents of the first item.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"h = hls_items[1]","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Dict{String, Any} with 10 entries:\n \"links\" => Any[Dict{String, Any}(\"rel\"=>\"self\", \"href\"=>\"https://cm…\n \"stac_extensions\" => Any[\"https://stac-extensions.github.io/eo/v1.0.0/schema.…\n \"geometry\" => Dict{String, Any}(\"coordinates\"=>Any[Any[Any[-121.964, 3…\n \"id\" => \"HLS.S30.T10TEK.2020273T190109.v1.5\"\n \"stac_version\" => \"1.0.0\"\n \"properties\" => Dict{String, Any}(\"datetime\"=>\"2020-09-29T19:13:24.996Z\"…\n \"bbox\" => Any[-123.0, 39.657, -121.702, 40.6509]\n \"type\" => \"Feature\"\n \"assets\" => Dict{String, Any}(\"B8A\"=>Dict{String, Any}(\"href\"=>\"http…\n \"collection\" => \"HLSS30.v1.5\"","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#Subset-by-band-by-filtering-to-only-include-the-NIR,-Red,-Blue,-and-Quality-(Fmask)-layers-in-the-list-of-links-to-access.-Below-you-can-find-the-different-band-numbers-for-each-of-the-two-products.-1","page":"Cloud-Native HLS dat","title":"Subset by band by filtering to only include the NIR, Red, Blue, and Quality (Fmask) layers in the list of links to access. Below you can find the different band numbers for each of the two products.","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#Sentinel-2:-1","page":"Cloud-Native HLS dat","title":"Sentinel 2:","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"evi_band_links = []\n\n# Define which HLS product is being accessed\nif (split(h[\"assets\"][\"browse\"][\"href\"], '/')[5] == \"HLSS30.015\")\n evi_bands = [\"B8A\", \"B04\", \"B02\", \"Fmask\"] # NIR RED BLUE Quality for S30\nelse\n evi_bands = [\"B05\", \"B04\", \"B02\", \"Fmask\"] # NIR RED BLUE Quality for L30\nend\n\n# Subset the assets in the item down to only the desired bands\nfor a in h[\"assets\"]\n for b in evi_bands\n if b == first(a)\n append!(evi_band_links, [h[\"assets\"][first(a)][\"href\"]])\n end\n end\nend\n\nfor e in evi_band_links println(e) end","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"https://lpdaac.earthdata.nasa.gov/lp-prod-protected/HLSS30.015/HLS.S30.T10TEK.2020273T190109.v1.5.B8A.tif\nhttps://lpdaac.earthdata.nasa.gov/lp-prod-protected/HLSS30.015/HLS.S30.T10TEK.2020273T190109.v1.5.B02.tif\nhttps://lpdaac.earthdata.nasa.gov/lp-prod-protected/HLSS30.015/HLS.S30.T10TEK.2020273T190109.v1.5.Fmask.tif\nhttps://lpdaac.earthdata.nasa.gov/lp-prod-protected/HLSS30.015/HLS.S30.T10TEK.2020273T190109.v1.5.B04.tif","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Remember from above that you can always quickly load in the browse image to get a quick view of the item.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Load jpg browse image into memory\nimage = gmtread(h[\"assets\"][\"browse\"][\"href\"]);\nimshow(image)","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Above, we see a partly cloudy observation over the northern Central Valley of California.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#.2-Load-a-Spatially-Subset-HLS-COG-into-Memory-1","page":"Cloud-Native HLS dat","title":"4.2 Load a Spatially Subset HLS COG into Memory","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Before loading the COGs into memory, run the cell below to check and make sure that you have a netrc file set up with your NASA Earthdata Login credentials, which will be needed to access the HLS files in the cells that follow. If you do not have a netrc file set up on your OS, the cell below should prompt you for your NASA Earthdata Login username and password.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"set_config_option(\"GDAL_HTTP_COOKIEFILE\", joinpath(tempdir(), \"cookies.txt\"));\nset_config_option(\"GDAL_HTTP_COOKIEJAR\", joinpath(tempdir(), \"cookies.txt\"));\nset_config_option(\"GDAL_DISABLE_READDIR_ON_OPEN\",\"YES\");\nset_config_option(\"CPL_VSIL_CURL_ALLOWED_EXTENSIONS\",\"TIF\");\nset_config_option(\"CPL_VSIL_CURL_USE_HEAD\",\"FALSE\");\nset_config_option(\"GDAL_HTTP_UNSAFESSL\", \"YES\");","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"for e in evi_band_links\n if split(e,'.')[end-1] == evi_bands[1] # NIR index\n println(\"/vsicurl/\"*e)\n tic()\n global nir = GMT.Gdal.read(\"/vsicurl/\"*e)\n toc()\n elseif split(e,'.')[end-1] == evi_bands[2] # Red index\n global red = GMT.Gdal.read(\"/vsicurl/\"*e)\n elseif split(e,'.')[end-1] == evi_bands[3] # Blue index\n global blue = GMT.Gdal.read(\"/vsicurl/\"*e)\n elseif split(e,'.')[end-1] == evi_bands[4] # Mask index\n global fmask = GMT.Gdal.read(\"/vsicurl/\"*e)\n end\nend\nprintln(\"The COGs have been loaded into memory!\")","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"/vsicurl/https://lpdaac.earthdata.nasa.gov/lp-prod-protected/HLSS30.015/HLS.S30.T10TEK.2020273T190109.v1.5.B8A.tif\nelapsed time: 11.319765 seconds\nThe COGs have been loaded into memory!","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Getting an error in the section above? Accessing these files in the cloud requires you to authenticate using your NASA Earthdata Login account. You will need to have a netrc file set up containing those credentials in your home directory in order to successfully run the code","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Below, take the farm field polygon and convert it from lat/lon (EPSG: 4326) into the native projection of HLS, UTM (aligned to the Military Grid Reference System). This must be done in order to use the Region of Interest (ROI) to subset the COG that is being pulled into memory–it must be in the native projection of the data being extracted.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"utm = getproj(nir); # Destination coordinate system\nDp = lonlat2xy(D, utm); # Project to UTM\nDp[1].geom = wkbPolygon; # Ensure it's a polygon for the mask calculation","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Compute the projected polygon bounding cordinates\nbb = gmtinfo(Dp, numeric=true)[1];","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Compute a mask with 1's inside the farm's polygon and 0's outside.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"mask = gdalrasterize(Dp, [\"-tr\",\"30\",\"30\", \"-te\", \"$(bb[1])\", \"$(bb[3])\", \"$(bb[2])\", \"$(bb[4])\", \"-burn\", \"1\", \"-init\", \"0\"]);","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Now, we can use the ROI to mask any pixels that fall outside of it and crop to the bounding box. This greatly reduces the amount of data that are needed to load into memory.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"nir_cropped = gdaltranslate(nir, [\"-projwin\", \"$(bb[1])\", \"$(bb[4])\", \"$(bb[2])\", \"$(bb[3])\"]);\nred_cropped = gdaltranslate(red, [\"-projwin\", \"$(bb[1])\", \"$(bb[4])\", \"$(bb[2])\", \"$(bb[3])\"]);\nblue_cropped = gdaltranslate(blue, [\"-projwin\", \"$(bb[1])\", \"$(bb[4])\", \"$(bb[2])\", \"$(bb[3])\"]);\nfmask_cropped = gdaltranslate(fmask, [\"-projwin\", \"$(bb[1])\", \"$(bb[4])\", \"$(bb[2])\", \"$(bb[3])\"]);\n\n@inbounds Threads.@threads for k = 1:length(fmask_cropped)\n (mask[k] == 0) && (fmask_cropped[k] = 1)\nend","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#.-Processing-HLS-Data-1","page":"Cloud-Native HLS dat","title":"5. Processing HLS Data","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"In this section, read the file metadata to retrieve and apply the scale factor, filter out nodata values, define a function to calculate EVI, and execute the EVI function on the data loaded into memory. After that, perform quality filtering to screen out any poor quality observations.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Compute the EVI index using the evi function from the RemoreS package and plot the results.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"EVI = evi(blue_cropped, red_cropped, nir_cropped);","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Apply a mask to the EVI layer using pixels with good quality as defined by the Fmask.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"The good quality is encoded in the fmask where its pixels are equal to zero.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Replace the flagged values by NaN\n@inbounds Threads.@threads for k = 1:length(EVI)\n (fmask_cropped[k] != 0) && (EVI[k] = NaN32)\nend","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Display the EVI\nimshow(EVI, colorbar=true)","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#.-Automation-1","page":"Cloud-Native HLS dat","title":"6. Automation","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"In this section, automate sections 4-5 for each HLS item that intersects our spatiotemporal subset of interest. Loop through each item and subset to the desired bands, load the spatial subset into memory, calculate EVI, quality filter, and save as a netCDF multi-layered cube.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Note: Be patient with the for loop below, it will take nearly an hour to complete.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Put it all together and loop through each of the files, visualize, calculate statistics on EVI, and export\nfor (j, h) in enumerate(hls_items)\n\n outName = split(h[\"assets\"][\"browse\"][\"href\"], '/')[end]\n outName = replace(outName, \".jpg\" => \"_EVI.grd\")\n\n tic()\n try\n evi_band_links = []\n # Define which HLS product is being accessed\n if (split(h[\"assets\"][\"browse\"][\"href\"], '/')[5] == \"HLSS30.015\")\n evi_bands = [\"B8A\", \"B04\", \"B02\", \"Fmask\"] # NIR RED BLUE Quality for S30\n else\n evi_bands = [\"B05\", \"B04\", \"B02\", \"Fmask\"] # NIR RED BLUE Quality for L30\n end\n\n for a in h[\"assets\"]\n for b in evi_bands\n (b == first(a)) && append!(evi_band_links, [h[\"assets\"][first(a)][\"href\"]])\n end\n end\n\n # Use vsicurl to load the data directly into memory (be patient, may take many seconds)\n for e in evi_band_links\n if split(e,'.')[end-1] == evi_bands[4] # Mask index\n local fmask = GMT.Gdal.read(\"/vsicurl/\"*e);\n global fmask_cropped = gdaltranslate(fmask, [\"-projwin\", \"$(bb[1])\", \"$(bb[4])\", \"$(bb[2])\", \"$(bb[3])\"]);\n break\n end\n end\n\n @inbounds for k = 1:length(fmask_cropped)\n (mask[k] == 0) && (fmask_cropped[k] = 1)\n end\n\n all(fmask_cropped.image .!= 0) && continue\n\n for e in evi_band_links\n if split(e,'.')[end-1] == evi_bands[1] # NIR index\n global nir = GMT.Gdal.read(\"/vsicurl/\"*e);\n elseif split(e,'.')[end-1] == evi_bands[2] # Red index\n global red = GMT.Gdal.read(\"/vsicurl/\"*e);\n elseif split(e,'.')[end-1] == evi_bands[3] # Blue index\n global blue = GMT.Gdal.read(\"/vsicurl/\"*e);\n end\n end\n\n nir_cropped = gdaltranslate(nir, [\"-projwin\", \"$(bb[1])\", \"$(bb[4])\", \"$(bb[2])\", \"$(bb[3])\"]);\n red_cropped = gdaltranslate(red, [\"-projwin\", \"$(bb[1])\", \"$(bb[4])\", \"$(bb[2])\", \"$(bb[3])\"]);\n blue_cropped = gdaltranslate(blue, [\"-projwin\", \"$(bb[1])\", \"$(bb[4])\", \"$(bb[2])\", \"$(bb[3])\"]);\n\n EVI = evi(blue_cropped, red_cropped, nir_cropped);\n\n # Replace the flagged values by NaN\n @inbounds for k = 1:length(EVI)\n (fmask_cropped[k] != 0) && (EVI[k] = NaN32)\n end\n\n #gmtwrite(outName, EVI)\n gdaltranslate(EVI, save=outName)\n catch err\n println(err)\n end\n toc()\n\n println(\"Processed file $j of $(length(hls_items))\")\nend","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"eviFiles = [o for o in readdir() if endswith(o, \"EVI.grd\")];","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"df = dateformat\"yyyymmddTHHMMSS\";\ntime = Vector{TimeType}(undef, length(eviFiles));\nfor (i, e) in enumerate(eviFiles)\n t = split(split(e, \".v1.5\")[1], \".\")[end];\n # Julia doesn't parse a date in yyyyjjjT... so must resort to brewed functions\n mon, day = monthday(doy2date(t[5:7], t[1:4]));\n time[i] = DateTime(@sprintf(\"%s%.02d%.02d%s\", t[1:4], mon, day, t[8:end]), df);\nend\n\n# Get the permutation vector p that puts time[p] in sorted order\np = sortperm(time);\neviFiles = eviFiles[p];\t\t# Sort the file names in ascending time order\ntime = time[p];\t\t\t\t# and the time too.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Save all EVI estimations in a netCDF 3d (a cube) file","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"stackgrids(eviFiles, time, z_unit=\"unix\", save=\"evi_cube.nc\")","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Interpolate along all layers at a point with coordinates x = 580740; y = 4418042","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"D = grdinterpolate(\"evi_cube.nc\", pt=(580740,4418042));","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Now, plot the time series showing the distribution of EVI values for our farm field.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"imshow(D, par=(TIME_SYSTEM=\"UNIX\",), coltypes=:t)","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"","category":"page"},{"location":"gallery/Aqua_orbits/remotes_sat_tracks/#Plot-AQUA-satellite-tracks-1","page":"Aqua orbits","title":"Plot AQUA satellite tracks","text":"","category":"section"},{"location":"gallery/Aqua_orbits/remotes_sat_tracks/#","page":"Aqua orbits","title":"Aqua orbits","text":"Compute 1 day of AQUA satellite orbits starting at current local time. Note, this will be accurate for the month of September 2021. For other dates it needs an updated TLE. Note also that repeating the commands below will produce different results since the current local time is used as the starting point.","category":"page"},{"location":"gallery/Aqua_orbits/remotes_sat_tracks/#","page":"Aqua orbits","title":"Aqua orbits","text":"Orbits calculation rely on the SatelliteToolbox package(s). Orbits are calculated with the help of the so called Two Line Element files that unfortunatelly have accuracy validity quite short (around one month). They can be obtainded from the Space Track site.","category":"page"},{"location":"gallery/Aqua_orbits/remotes_sat_tracks/#","page":"Aqua orbits","title":"Aqua orbits","text":"using RemoteS, GMT, SatelliteToolboxTle, SatelliteToolboxPropagators, SatelliteToolboxTransformations\n\n# The AQUA orbits TLE contents for the month of September 2021 \ntle1 = \"1 27424U 02022A 21245.83760660 .00000135 00000-0 39999-4 0 9997\";\ntle2 = \"2 27424 98.2123 186.0654 0002229 67.6025 313.3829 14.57107527 28342\";\norb = sat_tracks(tle=[tle1; tle2], duration=\"1D\");\n\n# The orbit track can be visualized with\nimshow(orb, proj=:Robinson, region=:global, coast=true)","category":"page"},{"location":"gallery/Aqua_orbits/remotes_sat_tracks/#","page":"Aqua orbits","title":"Aqua orbits","text":"","category":"page"},{"location":"gallery/Aqua_orbits/remotes_sat_tracks/#","page":"Aqua orbits","title":"Aqua orbits","text":"There is no point in plotting orbits for a lengthier duration because they would clutter the figure but we can compute them and display over a specific region on Earth.","category":"page"},{"location":"gallery/Aqua_orbits/remotes_sat_tracks/#","page":"Aqua orbits","title":"Aqua orbits","text":"# Compute orbits during 2 days at 15 seconds intervals\norb = sat_tracks(tle=[tle1; tle2], duration=\"2D\", step=15);\n\n# and plot them on my \"vicinity\"\nD = clip_orbits(orb, [-20, 10, 30, 50]);\n\nimshow(D, proj=:guess, coast=true, dpi=200)","category":"page"},{"location":"gallery/Aqua_orbits/remotes_sat_tracks/#","page":"Aqua orbits","title":"Aqua orbits","text":"","category":"page"},{"location":"gallery/Aqua_orbits/remotes_sat_tracks/#","page":"Aqua orbits","title":"Aqua orbits","text":"And imagine we would like to know the names of the AQUA scene files that cover a certain location? We can do it with the findscenes function to which we must provide the location of interest, the satellite (currently only AQUA or TERRA), the duration of the search and if we want Chlorophyl-a concentration or Sea Surface Temperature (see function help for details).","category":"page"},{"location":"gallery/Aqua_orbits/remotes_sat_tracks/#","page":"Aqua orbits","title":"Aqua orbits","text":"# Get the scene names of data with Chlorophyl-a concentration covering\n# the point (-8,36) and for two days before \"2021-09-07T17:00:00\"\ntle1 = \"1 27424U 02022A 21245.83760660 .00000135 00000-0 39999-4 0 9997\";\ntle2 = \"2 27424 98.2123 186.0654 0002229 67.6025 313.3829 14.57107527 28342\";\nfindscenes(-8,36, start=\"2021-09-07T17:00:00\", sat=:aqua, day=true, duration=-2, oc=1, tle=[tle1, tle2])","category":"page"},{"location":"gallery/Aqua_orbits/remotes_sat_tracks/#","page":"Aqua orbits","title":"Aqua orbits","text":"\t2-element Vector{String}:\n\tA2021251125500.L2_LAC_OC.nc\n\tA2021252134000.L2_LAC_OC.nc","category":"page"},{"location":"gallery/Aqua_orbits/remotes_sat_tracks/#","page":"Aqua orbits","title":"Aqua orbits","text":"Now you can download them from https://oceandata.sci.gsfc.nasa.gov/ob/getfile/A2021251125500.L2_LAC_OC.nc (but you will need to register first) and play with the grid_at_sensor function for interpolation and visualization.","category":"page"},{"location":"gallery/Aqua_orbits/remotes_sat_tracks/#","page":"Aqua orbits","title":"Aqua orbits","text":"Another cool thing we can do is to plot the area extent of the AQUA or TERRA scenes. We do it by first computing and orbit with a start and stop times and with increments of 1 minute (attention, this is an important factor). With that orbit we use the sat_tracks function to compute the polygons delimiting those areas.","category":"page"},{"location":"gallery/Aqua_orbits/remotes_sat_tracks/#","page":"Aqua orbits","title":"Aqua orbits","text":"using Dates\n\norb = sat_tracks(tle=[tle1; tle2], start=DateTime(\"2021-09-02T13:30:00\"),\n\tstop=DateTime(\"2021-09-02T13:40:00\"), step=\"1m\");\n\nDsc = sat_scenes(orb, \"AQUA\");","category":"page"},{"location":"gallery/Aqua_orbits/remotes_sat_tracks/#","page":"Aqua orbits","title":"Aqua orbits","text":"","category":"page"},{"location":"gallery/Aqua_orbits/remotes_sat_tracks/#","page":"Aqua orbits","title":"Aqua orbits","text":"The scene names are stored in the header field of the Dsc GMTdatset","category":"page"},{"location":"gallery/Aqua_orbits/remotes_sat_tracks/#","page":"Aqua orbits","title":"Aqua orbits","text":"julia> Dsc[1].header\n\n`AQUA_MODIS.20210902T133001.L2.SST.NRT.nc`\n\njulia> Dsc[2].header\n\n`AQUA_MODIS.20210902T133501.L2.SST.NRT.nc`","category":"page"},{"location":"gallery/Aqua_orbits/remotes_sat_tracks/#","page":"Aqua orbits","title":"Aqua orbits","text":"","category":"page"},{"location":"gallery/Aqua_orbits/remotes_sat_tracks/#","page":"Aqua orbits","title":"Aqua orbits","text":"Download a Neptune Notebook here","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#Exploring-a-*cube*-of-Landsat-8-data-1","page":"Landsat 8 images","title":"Exploring a cube of Landsat 8 data","text":"","category":"section"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"Here we will show examples of the type of things we can do with Landsat 8 data stored in a cube for better organisation and easyness of access.","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"The data was downloaded from EarthExplorer and comprises the scene with Product ID LC08_L1TP_204033_20210525_20210529_02_T1.","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"The cube was made with this instructions (but they would only work if you had the scene files in your computer).","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"path = C:/v/LC08_L1TP_204033_20210525_20210529_02_T1/LC08_L1TP_204033_20210525_20210529_02_T1_B;","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"cube = cutcube(bands=[2,3,4,5,6,7,10], template=path, region=(485490,531060,4283280,4330290), save=\"LC08_L1TP_20210525_02_cube.tiff\")","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"This creates a 3D GeoTIFF file with the companion MTL file saved in it as Metadata. We can see the band info by running the reportbands function. That information is quite handy because we can, for example, just refer to the red band and it will figure out which layer of the cube contains the Red band.","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"using RemoteS, GMT\nreportbands(\"c:/v/LC08_L1TP_20210525_02_cube.tiff\")\n7-element Vector{String}:\n \"Band 2 - Blue [0.45-0.51]\"\n \"Band 3 - Green [0.53-0.59]\"\n \"Band 4 - Red [0.64-0.67]\"\n \"Band 5 - NIR [0.85-0.88]\"\n \"Band 6 - SWIR 1 [1.57-1.65]\"\n \"Band 7 - SWIR 2 [2.11-2.29]\"\n \"Band 10 - Thermal IR 1 [10.6-11.19]\"","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"So to start our exploration the best is to generate a true color image. The truecolor function knows how to do that automatically including the histogram contrast stretch.","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"Irgb = truecolor(\"c:/v/LC08_L1TP_20210525_02_cube.tiff\");\nimshow(Irgb)","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"And we can compute the brightness temperature in Celsius at the Top of Atmosphere (TOA) from Band 10.","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"T = dn2temperature(\"c:/v/LC08_L1TP_20210525_02_cube.tiff\", band=10);\nimshow(T, dpi=150, colorbar=true)","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"Or the Radiance TOA for the Blue band.","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"Btoa = dn2radiance(\"c:/v/LC08_L1TP_20210525_02_cube.tiff\", bandname=\"blue\");\nimshow(Btoa, dpi=150, color=:gray)","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"Hmmm, very dark. Let's look at its histogram.","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"histogram(Btoa, auto=true, show=true)","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"Yes, the data is very concentraded in the low numbers. We will need to apply a contrast stretch. To do that operation we will use the rescale function with the stretch=true option that uses the limits displayed in the histogram figure above ans stretches the inner interval into [0 255] (by effect of the type=UInt8 option).","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"Btoa_img = rescale(Btoa, stretch=true, type=UInt8);\nimshow(Btoa_img)","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"Now we are going to do the same for all Red, Green and Blue bands and compose the in a truecolor image. Repeating, we are going to compute the radiance at the top of atmosphere, retain only the data inside the parts of the histogram where it is more concentrated and create a true color image. To compute the radiance TOA we can do it all at once with the dn2radiance applied to the cube and, like before, create the RGB image with truecolor","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"cube_toa_rad = dn2radiance(\"c:/v/LC08_L1TP_20210525_02_cube.tiff\");\nIrgb_toa = truecolor(cube_toa_rad);\nimshow(Irgb_toa)","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"Hm, yes, very nice but it looks very much like the one obtained directly with the digital numbers. Indeed, it does but let us zoom in.","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"grdimage(Irgb, region=(502380,514200,4311630,4321420), figsize=8, frame=:bare)\ngrdimage!(Irgb_toa, figsize=8, projection=:linear, xshift=8, frame=:bare, show=true)","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"We can now clearly see that the image on the right, the one made the radiance TOA, has an higher contrast than the one made with data without any corrections.","category":"page"},{"location":"gallery/Aqua_sst/remotes_L2_SST/#Interpolate-a-MODIS-L2-SST-file-1","page":"Aqua SST","title":"Interpolate a MODIS L2 SST file","text":"","category":"section"},{"location":"gallery/Aqua_sst/remotes_L2_SST/#","page":"Aqua SST","title":"Aqua SST","text":"The Level 2 MODIS files are the ones that contain the information at its maximum spatial resolution. However, in those products the data is not equally spaced so we must interpolate it first before use. The grid_at_sensor function provides a handy interface to do it easily.","category":"page"},{"location":"gallery/Aqua_sst/remotes_L2_SST/#","page":"Aqua SST","title":"Aqua SST","text":"Imagine that you have downloaded the file AQUA_MODIS.20210805T131001.L2.SST.NRT.nc from the OceanColor site (eventually following the example in Plot AQUA satellite tracks)","category":"page"},{"location":"gallery/Aqua_sst/remotes_L2_SST/#","page":"Aqua SST","title":"Aqua SST","text":"using RemoteS, GMT\n\n# Interpolate from sensor to geographic coordinates at approx 1 km grid steps\nG = grid_at_sensor(\"C:/v/AQUA_MODIS.20210805T131001.L2.SST.NRT.nc\", \"sst\", inc=0.01);\n\n# Display it\nimshow(G, proj=:guess, coast=true, dpi=200)","category":"page"},{"location":"gallery/Aqua_sst/remotes_L2_SST/#","page":"Aqua SST","title":"Aqua SST","text":"","category":"page"},{"location":"gallery/Aqua_sst/remotes_L2_SST/#","page":"Aqua SST","title":"Aqua SST","text":"Note that since we used a grid step 0f 0.01 for the interpolation and this value is very close to the MODIS maximum spatial resolution, the left and right regions have beam spacings 2 to 5 times this and show many little holes. Do not confuse these little holes with the larger ones that are caused by cloud coverage. So we will recalculate the grid at increments of ~2 km and over the region that has the higher data density.","category":"page"},{"location":"gallery/Aqua_sst/remotes_L2_SST/#","page":"Aqua SST","title":"Aqua SST","text":"# Recompue at a inc=0.02 and over a sub-region\nG = grid_at_sensor(\"C:/v/AQUA_MODIS.20210805T131001.L2.SST.NRT.nc\", \"sst\", region=(-13,10,33.8,44.5), inc=0.02);","category":"page"},{"location":"gallery/Aqua_sst/remotes_L2_SST/#","page":"Aqua SST","title":"Aqua SST","text":"# Make a nicer image with illumination.\nimshow(G, proj=:guess, coast=true, shade=true, title=\"Sea Surace Temperature\", colorbar=true)","category":"page"},{"location":"gallery/Aqua_sst/remotes_L2_SST/#","page":"Aqua SST","title":"Aqua SST","text":"","category":"page"},{"location":"gallery/Aqua_sst/remotes_L2_SST/#","page":"Aqua SST","title":"Aqua SST","text":"","category":"page"},{"location":"gallery/Aqua_sst/remotes_L2_SST/#","page":"Aqua SST","title":"Aqua SST","text":"Download a Neptune Notebook here","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#Spectral-indices-with-Landsat-8-imagery-1","page":"Landsat 8 NDVI","title":"Spectral indices with Landsat 8 imagery","text":"","category":"section"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"We will use here the same data cube that was introduced in the images example.","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"A very popular spectral indice is the NDVI which is deffined as the a normalized difference between the Near Infra Red (NIR) and the Red bands. Namely NDVI = (NIR - Red) / (NIR + Red). An heuristic says that NDVI values ~greater than 0.4 indicate green vegetation as higher the indice (maximum = 1) larger is the green vegetation content.","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"Since the data cube holds in it the information about each band, computing the NDVI is a trivial opration because we known where each band is in the data cube. Let's see it.","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"using RemoteS, GMT\nN = ndvi(\"LC08_L1TP_20210525_02_cube.tiff\");\nimshow(N, colorbar=true)","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"The spectral indices functions all have a threshold value that will NaNify all values threshold. Below we wipe out all values < 0.4 to show only the Green stuff","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"N = ndvi(\"LC08_L1TP_20210525_02_cube.tiff\", threshold=0.4);\nimshow(N, dpi=150, colorbar=1)","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"Cool but I would like to check that the result is correct.","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"The spectral indices functions have another option to obtain just a mask where the values are threshold, so we can use it to mask out the true color image and see what we get. ","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"# Compute a mask based on the condition that threshold >= 0.4\nmask = ndvi(\"LC08_L1TP_20210525_02_cube.tiff\", threshold=0.4, mask=true);","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"To mask out the true color image the best way is to use the mask as the alpha band. To make it easier we will recalculate the true color image here.","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"# Recalculate the true color image\nIrgb = truecolor(\"LC08_L1TP_20210525_02_cube.tiff\");\n\n# Apply the mask\nimage_alpha!(Irgb, alpha_band=mask, burn=1);\n\n# And save it to disk\ngmtwrite(\"rgb_masked.tiff\", Irgb)\n\nimshow(Irgb)","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"While we can see that only the green color is present in the above image, it's not easy to see the details. So let's zoom in but do also another thing. Let us see also what parts of the RGB image were not selected. To see that we will calculate the inverse mask, that is, the mask that retains all values < threshold. To achieve that we use the mask option with a negative number.","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"# Compute a mask based on the condition that threshold >= 0.4\nmask_inv = ndvi(\"LC08_L1TP_20210525_02_cube.tiff\", threshold=0.4, mask=-1)\n;\n# Recompute the true color image that was modified by the ``image_alpha!`` step above\nIrgb = truecolor(\"LC08_L1TP_20210525_02_cube.tiff\");\n\nimage_alpha!(Irgb, alpha_band=mask_inv, burn=1);\ngmtwrite(\"rgb_inv_masked.tiff\", Irgb)","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"Plot the green vegetation that passed the NDVI threshold test and the other part, side by side.","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"grdimage(\"rgb_masked.tiff\", region=(502380,514200,4311630,4321420), figsize=8, frame=:bare)\ngrdimage!(\"rgb_inv_masked.tiff\", figsize=8, projection=:linear, xshift=8, frame=:bare, show=true)","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"As we can see only the greenest part, the one that is probably more irrigated considering that all the river and cannals margins were retained, was extracted with the condition NDVI > 0.4. Off course, using different threshold values would lead to slightly different results.","category":"page"},{"location":"#RemoteS-1","page":"Index","title":"RemoteS","text":"","category":"section"},{"location":"#Index-1","page":"Index","title":"Index","text":"","category":"section"},{"location":"#","page":"Index","title":"Index","text":"Modules = [RemoteS]\nOrder = [:function, :type, :module]","category":"page"},{"location":"#Functions-1","page":"Index","title":"Functions","text":"","category":"section"},{"location":"#","page":"Index","title":"Index","text":"Modules = [RemoteS]\nOrder = [:function, :type, :module]","category":"page"},{"location":"#RemoteS.classify-Tuple{GMT.GItype, Any}","page":"Index","title":"RemoteS.classify","text":"I = classify(cube::GItype, model; class_names::Union{String, Vector{String}}=\"\") -> GMTimage\n\ncube: The cube wtih band data to classify.\nmodel: The trained model obtained from the train_raster function.\nclass_names: A vector of strings with the class names to be used in the categorical colorbar or a comma separated single with those class names. The number of class names must match the number used when training the model with train_raster.\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.classify-Tuple{GMT.GItype, Union{String, Vector{<:GMT.GMTdataset}}}","page":"Index","title":"RemoteS.classify","text":"I = classify(cube::GItype, train::Union{Vector{<:GMTdataset}, String}) -> GMTimage\n\ncube: The cube wtih band data to classify.\ntrain: A vector of GMTdatasets or a file name of one containing the polygons used to train the model. NOTE: The individual datasets MUST have associated an attribute called \"class\" containing the class name as a string. This can be achieved for text data in the form of a GMT multi-segment file (one where segments are separated by the '>' symbol) if the multi-segment separator line contains the text Attrib(class=name)\n\nReturns an image with the classification results where each class name was assigned a different integer number. That colorized image can plotted with viz(I colorbar=true).\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.clg-Tuple{Any, Any}","page":"Index","title":"RemoteS.clg","text":"CLG = clg(green, redEdge3; kw...)\n\nor\n\nCLG = clg(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)\n\nGreen cholorphyl index. Wu et al 2012.\n\nCLG = (redEdge3)/(green)-1 \n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.clip_orbits-Tuple{Any, Vector{<:Real}}","page":"Index","title":"RemoteS.clip_orbits","text":"clip_orbits(track, BoundingBox::Vector{<:Real})\n\nClips the orbits that are contained inside a rectangular geographical region\n\ntrack: A GMTdataset or a Mx2 matrix with the orbits [lon, lat] position. This is normally calculated with the sat_tracks function.\nBoundingBox: A vector the region limits made up with [lonmin, lonmax, latmin, latmax]\n\nReturns a GMTdataset vector with the chunks of tracks that cross inside the BoundingBox region.\n\n#Example Suppose orb holds orbits computed with sat_tracks() during 2 days, clip them inside the 20W-10E, 30N-45N window\n\nD = clip_orbits(orb, [-20, 10, 30, 50]);\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.clre-Tuple{Any, Any}","page":"Index","title":"RemoteS.clre","text":"CLRE = clre(redEdge1, redEdge3; kw...)\n\nor\n\nCLRE = clre(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)\n\nRedEdge cholorphyl index. Clevers and Gitelson 2013.\n\nCLRE = (redEdge3)/(redEdge1)-1\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.cutcube-Tuple{}","page":"Index","title":"RemoteS.cutcube","text":"cutcube(names=String[], bands=Int[], template=\"\", region=nothing, extension=\".TIF\", description=String[], mtl=\"\", sentinel2=0, save=\"\")\n\nCut a 3D cube out of a Landsat/Sentinel scene within a subregion region and a selection of bands.\n\nnames: (optional) A vector with the individual bands full file name\nbands: When names is not provided give a vector of integers corresponding to the choosen bands. This works well for Landsat and most of Sentinel bands. However, in later case, there are also bands that contain characters, for example band 8A. In this case bands should be a vector of strings including the extension. e.g. [\"02.jp2\", \"8A.jp2\"]\ntemplate: Goes together with the bands option. They are both composed a template * band[n] to recreate the full file name of each band.\nregion Is the region to extract and must contain the extracting region limits as [W, E, S, N] or a GMT style -R string (without the leading \"-R\").\nextension: In case the bands is numeric but file extensions are not \"*.TIF\" (case insensitive), use the extension passed by this option.\ndescription: A vector of strings (as many as bands) with a description for each band. If not provided and the file is recognized as a Landasat 8, band description is added automatically, otherwise we build one with the bands file names. This info will saved if data is written to a file.\nmtl: If reading from Landsat and the MTL file is not automatically found (you get an error) use this option to pass the full name of the MTL file.\nsentinel2: ESA is just unconsistent and names change with time and band numbers can have character (e.g. 8A) hence we need help to recognize Sentinel files so the known description can be assigned. Use sentinel=10, or =20 or =60 to indicate Sentinel files at those resolutions.\nsave: The file name where to save the output. If not provided, a GMTimage is returned.\n\nReturn: nothing if the result is written in file or a GMTimage otherwise.\n\nExamples\n\n# Cut a Landsat 8 scene for a small region (in UTM) and return a GMTimage with 3 bands in UInt16.\ntemp = \"C:\\SIG_AnaliseDadosSatelite\\SIG_ADS\\DadosEx2\\LC82040332015145LGN00\\LC82040332015145LGN00_B\";\ncube = cutcube(bands=[2,3,4], template=temp, region=[479670,492720,4282230,4294500])\n\n# The same example as above but save the data in a GeoTIFF disk file and use a string for `region`\ncutcube(bands=[2,3,4], template=temp, region=\"479670/492720/4282230/4294500\", save=\"landsat_cube.tif\")\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.dn2radiance-Tuple{String}","page":"Index","title":"RemoteS.dn2radiance","text":"R = dn2radiance(fname::String, [band::Int, bandname::String, mtl::String, save::String])\n\nComputes the radiance at TopOfAtmosphere of a Landsat 8 file\n\nfname: The name of either a LANDSAT_PRODUCT_ID geotiff band, or the name of a cube file created with the cutcube function. In the first case, if the companion MTLtxt file is not in the same directory as fname one can still pass it via the mtl=path-to-MTL-file option. In the second case it is mandatory to use one of the following two options.\nband: cubes created with cutcube assign descriptions starting with \"Band 1 ...\" an so on the other bands. So when band is used we search for the band named \"Band N\", where N = band.\nbandname: When we know the common designation of a band, for example \"Green\", or any part of a band description, for example \"NIR\", we can use that info to create a bandname string that will be matched against the cube's bands descriptions. We can use the reportbands function to see the bands description.\nsave: The file name where to save the output. If not provided, a GMTgrid is returned.\n\nReturns a Float32 GMTgrid\n\nExample:\n\nCompute the radiance TOA of Band 2 file.\n\nR = dn2radiance(\"LC08_L1TP_204033_20210525_20210529_02_T1_B2.TIF\")\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.dn2reflectance-Tuple{String}","page":"Index","title":"RemoteS.dn2reflectance","text":"R = dn2reflectance(fname::String, [band::Int, bandname::String, mtl::String, save::String])\n\nComputes the TopOfAtmosphere planetary reflectance of a Landsat8 file\n\nfname: The name of either a LANDSAT_PRODUCT_ID geotiff band, or the name of a cube file created with the cutcube function. In the first case, if the companion MTLtxt file is not in the same directory as fname one can still pass it via the mtl=path-to-MTL-file option. In the second case it is mandatory to use one of the following two options.\nband: cubes created with cutcube assign descriptions starting with \"Band 1 ...\" an so on the other bands. So when band is used we search for the band named \"Band N\", where N = band.\nbandname: When we know the common designation of a band, for example \"Green\", or any part of a band description, for example \"NIR\", we can use that info to create a bandname string that will be matched against the cube's bands descriptions. We can use the reportbands function to see the bands description.\nsave: The file name where to save the output. If not provided, a GMTgrid is returned.\n\nReturns a Float32 GMTgrid\n\nExample:\n\nCompute the reflectance TOA of Red Band stored in a cube\n\nR = dn2reflectance(cube, bandname=\"red\")\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.dn2temperature-Tuple{String}","page":"Index","title":"RemoteS.dn2temperature","text":"R = dn2temperature(fname::String; band::Int=0, mtl::String=\"\", save::String)\n\nComputes the brigthness temperature of Landasat8 termal band (10 or 11)\n\nfname: The name of either a LANDSAT_PRODUCT_ID geotiff band, or the name of a cube file created with the cutcube function. In the first case, if the companion MTLtxt file is not in the same directory as fname one can still pass it via the mtl=path-to-MTL-file option. In the second case it is mandatory to use one of the following two options.\nband: cubes created with cutcube assign descriptions starting with \"Band 1 ...\" an so on the other bands. So when band is used we search for the band named \"Band N\", where N = band.\nbandname: When we know the common designation of a band, for example \"Green\", or any part of a band description, for example \"NIR\", we can use that info to create a bandname string that will be matched against the cube's bands descriptions. We can use the reportbands function to see the bands description.\nsave: The file name where to save the output. If not provided, a GMTgrid is returned.\n\nReturns a Float32 GMTgrid\n\nExample:\n\nCompute the brightness temperature of Band 10 stored in a cube\n\nT = dn2temperature(cube, band=10)\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.evi-Tuple{Any, Any, Any}","page":"Index","title":"RemoteS.evi","text":"EVI = evi(blue, red, nir; kw...)\n\nor\n\nEVI = evi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)\n\nEnhanced vegetation index. Huete et al 1990\n\nEVI = G * ((nir - red) / (nir + C1 * red - C2 * blue + Levi)); C1, C2, G, Levi = 6.0, 7.5, 2.5, 1.\n\nThe first form accepts inputs as matrices, or file names of the data bands.\nThe second form is more versatile but also more complex to describe.\ncube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.\nbands: cubes created with cutcube assign descriptions starting with \"Band1 ...\" an so on the other bands. So when bands is used we search for bands named \"Band'band[k]'\", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.\nlayers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.\nbandnames: When we know the common designation of a band, for example \"Green\", or any part of a band description, for example \"NIR\", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.\nkwargs:\nthreshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN\nclasses: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.\nmask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise\nsave: Use save=\"file_name.ext\" to save the result in a disk file. File format is picked from file extension.\n\nIf none of bands, layers or bandnames is provided, we use the default band names shown in the first form.\n\nSee also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.\n\nReturns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.evi2-Tuple{Any, Any}","page":"Index","title":"RemoteS.evi2","text":"EVI2 = evi2(red, nir; kw...)\n\nor\n\nEVI2 = evi2(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)\n\nTwo-band Enhanced vegetation index. Jiang et al 2008\n\nEVI2 = G * ((nir - red) / (nir + 2.4 * red ))\n\nThe first form accepts inputs as matrices, or file names of the data bands.\nThe second form is more versatile but also more complex to describe.\ncube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.\nbands: cubes created with cutcube assign descriptions starting with \"Band1 ...\" an so on the other bands. So when bands is used we search for bands named \"Band'band[k]'\", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.\nlayers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.\nbandnames: When we know the common designation of a band, for example \"Green\", or any part of a band description, for example \"NIR\", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.\nkwargs:\nthreshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN\nclasses: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.\nmask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise\nsave: Use save=\"file_name.ext\" to save the result in a disk file. File format is picked from file extension.\n\nIf none of bands, layers or bandnames is provided, we use the default band names shown in the first form.\n\nSee also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.\n\nReturns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.findscenes-Tuple{Real, Real}","page":"Index","title":"RemoteS.findscenes","text":"findscenes(lon::Real, lat::Real; kwargs...)\n\nFind the names of the scenes that cover the location point lon, lat in the period determined by the dates and satellite set via kwargs.\n\nday: Search only on the day time part of the orbits.\nnight: Search only on the night time part of the orbits.\noc: For the AQUA or TERRA satellites pick only the chlorophyl content scenes.\nsst: For the AQUA or TERRA satellites pick only the Sae Surface Temperature content scenes.\nsat, SAT or satellite: Name of the satellite to use; choose from (string or symbols) :TERRA, :AQUA\nstart: A DateTime object or a string convertable to a DateTime with DateTime(start) specifying the start of the looking period. If omited, current time in UTC will be used.\nduration: Length of time for which the scenes are searched. The duration is expected in days and can be a negative number, meaning we'll look that span days from start.\nstop: As alternative to duration provide the end date for the serch. Same conditions as start\ntle or TLE: a file name with the TLE data for a specific satellite and period. It can also be a two elements string vector with the first and second lines of the TLE file.\n\nReturns\n\nA string vector with the scene names\n\nExample:\n\nFind the AQUA scenes with chlorophyl-a (oceancolor) that cover the point (-8, 36) in the two days before \"2021-09-07T17:00:00\" Note, this will be accurate for the month of September 2021. For other dates it needs an updated TLE.\n\ntle1 = \"1 27424U 02022A 21245.83760660 .00000135 00000-0 39999-4 0 9997\";\ntle2 = \"2 27424 98.2123 186.0654 0002229 67.6025 313.3829 14.57107527 28342\";\nfindscenes(-8,36, start=\"2021-09-07T17:00:00\", sat=:aqua, day=true, duration=-2, oc=1, tle=[tle1, tle2])\n\n2-element Vector{String}:\n\"A2021251125500.L2_LAC_OC.nc\"\n\"A2021252134000.L2_LAC_OC.nc\"\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.gli-Tuple{GMT.GMTimage{UInt8, 3}}","page":"Index","title":"RemoteS.gli","text":"GLI = gli(red, green, blue; kw...)\n\nor (here fname is a .png or .jpg file name)\n\nGLI = gli(fname::String; kw...)\n\nor\n\nGLI = gli(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)\n\nGreen Leaf Index. Louhaichi, M., Borman, M.M., Johnson, D.E., 2001. \n\nGLI = (2green - red - blue) / (2green + red + blue)\n\nThe first form accepts inputs as matrices, or file names of the data bands.\nThe second form is more versatile but also more complex to describe.\ncube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.\nbands: cubes created with cutcube assign descriptions starting with \"Band1 ...\" an so on the other bands. So when bands is used we search for bands named \"Band'band[k]'\", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.\nlayers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.\nbandnames: When we know the common designation of a band, for example \"Green\", or any part of a band description, for example \"NIR\", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.\nkwargs:\nthreshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN\nclasses: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.\nmask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise\nsave: Use save=\"file_name.ext\" to save the result in a disk file. File format is picked from file extension.\n\nIf none of bands, layers or bandnames is provided, we use the default band names shown in the first form.\n\nSee also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.\n\nReturns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.gndvi-Tuple{Any, Any}","page":"Index","title":"RemoteS.gndvi","text":"GNDVI = gndvi(green, nir; kw...)\n\nor\n\nGNDVI = gndvi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)\n\ngreen Normalized diff vegetation index: more sensitive to cholorphyll than ndvi. Gitelson, A., and M. Merzlyak\n\nGNDVI = (nir - green) / (nir + green)\n\nThe first form accepts inputs as matrices, or file names of the data bands.\nThe second form is more versatile but also more complex to describe.\ncube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.\nbands: cubes created with cutcube assign descriptions starting with \"Band1 ...\" an so on the other bands. So when bands is used we search for bands named \"Band'band[k]'\", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.\nlayers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.\nbandnames: When we know the common designation of a band, for example \"Green\", or any part of a band description, for example \"NIR\", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.\nkwargs:\nthreshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN\nclasses: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.\nmask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise\nsave: Use save=\"file_name.ext\" to save the result in a disk file. File format is picked from file extension.\n\nIf none of bands, layers or bandnames is provided, we use the default band names shown in the first form.\n\nSee also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.\n\nReturns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.grid_at_sensor","page":"Index","title":"RemoteS.grid_at_sensor","text":"G = grid_at_sensor(fname::String, sds_name::String=\"\"; V::Bool=false, kw...)\n\nRead one of those netCDF files that are not regular grids but have instead the coordinates in the LONGITUDE and LATITUDE arrays. MODIS L2 files are a good example of this. Data in theses files are not layed down on a regular grid and we must interpolate to get one. Normally the lon and lat arrays are called longitude and latitude and these it's what is seek for by default. But files exist that pretend to comply to CF but use other names. In this case, use the kwargs xarray & yarray to pass in the variable names. For example: xarray=\"XLONG\", yarray=\"XLAT\" The other fundamental info to pass in is the name of the array to be read/interpolated. We do that via the sds_name arg.\n\nband: In simpler cases the variable to be interpolated lays down on a 2D array but it is also possible that it is stored in a 3D array. If that is the case, use the keyword 'band' to select a band (ex: 'band=2') Bands are numbered from 1.\nregion | limits, inc | increment | spacing and search_radius: The interpolation is done so far with nearneighbor Both the region (-R) and increment (-I) are estimated from data but they can be set with region and inc kwargs as well. One can also set the nearneighbor serach radius with option search_radius. The defaul is to set search_radius equal to two times the average increment.\nquality: For MODIS data we can select the quality flag to filter by data quality. By default the best quality (=0) is used, but one can select another with the quality=val kwarg. Positive 'val' values select data of quality <= quality, whilst negative 'val' values select only data with quality >= abs(val). This allows for example to extract only the cloud coverage.\nt_srs or target_proj: Some polar grids come with longitude, latitude (or just lon, lat) arrays in geographical coordinates. There must be an (obscure) reason for this but the practical result is messy because coordinate spacings are highly variable preventing any decent guess. In these cases it is useful to reproject the data before griding. For that purpose use the t_srs or target_proj option to tell the program to do a coordinate conversion before gridding. t_srs should then be a proj4 string with the destiny projection system.\nnodata: Sometimes datasets use other than NaN to represent nodata but they don't specify it in the netCDF attributes (e.g. the NSIDC products). This option allows to fix this (i.e nodata=-9999) Note that this is automatically set for the NSIDC products.\nnointerp: Means to not do any nearneighbor interpolation but needs that region has been set.\nNSIDC_N and NSIDC_S: Set the s_srs, region, nointerp, nodata appropriate to read the See Ice NSIDC https://nsidc.org/data/polar-stereo/ps_grids.html grids.\ndataset or xyz: If instead of calculating a grid (returned as a GMTgrid type) user wants the x,y,z data intself, use the keywords dataset, or xyz and the output will be in a GMTdataset (i.e. use dataset=true).\n\nTo inquire just the list of available arrays use list=true or gdalinfo=true to get the full file info.\n\nExamples:\n\nG = grid_at_sensor(\"AQUA_MODIS.20020717T135006.L2.SST.nc\", \"sst\", V=true);\n\nG = grid_at_sensor(\"TXx-narr-annual-timavg.nc\", \"T2MAX\", xarray=\"XLONG\", yarray=\"XLAT\", V=true);\n\nG = grid_at_sensor(\"RDEFT4_20101021.nc\", \"sea_ice_thickness\", NSIDC_N=true);\n\n\n\n\n\n","category":"function"},{"location":"#RemoteS.mcari-Tuple{Any, Any, Any}","page":"Index","title":"RemoteS.mcari","text":"MCARI = mcari(green, red, redEdge1; kw...)\n\nor\n\nMCARI = mcari(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)\n\nModified Chlorophyll Absorption ratio index. Daughtery et al. 2000\n\nMCARI = (redEdge1 - red - 0.2 * (redEdge1 - green)) * (redEdge1 / red)\n\n(Sentinel-2 Band 5 (VNIR), Band 4 (Red) and Band 3 (Green)).\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.mndwi-Tuple{Any, Any}","page":"Index","title":"RemoteS.mndwi","text":"MNDWI = mndwi(green, swir2; kw...)\n\nor\n\nMNDWI = mndwi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)\n\nModified Normalised Difference Water Index. Xu2006\n\nMNDWI = (green-swir2) / (green+swir2)\n\nThe first form accepts inputs as matrices, or file names of the data bands.\nThe second form is more versatile but also more complex to describe.\ncube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.\nbands: cubes created with cutcube assign descriptions starting with \"Band1 ...\" an so on the other bands. So when bands is used we search for bands named \"Band'band[k]'\", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.\nlayers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.\nbandnames: When we know the common designation of a band, for example \"Green\", or any part of a band description, for example \"NIR\", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.\nkwargs:\nthreshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN\nclasses: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.\nmask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise\nsave: Use save=\"file_name.ext\" to save the result in a disk file. File format is picked from file extension.\n\nIf none of bands, layers or bandnames is provided, we use the default band names shown in the first form.\n\nSee also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.\n\nReturns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.msavi-Tuple{Any, Any}","page":"Index","title":"RemoteS.msavi","text":"MSAVI = msavi(red, nir; kw...)\n\nor\n\nMSAVI = msavi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)\n\nModified soil adjusted vegetation index. Qi 1994\n\nMSAVI = nir + 0.5 - (0.5 * sqrt(pow(2.0 * nir + 1.0, 2) - 8.0 * (nir - (2.0 * red))))\n\nThe first form accepts inputs as matrices, or file names of the data bands.\nThe second form is more versatile but also more complex to describe.\ncube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.\nbands: cubes created with cutcube assign descriptions starting with \"Band1 ...\" an so on the other bands. So when bands is used we search for bands named \"Band'band[k]'\", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.\nlayers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.\nbandnames: When we know the common designation of a band, for example \"Green\", or any part of a band description, for example \"NIR\", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.\nkwargs:\nthreshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN\nclasses: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.\nmask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise\nsave: Use save=\"file_name.ext\" to save the result in a disk file. File format is picked from file extension.\n\nIf none of bands, layers or bandnames is provided, we use the default band names shown in the first form.\n\nSee also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.\n\nReturns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.mtci-Tuple{Any, Any, Any}","page":"Index","title":"RemoteS.mtci","text":"MTCI = mtci(red, redEdge1, redEdge2; kw...)\n\nMeris Terrestrial Chlorophyll Index. Clevers and Gitelson 2013, Dash and Curran 2004\n\nMTCI = (redEdge2-redEdge1) / (redEdge1-red)\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.nbri-Tuple{Any, Any}","page":"Index","title":"RemoteS.nbri","text":"NBRI = nbri(nir, swir3; kw...)\n\nor\n\nNBRI = nbri(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)\n\nNormalised Burn Ratio Index. Garcia 1991\n\nNBRI = (nir - swir2) / (nir + swir2)\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.ndrei1-Tuple{Any, Any}","page":"Index","title":"RemoteS.ndrei1","text":"NDREI1 = ndrei1(redEdge1, redEdge2; kw...)\n\nNormalized difference red edge index. Gitelson and Merzlyak 1994\n\nNDREI1 = (redEdge2 - redEdge1) / (redEdge2 + redEdge1)\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.ndrei2-Tuple{Any, Any}","page":"Index","title":"RemoteS.ndrei2","text":"NDREI2 = ndrei2(redEdge1, redEdge3; kw...)\n\nor\n\nNDREI2 = ndrei2(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)\n\nNormalized difference red edge index 2. Barnes et al 2000\n\nNDREI2 = (redEdge3 - redEdge1) / (redEdge3 + redEdge1)\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.ndvi-Tuple{Any, Any}","page":"Index","title":"RemoteS.ndvi","text":"NDVI = ndvi(red, nir; kw...)\n\nor\n\nNDVI = ndvi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)\n\nCompute the NDVI vegetation index. Input can be either the bands file names, or GMTimage objects with the band's data.\n\nNDVI = (nir - red) / (nir + red)\n\nThe first form accepts inputs as matrices, or file names of the data bands.\nThe second form is more versatile but also more complex to describe.\ncube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.\nbands: cubes created with cutcube assign descriptions starting with \"Band1 ...\" an so on the other bands. So when bands is used we search for bands named \"Band'band[k]'\", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.\nlayers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.\nbandnames: When we know the common designation of a band, for example \"Green\", or any part of a band description, for example \"NIR\", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.\nkwargs:\nthreshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN\nclasses: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.\nmask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise\nsave: Use save=\"file_name.ext\" to save the result in a disk file. File format is picked from file extension.\n\nIf none of bands, layers or bandnames is provided, we use the default band names shown in the first form.\n\nSee also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.\n\nReturns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.ndwi-Tuple{Any, Any}","page":"Index","title":"RemoteS.ndwi","text":"NDWI = ndwi(green, nir; kw...)\n\nor\n\nNDWI = ndwi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)\n\nNormalized difference water index. McFeeters 1996. NDWI => (green - nir)/(green + nir)\n\nNDWI = (green - nir)/(green + nir)\n\nThe first form accepts inputs as matrices, or file names of the data bands.\nThe second form is more versatile but also more complex to describe.\ncube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.\nbands: cubes created with cutcube assign descriptions starting with \"Band1 ...\" an so on the other bands. So when bands is used we search for bands named \"Band'band[k]'\", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.\nlayers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.\nbandnames: When we know the common designation of a band, for example \"Green\", or any part of a band description, for example \"NIR\", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.\nkwargs:\nthreshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN\nclasses: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.\nmask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise\nsave: Use save=\"file_name.ext\" to save the result in a disk file. File format is picked from file extension.\n\nIf none of bands, layers or bandnames is provided, we use the default band names shown in the first form.\n\nSee also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.\n\nReturns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.ndwi2-Tuple{Any, Any}","page":"Index","title":"RemoteS.ndwi2","text":"NDWI2 = ndwi2(nir, swir2; kw...)\n\nor\n\nNDWI2 = ndwi2(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)\n\nNormalized difference water index. Gao 1996, Chen 2005 (also known as Normalized Difference Moisture Index NDBI and LSWI)\n\nNDWI2 = (nir - swir2)/(nir + swir2)\n\nThe first form accepts inputs as matrices, or file names of the data bands.\nThe second form is more versatile but also more complex to describe.\ncube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.\nbands: cubes created with cutcube assign descriptions starting with \"Band1 ...\" an so on the other bands. So when bands is used we search for bands named \"Band'band[k]'\", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.\nlayers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.\nbandnames: When we know the common designation of a band, for example \"Green\", or any part of a band description, for example \"NIR\", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.\nkwargs:\nthreshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN\nclasses: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.\nmask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise\nsave: Use save=\"file_name.ext\" to save the result in a disk file. File format is picked from file extension.\n\nIf none of bands, layers or bandnames is provided, we use the default band names shown in the first form.\n\nSee also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.\n\nReturns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.reflectance_surf-Tuple{String}","page":"Index","title":"RemoteS.reflectance_surf","text":"R = reflectance_surf(fname::String, [band::Int, bandname::String, mtl::String, save::String])\n\nComputes the radiance-at-surface of Landsat8 band using the COST model.\n\nfname: The name of either a LANDSAT_PRODUCT_ID geotiff band, or the name of a cube file created with the cutcube function. In the first case, if the companion MTLtxt file is not in the same directory as fname one can still pass it via the mtl=path-to-MTL-file option. In the second case it is mandatory to use one of the following two options.\nband: cubes created with cutcube assign descriptions starting with \"Band 1 ...\" an so on the other bands. So when band is used we search for the band named \"Band N\", where N = band.\nbandname: When we know the common designation of a band, for example \"Green\", or any part of a band description, for example \"NIR\", we can use that info to create a bandname string that will be matched against the cube's bands descriptions. We can use the reportbands function to see the bands description.\nsave: The file name where to save the output. If not provided, a GMTgrid is returned.\n\nReturns a Float32 GMTgrid\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.reportbands-Tuple{Any, Int64}","page":"Index","title":"RemoteS.reportbands","text":"reportbands(in; [layers=Int[]])\n\nor\n\nreportbands(in, layer;)\n\nReport the Bands description of the in input argument. This can be a GMTimage, a GMTgrid or a file name (a String) of a 'cube' file. Normally one made with the cutcube function. When the use conditions of this function are not met, either a warning or an error message (if too deep to be caught as a warning) will be issued.\n\nlayers: When this optional parameter is used, report the description of the bands in the vector layers\nlayer: A scalar with a unique band number. Alternative form to reportbands(in, layers=[layer])\n\nReturns a string vector.\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.sat_scenes-Tuple{Any, String}","page":"Index","title":"RemoteS.sat_scenes","text":"satscenes(track, satname::String)\n\nCompute polygons delimiting AQUA and TERRA scenes.\n\ntrac: Is an orbit computed with sat_tracks at steps of 1 minute (crucial)\nsat_name: The satellite name. At this time only AQUA and TERRA are allowed.\n\nReturns a GMTdataset vector with the polygons and the scene names in the dataset header field.\n\nExample\n\nImagine that orb was obtained with\n\norb = sat_tracks(tle=[tle1; tle2], start=DateTime(\"2021-09-02T13:30:00\"), \tstop=DateTime(\"2021-09-02T13:40:00\"), step=\"1m\");\n\nThe scenes limits (two) are computed with:\n\nDscenes = sat_scenes(orb, \"AQUA\");\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.sat_tracks-Tuple{}","page":"Index","title":"RemoteS.sat_tracks","text":"sat_tracks(; geocentric::Bool=false, tiles::Bool=false, position::Bool=false, kwargs...)\n\nCompute satellite tracks using the TLE, or Two Line Elements set, a data format that contains information about the orbit at a specific epoch of an Earth-orbiting object. It can also calculate polygons arround the scene extents of AQUA and TERRA satellites as well as create the scene names, which provides a mean to direct download that data.\n\nstart: A DateTime object or a string convertable to a DateTime with DateTime(start) specifying the start of the orbit calculation. If omited, current time in UTC will be used.\nduration: Length of time for which the orbit is calculated. Accepts duration in days, hours, minutes or seconds. The default is minutes (100 minutes). To use other units use a string with the value appended with 'D', 'h', 'm' or 's'. e.g. duration=\"55m\" to compute orbit 55 minutes from start\nstep or inc or dt: The time interval at which to compute locations along the orbit. The default unit here is seconds (30 sec) but minutes can be used as well by appending 'm'. e.g. step=\"1m\"\nstop: As alternative to duration provide the end date for the orbit. Same conditions as start\nposition: Computes only first location at the start time. Boolean, use position=true\ngeocentric: Boolean to controls if output is lon,lat,alt,time (the default) or ECEF coordinates + time.\ntle or TLE: a file name with the TLE data for a specific satellite and period. It can also be a two elements string vector with the first and second lines of the TLE file.\ntiles: Compute the scene limits and file names for some satellites. Currently AQUA only.\nsat, SAT or satellite: Name of the satellite to use; choose from (string or symbols) :TERRA, :AQUA. Use only with the tiles option.\n\nReturns\n\nA GMTdataset with the orbit or the scene polygons\n\nExample:\n\nCompute ~one orbit of the AQUA satellite starting at current local time. Note, this will be accurate for the month of September 2021. For other dates it needs an updated TLE.\n\ntle1 = \"1 27424U 02022A 21245.83760660 .00000135 00000-0 39999-4 0 9997\";\ntle2 = \"2 27424 98.2123 186.0654 0002229 67.6025 313.3829 14.57107527 28342\";\norb = sat_tracks(tle=[tle1; tle2], duration=100);\n\nand the orbit track can be visualized with\n\nimshow(orb, proj=:Robinson, region=:global, coast=true)\n\nWARNING: This function depends on the SatelliteToolbox extension that is not loaded by default. Load it with:\n\nusing RemoteS SatelliteToolboxTle SatelliteToolboxPropagators SatelliteToolboxTransformations\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.satvi-Tuple{Any, Any, Any}","page":"Index","title":"RemoteS.satvi","text":"SATVI = satvi(red, swir2, swir3; kw...)\n\nor\n\nSATVI = satvi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)\n\nSoil adjusted total vegetation index. Marsett 2006\n\nSATVI = ((swir1 - red) / (swir1 + red + L)) * (1.0 + L) - (swir2 / 2.0)\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.savi-Tuple{Any, Any}","page":"Index","title":"RemoteS.savi","text":"SAVI = savi(red, nir; kw...)\n\nor\n\nSAVI = savi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)\n\nSoil adjusted vegetation index. Huete 1988\n\nSAVI = (nir - red) * (1.0 + L) / (nir + red + L)\n\nThe first form accepts inputs as matrices, or file names of the data bands.\nThe second form is more versatile but also more complex to describe.\ncube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.\nbands: cubes created with cutcube assign descriptions starting with \"Band1 ...\" an so on the other bands. So when bands is used we search for bands named \"Band'band[k]'\", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.\nlayers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.\nbandnames: When we know the common designation of a band, for example \"Green\", or any part of a band description, for example \"NIR\", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.\nkwargs:\nthreshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN\nclasses: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.\nmask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise\nsave: Use save=\"file_name.ext\" to save the result in a disk file. File format is picked from file extension.\n\nIf none of bands, layers or bandnames is provided, we use the default band names shown in the first form.\n\nSee also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.\n\nReturns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.slavi-Tuple{Any, Any, Any}","page":"Index","title":"RemoteS.slavi","text":"SLAVI = slavi(red, nir, swir2; kw...)\n\nor\n\nSLAVI = slavi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)\n\nSpecific Leaf Area Vegetation Index. Lymburger 2000\n\nSLAVI = nir / (red + swir2)\n\nThe first form accepts inputs as matrices, or file names of the data bands.\nThe second form is more versatile but also more complex to describe.\ncube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.\nbands: cubes created with cutcube assign descriptions starting with \"Band1 ...\" an so on the other bands. So when bands is used we search for bands named \"Band'band[k]'\", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.\nlayers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.\nbandnames: When we know the common designation of a band, for example \"Green\", or any part of a band description, for example \"NIR\", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.\nkwargs:\nthreshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN\nclasses: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.\nmask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise\nsave: Use save=\"file_name.ext\" to save the result in a disk file. File format is picked from file extension.\n\nIf none of bands, layers or bandnames is provided, we use the default band names shown in the first form.\n\nSee also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.\n\nReturns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.subcube-Tuple{String}","page":"Index","title":"RemoteS.subcube","text":"subcube(cube::String; bands=Int[], bandnames=String[], layers=Int[])\n\nExtracts a subcube from cube with the layers in the bands vector, case in which we will search for bands named \"Band band[k]\", or those whose names correspond (even partially and case insensitive) to the descriptions in bandnames string vector. This means that the options bands and bandnames can only be used in 'cubes' with bands description. The layers option blindly extract the cube planes listed in the layer vector.\n\nReturns a GMTimage\n\nsubcube(cube::Union{GMT.GMTimage{UInt16, 3}, AbstractArray{<:AbstractFloat, 3}}; bands=Int[], bandnames=String[], layers=Int[])\n\nDoes the same but from an already in memory cube. Returns a type equal to the input type. No views, a data copy.\n\nExample\n\nExtracts the Red, Green and Blue layers from a Landsat 8 cube created with cutcube\n\nIrgb = subcube(\"LC08__cube.tiff\", bandnames = [\"red\", \"green\", \"blue\"])\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.tgi-Tuple{GMT.GMTimage{UInt8, 3}}","page":"Index","title":"RemoteS.tgi","text":"TGI = tgi(red, green, blue; kw...)\n\nor (here fname is a .png or .jpg file name)\n\nTGI = tgi(fname::String; kw...)\n\nor\n\nTGI = tgi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)\n\nTriangular Greenness Index. Hunt et al. 2013\n\nTGI = green - 0.39 * red - 0.61 * blue\n\nThe first form accepts inputs as matrices, or file names of the data bands.\nThe second form is more versatile but also more complex to describe.\ncube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.\nbands: cubes created with cutcube assign descriptions starting with \"Band1 ...\" an so on the other bands. So when bands is used we search for bands named \"Band'band[k]'\", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.\nlayers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.\nbandnames: When we know the common designation of a band, for example \"Green\", or any part of a band description, for example \"NIR\", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.\nkwargs:\nthreshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN\nclasses: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.\nmask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise\nsave: Use save=\"file_name.ext\" to save the result in a disk file. File format is picked from file extension.\n\nIf none of bands, layers or bandnames is provided, we use the default band names shown in the first form.\n\nSee also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.\n\nReturns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.train_raster-Tuple{GMT.GItype, Union{String, Vector{<:GMT.GMTdataset}}}","page":"Index","title":"RemoteS.train_raster","text":"model, classes = train_raster(cube::GItype, train::Union{Vector{<:GMTdataset}, String}; np::Int=0, density=0.1)\n\ncube: The cube wtih band data to classify.\ntrain: A vector of GMTdatasets or a file name of one containing the polygons used to train the model. NOTE: The individual datasets MUST have associated an attribute called \"class\" containing the class name as a string. This can be achieved for text data in the form of a GMT multi-segment file (one where segments are separated by the '>' symbol) if the multi-segment separator line contains the text Attrib(class=name)\nnp: Number of points per polygon to be determined by randinpolygon\ndensity: Alternative to np. See also the help of the randinpolygon function.\n\nReturns the trained model and the class names.\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.truecolor-Tuple{Any, Any, Any}","page":"Index","title":"RemoteS.truecolor","text":"Irgb = truecolor(bndR, bndG, bndB)\n\nTake three Landsat8/Sentinel2 UINT16 GMTimages or the file names of those bands and compose an RGB true color image applying automatic histogram stretching.\n\nReturn an UInt8 RGB GMTimage\n\nIrgb = truecolor(cube::GMTImage, bands::Vector{Int})\n\nMake an RGB composition of the 3 bands passed in the vector 'bands' from the layers in the multi-layered GMTimage cube\n\nReturn an auto-stretched UInt8 RGB GMTimage\n\nIrgb = truecolor(cube::String, [bands::Vector{Int}], [bandnames::Vector{String}], [raw=false])\n\nMake an RGB composition of 3 bands from the cube file holding a UInt16 multi-layered array (often created with cutcube) The band selection can be made with bands vector, case in which we will search for bands named \"Band[k]\" or where the bands description contain the contents of bandnames. If none of bands or bandnames is used we search for a made up bandnames=[\"red\", \"green\", \"blue\"].\n\nReturn an auto-stretched UInt8 RGB GMTimage OR a GMTimage{UInt16,3} if the raw option is set to true.\n\nIrgb = truecolor(cube::GMTgrid, [bands|layers::Vector{Int}], [bandnames::Vector{String}], [type=UInt8])\n\nMake an RGB composition of 3 bands from the cube file holding a Float32 multi-layered array. The band selection can be made with bands vector, case in which we will search for bands named \"Band[k]\" or where the bands description contain the contents of bandnames. If none of bands or bandnames is used we search for a made up bandnames=[\"red\", \"green\", \"blue\"].\n\nBy default we scale the bands to 0-255. Use type=UInt16 to scale the bands to 0-65535`. Note that this will matter only for the guessing of the good limits to perform the histogram stretching.\n\nExample:\n\nMake an RGB composite from data in the cube file \"LC08__cube.tiff\"\n\nI = truecolor(\"LC08__cube.tiff\");\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.vari-Tuple{GMT.GMTimage{UInt8, 3}}","page":"Index","title":"RemoteS.vari","text":"VARI = vari(red, green, blue; kw...)\n\nor (here fname is a .png or .jpg file name)\n\nVARI = vari(fname::String; kw...)\n\nor\n\nVARI = vari(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)\n\nVisible Atmospherically Resistant Index. Gitelson, A.A., Kaufman, Y.J., Stark, R., Rundquist, D., 2002\n\nVARI = (green - red) / (green + red - blue)\n\nThe first form accepts inputs as matrices, or file names of the data bands.\nThe second form is more versatile but also more complex to describe.\ncube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.\nbands: cubes created with cutcube assign descriptions starting with \"Band1 ...\" an so on the other bands. So when bands is used we search for bands named \"Band'band[k]'\", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.\nlayers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.\nbandnames: When we know the common designation of a band, for example \"Green\", or any part of a band description, for example \"NIR\", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.\nkwargs:\nthreshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN\nclasses: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.\nmask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise\nsave: Use save=\"file_name.ext\" to save the result in a disk file. File format is picked from file extension.\n\nIf none of bands, layers or bandnames is provided, we use the default band names shown in the first form.\n\nSee also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.\n\nReturns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.RemoteS","page":"Index","title":"RemoteS.RemoteS","text":"Package to perform operations with satellite data. Easy to use in computing true color images with automatic contrast stretch, many spectral indices and processing of MODIS L2 files.\n\n\n\n\n\n","category":"module"},{"location":"#RemoteS.classification_proba-Tuple{GMT.GItype, Any}","page":"Index","title":"RemoteS.classification_proba","text":"I = classification_proba(cube::GItype, model; class_number=1) -> GMTimage\n\nReturns an image with the assigned probabilities when classifying the class number class_number\n\ncube: The cube wtih band data to classify\nmodel: is the model obtained from the train_raster function\nclass_number: is the class number to be classified\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.read_mtl","page":"Index","title":"RemoteS.read_mtl","text":"readmtl(bandname::String, mtl::String=\"\"; get_full=false)\n\nUse the band_name of a Landsat8 band to find the MTL file with the scene parameters at which that band belongs and read the params needed to compute Brightness temperature, radiance at top of atmosphere, etc. If the MTL file does not lieve next to the band file, send its name via the mtl argument.\n\nThe get_full option makes this function return a tring with contents of the MTL file or nothing if the MTL file is not found.\n\nReturns a tuple with:\n\n(band=band, radmul=radmul, radadd=radadd, radmax=radmax, reflectmul=reflectmul, reflectadd=reflectadd, reflectmax=reflectmax, sunazim=sunazim, sunelev=sunelev, sundis=sunazim, K1=K1, K2=K2)\n\nor a string with MTL contents (or nothing if MTL file is not found)\n\n\n\n\n\n","category":"function"}] +[{"location":"gallery/HLS/cloud-native-hls-data/#Getting-Started-with-Cloud-Native-HLS-Data-in-Julia:-1","page":"Cloud-Native HLS dat","title":"Getting Started with Cloud-Native HLS Data in Julia:","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Extracting an EVI Time Series from Harmonized Landsat-8 Sentinel-2 (HLS) data in the Cloud using CMR's SpatioTemporal Asset Catalog (CMR-STAC). This tutorial demonstrates how to work with the HLS Landsat 8 (HLSL30.015) and Sentinel-2 (HLSS30.015) data products.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#NOTE:-This-tutorial-is-adapted-from-[Getting-Started-with-Cloud-Native-HLS-Data-in-Python](https://lpdaac.usgs.gov/resources/e-learning/getting-started-cloud-native-hls-data-python/)-1","page":"Cloud-Native HLS dat","title":"NOTE: This tutorial is adapted from Getting Started with Cloud-Native HLS Data in Python","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#.-Importing-packages-1","page":"Cloud-Native HLS dat","title":"1. Importing packages","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"using HTTP, JSON, GMT, RemoteS\n\nr = HTTP.request(\"GET\", \"https://cmr.earthdata.nasa.gov/stac/\");\nstac_response = JSON.parse(String(r.body));","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#.-Navigating-the-CMR-STAC-API-1","page":"Cloud-Native HLS dat","title":"2. Navigating the CMR-STAC API","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"What is STAC?","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"STAC is a specification that provides a common language for interpreting geospatial information in order to standardize indexing and discovering data.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Four STAC Specifications:","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"STAC API\nSTAC Catalog\nSTAC Collection\nSTAC Item","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#STAC-Catalog:-Contains-a-JSON-file-of-links-that-organize-all-of-the-collections-available.-1","page":"Cloud-Native HLS dat","title":"STAC Catalog: Contains a JSON file of links that organize all of the collections available.","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#Search-for-LP-DAAC-Catalogs,-and-print-the-information-contained-in-the-Catalog-that-we-will-be-using-today,-LPCLOUD-1","page":"Cloud-Native HLS dat","title":"Search for LP DAAC Catalogs, and print the information contained in the Catalog that we will be using today, LPCLOUD","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"stac_lp = [s for s in stac_response[\"links\"] if occursin(\"LP\", s[\"title\"])]\n\n# LPCLOUD is the STAC catalog we will be using and exploring today\nhr = [s for s in stac_lp if s[\"title\"] == \"LPCLOUD\"][1][\"href\"];\nr = HTTP.request(\"GET\", hr);\nlp_cloud = JSON.parse(String(r.body));","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#Print-the-links-contained-in-the-LP-CLOUD-STAC-Catalog-1","page":"Cloud-Native HLS dat","title":"Print the links contained in the LP CLOUD STAC Catalog","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"lp_links = lp_cloud[\"links\"];\n\nfor l in lp_links\n try\n println(l[\"href\"], \" is the \", l[\"title\"])\n catch\n println(l[\"href\"])\n end\nend","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"https://cmr.earthdata.nasa.gov/stac/LPCLOUD is the Provider catalog\nhttps://cmr.earthdata.nasa.gov/stac/ is the Root catalog\nhttps://cmr.earthdata.nasa.gov/stac/LPCLOUD/collections is the Provider Collections\nhttps://cmr.earthdata.nasa.gov/stac/LPCLOUD/search is the Provider Item Search\nhttps://cmr.earthdata.nasa.gov/stac/LPCLOUD/search is the Provider Item Search\nhttps://cmr.earthdata.nasa.gov/stac/LPCLOUD/conformance is the Conformance Classes\nhttps://api.stacspec.org/v1.0.0-beta.1/openapi.yaml is the OpenAPI Doc\nhttps://api.stacspec.org/v1.0.0-beta.1/index.html is the HTML documentation\nhttps://cmr.earthdata.nasa.gov/stac/LPCLOUD/collections/ASTGTM.v003\nhttps://cmr.earthdata.nasa.gov/stac/LPCLOUD/collections/HLSL30.v2.0\nhttps://cmr.earthdata.nasa.gov/stac/LPCLOUD/collections/HLSL30.v1.5\nhttps://cmr.earthdata.nasa.gov/stac/LPCLOUD/collections/HLSS30.v1.5\nhttps://cmr.earthdata.nasa.gov/stac/LPCLOUD/collections/HLSS30.v2.0","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#.-STAC-Collection:-Extension-of-STAC-Catalog-containing-additional-information-that-describe-the-STAC-Items-in-that-Collection.-1","page":"Cloud-Native HLS dat","title":"3. STAC Collection: Extension of STAC Catalog containing additional information that describe the STAC Items in that Collection.","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#Get-a-response-from-the-LPCLOUD-Collection-and-print-the-information-included-in-the-response.-1","page":"Cloud-Native HLS dat","title":"Get a response from the LPCLOUD Collection and print the information included in the response.","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Set collections endpoint to variable\nlp_collections = [l[\"href\"] for l in lp_links if l[\"rel\"] == \"collections\"][1];\n\n# Call collections endpoint\nr = HTTP.request(\"GET\", lp_collections);\ncollections_response = JSON.parse(String(r.body));\n\nprintln(\"This collection contains $(collections_response[\"description\"]) ($(length(collections_response[\"collections\"])) available)\")","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"This collection contains All collections provided by LPCLOUD (5 available)","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#As-of-October-3,-2021,-there-are-five-collections-available,-and-more-will-be-added-in-the-future.-1","page":"Cloud-Native HLS dat","title":"As of October 3, 2021, there are five collections available, and more will be added in the future.","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#Print-out-one-of-the-collections:-1","page":"Cloud-Native HLS dat","title":"Print out one of the collections:","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"collections = collections_response[\"collections\"];\ncollections[2]","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Dict{String, Any} with 8 entries:\n \"links\" => Any[Dict{String, Any}(\"rel\"=>\"self\", \"href\"=>\"https://cmr.e…\n \"id\" => \"HLSL30.v2.0\"\n \"stac_version\" => \"1.0.0\"\n \"title\" => \"HLS Landsat Operational Land Imager Surface Reflectance an…\n \"license\" => \"not-provided\"\n \"type\" => \"Collection\"\n \"description\" => \"The Harmonized Landsat and Sentinel-2 (HLS) project provid…\n \"extent\" => Dict{String, Any}(\"spatial\"=>Dict{String, Any}(\"bbox\"=>Any[…","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#In-CMR,-id-is-used-to-query-by-a-specific-product,-so-be-sure-to-save-the-ID-for-the-HLS-S30-and-L30-V1.5-products-below:-1","page":"Cloud-Native HLS dat","title":"In CMR, id is used to query by a specific product, so be sure to save the ID for the HLS S30 and L30 V1.5 products below:","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Search available collections for HLS and print them out\nhls_collections = [c for c in collections if contains(c[\"title\"], \"HLS\")];\n\n[println(\"$(h[\"title\"]) has ID (shortname) of: $(h[\"id\"])\") for h in hls_collections]","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"HLS Landsat Operational Land Imager Surface Reflectance and TOA Brightness Daily Global 30m v2.0 has ID (shortname) of: HLSL30.v2.0\nHLS Operational Land Imager Surface Reflectance and TOA Brightness Daily Global 30 m V1.5 has ID (shortname) of: HLSL30.v1.5\nHLS Sentinel-2 Multi-spectral Instrument Surface Reflectance Daily Global 30 m V1.5 has ID (shortname) of: HLSS30.v1.5\nHLS Sentinel-2 Multi-spectral Instrument Surface Reflectance Daily Global 30m v2.0 has ID (shortname) of: HLSS30.v2.0\n\n4-element Vector{Nothing}:\n nothing\n nothing\n nothing\n nothing","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Note that the id shortname is in the format: productshortname.vVVV (where VVV = product version)","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#Explore-the-attributes-contained-in-the-HLSS30-Collection.-1","page":"Cloud-Native HLS dat","title":"Explore the attributes contained in the HLSS30 Collection.","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Grab HLSS30 collection\ns30 = [h for h in hls_collections if h[\"id\"] == \"HLSS30.v1.5\"][1];\n\n# Check out the extent of this collection\nfor k in keys(s30[\"extent\"]) println(k, \" : \", s30[\"extent\"][k]) end","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"spatial : Dict{String, Any}(\"bbox\" => Any[Any[-180, -90, 180, 90]])\ntemporal : Dict{String, Any}(\"interval\" => Any[Any[\"2015-12-01T00:00:00.000Z\", nothing]])","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#So-here-we-can-see-that-the-extent-is-global,-and-can-also-see-the-temporal-range–where-None-means-on-going-or-to-present.-1","page":"Cloud-Native HLS dat","title":"So here we can see that the extent is global, and can also see the temporal range–where None means on-going or to present.","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"println(\"HLS S30 Start Date is: $(s30[\"extent\"][\"temporal\"][\"interval\"][1][1])\")","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"HLS S30 Start Date is: 2015-12-01T00:00:00.000Z","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#Next,-explore-the-attributes-of-the-HLSL30-collection.-1","page":"Cloud-Native HLS dat","title":"Next, explore the attributes of the HLSL30 collection.","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Above, notice that the L30 product has a different start date than the S30 product.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#.-STAC-Item:-Represents-data-and-metadata-assets-that-are-spatiotemporally-coincident-1","page":"Cloud-Native HLS dat","title":"4. STAC Item: Represents data and metadata assets that are spatiotemporally coincident","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#Query-the-HLSS30-collection-for-items-and-return-the-first-item-in-the-collection.-1","page":"Cloud-Native HLS dat","title":"Query the HLSS30 collection for items and return the first item in the collection.","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Go through all links in the collection and return the link containing the items endpoint\n\n# Set items endpoint to variable\ns30_items = [s[\"href\"] for s in s30[\"links\"] if s[\"rel\"] == \"items\"][1]","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"\"https://cmr.earthdata.nasa.gov/stac/LPCLOUD/collections/HLSS30.v1.5/items\"","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Call items endpoint\nr = HTTP.request(\"GET\", s30_items);\ns30_items_response = JSON.parse(String(r.body));\n\ns30_item = s30_items_response[\"features\"][1]","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Dict{String, Any} with 10 entries:\n \"links\" => Any[Dict{String, Any}(\"rel\"=>\"self\", \"href\"=>\"https://cm…\n \"stac_extensions\" => Any[\"https://stac-extensions.github.io/eo/v1.0.0/schema.…\n \"geometry\" => Dict{String, Any}(\"coordinates\"=>Any[Any[Any[40.9215, 19…\n \"id\" => \"HLS.S30.T37QGC.2016228T074942.v1.5\"\n \"stac_version\" => \"1.0.0\"\n \"properties\" => Dict{String, Any}(\"datetime\"=>\"2016-08-15T08:00:59.720Z\"…\n \"bbox\" => Any[40.9089, 19.7977, 41.1665, 20.7895]\n \"type\" => \"Feature\"\n \"assets\" => Dict{String, Any}(\"B8A\"=>Dict{String, Any}(\"href\"=>\"http…\n \"collection\" => \"HLSS30.v1.5\"","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#STAC-metadata-provides-valuable-information-on-the-item,-including-a-unique-ID,-when-it-was-acquired,-the-location-of-the-observation,-and-a-cloud-cover-assessment.-1","page":"Cloud-Native HLS dat","title":"STAC metadata provides valuable information on the item, including a unique ID, when it was acquired, the location of the observation, and a cloud cover assessment.","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Print metadata attributes from this observation\nprintln(\"The ID for this item is: $(s30_item[\"id\"])\")\nprintln(\"It was acquired on: $(s30_item[\"properties\"][\"datetime\"]))\")\nprintln(\"over: $(s30_item[\"bbox\"]) (Lower Left, Upper Right corner coordinates)\")\nprintln(\"It contains $(length(s30_item[\"assets\"])) assets\")\nprintln(\"and is $(s30_item[\"properties\"][\"eo:cloud_cover\"])% cloudy.\")","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"The ID for this item is: HLS.S30.T37QGC.2016228T074942.v1.5\nIt was acquired on: 2016-08-15T08:00:59.720Z)\nover: Any[40.908869, 19.797714, 41.166492, 20.789487] (Lower Left, Upper Right corner coordinates)\nIt contains 20 assets\nand is 4% cloudy.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#Print-out-the-ten-items-and-the-percent-cloud-cover–we-will-use-this-to-decidewhich-item-to-visualize-in-the-next-section.-1","page":"Cloud-Native HLS dat","title":"Print out the ten items and the percent cloud cover–we will use this to decidewhich item to visualize in the next section.","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#Using-the-information-printed-above,-set-the-item_index-below-to-whichever-observation-is-the-least-cloudy-above.-1","page":"Cloud-Native HLS dat","title":"Using the information printed above, set the item_index below to whichever observation is the least cloudy above.","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"item_index = 2;\n\n# Grab the next item in the list\ns30_item = s30_items_response[\"features\"][item_index];\n\nprintln(\"The ID for this item is: $(s30_item[\"id\"])\")\nprintln(\"It was acquired on: $(s30_item[\"properties\"][\"datetime\"])\")\nprintln(\"over: $(s30_item[\"bbox\"]) (Lower Left, Upper Right corner coordinates)\")\nprintln(\"It contains $(length(s30_item[\"assets\"])) assets\")\nprintln(\"and is $(s30_item[\"properties\"][\"eo:cloud_cover\"])% cloudy.\")","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"The ID for this item is: HLS.S30.T37QEE.2016228T074942.v1.5\nIt was acquired on: 2016-08-15T08:00:59.720Z\nover: Any[38.999805, 21.611674, 40.068079, 22.607038] (Lower Left, Upper Right corner coordinates)\nIt contains 20 assets\nand is 0% cloudy.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#Print-out-the-names-of-all-of-the-assets-included-in-this-item.-1","page":"Cloud-Native HLS dat","title":"Print out the names of all of the assets included in this item.","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"println(\"The following assets are available for download:\")\nkeys(s30_item[\"assets\"])","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"The following assets are available for download:\n\nKeySet for a Dict{String, Any} with 20 entries. Keys:\n \"B8A\"\n \"SZA\"\n \"B07\"\n \"B05\"\n \"B02\"\n \"B06\"\n \"B08\"\n \"B01\"\n \"B09\"\n \"Fmask\"\n \"VZA\"\n \"B10\"\n \"browse\"\n \"B03\"\n \"B04\"\n \"VAA\"\n \"metadata\"\n \"SAA\"\n \"B11\"\n \"B12\"","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#Notice-that-each-HLS-item-includes-a-browse-image.-Read-the-browse-file-into-memory-and-visualize-the-HLS-acquisition.-1","page":"Cloud-Native HLS dat","title":"Notice that each HLS item includes a browse image. Read the browse file into memory and visualize the HLS acquisition.","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"s30_item[\"assets\"][\"browse\"]","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Dict{String, Any} with 3 entries:\n \"href\" => \"https://data.lpdaac.earthdatacloud.nasa.gov/lp-prod-public/HLSS30…\n \"title\" => \"Download HLS.S30.T37QEE.2016228T074942.v1.5.jpg\"\n \"type\" => \"image/jpeg\"","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"img = gmtread(s30_item[\"assets\"][\"browse\"][\"href\"]);\nimshow(img)","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#Congrats!-You-have-pulled-your-first-HLS-asset-from-the-cloud-using-STAC!-1","page":"Cloud-Native HLS dat","title":"Congrats! You have pulled your first HLS asset from the cloud using STAC!","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#.-CMR-STAC-API:-Searching-for-Items-1","page":"Cloud-Native HLS dat","title":"3. CMR-STAC API: Searching for Items","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"In this section, instead of simply navigating through the structure of a STAC Catalog, use the search endpoint to query the API by region of interest and time period of interest.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#.1-Spatial-Querying-via-Bounding-Box-1","page":"Cloud-Native HLS dat","title":"3.1 Spatial Querying via Bounding Box","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"The search endpoint is one of the links found in the LPCLOUD STAC Catalog, which can be leveraged to retrieve STAC Items that match the submitted query parameters.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Grab the search endpoint for the LPCLOUD STAC Catalog and send a POST request to retrieve items.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Define the search endpoint\nlp_search = [l[\"href\"] for l in lp_links if l[\"rel\"] == \"search\"][1]\n\n# Set up a dictionary that will be used to POST requests to the search endpoint\nparams = Dict();","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"r = HTTP.request(\"POST\", lp_search);\nsearch_response = JSON.parse(String(r.body));\n\n\"$(length(search_response[\"features\"])) items found\"","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"\"10 items found\"","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"If we just call the search endpoint directly, it will default to returning the first 10 granules. Below, set a limit to return the first 100 matching items. Additional information on the spec for adding parameters to a search query can be found at:","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"https://github.com/radiantearth/stac-api-spec/tree/master/item-search#query-parameters-and-fields.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Add in a limit parameter to retrieve 100 items at a time.\nlim = 100;\nparams[\"limit\"] = lim;","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Above, we have added the limit as a parameter to the dictionary that we will post to the search endpoint to submit our request for data. As we keep moving forward in the tutorial, we will continue adding parameters to the params dictionary.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# send POST request to retrieve first 100 items in the STAC collection\nr = HTTP.post(lp_search, [\"Content-Type\" => \"application/json\"], JSON.json(params));\nsearch_response = JSON.parse(String(r.body));\n\n\"$(length(search_response[\"features\"])) items found\"","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"\"100 items found\"","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Load in the spatial region of interest for our use case using GMT. You will need to have downloaded the Field_Boundary.geojson from the repo, and it must be stored in the current working directory in order to continue. If you are still encountering issues, you can add the entire filepath to the file (ex: D = gmtread(\\\"C:/Username/HLS-Tutorial/Field_Boundary.geojson\\\") and try again.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Since the output is a vector of GMTdataset and all data is in first element\nD = gdalread(\"c:/v/Field_Boundary.geojson\")[1];","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Plot the geometry of the farm field boundaries.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"imshow(D, projection=:guess)","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"The farm field used in this example use case is located northwest of Chico, CA.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Now, add the bounding box of the region of interest to the CMR-STAC API Search query using the bbox parameter.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Compute the polygon bounding cordinates\nbb = gmtinfo(D, C=1)[1];\n\nbbox = \"$(bb[1]),$(bb[3]),$(bb[2]),$(bb[4])\";","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"params[\"bbox\"] = bbox;\nparams","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Dict{Any, Any} with 2 entries:\n \"bbox\" => \"-122.0622682571411,39.897234301806,-122.04918980598451,39.9130938…\n \"limit\" => 100","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Send POST request with bbox included\nr = HTTP.post(lp_search, [\"Content-Type\" => \"application/json\"], JSON.json(params));\nsearch_response = JSON.parse(String(r.body));\n\n\"$(length(search_response[\"features\"])) items found\"","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"\"100 items found\"","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#.2-Temporal-Querying-1","page":"Cloud-Native HLS dat","title":"3.2 Temporal Querying","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Finally, you can narrow your search to a specific time period of interest using the datetime parameter. Here we have set the time period of interest from September 2020 through March 2021. Additional information on setting temporal searches can be found in the NASA CMR Documentation.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Define start time period / end time period\ndate_time = \"2020-09-01T00:00:00Z/2021-03-31T23:59:59Z\";\n\nparams[\"datetime\"] = date_time\nparams","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Dict{Any, Any} with 3 entries:\n \"datetime\" => \"2020-09-01T00:00:00Z/2021-03-31T23:59:59Z\"\n \"bbox\" => \"-122.0622682571411,39.897234301806,-122.04918980598451,39.9130…\n \"limit\" => 100","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Send POST request with datetime included\nr = HTTP.post(lp_search, [\"Content-Type\" => \"application/json\"], JSON.json(params))\nsearch_response = JSON.parse(String(r.body));\n\n\"$(length(search_response[\"features\"])) items found\"","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"\"100 items found\"","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"params","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Dict{Any, Any} with 3 entries:\n \"datetime\" => \"2020-09-01T00:00:00Z/2021-03-31T23:59:59Z\"\n \"bbox\" => \"-122.0622682571411,39.897234301806,-122.04918980598451,39.9130…\n \"limit\" => 100","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#As-of-October-4,-2021,-the-HLS-Operational-Land-Imager-Surface-Reflectance-and-TOA-Brightness-(HLSL30)-product-has-been-provisionally-released,-and-this-tutorial-has-been-updated-to-show-how-to-combine-observations-from-both-products-into-a-time-series.-1","page":"Cloud-Native HLS dat","title":"As of October 4, 2021, the HLS Operational Land Imager Surface Reflectance and TOA Brightness (HLSL30) product has been provisionally released, and this tutorial has been updated to show how to combine observations from both products into a time series.","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Next, add the shortname for the HLSS30 v1.5 product (HLSS30.v1.5) to the params dictionary, and query the CMR-STAC LPCLOUD search endpoint for just HLSS30 items.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"s30_id = \"HLSS30.v1.5\"\nparams[\"collections\"] = [s30_id];","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Search for the HLSS30 items of interest:\n# Send POST request with collection included\nr = HTTP.post(lp_search, [\"Content-Type\" => \"application/json\"], JSON.json(params))\ns30_items = JSON.parse(String(r.body))[\"features\"];\nlength(s30_items)","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"61","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Append the HLSL30 V1.5 Product shortname (ID) to the list under the collections parameter.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"l30_id = \"HLSL30.v1.5\";\nappend!(params[\"collections\"], [l30_id])\nparams","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Dict{Any, Any} with 4 entries:\n \"datetime\" => \"2020-09-01T00:00:00Z/2021-03-31T23:59:59Z\"\n \"collections\" => [\"HLSS30.v1.5\", \"HLSL30.v1.5\"]\n \"bbox\" => \"-122.0622682571411,39.897234301806,-122.04918980598451,39.9…\n \"limit\" => 100","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#The-collections-parameter-is-a-list-and-can-include-multiple-product-collection-short-names.-1","page":"Cloud-Native HLS dat","title":"The collections parameter is a list and can include multiple product collection short names.","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Search for the HLSS30 and HLSL30 items of interest:\n# Send POST request with S30 and L30 collections included\nr = HTTP.post(lp_search, [\"Content-Type\" => \"application/json\"], JSON.json(params))\nhls_items = JSON.parse(String(r.body))[\"features\"];\nlength(hls_items)","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"68","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#.-Extracting-HLS-COGs-from-the-Cloud-1","page":"Cloud-Native HLS dat","title":"4. Extracting HLS COGs from the Cloud","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"In this section, configure gdal and rasterio to use vsicurl to access the cloud assets that we are interested in, and read them directly into memory without needing to download the files.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# GDAL configurations used to successfully access LP DAAC Cloud Assets via vsicurl \nset_config_option(\"GDAL_HTTP_COOKIEFILE\", joinpath(tempdir(), \"cookies.txt\"))\nset_config_option(\"GDAL_HTTP_COOKIEJAR\", joinpath(tempdir(), \"cookies.txt\"))\nset_config_option(\"GDAL_DISABLE_READDIR_ON_OPEN\",\"YES\")\nset_config_option(\"CPL_VSIL_CURL_ALLOWED_EXTENSIONS\",\"TIF\")\nset_config_option(\"CPL_VSIL_CURL_USE_HEAD\",\"FALSE\")\nset_config_option(\"GDAL_HTTP_UNSAFESSL\", \"YES\")","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#.1-Subset-by-Band-1","page":"Cloud-Native HLS dat","title":"4.1 Subset by Band","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"View the contents of the first item.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"h = hls_items[1]","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Dict{String, Any} with 10 entries:\n \"links\" => Any[Dict{String, Any}(\"rel\"=>\"self\", \"href\"=>\"https://cm…\n \"stac_extensions\" => Any[\"https://stac-extensions.github.io/eo/v1.0.0/schema.…\n \"geometry\" => Dict{String, Any}(\"coordinates\"=>Any[Any[Any[-121.964, 3…\n \"id\" => \"HLS.S30.T10TEK.2020273T190109.v1.5\"\n \"stac_version\" => \"1.0.0\"\n \"properties\" => Dict{String, Any}(\"datetime\"=>\"2020-09-29T19:13:24.996Z\"…\n \"bbox\" => Any[-123.0, 39.657, -121.702, 40.6509]\n \"type\" => \"Feature\"\n \"assets\" => Dict{String, Any}(\"B8A\"=>Dict{String, Any}(\"href\"=>\"http…\n \"collection\" => \"HLSS30.v1.5\"","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#Subset-by-band-by-filtering-to-only-include-the-NIR,-Red,-Blue,-and-Quality-(Fmask)-layers-in-the-list-of-links-to-access.-Below-you-can-find-the-different-band-numbers-for-each-of-the-two-products.-1","page":"Cloud-Native HLS dat","title":"Subset by band by filtering to only include the NIR, Red, Blue, and Quality (Fmask) layers in the list of links to access. Below you can find the different band numbers for each of the two products.","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#Sentinel-2:-1","page":"Cloud-Native HLS dat","title":"Sentinel 2:","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"evi_band_links = []\n\n# Define which HLS product is being accessed\nif (split(h[\"assets\"][\"browse\"][\"href\"], '/')[5] == \"HLSS30.015\")\n evi_bands = [\"B8A\", \"B04\", \"B02\", \"Fmask\"] # NIR RED BLUE Quality for S30\nelse\n evi_bands = [\"B05\", \"B04\", \"B02\", \"Fmask\"] # NIR RED BLUE Quality for L30\nend\n\n# Subset the assets in the item down to only the desired bands\nfor a in h[\"assets\"]\n for b in evi_bands\n if b == first(a)\n append!(evi_band_links, [h[\"assets\"][first(a)][\"href\"]])\n end\n end\nend\n\nfor e in evi_band_links println(e) end","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"https://lpdaac.earthdata.nasa.gov/lp-prod-protected/HLSS30.015/HLS.S30.T10TEK.2020273T190109.v1.5.B8A.tif\nhttps://lpdaac.earthdata.nasa.gov/lp-prod-protected/HLSS30.015/HLS.S30.T10TEK.2020273T190109.v1.5.B02.tif\nhttps://lpdaac.earthdata.nasa.gov/lp-prod-protected/HLSS30.015/HLS.S30.T10TEK.2020273T190109.v1.5.Fmask.tif\nhttps://lpdaac.earthdata.nasa.gov/lp-prod-protected/HLSS30.015/HLS.S30.T10TEK.2020273T190109.v1.5.B04.tif","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Remember from above that you can always quickly load in the browse image to get a quick view of the item.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Load jpg browse image into memory\nimage = gmtread(h[\"assets\"][\"browse\"][\"href\"]);\nimshow(image)","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Above, we see a partly cloudy observation over the northern Central Valley of California.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#.2-Load-a-Spatially-Subset-HLS-COG-into-Memory-1","page":"Cloud-Native HLS dat","title":"4.2 Load a Spatially Subset HLS COG into Memory","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Before loading the COGs into memory, run the cell below to check and make sure that you have a netrc file set up with your NASA Earthdata Login credentials, which will be needed to access the HLS files in the cells that follow. If you do not have a netrc file set up on your OS, the cell below should prompt you for your NASA Earthdata Login username and password.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"set_config_option(\"GDAL_HTTP_COOKIEFILE\", joinpath(tempdir(), \"cookies.txt\"));\nset_config_option(\"GDAL_HTTP_COOKIEJAR\", joinpath(tempdir(), \"cookies.txt\"));\nset_config_option(\"GDAL_DISABLE_READDIR_ON_OPEN\",\"YES\");\nset_config_option(\"CPL_VSIL_CURL_ALLOWED_EXTENSIONS\",\"TIF\");\nset_config_option(\"CPL_VSIL_CURL_USE_HEAD\",\"FALSE\");\nset_config_option(\"GDAL_HTTP_UNSAFESSL\", \"YES\");","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"for e in evi_band_links\n if split(e,'.')[end-1] == evi_bands[1] # NIR index\n println(\"/vsicurl/\"*e)\n tic()\n global nir = GMT.Gdal.read(\"/vsicurl/\"*e)\n toc()\n elseif split(e,'.')[end-1] == evi_bands[2] # Red index\n global red = GMT.Gdal.read(\"/vsicurl/\"*e)\n elseif split(e,'.')[end-1] == evi_bands[3] # Blue index\n global blue = GMT.Gdal.read(\"/vsicurl/\"*e)\n elseif split(e,'.')[end-1] == evi_bands[4] # Mask index\n global fmask = GMT.Gdal.read(\"/vsicurl/\"*e)\n end\nend\nprintln(\"The COGs have been loaded into memory!\")","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"/vsicurl/https://lpdaac.earthdata.nasa.gov/lp-prod-protected/HLSS30.015/HLS.S30.T10TEK.2020273T190109.v1.5.B8A.tif\nelapsed time: 11.319765 seconds\nThe COGs have been loaded into memory!","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Getting an error in the section above? Accessing these files in the cloud requires you to authenticate using your NASA Earthdata Login account. You will need to have a netrc file set up containing those credentials in your home directory in order to successfully run the code","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Below, take the farm field polygon and convert it from lat/lon (EPSG: 4326) into the native projection of HLS, UTM (aligned to the Military Grid Reference System). This must be done in order to use the Region of Interest (ROI) to subset the COG that is being pulled into memory–it must be in the native projection of the data being extracted.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"utm = getproj(nir); # Destination coordinate system\nDp = lonlat2xy(D, utm); # Project to UTM\nDp[1].geom = wkbPolygon; # Ensure it's a polygon for the mask calculation","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Compute the projected polygon bounding cordinates\nbb = gmtinfo(Dp, numeric=true)[1];","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Compute a mask with 1's inside the farm's polygon and 0's outside.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"mask = gdalrasterize(Dp, [\"-tr\",\"30\",\"30\", \"-te\", \"$(bb[1])\", \"$(bb[3])\", \"$(bb[2])\", \"$(bb[4])\", \"-burn\", \"1\", \"-init\", \"0\"]);","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Now, we can use the ROI to mask any pixels that fall outside of it and crop to the bounding box. This greatly reduces the amount of data that are needed to load into memory.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"nir_cropped = gdaltranslate(nir, [\"-projwin\", \"$(bb[1])\", \"$(bb[4])\", \"$(bb[2])\", \"$(bb[3])\"]);\nred_cropped = gdaltranslate(red, [\"-projwin\", \"$(bb[1])\", \"$(bb[4])\", \"$(bb[2])\", \"$(bb[3])\"]);\nblue_cropped = gdaltranslate(blue, [\"-projwin\", \"$(bb[1])\", \"$(bb[4])\", \"$(bb[2])\", \"$(bb[3])\"]);\nfmask_cropped = gdaltranslate(fmask, [\"-projwin\", \"$(bb[1])\", \"$(bb[4])\", \"$(bb[2])\", \"$(bb[3])\"]);\n\n@inbounds Threads.@threads for k = 1:length(fmask_cropped)\n (mask[k] == 0) && (fmask_cropped[k] = 1)\nend","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#.-Processing-HLS-Data-1","page":"Cloud-Native HLS dat","title":"5. Processing HLS Data","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"In this section, read the file metadata to retrieve and apply the scale factor, filter out nodata values, define a function to calculate EVI, and execute the EVI function on the data loaded into memory. After that, perform quality filtering to screen out any poor quality observations.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Compute the EVI index using the evi function from the RemoreS package and plot the results.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"EVI = evi(blue_cropped, red_cropped, nir_cropped);","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Apply a mask to the EVI layer using pixels with good quality as defined by the Fmask.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"The good quality is encoded in the fmask where its pixels are equal to zero.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Replace the flagged values by NaN\n@inbounds Threads.@threads for k = 1:length(EVI)\n (fmask_cropped[k] != 0) && (EVI[k] = NaN32)\nend","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Display the EVI\nimshow(EVI, colorbar=true)","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#.-Automation-1","page":"Cloud-Native HLS dat","title":"6. Automation","text":"","category":"section"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"In this section, automate sections 4-5 for each HLS item that intersects our spatiotemporal subset of interest. Loop through each item and subset to the desired bands, load the spatial subset into memory, calculate EVI, quality filter, and save as a netCDF multi-layered cube.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Note: Be patient with the for loop below, it will take nearly an hour to complete.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"# Put it all together and loop through each of the files, visualize, calculate statistics on EVI, and export\nfor (j, h) in enumerate(hls_items)\n\n outName = split(h[\"assets\"][\"browse\"][\"href\"], '/')[end]\n outName = replace(outName, \".jpg\" => \"_EVI.grd\")\n\n tic()\n try\n evi_band_links = []\n # Define which HLS product is being accessed\n if (split(h[\"assets\"][\"browse\"][\"href\"], '/')[5] == \"HLSS30.015\")\n evi_bands = [\"B8A\", \"B04\", \"B02\", \"Fmask\"] # NIR RED BLUE Quality for S30\n else\n evi_bands = [\"B05\", \"B04\", \"B02\", \"Fmask\"] # NIR RED BLUE Quality for L30\n end\n\n for a in h[\"assets\"]\n for b in evi_bands\n (b == first(a)) && append!(evi_band_links, [h[\"assets\"][first(a)][\"href\"]])\n end\n end\n\n # Use vsicurl to load the data directly into memory (be patient, may take many seconds)\n for e in evi_band_links\n if split(e,'.')[end-1] == evi_bands[4] # Mask index\n local fmask = GMT.Gdal.read(\"/vsicurl/\"*e);\n global fmask_cropped = gdaltranslate(fmask, [\"-projwin\", \"$(bb[1])\", \"$(bb[4])\", \"$(bb[2])\", \"$(bb[3])\"]);\n break\n end\n end\n\n @inbounds for k = 1:length(fmask_cropped)\n (mask[k] == 0) && (fmask_cropped[k] = 1)\n end\n\n all(fmask_cropped.image .!= 0) && continue\n\n for e in evi_band_links\n if split(e,'.')[end-1] == evi_bands[1] # NIR index\n global nir = GMT.Gdal.read(\"/vsicurl/\"*e);\n elseif split(e,'.')[end-1] == evi_bands[2] # Red index\n global red = GMT.Gdal.read(\"/vsicurl/\"*e);\n elseif split(e,'.')[end-1] == evi_bands[3] # Blue index\n global blue = GMT.Gdal.read(\"/vsicurl/\"*e);\n end\n end\n\n nir_cropped = gdaltranslate(nir, [\"-projwin\", \"$(bb[1])\", \"$(bb[4])\", \"$(bb[2])\", \"$(bb[3])\"]);\n red_cropped = gdaltranslate(red, [\"-projwin\", \"$(bb[1])\", \"$(bb[4])\", \"$(bb[2])\", \"$(bb[3])\"]);\n blue_cropped = gdaltranslate(blue, [\"-projwin\", \"$(bb[1])\", \"$(bb[4])\", \"$(bb[2])\", \"$(bb[3])\"]);\n\n EVI = evi(blue_cropped, red_cropped, nir_cropped);\n\n # Replace the flagged values by NaN\n @inbounds for k = 1:length(EVI)\n (fmask_cropped[k] != 0) && (EVI[k] = NaN32)\n end\n\n #gmtwrite(outName, EVI)\n gdaltranslate(EVI, save=outName)\n catch err\n println(err)\n end\n toc()\n\n println(\"Processed file $j of $(length(hls_items))\")\nend","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"eviFiles = [o for o in readdir() if endswith(o, \"EVI.grd\")];","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"df = dateformat\"yyyymmddTHHMMSS\";\ntime = Vector{TimeType}(undef, length(eviFiles));\nfor (i, e) in enumerate(eviFiles)\n t = split(split(e, \".v1.5\")[1], \".\")[end];\n # Julia doesn't parse a date in yyyyjjjT... so must resort to brewed functions\n mon, day = monthday(doy2date(t[5:7], t[1:4]));\n time[i] = DateTime(@sprintf(\"%s%.02d%.02d%s\", t[1:4], mon, day, t[8:end]), df);\nend\n\n# Get the permutation vector p that puts time[p] in sorted order\np = sortperm(time);\neviFiles = eviFiles[p];\t\t# Sort the file names in ascending time order\ntime = time[p];\t\t\t\t# and the time too.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Save all EVI estimations in a netCDF 3d (a cube) file","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"stackgrids(eviFiles, time, z_unit=\"unix\", save=\"evi_cube.nc\")","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Interpolate along all layers at a point with coordinates x = 580740; y = 4418042","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"D = grdinterpolate(\"evi_cube.nc\", pt=(580740,4418042));","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"Now, plot the time series showing the distribution of EVI values for our farm field.","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"imshow(D, par=(TIME_SYSTEM=\"UNIX\",), coltypes=:t)","category":"page"},{"location":"gallery/HLS/cloud-native-hls-data/#","page":"Cloud-Native HLS dat","title":"Cloud-Native HLS dat","text":"","category":"page"},{"location":"gallery/Aqua_orbits/remotes_sat_tracks/#Plot-AQUA-satellite-tracks-1","page":"Aqua orbits","title":"Plot AQUA satellite tracks","text":"","category":"section"},{"location":"gallery/Aqua_orbits/remotes_sat_tracks/#","page":"Aqua orbits","title":"Aqua orbits","text":"Compute 1 day of AQUA satellite orbits starting at current local time. Note, this will be accurate for the month of September 2021. For other dates it needs an updated TLE. Note also that repeating the commands below will produce different results since the current local time is used as the starting point.","category":"page"},{"location":"gallery/Aqua_orbits/remotes_sat_tracks/#","page":"Aqua orbits","title":"Aqua orbits","text":"Orbits calculation rely on the SatelliteToolbox package(s). Orbits are calculated with the help of the so called Two Line Element files that unfortunatelly have accuracy validity quite short (around one month). They can be obtainded from the Space Track site.","category":"page"},{"location":"gallery/Aqua_orbits/remotes_sat_tracks/#","page":"Aqua orbits","title":"Aqua orbits","text":"using RemoteS, GMT, SatelliteToolboxTle, SatelliteToolboxPropagators, SatelliteToolboxTransformations\n\n# The AQUA orbits TLE contents for the month of September 2021 \ntle1 = \"1 27424U 02022A 21245.83760660 .00000135 00000-0 39999-4 0 9997\";\ntle2 = \"2 27424 98.2123 186.0654 0002229 67.6025 313.3829 14.57107527 28342\";\norb = sat_tracks(tle=[tle1; tle2], duration=\"1D\");\n\n# The orbit track can be visualized with\nimshow(orb, proj=:Robinson, region=:global, coast=true)","category":"page"},{"location":"gallery/Aqua_orbits/remotes_sat_tracks/#","page":"Aqua orbits","title":"Aqua orbits","text":"","category":"page"},{"location":"gallery/Aqua_orbits/remotes_sat_tracks/#","page":"Aqua orbits","title":"Aqua orbits","text":"There is no point in plotting orbits for a lengthier duration because they would clutter the figure but we can compute them and display over a specific region on Earth.","category":"page"},{"location":"gallery/Aqua_orbits/remotes_sat_tracks/#","page":"Aqua orbits","title":"Aqua orbits","text":"# Compute orbits during 2 days at 15 seconds intervals\norb = sat_tracks(tle=[tle1; tle2], duration=\"2D\", step=15);\n\n# and plot them on my \"vicinity\"\nD = clip_orbits(orb, [-20, 10, 30, 50]);\n\nimshow(D, proj=:guess, coast=true, dpi=200)","category":"page"},{"location":"gallery/Aqua_orbits/remotes_sat_tracks/#","page":"Aqua orbits","title":"Aqua orbits","text":"","category":"page"},{"location":"gallery/Aqua_orbits/remotes_sat_tracks/#","page":"Aqua orbits","title":"Aqua orbits","text":"And imagine we would like to know the names of the AQUA scene files that cover a certain location? We can do it with the findscenes function to which we must provide the location of interest, the satellite (currently only AQUA or TERRA), the duration of the search and if we want Chlorophyl-a concentration or Sea Surface Temperature (see function help for details).","category":"page"},{"location":"gallery/Aqua_orbits/remotes_sat_tracks/#","page":"Aqua orbits","title":"Aqua orbits","text":"# Get the scene names of data with Chlorophyl-a concentration covering\n# the point (-8,36) and for two days before \"2021-09-07T17:00:00\"\ntle1 = \"1 27424U 02022A 21245.83760660 .00000135 00000-0 39999-4 0 9997\";\ntle2 = \"2 27424 98.2123 186.0654 0002229 67.6025 313.3829 14.57107527 28342\";\nfindscenes(-8,36, start=\"2021-09-07T17:00:00\", sat=:aqua, day=true, duration=-2, oc=1, tle=[tle1, tle2])","category":"page"},{"location":"gallery/Aqua_orbits/remotes_sat_tracks/#","page":"Aqua orbits","title":"Aqua orbits","text":"\t2-element Vector{String}:\n\tA2021251125500.L2_LAC_OC.nc\n\tA2021252134000.L2_LAC_OC.nc","category":"page"},{"location":"gallery/Aqua_orbits/remotes_sat_tracks/#","page":"Aqua orbits","title":"Aqua orbits","text":"Now you can download them from https://oceandata.sci.gsfc.nasa.gov/ob/getfile/A2021251125500.L2_LAC_OC.nc (but you will need to register first) and play with the grid_at_sensor function for interpolation and visualization.","category":"page"},{"location":"gallery/Aqua_orbits/remotes_sat_tracks/#","page":"Aqua orbits","title":"Aqua orbits","text":"Another cool thing we can do is to plot the area extent of the AQUA or TERRA scenes. We do it by first computing and orbit with a start and stop times and with increments of 1 minute (attention, this is an important factor). With that orbit we use the sat_tracks function to compute the polygons delimiting those areas.","category":"page"},{"location":"gallery/Aqua_orbits/remotes_sat_tracks/#","page":"Aqua orbits","title":"Aqua orbits","text":"using Dates\n\norb = sat_tracks(tle=[tle1; tle2], start=DateTime(\"2021-09-02T13:30:00\"),\n\tstop=DateTime(\"2021-09-02T13:40:00\"), step=\"1m\");\n\nDsc = sat_scenes(orb, \"AQUA\");","category":"page"},{"location":"gallery/Aqua_orbits/remotes_sat_tracks/#","page":"Aqua orbits","title":"Aqua orbits","text":"","category":"page"},{"location":"gallery/Aqua_orbits/remotes_sat_tracks/#","page":"Aqua orbits","title":"Aqua orbits","text":"The scene names are stored in the header field of the Dsc GMTdatset","category":"page"},{"location":"gallery/Aqua_orbits/remotes_sat_tracks/#","page":"Aqua orbits","title":"Aqua orbits","text":"julia> Dsc[1].header\n\n`AQUA_MODIS.20210902T133001.L2.SST.NRT.nc`\n\njulia> Dsc[2].header\n\n`AQUA_MODIS.20210902T133501.L2.SST.NRT.nc`","category":"page"},{"location":"gallery/Aqua_orbits/remotes_sat_tracks/#","page":"Aqua orbits","title":"Aqua orbits","text":"","category":"page"},{"location":"gallery/Aqua_orbits/remotes_sat_tracks/#","page":"Aqua orbits","title":"Aqua orbits","text":"Download a Neptune Notebook here","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#Exploring-a-*cube*-of-Landsat-8-data-1","page":"Landsat 8 images","title":"Exploring a cube of Landsat 8 data","text":"","category":"section"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"Here we will show examples of the type of things we can do with Landsat 8 data stored in a cube for better organisation and easyness of access.","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"The data was downloaded from EarthExplorer and comprises the scene with Product ID LC08_L1TP_204033_20210525_20210529_02_T1.","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"The cube was made with this instructions (but they would only work if you had the scene files in your computer).","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"path = C:/v/LC08_L1TP_204033_20210525_20210529_02_T1/LC08_L1TP_204033_20210525_20210529_02_T1_B;","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"cube = cutcube(bands=[2,3,4,5,6,7,10], template=path, region=(485490,531060,4283280,4330290), save=\"LC08_L1TP_20210525_02_cube.tiff\")","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"This creates a 3D GeoTIFF file with the companion MTL file saved in it as Metadata. We can see the band info by running the reportbands function. That information is quite handy because we can, for example, just refer to the red band and it will figure out which layer of the cube contains the Red band.","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"using RemoteS, GMT\nreportbands(\"c:/v/LC08_L1TP_20210525_02_cube.tiff\")\n7-element Vector{String}:\n \"Band 2 - Blue [0.45-0.51]\"\n \"Band 3 - Green [0.53-0.59]\"\n \"Band 4 - Red [0.64-0.67]\"\n \"Band 5 - NIR [0.85-0.88]\"\n \"Band 6 - SWIR 1 [1.57-1.65]\"\n \"Band 7 - SWIR 2 [2.11-2.29]\"\n \"Band 10 - Thermal IR 1 [10.6-11.19]\"","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"So to start our exploration the best is to generate a true color image. The truecolor function knows how to do that automatically including the histogram contrast stretch.","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"Irgb = truecolor(\"c:/v/LC08_L1TP_20210525_02_cube.tiff\");\nimshow(Irgb)","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"And we can compute the brightness temperature in Celsius at the Top of Atmosphere (TOA) from Band 10.","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"T = dn2temperature(\"c:/v/LC08_L1TP_20210525_02_cube.tiff\", band=10);\nimshow(T, dpi=150, colorbar=true)","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"Or the Radiance TOA for the Blue band.","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"Btoa = dn2radiance(\"c:/v/LC08_L1TP_20210525_02_cube.tiff\", bandname=\"blue\");\nimshow(Btoa, dpi=150, color=:gray)","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"Hmmm, very dark. Let's look at its histogram.","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"histogram(Btoa, auto=true, show=true)","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"Yes, the data is very concentraded in the low numbers. We will need to apply a contrast stretch. To do that operation we will use the rescale function with the stretch=true option that uses the limits displayed in the histogram figure above ans stretches the inner interval into [0 255] (by effect of the type=UInt8 option).","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"Btoa_img = rescale(Btoa, stretch=true, type=UInt8);\nimshow(Btoa_img)","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"Now we are going to do the same for all Red, Green and Blue bands and compose the in a truecolor image. Repeating, we are going to compute the radiance at the top of atmosphere, retain only the data inside the parts of the histogram where it is more concentrated and create a true color image. To compute the radiance TOA we can do it all at once with the dn2radiance applied to the cube and, like before, create the RGB image with truecolor","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"cube_toa_rad = dn2radiance(\"c:/v/LC08_L1TP_20210525_02_cube.tiff\");\nIrgb_toa = truecolor(cube_toa_rad);\nimshow(Irgb_toa)","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"Hm, yes, very nice but it looks very much like the one obtained directly with the digital numbers. Indeed, it does but let us zoom in.","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"grdimage(Irgb, region=(502380,514200,4311630,4321420), figsize=8, frame=:bare)\ngrdimage!(Irgb_toa, figsize=8, projection=:linear, xshift=8, frame=:bare, show=true)","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"","category":"page"},{"location":"gallery/L8cube_img/remotes_L8_cube_img/#","page":"Landsat 8 images","title":"Landsat 8 images","text":"We can now clearly see that the image on the right, the one made the radiance TOA, has an higher contrast than the one made with data without any corrections.","category":"page"},{"location":"gallery/Aqua_sst/remotes_L2_SST/#Interpolate-a-MODIS-L2-SST-file-1","page":"Aqua SST","title":"Interpolate a MODIS L2 SST file","text":"","category":"section"},{"location":"gallery/Aqua_sst/remotes_L2_SST/#","page":"Aqua SST","title":"Aqua SST","text":"The Level 2 MODIS files are the ones that contain the information at its maximum spatial resolution. However, in those products the data is not equally spaced so we must interpolate it first before use. The grid_at_sensor function provides a handy interface to do it easily.","category":"page"},{"location":"gallery/Aqua_sst/remotes_L2_SST/#","page":"Aqua SST","title":"Aqua SST","text":"Imagine that you have downloaded the file AQUA_MODIS.20210805T131001.L2.SST.NRT.nc from the OceanColor site (eventually following the example in Plot AQUA satellite tracks)","category":"page"},{"location":"gallery/Aqua_sst/remotes_L2_SST/#","page":"Aqua SST","title":"Aqua SST","text":"using RemoteS, GMT\n\n# Interpolate from sensor to geographic coordinates at approx 1 km grid steps\nG = grid_at_sensor(\"C:/v/AQUA_MODIS.20210805T131001.L2.SST.NRT.nc\", \"sst\", inc=0.01);\n\n# Display it\nimshow(G, proj=:guess, coast=true, dpi=200)","category":"page"},{"location":"gallery/Aqua_sst/remotes_L2_SST/#","page":"Aqua SST","title":"Aqua SST","text":"","category":"page"},{"location":"gallery/Aqua_sst/remotes_L2_SST/#","page":"Aqua SST","title":"Aqua SST","text":"Note that since we used a grid step 0f 0.01 for the interpolation and this value is very close to the MODIS maximum spatial resolution, the left and right regions have beam spacings 2 to 5 times this and show many little holes. Do not confuse these little holes with the larger ones that are caused by cloud coverage. So we will recalculate the grid at increments of ~2 km and over the region that has the higher data density.","category":"page"},{"location":"gallery/Aqua_sst/remotes_L2_SST/#","page":"Aqua SST","title":"Aqua SST","text":"# Recompue at a inc=0.02 and over a sub-region\nG = grid_at_sensor(\"C:/v/AQUA_MODIS.20210805T131001.L2.SST.NRT.nc\", \"sst\", region=(-13,10,33.8,44.5), inc=0.02);","category":"page"},{"location":"gallery/Aqua_sst/remotes_L2_SST/#","page":"Aqua SST","title":"Aqua SST","text":"# Make a nicer image with illumination.\nimshow(G, proj=:guess, coast=true, shade=true, title=\"Sea Surace Temperature\", colorbar=true)","category":"page"},{"location":"gallery/Aqua_sst/remotes_L2_SST/#","page":"Aqua SST","title":"Aqua SST","text":"","category":"page"},{"location":"gallery/Aqua_sst/remotes_L2_SST/#","page":"Aqua SST","title":"Aqua SST","text":"","category":"page"},{"location":"gallery/Aqua_sst/remotes_L2_SST/#","page":"Aqua SST","title":"Aqua SST","text":"Download a Neptune Notebook here","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#Spectral-indices-with-Landsat-8-imagery-1","page":"Landsat 8 NDVI","title":"Spectral indices with Landsat 8 imagery","text":"","category":"section"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"We will use here the same data cube that was introduced in the images example.","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"A very popular spectral indice is the NDVI which is deffined as the a normalized difference between the Near Infra Red (NIR) and the Red bands. Namely NDVI = (NIR - Red) / (NIR + Red). An heuristic says that NDVI values ~greater than 0.4 indicate green vegetation as higher the indice (maximum = 1) larger is the green vegetation content.","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"Since the data cube holds in it the information about each band, computing the NDVI is a trivial opration because we known where each band is in the data cube. Let's see it.","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"using RemoteS, GMT\nN = ndvi(\"LC08_L1TP_20210525_02_cube.tiff\");\nimshow(N, colorbar=true)","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"The spectral indices functions all have a threshold value that will NaNify all values threshold. Below we wipe out all values < 0.4 to show only the Green stuff","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"N = ndvi(\"LC08_L1TP_20210525_02_cube.tiff\", threshold=0.4);\nimshow(N, dpi=150, colorbar=1)","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"Cool but I would like to check that the result is correct.","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"The spectral indices functions have another option to obtain just a mask where the values are threshold, so we can use it to mask out the true color image and see what we get. ","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"# Compute a mask based on the condition that threshold >= 0.4\nmask = ndvi(\"LC08_L1TP_20210525_02_cube.tiff\", threshold=0.4, mask=true);","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"To mask out the true color image the best way is to use the mask as the alpha band. To make it easier we will recalculate the true color image here.","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"# Recalculate the true color image\nIrgb = truecolor(\"LC08_L1TP_20210525_02_cube.tiff\");\n\n# Apply the mask\nimage_alpha!(Irgb, alpha_band=mask, burn=1);\n\n# And save it to disk\ngmtwrite(\"rgb_masked.tiff\", Irgb)\n\nimshow(Irgb)","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"While we can see that only the green color is present in the above image, it's not easy to see the details. So let's zoom in but do also another thing. Let us see also what parts of the RGB image were not selected. To see that we will calculate the inverse mask, that is, the mask that retains all values < threshold. To achieve that we use the mask option with a negative number.","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"# Compute a mask based on the condition that threshold >= 0.4\nmask_inv = ndvi(\"LC08_L1TP_20210525_02_cube.tiff\", threshold=0.4, mask=-1)\n;\n# Recompute the true color image that was modified by the ``image_alpha!`` step above\nIrgb = truecolor(\"LC08_L1TP_20210525_02_cube.tiff\");\n\nimage_alpha!(Irgb, alpha_band=mask_inv, burn=1);\ngmtwrite(\"rgb_inv_masked.tiff\", Irgb)","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"Plot the green vegetation that passed the NDVI threshold test and the other part, side by side.","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"grdimage(\"rgb_masked.tiff\", region=(502380,514200,4311630,4321420), figsize=8, frame=:bare)\ngrdimage!(\"rgb_inv_masked.tiff\", figsize=8, projection=:linear, xshift=8, frame=:bare, show=true)","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"","category":"page"},{"location":"gallery/L8cube_ndvi/remotes_L8_NDVI/#","page":"Landsat 8 NDVI","title":"Landsat 8 NDVI","text":"As we can see only the greenest part, the one that is probably more irrigated considering that all the river and cannals margins were retained, was extracted with the condition NDVI > 0.4. Off course, using different threshold values would lead to slightly different results.","category":"page"},{"location":"#RemoteS-1","page":"Index","title":"RemoteS","text":"","category":"section"},{"location":"#Index-1","page":"Index","title":"Index","text":"","category":"section"},{"location":"#","page":"Index","title":"Index","text":"Modules = [RemoteS]\nOrder = [:function, :type, :module]","category":"page"},{"location":"#Functions-1","page":"Index","title":"Functions","text":"","category":"section"},{"location":"#","page":"Index","title":"Index","text":"Modules = [RemoteS]\nOrder = [:function, :type, :module]","category":"page"},{"location":"#RemoteS.classify-Tuple{GMT.GItype, Any}","page":"Index","title":"RemoteS.classify","text":"I = classify(cube::GItype, model; class_names::Union{String, Vector{String}}=\"\") -> GMTimage\n\ncube: The cube wtih band data to classify.\nmodel: The trained model obtained from the train_raster function.\nclass_names: A vector of strings with the class names to be used in the categorical colorbar or a comma separated single with those class names. The number of class names must match the number used when training the model with train_raster.\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.classify-Tuple{GMT.GItype, Union{String, Vector{<:GMT.GMTdataset}}}","page":"Index","title":"RemoteS.classify","text":"I = classify(cube::GItype, train::Union{Vector{<:GMTdataset}, String}) -> GMTimage\n\ncube: The cube wtih band data to classify.\ntrain: A vector of GMTdatasets or a file name of one containing the polygons used to train the model. NOTE: The individual datasets MUST have associated an attribute called \"class\" containing the class name as a string. This can be achieved for text data in the form of a GMT multi-segment file (one where segments are separated by the '>' symbol) if the multi-segment separator line contains the text Attrib(class=name)\n\nReturns an image with the classification results where each class name was assigned a different integer number. That colorized image can plotted with viz(I colorbar=true).\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.clg-Tuple{Any, Any}","page":"Index","title":"RemoteS.clg","text":"CLG = clg(green, redEdge3; kw...)\n\nor\n\nCLG = clg(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)\n\nGreen cholorphyl index. Wu et al 2012.\n\nCLG = (redEdge3)/(green)-1 \n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.clip_orbits-Tuple{Any, Vector{<:Real}}","page":"Index","title":"RemoteS.clip_orbits","text":"clip_orbits(track, BoundingBox::Vector{<:Real})\n\nClips the orbits that are contained inside a rectangular geographical region\n\ntrack: A GMTdataset or a Mx2 matrix with the orbits [lon, lat] position. This is normally calculated with the sat_tracks function.\nBoundingBox: A vector the region limits made up with [lonmin, lonmax, latmin, latmax]\n\nReturns a GMTdataset vector with the chunks of tracks that cross inside the BoundingBox region.\n\n#Example Suppose orb holds orbits computed with sat_tracks() during 2 days, clip them inside the 20W-10E, 30N-45N window\n\nD = clip_orbits(orb, [-20, 10, 30, 50]);\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.clre-Tuple{Any, Any}","page":"Index","title":"RemoteS.clre","text":"CLRE = clre(redEdge1, redEdge3; kw...)\n\nor\n\nCLRE = clre(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)\n\nRedEdge cholorphyl index. Clevers and Gitelson 2013.\n\nCLRE = (redEdge3)/(redEdge1)-1\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.cutcube-Tuple{}","page":"Index","title":"RemoteS.cutcube","text":"cutcube(names=String[], bands=Int[], template=\"\", region=nothing, extension=\".TIF\", description=String[], mtl=\"\", sentinel2=0, save=\"\")\n\nCut a 3D cube out of a Landsat/Sentinel scene within a subregion region and a selection of bands.\n\nnames: (optional) A vector with the individual bands full file name\nbands: When names is not provided give a vector of integers corresponding to the choosen bands. This works well for Landsat and most of Sentinel bands. However, in later case, there are also bands that contain characters, for example band 8A. In this case bands should be a vector of strings including the extension. e.g. [\"02.jp2\", \"8A.jp2\"]\ntemplate: Goes together with the bands option. They are both composed a template * band[n] to recreate the full file name of each band.\nregion Is the region to extract and must contain the extracting region limits as [W, E, S, N] or a GMT style -R string (without the leading \"-R\").\nextension: In case the bands is numeric but file extensions are not \"*.TIF\" (case insensitive), use the extension passed by this option.\ndescription: A vector of strings (as many as bands) with a description for each band. If not provided and the file is recognized as a Landasat 8, band description is added automatically, otherwise we build one with the bands file names. This info will saved if data is written to a file.\nmtl: If reading from Landsat and the MTL file is not automatically found (you get an error) use this option to pass the full name of the MTL file.\nsentinel2: ESA is just unconsistent and names change with time and band numbers can have character (e.g. 8A) hence we need help to recognize Sentinel files so the known description can be assigned. Use sentinel=10, or =20 or =60 to indicate Sentinel files at those resolutions.\nsave: The file name where to save the output. If not provided, a GMTimage is returned.\n\nReturn: nothing if the result is written in file or a GMTimage otherwise.\n\nExamples\n\n# Cut a Landsat 8 scene for a small region (in UTM) and return a GMTimage with 3 bands in UInt16.\ntemp = \"C:\\SIG_AnaliseDadosSatelite\\SIG_ADS\\DadosEx2\\LC82040332015145LGN00\\LC82040332015145LGN00_B\";\ncube = cutcube(bands=[2,3,4], template=temp, region=[479670,492720,4282230,4294500])\n\n# The same example as above but save the data in a GeoTIFF disk file and use a string for `region`\ncutcube(bands=[2,3,4], template=temp, region=\"479670/492720/4282230/4294500\", save=\"landsat_cube.tif\")\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.dn2radiance-Tuple{String}","page":"Index","title":"RemoteS.dn2radiance","text":"R = dn2radiance(fname::String, [band::Int, bandname::String, mtl::String, save::String])\n\nComputes the radiance at TopOfAtmosphere of a Landsat 8 file\n\nfname: The name of either a LANDSAT_PRODUCT_ID geotiff band, or the name of a cube file created with the cutcube function. In the first case, if the companion MTLtxt file is not in the same directory as fname one can still pass it via the mtl=path-to-MTL-file option. In the second case it is mandatory to use one of the following two options.\nband: cubes created with cutcube assign descriptions starting with \"Band 1 ...\" an so on the other bands. So when band is used we search for the band named \"Band N\", where N = band.\nbandname: When we know the common designation of a band, for example \"Green\", or any part of a band description, for example \"NIR\", we can use that info to create a bandname string that will be matched against the cube's bands descriptions. We can use the reportbands function to see the bands description.\nsave: The file name where to save the output. If not provided, a GMTgrid is returned.\n\nReturns a Float32 GMTgrid\n\nExample:\n\nCompute the radiance TOA of Band 2 file.\n\nR = dn2radiance(\"LC08_L1TP_204033_20210525_20210529_02_T1_B2.TIF\")\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.dn2reflectance-Tuple{String}","page":"Index","title":"RemoteS.dn2reflectance","text":"R = dn2reflectance(fname::String, [band::Int, bandname::String, mtl::String, save::String])\n\nComputes the TopOfAtmosphere planetary reflectance of a Landsat8 file\n\nfname: The name of either a LANDSAT_PRODUCT_ID geotiff band, or the name of a cube file created with the cutcube function. In the first case, if the companion MTLtxt file is not in the same directory as fname one can still pass it via the mtl=path-to-MTL-file option. In the second case it is mandatory to use one of the following two options.\nband: cubes created with cutcube assign descriptions starting with \"Band 1 ...\" an so on the other bands. So when band is used we search for the band named \"Band N\", where N = band.\nbandname: When we know the common designation of a band, for example \"Green\", or any part of a band description, for example \"NIR\", we can use that info to create a bandname string that will be matched against the cube's bands descriptions. We can use the reportbands function to see the bands description.\nsave: The file name where to save the output. If not provided, a GMTgrid is returned.\n\nReturns a Float32 GMTgrid\n\nExample:\n\nCompute the reflectance TOA of Red Band stored in a cube\n\nR = dn2reflectance(cube, bandname=\"red\")\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.dn2temperature-Tuple{String}","page":"Index","title":"RemoteS.dn2temperature","text":"R = dn2temperature(fname::String; band::Int=0, mtl::String=\"\", save::String)\n\nComputes the brigthness temperature of Landasat8 termal band (10 or 11)\n\nfname: The name of either a LANDSAT_PRODUCT_ID geotiff band, or the name of a cube file created with the cutcube function. In the first case, if the companion MTLtxt file is not in the same directory as fname one can still pass it via the mtl=path-to-MTL-file option. In the second case it is mandatory to use one of the following two options.\nband: cubes created with cutcube assign descriptions starting with \"Band 1 ...\" an so on the other bands. So when band is used we search for the band named \"Band N\", where N = band.\nbandname: When we know the common designation of a band, for example \"Green\", or any part of a band description, for example \"NIR\", we can use that info to create a bandname string that will be matched against the cube's bands descriptions. We can use the reportbands function to see the bands description.\nsave: The file name where to save the output. If not provided, a GMTgrid is returned.\n\nReturns a Float32 GMTgrid\n\nExample:\n\nCompute the brightness temperature of Band 10 stored in a cube\n\nT = dn2temperature(cube, band=10)\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.evi-Tuple{Any, Any, Any}","page":"Index","title":"RemoteS.evi","text":"EVI = evi(blue, red, nir; kw...)\n\nor\n\nEVI = evi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)\n\nEnhanced vegetation index. Huete et al 1990\n\nEVI = G * ((nir - red) / (nir + C1 * red - C2 * blue + Levi)); C1, C2, G, Levi = 6.0, 7.5, 2.5, 1.\n\nThe first form accepts inputs as matrices, or file names of the data bands.\nThe last form is more versatile but also more complex to describe.\ncube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.\nbands: cubes created with cutcube assign descriptions starting with \"Band1 ...\" an so on the other bands. So when bands is used we search for bands named \"Band'band[k]'\", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.\nlayers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.\nbandnames: When we know the common designation of a band, for example \"Green\", or any part of a band description, for example \"NIR\", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.\n\nKwargs\n\nthreshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN\nclasses: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.\nmask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise\nsave: Use save=\"file_name.ext\" to save the result in a disk file. File format is picked from file extension.\norder | bands_order | rgb: For the GLI, TGI and VARI (RGB) indices, we allow to reorder the bands and change the expected RGB order. Pass in a string, or symbol, with the color order. For example, order=:rbg\n\nwill swap the green and blue components making the result index identify the _reds_ instead of the _greens_.\nNot good for vegetation indices, but potentially useful for other purposes.\n\nIf none of bands, layers or bandnames is provided, we use the default band names shown in the first form.\n\nSee also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.\n\nReturns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.evi2-Tuple{Any, Any}","page":"Index","title":"RemoteS.evi2","text":"EVI2 = evi2(red, nir; kw...)\n\nor\n\nEVI2 = evi2(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)\n\nTwo-band Enhanced vegetation index. Jiang et al 2008\n\nEVI2 = G * ((nir - red) / (nir + 2.4 * red ))\n\nThe first form accepts inputs as matrices, or file names of the data bands.\nThe last form is more versatile but also more complex to describe.\ncube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.\nbands: cubes created with cutcube assign descriptions starting with \"Band1 ...\" an so on the other bands. So when bands is used we search for bands named \"Band'band[k]'\", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.\nlayers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.\nbandnames: When we know the common designation of a band, for example \"Green\", or any part of a band description, for example \"NIR\", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.\n\nKwargs\n\nthreshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN\nclasses: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.\nmask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise\nsave: Use save=\"file_name.ext\" to save the result in a disk file. File format is picked from file extension.\norder | bands_order | rgb: For the GLI, TGI and VARI (RGB) indices, we allow to reorder the bands and change the expected RGB order. Pass in a string, or symbol, with the color order. For example, order=:rbg\n\nwill swap the green and blue components making the result index identify the _reds_ instead of the _greens_.\nNot good for vegetation indices, but potentially useful for other purposes.\n\nIf none of bands, layers or bandnames is provided, we use the default band names shown in the first form.\n\nSee also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.\n\nReturns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.findscenes-Tuple{Real, Real}","page":"Index","title":"RemoteS.findscenes","text":"findscenes(lon::Real, lat::Real; kwargs...)\n\nFind the names of the scenes that cover the location point lon, lat in the period determined by the dates and satellite set via kwargs.\n\nday: Search only on the day time part of the orbits.\nnight: Search only on the night time part of the orbits.\noc: For the AQUA or TERRA satellites pick only the chlorophyl content scenes.\nsst: For the AQUA or TERRA satellites pick only the Sae Surface Temperature content scenes.\nsat, SAT or satellite: Name of the satellite to use; choose from (string or symbols) :TERRA, :AQUA\nstart: A DateTime object or a string convertable to a DateTime with DateTime(start) specifying the start of the looking period. If omited, current time in UTC will be used.\nduration: Length of time for which the scenes are searched. The duration is expected in days and can be a negative number, meaning we'll look that span days from start.\nstop: As alternative to duration provide the end date for the serch. Same conditions as start\ntle or TLE: a file name with the TLE data for a specific satellite and period. It can also be a two elements string vector with the first and second lines of the TLE file.\n\nReturns\n\nA string vector with the scene names\n\nExample:\n\nFind the AQUA scenes with chlorophyl-a (oceancolor) that cover the point (-8, 36) in the two days before \"2021-09-07T17:00:00\" Note, this will be accurate for the month of September 2021. For other dates it needs an updated TLE.\n\ntle1 = \"1 27424U 02022A 21245.83760660 .00000135 00000-0 39999-4 0 9997\";\ntle2 = \"2 27424 98.2123 186.0654 0002229 67.6025 313.3829 14.57107527 28342\";\nfindscenes(-8,36, start=\"2021-09-07T17:00:00\", sat=:aqua, day=true, duration=-2, oc=1, tle=[tle1, tle2])\n\n2-element Vector{String}:\n\"A2021251125500.L2_LAC_OC.nc\"\n\"A2021252134000.L2_LAC_OC.nc\"\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.gli-Tuple{GMT.GMTimage{UInt8, 3}}","page":"Index","title":"RemoteS.gli","text":"GLI = gli(red, green, blue; kw...)\n\nor (here fname is a .png or .jpg file name)\n\nGLI = gli(fname::String; kw...)\n\nor\n\nGLI = gli(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)\n\nGreen Leaf Index. Louhaichi, M., Borman, M.M., Johnson, D.E., 2001. \n\nGLI = (2green - red - blue) / (2green + red + blue)\n\nThe first form accepts inputs as matrices, or file names of the data bands.\nThe last form is more versatile but also more complex to describe.\ncube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.\nbands: cubes created with cutcube assign descriptions starting with \"Band1 ...\" an so on the other bands. So when bands is used we search for bands named \"Band'band[k]'\", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.\nlayers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.\nbandnames: When we know the common designation of a band, for example \"Green\", or any part of a band description, for example \"NIR\", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.\n\nKwargs\n\nthreshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN\nclasses: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.\nmask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise\nsave: Use save=\"file_name.ext\" to save the result in a disk file. File format is picked from file extension.\norder | bands_order | rgb: For the GLI, TGI and VARI (RGB) indices, we allow to reorder the bands and change the expected RGB order. Pass in a string, or symbol, with the color order. For example, order=:rbg\n\nwill swap the green and blue components making the result index identify the _reds_ instead of the _greens_.\nNot good for vegetation indices, but potentially useful for other purposes.\n\nIf none of bands, layers or bandnames is provided, we use the default band names shown in the first form.\n\nSee also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.\n\nReturns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.gndvi-Tuple{Any, Any}","page":"Index","title":"RemoteS.gndvi","text":"GNDVI = gndvi(green, nir; kw...)\n\nor\n\nGNDVI = gndvi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)\n\ngreen Normalized diff vegetation index: more sensitive to cholorphyll than ndvi. Gitelson, A., and M. Merzlyak\n\nGNDVI = (nir - green) / (nir + green)\n\nThe first form accepts inputs as matrices, or file names of the data bands.\nThe last form is more versatile but also more complex to describe.\ncube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.\nbands: cubes created with cutcube assign descriptions starting with \"Band1 ...\" an so on the other bands. So when bands is used we search for bands named \"Band'band[k]'\", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.\nlayers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.\nbandnames: When we know the common designation of a band, for example \"Green\", or any part of a band description, for example \"NIR\", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.\n\nKwargs\n\nthreshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN\nclasses: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.\nmask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise\nsave: Use save=\"file_name.ext\" to save the result in a disk file. File format is picked from file extension.\norder | bands_order | rgb: For the GLI, TGI and VARI (RGB) indices, we allow to reorder the bands and change the expected RGB order. Pass in a string, or symbol, with the color order. For example, order=:rbg\n\nwill swap the green and blue components making the result index identify the _reds_ instead of the _greens_.\nNot good for vegetation indices, but potentially useful for other purposes.\n\nIf none of bands, layers or bandnames is provided, we use the default band names shown in the first form.\n\nSee also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.\n\nReturns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.grid_at_sensor","page":"Index","title":"RemoteS.grid_at_sensor","text":"G = grid_at_sensor(fname::String, sds_name::String=\"\"; V::Bool=false, kw...)\n\nRead one of those netCDF files that are not regular grids but have instead the coordinates in the LONGITUDE and LATITUDE arrays. MODIS L2 files are a good example of this. Data in theses files are not layed down on a regular grid and we must interpolate to get one. Normally the lon and lat arrays are called longitude and latitude and these it's what is seek for by default. But files exist that pretend to comply to CF but use other names. In this case, use the kwargs xarray & yarray to pass in the variable names. For example: xarray=\"XLONG\", yarray=\"XLAT\" The other fundamental info to pass in is the name of the array to be read/interpolated. We do that via the sds_name arg.\n\nband: In simpler cases the variable to be interpolated lays down on a 2D array but it is also possible that it is stored in a 3D array. If that is the case, use the keyword 'band' to select a band (ex: 'band=2') Bands are numbered from 1.\nregion | limits, inc | increment | spacing and search_radius: The interpolation is done so far with nearneighbor Both the region (-R) and increment (-I) are estimated from data but they can be set with region and inc kwargs as well. One can also set the nearneighbor serach radius with option search_radius. The defaul is to set search_radius equal to two times the average increment.\nquality: For MODIS data we can select the quality flag to filter by data quality. By default the best quality (=0) is used, but one can select another with the quality=val kwarg. Positive 'val' values select data of quality <= quality, whilst negative 'val' values select only data with quality >= abs(val). This allows for example to extract only the cloud coverage.\nt_srs or target_proj: Some polar grids come with longitude, latitude (or just lon, lat) arrays in geographical coordinates. There must be an (obscure) reason for this but the practical result is messy because coordinate spacings are highly variable preventing any decent guess. In these cases it is useful to reproject the data before griding. For that purpose use the t_srs or target_proj option to tell the program to do a coordinate conversion before gridding. t_srs should then be a proj4 string with the destiny projection system.\nnodata: Sometimes datasets use other than NaN to represent nodata but they don't specify it in the netCDF attributes (e.g. the NSIDC products). This option allows to fix this (i.e nodata=-9999) Note that this is automatically set for the NSIDC products.\nnointerp: Means to not do any nearneighbor interpolation but needs that region has been set.\nNSIDC_N and NSIDC_S: Set the s_srs, region, nointerp, nodata appropriate to read the See Ice NSIDC https://nsidc.org/data/polar-stereo/ps_grids.html grids.\ndataset or xyz: If instead of calculating a grid (returned as a GMTgrid type) user wants the x,y,z data intself, use the keywords dataset, or xyz and the output will be in a GMTdataset (i.e. use dataset=true).\n\nTo inquire just the list of available arrays use list=true or gdalinfo=true to get the full file info.\n\nExamples:\n\nG = grid_at_sensor(\"AQUA_MODIS.20020717T135006.L2.SST.nc\", \"sst\", V=true);\n\nG = grid_at_sensor(\"TXx-narr-annual-timavg.nc\", \"T2MAX\", xarray=\"XLONG\", yarray=\"XLAT\", V=true);\n\nG = grid_at_sensor(\"RDEFT4_20101021.nc\", \"sea_ice_thickness\", NSIDC_N=true);\n\n\n\n\n\n","category":"function"},{"location":"#RemoteS.mcari-Tuple{Any, Any, Any}","page":"Index","title":"RemoteS.mcari","text":"MCARI = mcari(green, red, redEdge1; kw...)\n\nor\n\nMCARI = mcari(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)\n\nModified Chlorophyll Absorption ratio index. Daughtery et al. 2000\n\nMCARI = (redEdge1 - red - 0.2 * (redEdge1 - green)) * (redEdge1 / red)\n\n(Sentinel-2 Band 5 (VNIR), Band 4 (Red) and Band 3 (Green)).\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.mndwi-Tuple{Any, Any}","page":"Index","title":"RemoteS.mndwi","text":"MNDWI = mndwi(green, swir2; kw...)\n\nor\n\nMNDWI = mndwi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)\n\nModified Normalised Difference Water Index. Xu2006\n\nMNDWI = (green-swir2) / (green+swir2)\n\nThe first form accepts inputs as matrices, or file names of the data bands.\nThe last form is more versatile but also more complex to describe.\ncube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.\nbands: cubes created with cutcube assign descriptions starting with \"Band1 ...\" an so on the other bands. So when bands is used we search for bands named \"Band'band[k]'\", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.\nlayers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.\nbandnames: When we know the common designation of a band, for example \"Green\", or any part of a band description, for example \"NIR\", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.\n\nKwargs\n\nthreshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN\nclasses: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.\nmask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise\nsave: Use save=\"file_name.ext\" to save the result in a disk file. File format is picked from file extension.\norder | bands_order | rgb: For the GLI, TGI and VARI (RGB) indices, we allow to reorder the bands and change the expected RGB order. Pass in a string, or symbol, with the color order. For example, order=:rbg\n\nwill swap the green and blue components making the result index identify the _reds_ instead of the _greens_.\nNot good for vegetation indices, but potentially useful for other purposes.\n\nIf none of bands, layers or bandnames is provided, we use the default band names shown in the first form.\n\nSee also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.\n\nReturns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.msavi-Tuple{Any, Any}","page":"Index","title":"RemoteS.msavi","text":"MSAVI = msavi(red, nir; kw...)\n\nor\n\nMSAVI = msavi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)\n\nModified soil adjusted vegetation index. Qi 1994\n\nMSAVI = nir + 0.5 - (0.5 * sqrt(pow(2.0 * nir + 1.0, 2) - 8.0 * (nir - (2.0 * red))))\n\nThe first form accepts inputs as matrices, or file names of the data bands.\nThe last form is more versatile but also more complex to describe.\ncube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.\nbands: cubes created with cutcube assign descriptions starting with \"Band1 ...\" an so on the other bands. So when bands is used we search for bands named \"Band'band[k]'\", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.\nlayers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.\nbandnames: When we know the common designation of a band, for example \"Green\", or any part of a band description, for example \"NIR\", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.\n\nKwargs\n\nthreshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN\nclasses: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.\nmask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise\nsave: Use save=\"file_name.ext\" to save the result in a disk file. File format is picked from file extension.\norder | bands_order | rgb: For the GLI, TGI and VARI (RGB) indices, we allow to reorder the bands and change the expected RGB order. Pass in a string, or symbol, with the color order. For example, order=:rbg\n\nwill swap the green and blue components making the result index identify the _reds_ instead of the _greens_.\nNot good for vegetation indices, but potentially useful for other purposes.\n\nIf none of bands, layers or bandnames is provided, we use the default band names shown in the first form.\n\nSee also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.\n\nReturns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.mtci-Tuple{Any, Any, Any}","page":"Index","title":"RemoteS.mtci","text":"MTCI = mtci(red, redEdge1, redEdge2; kw...)\n\nMeris Terrestrial Chlorophyll Index. Clevers and Gitelson 2013, Dash and Curran 2004\n\nMTCI = (redEdge2-redEdge1) / (redEdge1-red)\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.nbri-Tuple{Any, Any}","page":"Index","title":"RemoteS.nbri","text":"NBRI = nbri(nir, swir3; kw...)\n\nor\n\nNBRI = nbri(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)\n\nNormalised Burn Ratio Index. Garcia 1991\n\nNBRI = (nir - swir2) / (nir + swir2)\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.ndrei1-Tuple{Any, Any}","page":"Index","title":"RemoteS.ndrei1","text":"NDREI1 = ndrei1(redEdge1, redEdge2; kw...)\n\nNormalized difference red edge index. Gitelson and Merzlyak 1994\n\nNDREI1 = (redEdge2 - redEdge1) / (redEdge2 + redEdge1)\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.ndrei2-Tuple{Any, Any}","page":"Index","title":"RemoteS.ndrei2","text":"NDREI2 = ndrei2(redEdge1, redEdge3; kw...)\n\nor\n\nNDREI2 = ndrei2(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)\n\nNormalized difference red edge index 2. Barnes et al 2000\n\nNDREI2 = (redEdge3 - redEdge1) / (redEdge3 + redEdge1)\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.ndvi-Tuple{Any, Any}","page":"Index","title":"RemoteS.ndvi","text":"NDVI = ndvi(red, nir; kw...)\n\nor\n\nNDVI = ndvi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)\n\nCompute the NDVI vegetation index. Input can be either the bands file names, or GMTimage objects with the band's data.\n\nNDVI = (nir - red) / (nir + red)\n\nThe first form accepts inputs as matrices, or file names of the data bands.\nThe last form is more versatile but also more complex to describe.\ncube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.\nbands: cubes created with cutcube assign descriptions starting with \"Band1 ...\" an so on the other bands. So when bands is used we search for bands named \"Band'band[k]'\", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.\nlayers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.\nbandnames: When we know the common designation of a band, for example \"Green\", or any part of a band description, for example \"NIR\", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.\n\nKwargs\n\nthreshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN\nclasses: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.\nmask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise\nsave: Use save=\"file_name.ext\" to save the result in a disk file. File format is picked from file extension.\norder | bands_order | rgb: For the GLI, TGI and VARI (RGB) indices, we allow to reorder the bands and change the expected RGB order. Pass in a string, or symbol, with the color order. For example, order=:rbg\n\nwill swap the green and blue components making the result index identify the _reds_ instead of the _greens_.\nNot good for vegetation indices, but potentially useful for other purposes.\n\nIf none of bands, layers or bandnames is provided, we use the default band names shown in the first form.\n\nSee also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.\n\nReturns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.ndwi-Tuple{Any, Any}","page":"Index","title":"RemoteS.ndwi","text":"NDWI = ndwi(green, nir; kw...)\n\nor\n\nNDWI = ndwi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)\n\nNormalized difference water index. McFeeters 1996. NDWI => (green - nir)/(green + nir)\n\nNDWI = (green - nir)/(green + nir)\n\nThe first form accepts inputs as matrices, or file names of the data bands.\nThe last form is more versatile but also more complex to describe.\ncube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.\nbands: cubes created with cutcube assign descriptions starting with \"Band1 ...\" an so on the other bands. So when bands is used we search for bands named \"Band'band[k]'\", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.\nlayers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.\nbandnames: When we know the common designation of a band, for example \"Green\", or any part of a band description, for example \"NIR\", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.\n\nKwargs\n\nthreshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN\nclasses: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.\nmask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise\nsave: Use save=\"file_name.ext\" to save the result in a disk file. File format is picked from file extension.\norder | bands_order | rgb: For the GLI, TGI and VARI (RGB) indices, we allow to reorder the bands and change the expected RGB order. Pass in a string, or symbol, with the color order. For example, order=:rbg\n\nwill swap the green and blue components making the result index identify the _reds_ instead of the _greens_.\nNot good for vegetation indices, but potentially useful for other purposes.\n\nIf none of bands, layers or bandnames is provided, we use the default band names shown in the first form.\n\nSee also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.\n\nReturns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.ndwi2-Tuple{Any, Any}","page":"Index","title":"RemoteS.ndwi2","text":"NDWI2 = ndwi2(nir, swir2; kw...)\n\nor\n\nNDWI2 = ndwi2(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)\n\nNormalized difference water index. Gao 1996, Chen 2005 (also known as Normalized Difference Moisture Index NDBI and LSWI)\n\nNDWI2 = (nir - swir2)/(nir + swir2)\n\nThe first form accepts inputs as matrices, or file names of the data bands.\nThe last form is more versatile but also more complex to describe.\ncube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.\nbands: cubes created with cutcube assign descriptions starting with \"Band1 ...\" an so on the other bands. So when bands is used we search for bands named \"Band'band[k]'\", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.\nlayers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.\nbandnames: When we know the common designation of a band, for example \"Green\", or any part of a band description, for example \"NIR\", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.\n\nKwargs\n\nthreshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN\nclasses: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.\nmask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise\nsave: Use save=\"file_name.ext\" to save the result in a disk file. File format is picked from file extension.\norder | bands_order | rgb: For the GLI, TGI and VARI (RGB) indices, we allow to reorder the bands and change the expected RGB order. Pass in a string, or symbol, with the color order. For example, order=:rbg\n\nwill swap the green and blue components making the result index identify the _reds_ instead of the _greens_.\nNot good for vegetation indices, but potentially useful for other purposes.\n\nIf none of bands, layers or bandnames is provided, we use the default band names shown in the first form.\n\nSee also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.\n\nReturns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.reflectance_surf-Tuple{String}","page":"Index","title":"RemoteS.reflectance_surf","text":"R = reflectance_surf(fname::String, [band::Int, bandname::String, mtl::String, save::String])\n\nComputes the radiance-at-surface of Landsat8 band using the COST model.\n\nfname: The name of either a LANDSAT_PRODUCT_ID geotiff band, or the name of a cube file created with the cutcube function. In the first case, if the companion MTLtxt file is not in the same directory as fname one can still pass it via the mtl=path-to-MTL-file option. In the second case it is mandatory to use one of the following two options.\nband: cubes created with cutcube assign descriptions starting with \"Band 1 ...\" an so on the other bands. So when band is used we search for the band named \"Band N\", where N = band.\nbandname: When we know the common designation of a band, for example \"Green\", or any part of a band description, for example \"NIR\", we can use that info to create a bandname string that will be matched against the cube's bands descriptions. We can use the reportbands function to see the bands description.\nsave: The file name where to save the output. If not provided, a GMTgrid is returned.\n\nReturns a Float32 GMTgrid\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.reportbands-Tuple{Any, Int64}","page":"Index","title":"RemoteS.reportbands","text":"reportbands(in; [layers=Int[]])\n\nor\n\nreportbands(in, layer;)\n\nReport the Bands description of the in input argument. This can be a GMTimage, a GMTgrid or a file name (a String) of a 'cube' file. Normally one made with the cutcube function. When the use conditions of this function are not met, either a warning or an error message (if too deep to be caught as a warning) will be issued.\n\nlayers: When this optional parameter is used, report the description of the bands in the vector layers\nlayer: A scalar with a unique band number. Alternative form to reportbands(in, layers=[layer])\n\nReturns a string vector.\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.sat_scenes-Tuple{Any, String}","page":"Index","title":"RemoteS.sat_scenes","text":"satscenes(track, satname::String)\n\nCompute polygons delimiting AQUA and TERRA scenes.\n\ntrac: Is an orbit computed with sat_tracks at steps of 1 minute (crucial)\nsat_name: The satellite name. At this time only AQUA and TERRA are allowed.\n\nReturns a GMTdataset vector with the polygons and the scene names in the dataset header field.\n\nExample\n\nImagine that orb was obtained with\n\norb = sat_tracks(tle=[tle1; tle2], start=DateTime(\"2021-09-02T13:30:00\"), \tstop=DateTime(\"2021-09-02T13:40:00\"), step=\"1m\");\n\nThe scenes limits (two) are computed with:\n\nDscenes = sat_scenes(orb, \"AQUA\");\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.sat_tracks-Tuple{}","page":"Index","title":"RemoteS.sat_tracks","text":"sat_tracks(; geocentric::Bool=false, tiles::Bool=false, position::Bool=false, kwargs...)\n\nCompute satellite tracks using the TLE, or Two Line Elements set, a data format that contains information about the orbit at a specific epoch of an Earth-orbiting object. It can also calculate polygons arround the scene extents of AQUA and TERRA satellites as well as create the scene names, which provides a mean to direct download that data.\n\nstart: A DateTime object or a string convertable to a DateTime with DateTime(start) specifying the start of the orbit calculation. If omited, current time in UTC will be used.\nduration: Length of time for which the orbit is calculated. Accepts duration in days, hours, minutes or seconds. The default is minutes (100 minutes). To use other units use a string with the value appended with 'D', 'h', 'm' or 's'. e.g. duration=\"55m\" to compute orbit 55 minutes from start\nstep or inc or dt: The time interval at which to compute locations along the orbit. The default unit here is seconds (30 sec) but minutes can be used as well by appending 'm'. e.g. step=\"1m\"\nstop: As alternative to duration provide the end date for the orbit. Same conditions as start\nposition: Computes only first location at the start time. Boolean, use position=true\ngeocentric: Boolean to controls if output is lon,lat,alt,time (the default) or ECEF coordinates + time.\ntle or TLE: a file name with the TLE data for a specific satellite and period. It can also be a two elements string vector with the first and second lines of the TLE file.\ntiles: Compute the scene limits and file names for some satellites. Currently AQUA only.\nsat, SAT or satellite: Name of the satellite to use; choose from (string or symbols) :TERRA, :AQUA. Use only with the tiles option.\n\nReturns\n\nA GMTdataset with the orbit or the scene polygons\n\nExample:\n\nCompute ~one orbit of the AQUA satellite starting at current local time. Note, this will be accurate for the month of September 2021. For other dates it needs an updated TLE.\n\ntle1 = \"1 27424U 02022A 21245.83760660 .00000135 00000-0 39999-4 0 9997\";\ntle2 = \"2 27424 98.2123 186.0654 0002229 67.6025 313.3829 14.57107527 28342\";\norb = sat_tracks(tle=[tle1; tle2], duration=100);\n\nand the orbit track can be visualized with\n\nimshow(orb, proj=:Robinson, region=:global, coast=true)\n\nWARNING: This function depends on the SatelliteToolbox extension that is not loaded by default. Load it with:\n\nusing RemoteS SatelliteToolboxTle SatelliteToolboxPropagators SatelliteToolboxTransformations\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.satvi-Tuple{Any, Any, Any}","page":"Index","title":"RemoteS.satvi","text":"SATVI = satvi(red, swir2, swir3; kw...)\n\nor\n\nSATVI = satvi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)\n\nSoil adjusted total vegetation index. Marsett 2006\n\nSATVI = ((swir1 - red) / (swir1 + red + L)) * (1.0 + L) - (swir2 / 2.0)\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.savi-Tuple{Any, Any}","page":"Index","title":"RemoteS.savi","text":"SAVI = savi(red, nir; kw...)\n\nor\n\nSAVI = savi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)\n\nSoil adjusted vegetation index. Huete 1988\n\nSAVI = (nir - red) * (1.0 + L) / (nir + red + L)\n\nThe first form accepts inputs as matrices, or file names of the data bands.\nThe last form is more versatile but also more complex to describe.\ncube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.\nbands: cubes created with cutcube assign descriptions starting with \"Band1 ...\" an so on the other bands. So when bands is used we search for bands named \"Band'band[k]'\", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.\nlayers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.\nbandnames: When we know the common designation of a band, for example \"Green\", or any part of a band description, for example \"NIR\", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.\n\nKwargs\n\nthreshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN\nclasses: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.\nmask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise\nsave: Use save=\"file_name.ext\" to save the result in a disk file. File format is picked from file extension.\norder | bands_order | rgb: For the GLI, TGI and VARI (RGB) indices, we allow to reorder the bands and change the expected RGB order. Pass in a string, or symbol, with the color order. For example, order=:rbg\n\nwill swap the green and blue components making the result index identify the _reds_ instead of the _greens_.\nNot good for vegetation indices, but potentially useful for other purposes.\n\nIf none of bands, layers or bandnames is provided, we use the default band names shown in the first form.\n\nSee also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.\n\nReturns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.slavi-Tuple{Any, Any, Any}","page":"Index","title":"RemoteS.slavi","text":"SLAVI = slavi(red, nir, swir2; kw...)\n\nor\n\nSLAVI = slavi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)\n\nSpecific Leaf Area Vegetation Index. Lymburger 2000\n\nSLAVI = nir / (red + swir2)\n\nThe first form accepts inputs as matrices, or file names of the data bands.\nThe last form is more versatile but also more complex to describe.\ncube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.\nbands: cubes created with cutcube assign descriptions starting with \"Band1 ...\" an so on the other bands. So when bands is used we search for bands named \"Band'band[k]'\", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.\nlayers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.\nbandnames: When we know the common designation of a band, for example \"Green\", or any part of a band description, for example \"NIR\", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.\n\nKwargs\n\nthreshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN\nclasses: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.\nmask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise\nsave: Use save=\"file_name.ext\" to save the result in a disk file. File format is picked from file extension.\norder | bands_order | rgb: For the GLI, TGI and VARI (RGB) indices, we allow to reorder the bands and change the expected RGB order. Pass in a string, or symbol, with the color order. For example, order=:rbg\n\nwill swap the green and blue components making the result index identify the _reds_ instead of the _greens_.\nNot good for vegetation indices, but potentially useful for other purposes.\n\nIf none of bands, layers or bandnames is provided, we use the default band names shown in the first form.\n\nSee also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.\n\nReturns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.subcube-Tuple{String}","page":"Index","title":"RemoteS.subcube","text":"subcube(cube::String; bands=Int[], bandnames=String[], layers=Int[])\n\nExtracts a subcube from cube with the layers in the bands vector, case in which we will search for bands named \"Band band[k]\", or those whose names correspond (even partially and case insensitive) to the descriptions in bandnames string vector. This means that the options bands and bandnames can only be used in 'cubes' with bands description. The layers option blindly extract the cube planes listed in the layer vector.\n\nReturns a GMTimage\n\nsubcube(cube::Union{GMT.GMTimage{UInt16, 3}, AbstractArray{<:AbstractFloat, 3}}; bands=Int[], bandnames=String[], layers=Int[])\n\nDoes the same but from an already in memory cube. Returns a type equal to the input type. No views, a data copy.\n\nExample\n\nExtracts the Red, Green and Blue layers from a Landsat 8 cube created with cutcube\n\nIrgb = subcube(\"LC08__cube.tiff\", bandnames = [\"red\", \"green\", \"blue\"])\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.tgi-Tuple{GMT.GMTimage{UInt8, 3}}","page":"Index","title":"RemoteS.tgi","text":"TGI = tgi(red, green, blue; kw...)\n\nor (here fname is a .png or .jpg file name)\n\nTGI = tgi(fname::String; kw...)\n\nor\n\nTGI = tgi(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)\n\nTriangular Greenness Index. Hunt et al. 2013\n\nTGI = green - 0.39 * red - 0.61 * blue\n\nThe first form accepts inputs as matrices, or file names of the data bands.\nThe last form is more versatile but also more complex to describe.\ncube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.\nbands: cubes created with cutcube assign descriptions starting with \"Band1 ...\" an so on the other bands. So when bands is used we search for bands named \"Band'band[k]'\", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.\nlayers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.\nbandnames: When we know the common designation of a band, for example \"Green\", or any part of a band description, for example \"NIR\", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.\n\nKwargs\n\nthreshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN\nclasses: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.\nmask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise\nsave: Use save=\"file_name.ext\" to save the result in a disk file. File format is picked from file extension.\norder | bands_order | rgb: For the GLI, TGI and VARI (RGB) indices, we allow to reorder the bands and change the expected RGB order. Pass in a string, or symbol, with the color order. For example, order=:rbg\n\nwill swap the green and blue components making the result index identify the _reds_ instead of the _greens_.\nNot good for vegetation indices, but potentially useful for other purposes.\n\nIf none of bands, layers or bandnames is provided, we use the default band names shown in the first form.\n\nSee also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.\n\nReturns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.train_raster-Tuple{GMT.GItype, Union{String, Vector{<:GMT.GMTdataset}}}","page":"Index","title":"RemoteS.train_raster","text":"model, classes = train_raster(cube::GItype, train::Union{Vector{<:GMTdataset}, String}; np::Int=0, density=0.1)\n\ncube: The cube wtih band data to classify.\ntrain: A vector of GMTdatasets or a file name of one containing the polygons used to train the model. NOTE: The individual datasets MUST have associated an attribute called \"class\" containing the class name as a string. This can be achieved for text data in the form of a GMT multi-segment file (one where segments are separated by the '>' symbol) if the multi-segment separator line contains the text Attrib(class=name)\nnp: Number of points per polygon to be determined by randinpolygon\ndensity: Alternative to np. See also the help of the randinpolygon function.\n\nReturns the trained model and the class names.\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.truecolor-Tuple{Any, Any, Any}","page":"Index","title":"RemoteS.truecolor","text":"Irgb = truecolor(bndR, bndG, bndB)\n\nTake three Landsat8/Sentinel2 UINT16 GMTimages or the file names of those bands and compose an RGB true color image applying automatic histogram stretching.\n\nReturn an UInt8 RGB GMTimage\n\nIrgb = truecolor(cube::GMTImage, bands::Vector{Int})\n\nMake an RGB composition of the 3 bands passed in the vector 'bands' from the layers in the multi-layered GMTimage cube\n\nReturn an auto-stretched UInt8 RGB GMTimage\n\nIrgb = truecolor(cube::String, [bands::Vector{Int}], [bandnames::Vector{String}], [raw=false])\n\nMake an RGB composition of 3 bands from the cube file holding a UInt16 multi-layered array (often created with cutcube) The band selection can be made with bands vector, case in which we will search for bands named \"Band[k]\" or where the bands description contain the contents of bandnames. If none of bands or bandnames is used we search for a made up bandnames=[\"red\", \"green\", \"blue\"].\n\nReturn an auto-stretched UInt8 RGB GMTimage OR a GMTimage{UInt16,3} if the raw option is set to true.\n\nIrgb = truecolor(cube::GMTgrid, [bands|layers::Vector{Int}], [bandnames::Vector{String}], [type=UInt8])\n\nMake an RGB composition of 3 bands from the cube file holding a Float32 multi-layered array. The band selection can be made with bands vector, case in which we will search for bands named \"Band[k]\" or where the bands description contain the contents of bandnames. If none of bands or bandnames is used we search for a made up bandnames=[\"red\", \"green\", \"blue\"].\n\nBy default we scale the bands to 0-255. Use type=UInt16 to scale the bands to 0-65535`. Note that this will matter only for the guessing of the good limits to perform the histogram stretching.\n\nExample:\n\nMake an RGB composite from data in the cube file \"LC08__cube.tiff\"\n\nI = truecolor(\"LC08__cube.tiff\");\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.vari-Tuple{GMT.GMTimage{UInt8, 3}}","page":"Index","title":"RemoteS.vari","text":"VARI = vari(red, green, blue; kw...)\n\nor (here fname is a .png or .jpg file name)\n\nVARI = vari(fname::String; kw...)\n\nor\n\nVARI = vari(cube::Union{String, GMTgrid}; [bands=Int[], bandnames=String[], layers=Int[]], kwargs...)\n\nVisible Atmospherically Resistant Index. Gitelson, A.A., Kaufman, Y.J., Stark, R., Rundquist, D., 2002\n\nVARI = (green - red) / (green + red - blue)\n\nThe first form accepts inputs as matrices, or file names of the data bands.\nThe last form is more versatile but also more complex to describe.\ncube: Is the file name of a 'cube', a multi-layered file normally created with the cutcube function. If this file was created with band descriptions one can use the bands or the bandnames options.\nbands: cubes created with cutcube assign descriptions starting with \"Band1 ...\" an so on the other bands. So when bands is used we search for bands named \"Band'band[k]'\", where band[k] loops over all elements of the bands vector. WARNING: the elements order in the vector must be sorted in increasing wavelength numbers, i.e. like the example for the first form.\nlayers: Use this option when you are certain of the bands order in the cube or the it doesn't have a bands description. The selection will be made with cube[:,:,layer[1]], etc... WARNING: same warn as above.\nbandnames: When we know the common designation of a band, for example \"Green\", or any part of a band description, for example \"NIR\", we can use that info to create a bandnames string vector that will be matched against the cube's bands descriptions.\n\nKwargs\n\nthreshold: When a threshold is provided we return a GMTgrid where vals[ij] < threshold = NaN\nclasses: is a vector with up to 3 elements (class separators) and we return a UInt8 GMTimage with the indices categorized into vals[ij] > classes[1] = 1; vals[ij] > classes[2] = 2; vals[ij] > classes[3] = 3 and 0 otherwise.\nmask: Used together with threshold outputs a UInt8 GMTimage mask with vals[ij] >= threshold = 255 and 0 otherwise If mask=-1 (or any other negative number) we compute instead a mask where vals[ij] < threshold = 255 and 0 otherwise\nsave: Use save=\"file_name.ext\" to save the result in a disk file. File format is picked from file extension.\norder | bands_order | rgb: For the GLI, TGI and VARI (RGB) indices, we allow to reorder the bands and change the expected RGB order. Pass in a string, or symbol, with the color order. For example, order=:rbg\n\nwill swap the green and blue components making the result index identify the _reds_ instead of the _greens_.\nNot good for vegetation indices, but potentially useful for other purposes.\n\nIf none of bands, layers or bandnames is provided, we use the default band names shown in the first form.\n\nSee also https://www.indexdatabase.de/ for a list of indices and the appropriate band names per sensor.\n\nReturns either a Float32 GMTgrid or a UInt8 GMTimage if the mask or classes options are used.\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.RemoteS","page":"Index","title":"RemoteS.RemoteS","text":"Package to perform operations with satellite data. Easy to use in computing true color images with automatic contrast stretch, many spectral indices and processing of MODIS L2 files.\n\n\n\n\n\n","category":"module"},{"location":"#RemoteS.classification_proba-Tuple{GMT.GItype, Any}","page":"Index","title":"RemoteS.classification_proba","text":"I = classification_proba(cube::GItype, model; class_number=1) -> GMTimage\n\nReturns an image with the assigned probabilities when classifying the class number class_number\n\ncube: The cube wtih band data to classify\nmodel: is the model obtained from the train_raster function\nclass_number: is the class number to be classified\n\n\n\n\n\n","category":"method"},{"location":"#RemoteS.read_mtl","page":"Index","title":"RemoteS.read_mtl","text":"readmtl(bandname::String, mtl::String=\"\"; get_full=false)\n\nUse the band_name of a Landsat8 band to find the MTL file with the scene parameters at which that band belongs and read the params needed to compute Brightness temperature, radiance at top of atmosphere, etc. If the MTL file does not lieve next to the band file, send its name via the mtl argument.\n\nThe get_full option makes this function return a tring with contents of the MTL file or nothing if the MTL file is not found.\n\nReturns a tuple with:\n\n(band=band, radmul=radmul, radadd=radadd, radmax=radmax, reflectmul=reflectmul, reflectadd=reflectadd, reflectmax=reflectmax, sunazim=sunazim, sunelev=sunelev, sundis=sunazim, K1=K1, K2=K2)\n\nor a string with MTL contents (or nothing if MTL file is not found)\n\n\n\n\n\n","category":"function"}] }