Merging Internet information with NIMA geospatial data to create answers in a short timeframe. Arcview allows NIMA geospatial analysts the ability to answer an issue quickly. Arcview processes NIMA geospatial information to answer questions within a two hour turnaround (from start, to posting the answer on the internet). The ArcView extensions, along with the ability to write Avenue scripts, allow for quick import of geospatial data and collateral information. Once imported the data is easily stripped or instensified using collateral sources via the Internet.
The problem is the ability to use the data from the Internet quickly and easily. Usually the geographic information is not saved in a clean text tab-delimited or *dbf format. Also, the coordinates or information are intermingled with other textual data within a report. Therefore, there is a need to be able to strip the needed information out in order to add as an 'add event theme.' The other problem is the ability to covert a text file into a text, tab-delimited, file. I will describe a process to convert and plot a text file, into 20000 geolocated attributed features, within two hours.
Merge internet or other information with NIMA geospatial data to answer an issue within a two hour turnaround (from start, to posting on the internet) .
a. The textual data file must contain geographic coordinates in an ArcView usable format.
b. Obtaining and using NIMA geospatial information.
a. Use "Word" processing software.
b. Use ArcView Extensions.
c. Use ArcView scripts.
a. The textual data file must contain geographic coordinates in an ArcView usable format.
There are two types of textual data files. Internet pages saved to text and text files. Either source may contain geographic coordinates and relevant material within the body. This makes the portrayal of data nearly impossible to plot in ArcView unless the files are edited into a Tab-delimited or ArcView usable text file format.
b. Obtain NIMA geospatial data. The various format types are...
File formats and file sizes are some concerns / problems to be aware of when obtaining NIMA geospatial data. First, the transmission over the internet of geospatial data is in the format of a gunzip, tar, zip, or compressed tar file,*.gz, *.tar, *ZIP, and *tar.Z, respectively. The size of the compressed files range between 3 Megabytes to 50 Megabytes. Therefore, transmission send and receive time is between 1 minute to 1.5 hours per download. A helpful hint is to download the minimal amount of files necessary to answer your issue. For example, use VMAP data to portray a similar ADRG scene. The advantage of VMAP data is smaller file size, kilobytes (vector file) versus megabytes (raster file). Second, once the geospatial data is downloaded the native NIMA geospatial data format and size may be of concern. Does your GIS software read NIMA geospatial data formats raster product format, imagine, vector product format, and DTED, *.rpf, *img, *vpf, *dt1, respectively? Is your hardware able to handle the size of the geospatial data ranging from 3 kilobytes to >500 Megabytes? Both questions may add 10 minutes to hours in processing the data to a usable GIS format.
If the GIS software reads NIMA geospatial data, i.e. ArcView 3.1, timelines are reduced. The useful ArcView 3.1 delivered extensions are ADRG Image support, CADRG Image Support (note, I've had to turn on both the CADRG and the ADRG extensions inorder to read CADRG files), and CIB Image Support. A useful extension found in user groups or on the Esri "GIS Defense Resource Kit" CD is DTED. Below is a brief description of the use of the DTED extension.
Load or place the DTED extension into the ArcView/Ext32 directory.
Locate or Load the DTED CD of interest.
Select the extension within your project. Notice 'DTED' is added to the View menu bar between View and Theme.
Create a Catalog Shapefile, select DTED>Create DTED Catalog.
Select cells to merge into a grid file.
Selected Cells to merge are in yellow
Select DTED>Merge Selected DTED Cells, to create an elevation grid file.
Select DTED>Compute Hillshade (DD Grid), to create a hillshaded elevation grid file.
Hillshaded elevation grid file
If the GIS software is unable to read NIMA data, your timelines increase. Use NIMAMUSE as a file converter.
NIMAMUSE converts NIMA geospatial data into usable formats, i.e. TIFF, Shapefiles, Imagine.
a&c. Now combine the text file with the NIMA geospatial data. Since the text file is in an ArcView usable format the only concern is whether the geographics are in Decimal Degrees (dd). If the geographics are in decimal degrees ArcView's View>Add Event Theme plots the information, nicely. If the text file's geographics are in degrees, minutes, seconds, decimal seconds (dddmmss.ss), then an Avenue Script "dms2ddenhanced" (I am including the script under MISCELLANEOUS) may be used to convert to decimal degrees. Here is a brief procedure for using the Avenue Script "dms2ddenhanced." 1. ArcView Project is active with appropriate extension(s) turned on. 2. Add the ArcView usable formatted text file as a *.dbf (dbase) table to the project. 3. Load the script "dms2ddenhanced." 4. Run the script 5. Select your view with NIMA geospatial data. 6. Select View>Add Event Theme and remember to select the correct fields for X (dd-longitude) and Y (dd-latitude)! Now the sources (text file and NIMA geospatial data) are combined in ArcView. Use ArcView's Layout or File > Export, to tailor the information for posting on your website.
This is one method to merge internet or other information with NIMA geospatial data to answer an issue in a two hour turnaround (from start, to posting on the internet).
Esri, Defense Resource Kit CD and ArcView 3.1 Sample Scripts dms2dd.
DOD and NIMA, creators of scripts, dms2dd and dw.View.30.CoordAsDecimal, 1996.
Note dms2dd are two different scripts.
NIMA's website: http://www.nima.mil
Non U.S. DoD activities requesting NIMA geospatial data should contact:
Director
National Imagery and Mapping Agency
ATTN: Release Officer, Stop P-25 (NPS)
12310 Sunrise Valley Drive, Reston, VA 20191-3449
Tel. Fax: (703) 264-3405
dms2ddenhanced script:
' Name: DMS2DD_enhanced
' Date: 9 July 1999
' Title: Converts DegreesMinutesSeconds values to DecimalDegrees
' Description: Converts DegreesMinutesSeconds and/or decimal second values in
' a table to DecimalDegrees. A new field for the converted
' values is added to the table.
' ' Values greater than 180 or less than -180 may not be
'converted correctly.
' ' Requires: The table must be editable (dBASE or INFO) and you must
' have write access to it. The table must have a field
' in which the DMS values are stored in the format DDD MM SS.ss{}.
' Where {} is either N,S,W,E. Working on allowing "-" at the beginning.
' Note: dw.View.30.CoordAsDecimal script is included within this script.
'
' Author: NIMA
'
' History: Modified Esri AV 3.1, sample scritp 'dms2dd'
' Modified DoD and NIMA authors of 'dms2dd' and 'dw.View.30.CoordAsDecimal'
' scripts, created back in 1996. For more info please contact Paul Rabatin,
' NIMA, Integrated Program Office, 703-874-7018.
'
' Filename: dms2dd_enhanced.ave or dms2dd_3.ave
thisProject = av.GetProject
' Get the list of tables in the project and let the user pick one
tabList = {}
for each i in av.GetProject.GetDocs
if (i.Is(Table)) then
tabList.Add(i)
end
end
' Have the user pick the table to convert
tb = MsgBox.ChoiceAsString(tabList,
"Choose the table which contains the values to convert:",
"Convert Latitude DMS values to Latitude DD")
if (tb = Nil) then
return ""
end
tbv = tb.GetVTab
theDb = tb.GetVtab
theDb.StartEditingWithRecovery
recCount = theDb.GetNumRecords
' Have the user pick the field with the DMS values
latitude = MsgBox.ChoiceAsString(tbv.GetFields,
"Choose the field to convert Latitude from DMS to DD",
"Select field")
if (latitude = Nil) then
return ""
end
theLatField = latitude
latFieldName = MsgBox.Input("Enter a name for the new Latitude DD field (up to 8 characters):",
"Convert DMS values to DD","DD-Y")
if (latFieldName = Nil) then
return ""
end
' Make sure you can write to the table, and that the field doesn't already exist
if (tbv.CanEdit.Not) then
MsgBox.Info("Cannot edit the table.","Convert DMS values to DD")
return ""
end
if (tbv.FindField(latFieldName).Is(Field)) then
MsgBox.Info("A field with name"++latFieldName.asString++
"already exists.","Convert DMS values to DD")
return ""
end
' Ends the Field finder....
'Prompt user of current record selection
if (theDb.GetSelection.Count = 0)then
if (theDb.GetSelection.count <> recCount) then
SelAllRec = msgBox.YesNo ("Select all Records in Table?",theDb.asString, TRUE)
if (SelALLRec.Not) then
else
theDb.GetSelection.SetAll
'theDb.UpdateSelection
end
end
end
'Now script adds fields to *.dbf file.
' If we can get this far, we can add the new field
tbv.SetEditable(true)
newlat = Field.Make(latFieldName,#FIELD_DECIMAL,12,6)
tbv.AddFields({newlat})
for each i in theDb.GetSelection
LatVal = theDb.returnValueString(theLatField, i)
' LongVal = theDb.returnValueString(theLongField, i)
' Now the break-up of the field into ddd mm ss.sss starts along with the conversion
' to decimal degrees.
if (LatVal = nil) then
MsgBox.Error("Failed to receive string",Script.The.GetName)
return nil
end
' check all but last character, because it is N or S or E or W
theNumberPart = LatVal.Left(LatVal.Count -1)
if (theNumberPart.IsNumber.Not) then
' should be all digits
return nil
end
'If the coordinate is South (S) or West (W) we need to make it
' negative. The next line will be used later on to change the
' coordinate to a negative dd.dddd
theStringPart = LatVal.Right(1).UCase
if (theStringPart.IsNumber) then '
return nil
end
junk = theNumberPart.AsTokens(".") ' split into list, div. at dec point
if (junk.Count > 1) then ' yes, there's a decimal in it
secondsDecimal = ("."+junk.Get(1)).AsNumber
theNumberPart = junk.get(0)
else
secondsDecimal = 0
end
' Loop through number part, grabbing each two digits.
' I reuse the "junk" variable rather than creating a new variable.
junk = {}
while (theNumberPart.Count > 0)
if (theNumberPart.Count = 3) then
junk.Add(theNumberPart)
theNumberPart= ""
else
junk.Add(theNumberPart.Right(2))
theNumberPart = theNumberPart.Left((theNumberPart.Count) - 2)
end
end
' Now we have a list, but in reverse order.
' It may be {"SS","MM","DD"}, {"MM","DD"}, or {"DD"}.
if (junk.Count = 3) then
theNumber = junk.Get(2).AsNumber +
(junk.Get(1).AsNumber/60) +
((junk.Get(0).AsNumber)+secondsDecimal/3600)
elseif (junk.Count = 2) then
theNumber = junk.Get(1).AsNumber +
(junk.Get(0).AsNumber/60)
elseif (junk.Count = 1) then
theNumber = junk.Get(0).AsNumber
else
MsgBox.Error("Couldn't understand"++LatVal.Quote,Script.The.GetName)
return nil
end
if ("WS".Contains(theStringPart)) then ' coord should be negative
theNumber = theNumber.Negate '
end '
newLatDD = theNumber
' Save Converted Latitude to the *dbf
theDb.SetValue(newlat,i,newLatDD.asString)
end
'
'End conversion for Latitude...
'
' Now convert the Longitude DMS field...
'
' Have the user pick the field with the DMS values
longitude = MsgBox.ChoiceAsString(tbv.GetFields,
"Choose the longitude field to convert from DMS to DD",
"Select field")
if (longitude = Nil) then
return ""
end
theLongField = longitude
longFieldName = MsgBox.Input("Enter a name for the Longitude new field (up to 8 characters):",
"Convert DMS values to DD","DD-X")
if (longFieldName = Nil) then
return ""
end
' Make sure you can write to the table, and that the field doesn't already exist
if (tbv.CanEdit.Not) then
MsgBox.Info("Cannot edit the table.","Convert DMS values to DD")
return ""
end
if (tbv.FindField(longFieldName).Is(Field)) then
MsgBox.Info("A field with name"++longFieldName.asString++
"already exists.","Convert DMS values to DD")
return ""
end
'ends the field finder to convert from dms to dd
'Prompt user of current record selection
if (theDb.GetSelection.Count = 0)then
if (theDb.GetSelection.count <> recCount) then
SelAllRec = msgBox.YesNo ("Select all Records in Table?",theDb.asString, TRUE)
if (SelALLRec.Not) then
else
theDb.GetSelection.SetAll
'theDb.UpdateSelection
end
end
end
'Now script adds fields to *.dbf file.
' If we can get this far, we can add the new field
tbv.SetEditable(true)
newlong = Field.Make(longFieldName,#FIELD_DECIMAL,12,6)
tbv.AddFields({newlong})
for each i in theDb.GetSelection
' LatVal = theDb.returnValueString(theLatField, i)
LongVal = theDb.returnValueString(theLongField, i)
' Now the break-up of the field into ddd mm ss.sss starts along with the conversion
' to decimal degrees.
if (LongVal = nil) then
MsgBox.Error("Failed to receive string",Script.The.GetName)
return nil
end
' check all but last character, because it is N or S or E or W
theNumberPart = LongVal.Left(LongVal.Count -1)
if (theNumberPart.IsNumber.Not) then
' should be all digits
return nil
end
'If the coordinate is South (S) or West (W) we need to make it
' negative. The next line will be used later on to change the
' coordinate to a negative dd.dddd
theStringPart = LongVal.Right(1).UCase
if (theStringPart.IsNumber) then '
return nil
end
' Check for decimal (assumed to be part of seconds)
junk = theNumberPart.AsTokens(".") ' split into list, div. at dec point
if (junk.Count > 1) then ' yes, there's a decimal in it
secondsDecimal = ("."+junk.Get(1)).AsNumber
theNumberPart = junk.get(0)
else
secondsDecimal = 0
end
' Loop through number part, grabbing each two digits.
' I reuse the "junk" variable rather than creating a new variable.
junk = {}
while (theNumberPart.Count > 0)
if (theNumberPart.Count = 3) then
junk.Add(theNumberPart)
theNumberPart= ""
else
junk.Add(theNumberPart.Right(2))
theNumberPart = theNumberPart.Left((theNumberPart.Count) - 2)
end
end
' Now we have a list, but in reverse order.
' It may be {"SS","MM","DD"}, {"MM","DD"}, or {"DD"}.
if (junk.Count = 3) then
theNumber = junk.Get(2).AsNumber +
(junk.Get(1).AsNumber/60) +
((junk.Get(0).AsNumber)+secondsDecimal/3600)
elseif (junk.Count = 2) then
theNumber = junk.Get(1).AsNumber +
(junk.Get(0).AsNumber/60)
elseif (junk.Count = 1) then
theNumber = junk.Get(0).AsNumber
else
MsgBox.Error("Couldn't understand"++LatVal.Quote,Script.The.GetName)
return nil
end
if ("WS".Contains(theStringPart)) then ' coord should be negative
theNumber = theNumber.Negate '
end '
newLongDD = theNumber
theDb.SetValue(newlong,i,newLongDD.asString)
end
doSave = MsgBox.YesNoCancel("Save Edits?","Stop Editing"++theDb.asString, True)
if (theDb.StopEditingWithRecovery(doSave).Not) then
if(doSave = nil) then
return nil
end
end