[INTERNAL] One way to bring TeraScan TDF data into ENVI
Anonym
While ENVI does not currently support direct reading of TeraScan TDF data, it is possible to bring TeraScan data into ENVI programmatically. This Help Article discusses the necessary steps.
The TeraScan TDF format is a fully programmable API that is very similar in structure to other hierarchical data formats like HDF and CDF. ENVI cannot currently ingest TDF files directly, but there is an available workaround: The TDF-formatted data can be exported via the TeraScan system to a delimited ASCII file with each line in the file following this format:
X Location | Y Location | Band 1 | Band 2 | Band 3 | Band 4 | Band 5 | Latitude | Longitude
The above example (and the code below) is for 5-band AVHRR data, but the general format should be the same regardless of the number of bands. The challenge is to take these ASCII data and turn them into a georeferenced image that can be used within ENVI. The commented example code covers everything that needs to take place, but an overview of the entire process can be found below:
- The ASCII data are read into an IDL array.
- Two new arrays are built, based on the dimensions of the original image, to hold the spectral and spatial data for the image
- The spectral and spatial data are retrieved one pixel at a time (one text line at a time) and placed in the correct image X/Y locations in the new arrays. These arrays are written out to ENVI format image files.
- The spatial data image is used to create a Geographic Lookup Table (GLT) so that the spectral data can be georeferenced using the native sensor input geometry.
- The GLT is applied to the spectral data file to create a georeferenced ENVI format image file.
Code example:
PRO create_georef_envi_file_from_tdf_ascii
compile_opt idl2
;Specify input file. This example was built for 5-band
;AVHRR data.
filename = dialog_pickfile(title='Select ASCII input file')
if filename eq '' then return
;Specify output path
output_dir = dialog_pickfile(title='Select output directory', /directory)
if output_dir eq'' then return
;Read in delimited ASCII data. For this program to work, the data must
;be outputted from the TeraScan system in the following format:
; X Location | Y Location | Band 1 | Band 2| Band 3| Band 4| Band 5| Latitude | Longitude
envi_read_cols, filename, data
;Pass data to a pointer. Depending on the size of the input file, this process could
;take up a lot of system memory.
pdata = ptr_new(data, /no_copy)
;Obtain data array dimensions
dimensions = size(*pdata, /l64, /dimensions)
;Use max function to figure out the number of samples and lines in the image
x_extent = max((*pdata)[0,*])
y_extent = max((*pdata)[1,*])
;Create BIP container array for image data
data_array = fltarr(x_extent, y_extent, 5)
;Create BIP container array for geographic data
lat_lon_array = fltarr(x_extent, y_extent, 2)
;Create array to hold one line of data from ASCII file
data_line = fltarr(1,9)
for i=0LL, dimensions[1]-1 do begin
;Grab line of data
data_line = (*pdata)[*,i]
;Figure out what pixel the data relate to
pixel_location = [data_line[0]-1,data_line[1]-1]
;Retrieve spectral data for that pixel
pixel_data = transpose(data_line[2:6])
;Place spectral data in correct pixel location in container array
data_array[pixel_location[0], pixel_location[1],*] = pixel_data
;Grab geographic data for the pixel
geo_data = transpose(data_line[7:8])
;Place geographic data in correct pixel location in container array
lat_lon_array[pixel_location[0], pixel_location[1],*] = geo_data
endfor
;Clear data from memory
ptr_free, pdata
;Create ENVI files for the spectral and spatial data. The spectral file has five bands, the
;spatial file has two (latitude, longitude). NO_COPY keyword is set to reduce the risk of
;a memory allocation error.
envi_write_envi_file, data_array, bnames=['Band 1','Band 2','Band 3,','Band 4','Band 5'], $
out_name=output_dir+path_sep()+file_basename(filename)+'_envi.img', r_fid=data_fid, $
/no_copy
envi_write_envi_file, lat_lon_array, bnames=['Latitude (Y)', 'Longitude (X)'], $
out_name=output_dir+path_sep()+file_basename(filename)+'_geo.img', r_fid=geo_fid, $
/no_copy
;Obtain basic information about the spectral data file
envi_file_query, data_fid, ns=ns, nl=nl, nb=nb
;Create input and output map projections for the spectral data. In this example, both are
;Geographic Lat/Lon
input_proj = envi_proj_create(/geographic)
output_proj = envi_proj_create(/geographic)
;Create a Geographic Lookup Table (GLT) for the spectral data.
envi_doit, 'envi_glt_doit', dims=[-1, 0, ns-1, 0, nl-1], i_proj=input_proj, o_proj=output_proj, $
out_name=output_dir+path_sep()+file_basename(filename)+'_glt.img', x_fid=geo_fid, $
x_pos=1, y_fid=geo_fid, y_pos=0, r_fid=glt_fid
;Apply GLT to spectral data, output georeferenced file.
envi_doit, 'envi_georef_from_glt_doit', fid=data_fid, glt_fid=glt_fid, $
pos=lindgen(nb), out_name=output_dir+path_sep()+file_basename(filename)+'_glt_georef.img'
end