Loop through layers in LayerGroup?

Feb 14, 2008 at 3:47 PM
Hello list,

I have a SharpMap map that contains 2 layergroups that both contain 7 layers or more. Most of these layers are vector, some are WMS.

I am implementing a mapClick in the AJAXMap sample. I already created a function to get info from a single dataset, but I would like to determine which datasources to query from the original map. So I want to create a loop like:

Foreach (SharpMap.Layers.Layer _lyr in myMap.Layers)
{

If (_lyr.GetType().FullName == "SharpMap.Layer.LayerGroup")
{
//get the undelying layers (how?)
}
}

Is there anyone that has any experience with this? I get the feeling the object model for layers and layer groups might not be ready for getting information like this?

Kind regards,

Milo van der Linden
Coordinator
Feb 14, 2008 at 6:28 PM
Here is what I'd do:

foreach (SharpMap.Layers.LayerGroup layerGroup in myMap.Layers)
{
   if(layerGroup != null)
   {
      foreach(SharpMap.Layers.Layer subLayer in layerGroup.Layers)
      {
           // do stuff ...
      }
   }  
}
Feb 15, 2008 at 6:35 AM
Edited Feb 15, 2008 at 6:57 AM
Thank you codekaizen!

I am going to test this when I reach the office today.
My first guess is that to return all the "click information" I need an InfoHandler like :

Removed code snippet because it contained errors
Feb 15, 2008 at 6:56 AM
Yes! I got it working! Now my AjaxMap also has a real Info-click handler.
My next small project will be to create a layer-control (or legend) in almost the same way.

public class InfoHandler : IHttpHandler {
          
    public void ProcessRequest (HttpContext context) {
        context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
        //Right now, I output as text, because I assign it to the innerHTML, all html code is parsed correctly. The next line can be changed to parse XML or JSON to give a
        //broader range of control to the javascript at the frontend.
        context.Response.ContentType = "text/plain";
        if (context.Request["x"] != null && context.Request["y"] != null)
        {
            string strx = context.Request["x"];
            string stry = context.Request["y"];
            
            double x = Convert.ToDouble(strx.Replace(".", ","));
            double y = Convert.ToDouble(stry.Replace(".", ","));
 
            SharpMap.Map myMap = MapHelper.InitializeMap(new System.Drawing.Size(10, 10));
            SharpMap.Geometries.Point p = new SharpMap.Geometries.Point(x, y);
            string str_out = "";
            foreach (SharpMap.Layers.LayerGroup layerGroup in myMap.Layers)
            {
                if (layerGroup != null)
                {
                    foreach (SharpMap.Layers.VectorLayer subLayer in layerGroup.Layers)
                    {
                        if (subLayer.DataSource.GetType().FullName == "SharpMap.Data.Providers.Ogr")
                        {
                            SharpMap.Data.FeatureDataSet ds = new SharpMap.Data.FeatureDataSet();
                            subLayer.DataSource.ExecuteIntersectionQuery(p.GetBoundingBox(), ds);
                            
                            if (ds.Tables[0].Count > 0)
                            {
                                //loop through the records en append it's content to the
                                //output string
                                
                                foreach (SharpMap.Data.FeatureDataRow row in ds.Tables[0].Rows)
                                {
                                    foreach (DataColumn col in ds.Tables[0].Columns)
                                    {
                                        // Change this little piece of output to control how the data gets presented in the frontend.
                                        string colname = col.ColumnName;
                                        string colValue = Convert.ToString(row[col.ColumnName]);
                                        str_out += "<B>" + colname + "</B>:" + colValue + "<br>";
                                    }
                                    str_out += "<br>";
                                }
                                ds = null;
                            }
                        }
                        //context.Response.Write(str_out);
                    }
                    
                }
                
            }
            context.Response.Write(str_out);
        }
        else 
        {
                context.Response.Write("Geen gegevens"); 
        }            
    }
Coordinator
Feb 15, 2008 at 4:50 PM
Very nice, milo!

You might consider not using strings to check types - it is much safer to do this:

...
                    foreach (SharpMap.Layers.VectorLayer subLayer in layerGroup.Layers)
                    {
                        if (subLayer.DataSource is SharpMap.Data.Providers.Ogr)
                        {
...
Feb 16, 2008 at 9:09 AM
Perfect!

That is the final piece of the puzzle. I changed the getType() to your suggestion and it works.

Jul 2, 2008 at 5:29 AM
Hi there,

I'm after this functionality in an app I'm putting together with the AjaxMap control.  Are you (Milo) able to explain how you get the javascript in your .aspx page to launch this InfoHandler (passing the clicked coordinates). 
I'm not great with javascript and I think this basic example would help me greatly. 

Once I get that going, I'm wanting to get some drawing tools built for the AjaxMap, so that users can create features and edit them in a nice manner.  You don't happen to have any code along those lines lying around that
I could base my work on?  It's always worth asking just in case.

Thanks, Steve