4

I am very new to ArcGIS and ArcObjects.

I am writing a code for a button that will detect a selected feature and then select other features based on the feature that I had selected please take a look at my code

public class LandmarkBtn : ESRI.ArcGIS.Desktop.AddIns.Button {

    public LandmarkBtn() {
    }

    protected override void OnClick() {
         var doc = ArcMap.Document;
        var focusMap = doc.FocusMap;
        IEnumLayer layer = focusMap.get_Layers(null,true);
        ILayer lyr = null;
        IFeatureClass Lmarks = null;

        while ((lyr = layer.Next()) != null) {

            var featureLayer = lyr as IFeatureLayer;
            if (featureLayer == null)
                continue;  



        var name = featureLayer.FeatureClass.AliasName;

            if ("landmarks".Equals(name.ToLowerInvariant())) {


                Lmarks = featureLayer.FeatureClass;
                break;
            }
        }

        if (Lmarks == null) {
            MessageBox.Show("Sorry, No LM Layer Found");
            return;
        }


        var selection = (IEnumFeature)focusMap.FeatureSelection;
        IFeature ftr = null;
        ftr = selection.Next();

ftr now holds the selected landmark(feature), I want to perform a query that will select features from another layer that are within 100 meters of the landmark feature, can you please direct me onto where I should look or provide me with a sample code that might help?

5

This will take multiple steps:

  1. Get a cursor from you selection set

        public static IFeatureCursor GetSelectedFeatures(IFeatureLayer featureLayer)
    {
        if (featureLayer == null) return null;
        IFeatureSelection fSel = (IFeatureSelection)featureLayer;
        ISelectionSet selSet = (ISelectionSet)fSel.SelectionSet;
        ICursor cursor = null;
        selSet.Search(null, false, out cursor);
        IFeatureCursor fCursor = cursor as IFeatureCursor;
        return fCursor;
    }
    
  2. Union and buffer the items in the cursor

    public static IPolygon UnionShapes(IFeatureCursor cursor, double bufferDist)
    {
        if (cursor == null) return null;
        IFeature pFeat = cursor.NextFeature();
        if (pFeat != null)
        {
            if (pFeat.Shape is IPoint)
            {
                ITopologicalOperator ptopBuffer = (ITopologicalOperator)pFeat.Shape;
                IPolygon pTempPoly = (IPolygon)ptopBuffer.Buffer(bufferDist);
                ITopologicalOperator ptopUnion = (ITopologicalOperator)pTempPoly;
                pFeat = cursor.NextFeature();
                while (pFeat != null)
                {
                    ptopBuffer = (ITopologicalOperator)pFeat.Shape;
                    pTempPoly = (IPolygon)ptopBuffer.Buffer(bufferDist);
                    ptopUnion = (ITopologicalOperator)ptopUnion.Union(pTempPoly);
                    pFeat = cursor.NextFeature();
                }
                return (IPolygon)ptopUnion;
            }
            return null;
        }
        return null;
    }
    
  3. Select the spatial filter on the new shape

       public static ISpatialFilter CreateSpatialFilter(IFeatureClass fc, IGeometry shape)
    {
        if (fc == null) return null;
        ISpatialFilter sf = new SpatialFilterClass();
        sf.GeometryField = fc.ShapeFieldName;
        sf.Geometry = shape;
        sf.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
        return sf;
    }
    
  4. Search on the feature class with the filter.

        public static IFeatureCursor GetSelectedItemsByShape(IFeatureClass fc, ISpatialFilter filter)
    {
        try
        {
            if (filter == null) return null;
            if (fc == null) return null;
            IFeatureCursor fcursor = fc.Search(filter, true);
            return fcursor;
        }
        catch
        {
            return null;
        }
    }
    
  5. Then if you want to select the new features:

        public static ISelectionSet CursorToSelectionSet(IFeatureLayer layer, IFeatureCursor cursor)
    {
    
        IFeatureSelection fSel = (IFeatureSelection)layer;
        if (cursor != null)
        {
            IFeature feat = cursor.NextFeature();
            while (feat != null)
            {
                fSel.Add(feat);
                feat = cursor.NextFeature();
            }
        }
        return fSel.SelectionSet;
    }
    

Good Luck

  • 1
    Where are you releasing the cursor? – Kirk Kuykendall Aug 28 '14 at 22:03
2

I recommend you complete the Building Add-ins for ArcGIS Desktop walk-through then look at some of the code snippets that are availalbe to developoers.

To address your question; You need to first isolate the geometry of the feature you want to use to do the selection, locate and set the destination feature class, create a spatial filter set the initial feature geometry to it and use the spatial feature to make the selection. Lastly yo will need to call the refresh method the draw the selection on map.

Here is a similar example (VB.NET) I use to select features on a specific layer in a OnMouseUp event. In this case instead of using a feature geometry to make the selection, the spatial filter input geometry is created from either the mouse location point (in case of a single click) or a rectangle drawn with the mouse on screen. The actual procedure for selecting features on a particular layer would be similar in your case - using a spatial filter object.

Protected Overrides Sub OnMouseUp(ByVal arg As ESRI.ArcGIS.Desktop.AddIns.Tool.MouseEventArgs)
        On Error GoTo Trap
        Dim mxDoc As ESRI.ArcGIS.ArcMapUI.IMxDocument = My.ArcMap.Document
        If arg.Button = Windows.Forms.MouseButtons.Left Then

            Dim pEnv As ESRI.ArcGIS.Geometry.IEnvelope = New ESRI.ArcGIS.Geometry.Envelope

            'Dim pGeoFeatureLayer As ESRI.ArcGIS.Carto.IGeoFeatureLayer
            Dim pFeatureSelection As ESRI.ArcGIS.Carto.IFeatureSelection
            Dim pSpatialFilter As ESRI.ArcGIS.Geodatabase.ISpatialFilter = New ESRI.ArcGIS.Geodatabase.SpatialFilter
            Dim pLayer As ESRI.ArcGIS.Carto.ILayer = Nothing
            Dim pFeatureLayer As ESRI.ArcGIS.Carto.IFeatureLayer = Nothing
            Dim point As ESRI.ArcGIS.Geometry.IPoint = TryCast(m_focusMap.ScreenDisplay.DisplayTransformation.ToMapPoint(arg.X, arg.Y), ESRI.ArcGIS.Geometry.IPoint)
            Dim bFull As Boolean


            pLayer = mxDoc.SelectedLayer
            pFeatureLayer = pLayer
            If Not pFeatureLayer.Selectable Then pFeatureLayer.Selectable = True 'override default selectibility to true

            If (Not pLayer Is Nothing And TypeOf pLayer Is ESRI.ArcGIS.Carto.IGeoFeatureLayer) Or _
             (Not pLayer Is Nothing And TypeOf pLayer Is ESRI.ArcGIS.Carto.IAnnotationLayer) Then

                pFeatureSelection = pFeatureLayer

                If Not m_pFeedbackEnv Is Nothing Then
                    pEnv = TryCast(m_pFeedbackEnv.Stop(), ESRI.ArcGIS.Geometry.IEnvelope)

                    With pSpatialFilter
                        .GeometryField = pFeatureLayer.FeatureClass.ShapeFieldName
                        If (Not pEnv Is Nothing) And (pEnv.IsEmpty = False) Then
                            .Geometry = pEnv
                        Else
                            .Geometry = point
                        End If
                        .SpatialRel = 1
                    End With

                Else
                    With pSpatialFilter
                        .GeometryField = pFeatureLayer.FeatureClass.ShapeFieldName
                        .Geometry = point
                        .SpatialRel = 1
                    End With
                End If

                If Not arg.Shift Then
                    If pFeatureLayer.FeatureClass.FeatureCount(pSpatialFilter) > 0 Then
                        pFeatureSelection.SelectFeatures(TryCast(pSpatialFilter, ESRI.ArcGIS.Geodatabase.ISpatialFilter), 0, False)
                    Else
                        My.ArcMap.Document.FocusMap.ClearSelection()
                        ''bFull = True
                    End If

                Else
                    pFeatureSelection.SelectFeatures(TryCast(pSpatialFilter, ESRI.ArcGIS.Geodatabase.ISpatialFilter), 1, False)
                End If


                'Refresh the selections
                m_lineFeedback.Stop() 'stop line feedback
                m_lineFeedback = Nothing
                m_pFeedbackEnv = Nothing 'MUST CANCEL FEEDBACK BEFORE REFRES ELSE CRASH WILL OCCUR

                m_isMouseDown = False
                'm_focusMap.PartialRefresh(ESRI.ArcGIS.Carto.esriViewDrawPhase.esriViewGeoSelection, mxDoc.SelectedLayer, mxDoc.ActiveView.Extent.Envelope)
                m_focusMap.Refresh()
                Else
                    'if Layer is not selected or not a golayer use default selection across all layers 
                    If m_pFeedbackEnv IsNot Nothing Then
                        pEnv = m_pFeedbackEnv.Stop()
                        If pEnv IsNot Nothing Then
                            With My.ArcMap.Document.FocusMap
                                .ClearSelection() 'clear previous selection before making new
                                .SelectByShape(pEnv, Nothing, False)
                            End With
                        End If
                    End If
                    m_lineFeedback.Stop() 'stop line feedback
                    m_lineFeedback = Nothing
                    m_pFeedbackEnv = Nothing
                    m_isMouseDown = False
                    'm_focusMap.PartialRefresh(ESRI.ArcGIS.Carto.esriViewDrawPhase.esriViewGeoSelection, mxDoc.SelectedLayer, mxDoc.ActiveView.Extent.Envelope)
                    m_focusMap.Refresh()
                End If

        End If



        Exit Sub
Trap:

        'MsgBox(Err.Description)
        m_isMouseDown = False
        m_lineFeedback = Nothing
        m_pFeedbackEnv = Nothing
    End Sub

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.