is there a way to get ALL attributes of ONE feature

1293
10
Jump to solution
06-15-2012 04:07 AM
MauriceSchoenert
New Contributor
hi,

I can't find the proper interface, if there is one, to retrieve the values of one feature in an attribute table:

For Example, this code  :

Dim pMxDoc As IMxDocument Set pMxDoc = Application.Document Dim pMap As IMap Set pMap = pMxDoc.FocusMap Dim pActiveView As IActiveView Set pActiveView = pMap Dim pFeatureLayer As IFeatureLayer Set pFeatureLayer = pMap.Layer(0) Dim pFeatureSelection As IFeatureSelection Set pFeatureSelection = pFeatureLayer   Set pTable = pFeatureLayer.FeatureClass Dim pFClass As IFeatureClass Set pFClass = pFeatureLayer.FeatureClass Dim pFCursor As IFeatureCursor Set pFCursor = pFClass.Update(Nothing, False) Dim pF As IFeature Set pF = pFCursor.NextFeature   Do Until pF Is Nothing ListBox3.AddItem pF.Value(6) Set pF = pFCursor.NextFeature Loop


gives me all values of all features at index(6) of my attribute table.
I'm trying to get all values of just one feature.

The ICursor / IRow Interface works, if i got it right, the same way as the IFeatureCursor/ IFeature interface, both "moving vertically"  (NextRow/NextFeature)
Is there something like ~ NextColumn to move the Cursor "horizontal"?


Thanks for your help
0 Kudos
1 Solution

Accepted Solutions
JoeHershman
MVP Regular Contributor
When you get a cursor from SelectionSet it is a read only cursor so you cannot do an Update on it.  To do an Update you need to get an Update cursor from the IFeatureClass::Update method (likewise if you want to do an Insert you need an InsertCursor).

Also I am not sure how you access your tool but need to be editing when you do an update.  Depending on how you got to the workspace that might be something you have to do in your application

Good Luck
Thanks,
-Joe

View solution in original post

0 Kudos
10 Replies
KenBuja
MVP Esteemed Contributor
What you want to do is cycle through all the fields for the feature to get their values

dim i as integer
for i = 0 to pF.Fields.FieldCount - 1
  if pF.Fields.Field(i).Type < 6 then 'this line adds only the numeric, text, and date field attributes, not the Shape or OID field or other types
    ListBox3.AddItem pF.Value(i)
  end if
next
0 Kudos
VivekPrasad
Occasional Contributor
Use "QueryFilter" with proper "WhereClause" property set to it.

http://help.arcgis.com/en/sdk/10.0/arcobjects_net/componenthelp/index.html#/IQueryFilter_Interface/0...

Pass the object of "IQueryFilter" as a parameter on calling "Search" or "Update" cursors as a first parameter instead of �??Nothing�?�.

Have a look at the below example�?�

Eg:

Dim pQFilter As IQueryFilter
Set pQFilter = New QueryFilter
   
pQFilter.WhereClause = �??<<>>�?�

Set pFCursor = pFClass.Update(pQFilter, False)
0 Kudos
MauriceSchoenert
New Contributor
Hi,

thank you Ken and Vara for ur replies: i tried both ur recommendations

I didn't get to work the QueryFilter, maybe because of the syntax: I tried
pQFilter.WhereClause = �??FID = " & strBEZUserForm3 &"�?�
but I don't know how to proceed to read out the Features Attributes defined by that QueryFilter. (For k = 0 To pF.Fields.FieldCount - 1 just gives me the first Row (Index=0), rather then the Feature's Attributes defined by the QueryFilter)

The  #     For k = 0 To pF.Fields.FieldCount - 1     # cylce works fine and is just what i like to do, but is there a way to tell the programm, which Row it should read out, like an index? I'm trying to create a userform, in which the User is in the end able to edit Features. first he selects the particular feature and then a userform pops up where the Feature's Attributes are shown (see following Code/Attachment(Screenshot): Litsbox3)

big thank you for ur help!!!


'This is UserForm5
Private Sub UserForm_Initialize()

Dim strBEZUserForm3 As String
Dim strFIDUserForm3 As String
Dim i As Integer
Dim j As Integer

'User selected a unique Feature: Storing his choice (made in UserForm3) in ListBox1 by name (the name just aims at visualization purposes)
'and in ListBox3 by its identificationnumber (the ID is unique)
For j = 0 To 550
For i = 0 To 550
    If UserForm3.ListBox1.Selected(i) = True Then
    'Uncomment Me: 'ListBoxXXX.AddItem UserForm3.ListBox1.List(i)
    strBEZUserForm3 = UserForm3.ListBox1.List(i)
    ListBox1.AddItem strBEZUserForm3
    End If
Next i
If UserForm3.ListBox2.Selected(j) = True Then
    'Uncomment Me: 'ListBoxXXX.AddItem UserForm3.ListBox2.List(j)
    strFIDUserForm3 = UserForm3.ListBox2.List(j)
    ListBox2.AddItem strFIDUserForm3
    End If
Next j

'MsgBox strBEZUserForm3
'MsgBox strFIDUserForm3

ListBox3.ColumnCount = 2

Dim pMxDoc As IMxDocument
Set pMxDoc = Application.Document
Dim pMap As IMap
Set pMap = pMxDoc.FocusMap
Dim pActiveView As IActiveView
Set pActiveView = pMap
Dim pFeatureLayer As IFeatureLayer
Set pFeatureLayer = pMap.Layer(0)


Dim pFClass As IFeatureClass
Set pFClass = pFeatureLayer.FeatureClass
Dim pFCursor As IFeatureCursor
Set pFCursor = pFClass.Update(Nothing, False)
Dim pF As IFeature
Set pF = pFCursor.NextFeature

'Trying to load the (User's choice) feature's attributes into ListBox3
'Trying to identify the feature by it's identificationnumber (= ID, stored in Attribute Table field "FID" / respectively stored in Listbox3)
'In theory i should loop through the Rows/features and look for the ID,
'if it is found, the programm should return the feature's attributes (like the following For-Next Loop does)
'but how to tell the programm which feature's attributes to return?
'I tried to build a Do-While-Loop around the For-Next Statement, questioning: If pF.Value(k)= strFIDUserForm3 Then
'That's not working, because it's more setting the Value rather then comparing it

Dim k As Integer
For k = 0 To pF.Fields.FieldCount - 1
  If pF.Fields.Field(k).Type < 6 Then 'this line adds only the numeric, text, and date field attributes, not the Shape or OID field or other types
    ListBox3.AddItem pF.Value(k)
  End If
Next k



Unload UserForm3

End Sub



[ATTACH=CONFIG]15269[/ATTACH]
0 Kudos
JoeHershman
MVP Regular Contributor
A cursor is not indexed it only allows you to loop through the features to get access to an individual feature.


What I would suggest for what you are trying to accomplish is to create an object which holds the attributes of the Feature (or the feature itself).  You could load something like a listbox or tree with a collection of those features.  When the user selects a feature from your list it then populates the edit list.  Look at the Identify tool, that would be a good example of a UI like what I mean, but there are other ways for the user to enter what feature he wants.  Something along these lines is what I mean



        List<MyFeature> _myFeatures = new List<MyFeature>();
        
        private void LoadTree(object sender, EventArgs e)
        {
            //do stuff to get your cursor


            IFeature feature = cursor.NextFeature();
            while ( feature != null )
            {
                MyFeature myFeature = new MyFeature();
                myFeature.Feature = feature;
                myFeature.Name = feature.Value[(feature.Fields.FindField("displayFieldName"))].ToString();
                myFeature.ObjectId = feature.OID;


                _myFeatures.Add(myFeature);
                feature = cursor.NextFeature();
            }


            treeView.AfterSelect += TreeNodeSelected;
            TreeNode parentNode = treeView.Nodes.Add("Features");
            foreach ( var myFeature in _myFeatures )
            {
                TreeNode child = parentNode.Nodes.Add(myFeature.ObjectId.ToString(), myFeature.Name);
            }
        }


        private void TreeNodeSelected(object sender, TreeViewEventArgs e)
        {
            MyFeature myFeature = _myFeatures.FirstOrDefault(f => f.ObjectId.ToString() == e.Node.Name);
            //loop through field on myFeature.Feature like before
        }
    }


    public class MyFeature
    {
        public int ObjectId { get; set; }
        public string Name { get; set; }
        public IFeature Feature { get; set; }
    }







The above code is meant to give an idea of an approach, it is not tested code

Hope that helps
Thanks,
-Joe
0 Kudos
MauriceSchoenert
New Contributor
Hi Joe,

the user already identified the feature in a prior formular and it is ?selected? by a query definition, so that the attribute table just shows one highlighted feature.
Do u mean by "create an object which holds the attributes of the Feature" something like a 'selectionSet' from the 'IFeatureSelection Interface'. I'm sorry, i'm new to arcObject, so i just know little about its Methods and properties.
0 Kudos
JoeHershman
MVP Regular Contributor
OK I was not clear on everything when I wrote my description, it sounds like you are already selecting the feature.  Then you don't want to use something like selection set you want to use exactly IFeatureSelection::SelectionSet :).  You can call Search on the ISelectionSet to get the selected item and then using the previous code display all the fields values in your list

Hope that helps
Thanks,
-Joe
0 Kudos
MauriceSchoenert
New Contributor
thx a lot guys! it worked! Now i just need to write the code to edit.. 😉
see also: http://forums.esri.com/Thread.asp?c=93&f=993&t=267503


'
Private Sub UserForm_Initialize()

Dim strBEZUserForm3 As String
Dim strFIDUserForm3 As String
Dim i As Integer
Dim j As Integer

'Populating the ListBox1 and ListBox2 with the user's choice feature [now really unnecessary]
For j = 0 To 550
For i = 0 To 550
    If UserForm3.ListBox1.Selected(i) = True Then
    'Uncomment Me: 'ListBoxXXX.AddItem UserForm3.ListBox1.List(i)
    strBEZUserForm3 = UserForm3.ListBox1.List(i)
    ListBox1.AddItem strBEZUserForm3
    End If
Next i
If UserForm3.ListBox2.Selected(j) = True Then
    'Uncomment Me: 'ListBoxXXX.AddItem UserForm3.ListBox2.List(j)
    strFIDUserForm3 = UserForm3.ListBox2.List(j)
    ListBox2.AddItem strFIDUserForm3
    End If
Next j

'MsgBox strBEZUserForm3
'MsgBox strFIDUserForm3

'ListBox3.ColumnCount = 2

Dim pMxDoc As IMxDocument
Set pMxDoc = Application.Document
Dim pMap As IMap
Set pMap = pMxDoc.FocusMap
Dim pActiveView As IActiveView
Set pActiveView = pMap
Dim pFeatureLayer As IFeatureLayer
Set pFeatureLayer = pMap.Layer(0)

'Connect Interfaces/Set proterties (the Feature/Row is still selected due to prior Definition Query in UserForm3)
Dim pFSelection As IFeatureSelection
Set pFSelection = pFeatureLayer
'Pointing the Cursor to the selected Feature/Row
Dim pFCursor As IFeatureCursor
pFSelection.SelectionSet.Search Nothing, False, pFCursor

Dim pF As IFeature
Set pF = pFCursor.NextFeature

'Getting the value of the selected feature into the ListBox3
Dim k As Integer
For k = 0 To pF.Fields.FieldCount - 1
'the following line adds only the numeric, text, and date field attributes, not the Shape or OID field or other types
If pF.Fields.Field(k).Type < 6 Then
ListBox3.AddItem pF.Value(k)
End If
Next k


Unload UserForm3

End Sub
0 Kudos
MauriceSchoenert
New Contributor
Hi, its me again xD

my problem: i cant update the Value of the Attribute Table with the "pFCursor.UpdateFeature pF" method
My wild guess is: because i try to write string expression (from InputBox) into long/Double/etc Fields of the Attribute Table, but even though when i write string to a string Attribute-Table-field it isnt working??
The thing is: i can get/store the Value (strAnwAuswahl = pF.Value(intPlusIndex)) of that particular Field, but cannot set it (pF.Value(intPlusIndex) = strAnwEingabe) ??



...
Dim pFSelection As IFeatureSelection
Set pFSelection = pFeatureLayer
Dim pFCursor As IFeatureCursor
pFSelection.SelectionSet.Search Nothing, False, pFCursor
Dim pF As IFeature
Set pF = pFCursor.NextFeature


'Hilfvariablen deklarieren
Dim intPlusIndex As Integer
Dim strAnwAuswahl As String
Dim strAnwEingabe As String
Dim strFeldName As String


If ListBox3.Selected(ListBox3.ListIndex) = True Then
intPlusIndex = ListBox3.ListIndex + 2
strAnwAuswahl = pF.Value(intPlusIndex)                      'can read
MsgBox strAnwAuswahl
ListBox4.Selected(ListBox3.ListIndex) = True
strFeldName = ListBox4.Value
strAnwEingabe = InputBox("Der Wert des Feldes '" & strFeldName & "' ist '" & strAnwAuswahl & "'. Zum ändern geben Sie einen neuen Wert ein:", "Neuen Wert setzen", "Geben Sie hier den neuen Wert ein")
MsgBox strAnwEingabe


pF.Value(intPlusIndex) = strAnwEingabe     'but cannot write
pFCursor.UpdateFeature pF

'If pF.Fields.Field(intPlusIndex).Type < 4 Then
'a = CLng(strAnwEingabe)
'End If

End If


End Sub
0 Kudos
JoeHershman
MVP Regular Contributor
When you get a cursor from SelectionSet it is a read only cursor so you cannot do an Update on it.  To do an Update you need to get an Update cursor from the IFeatureClass::Update method (likewise if you want to do an Insert you need an InsertCursor).

Also I am not sure how you access your tool but need to be editing when you do an update.  Depending on how you got to the workspace that might be something you have to do in your application

Good Luck
Thanks,
-Joe
0 Kudos