Lesson 4: Practice 4

Solution:

 

    Public Sub Practice4()

 

        Dim pMxDoc As IMxDocument

        pMxDoc = My.ArcMap.Application.Document

 

        Dim pMap As IMap

        pMap = pMxDoc.FocusMap

 

        Dim pLayer As ILayer

        Dim pLayers As IEnumLayer

        Dim pStateLayer As IFeatureLayer

        Dim pRoadLayer As IFeatureLayer

 

        pLayers = pMap.Layers

        pLayer = pLayers.Next

 

        Do Until pLayer Is Nothing

            If pLayer.Name = "us_boundaries" Then

                pStateLayer = pLayer

            ElseIf pLayer.Name = "us_roads" Then

                pRoadLayer = pLayer

            End If

 

            pLayer = pLayers.Next

        Loop

 

        Dim pQueryFilter As IQueryFilter

        pQueryFilter = New QueryFilter

        pQueryFilter.WhereClause = "NAME = 'New York'"

 

        Dim pStateFClass As IFeatureClass

        pStateFClass = pStateLayer.FeatureClass

 

        Dim pStateFCursor As IFeatureCursor

        pStateFCursor = pStateFClass.Search(pQueryFilter, True)

 

        Dim pStateFeature As IFeature

        pStateFeature = pStateFCursor.NextFeature  '** Moving to the NY feature

 

        Dim pGeom As IGeometry

        pGeom = pStateFeature.Shape   '** Getting the NY polygon geometry

 

        Dim pSpatialFilter As ISpatialFilter

        pSpatialFilter = New SpatialFilter

 

        With pSpatialFilter

            .Geometry = pGeom       '** Setting equal to NY shape

            .GeometryField = "SHAPE"

            .SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects  '** Getting roads that intersect NY

        End With

 

        Dim pFSel As IFeatureSelection

        pFSel = pRoadLayer   '** QI

 

        pFSel.SelectFeatures(pSpatialFilter, esriSelectionResultEnum.esriSelectionResultNew, False)

 

        Dim pActiveView As IActiveView

        pActiveView = pMap

 

        pActiveView.Refresh()

 

    End Sub 

Explanation

Again, the code in this procedure that obtains pointers to the necessary layers should look familiar by now. From there, selecting roads in New York requires obtaining that state's geometry. There are multiple ways to approach this part of the problem; the approach used in this solution is as follows:

  1. Set up a QueryFilter that identifies New York (and only New York).
  2. Get the States FeatureClass.
  3. Use the QueryFilter to create a FeatureCursor. (There should be only one Feature in it.)
  4. Get the New York Feature.
  5. Get its Geometry.

With the Geometry in hand, you're ready to set up a SpatialFilter to select roads that are within New York. The Geometry should be used to set the Geometry property of the SpatialFilter. The GeometryField property should be set to "SHAPE", the name of the field that stores the geometry. A number of SpatialRel constants will work (just as a number of choices in the Select By Location dialog box would work in performing the selection manually).

Keep in mind that setting up a SpatialFilter (or QueryFilter) is analogous to writing and saving a query. The next step is to decide whether to use that SpatialFilter to create a FeatureCursor (a collection of the individual matching Feature objects that you can work with) or to simply highlight the matching Features both on the map and in the attribute table. In this case, you're told to highlight the features, so the SpatialFilter should be used in a SelectFeatures statement. SelectFeatures is a method of the FeatureLayer class, but is accessed through IFeatureSelection, not IFeatureLayer. Therefore, a QI is necessary to call that method. After calling SelectFeatures, remember to refresh the map using IActiveView::Refresh.