NETWORK1.sml

  Download

More scripts: Advanced

Syntax Highlighing:

comments, key words, predefined symbols, class members & methods, functions & classes
            
### NETWORK1.SML
### script to use network analysis on a road network (lines in vector Roads)
### to find short route between farm gates (points in vector Farms) and 
### processing plants (points in vector Plants).  Farm gate and plant points do
### not fall exactly on road lines.  Input vectors for Roads and Farms are copied to
### a selected output file for modification.
 
### For each farm gate point, the script adds a node at the closest point on the
### closest road line and keeps track of these nodes in an array that associates
### them with the correct farm.  A new table for nodes in the Road vector also
### records the farm number for each added nodes  Nodes are similarly added and
### attributed for each of the processing plants.  
### The shortest distance between each farm and processing plant is then
### calculated using network analysis functions.  The script adds two
### new tables to the point database of the Farms vector: one with records
### attached to each point that list the distance to each of the processing plants
### and another that provides the geographic coordinates of each processing plant
### in the same coordinate system used by the Farms object. 
### Updated 8 March 2006 - DRB
### -Now handles case where Farm and Plant share the same node in the roads vector
### Variable Declarations
vector FarmsIn, Plants, RoadsIn;
vector Farms, Roads;
class GEOREF farmgeo, tempgeo, plantgeo;
numeric numPoints;
numeric numFarms;
numeric numPlants;
numeric numLines;
numeric i, j;				# counters for processing loops
numeric tempx;				# x coordinate of farm gate or processing plant
numeric tempy;				# y coordinate of farm gate or processing plant
numeric linenumber;		# element number for line closest to current point
numeric a, b;				# map coordinates of closest point on closest line
numeric distance; 
class DATABASE db;						# handle for Farms point database
class DBTABLEINFO tinfo1, tinfo2;	# handles for new tables in Farms point database
class DATABASE dblines;					# handle for road lines database
class DATABASE dbnodes;					# handle for road node database
class DBTABLEINFO nftable, nptable;	# handles for new tables in road node database
######## Program ########
clear();  		# clear console
############################################################
### Get input vector objects and the filename for output file 
############################################################
GetInputVector( FarmsIn );
GetInputVector( Plants ); 
GetInputVector( RoadsIn );
### check for LINESTATS table in Roads line database and 
### if not present create prompt user to create one and exit.
dblines = OpenVectorLineDatabase( RoadsIn );
if ( !TableExists(dblines, "LINESTATS" ) ) {
	PopupMessage("Missing LINESTATS table. \nCompute Standard Attributes for Roads vector before running script." );
	Exit();
	}
### copy FarmsIn to output file and open copy Farms initialized for modification
### with VectorToolkit
string srcfilename$, destfilename$, objName$; 
numeric srcObjectNum;
destfilename$ = GetOutputFileName("", "Select an output Project File:", "rvc");
CreateProjectFile(destfilename$, "output from network1.sml");
srcfilename$ = GetObjectFileName( FarmsIn );
srcObjectNum = GetObjectNumber( FarmsIn );
objName$ = GetObjectName( srcfilename$, srcObjectNum );
CopyObject( srcfilename$, srcObjectNum, destfilename$ );
OpenVector( Farms, destfilename$, objName$, "VectorToolkit" );
CloseVector( FarmsIn );
### copy RoadsIn to output file and open copy Roads initialized for modification
### with VectorToolkit
srcfilename$ = GetObjectFileName( RoadsIn );
srcObjectNum = GetObjectNumber( RoadsIn );
objName$ = GetObjectName( srcfilename$, srcObjectNum );
CopyObject( srcfilename$, srcObjectNum, destfilename$ );
OpenVector( Roads, destfilename$, objName$, "VectorToolkit" );
CloseVector( RoadsIn );
### get georeference information for each vector
farmgeo = GetLastUsedGeorefObject( Farms );
tempgeo = GetLastUsedGeorefObject( Roads );
plantgeo = GetLastUsedGeorefObject( Plants );
#########################################################
### create new point database tables in Farms vector
#########################################################
### create new table to hold processing plant locations
db = OpenVectorPointDatabase(Farms);
numeric recordnumber;
Array numeric records[1];
tinfo1 = TableCreate(db,"Plant_Num","Created by SML script");
TableAddFieldInteger( tinfo1, "Plant", 3 );
TableAddFieldFloat( tinfo1, "xcoord", 25, 6 );
TableAddFieldFloat( tinfo1, "ycoord", 25, 6 );
### create new table to hold distance to each processing plant
string tablename$  = "Plant_Dist";
tinfo2 = TableCreate( db, tablename$, "Created by SML Script" );
TableAddFieldInteger( tinfo2, "Plant", 3 );
class DBFIELDINFO the_field;
the_field = TableAddFieldFloat( tinfo2, "Net_Dist", 25, 6 );
the_field.UnitType = "Distance";
the_field.Units = "kilometers";
#########################################################
### create new node database tables in Roads vector
#########################################################
dbnodes = OpenVectorNodeDatabase( Roads );
### create new table to hold Farm number for new farm gate nodes
nftable = TableCreate( dbnodes, "FarmGates", "Farm gate node info" ); 
TableAddFieldInteger( nftable, "FarmNum", 7 );
### create new table to hold Plant number for plant nodes
nptable = TableCreate( dbnodes, "Plants", "Plant info" );
TableAddFieldInteger( nptable, "PlantNum", 9 );
##########################################################
### process Farm points and add nodes to lines
##########################################################
numFarms = NumVectorPoints( Farms );
printf( "The number of farms is %d\n", numFarms );
Array numeric farms[numFarms];		# array to hold node number for each farm gate;
												# array index = element number of farm gate point
for i = 1 to numFarms {
	SetStatusMessage( sprintf( "Processing point %d of %d of farms",i,numFarms ) );
	### get object coordinate of farm gate point and transform to map coordinates
	tempx = Farms.point[i].Internal.x;
	tempy = Farms.point[i].Internal.y;
	GeorefTrans( farmgeo, tempx, tempy, tempgeo, tempx, tempy );
	### find line closest to point and closest point on that line and add node
	linenumber = FindClosestLine( Roads, tempx, tempy );
	ClosestPointOnLine( Roads, linenumber, tempx, tempy, a, b );
	VectorAddNode( Roads, a, b, 1 );
	### update farm gate array
	farms[i] = FindClosestNode( Roads, a, b );
	### add record to FarmGates node table in Roads vector
	recordnumber = TableNewRecord( nftable, i );
	records[1] = recordnumber;
	TableWriteAttachment( nftable, farms[i], records, 1 );
	}
#######################################################
### process plant points and add nodes to lines
#######################################################
numPlants = NumVectorPoints( Plants );
printf( "The number of plants is %d\n",numPlants );
Array numeric plants[numPlants];		# array to hold node number for each processing plant;
for i = 1 to numPlants {
	SetStatusMessage( sprintf( "Processing point %d of %d of plants", i, numPlants ) );
	### get object coordinate of processing plant point and transform to map coordinates
	tempx = Plants.point[i].Internal.x;
	tempy = Plants.point[i].Internal.y;
	GeorefTrans( plantgeo, tempx, tempy, tempgeo, tempx, tempy );
	### find line closest to point and closest point on that line and add node
	linenumber = FindClosestLine( Roads, tempx, tempy );
	ClosestPointOnLine( Roads, linenumber, tempx, tempy, a, b );
	VectorAddNode( Roads, a, b, 1 );
	### update processing plant array
	plants[i] = FindClosestNode( Roads, a, b );
	### add record to table Plant_Num table in Farms vector
	recordnumber = TableNewRecord( tinfo1, i, tempx, tempy );
	### add record to Plants node table in Roads vector
	recordnumber = TableNewRecord( nptable, i );
	records[1] = recordnumber;
	TableWriteAttachment( nptable, plants[i], records, 1 );
	}
#VectorValidate( Roads );
VectorUpdateStdAttributes( Roads );
CloseVector( Roads );  				# close road vector
#########################################################
### perform network analysis on road vector
#########################################################
class Network net;
class Route route;
class MultiRoute multiroute;
numeric imp;						# impedance for road line = line length
string report$;					# string for network route report
### initialize vector for network analysis
string filename$ = GetObjectFileName( Roads );
net = NetworkInit( filename$, GetObjectName( filename$, GetObjectNumber( Roads ) ) );
NetworkSetDefaultAttributes( net );
### process road lines to set impedance in each direction from line length
numLines = NumVectorLines( Roads );
for i = 1 to numLines {
	imp = ( Roads.line[i].LINESTATS.Length );
	NetworkLineSetImpedance( net, i, imp, "FromTo" );
	NetworkLineSetImpedance( net, i, imp, "ToFrom" );
	}
### perform multiroute analysis
numeric total = numFarms * numPlants;
numeric count = 1;
for j = 1 to numPlants {
	printf( "Plant %d\n", j );
	SetStatusMessage( sprintf( "Calculating all routes from plant %d of %d", j, numPlants ) );
	NetworkCalculateMultiRoute( net, plants[j], farms, numFarms, multiroute );
	for i = 1 to numFarms {
		SetStatusMessage( sprintf( "Calculating route %d of %d", count, total ) );
		count += 1;
		if (plants[j] == farms[i]) {
			printf( "Plant %d is at the same location as farm %d\n", j, i);
			### set distance to 0 and update plant distance table in Farms vector
			recordnumber = TableNewRecord( tinfo2, j, 0 );
			records[1] = recordnumber;
			TableWriteAttachment( tinfo2, i, records, 1 );
		} else {
			printf( "Route from plant %d to farm %d\n", j, i );
			NetworkMultiRouteGetRoute( multiroute, farms[i], route );
			report$ = NetworkRouteGetReport( route );
			### get distance and update plant distance table in Farms vector
			distance = StrToNum( GetToken( report$, " ", 18 ) );
			recordnumber = TableNewRecord( tinfo2, j, distance / 1000 );  # m / 1000 = km
			records[1] = recordnumber;
			TableWriteAttachment( tinfo2, i, records, 1 );
			NetworkRouteClose( route );
			}
		}
	NetworkMultiRouteClose(multiroute);
	}
NetworkClose(net);
CloseVector( Farms );
CloseVector( Roads );
CloseVector( Plants );
printf("Script Ran to Completion");