Syntax Highlighing:
comments, key words, predefined symbols, class members & methods, functions & classes
# DB_WRITE1.SML
# 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;
clear();
PopupMessage("Select / CB_DATA / CB_SOILS.RVC / CBSOILS_Lite" );
### Get input vector object with polygons.
GetInputVector(VectIn);
### Get georeference parameters for input vector.
class RVC_GEOREFERENCE georefV;
VectIn.GetDefaultGeoref(georefV);
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.SetName("Georeference");
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.SetImplied();
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 );
++pointnum;
# 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 );
print("Done.");
# End