More scripts: Database

Syntax Highlighing:

comments, key words, predefined symbols, class members & methods, functions & classes
# Sample script for tutorial "Writing Scripts with SML".
# Illustrates creating database table, fields,
# and attaching records using DATABASE class and functions.
# version 19 November 2009
# Script uses vector object CBSOILS_Lite as input. It creates
# an output vector with a point at the centroid position of
# each soil polygon in the input. These points are attributed
# with selected values from the input Class, DESCRIPTN, and
# YIELD tables.
# Some records in the input CBSOILS_Lite Class table are attached
# to multiple polygons; there are no duplicate records in the Class table.
# The script maintains this structure in the output vector by iterating 
# through the records in the input Class table to get the
# desired attribute from this table and from related records
# in the other input tables, and creating a record in the output
# vector point database with these values.  For each Class
# record the script also gets the list of attached soil polygons
# and iterates through these to create a corresponding centroid
# point in the output vector and attach the current soil data record
# to it.
### Declarations
class RVC_VECTOR VectIn, VectOut;
PopupMessage("Select / CB_DATA / CB_SOILS.RVC / CBSOILS_Lite" );
### Get input vector object with polygons.
### Get georeference parameters for input vector.
printf("VectIn Coordinate Reference System = %s\n", georefV.GetCoordRefSys().Name);
### Get transformation from object to map coordinates for the input vector
class TRANS2D_MAPGEN transObjToMap;
georefV.GetTransParm(transObjToMap, 0, georefV.GetCalibModel() );
### Open the polygon database in the input vector object
class DATABASE polydb;					# handle for polygon database.
polydb = OpenVectorPolyDatabase( VectIn );
# Get information about the "CLASS" polygon table;
# Will need to iterate through records in this table to find attached polygons.
class DBTABLEINFO classTbl;
classTbl = TableGetInfo( VectIn.poly.CLASS );
# Get information about "DESCRIPTN" polygon table;
# This is needed later to check if attached records exist.
class DBTABLEINFO descriptn;			# handle for DESCRIPTN table.
descriptn = TableGetInfo( VectIn.poly.DESCRIPTN );
### Get new output vector object initialized for use with
### with the Vector Toolkit, and create implied 
### georeference using parameters from input vector.
GetOutputVector( VectOut, "VectorToolkit,Planar" );
# set name and description for a georeference subobject of the output vector
class RVC_DESCRIPTOR descriptor;
descriptor.SetDescription( sprintf("Implied georeference to %s", georefV.GetCoordRefSys().Name) );
# set up georeference for the output vector
class RVC_GEOREFERENCE georefOut;
georefOut.SetCoordRefSys(georefV.GetCoordRefSys() );
georefOut.Make(VectOut, descriptor);
printf("VectOut Coordinate Reference System = %s\n", georefOut.GetCoordRefSys().Name);
# Create point database for VectOut.
class DATABASE pdb;							# handle for point database
pdb = OpenVectorPointDatabase( VectOut );
# Create blank table "SoilTypes" in point database.
class DBTABLEINFO soiltype;				# handle for table
soiltype = TableCreate(pdb,"SoilTypes","Table created by SML script");
soiltype.OneRecordPerElement = 1;  		# set attachment type for records
# Create string field "SYMBOL" in "SoilTypes".
class DBFIELDINFO symbol;					# handle for field
symbol = TableAddFieldString(soiltype,"SYMBOL",6,6);
# Create string field "SOIL" in "SoilTypes".
class DBFIELDINFO soil;						# handle for field
soil = TableAddFieldString(soiltype,"SOIL",80,80);
# Create integer field "WHEAT_YLD" in "SoilTypes".
class DBFIELDINFO wheat;					# handle for field
wheat = TableAddFieldInteger(soiltype,"WHEAT_YLD",10);
array numeric polyrecords[1]; 	# array to hold polygon record number
array numeric ptrecords[1];		# array to hold point record number for attachment.
numeric i, j;						# counters for processing loop
class STRING name$;				# value for Name field in the DESCRIPTN table
numeric wheatnum;					# value for WHEAT field in the YIELD table
class STRING symbol$;			# value for Class field in the CLASS table
numeric numAttached;				# number of polygons attached to the current CLASS table record
array numeric polyArray[10];		# array of polygon element numbers attached to current CLASS table record
numeric polynum;					# number of current attached polygon
class POINT2D pt;					# coordinates of the polygon centroid
numeric pointnum;					# counter for number of points added to outut vector
numeric recordnum;				# record number created by TableNewRecord() function call
# Main processing loop
# Loop through the records in the CLASS polygon table and read value from Class field.
for i = 1 to classTbl.NumRecords
	# get the value for the Class string field for the ith record in the CLASS table
	symbol$ = VectIn.poly.CLASS[i].Class$;
	# get list of polygons that the current CLASS record is attached to.
	numAttached = TableGetRecordElementList(classTbl, i, polyArray);
	printf("record = %d, number polys attached = %d\n", i, numAttached);
	polynum = polyArray[1];		# get number of first attached polygon to get remaining attributes needed
	# polygons in WATER class don't have records in the
	# DESCRIPTN and YIELD tables so check for attached
	# record before trying to read values.
	if (TableReadAttachment( descriptn, polynum, polyrecords ) > 0 ) {
		name$ = VectIn.poly[polynum].DESCRIPTN.NAME$;
		wheatnum = VectIn.poly[polynum].YIELD.WHEAT; 
	else {
		name$ = "Water body";
		wheatnum = 0;
	printf("class = %s, name = %s, yield = %d\n", symbol$, name$, wheatnum);
	# Create new record in SoilType table with current field values.
	recordnum = TableNewRecord( soiltype, symbol$, name$, wheatnum );
	ptrecords[1] = recordnum;
	# loop through the attached polygons to create a point for each and attach
	# to each the point record just created.
	for j = 1 to numAttached
		polynum = polyArray[j]; # get current polygon element number from array
		# centroid position from POLYSTATS table in object coordinates
		pt.x = VectIn.poly[polynum].POLYSTATS.CentX;
		pt.y = VectIn.poly[polynum].POLYSTATS.CentY;
		# transform point coordinates to map coordinates
		pt = transObjToMap.ConvertPoint2DFwd(pt);
		VectorAddPoint( VectOut, pt.x, pt.y );
		# Attach the record to current point element.
		TableWriteAttachment( soiltype, pointnum, ptrecords, 1, "point" );
		} # end of loop through attached polygons 
	printf("Attached record to %d points.\n", numAttached);
	}	# end of loop through records in CLASS table
VectorValidate( VectOut );
CloseVector( VectOut );
# End