Select to view content in your preferred language

How to restrict identify layers

5776
32
03-10-2011 08:20 AM
DonFreeman
Emerging Contributor
Is there a way to restrict the layers that are returned with an identify query?
  private void QueryPoint_MouseClick(object sender, ESRI.ArcGIS.Client.Map.MouseEventArgs e)
   {
   ESRI.ArcGIS.Client.Geometry.MapPoint clickPoint = e.MapPoint;

   ESRI.ArcGIS.Client.Tasks.IdentifyParameters identifyParams = new IdentifyParameters()
   {
    Geometry = clickPoint,
    MapExtent = MyMap.Extent,
    Width = (int)MyMap.ActualWidth,
    Height = (int)MyMap.ActualHeight,
    LayerOption = LayerOption.visible,
    SpatialReference = MyMap.SpatialReference
   };

   IdentifyTask identifyTask = new IdentifyTask("http://gismaps.pagnet.org/arcgis/rest/services/Interactive_TIP_2011/MapServer");
   identifyTask.ExecuteCompleted += IdentifyTask_ExecuteCompleted;
  
   identifyTask.ExecuteAsync(identifyParams);

   GraphicsLayer graphicsLayer = MyMap.Layers["MyGraphicsLayer"] as GraphicsLayer;
   graphicsLayer.ClearGraphics();
   ESRI.ArcGIS.Client.Graphic graphic = new ESRI.ArcGIS.Client.Graphic()
   {
    Geometry = clickPoint,
    Symbol = LayoutRoot.Resources["DefaultPictureSymbol"] as ESRI.ArcGIS.Client.Symbols.Symbol
   };
   graphicsLayer.Graphics.Add(graphic);
   }

I tried putting the layer numbers in the url but that did not work.
Thanks
0 Kudos
32 Replies
BrandonCales
Regular Contributor
I can't find it, but I thought I saw a post somewhere, where they cycled through all the Visible Layers to create a list (e.g. foreach (isvisible...))

If that is possible, then it would be easier to exclude a layer with a given ID, versus Add/AddRange all but the layer?

Just trying to think of a way around.
0 Kudos
BrandonCales
Regular Contributor
here is kind of what I'm looking for,  however this does seam to see layers that are in scale range versus is visible. My legend shows layers as 'visible', but are disabled until that are in scale range - there should be an option for this that can be used more globally.

// Initialize Identify parameters. Specify searching of all layers.
            ESRI.ArcGIS.Client.Tasks.IdentifyParameters identifyParameters = new IdentifyParameters()
            {
                Geometry = args.MapPoint,
                MapExtent = MyMap.Extent,
                Width = (int)MyMap.ActualWidth,
                Height = (int)MyMap.ActualHeight,
                LayerOption = LayerOption.visible,
                SpatialReference = MyMap.SpatialReference,
                Tolerance = 5
            };

            //identifyParameters.LayerIds.AddRange(new int[] { 0, 78 });

            ArcGISDynamicMapServiceLayer MainLayer = MyMap.Layers["MainLayer"] as ArcGISDynamicMapServiceLayer;

            // now turn on only those that we're interested in seeing...
            for (int i = 0; i < MainLayer.Layers.Count(); i++)
            {
                if (MainLayer.Layers.ID == 79) 
                {
                    MessageBox.Show("Skip: " + MainLayer.Layers.Name);
                    MessageBox.Show(MainLayer.GetLayerVisibility(MainLayer.Layers.ID).ToString());
                }
                else
                {
                    if (MainLayer.GetLayerVisibility(MainLayer.Layers.ID) == true)
                    {
                        identifyParameters.LayerIds.Add(MainLayer.Layers.ID);
                        //LayerList.Add(MainLayer.Layers.ID);
                    }
                }
                //identifyParameters.LayerIds.AddRange(LayerList);
                
            }


I can't find it, but I thought I saw a post somewhere, where they cycled through all the Visible Layers to create a list (e.g. foreach (isvisible...))

If that is possible, then it would be easier to exclude a layer with a given ID, versus Add/AddRange all but the layer?

Just trying to think of a way around.
0 Kudos
DominiqueBroux
Esri Frequent Contributor

My legend shows layers as 'visible', but are disabled until that are in scale range - there should be an option for this that can be used more globally.


When you set the layerids to a list of sublayer to identify, the 'LayerOption' defines if the identify should be done on all layers of the list or only the layers of the list which are currently in the scale range:
     - LayerOption.all : all layers defined in LayerIds are identified
     - LayerOption.visible : only visible layers in LayerIds (taking care of the scale range) are identified
0 Kudos
BrandonCales
Regular Contributor
I have my LayerOption set to visible and regardless of me specifying layers or not, it still Identify's a layer that is not in scale range?
0 Kudos
DominiqueBroux
Esri Frequent Contributor
I noticed that your map service contains group layers.
Take care that if you include a group layer in the list of layer to identify, all sublayers of this group layer will be identified.

I would recommend not to include the group layers in the list.

That being said I am not sure that explains your issue but it's worth the try.

If you still get the issue and that your service is public, could you check with fiddler what kind of identify request is sent to the server and could you share the URL of this request?

Thanks
0 Kudos
PatrickBrooke
Emerging Contributor
There are a couple of ways to accomplish this. The easiest way is if you use the new legend control ESRI developed for the Silverlight API. You can see my implementation and its behavior with idenitfy at

http://gis.modestogov.com

If interested in this type of identify layer restriction, I will elaborate further how to achieve this. This method is entirely dynamic. BTW, I am using group layers as well in mine, though you can't really tell on our public facing application.

You can also, on layer initialize, create a event void that gets all of the layer names and IDs from your map service. Then you can hard code a list of layers that you want identifiable, but that is very static. You are correct in your previous post that you would cycle through a list (foreach) using this approach.

I have my LayerOption set to visible and regardless of me specifying layers or not, it still Identify's a layer that is not in scale range?


This is because your REST service is stateless, your service does not know when they become visible in your app. Since they are checked on in your .mxd it calls them visible, regardless of your scale range, since the rest service does not know your apps scale range unless you tell it. You can send in the envelope (map extent) and resolution in to your query to handle this if you want to do it that way. The arguments are available on the identify task. This way the map service knows what your app is doing.

I suggest you use the legend control though if you can, it is sooooo simple 🙂
0 Kudos
BrandonCales
Regular Contributor
Very Nice..all of it! Yours seems to work as I expect it, where until your parcels are visible, you cannot identify them. I'd definitely be interested in more on this - and any of your other functionality you'd care to share 😉

If easier, I can provide you with my email.

I guess I'm more used to .NET ADF where it utilizes how my mxd is setup. I was kind of hoping for it to.

I have it working

There are a couple of ways to accomplish this. The easiest way is if you use the new legend control ESRI developed for the Silverlight API. You can see my implementation and its behavior with idenitfy at

http://gis.modestogov.com

If interested in this type of identify layer restriction, I will elaborate further how to achieve this. This method is entirely dynamic. BTW, I am using group layers as well in mine, though you can't really tell on our public facing application.

You can also, on layer initialize, create a event void that gets all of the layer names and IDs from your map service. Then you can hard code a list of layers that you want identifiable, but that is very static. You are correct in your previous post that you would cycle through a list (foreach) using this approach.



This is because your REST service is stateless, your service does not know when they become visible in your app. Since they are checked on in your .mxd it calls them visible, regardless of your scale range, since the rest service does not know your apps scale range unless you tell it. You can send in the envelope (map extent) and resolution in to your query to handle this if you want to do it that way. The arguments are available on the identify task. This way the map service knows what your app is doing.

I suggest you use the legend control though if you can, it is sooooo simple 🙂
0 Kudos
PatrickBrooke
Emerging Contributor
Parcels don't identify? I can't recreate that error, they do when I try. Are you getting an error message in your browser?

Anyway, back to your problem...

Using the legend control, here is what I do (I am going to assume that anyone who takes this suggest will look at ESRI's legend sample and see how to implement the legend).

For the identify task I create a function of the type List int[]

public List<int> checkVisibility()
        {           
           List<int> visibleLayers = new List<int>();
           
                if (mapLegend.LayerItems != null)
                {                    
                   //look at layers in group layer "0"
                   foreach (LayerItemViewModel enabledLyr in mapLegend.LayerItems[0].LayerItems)
                    {
                     for (int i = 0; i < enabledLyr.LayerItems.Count; i++)
                        {                           
                                if (enabledLyr.LayerItems.IsVisible)
                                {
                                    visibleLayers.Add(enabledLyr.LayerItems.SubLayerID);
                                }   
                         }                      
            
             return visibleLayers;
               }

   //then on your identify task parameter
   identifyParams.LayerIds.AddRange(checkVisibility()); 
        }


This will check the legend each time to see what is visible based on being check on in the legend or visible in the scale range. This is a simplified version of what I did, just to give an idea.

If you need more, then yeah, maybe we should do e-mail or phone. It is pretty simple, but complicated at the same time.
0 Kudos
BrandonCales
Regular Contributor
No..I meant that it works as expected and how I want it.

I will give it a shot...thanks a bunch
0 Kudos
RamonLira
Deactivated User
I noticed that your map service contains group layers.
Take care that if you include a group layer in the list of layer to identify, all sublayers of this group layer will be identified.

I would recommend not to include the group layers in the list.

That being said I am not sure that explains your issue but it's worth the try.

If you still get the issue and that your service is public, could you check with fiddler what kind of identify request is sent to the server and could you share the URL of this request?

Thanks


The identify task supports  query to raster layers? is there any example? because I had problems in the identification of raster layers. I have groups of raster layers and  groups of feature layers , but identification only send me the result of the first two raster layers for each group although I assigned the entire list of raster layers to identify. For Feature layers is not problem, return all results.
0 Kudos