Help with IFeatureLayer

2961
9
Jump to solution
06-18-2012 05:48 AM
DaveCouture
New Contributor III
Iâ??m trying to create a simple Query, with VS2010. All I want to do is have a Selection by Attribute, using a Geodatabase Feature Class in the ActiveView. Iâ??m using the SelectMapFeaturesByAttributeQuery Snippet, but the code is a little unclear as to how I invoke the Feature Class by it's name, and not by order (Layer(0))

Imports ESRI.ArcGIS.esriSystem
Imports ESRI.ArcGIS.Geometry
Imports ESRI.ArcGIS.Geodatabase
Imports ESRI.ArcGIS.Carto
Public Class Button1
  Inherits ESRI.ArcGIS.Desktop.AddIns.Button

  Public Sub New()

  End Sub

  Protected Overrides Sub OnClick()

        SelectMapFeaturesByAttributeQuery(My.ArcMap.Document.ActiveView, ??????, "PID = '00000000'")

        My.ArcMap.Application.CurrentTool = Nothing
  End Sub

  Protected Overrides Sub OnUpdate()
    Enabled = My.ArcMap.Application IsNot Nothing
  End Sub


    Public Sub SelectMapFeaturesByAttributeQuery(ByVal activeView As IActiveView, ByVal featureLayer As IFeatureLayer, ByVal whereClause As System.String)

        If activeView Is Nothing OrElse featureLayer Is Nothing OrElse whereClause Is Nothing Then
            Return
        End If

        Dim featureSelection As IFeatureSelection = TryCast(featureLayer, IFeatureSelection) ' Dynamic Cast

        ' Set up the query
        Dim queryFilter As IQueryFilter = New QueryFilterClass
        queryFilter.WhereClause = whereClause

        ' Invalidate only the selection cache. Flag the original selection
        activeView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, Nothing, Nothing)

        ' Perform the selection
        featureSelection.SelectFeatures(queryFilter, esriSelectionResultEnum.esriSelectionResultNew, False)

        ' Flag the new selection
        activeView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, Nothing, Nothing)

    End Sub
0 Kudos
1 Solution

Accepted Solutions
AlexanderGray
Occasional Contributor III
Yes, there a lot of things kind of strange with this forum...  People posting questions and then posting an answer and marking their own post as the answer post.  However, the points are browny points anyway and the value comes from the users not from the points.

As far as getting the correct layer, yes the code you posted should work as long as you have the option strict off (which I don't recommend.)  Option strict forces you to explicit cast (type conversion) to the specific type before you pass in an argument to a method.  In your case, your method signature calls for an IFeatureLayer.  Your method passes in an ILayer.  That works fine as long as the ILayer happens to be a FeatureLayer.  All FeatureLayers implement ILayer but lots of other types of layers implement ILayer such as grouplayer, rasterlayer, etc. and don't implement IFeatureLayer.  Explicitly casting your ILayer to IFeatureLayer is a better practice.

Dim fLayer as IfeatureLayer = ctype(pMap.Layer(0), IFeatureLayer) SelectMapFeaturesByAttributeQuery(pMap.ActiveView, flayer, "PID = '00000000'")


Now there is always the chance the first layer in the map is not a featurelayer, in which case the first line would fail

if typeof pMap.Layer(0) is IFeatureLayer then   Dim fLayer as IfeatureLayer = ctype(pMap.Layer(0), IFeatureLayer)   SelectMapFeaturesByAttributeQuery(pMap.ActiveView, flayer, "PID = '00000000'") End if


or better yet, trycast returns nothing if the cast fails
Dim fLayer as IfeatureLayer = trycast(pMap.Layer(0), IFeatureLayer) if fLayer isnot Nothing then   SelectMapFeaturesByAttributeQuery(pMap.ActiveView, flayer, "PID = '00000000'") end if


You can write a for loop to go from 0 to pMap.LayerCount -1 and look at the layer of featureclass name.  However, if you hit a group layer, it will be skipped and you will never look at the sub layers and also the code will crash if your map is empty (you can check the layercount before calling.)  I prefer to use the IMap.Layers method.

Dim featLayerUid As New UIDClass featLayerUid.Value = "{40A9E885-5533-11D0-98BE-00805F7CED21}" 'IFeatureLayer Dim enumLayer As IEnumLayer = pMap.Layers(featLayerUid , True)  'True argument looks at sub layers in a group enumLayer.Reset() Dim layer As ILayer = enumLayer.Next Do While Not (layer Is Nothing)       dim fLayer as IFeatureLayer = CType(layer, IFeatureLayer) 'Guaranteed to work since only querying IFeatureLayers.       if ctype(fLayer.FeatureClass, IDataset).Name = "Name_I_am_looking_for" then            SelectMapFeaturesByAttributeQuery(pMap.ActiveView, fLayer, "PID = '00000000'")            exit do       end if       layer = enumLayer.Next() Loop    

View solution in original post

0 Kudos
9 Replies
AlexanderGray
Occasional Contributor III
First off there is a difference between featureclass and featurelayer.  The featureclass is the data source (like a table) and the featurelayer is the representation of the data (like a report.)  The featurelayer may or may not have the same name as the featureclass.
You still have to loop through the layers of the map using the layer index and look for the layer name.  If you need to compare the featureclass name and get the featureclass from the featurelayer.
Cheers
0 Kudos
DaveCouture
New Contributor III
Thanks Alexander. I understand what you are saying, but I have no idea how to do it (yet). I just started to learn VS2010 and ArcGIS 10. I'm familiar with VBA , but I'm not familiar with ArcGIS Development kit.

I'll try to get it to work, nontheless!

Let's assume there's only one layer (Feature Class), loaded in ArcMap. What would be the argument, then?

Dim pMap = My.ArcMap.Document
SelectMapFeaturesByAttributeQuery(pMap.ActiveView, pMap.Layer(0), "PID = '00000000'")
0 Kudos
DaveCouture
New Contributor III
No takers, eh?  I just need to know how to select the first layer, then I'm done!
0 Kudos
LeoDonahue
Occasional Contributor III
I wasn't going to reply, because it seemed more of a nitpick and me being somewhat rude.

However, why would you mark a previous reply as the answer and still not have a solution to your problem?  Doesn't seem right.  I'm just saying what most people are probably thinking.
0 Kudos
DaveCouture
New Contributor III
Sorry, but he did give me a valid answer, but it wasn't the solution to my problem.  I just make a difference between the two, but I guess this forum works differently.  I can remove it, if that's the reason why I don';t get replies.
0 Kudos
LeoDonahue
Occasional Contributor III
I'm not saying remove Alexander's points, I'm just asking why mark a thread as answered when you still don't have the answer you need?
0 Kudos
DaveCouture
New Contributor III
I made a mistake and I tried to change the Checkmark, but it didn't allowed me.  What was I suppose to do?
0 Kudos
AlexanderGray
Occasional Contributor III
Yes, there a lot of things kind of strange with this forum...  People posting questions and then posting an answer and marking their own post as the answer post.  However, the points are browny points anyway and the value comes from the users not from the points.

As far as getting the correct layer, yes the code you posted should work as long as you have the option strict off (which I don't recommend.)  Option strict forces you to explicit cast (type conversion) to the specific type before you pass in an argument to a method.  In your case, your method signature calls for an IFeatureLayer.  Your method passes in an ILayer.  That works fine as long as the ILayer happens to be a FeatureLayer.  All FeatureLayers implement ILayer but lots of other types of layers implement ILayer such as grouplayer, rasterlayer, etc. and don't implement IFeatureLayer.  Explicitly casting your ILayer to IFeatureLayer is a better practice.

Dim fLayer as IfeatureLayer = ctype(pMap.Layer(0), IFeatureLayer) SelectMapFeaturesByAttributeQuery(pMap.ActiveView, flayer, "PID = '00000000'")


Now there is always the chance the first layer in the map is not a featurelayer, in which case the first line would fail

if typeof pMap.Layer(0) is IFeatureLayer then   Dim fLayer as IfeatureLayer = ctype(pMap.Layer(0), IFeatureLayer)   SelectMapFeaturesByAttributeQuery(pMap.ActiveView, flayer, "PID = '00000000'") End if


or better yet, trycast returns nothing if the cast fails
Dim fLayer as IfeatureLayer = trycast(pMap.Layer(0), IFeatureLayer) if fLayer isnot Nothing then   SelectMapFeaturesByAttributeQuery(pMap.ActiveView, flayer, "PID = '00000000'") end if


You can write a for loop to go from 0 to pMap.LayerCount -1 and look at the layer of featureclass name.  However, if you hit a group layer, it will be skipped and you will never look at the sub layers and also the code will crash if your map is empty (you can check the layercount before calling.)  I prefer to use the IMap.Layers method.

Dim featLayerUid As New UIDClass featLayerUid.Value = "{40A9E885-5533-11D0-98BE-00805F7CED21}" 'IFeatureLayer Dim enumLayer As IEnumLayer = pMap.Layers(featLayerUid , True)  'True argument looks at sub layers in a group enumLayer.Reset() Dim layer As ILayer = enumLayer.Next Do While Not (layer Is Nothing)       dim fLayer as IFeatureLayer = CType(layer, IFeatureLayer) 'Guaranteed to work since only querying IFeatureLayers.       if ctype(fLayer.FeatureClass, IDataset).Name = "Name_I_am_looking_for" then            SelectMapFeaturesByAttributeQuery(pMap.ActiveView, fLayer, "PID = '00000000'")            exit do       end if       layer = enumLayer.Next() Loop    
0 Kudos
DaveCouture
New Contributor III
Thanks a bunch - it's working!!
0 Kudos