Select to view content in your preferred language

How to program "share a line segment with" functionality of Select by Location

1274
10
Jump to solution
04-23-2012 11:31 AM
USFS_AGOLAdministrator
Deactivated User
Hello all,

I have created a tool which finds the second largest polygon in a selectionset, and eliminates a polygon to the second largest polygon, instead of the largest polygon, as the native eliminate tool does in ArcMap.  In the Select By Location form, it gives you the option of selecting between several different Spatial selection methods, of which "Target layer features share a line segment with the source layer feature" is one of them.  I have written the following code:

Dim pSF As ISpatialFilter             pSF.Geometry = pFeat.Shape             pSF.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects


It seems the ISpatialFilter interface does not give the ability to select features that share a line segment.  It gives the ability to do a bunch of other things, but selecting features that share a line segment is not one of them.  Is there another interface I'm missing somewhere that does give that functionality?
0 Kudos
1 Solution

Accepted Solutions
LanceShipman
Esri Regular Contributor
The GP tool arcpy.SelectLayerByLocation_management (Select Layer By Location in the toolbox) supports this query. It can be used from python or from .NET.

View solution in original post

0 Kudos
10 Replies
LanceShipman
Esri Regular Contributor
The GP tool arcpy.SelectLayerByLocation_management (Select Layer By Location in the toolbox) supports this query. It can be used from python or from .NET.
0 Kudos
USFS_AGOLAdministrator
Deactivated User
Lance,

The first code block below is how I currently have the code set up.  The second code block is my attempt at fixing it.  Since there is no "esriSpatialRelEnum.esriSpatialRelSharesALineSegmentWith" functionality, I attempted doing it using a gp tool, as you suggested.  Am I on the right track?

While Not pFeat Is Nothing
                    comReleaser.ManageLifetime(pFeat)
                    nNumAdjacent = 0
                    nCurRecNo = nCurRecNo + 1
                    'MsgBox(pFeat.OID)

                    With pSpFltr
                        .Geometry = pFeat.Shape 'EDGAR pPolygon
                        .SpatialRel = esriSpatialRelEnum.esriSpatialRelTouches
                        .OutputSpatialReference("Shape") = pSpRef   'm_pfc.Fields.Field(nShpFieldNDX).GeometryDef.SpatialReference
                        .SubFields = "Shape"
                        .GeometryField = "Shape"
                    End With

                    Dim intFeatCount As Integer = m_pfc.FeatureCount(pSpFltr)
                    'MsgBox(intFeatCount)

                    pFeat.Value(lFld) = intFeatCount
                    pFeatCur.UpdateFeature(pFeat)
                    'pFeat.Store()

                    My.ArcMap.Application.StatusBar.Message(0) = nCurRecNo.ToString & "/" & n.ToString & " records complete."
                    Me.ProgressBar1.Value = nCurRecNo

                    '


                    GC.Collect()
                    GC.WaitForPendingFinalizers()


                    Marshal.ReleaseComObject(pFeat)

                    'comReleaser.ReleaseCOMObject(pFeat)
                    pFeat = pFeatCur.NextFeature

                    Application.DoEvents()
                End While


Dim gp As IGeoProcessor = New GeoProcessor
          Dim strParam As IVariantArray = New VarArray
          gp.OverwriteOutput = True
          gp.SetEnvironmentValue("Workspace", m_gdbPath)

          'set the parameters for the select layer by location tool
          strParam.Add(pNewFLayer.Name)
          strParam.Add("SHARE_A_LINE_SEGMENT_WITH")

          'execute the select layer by location tool
          Dim results As IGeoProcessorResult = CType(gp.Execute("SelectLayerByLocation_Management",strParam, Nothing), IGeoProcessorResult)

          If results.Status <> ESRI.ArcGIS.esriSystem.esriJobStatus.esriJobSucceeded Then
               MsgBox("Failed to execute select by layer!", MsgBoxStyle.Information, "frmSelectLayer_btnRun_click")
               results = Nothing
               gp = Nothing
               Exit Sub
          End If
          gp = Nothing

0 Kudos
USFS_AGOLAdministrator
Deactivated User
This is the code that worked.  This assumes a feature is already selected before this code is run.  Other parts of my code loops through each feature of the layer, selects it, does a select by location on it, and returns the number of neighboring polygons for each feature in the layer.

        Dim gp As IGeoProcessor = New GeoProcessor
        Dim strParam As IVariantArray = New VarArray
        gp.OverwriteOutput = True

        strParam.Add(m_pFLay.Name)
        strParam.Add("SHARE_A_LINE_SEGMENT_WITH")

        'execute the select layer by location tool
        Dim results As IGeoProcessorResult = CType(gp.Execute("SelectLayerByLocation_Management", strParam, Nothing), IGeoProcessorResult)

        If results.Status <> ESRI.ArcGIS.esriSystem.esriJobStatus.esriJobSucceeded Then
            MsgBox("Failed to execute select by layer!", MsgBoxStyle.Information, "frmSelectLayer_btnRun_click")
            results = Nothing
            gp = Nothing
            Exit Sub
        End If
0 Kudos
LanceShipman
Esri Regular Contributor
Looks good. Are you getting the results that you expect?
0 Kudos
USFS_AGOLAdministrator
Deactivated User
Well, I'm trying to figure out how to select the feature in the feature class.  My original code, in the first code block of this post, is looping through each feature in the layer.  But in order for it to do the select by location on only that feature, it has to be selected.  So I'm trying to figure out how to select each feature as it loops through, so it can do the select by location on each feature, and return to me the number of neighboring polygons each feature has.
0 Kudos
USFS_AGOLAdministrator
Deactivated User
Hopefully I'm getting a little closer.  Here's my latest code.  It is selecting all features in the feature class at the same time, not just the ones that share a line segment with the selected polygon.  Can you see where I'm going wrong?

Dim pQF As IQueryFilter = New QueryFilter
        Dim pMxDoc As IMxDocument = My.ArcMap.Document
        Dim pActView As IActiveView = pMxDoc.ActiveView

        Dim gp As IGeoProcessor = New GeoProcessor
        Dim strParam As IVariantArray = New VarArray
        gp.OverwriteOutput = True

        strParam.Add(m_pFLay.Name)
        strParam.Add("SHARE_A_LINE_SEGMENT_WITH")            

        pFeat = pFeatCur.NextFeature

        While Not pFeat Is Nothing
                    '----------------test changes--------------------------------
             pQF.WhereClause = "OBJECTID = " & pFeat.OID
             Dim pSel As ISelectionSet = m_pFLay.FeatureClass.Select(pQF, esriSelectionType.esriSelectionTypeSnapshot, esriSelectionOption.esriSelectionOptionNormal, pWorkspace)
             pMxDoc.CurrentContentsView.Refresh(Nothing)
             pActView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, Nothing, Nothing)

             'execute the select layer by location tool
             Dim results As IGeoProcessorResult = CType(gp.Execute("SelectLayerByLocation_Management", strParam, Nothing), IGeoProcessorResult)

             If results.Status <> ESRI.ArcGIS.esriSystem.esriJobStatus.esriJobSucceeded Then
                  MsgBox("Failed to execute select by layer!", MsgBoxStyle.Information, "frmSelectLayer_btnRun_click")
                   results = Nothing
                   gp = Nothing
                   Exit Sub
             End If
     end while
'-----------------end test changes----------------------------------------------
0 Kudos
LanceShipman
Esri Regular Contributor
What results are you getting? Error message?
0 Kudos
USFS_AGOLAdministrator
Deactivated User
What results are you getting? Error message?


It is not throwing an error message at all.  It is correctly selecting each feature as it loops through, but then when I try to get it to select the neighboring polygons that share a border, it selects everything in the layer.  No errors returned.
0 Kudos
USFS_AGOLAdministrator
Deactivated User
Here is the final code, which works great.  The next thing to check into is speed.  I think doing an actual selection on the layer, and displaying it will slow it down greatly.  But for now, it works.

pQF.WhereClause = "OBJECTID = " & pFeat.OID
                    Dim pSel As ISelectionSet = m_pFLay.FeatureClass.Select(pQF, esriSelectionType.esriSelectionTypeIDSet, esriSelectionOption.esriSelectionOptionNormal, pWorkspace)
                    strParam.Add(m_pFLay.Name)
                    strParam.Add("NEW_SELECTION")
                    strParam.Add(pQF.WhereClause)

                    ''execute the select layer by attribute tool
                    Dim results2 As IGeoProcessorResult = CType(gp.Execute("SelectLayerByAttribute_Management", strParam, Nothing), IGeoProcessorResult)

                    If results2.Status <> ESRI.ArcGIS.esriSystem.esriJobStatus.esriJobSucceeded Then
                        MsgBox("Failed to execute select by attribute!", MsgBoxStyle.Information, "frmSelectLayer_btnRun_click")
                        results2 = Nothing
                        gp = Nothing
                        Exit Sub
                    End If

                    pActView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, Nothing, Nothing)
                    pMxDoc.CurrentContentsView.Refresh(Nothing)
                    pMxDoc.ActiveView.Refresh()

                    'now execute the select layer by location tool
                    strParam.RemoveAll()

                    gp.OverwriteOutput = True

                    strParam.Add(m_pFLay.Name)
                    strParam.Add("SHARE_A_LINE_SEGMENT_WITH")
                    strParam.Add("")
                    strParam.Add("")
                    strParam.Add("NEW_SELECTION")

                    ''execute the select layer by location tool
                    Dim results As IGeoProcessorResult = CType(gp.Execute("SelectLayerByLocation_Management", strParam, Nothing), IGeoProcessorResult)

                    If results.Status <> ESRI.ArcGIS.esriSystem.esriJobStatus.esriJobSucceeded Then
                        MsgBox("Failed to execute select by layer!", MsgBoxStyle.Information, "frmSelectLayer_btnRun_click")
                        results = Nothing
                        gp = Nothing
                        Exit Sub
                    End If

                    strParam.RemoveAll()
                    strParam.Add(m_pFLay.Name)
                    Dim results3 As IGeoProcessorResult = CType(gp.Execute("GetCount_Management", strParam, Nothing), IGeoProcessorResult)
                    'MsgBox(results3)
                    strParam.RemoveAll()
0 Kudos