############################################################### # # Import GPS data from Text file and display it # Version 1 January 13 2005 # # William Ferris # Digital Environmental # wferris@digitalenvironmental.ca # ############################################################### # # This Macro will import GPS or any point data from a comma delimited # text file that has 6 standard fields. # # This text file can have a one line header and the following fields # waypoint - Integer # easting - Integer # northing - Integer # date - Text # symbol - Text # comment - Text # # note is OSX there may be bug in import so make sure to delete the last line in # in the CSV file. # # The limitation of this method is that the georeferencing is taken fromthe first vector # of the first group. # ################################################################### class FILE gpsfile; class DATABASE db; class DBTABLEINFO table; class DBTABLEVAR tablevar; class DBFIELDINFO waypoint,easting,northing,date,symbol,comment; class GRE_GROUP gp,group; class GRE_LAYER layer; class GRE_LAYER_VECTOR vectorlayer; class STYLEOBJECT style; class GEOREF curGeoRef; class Vector GpsVector,V,curVector; class Raster curRaster; string theString$,token$,delimits$,thedate$,thesymbol$,thecomment$,rvcfilename$,objectname$,stylestring$,description$; numeric n,i,thewaypoint,theeasting,thenorthing,therecord,pointnum,recordnum,objectNumber; array numeric ptrecords[1]; ## the delimiter between fields in the text file is a commma delimits$ = ","; ## get the actual text file that contains the data in csv format (commna delimited) gpsfile = GetInputTextFile("c:/default.csv", "Select text file for input", "csv"); # wanted to use GetOutputObject so I could limit it to new objects only but there seems to # be a bug currently in the routine under v7.0 so use GetOutputVector instead. # I had a version which just added it the existing vector but choose to create single unique # vectors for cosmetic and practial reasons. GetOutputVector(GpsVector, "VectorToolKit"); objectNumber = GetObjectNumber(GpsVector); rvcfilename$ = GetObjectFileName(GpsVector); objectname$ = GetObjectName(rvcfilename$,objectNumber); db = OpenVectorPointDatabase(GpsVector); if(TableExists(db,"GPS_Data") == 0) { # create the database for the new point vector db = OpenVectorPointDatabase(GpsVector); table = TableCreate(db,"GPS_Data","Created from imported GPS point locations"); # set it so there is only one element per record (line) table.OneRecordPerElement = 1; # create the new fields for the database. waypoint = TableAddFieldInteger(table,"Waypoint",4); easting = TableAddFieldInteger(table,"Easting",6); northing = TableAddFieldInteger(table,"Northing",7); date = TableAddFieldString(table,"Date",15,15); symbol = TableAddFieldString(table,"Symbol",15,15); comment = TableAddFieldString(table,"Comment",254,50); } # get the header line to determine the number of fields # and this will move the next line read to the actual data theString$ = fgetline$(gpsfile); # this counts the number of comma's which gives us the number of fields # so no comma's in the comment field! n = NumberTokens(theString$,delimits$); #### should put an error routine in here if there are more than 6 # this works if it is a new vector or if we are adding points to an existing vector pointnum = NumVectorPoints(GpsVector) + 1; # continue reading the text file until the end of the file is reached while (!feof(gpsfile)) { # get the next line theString$ = fgetline$(gpsfile); for i = 1 to n { token$ = GetToken(theString$,delimits$,i); if (i == 1) then { thewaypoint = StrToNum(token$); } if (i == 2) then { theeasting = StrToNum(token$); } if (i == 3) then { thenorthing = StrToNum(token$); } if (i == 4) then { thedate$ = token$; # once we get to the date field we have the point x and y location so we can # create a new point which we are going to attach the database record to VectorAddPoint(GpsVector,theeasting,thenorthing); } if (i == 5) then { thesymbol$ = token$; } if (i == 6) then { thecomment$ = token$; } } # we create a new record and the associated table data recordnum = TableNewRecord(table,thewaypoint,theeasting,thenorthing,thedate$,thesymbol$,thecomment$); ptrecords[1] = recordnum; # now we attach this data string to the point we created earlier TableWriteAttachment(table,pointnum,ptrecords,1,"point"); pointnum = pointnum + 1; } fclose(gpsfile); CloseVector(GpsVector); # always a good idea to validate your vector after creating it. VectorValidate(GpsVector); # Get the name of the first group and cycle through them to find out if # the 'Imported GPS Data' group is already present in the layout. group = Layout.FirstGroup; while (group.Name != "" && group.Name != "Imported GPS Data") { group = group.NextGroup; } # if the group hasn't been already added to the layout then create it. if (group.Name == "") { gp = GroupCreate("Imported GPS Data",Layout); # attach the new group to the first group so it will display properly GroupAttachHorizontal(gp,"Geographic",0,"Group","Geographic",Layout.FirstGroup); GroupAttachVertical(gp,"Geographic",0,"Group","Geographic",Layout.FirstGroup); } else { # if it already exists get its 'name' gp = group; } # get the object we are going to use for the GEOREF object from the first group layer = Layout.FirstGroup.FirstLayer; # now add our newly created vector to our new group that we just created GroupQuickAddVector(gp,rvcfilename$, objectNumber); # open the vector that we created so we can add georeferencing and sytles vectorlayer = gp.ActiveLayer; DispGetVectorFromLayer(V,vectorlayer); while(layer.Type != "Vector" && layer.NextLayer != 0) { layer = layer.NextLayer; } DispGetVectorFromLayer(curVector,layer); CopySubobjects(curVector,V,"GEOREF"); # we set the vector to use a style object and set it to use a style script # to display the points # the style object is just one from the standard styles available from MIPs # in the standard install. Copy it over to the RVC project you are going to # use the import script on. style = OpenStyleObject(rvcfilename$,"Basic"); vectorlayer.StyleObject = style; vectorlayer.Point.StyleMode = "ByScript"; # get the style script for the point symbols, remember must be in the # same directory as the RVC. I created the style script previously and # saved it. remember changes to the style script will affect only new # imports not the pre-existing ones. stylestring$ = ScriptResourceReadFull("point_symbols.qry"); vectorlayer.Point.Script = stylestring$; # when I figure out how to do this I will add automatic data tip setting #vectorlayer.ShowDataTips = 1; # now that we have everything let us zoom to the new layer extents ViewZoomToLayer(View,vectorlayer); # close the vector we created and any other objects we opened CloseVector(V); # write the layout with the new group back to the RVC, when you next open the # layout object it will be there with the points you imported. LayoutWrite(Layout,rvcfilename$,Layout.Name,"Field GPS data added");