home products news downloads documentation support gallery online maps resellers search
TNTmips Downloads Menu

HOME

CONTACT US

CURRENT RELEASE
  TNT 2013

DEVELOPMENT VERSION
  TNT 2014

TNTmips Pro
PRIOR RELEASES
  TNT 2012

FREE SOFTWARE
  TNTmips Free
  TNTatlas
  TNTsdk

MORE DOWNLOADS
  HASP Key Driver
  Screen Recorder
  TNT Language Kits
  Sample Geodata
  TNT Scripts

DOCUMENTATION
  TNTmips Tutorials
  Tutorial Datasets
  Technical Guides
  Scripts
  Quick Guides

MORE INFO
  Download FAQs
  FTP
  Download Managers
  Find Reseller

SITE MAP


NETWORK1.sml


### 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");



Back Home ©MicroImages, Inc. 2013 Published in the United States of America
11th Floor - Sharp Tower, 206 South 13th Street, Lincoln NE 68508-2010   USA
Business & Sales: (402)477-9554  Support: (402)477-9562  Fax: (402)477-9559
Business info@microimages.com  Support support@microimages.com  Web webmaster@microimages.com

25 March 2009

page update: 26 May 11