Mexican Spotted Owl, stretching...

ArcGIS Tools
ArcView 3.x Extensions
GIS Consultation
Unit Converter
Jenness Enterprises
Search

 

Progress Meter

NAME:   Progress Meter v. 1.1   (Click Name to Download)

AKA:  Progress Meter.zip

Last Modified:  March 27, 2001

TITLE:  Progress Meter Dialog

TOPICS:  ArcView 3.x, Dialog, Script, Tools, Analysis

AUTHOR:  Jeff Jenness

Wildlife Biologist, GIS Analyst

US Forest Service, Rocky Mountain Research Station

2500 S. Pine Knoll Drive

Flagstaff, AZ 86001

jeffj@jennessent.com 

Illustration of Progress Meter in action...

DESCRIPTION:  This Progress Meter is a modeless dialog you can incorporate into a script or extension to show what ArcView is currently working on, how long it's been working and how long it'll probably take to finish. It's especially well adapted for scripts that have lengthy "for each" loops that take hours, days or weeks to finish.

The file "progress_meter.zip" contains three files:

  1. Progress Meter.doc:  A Microsoft Word version of this on-line documentation.

  2. progress_meter.ded:  The actual ProgressMeter Dialog

  3. generic_progress.apr:  A generic project file incorporating the Progress Meter dialog to demonstrate how it's used.

There are two sample scripts included in the "generic_progress.apr" project file. The one called "GenericScript" can be run from the View by clicking on the button on the far right with the  icon on it. You need to have a point, line or polygon theme in your view before the script will actually do anything, though.  The second sample script (called "Sample") can be run from within the script window by clicking on the "Run" button (the one with the running person on it).  This script makes a list containing 159 numbers, then just counts through them and updates the dialog as it goes.  It pauses briefly between each number so you have time to observe the dialog in action.

These instructions are repeated at the beginning of the "GenericScript" script.

When you run a script or extension that uses the progress meter, the meter will give you seven pieces of information (see picture above): 

  1. Begin Time; or the time the calculations start.

  2. The Current Time

  3. Total number of steps in the "For Each" loop, and what current step it's on.

  4. Percentage of steps completed.

  5. A statement of what specific task is currently being worked on.

  6. An estimate of how much longer the extension will probably take to run.

  7. A green graphic progress bar that expands until it reaches full width when the work is done.

INSTRUCTIONS:  If you are running the "generic_progress.apr" project file, then the dialog designer and the Progress Meter Dialog are already loaded (steps 1-5). Otherwise follow all steps.

  1. First load the Dialog Designer extension.

  2. Open a new Dialog (It'll probably be called "Dialog1").

  3. When you have a new Dialog open, click on the "Load Text File" button.

  4. Find the dialog called "progress_meter.ded" and open it.

  5. Now delete "Dialog1" unless you want to make something else with it.

  6. When you opened "progress_meter.ded" you automatically put a dialog called "ProgressMeter" into your Dialogs, and a script called "ProgressDialog.Open" into your Scripts.  You don't have to mess with the "ProgressDialog.Open" script unless you want to.  All it does is center the dialog on the screen when the Dialog is opened, set some initial values for the text labels and position the progress bar.

  7. This is a "non-modal" or "modeless" dialog, meaning that it can stand open on the screen while ArcView does things in the background.   If this were a "modal" dialog, then ArcView would stop until you turned the dialog off.  The dialogs you see when you save files are modal dialogs.

  8. If you open the dialog and look at it, (see image above) you'll see six Text Labels and one graphic image that becomes a graphic Progress Bar.  When you open the dialog in ArcView, you can double-click on these objects to see their lists of properties.  The two properties that matter most right now are the Names and Labels of the five Text Labels, and the Name and Size of the green Progress Bar.  At different points in your script, you will change the labels of the Text Labels, and the size of the Graphic Bar, to reflect what your progress status is, and you have to call them by name in order to change them.  Here are their names:

    1. BeginTime:  Name is "lblBeginTime" and current label is "BeginTime".

    2. Current Time:  Name is "lblCurrentTime" and current label is "12:12:35 AM"

    3. RecordNumber:  Name is "lblRecordNumber" and current label is "RecordNumber:

    4. Calculating...:  Name is "lblIndex" and current label is "Calculating...".

    5. Estimated Time Left...:  Name is "lblTimeLeft" and current label is "Estimated Time Left...".

    6. (00.0%):  Name is "lblPercentDone" and current label is "(00.0%)"

    7. Green Progress Bar:  Name is "icnProgressLine". You make this grow by changing the size of the Icon Box.  In other words, the green image is always full size, but it's clipped by the boundaries of the Icon Box that contains it.  As the Icon Box grows, you see more and more of the bar inside it.  It makes a weird effect when you run it fast, but it does the job.  IMPORTANT:  You need to know that the Progress Bar is always 13 pixels high, and it grows from 0 pixels to a maximum of 268 pixels in width.

  9. Somewhere at the beginning of your script, assign the dialog and these text labels to their own variable names with the following lines:

     

    theProgressDialog = av.FindDialog ("ProgressMeter")

    thePDBeginTime = theProgressDialog.FindByName("lblBeginTime")
    thePDCurrentTime = theProgressDialog.FindByName("lblCurrentTime")

    thePDRecordNumber = theProgressDialog.FindByName("lblRecordNumber")

    thePDIndex = theProgressDialog.FindByName("lblIndex")

    thePDTimeLeft = theProgressDialog.FindByName("lblTimeLeft")

    thePDPercentDone = theProgressDialog.FindByName("lblPercentDone")

    thePDProgressBar = theProgressDialog.FindByName("icnProgressLine")

  10. At some point you'll want to make the dialog visible. Use the "Open" request.

     theProgressDialog.Open

  11. Then, as you send new information to these labels, you'll use the "SetLabel" request to change them. I like to use the following initial label values:

     

    ' - BEGIN TIME ------------------------------------------------------------------------------

    ' Just set the date format.

    Date.SetDefFormat ("MMMM d, h:m:s AMPM")

    ' Find the exact time this request is executed. I put this line in right before my script '

    ' starts calculating things.

    BeginTime = Date.Now

    ' Put the BeginTime value in to the dialog box.

    thePDBeginTime.SetLabel("Began Job: "+BeginTime.AsString)

    ' - CURRENT TIME ----------------------------------------------------------------------------

    ' Finds the current time and formats it, then writes current time to the label.

    thePDCurrentTime.SetLabel(date.now.setFormat("h:m:s AMPM").AsString)

    '- RECORD NUMBER --------------------------------------------------------------------------- 

    thePDRecordNumber.SetLabel ("Working on Record # 1 out of [some number]")

    '- INDEX -----------------------------------------------------------------------------------

    thePDIndex.SetLabel ("Calculating [Insert the activity]")

    '- TIME LEFT ------------------------------------------------------------------------------- 

    thePDTimeLeft.SetLabel ("Estimated time remaining: ---:---:---")

    '- PERCENT DONE ----------------------------------------------------------------------------

    thePDPercentDone.SetLabel ("(00.0%)")

    '- PROGRESS BAR ----------------------------------------------------------------------------

    ' This makes the Green Bar 0 pixels wide and 13 pixels high.

    thePDProgressBar.ResizeTo (0,13)

  12. As you work through the script and move through progressive iterations of your "for each" loop, you send new messages to each of these labels. At the end of each loop, use the following code to keep a somewhat accurate estimate of how much time is remaining:

    theDuration = (Date.Now - BeginTime).AsSeconds

    PredictedDuration = (theDuration * thePolyCount)/(theRecord+1)

    EstTimeLeft = (PredictedDuration-theDuration)+1

     

    EstHoursLeft = (EstTimeLeft/3600).Truncate

    EstMinutesLeft = ((EstTimeLeft - (EstHoursLeft*3600))/60).Truncate

    EstSecondsLeft = (EstTimeLeft - (EstHoursLeft*3600) - (EstMinutesLeft*60)).Truncate

    EstHoursStr = EstHoursLeft.AsString

    If (EstMinutesLeft >= 10) then

        EstMinutesStr = EstMinutesLeft.AsString

    else

        EstMinutesStr = "0"+EstMinutesLeft.AsString

    end

    If (EstSecondsLeft >= 10) then

        EstSecondsStr = EstSecondsLeft.AsString

    else

        EstSecondsStr = "0"+EstSecondsLeft.AsString

    end

    theProgressDialog.Activate ' THIS LINE IS SOMETIMES NECESSARY TO MAKE THE

                                                ' DIALOG UPDATE ITSELF.

    EstTimeLeftStr = EstHoursStr +":"+EstMinutesStr+":"+EstSecondsStr

    thePDTimeLeft.SetLabel ("Estimated time remaining: "+EstTimeLeftStr)

  13. When you're done with your loops, close the dialog. Use the "Close" request.

    theProgressDialog.Close

There are two scripts in the "generic_progress.apr" project file which make use of this code and demonstrate the Progress Meter.

bullet

GenericScript:  GenericScript is run by opening a View, loading up a Point, Line or Feature Theme, and clicking on the button on the far right with the  icon on it.  This script works through each feature in the theme, doing nothing but counting how far along it's gone.  It updates the Progress Meter with the number of the feature it's looking at, what proportion of the theme it's gone through, and how much farther it has to go.  This example is most effective if you use it on a theme with several hundred features, since the script is doing nothing but counting through them.  If you use it on a theme with less than a hundred or so features, it might go so fast you won't get a clear idea of what the Progress Meter is doing.  Download genericscript.ave.

bullet

Sample:  Sample is run from the script editor.  All it does is create a list containing 159 numbers and counts through them.  In order to delay the action some, it pauses between each number for long enought to count to 5,000, then continues.  To run it, make sure the script is compiled and then click the "Run" button.  Download sample.ave

Enjoy! Please contact the author if you have problems or find bugs.

            Jeff Jenness                                      jeffj@jennessent.com

            3020 N. Schevene Blvd.

            Flagstaff, AZ  86004

                        USA

Please visit Jenness Enterprises ArcView Extensions site for more ArcView Extensions and other software by the author.  We also offer customized ArcView-based GIS consultation services to help you meet your specific data analysis and application development needs.