Title of Paper

 

Migrating Avenue to ArcGIS™

 

Authors' Names

 

Constantine N. Tonias, P.E. and Elias C. Tonias, P.E.

 

Abstract

 

With the increased use and popularity of ArcGIS™, the need to migrate Avenue based applications to the ArcGIS™ environment has increased significantly.  As such, many developers are faced with the dilemma of how to efficiently convert their Avenue code into a format that utilizes ArcObjects, and which is compatible with ArcGIS™.  One approach, which this paper addresses, is to develop a series of “wraparounds” that facilitates the conversion process.  That is, the creation of a library of procedures that emulate the function of Avenue requests.  By establishing a one to one correspondence between Avenue requests and “wraparounds”, the developer is able to substitute an Avenue request with the appropriate “wraparound”, thereby significantly reducing the amount of time required to perform the conversion.

 

This paper is a case study of how thousands of lines of Avenue code were converted into VB/VBA using a “wraparound” approach.  Topics covered in this paper include: general Avenue to VB/VBA syntax differences, Views, Themes, Tables, Selection Sets, Graphic Elements, Querying, Calculating, File I/O operations, Message Boxes, Progress Bars, User-Document interaction, Manipulation of Feature Shapes, Legends, Classifications and Application deployment.

 

Paper Body

 

1. Introduction

 

With the increased use and popularity of ArcGIS™, the need to migrate Avenue based applications to the ArcGIS environment has increased significantly.  As such, many developers are faced with the dilemma of how to efficiently convert their Avenue code into a format that utilizes ArcObjects™, and which is compatible with ArcGIS.  One approach, which this paper addresses, is to develop a series of “wraparounds” that facilitates the conversion process.  That is, the creation of a library of procedures that emulate the function of Avenue requests.  By establishing a one to one correspondence between Avenue requests and “wraparounds”, the developer is able to substitute an Avenue request with the appropriate “wraparound”, thereby significantly reducing the amount of time required to perform the conversion.

 

Like most new explorations, it is the pioneers that catch the first arrows.  Having gone through the process of converting thousands of lines of Avenue code, the authors have learned, and wish to share a few lessons, which might benefit their fellow Avenue programmers who will be converting their applications to the ArcGIS environment.  After all, we don't all have to be pioneers.

 

During the mid to late 1990's, The CEDRA Corporation had developed a number of Avenue based applications for shapefile editing (CEDRA-AVcad™), coordinate geometry computations (CEDRA-AVcogo™), parcel mapping (CEDRA-AVparcel™), sewer modeling (CEDRA-AVsand™) and water distribution modeling (CEDRA-AVwater™).  All of these applications represented well over 500,000 lines of Avenue code.  As CEDRA began the conversion to the ArcGIS environment, a systematic approach was taken to develop a "wraparound" for each of the Avenue requests, which was used in their software.  As more and more of the software was converted, the number of "wraparounds" increased, and the conversion began to pick up speed.  CEDRA felt that since the use of these "wraparounds" greatly enhanced its conversion process, than surely others could benefit as well.  With this in mind, CEDRA has published a book titled Avenue Wraps, containing all of the "wraparounds" created during its conversion process in digital (optional CD), as well as, descriptive form.

 

Just as with the 90-10 software rule, that is, a user only uses 10% of a software's total functionality, Avenue developers probably only use 10% of the available Avenue requests.  Although an accurate figure is not available, it is approximated that at least 2500 to 3000 Avenue requests exist.  Avenue Wraps contains over 280 "wraparounds", which is approximately 10% of the total number of Avenue requests.  The "wraparounds" represent a one-to-one mapping for the most popular Avenue requests.  In addition to the Avenue requests used in the CEDRA software, all of the requests identified in the Introduction to Avenue™ training book have a corresponding Avenue Wrap.

 

Presented below, in the sequence of the Chapters in the Avenue Wraps book, is a description of what was involved in converting CEDRA's Avenue based applications to ArcGIS.  The intent of this presentation is to (a) demonstrate how Avenue code can be converted to ArcGIS code, and (b) describe the methodology behind the conversion.

 

2. General Conversion Guidelines

 

In migrating to the ArcGIS environment, the developer actually has a choice in how to integrate with ArcGIS.  Since ArcGIS is a Component Object Model (COM) based application, a developer can use any COM compliant programming language to interface with ArcGIS.  This includes Visual Basic, Visual C++ and the like.  If one wishes to minimize the amount of recoding, the clear choice is to perform the migration in the Visual Basic (VB) and Visual Basic for Applications (VBA) environments.  The reason being is that Avenue syntax is similar to VB/VBA.  So that, VB/VBA makes perfect sense, if one does not wish to perform a complete rewrite.  As a matter of fact, Avenue was developed using VB as the basis for the language.  Note that there is a difference between VB and VBA.  This difference will be addressed later on.

 

Between VB and VBA, the VBA environment is most similar to the Avenue environment.  Specifically, the programmer can easily develop, and test the application directly within ArcMap.  Any other COM programming language would involve the developer to (a) develop the code, (b) compile the code, (c) create an Active X DLL, (d) load the Active X DLL in ArcMap, and (e) test the code.  If an error were detected, the developer would have to exit ArcMap, correct the error, and repeat the process described above.  This approach leads to a much longer conversion process.  Therefore, it makes senses to convert Avenue code in the VBA environment.

 

In converting Avenue code there are primarily three aspects, which the programmer needs to address.

 

First, there is the issue of the syntax differences between Avenue and VB/VBA.  This includes:

         Differences in how statements are structured (if ... then ... end, for each ... end, etc.),

         Differences in names of intrinsic functions such as square root (sqrt vs. sqr),

         Manipulation of string variables (Count vs. len),

         Handling of lists (Get vs. Item),

and so forth.  These, however, are relatively easy to solve, and do not provide much of a problem, other than time.

 

Second, unlike Avenue in which variables did not have to be declared, in the VB/VBA environment variables do have to be declared.  This issue, although not terribly difficult, is time consuming and tedious, and if not done right, can cause errors, which are difficult to debug.  For those who have developed programs in Fortran, C, C++ and the like know, variable declaration is not a glamorous aspect of programming, and is a stark departure from Avenue, in which variables could be created without regard to specification of type.  So that, like the item discussed above, this part of the conversion is relatively easy to overcome.

 

Third, there is the issue of writing the appropriate ArcObjects code to perform the task of the Avenue request that is to be converted.  This is where most of the conversion work will be spent, and where the “wraparounds” come into play.  By using “wraparounds”, the developer no longer needs to worry about writing the appropriate ArcObjects code.  This code is buried within the “wraparound”.  Using Avenue Wraps, the developer searches its library of procedures for the “wraparound” which corresponds to the desired Avenue request.  For Avenue programmers, who have no experience with ArcObjects, trying to convert Avenue code using ArcObjects is going to be a difficult task.  That is why this notion of "wraparounds" is so important and essential to the conversion process.

 

As an example of how “wraparounds” can be used, let’s review the Avenue code shown below:

 

              Msg = "Okay to continue ?"

              Heading = "My Command"

              Default = True

              ians = MsgBox.YesNoCancel(Msg, Heading, Default)

              if (ians = Nil) then

                 .... do something

              end

              if (ians.Not) then

                 .... do something

              else

                 .... do something

              end

 

The Avenue code demonstrates the use of the YesNoCancel request as applied to the MsgBox class along with how the response from the user is handled.  Below is how the Avenue code could be converted in VB/VBA using Avenue Wraps:

 

              Dim Msg As Variant, Heading As Variant

              Dim Default As Boolean

              Dim ians As Integer

              Msg = "Okay to continue ?"

              Heading = "My Command"

              Default = True

              Call avMsgBoxYesNoCancel(Msg, Heading, Default, ians)

              If (ians = vbCancel) Then

                 .... do something

              End If

              If (ians = vbNo) Then

                 .... do something

              End If

              If (ians = vbYes) Then

                 .... do something

              End If

 

Note the use of the “wraparound”, avMsgBoxYesNoCancel.  In addition to the use of the “wraparound”, note:

         That the variables have been declared using the Dim statement, and that in the first declaration statement where two variables appear, the type of variable assignment is applied to each variable (not just once at the end of the declaration),

         The syntax difference in the use of the “if ... then” statement (there must be an End If, and not just an End), and

         The variable “ians” that is passed back by the YesNoCancel request is a Boolean, while the avMsgBoxYesNoCancel “wraparound” returns the same variable as an integer value, which is equal to one of the predefined VB constants.

 

“If..Then” statements:            Regarding the use of the “If..Then” statement, although the overall structure of this statement is similar in both Avenue and VB/VBA, there are some minute differences that should be brought to light.  While VB/VBA does an excellent job in displaying syntax errors, it will not flag the “end” statement in the Avenue code sample as an error.  As shown in the VB/VBA code, the “End If” terminates the “if..then” statement, and not the statement “end” statement by itself.  Thus the programmer must be cognizant of this during the conversion.

 

Furthermore, in Avenue one may write:

 

              If (a.NE.B) then x = y End

 

While in VB/VBA, the programmer would write:

 

              If (a <> b) then

                 x = y

              End If

 

Thus, perhaps one of the first steps during the conversion process would be to convert these statements first.  Although there is a way to introduce concatenated statements in VB/VBA, it is felt that the above methodology is just as easy, and provides for a more clear representation of complex If...then statements.

 

"Iterative or Loop" Statements:             Another syntax issue is that of the iterative statements such as the “while”, “for each”, “for” and the like.  So that, once the “if...then” statements have been taken care of, the next thing that could be tackled would be the iterative statements.  Although it is understood that each programmer has a personal programming style and approach in performing the conversion, the above points merely illustrate the types of syntax differences, which the programmer will need to address.

 

"Error Trapping":                       Finally, a good feature to take advantage of in the VB/VBA environment, which is not available in Avenue, is the ability to trap errors.  Error trapping provides the developer a means to avoid application runtime errors, which typically result in the application to cease to operate properly.  By avoiding application runtime errors, the application can still be used to perform other functions, should an error be encountered, rather than simply "dying".  This results in giving the application a more professional appearance.  The code below demonstrates the use of error trapping:

              '

              Public Sub ShowErrorTrapping()

              '

              Dim pMxApp As IMxApplication

              Dim pmxDoc As IMxDocument

              Dim pActiveView As IActiveView

              Dim pMap As IMap

              '

              '  ---This statement informs the application where to

              '  ---branch when an error is detected in the procedure

              On Error GoTo Errorhandler

              '

              '  ---Get the active view

              Call avGetActiveDoc(pMxApp, pmxDoc, pActiveView, pMap)

              '

              '  ---do something else

                  .

                  .

                  .

              '

              '  ---At this point, our work is done

              Exit Sub

              '

              '  ---Handle any errors detected in the procedure

              Errorhandler:

              '

              '  ---Display detected error number and a description

              MsgBox "Error " & Err.Number & " - " & Err.Description & _

                     Chr(13) & "Subroutine: ShowErrorTrapping"

              '

              End Sub

 

Note that the introduction of comments in VB/VBA is the same as in Avenue with the exception that comments appear in the color green.  In addition, syntax errors detected in VB/VBA appear in the color red as soon as the typing of a statement has been completed.  This is quite a good feature, but it has a bothersome side effect.  In addition to displaying the erroneous statement in red, VB/VBA also beeps and displays an error message box, which must be closed before the user can continue typing.

 

3. Application - Document Avenue Wraps

 

In Avenue the very first statement that typically appeared in a script was:

 

              theView = av.GetActiveDoc

 

The object, theView, gave the developer access to all of the themes in the view.  For example, a list of visible themes in the view could be ascertained by the statement:

 

              vThemesList = theView.GetVisibleThemes

 

Using Avenue Wraps the above statements would appear as:

 

              Dim pMxApp As IMxApplication

              Dim pmxDoc As IMxDocument

              Dim pActiveView As IActiveView

              Dim pMap As IMap

              Dim vThemesList As New Collection

              Call avGetActiveDoc(pMxApp, pmxDoc, pActiveView, pMap)

              Call avGetVisibleThemes(pmxDoc, vThemesList)

 

The first point that needs to be made, in reviewing the above code, is that in Avenue a developer applied a request to an object, which resulted in another object being created, vThemesList in the above Avenue example.  This approach is not possible using ArcObjects.  Therefore, to simulate the Avenue approach, Avenue Wraps provides a subroutine or function to perform the function of the Avenue request by using the argument list in the subroutine or function to pass objects in and out.

 

The second point is that a List object in Avenue translates to a Collection object in VB/VBA.  Note that List objects in Avenue are zero based, while Collections begin at the index value 1.  For example, the first visible theme in vThemesList would be found by issuing the following statement:

 

              firstVTheme = vThemesList.Get(0)

 

while in VB/VBA the statement would appear as:

 

              firstVTheme = vThemesList.Item(1)

 

Note that the Avenue request Get becomes Item in VB/VBA.  So that, the search for and revision of lists into collections, the change of Get to Item, and the altering of the indexing could be done at the start of the conversion process.

 

The final point is that the Avenue code contains two lines of code, while the VB/VBA code contains seven, the first five of which are declaration statements.  Thus, even though there is a one to one correspondence between the Avenue requests and the “wraparounds”, the number of lines of VB/VBA code is greater than its Avenue counterpart due to the declaration statements.  To make the VB/VBA code easier to read, it is suggested that all of the declaration statements be placed at the top of the procedure, rather than scattered throughout the subroutine or function.  One procedure, which one may consider, is to introduce the declaration statements within the code where new variables are first encountered, and then, after the code has been tested, move the declaration statements to the top of the procedure in the same sequence of occurrence.

 

4. File Input and Output Avenue Wraps

 

In dealing with file I/O, it is primarily native VB/VBA code that is used to accomplish reading and writing of files.  ArcObjects itself does not provide functionality to read and write files.  As such, the "wraparounds" found in Avenue Wraps are VB/VBA code which provide the functionality found in their Avenue counterparts.

 

For example the Avenue statement to open a file for writing would appear as:

 

              aLineFile = LineFile.Make (aFileName, #FILE_PERM_WRITE)

 

while using Avenue Wraps, the statement would look like this:

 

              Dim aFileName As String

              Dim aLineFile

              Set aLineFile = avLineFileMake(aFileName, "WRITE")

 

Note the use of the word Set.  In VB/VBA when dealing with objects the keyword Set is used to create an object.  In this example, aLineFile is a file system object.  In addition, in Avenue there were enumerations (predefined values or constants), which certain requests recognized.  Avenue Wraps simulates enumerations by using strings that reflect the enumeration, such as "WRITE" for "FILE_PERM_WRITE".

 

5. Theme and Table Avenue Wraps

 

This is the heart of any application.  This is where the developer manipulates the data in a table.  In Avenue the developer would operate on an FTab or VTab object depending upon the type of table being processed.  Using ArcObjects, the developer uses:

         The IFeature interface, if dealing with an FTab, or,

         The IRow interface, if dealing with a VTab.

To avoid having to create a separate set of "wraparounds", one for FTab's and one for VTab's, most of the "wraparounds" have been written to process both FTab's and VTab's by having the user pass the name of the theme or table to be processed, rather than, passing an FTab or VTab object.

 

For example the following Avenue code writes a value, 24, to a specific record, 12, in an FTab:

 

              theView = av.GetActiveDoc

              theTheme = theView.FindTheme("L_0ln")

              theFTab = theTheme.GetFTab

              col = theFTab.FindField("MAP")

              rec = 12

              theFTab.SetEditable(true)

              theFTab.SetValue(col, rec, 24)

              theFTab.SetEditable(false)

 

Using Avenue Wraps, the above code could be converted as follows:

 

              Dim pMxApp As IMxApplication, pmxDoc As IMxDocument

              Dim pActiveView As IActiveView, pMap As IMap

              Dim theTheme As String

              Dim theFTab As IFields

              Dim pFeatCls As IFeatureClass, pLayer As IFeatureLayer

              Dim col As Long, rec As Long

              Call avGetActiveDoc(pMxApp, pmxDoc, pActiveView, pMap)

              theTheme = "L_0ln"

              Call avGetFTab(pmxDoc, theTheme, theFTab, pFeatCls, pLayer)

              col = theFTab.FindField("MAP")

              rec = 12

              Call avSetEditable(pmxDoc, theTheme, true)

              Call avSetValue(pmxDoc, theTheme, col, rec, 24)

              Call avSetEditable(pmxDoc, theTheme, false)

 

The Avenue Wraps code shown above could be used on either an FTab or a VTab, because the "wraparounds" check if the given name passed in corresponds to a theme or to a table.  Note that the FindField request has a direct counterpart in the ArcObjects world.  This is one of the very, very few examples where a "wraparound" was not required.

 

As stated above, the "wraparound", avSetValue, operates on either an FTab or a VTab.  However, it cannot be used to store geometry (a feature's shape).  In this case the "wraparound", avSetValueG, must be used.  The reason is that when storing attribute information with avSetValue, the ArcObjects Value property is used.  However, in order to store geometry (a feature's shape), the ArcObjects Shape property needs to be used.  Since there are two different properties, two different “wraparounds” were created, one to store attribute data and the other to store geometry.

 

Continuing with the example above, the Avenue code below would store a two-point line in record 12 of the FTab:

 

              aShape = Polyline.Make({{20000.0, 20000.0, 30000.0, 25000.0}})

              col = theFTab.FindField("SHAPE")

              theFTab.SetEditable(true)

              theFTab.SetValue(col, rec, aShape)

              theFTab.SetEditable(false)

 

Using Avenue Wraps, the above code could be converted as follows:

 

              Dim aShape As IPolyline

              Dim col As Long

              Set aShape = avPolyline2Pt(20000#, 20000#, 30000#, 25000#)

              col = theFTab.FindField("SHAPE")

              Call avSetEditable(pmxDoc, theTheme, true)

              Call avSetValueG(pmxDoc, theTheme, col, rec, aShape)

              Call avSetEditable(pmxDoc, theTheme, false)

 

In reviewing the above Avenue Wraps code, note the # character in the "wraparound" avPolyline2Pt.  When a number is hard coded with .0, .00, .000, etc., VB/VBA will remove the zeros and replace them with the # character.  In addition, note that there is no direct Avenue counterpart to the "wraparound", avPolyline2Pt.  During CEDRA's conversion process, in an effort to minimize the amount of recoding, certain "wraparounds" were developed that do not have corresponding Avenue requests, but satisfy a need in that they facilitate the conversion process.  In the CEDRA software there were a lot of cases in which two point lines were being created using the double left ({{) and the double right (}}) brace characters.  Rather than using the "wraparound", CreateList and adding point features to the lists (reference is made to the Section 8 example), the "wraparound", avPolyline2Pt was created.

 

As a matter of fact, there are a number of "wraparounds" which do not have an Avenue counterpart, but when used, greatly help in the conversion of Avenue to VB/VBA code.

 

Finally, a good feature to take advantage of is the Undo / Redo capabilities of ArcObjects.  The “wraparound”, avSetEditable, when used with the false parameter on a theme will not terminate the editing of the theme.  Rather, the “wraparound” only flushes any buffered writes there may be on the theme.  Thus, the theme remains in an editable state.  This is intentionally done so that the developer can take advantage of the Undo / Redo capabilities.  To do so, the “wraparounds”, avStartOperation and avStopOperation, should be used.  These “wraparounds” begin and terminate an edit operation which is added to the Editor’s operation stack.  This enables the end user to perform an Undo or Redo operation.  The avStartOperation subroutine is called after the theme has been made editable.  The avStopOperation subroutine is called when the desired editing has been completed.  A call to the avStopOperation subroutine must be made if a call to the avStartOperation subroutine has been issued.  There is no limit to the number of times these subroutines can be called within an edit session.  The “wraparound”, avStopEditing, will terminate the Editor saving any edits that may have been made.

 

6. Feature Selection Avenue Wraps

 

The "wraparounds" in this section follow the convention in the previous section in that the developer passes the name of the theme or layer to be processed rather than an FTab or VTab object.  For example, the following Avenue code could be used to cycle through the selected set of features in a theme to compute a total value for a field called Deposits:

 

              theView = av.GetActiveDoc

              theTheme = theView.FindTheme("L_0ln")

              theFTab = theTheme.GetFTab

              col = theFTab.FindField("Deposits")

              sel = theFTab.GetSelection

              total = 0.0

              for each rec in sel

                  deposit = theFTab.ReturnValue(col, rec)

                  total = total + deposit

              end

 

Using Avenue Wraps, the above code could be converted as follows:

 

              Dim pMxApp As IMxApplication, pmxDoc As IMxDocument

              Dim pActiveView As IActiveView, pMap As IMap

              Dim theTheme As String

              Dim theFTab As IFields

              Dim pFeatCls As IFeatureClass, pLayer As IFeatureLayer

              Dim col As Long

              Dim sel As ISelectionSet, selList As New Collection

              Dim total As Double, iRec As Long, rec As Long

              Dim pFeat As IFeature

              Dim deposit As Double

              Call avGetActiveDoc(pMxApp, pmxDoc, pActiveView, pMap)

              theTheme = "L_0ln"

              Call avGetFTab(pmxDoc, theTheme, theFTab, pFeatCls, pLayer)

              col = theFTab.FindField("Deposits")

              Call avGetSelection(pmxDoc, theTheme, sel)

              Call avGetSelectionIDs(sel, selList)

              total = 0#

              For iRec = 1 to selList.Count

                  rec = selList.Item(iRec)

                  Set pFeat = pFeatCls.GetFeature(rec)

                  deposit = pFeat.Value(col)

                  total = total + deposit

              Next

 

In reviewing the above Avenue Wraps code, note the use of the "wraparound", avGetSelectionIDs.  This "wraparound" returns a collection of OIDs (object identification numbers) for each of the selected features.  So that, rather than looping on the selected set, sel, as was done in Avenue, a loop is performed on the collection, selList.  An OID is extracted from selList and a feature extracted from the pFeatCls object.  Using the feature, pFeat, the deposit value is extracted and added to total.  This example illustrates the main difference between Avenue and ArcObjects, in that, in Avenue manipulation of data was performed on FTab or VTab objects.  Using ArcObjects, manipulation of data is performed using the IFeature interface, for FTab's, and the IRow interface, for VTab's.  Obviously, this difference poses an obstacle in converting Avenue code, but using the "wraparound", avGetSelectionIDs, a work-around is fairly easily achieved.

 

7. Message and Menu Boxes Avenue Wraps

 

This was the portion of the conversion that was probably the easiest to deal with.  Basically what was done was to create a single form, and then programmatically alter the form based upon the type of dialog box that needed to be displayed.  For example, the Avenue Info request which appeared as:

 

              MsgBox.Info("A sample message string.", "MsgBox Test")

 

would be converted using Avenue Wraps as:

 

              Call avMsgBoxInfo("A sample message string.", "MsgBox Test")

 

Internally, avMsgBoxInfo calls another subroutine passing information, which denotes that the Info request is to be simulated.  By taking the approach to programmatically modify a single form, we avoid the alternative of having to create a unique form for every type of dialog box that is used in the CEDRA software.  So that, the Avenue requests Warning, YesNo and YesNoCancel, as well as Info, all end up calling the same subroutine which in turn uses the same Avenue Wraps form, MessageBox.  Likewise, the other Avenue message box requests, Choice, Input, List, MultiInput and MultiList all end up using the Avenue Wraps form, VDialogBox.  Thus, based upon what information is passed into the controlling subroutine, the appropriate dialog box is displayed.

 

In addition, to simply the conversion of the standard MsgBox requests, additional "wraparounds" were developed to provide for more sophisticated dialog boxes, such as dialog boxes that could contain "drop-down" items in addition to typical data line items.  Shown below is an example of a dialog box created with the VDBbuild subroutine.  So that, not only is VDBbuild used to create the Choice, Input, List, MultiInput and MultiList dialog boxes, it can also be called directly to create the dialog box below.

 

 

Additionally, some CEDRA commands required the use of a horizontal version of VDBbuild.  In the ArcView GIS 3.x environment, the Dialog Designer was used to create the appropriate dialog boxes.  In Avenue Wraps, the subroutine HDBbuild was written to provide the developer a horizontal implementation of VDBbuild.  Shown below is an example of a dialog box created by HDBbuild.

 

 

The VDBbuild and HDBbuild “wraparounds” are examples of where the extended functionality in VB/VBA was used to enhance the appearance of CEDRA's applications.

 

8. Geometry Avenue Wraps

 

This section is similar to the message box section, and converts rather straight forwardly with Avenue Wraps.  However, there are some minor issues that need to be recognized.  For example:

 

q                   To create a point in Avenue, the developer could use the statement:

 

              aPoint = 5000.0 @ 5000.0

 

There is no counterpart for the @ character, so that, the above statement needs to be rewritten as:

 

              Dim aPoint As IPoint

              Set aPoint = avPointMake(5000#, 5000#)

 

Again, note the use of the word Set, when an object is being created.

 

q                   To create a polyline, which is comprised of four vertex points in Avenue, the developer could use the statement:

 

              myLine = PolyLine.Make({{aPt1, aPt2, aPt3, aPt4}})

 

Since, like the @ character, there is no substitution for the left ({) and for the right (}) brace characters, which are used to create a list object, the above statement needs to be converted as follows:

 

              Dim shapeList As New Collection

              Dim partList As New Collection

              Dim aPt1 As IPoint, aPt2 As IPoint, aPt3 As IPoint, aPt4 As IPoint

              Dim myLine As IPolyline

              Call CreateList(shapeList)

              Call CreateList(partList)

              partList.Add aPt1

              partList.Add aPt2

              partList.Add aPt3

              partList.Add aPt4

              shapeList.Add partList

              Set myLine = avPolylineMake(shapeList)

 

It is important to keep in mind the following:

         The Avenue Wrap CreateList simulates the function of the left ({) and of the right (}) brace characters

         When an object is added to a collection, the left parenthesis (() and the right parenthesis ()) characters are not used.  For example, when the point objects aPt1, aPt2, aPt3 and aPt4 are added to partList, and when the collection, partList, is added to shapeList.

 

Using the left and right parenthesis characters, when objects are involved, will result in the display of an error message.

 

As shown in the Section 5 example, it is possible to use the Avenue Wrap, avPolyline2Pt, to create a two-point line.  However, for non two-point line shapes, the approach using the Avenue Wrap, CreateList, will need to be followed.

 

9. User Document Interaction

 

This section pertains to the creation of the graphical user interface (GUI).  That is, the creation of the menu items and tools which are to be made available to the end user.  Unfortunately there is no correspondence in the creation of menu items and tools between the Avenue and VB/VBA environments.  So that, the developer is basically starting from scratch using native VB/VBA functionality to create the GUI.

 

Regarding the use of tools, there is the issue of how the user interacts with the map display.  That is, how is a "pick" made, how is a line, circle or polygon drawn and so forth.  In Avenue there were the ReturnUserPoint, ReturnUserPolyLine, ReturnUserPolygon and so forth requests, which were applied to a Display object.  In VB/VBA, the programmer will need to write code for the type of "event" that is desired.  Every tool will have a certain set of events, for which the programmer can write code for, if desired.  That is to say, the developer does not have to write code for every event that is supported by a tool.  Depending upon the operation of the tool, one or many events can be coded.

 

In the case of the ReturnUserPolyLine request, the developer could write code for the MouseDown event to simulate the request.  To simulate the yellow balloon help message, which was displayed when the user moved the mouse over a tool, code for the tool's ToolTip event could be written.

 

Since VB/VBA provides a far more robust environment for dealing with user-application interaction, this is an area where the developer can truly enhance the Avenue application in the VB/VBA environment.

 

As noted above, there is a difference between VB and VBA, so that if an Active X DLL is to be created, the developer will need to recreate in VB any menu items and tools that were created using VBA.  Although duplicitous, there is no alternative.

 

10. Graphics and Symbols

 

Although not used extensively in CEDRA's applications, the "wraparounds" corresponding to the requests, which operate on graphic elements, were developed to satisfy those used in the Introduction to Avenue training book.  One difference between the Avenue requests and the "wraparounds" is that the "wraparounds" require the developer to specify the type of graphic that is being processed.  For example, to create in Avenue a graphic element which represents a point, the following statement could be used:

 

              aShape = Point.Make(5000.0, 5000.0)

              theShape = GraphicShape.Make(aShape)

 

With ArcObjects, every type of graphic element uses a different interface.  Hence, the easiest way to implement graphic element support is to have the developer pass in the type of graphic element that is being operated on.  As such, the above Avenue statement would be converted into:

 

              Dim aShape As IGeometry

              Dim theShape As IElement

              Set aShape = avPointMake(5000#, 5000#)

              Set theShape = avGraphicShapeMake("MARKER", aShape)

 

The first argument in avGraphicShapeMake denotes the type of graphic element to be created.  This value could be PEN, MARKER or FILL, which correspond to line, point and polygon graphic elements, respectively.

 

Another difference between the Avenue requests and the "wraparounds" is that in the ArcGIS environment, the developer can control which layer (annotation target) the graphics are added to.  In Avenue all graphics, in a view, were added to the view's graphic list.  In the ArcGIS environment, the developer has the option of adding graphics to the basic graphics layer or to any other graphics layer that may exist.  This gives the developer a lot more flexibility in managing graphic elements.

 

11. Classifications and Legends

 

The "wraparounds" for this section were probably the most frustrating to develop because the terminology between Avenue and ArcObjects is so completely different.  For example in Avenue the developer worked with Legends.  The corresponding term in ArcObjects is Renderer.  In addition, the way ArcObjects handles classifications makes it difficult to correlate Avenue requests to ArcObjects.  That is why the "wraparounds" for classifications, such as avInterval, avUnique, etc., operate on the name of the theme rather than on a Legend object.  For example, the Avenue code shown below assigns a single symbol classification to a theme:

 

              theView = av.GetActiveDoc

              thmName = "SomeName"

              aTheme = theView.FindTheme(thmName)

              aLegend = aTheme.GetLegend

              aLegend.SingleSymbol

 

Using Avenue Wraps, the above code would appear as:

 

              Dim pMxApp As IMxApplication

              Dim pmxDoc As IMxDocument

              Dim pActiveView As IActiveView

              Dim pMap As IMap

              Dim thmName As String

              Dim aDesc As String, aLabel As String

              Dim pSym As ISymbol

              Call avGetActiveDoc(pMxApp, pmxDoc, pActiveView, pMap)

              thmName = "SomeName"

              Call avSingleSymbol(pmxDoc, thmName, aDesc, aLabel, pSym)

 

The last three arguments allow the user to control the name of the renderer, the classification name that appears in the Table of Contents, and the symbol used to display all of features in the theme, respectively.  Should the developer wish to use default values, the statement would appear as:

 

              Call avSingleSymbol(pmxDoc, thmName, NULL, NULL, NOTHING)

 

Note that in Avenue the keyword NIL could be used to signify that a variable had no value.  In VB/VBA, the keyword NULL is used for string and variant types, while NOTHING is used for objects.

 

12. Utility Macros

 

Like Avenue, where the scripts are embedded in the ArcView project file, in VBA, the modules, which contain the VBA code, are embedded in the ArcMap document file.  Therefore, if the document file is deleted or becomes corrupt, all of the VBA code would be lost.  To avoid such distasteful situations it is highly recommended that the VBA code be saved to external disk files.  The "wraparound", ExportVBAcode, is provided solely for this purpose.  In addition to exporting all of the VBA modules, the "wraparound" also exports all of the forms that exist in the document file, as well as, all of the Class modules.  Conversely, the "wraparound", LoadVBAcode, can be used to import the modules and forms, which were exported.  Note that the file ThisDocument.cls contains the menu items and tools (GUI) created by the user with VBA.

 

Note that when using VB, not VBA, no source code is stored in the VB project file.  That is, the VB project file simply contains pointers to disk files, which actually contain the source code.  So that, a text editor could be used to modify a file (outside of VB), and then, when VB is invoked, the modifications to the file would be visible to the developer within the VB project file.

 

13. Avenue Wraps Forms

 

In Avenue, the developer could use the Dialog Designer to create a custom form.  In VB/VBA, the form designer is used to create custom forms.  Operating like the Dialog Designer, the VB/VBA form designer enables the designer to add specific types of controls to a form.  Each control has a specific set of properties and associated events.  Thus, the developer is basically starting from scratch using native VB/VBA functionality to create any custom forms.

 

Note that any form created in VBA will need to be recreated in VB.  While VBA modules (source code) can be imported into a VB project file, VBA forms cannot be imported.  They will need to be recreated.  In addition, some VB form controls contain different properties than their VBA counterparts, so the developer has to be aware of this when designing the form.

 

14. Application Deployment Methods

 

Once the application has been tested and is ready for distribution, the programmer can either:

         Package the application as a protected ArcMap template file (.mxt) in the VBA environment, or

         Build an Active X DLL in the VB environment.

 

To package the application as a protected ArcMap template file requires very little work, and is a quick and easy way of deploying an application.  Within minutes, a developer can create a protected ArcMap template file.

 

Building an Active X DLL, on the other hand, requires a fair amount of work.  Depending upon the complexity of the GUI, building an Active X DLL can take anywhere from a few hours to several days.  For clarification, Avenue developers can think of an Active X DLL as an ArcView GIS 3.x extension.  That is, the Active X DLL exists external to the ArcMap document file, much like an extension exists external to the ArcView project file.  Thus, there is an advantage in creating an Active X DLL.

 

In building an Active X DLL the developer operates in the VB environment.  As a by-product of this, the developer will need to recreate the graphical user interface (GUI) that was previously created in the VBA environment, by building Class objects, and writing code for the appropriate events to perform the same functionality provided in the VBA environment.  All of the other VBA modules, however, will not have to be re-written, but rather, they can be loaded in the VB environment as is.

 

Shown below is a possible directory structure for converting an Avenue based application, or developing a new ArcMap based application.

 

 

As can be seen, a top-level directory is created for the application.  Within this directory, three sub-directories are created, Testing, VBAcode and DLL, although any naming convention can be used.  These directories will contain certain information, as described below, which will be established during the conversion or development cycle.

           

The Testing directory is to contain the ArcMap document file appl.mxd, where the application will be initially developed and debugged.  As mentioned above, all of the code modules, forms, etc. are stored within the document file, just like an ArcView GIS 3.x project file contains all of the dialogs and scripts that comprise an application.  Therefore, for safety reasons, it is suggested that the ExportVBAcode “wraparound” be used to export the modules, forms, etc., within the ArcMap document file, into the VBAcode folder.  In so doing, should "tragedy" strike the ArcMap document file, all would not be lost.

 

The VBAcode directory, as stated above, provides a repository for the code modules forms, etc., external to the ArcMap document file.  In addition to providing this service, it is the code modules in this directory that will be added to the VB project file, which is used to create the Active X DLL.

 

The DLL directory is to contain the VB project file appl.vbp, which builds the Active X DLL for the application.  In addition, all of the Class modules and forms comprising the Active X DLL will also be stored in this directory.  Note that the forms created in the VBA environment within the ArcMap document file will need to be recreated in the VB environment.  The code modules in the VBAcode directory will be added to the VB project file without modification.  Thus, the DLL directory will contain only those modules that are specific to building the Active X DLL.  Note that the VB project file does not actually contain the code.  The VB project file only contains pathnames to the files referenced in the project file.  So that, if one of the files referenced by the VB project file is deleted or modified, the VB project file will not function as desired.

 

15. Summary

 

After spending more than five years of developing Avenue based applications, the notion of having to convert all of that code to ArcGIS was a little overwhelming.  However, over the course of a year, the first two months being the most frustrating, the conversion was completed, applications were made available for ArcGIS, and a book, Avenue Wraps, was published.

 

The philosophy of writing equivalent procedures for the Avenue requests truly simplified the conversion process, in that, large blocks of code did not have to be rewritten.  Instead, a simple name substitution could be made.  The examples shown in this paper illustrate this concept.

 

As an additional by-product of this type of approach, developers who are used to programming in Avenue can develop new applications for ArcGIS using the same Avenue approach, with which they are familiar, by using the Avenue Wraps “wraparounds”.

 

Since a direct translator from Avenue to ArcObjects does not exist, the next best solution is to have a library of procedures that emulate Avenue requests.  The authors hope that the information put forth in this paper, and in the Avenue Wraps publication, help Avenue developers move forward to the ArcGIS environment.  Like any new endeavor, the biggest hurdle to overcome is getting started.  In the case of converting Avenue code, the “wraparound” approach makes that first step a little bit smaller to take.

 

Acknowledgements

 

To all those who supplied the sample code included in the ArcObjects Developer Help.  The samples provided a valuable resource in being able to determine how certain tasks could be accomplished.

 

Appendixes

 

End Notes

 

References

 

CEDRA-AVcad, CEDRA-AVcogo, CEDRA-AVland, CEDRA-AVparcel, CEDRA-AVsand and CEDRA-AVwater are trademarks of The CEDRA Corporation, Rochester, New York.

 

ArcView GIS, ArcGIS, ArcObjects and Introduction to Avenue are trademarks of Environmental Systems Research Institute, Inc. (ESRI), Redlands, California.

 

Visual Basic, Visual C++ are registered trademarks of Microsoft, Inc., Redmond, Washington

 

Author Information

 

Constantine N. Tonias, P. E. is a professional civil engineer and president of The CEDRA Corporation.  Graduating from Rensselaer Polytechnic Institute with Bachelor of Science and Masters of Science degrees in Civil Engineering he oversees the research and development operations of the corporation. Mr. Tonias has been responsible for the development of The CEDRA System, an interactive design and drafting system particularly tailored for the civil engineering practice, major portions of which have been ported to ArcView® GIS 3.x and ArcGIS™.  His computer experience also includes the conversion of numerous computing programs between various computing hardware and operating system environments.

 

Organization: The CEDRA Corporation

Address: 65 West Broad Street

Phone: 585-232-6998

Fax: 585-262-2042

E-mail: cedra@cedra.com

 

Elias C. Tonias, P. E., is a professional civil engineer and a pioneer in the application of computers in Civil Engineering.  Mr. Tonias holds a Bachelor of Science degree in Civil Engineering from Rensselaer Polytechnic Institute and a Masters of Science from The Ohio State University and is a technical consultant to The CEDRA Corporation in the development of engineering computing software.  He has written extensively in this field, and has managed the development of a wide variety of software.  Having been involved with software development since the very early days of the computer age, he was forced to go through a series of program conversions from computer environment to computer environment.

 

Organization: Tonias Engineers

Address: 65 West Broad Street

Phone: 585-232-6995

Fax: 585-262-2042

E-mail: ect@tonias.com