1

I was thinking to select an area or a boundary in ArcMap on MouseDown Event and select all the features inside it.

How do I select the boundary with the code in C#?

Here is what I did:

public override void OnMouseDown(int Button, int Shift, int X, int Y)
    {
     screenPoint = new ESRI.ArcGIS.Geometry.Point();
     screenPoint.X = X;
     screenPoint.Y = Y;

     IScreenDisplay screenDisplay = (m_application.Document as IMxDocument).ActiveView.ScreenDisplay;

     mapPoint = screenDisplay.DisplayTransformation.ToMapPoint(X, Y);

     IMxDocument pMxDoc = (IMxDocument)m_application.Document;
     IMap pMap = (IMap)pMxDoc.FocusMap;
     mapPoint.SpatialReference = pMap.SpatialReference;

     ITopologicalOperator pTopOp = mapPoint as ITopologicalOperator;

     ISpatialFilter pSpatFlt = new SpatialFilterClass();
     //pSpatFlt.SpatialRel =esriSpatialRelEnum.esriSpatialRelIntersects;
     pSpatFlt.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;

     ESRI.ArcGIS.esriSystem.UID pFeatLayerUID = new 
     ESRI.ArcGIS.esriSystem.UIDClass();
     pFeatLayerUID.Value = "{40A9E885-5533-11d0-98BE-00805F7CED21}"; /* refer http:// help.arcgis.com/EN/sdk/10.0/ArcObjects_NET/componenthelp/index.html#/Layers_Property/001200000m9t000000/ */
     IEnumLayer pEnumLayer = pMap.get_Layers(pFeatLayerUID, true);
     ILayer pThisLayer;
     //IFeatureLayer pThisFeatLayer = pThisLayer as IFeatureLayer;
     IActiveView activeView = (m_application.Document as IMxDocument).ActiveView;
     IFeatureLayer pThisFeatLayer;
     while ((pThisLayer = pEnumLayer.Next()) != null)
         {
         pThisFeatLayer = pThisLayer as IFeatureLayer;
         IFeatureCursor pFtCur = pThisFeatLayer.Search(pSpatFlt, true);
         IFeature pFt = pFtCur.NextFeature();
         FlashFeature(activeView, pFt);
         if (pFt != null)
             {
                 IFeatureClass fC = (IFeatureClass)pFt.Class;
                 MessageBox.Show(fC.AliasName.ToString());
                 break;
             }
         }
  • 2
    How far have you got? It would be pointless to show you code you already have. Have you created your ArcMap addin tool? Wired the MouseDown event? Isolated the layer or layers you want to select from? transformed screen to map coordinates? Created a spatial filter? What data are you using for your boundary and what geometry type? – Michael Stimson Jun 8 '17 at 21:01
  • Hey I have added the code with which I was trying. I am using BaseTool to do that – royan Jun 9 '17 at 6:25
0

You're very close, you have all the objects you need but if I can make some recommendations. The topological operator, screen point and feature class aren't used so I got rid of them.

Selection is done in two rounds:

  1. Search the polygon layers in the map for a polygon feature that intersects the clicked point.
  2. Using the found polygon search all other layers.

I suspect your main problem is that the ISpatialFilter is never assigned a geometry to select with. I find it best to project the selecting geometry to the same spatial reference as the feature class before setting the ISpatialFilter.Geometry property.

public override void OnMouseDown(int Button, int Shift, int X, int Y)
{
  IApplication m_application = ArcMap.Application;
  IScreenDisplay screenDisplay = (m_application.Document as IMxDocument).ActiveView.ScreenDisplay;
  IMxDocument pMxDoc = (IMxDocument)m_application.Document;
  IMap pMap = (IMap)pMxDoc.FocusMap;

  ISpatialFilter pSpatFlt = new SpatialFilterClass();
  pSpatFlt.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;

  ESRI.ArcGIS.esriSystem.UID pFeatLayerUID = new ESRI.ArcGIS.esriSystem.UIDClass();
  pFeatLayerUID.Value = "{40A9E885-5533-11d0-98BE-00805F7CED21}"; /* refer http:// help.arcgis.com/EN/sdk/10.0/ArcObjects_NET/componenthelp/index.html#/Layers_Property/001200000m9t000000/ */
  IEnumLayer pEnumLayer = pMap.get_Layers(pFeatLayerUID, true);
  ILayer pThisLayer;
  IActiveView activeView = (m_application.Document as IMxDocument).ActiveView;
  IFeatureLayer pThisFeatLayer;
  IFeatureLayer pSelectFromFeatLayer = null;
  IFeature pSelectingFeature = null;

  // first loop through the layers, but only the polygon feature layers
  // to find a polygon where the user clicks.
  while ((pThisLayer = pEnumLayer.Next()) != null)
  {
    if (pThisLayer.Valid) // returns true if the layers' data source is not broken
    {
      pThisFeatLayer = pThisLayer as IFeatureLayer;
      if (pThisFeatLayer.FeatureClass.ShapeType == esriGeometryType.esriGeometryPolygon)
      {
        // only selecting polygons on this round
        IPoint mapPoint = screenDisplay.DisplayTransformation.ToMapPoint(X, Y);
        mapPoint.SpatialReference = pMap.SpatialReference;
        mapPoint.Project((pThisFeatLayer.FeatureClass as IGeoDataset).SpatialReference);
        pSpatFlt.Geometry = mapPoint; // Assign the selecting geometry to the spatial filter

        IFeatureCursor pFtCur = pThisFeatLayer.Search(pSpatFlt, true);
        IFeature pFt = pFtCur.NextFeature();

        if (pFt != null)
        {
          pSelectFromFeatLayer = pThisFeatLayer;
          pSelectingFeature = pFt;
          break; // break on the first polygon feature layer that creates a selection from the point
        }
      }
    }
  }

  if (pSelectFromFeatLayer != null) // go to the second round of selection only if a selecting polygon found
  {
    pEnumLayer = pMap.get_Layers(pFeatLayerUID, true); // restart the enum for the layers
    pMap.ClearSelection(); // clear the current selection

    while ((pThisLayer = pEnumLayer.Next()) != null)
    {
      if (pThisLayer.Valid)// returns true if the layers' data source is not broken
      {
        pThisFeatLayer = pThisLayer as IFeatureLayer;
        if (pThisFeatLayer.Name != pSelectFromFeatLayer.Name)
        {
          // don't select the same layer
          IGeometry pSelGeom = pSelectingFeature.ShapeCopy; // always get with shapecopy
          pSelGeom.Project((pThisFeatLayer.FeatureClass as IGeoDataset).SpatialReference);
          pSpatFlt.Geometry = pSelGeom; // assign the polygon geometry to the spatial filter.

          if (pThisFeatLayer.FeatureClass.FeatureCount(pSpatFlt) > 0)// there will be something selected on this feature class
          { 
            // select the features from this layer on the map
            (pThisFeatLayer as IFeatureSelection).SelectFeatures(pSpatFlt, esriSelectionResultEnum.esriSelectionResultAdd, false);
          }
        }
      }
    }
    FlashFeature(activeView, pSelectingFeature); // I'm assuming that this will refresh the display first with IActiveView.Refresh();
  }
}

One thing to beware of, selecting from the feature class ignores any definition queries set on the feature layer, you can set the ISpatialFilter.WhereClause to the (pThisFeatLayer as IFeatureLayerDefinition).DefinitionExpression and ISpatialFilter.SearchOrder to esriSearchOrder.esriSearchOrderAttribute to use the where clause of the layer before trying to select by geometry; attribute queries are usually much faster than geometry queries so it makes sense to do that first.

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.