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:
- Set up a QueryFilter that identifies New York (and only New York).
- Get the States FeatureClass.
- Use the QueryFilter to create a FeatureCursor. (There should be only one Feature in it.)
- Get the New York Feature.
- 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.