SOILDATA.sml

  Download

More scripts: SML Fundamentals

Syntax Highlighing:

comments, key words, predefined symbols, class members & methods, functions & classes
            
# SOILDATA.sml
# Sample script for tutorial "Writing Scripts with SML".
# Demonstrates extracting attribute information from geospatial data, writing it to
# an external file, and launching that file in another application.
# Script processes a vector soil map to determine the soil types, the cumulative
# area for each soil type in acres, and creates a Comma-Separated Values (CSV)
# text file listing the soil symbol, acres, map unit identifier, and soil description.
# The input vector must have polygons and a polygon database table "MAPUNIT".
clear();
numeric i;			# loop counter
# get the input vector object
class RVC_VECTOR SoilVec;
GetInputVector(SoilVec);
### check that this is an appropriate vector object for this script
if (SoilVec.$Info.NumPolys == 0) 	# check that the vector has polygons
	{
	PopupMessage("Vector must contain polygon elements to use this script. Exiting script.");
	Exit();
	}
# check if polygon table "MAPUNIT" exists.	
class RVC_DBASE_POLYGON polyDB;
polyDB.OpenAsSubobject(SoilVec, "Read");
if (polyDB.IsTableValid("MAPUNIT")  == 0 )
	{
	PopupMessage("Selected vector must include a polygon table named 'MAPUNIT'. Exiting now.");
	Exit();
	}
# check if POLYSTATS table exists; if not, make one.
if (polyDB.IsTableValid("POLYSTATS") == 0 )
	{
	VectorToolkitInit(SoilVec);
	VectorUpdateStdAttributes(SoilVec);	
	}
# prompt user for name of output CSV file; open file and write header line
class STRING dfltName$ = _context.ScriptDir + "/outfile";
class STRING outfileName$ = GetOutputFileName(dfltName$, "Choose output CSV file:", "csv");
class FILE outfile = fopen(outfileName$, "w");
fprint(outfile, "musym,acres,muid,muname");
numeric polyarea;					# area of current polygon from POLYSTATS table
numeric polynumHash[];		# hash to store element number of first polygon for each soil type
numeric soilAreaHash[];		# hash to store areas for different soil types
class STRING soilkey$;			# key to hash entries	
class STRINGLIST keylist;	# list of soil types (keys) gotten from soilAreaHash
# loop through soil polygons to get areas from POLYSTATS table;
# use HASH to keep track of soil types and sum areas for polygons of same soil type
for i = 1 to SoilVec.$Info.NumPolys 
	{
	soilkey$ = SoilVec.Poly[i].MAPUNIT.musym$;
	polyarea = SoilVec.Poly[i].POLYSTATS.Area;
	# add area of current polygon to value already stored in soil area hash for that soil; 
	# new keys are added automatically to the hash; ignore water polygons with no record in MAPUNIT table
	if (soilkey$ <> "") then
		soilAreaHash[soilkey$] += polyarea;
	}
# get list of soilAreaHash keys as a stringlist to loop through them, and sort alphabetically
keylist = soilAreaHash.GetKeys();
keylist.Sort();
numeric areaScale = GetUnitConvArea("square meters", "acres");	# scale for converting areas to acres
class STRING musym$, muid$, muname$;
numeric recordnum;
# get old-style table info for the MAPUNIT table for record search
class DBTABLEINFO mapunitTbl;
mapunitTbl = TableGetInfo(SoilVec.poly.MAPUNIT);
# loop through keys by numeric position in stringlist (starting with 0)
for i = 0 to keylist.GetNumItems() -1
	{
	musym$ = keylist.GetString(i);		# soil identifier	
	polyarea = soilAreaHash[musym$] * areaScale;		# get area for soil type and convert to acres
	# get muid and soil name from field in MAPUNIT table
	recordnum = TableKeyFieldLookup(mapunitTbl, "musym", musym$);
	muid$ = SoilVec.Poly.MAPUNIT[recordnum].muid$;
	# the numname values contain commas, so must be enclosed in double quotes for use in CSV file
	muname$ = "\"" + SoilVec.Poly.MAPUNIT[recordnum].muname$ + "\"";
	# write values to a line in the output CSV file
	fprintf(outfile, "%s,%.2f,%s,%s\n", musym$, polyarea, muid$, muname$);
	}
# close the output CSV file and open it in registered spreadsheet program
CloseVector(SoilVec);
fclose(outfile);
RunAssociatedApplication(outfileName$);
print("Done.");