X
28 Rate this article:
No rating

[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