How to create a new IEnumLayer object?

3554
6
Jump to solution
11-03-2014 06:24 PM
ericliprandi
New Contributor III

Hi,

I am trying to filter an IEnumLayer to only contain visible layers. I want to pass this to IFeatureCache2.AddLayers(...). I could not find any public implementations of IEnumLayer. Since we are in C# I wrote a couple of extension methods that convert IEnumLayer to IEnumerable<ILayer> and vice-versa. But passing my custom implementation of IEnumLayer did not seem to make AddLayers(...) happy.

Here is my extensions class:


    public static class EnumLayerExtensions
    {
        public static IEnumerable<ILayer> AsEnumerable(this IEnumLayer layers)
        {
            layers.Reset();
            var layer = layers.Next();
            while (layer != null)
            {
                yield return layer;
                layer = layers.Next();
            }
        }


        public static IEnumLayer ToEnumLayer(this IEnumerable<ILayer> layers)
        {
            return new EnumLayerWrapper(layers);
        }


        private class EnumLayerWrapper : IEnumLayer
        {
            private readonly ILayer[] _layers;
            private int _index;


            public EnumLayerWrapper(IEnumerable<ILayer> layers)
            {
                _layers = layers.ToArray();
                _index = 0;
            }


            public ILayer Next()
            {
                return _index < _layers.Length ? _layers[_index++] : null;
            }


            public void Reset()
            {
                _index = 0;
            }
        }
    }



using this I can then write the following code:


var visibleLayers = Map.Layers.AsEnumerable().Where(l=>l.Visible);


var cache = new FeatureCacheClass() as IFeatureCache2;


cache.Initialize(point,radius);


cache.AddLayers(visibleLayers.ToEnumLayer(), null);



In the above code, line 04 will just run for ever as-is. If I use the layers straight from the Map, it comes back fairly fast. I have written a handful of unit tests to validate my implementation of ToEnumLayer() and they all seem to pass. Based on all this, I have a couple of questions:

  1. Is there an out of the box implementation of IEnumLayer that I can use to filter visible layers only to pass to IFeatureCache2.AddLayers()?
  2. What's wrong with my implementation of IEnumLayer?

Thanks in advance for any help,

Eric.

Tags (2)
0 Kudos
1 Solution

Accepted Solutions
by Anonymous User
Not applicable

Eric,

You'll probably find its looping through the ILayer Next implementation.

You'll need to throw an exception there rather than return null.

    public ILayer Next()

    {

      if (index < layers.Count)

        return layers[index++];

      else

        throw new Exception();

    }

View solution in original post

0 Kudos
6 Replies
ModyBuchbinder
Esri Regular Contributor

Hi

There is no way to create IEnumLauers only to get it from IMap.Layers

If you need only the visible layers run a loop on the layers (from bottom up) and IMap.DeleteLayer all the non-visible layers and then use IMap.Layers.

Then you can exists without save or keep a list of the deleted layers and add them back to the map.

Have Fun

Mody

0 Kudos
ErinBrimhall
Occasional Contributor II

Eric,

At a glance, your extension methods and wrapper class implementing IEnumLayer look good.  The problem may be in the way that the IFeatureCache object is interacting with the structure you've created.

Have you instrumented the methods of your wrapper class (e.g. Debug.WriteLine) to see what happens after calling cache.AddLayers?

0 Kudos
by Anonymous User
Not applicable

Eric,

You'll probably find its looping through the ILayer Next implementation.

You'll need to throw an exception there rather than return null.

    public ILayer Next()

    {

      if (index < layers.Count)

        return layers[index++];

      else

        throw new Exception();

    }

0 Kudos
ericliprandi
New Contributor III

Sean,

Thanks for the info. It all sounded too familiar when Rich Ruh‌ contacted me yesterday to see if that would work. It does actually work. Now, my custom IEnumLayer implementation does work.

However, my first experiments are not looking too promising the IFeatureCache2 respecting layers. It seems that it goes straight to the FeatureClass, ignoring the definition query.

0 Kudos
by Anonymous User
Not applicable

Eric,

You're right. I took a look at the source and despite the name, AddLayers is adding the underlying featureclass to the cache rather than the display layer, so it wont respect the definition query. I'll add a CR....

0 Kudos
RichRuh
Esri Regular Contributor

Eric,

Giving credit where credit is due, Sean Jones‌ provided the answer to me when I contacted you yesterday.

--Rich

0 Kudos