ArcObjects – Using VB.NET to Perform Spatial Query and Get Fields Value of Desired Layer

arcobjectsspatial-queryvb.net

Currently I am using ArcObjects (10.2.1) in vb.net (vs 2012). What I intent to develop is a spatial query tool. There are 2 steps in the function:

(1) Use "Select Features" tool in ArcMap to select features in a certain area.

(2) List the several fields of features selected of a layer.

My question is how to get the field values only for a desired feature layer. My code is listed below. It only works when only the desired layer is enabled on ArcMap.

    Dim pMxDoc As IMxDocument
    Dim pMap As IMap
    Dim pEnumFeature As IEnumFeature
    Dim pEnumFeatureSetup As IEnumFeatureSetup
    Dim pFeature As IFeature

    pMxDoc = My.ArcMap.Document
    pMap = pMxDoc.FocusMap
    pEnumFeature = pMap.FeatureSelection
    pEnumFeatureSetup = pEnumFeature
    pEnumFeatureSetup.AllFields = True
    pFeature = pEnumFeature.Next

    Dim layerNum = GetIndexNumberFromLayerName(pActiveView, "testdb.DBO.testTable")
    pFeatSel = pMap.Layer(layerNum)

    Dim tempArr As New List(Of String)
    Do While (Not pFeature Is Nothing)
        tempArr.Add(pFeature.Value(pFeature.Fields.FindField("Item_ID")).ToString)
        pFeature = pEnumFeature.Next
    Loop

    Dim message = String.Join(Environment.NewLine, tempArr.ToArray())
    Dim lstOfString As List(Of String) = New List(Of String)(tempArr)
    Dim selectedCount = lstOfString.Count

    End If


Public Function GetIndexNumberFromLayerName(ByVal activeView As ESRI.ArcGIS.Carto.IActiveView, ByVal layerName As System.String) As System.Int32

    If activeView Is Nothing OrElse layerName Is Nothing Then
        Return -1
    End If

    Dim map As ESRI.ArcGIS.Carto.IMap = activeView.FocusMap
    Dim numberOfLayers As System.Int32 = map.LayerCount
    Dim i As System.Int32 = 0
    Do While i < numberOfLayers
        If layerName = map.Layer(i).Name Then
            Return i
        End If
        i += 1
    Loop
    Return -1
    LayerNumber = i
End Function

Best Answer

I think you are making this more difficult than it has to be. You are obtaining your selected features from IMap.FeatureSelection. So multiple layers could return a selection.

A much better way is to get a handle on your ILayer, cast that into an IFeatureLayer then point an IFeatureSelection interface to IFeatureLayer. From this you can get an ISelectionSet. This has a Search method which returns a cursor over the selection in that specific layer.

Here is a bit of sample code:

Dim pFeatureSelection As IFeatureSelection
pFeatureSelection = pFeatureLayer

Dim pSelectionSet As ISelectionSet
pSelectionSet = pFeatureSelection.SelectionSet

Dim pFeatureCursor As IFeatureCursor = Nothing
pSelectionSet.Search(Nothing, True, pFeatureCursor)
Related Question