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?

PolyGeo
65.5k29 gold badges115 silver badges350 bronze badges
asked Aug 28, 2014 at 10:04

2 Answers 2

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

answered Aug 28, 2014 at 15:55
1
  • 1
    Where are you releasing the cursor? Commented Aug 28, 2014 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
answered Aug 28, 2014 at 15:12
1
  • someone voted this down. Can you please provide reasons? Commented Sep 22, 2014 at 17:18

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.