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?
2 Answers 2
This will take multiple steps:
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; }
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; }
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; }
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; } }
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
-
1Where are you releasing the cursor?Kirk Kuykendall– Kirk Kuykendall2014年08月28日 22:03:52 +00:00Commented Aug 28, 2014 at 22:03
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
-
someone voted this down. Can you please provide reasons?Jakub Sisak GeoGraphics– Jakub Sisak GeoGraphics2014年09月22日 17:18:25 +00:00Commented Sep 22, 2014 at 17:18
Explore related questions
See similar questions with these tags.