spatial query based on mouse click event

861
3
05-06-2013 01:22 PM
NadeemQazi
New Contributor III
Please look the code , I  wish to access the feature at the mouse coordinate on mouse click event. however my code below return all the records rather than a single point. any guess what is wrong.

IMxApplication pMxApp = null;
            pMxApp = (IMxApplication)ArcMap.Application;
            IMxDocument pMxDoc = null;

            pMxDoc = ArcMap.Document;
            if (pMxDoc.SelectedLayer == null)
            {
                MessageBox.Show("There is no layer selected.  First select a time-aware layer.");
                return;
            }
            IMap pMap = pMxDoc.FocusMap;
            IFeatureLayer feature_layer = (IFeatureLayer)pMap.get_Layer(0);// put the index of ur lauer
            IPoint point = new PointClass();

            x = pMxDoc.CurrentLocation.X; // this is point returns when user click on mouse.
            y = pMxDoc.CurrentLocation.Y;
            MessageBox.Show(x+ ":" + y);
            point.PutCoords(x, y);
            // point.PutCoords(280, 240);
            point.SpatialReference = pMap.SpatialReference;
            ISpatialFilter spatial_filter = new SpatialFilterClass();
            spatial_filter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
            spatial_filter.Geometry = point;
            spatial_filter.GeometryField = feature_layer.FeatureClass.ShapeFieldName;
            MessageBox.Show(spatial_filter.GeometryField.ToString());
            IFeatureCursor feature_cursor = feature_layer.FeatureClass.Search(spatial_filter, false);
            IFeature feature = feature_cursor.NextFeature();
         
            while (feature != null)   // here it returns the whole records rather than single point.
            {
                // do what u wan0t with the feature
                MessageBox.Show(feature.get_Value(3).ToString());
                feature = feature_cursor.NextFeature();
            }
        }

   
    }
0 Kudos
3 Replies
BarbaraSchneider1
New Contributor III
Hello,

what type of layer do you query (IFeatureLayer feature_layer = (IFeatureLayer)pMap.get_Layer(0)) ? Is it a point layer? If so, you will never get the exact point using this query. You will have to apply a scale dependent buffer to your mouse point, e.g.:

IEnvelope env = new EnvelopeClass();
env.SpatialReference = pMap.SpatialReference;
env.PutCoords(x - ..., y - ..., x + ..., y + ...);
...
spatial_filter.Geometry = env;


Does this help?

Barbara
0 Kudos
BillBrodie
New Contributor II
Here is a C# function I have used to find the nearest feature from a layer.  It buffers an input point to make the spatial query geometry, then determines which intersecting feature is closest - return just that one feature.

Hope it helps.

   /// <summary> Find the nearest feature in the layer from a point within a maximum distance
        /// </summary>
        /// <param name="searchLayer">Layer to search</param>
        /// <param name="nearPoint">Point to search near</param>
        /// <param name="maxDistance">Maximum distance</param>
        /// <returns>Nearest feat or null if none within the maximum distance</returns>
        public static IFeature GetNearestFeature(IFeatureLayer searchLayer, IPoint nearPoint, double maxDistance)
        {
            //todo: get the feature class and call the primary overload ...
            ITopologicalOperator topo = (ITopologicalOperator)nearPoint;
            IProximityOperator prox = (IProximityOperator)nearPoint;
            IFeature nearFeat = null;
            double nearDist = 0;

            string saveDefinitionQuery = string.Empty;
            if (string.IsNullOrEmpty(((IFeatureLayerDefinition)searchLayer).DefinitionExpression))
            {
                saveDefinitionQuery = ((IFeatureLayerDefinition)searchLayer).DefinitionExpression;
                ((IFeatureLayerDefinition)searchLayer).DefinitionExpression = string.Empty;
            }

            ISpatialFilter filter = new SpatialFilterClass();
            try
            {
                filter.Geometry = topo.Buffer(maxDistance);
                filter.GeometryField = searchLayer.FeatureClass.ShapeFieldName;
                filter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
            }
            catch (Exception ex)
            {
                //todo: handle this
            }
            finally
            {
                //restore the definition query
                ((IFeatureLayerDefinition)searchLayer).DefinitionExpression = saveDefinitionQuery;

            }
            IFeatureCursor cursor = searchLayer.Search(filter, false);

            try
            {
                IFeature testFeat = null;
                while ((testFeat = cursor.NextFeature()) != null)
                {
                    double testDist = prox.ReturnDistance(testFeat.Shape);
                    if (testDist < nearDist || nearFeat == null)
                    {
                        nearFeat = testFeat;
                        nearDist = testDist;
                    }
                }
            }
            catch (Exception ex)
            {
                //todo:handle
            }
            finally
            {
                Marshal.ReleaseComObject(cursor);
            }

            return nearFeat;
        }

Good Luck
0 Kudos
CarstenSchumann
Occasional Contributor

Depending on your map-coordinate system you should also transform your coordinates returned from your mouse-position into real world coords before doing any buffer (as mentioned by Barbara Schneider‌) or calculating any near features (see @Bill Brodie)

0 Kudos