GEOG 490/590: GIS Programming
Lab4. ArcMap Layers
Display & Attribute Data Manipulation
Due Nov 15 before class.
Introduction:
Hooray! No more ESRI online
courses!
You will create a Layers &
Attribute Manipulation (LAM) AP that mimics what the instructor demonstrated in
class. You should find several small shapefiles to
use as test data. The shapefiles must have numerical
attribute fields. One good example is the RLIS census track dataset on the I drive. The specifications of the AP follow.
Layers & Attribute Manipulation (LAM) Tool:
The LAM Tool (Figure 1) allows users to add/delete GIS data layers to/from the active ArcMap map frame. A list box shows the names of the layers that are added to the frame. The order of the items in the list box can be changed and is linked with the display order in ArcMap (Figure 2). Once an item in the layer list is selected, its attribute fields can be displayed in a attribute list box. Users can select a numerical field from the attribute list box to display its minimum, maximum, and average. A sample layout of the UserForm of the AP is shown in Figure 3. The form should have:
l Two command buttons for adding / removing layers from the display list.
l Two command buttons for moving a selected layer up and down the display list.
l Two list boxes for showing the names of map layers and attribute fields.
l A command button for showing the attribute fields.
l A command button for calculating the summary statistics of a selected numerical field.
l Three text box for displaying the minimum, maximum, and average.
l A command button to clear the layer list and reset the AP.
l You also need to add labels to annotate the objects on the form.
Add Layer
Command Button:
You will use the GxDialog object that you used in
Lab 3 to select a GIS layer. You need to change the GxObjectFilter
type to GxFilterDataset. That is:
Dim pFilter
As IGxObjectFilter
Set pFilter
= New GxFilterDatasets
Once the GxDialog object returns a value
successfully, you can use the following procedures to display the map.
Dim pFLayer As IfeatureLayer
Set pFLayer = New FeatureLayer
Set pFLayer.FeatureClass = pGxDataset.Dataset
pFLayer.Name = pGxDataset.Dataset.Name
'add
the feature layer to the active map
pMap.AddLayer pFLayer
pMxDoc.ActivatedView.Refresh
You also need to add the name of the
layer to the Layer list box. Please note that the AddLayer
method of a Map object adds a layer to the top of the TOC (Table of Contents)
of the map while the AddItem method of a list box
adds an item to the end of the list. One easy way to synchronize the TOC and
the list box is, whenever a layer is added or removed, the program resets the
list box and displays the updated TOC. The same procedure will be used when the
order of the items in the layer list is modified. This is a good reason for us
to create a private subroutine to update the list box using map layer
information. Add the following code to the UserForm. Please note that you have to declare pMap object variable as a form-level variable (i.e.,
outside any sub or function) and instantiate it when the UserForm
is initialized. Also, the sample code is just for your reference, you must read
it carefully and modify it to fit your AP.
Private Sub DisplayLayerNames()
Dim layercounter
As Integer
Dim i As Integer
lstLayer.Clear 'reset the lstLayer
list box
'add the
layer name to the list box
layercounter = pMap.LayerCount
- 1
For i =
0 To layercounter
lstLayer.AddItem
pMap.Layer(i).Name
Next
End Sub
When you need to update the Layer
list box, just enter DisplayLayerName in your
program. You can find an example of using this subroutine in the Move Down/Up section below.
Remove Layer
Command Button:
When a user clicks on an item in the
Layer list box, the Remove Layer command button becomes enabled. You will use
the DeleteLayer method of a map object to remove a
layer. You also need to remove the selected item from the Layer list box. As
mentioned earlier, you can use the DisplayLayerNames
subroutine to sync the list box, or use the RemoveItem
method of a list box to remove the item. You also need to check if there is any
layer left in the list box. If none left, then you need to disable the Remove
Layer button.
Dim pFLayer
As IFeatureLayer
Set pFLayer
= pMap.Layer(lstLayer.ListIndex)
pMap.DeleteLayer pFLayer
lstLayer.RemoveItem
lstLayer.ListIndex
pMxDoc.ActivatedView.Refresh
If lstLayer.ListCount
= 0 Then cmbRemoveLayer.Enabled = False
Move Down/Move
Up Command Buttons & Layer List Box:
To use the Move Down/Move Up
functions, the user has to select an item from the Layer list box first. Then,
depending on which item is selected, the program enables or disables the Move
Down or Move Up buttons. The code to control these actions needs to be put in
the Click event procedure (i.e., lstLayer_Click(), when the name of the Layer list box is lstLayer.) The ListIndex property
of the list box tells you which item in the list is selected. When an item in
the Layer list box is selected, the Remove Layer and Show Attribute Fields command
buttons are enabled.
Private Sub lstLayer_Click()
cmbShowAtt.Enabled
= True
cmbRemoveLayer.Enabled
= True
'don't
enable up or down button when there's only one layer
If lstLayer.ListCount
= 1 Then Exit Sub
'enable
the down button when the selected layer
'is
not the last layer
If lstLayer.ListIndex
< (lstLayer.ListCount - 1) _
Then cmbDown.Enabled
= True Else cmbDown.Enabled = False
'enable
the up button when the selected layer
'is
not the first layer
If lstLayer.ListIndex
> 0 Then cmbUp.Enabled = True _
Else cmbUp.Enabled
= False
End Sub
The MoveLayer method of a map object allows you
to rearrange the display order of a layer in a map object. You will need to know
the position the layer is moved to and a pointer that points to the layer that
is to be moved. Below is the sample code for the Move Down button. The Move Up
button uses the same logic.
Private Sub cmbDown_Click()
Dim position As Long
position
= lstLayer.ListIndex
'assign
reference to pFLayer
Dim pFLayer
As IFeatureLayer
Set pFLayer
= pMap.Layer(position)
'swap
the layer listbox
pMap.MoveLayer
pFLayer, position + 1
'refresh
the active map and the layer list box
pMxDoc.ActivatedView.Refresh
DisplayLayerNames
'keep
the selected item being selected after the move
lstLayer.ListIndex
= position + 1
End Sub
Show Attribute
Field Command Button:
When the Show Attribute Fields command button is clicked, the names and
types of the attribute fields of the select map layer are displayed in the
Attribute list box. Please refer to Week5’s lecture notes for retrieving
the name and type information of the fields in an attribute table. Check the
notes on the IFields and IField interfaces. After you retrieve the field information, use the code below
to add them to the Attribute list box.
Dim fcount As
Long, i As Long
fcount = pFields.FieldCount - 1
lstAttList.Clear
For i = 0 To fcount
Set aField = pFields.Field(i)
lstAttList.AddItem
aField.Name & ", " & aField.Type
Next
Summary
Statistics Command Button & Attribute List Box:
The final piece of the LAM AP is finding the minimum and maximum of a
selected numerical attribute field and calculating its average value. You have
to check if the field you selected is a numerical field. If yes, then you
enable the Summary Statistics button. Disable the Summary Statistics button
otherwise. You have extracted field type information when creating the
Attribute list and stored type information in the list items. You can get the
type information from the list items without accessing the attribute table of
the map layer. Here is how it’s done in the Click event of the Attribute
list box. Please read the code carefully because it contains important
information. For example, you should know that when the value of the field type
property is smaller then 4 (i.e., 0, 1, 2, and 3), then the field is a
numerical field (see lecture note a complete list of field types.)
Private Sub lstAttList_Click()
Dim atttype As
Integer
Dim attstr As
String
'check the
attribute type
attstr
= lstAttList.List(lstAttList.ListIndex)
'extract the
attribute type information from the string
atttype
= Right(attstr, Len(attstr)
- InStr(attstr,
","))
'numerical data
types are:
'samll integer(0), long
integer(1), single(2), and double(3)
If atttype <=
3 Then
cmbStats.Enabled
= True
'reset the
text in the textbox
txtMin.Text =
""
txtMax.Text =
""
txtAverage.Text = ""
Else
cmbStats.Enabled
= False
End If
End Sub
Once you have a numerical field selected, the next step is to read the
values of its records and find the min/max/mean values. Please refer to
Week5’s lecture notes to see how to get the values from an attribute
table. You will need to use the ICursor and IFeature interfaces
for this task.
You don’t have to store the values you read in an array to find the
min/max/mean values. The code below is an example of finding/calculating these
numbers. You begin the procedures by setting the minimum (attmin)
to the largest number you can get and the maximum (attmax)
to the smallest number. A variant type variable (attsum), initialized to 0, holds the sum of all numbers you
retrieve from the attribute table. Then use a loop to compare the minimum and
maximum with the number you retrieve and add the number to attsum.
Dim attmin, attmax, attsum, tempval
'initialize values
attmin = 2147483647
attmax
= -2147483648#
attsum
= 0
nrecord
= pFLayer.FeatureClass.FeatureCount(Nothing)
Dim aFeature As IFeature
'find min, max,
and sum of all values
For i = 1 To nrecord
Set aFeature
= pCursor.NextFeature
tempval
= aFeature.Value(lstAttList.ListIndex)
If tempval
< attmin Then attmin = tempval
If tempval
> attmax Then attmax = tempval
attsum
= attsum + tempval
Next
'update output
textboxes
txtMin.Text = Format(attmin, "0.000")
txtMax.Text = Format(attmax, "0.000")
txtAverage.Text =
Format(attsum / nrecord, "0.000")
Clear Map
Command Button:
The Clear Map button removes all
layers from the map and reset every control on the UserForm.
'clear
layers in the active map frame
pMap.ClearLayers
'clear
the TOC
pMxDoc.UpdateContents
'refresh
the map document
pMxDoc.ActivatedView.Refresh
'clear
attribute and layer lists
lstAttList.Clear
lstLayer.Clear
Lab Deliverables:
Don’t forget to
test/debug your AP. Try different ways of using the AP and see if that
generates any error or unpredictable behavior. Submit your zipped mxd file. The mxd file must have
the following features:
1.
A UserForm and its associated procedures of the LAM AP.
2.
An ArcMap ToolBar containing a
button that when clicked brings up the UserForm.
3.
Make sure
your code is properly commented.