Select to view content in your preferred language

Reset ArcGISDynamicMapServiceLayer Layers to Initial Visibility

1274
5
02-28-2013 12:17 PM
LanceCrumbliss
Frequent Contributor
Is there an easy way to reset the Layers in a ArcGISDynamicMapServiceLayer to their initial Visibility state?  I would like for a button in the application to perform a map reset (zoom to initial extent - which it currently does already - and reset all layer visibility states).  That is, to their default visibility as defined in the MapService.

Lance
0 Kudos
5 Replies
LanceCrumbliss
Frequent Contributor
Certainly there is a better way than this

 For Each livm As LayerItemViewModel In esriLegend.LayerItems                
If TypeOf livm.Layer Is ArcGISDynamicMapServiceLayer Then
                    Dim agdsl As ArcGISDynamicMapServiceLayer = CType(livm.Layer, ArcGISDynamicMapServiceLayer)
                    Dim dvl As List(Of Integer) = (From x In agdsl.Layers Where CBool(x.DefaultVisibility) = True And x.SubLayerIds Is Nothing Select x.ID).ToList
                    Dim gl As List(Of LayerInfo) = (From x In agdsl.Layers Where CBool(x.DefaultVisibility) = False And x.SubLayerIds IsNot Nothing).ToList
                    For Each li As LayerInfo In gl
                        For Each i As Integer In li.SubLayerIds
                            dvl.Remove(i)
                        Next
                    Next
                    agdsl.VisibleLayers = dvl.ToArray
                End If
            Next


It looks ugly, for one.  Another reason is that group layers in the legend will be displayed differently than on a true "reset".  For example, by default a grouplayer may have been set to not visible, but its sublayers to visible.  By default, that means no sublayers in the group display although they're checked in the legend (desired behavior!).  After the above code runs, of course the sublayers will be unchecked in the legend.  The map displays correctly, but the user loses the ability to simply turn on the grouplayer to make all the sublayers visible (because they've been unchecked!).  The user would have to check on all the sublayers.

Lance
0 Kudos
LanceCrumbliss
Frequent Contributor
i have to say i'm really surprised that this question hasn't been raised before.  Not that I've ever used a "reset map" feature personally, but it isn't the first time I've been asked to put one in an application.  It actually seems like a logical function to have in there the more I think about it.
0 Kudos
DominiqueBroux
Esri Frequent Contributor
Resetting VisibleLayers to null should do the job.
Unfortunately it seems there is a bug in the API since the layer is correctly reset to its original state but the legend is not updated.

Thanks for pointing out that issue, we'll try to get it fixed in a future version.

That being said, my feeling is that you shoud get the expected result with code like:

Dim dvl As List(Of Integer) = (From x In agdsl.Layers Where CBool(x.DefaultVisibility) = True Select x.ID).ToList
agdsl.VisibleLayers = dvl.ToArray
0 Kudos
JustinCornell
Occasional Contributor

That being said, my feeling is that you shoud get the expected result with code like:

Dim dvl As List(Of Integer) = (From x In agdsl.Layers Where CBool(x.DefaultVisibility) = True Select x.ID).ToList
agdsl.VisibleLayers = dvl.ToArray


Unfortunately that fix won't truly work.  If there is a parent layer defaulted off and it contains a child layer defaulted on then it would turn on the child even though the parent is defaulted off.
0 Kudos
JustinCornell
Occasional Contributor
Here is a sample (sorry c# not vb.net) of what I do to get around this bug.  It takes into account nested parent layers and uses the outermost parents' visibility.  Hope this helps.

var ids = new List<int>();
var parentLayers = _dmsl.Layers.Where(x => x.SubLayerIds != null).ToArray();
foreach (var l in _dmsl.Layers)
{
    if (parentLayers.Contains(l) && l.DefaultVisibility)
    {
        ids.Add(l.ID);
    }
    else
    {
        //find the parent of the child layer
        var pl = parentLayers.Where(x => x.SubLayerIds.Contains(x.ID)).FirstOrDefault();

        //iterate through parent layers until we reached the outermost parent
        while (parentLayers.Contains(pl))
        {
            var tempPl = parentLayers.Where(x => x.SubLayerIds.Contains(pl.ID)).FirstOrDefault();
            if (tempPl == null)
                break;
            else
                pl = tempPl;
        }

        //determine if the layer should be visible
        if (pl != null)
        {
            if (pl.DefaultVisibility && l.DefaultVisibility)
                ids.Add(l.ID);
        }
    }
}
0 Kudos