GEOG 490/590: GIS Programming
Lab4. ArcMap Layers Display & Attribute Data Manipulation
Due Feb 25 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 an 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.