[SOLVED]: Select all elements around a clicked point

Dec 6, 2012 at 4:22 PM
Edited Dec 6, 2012 at 4:29 PM

Hi all,


I am trying to implement a funcionality but I am not able to get it. I hope that after publishing it here, someone would be able to help me.


I need to retrieve all the elements found near a clicked point from a particular layer.


Here's the code I am trying to make it work. (f_SelectelementsAround is a private function which is called from Click Event function over a MapControl):

 

   private void f_selectElementsAround(MouseEventArgs e)
        {
            /// Recover all Layers 
            List<DotSpatial.Symbology.ILayer> allLayers = mapa.GetAllLayers();

            ///Get 'pozoreg' layer
            DotSpatial.Symbology.ILayer layerPozoReg = allLayers[4];

            //Create a 'square' around the clicked point
            //
            //  pLeftTop  _____  pRightTop
            //           |     |
            //           |     |
            //           |_____|
            //    pLeftBot      pRightBot
            System.Drawing.Point pLeftTop = new System.Drawing.Point(e.Location.X - 1, e.Location.Y - 1);
            System.Drawing.Point pLeftBot = new System.Drawing.Point(e.Location.X - 1, e.Location.Y + 1);
            System.Drawing.Point pRightTop = new System.Drawing.Point(e.Location.X + 1, e.Location.Y - 1);
            System.Drawing.Point pRightBot = new System.Drawing.Point(e.Location.X + 1, e.Location.Y + 1);

            //Transform points to coordinates trough projection
            Coordinate cMin = mapa.PixelToProj(pLeftTop);
            Coordinate cMax = mapa.PixelToProj(pRightBot);


            ///Create an envelope that represents the selected area
            IEnvelope envelopeNearbyElement = new Envelope(cMin.X, cMin.Y, cMax.X, cMax.Y);


            //Get selected elements
            //--- FROM THIS POINT I AM NOT SURE IF I AM DOING RIGHT -----
            bool elementsFound = layerPozoReg.Select(envelopeNearbyElement, null);

            //Show selected items
            IMapFeatureLayer objLayer;
            ISelection objSelection;

            objLayer = (IMapFeatureLayer)layerPozoReg;
            objSelection = objLayer.Selection;

            List<IFeature> featuresSelected = objSelection.ToFeatureList();

        }

The point is that I always get results, but I get too many. It seems like the entire area of the layer is always selected; as you can see in the next screenshot.

Thank you very much in advance!
Dec 7, 2012 at 11:52 AM

I didn't do it exactly, but I did it to select features around one selected feature

In some old discussion I found an example using the following commands (sorry it is in vb.net, but there are translators on the web, and the example is very simple)

                Dim tolerant As Extent 
                'then set your extent dimension to the area around your point to use to select features nearby
                 
                Dim resultS As List(Of IFeature) = yourFearureset.[Select](tolerant)

with these commands you can get the list of features (resultS) around your point, that lies within the square extent you want to use.

Hope it helps
Oscar
Dec 8, 2012 at 10:12 AM
Edited Dec 8, 2012 at 10:22 AM

Hi oscarfone,

 

Thank you for you answer. I realy think I need more experiencie with Dotspatial, because I can't do next step. Now my code changed this way:

   private void f_selectElementsAround(MouseEventArgs e)
        {
            /// Recover all Layers 
            IMapPointLayer[] allLayers = mapa.GetPointLayers();

            ///Get 'pozoreg' layer
            DotSpatial.Symbology.ILayer layerPozoReg = allLayers[4];

            // Get rectangle around clicked area
            Rectangle recNearbyElements = new Rectangle(Location.X, Location.Y, 1, 1);

           // Transform rectangle to Extent trought project
           Extent extNearbyElements = mapa.PixelToProj(recNearbyElements);


           // MISSING: Get FeatureSet from layer
           FeautreSet fsLayerPozoreg = getFeatureSetfromlayer(layerPozoReg);

         //Perform select
         List<IFeature> selectedElements = fsLayerPozoreg.Select(extNearbyElements);
        }
         

Can you see the layerPozoReg? I need to get its FeatureSet in order to perform the 'Select'; but I don't know how to do it. 

For you information; that layer was previously created from a shapefile.
Thank you very much for your help.
Dec 8, 2012 at 11:06 AM

I don't know if Ilayer has the same fields as imappointlayer, 

however to get the featureset of layerPozoReg you should do something like:

 

fsLayerPozoreg=layerPozoReg.dataset

 

for me it works if I declare layerPozoReg as imappointlayer, if your doesn't try declare layerPozoReg as imappointlayer

Hope this helps

Oscar

Dec 10, 2012 at 9:01 AM

Hi,

I think I got it finally. Thank you very much oscarfone77 for helping me. I post the code in order to help others to reach the functionality. 

        private void f_selectElementsAround(MouseEventArgs e)
        {
            /// Recover all Layers 
            IMapFeatureLayer[] allLayers = mapa.GetFeatureLayers();

            ///Get 'pozoreg' layer
            DotSpatial.Symbology.ILayer layerPozoReg = allLayers[4];
         
            //Create a rectanle(in fact, a square). Move its starting point in order to build a square around the clicked point
            Rectangle recNearbyElements = new Rectangle(e.X-50, e.Y-50, 100, 100);

            //Transform points to coordinates trough projection
            Extent extNearbyElements = mapa.PixelToProj(recNearbyElements);

            //Create a new FeatureSet
            FeatureSet fsPozoLayer = new FeatureSet();

            //Cast the DataSet of our loaded layer to a FeatureSet
            fsPozoLayer = (FeatureSet)layerPozoReg.DataSet;

            //Select all the elements that are in the square generated around the clicked point
            List<IFeature> selectedElements = fsPozoLayer.Select(extNearbyElements);

        }

Marked as answer by omiras on 2/3/2015 at 5:52 AM
Dec 17, 2012 at 7:53 AM

Hi Omiras ,

 

I have tried your code as mentioned above, please see my code , where I am not getting any values to the selected Elements where I am binding the result set to datagridview

 

 IMapFeatureLayer[] allLayers = uxMap .GetFeatureLayers();

 DotSpatial.Symbology.ILayer layerPozoReg = allLayers[4];

Rectangle recNearbyElements = new Rectangle(e.X - 50, e.Y - 50, 100, 100);

Extent extNearbyElements = uxMap.PixelToProj(recNearbyElements);

FeatureSet fsPozoLayer = new FeatureSet();

fsPozoLayer = (FeatureSet)layerPozoReg.DataSet;

 List<IFeature> selectedElements = fsPozoLayer.Select(extNearbyElements);

DataTable dt = new DataTable();           

dt = fsPozoLayer.DataTable;           

dataGridView1.DataSource = dt;

Dec 18, 2012 at 8:05 AM
nkhl3059 wrote:

 

 IMapFeatureLayer[] allLayers = uxMap .GetFeatureLayers();

 DotSpatial.Symbology.ILayer layerPozoReg = allLayers[4];

I am doing it because I know what's inside my "5th layer". Is that also the layer you want to Select?

Are you sure that there are element near where you click?

Dec 18, 2012 at 9:38 AM

 

Hi Omiras

 

No I want to get the attribute information randomly when user clicks on particular layer

for that I have modified  the above code i.e DotSpatial.Symbology.ILayer layerPozoReg = allLayers[0];

still i am not getting anything to fsPozoLayer ,


Dec 18, 2012 at 9:48 AM
Edited Dec 18, 2012 at 10:13 AM

Hi,

 

Then I think you have to iterate trough all the layers. I leave my code; but probably you'll have to adapt it.

 

  public static List f_getAllElementsAround(Map mapa,  List selectableLayers, int x, int y) 
        {
            List result = new List();

            /* We compute a rectangle */
            //Create a rectanle(in fact, a square). Move its starting point in order to build a square //around the clicked point
            Rectangle recNearbyElements = new Rectangle(x - 50, y - 50, 100, 100);

            //Transform points to coordinates trough projection
            Extent extNearbyElements = mapa.PixelToProj(recNearbyElements);

            /* Iterate all the layers. We'll save id information of the found elements */
            foreach (layerGalia nextLayer in selectableLayers)
            {
                IMapLayer currentExploredLayer = nextLayer.m_layer;

                FeatureSet fsCurrentLayer = new FeatureSet();

                //Cast the DataSet of our loaded layer to a FeatureSet
                fsCurrentLayer = (FeatureSet)currentExploredLayer.DataSet;

                //Select all the elements that are in the square generated around the clicked point
                List selectedElements = fsCurrentLayer.Select(extNearbyElements);

                /* Add each Feature found to result list */
                foreach (IFeature nextElement in selectedElements)
                {
                    //Curiosity : we can't cast from Database to long in a straight way. We need to cast first to integer.
                    long nextObjectId = (int) (nextElement.DataRow.ItemArray[0]);
                    String nextLabel = (String) (nextElement.DataRow.ItemArray[1]);
    // elementIdentifier is just a simple class made by me to hold Id,Name pair values
                    elementIdentifier nextId = new elementIdentifier(nextObjectId, nextLayer.m_name, nextLabel);
                    result.Add(nextId);
                }
            }

            return result;
        }
Dec 18, 2012 at 9:52 AM
Edited Dec 18, 2012 at 9:55 AM

Can you help me out with my code.

as above

'

Dec 18, 2012 at 9:55 AM
Edited Dec 18, 2012 at 9:55 AM
nkhl3059 wrote:

what is list over here , 

If you mean: 

List selectableLayers

It's a List of all IMapLayers that you want to consider to be able to select.

Dec 18, 2012 at 9:59 AM

is there any assembly that i need to refer