Finding Nearest Feature

2929
4
05-03-2011 09:02 AM
DuncanRager
New Contributor
Greetings,

I have:

(a) point feature class
(b) polyline feature class

I am trying to loop through the (a) point feature class to find the nearest feature from the (b) polyline feature class.

Just as a start to more complex command, I'd like to find and select the nearest (b) polyline, and create a message box that tells me its ObjectID, just so I know that the method for finding the nearest line is working.

I've come across 2 options, both of which I'm having issues with.

(1) The IIndexQuery.NearestFeature method, which I could use in combination with the IFeature.GetFeature method to select the polyline feature of interest.

I've successfully entered the parameters (I think), but the NearestFeature method returns a "-1" for each of the features FIDs. This makes sense, because my features have an 'ObjectID' field, but no 'FID' field. Is there a way around that? Or does the NearestFeature method only check for FID?

(2) The IHitTest.HitTest method, which returns a segment index of the nearest feature.

The problem here is that I'm looking for a value in a field for the whole line, not just a segment of the line. Is there a way to return the whole feature from the segment index?

Any other suggestions on finding the nearest line from a given point?

Thanks so much,

DR
0 Kudos
4 Replies
JoelCappello
New Contributor
I have code that uses IIndexQuery2.NearestFeature as well. Not sure why you're getting -1 for a vlaue. My code queries a file geodatabase where it's the objectid that is taken. What you can do (once you get the -1 issue worked out) is use the FID # to query for the polyline you need and extract the attribues then. Hope that helps.
-Joel
0 Kudos
DuncanRager
New Contributor
Perhaps a look at my code would help:

Private Sub NHD_Prep_Click()

    'Set general variables
    Dim pMxDoc As IMxDocument
    Set pMxDoc = ThisDocument
    Dim pMap As IMap
    Set pMap = pMxDoc.FocusMap
    
    'Set variables for the line layer of interest
    Dim pNhdLayer As ILayer
    Set pNhdLayer = pMap.Layer(0)
    Dim pNhdFLayer As IFeatureLayer
    Set pNhdFLayer = pNhdLayer
    Dim pNhdFClass As IFeatureClass
    Set pNhdFClass = pNhdFLayer.FeatureClass
    Dim pNhdFeatureIndex As IFeatureIndex
    Set pNhdFeatureIndex = New FeatureIndex
    Set pNhdFeatureIndex.FeatureClass = pNhdFClass
    Dim pNhdIndexQuery As IIndexQuery2
    Set pNhdIndexQuery = pNhdFeatureIndex
        
    'Set variables for the point layer of interest
    Dim pLayer As ILayer
    Set pLayer = pMap.Layer(1)
    Dim pFLayer As IFeatureLayer
    Set pFLayer = pLayer
    Dim pFClass As IFeatureClass
    Set pFClass = pFLayer.FeatureClass
    
    'Set number variables
    Dim nearReachFID As Long
    Dim distance As Double
    Dim strReach As String
    Dim dblmeas As Double
    
    'Check to make sure the layer of interest is on top
    If pMxDoc.FocusMap.Layer(0).Name <> "NHD Flowline" Then
        MsgBox "Please place NHD Flowline on the top spot of the TOC..."
        Exit Sub
    End If
    
    'Start Cursor on point layer features
    Dim pFCursor As IFeatureCursor
    Set pFCursor = pFClass.Search(Nothing, True)
    Dim pFeature As IFeature
    Set pFeature = pFCursor.NextFeature
    
    Do Until pFeature Is Nothing
               
        'Use nearest point method to find the line FID and distance to it
        Dim pPointFeature As IPoint
        Set pPointFeature = pFeature.Shape
        
        pNhdIndexQuery.NearestFeature pPointFeature, nearReachFID, distance
              
        MsgBox "This is the " & pFeature.Value(pFeature.Fields.FindField("Name")) & " feature. " _
        & "The distance from this point to the nearest line, " & nearReachFID & ", is " & distance
        
        Set pFeature = pFCursor.NextFeature
    Loop
    
End Sub
0 Kudos
JoelCappello
New Contributor
I can't see a problem with your code. I took a look at my code (c#) and came accross this line:

if (!(intClosestFID == -1))//need to figure out why -1 is coming back on the IndexQuery or find another way to get the pipe

I never figured it out. Luckily getting the closest pipe wasn't mission critical to the project. Just a nice feature (that doesn't work all the time).
0 Kudos
DuncanRager
New Contributor
OK so my co-worker helped me figure this out...

Turns out I hadn't declared an envelope for my featureIndex, which in turn, left my indexQuery empty. Not sure if this was your problem jacapello.

Underneath:

Dim pNhdIndexQuery As IIndexQuery2


I added the following lines of code:

Dim pEnvelope As IEnvelope
Set pEnvelope = New Envelope
pNhdFeatureIndex.Index Nothing, pEnvelope


This comes before:

Set pNhdIndexQuery = pNhdFeatureIndex


You also need to ensure that the projections of your data frame, sourceindex, and inpoints all match, lest you catch an error.

Hope this helps,

DR
0 Kudos