Select to view content in your preferred language

Zoom To Layer Capability in TOC

3690
18
01-20-2011 07:25 AM
PaulHuppé
Deactivated User
Hi,
I am trying to add a zoom-to individual layers inside a map service.  In my Legend template, I added an image to represent the zoom action and I wanted to add an event trigger that would automatically zoom to the extent of that layer.  Something like:

<Image Source="images/zoom.png">
    <i:Interaction.Triggers>
          <i:EventTrigger EventName="Click">
                   <esri:ZoomToAction TargetName="Map">
                           <esri:ZoomToAction.Geometry>

                                  Use some binding here to get the envelope

                           </esri:ZoomToAction.Geometry>
                    </esri:ZoomToAction>
          </i:EventTrigger>
   </i:Interaction.Triggers>
</Image>


But, when I try to add this, I get a message saying "A value of type 'ZoomToAction' cannot be added to a collection or dictionary of type 'TriggerActionCollection'."  Can't I do this?  There is something similar done in the online samples that zoom-to a hardcoded envelope. Here is the code that is used:

                    <Button Style="{StaticResource MenuItem}" 
                            Content="Zoom To" >
                        <i:Interaction.Triggers>
                            <i:EventTrigger EventName="Click">
                                <esri:ZoomToAction
                                    TargetName="MyMap">
                                    <esri:ZoomToAction.Geometry>
                                        <esri:Envelope XMin="-14930991.170" YMin="3611744.037" XMax="-11348896.882" YMax="5340571.181" />
                                    </esri:ZoomToAction.Geometry>
                                </esri:ZoomToAction>
                            </i:EventTrigger>
                        </i:Interaction.Triggers>
                    </Button>


There is another sample that zooms to a service layer.

                    <Button Style="{StaticResource MenuItem}" 
                            Content="Zoom To Layer" >
                        <i:Interaction.Triggers>
                            <i:EventTrigger EventName="Click">
                                <esri:ZoomToLayerAction
                                    LayerID="MyFeatureLayer"
                                    TargetName="MyMap" />
                            </i:EventTrigger>
                        </i:Interaction.Triggers>
                    </Button>



I am using the Legend control in the 2.1 API.
Paul
0 Kudos
18 Replies
DominiqueBroux
Esri Frequent Contributor

But, the trigger does not seem to do anything.


After digging this issue, I found that the issue is coming from TargetName="Map". As it's defined in a template, the domain name is not the same and we can't access element name defined in the main page.


Question: Does the ZoomToLayerAction work only for a Feature layer, or should it also work for any layer in a ArcGISDynamicMapServiceLayer?


The ZoomToLayerAction is working for an ArcGISDynamicMapServiceLayer but is not working for the sublayers.

Furthermore the action is not working if the layer is not in the same spatial reference than the map.

With all these limitations, this action looks as not very useful in your case, so you should probably develop your own zoom code.
0 Kudos
PaulHuppé
Deactivated User
I thought that I would not be able to do it so I have already started to do my own zoom code.  My code does return strange values.  The map uses the spatial reference of the first service in the list of services defined which is fine.  All other services are projected on the fly as required and things are showing up where they should be.  But, when I try to get the extent of a specific layer, it is returned in the projection of the map service it comes from instead of using the application's Map spatial reference.  here is the code being used:

        private void imgZoomToLayer_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            Image img = (Image)sender;
            string layer = img.Tag.ToString();
            ESRI.ArcGIS.Client.Geometry.Envelope envLayer = FindLayerExtent(layer);
            envLayer.SpatialReference = Map.SpatialReference;
            Map.ZoomTo(envLayer as ESRI.ArcGIS.Client.Geometry.Envelope);
        }


        private ESRI.ArcGIS.Client.Geometry.Envelope FindLayerExtent(string desiredLayer)
        {
            ESRI.ArcGIS.Client.Geometry.Envelope envLayer = null;
            foreach (ESRI.ArcGIS.Client.Layer service in Map.Layers)
            {
                string sname = service.ID;
                if (service.GetType().ToString() == "ESRI.ArcGIS.Client.ArcGISDynamicMapServiceLayer")
                {
                    ArcGISDynamicMapServiceLayer l = (ArcGISDynamicMapServiceLayer)service;
                    foreach (ESRI.ArcGIS.Client.LayerInfo slayer in l.Layers)
                    {
                        if (desiredLayer == slayer.Name)
                        {
                            envLayer = Map.Layers[l.ID].FullExtent;
                        }
                    }
                }
            }
            return envLayer;
        }


For example, if I click the zoom button next to the "DEM Atlantic Relief" layer (see image "map.png"), I get extents as shown in the image attached call "extent_DEM.png".  But, the Map.Extent is as shown in the image "extent_Map.png".  As you can see, the extents of the layer are not projected to the map extent and when the methods does the ZoomTo, it results in a zoom out because of the values of the layer extent returned.
0 Kudos
DominiqueBroux
Esri Frequent Contributor
I don't know what are the spatial references of your map (i.e your base map service) and of your map services.

But if they are not identical you have to project the fullextent of the map services to the spatial reference of the map.

Your code :  'envLayer.SpatialReference = Map.SpatialReference;' is not doing any projection, it's just setting a property of the geometry.

Instead, if the two spatial references are different, the code should project envLayer to Map.SpatialReference.

Most generally, to project a geometry, you can use a geometry service (see sample : http://help.arcgis.com/en/webapi/silverlight/samples/start.htm#Project).

In the specific case of WebMercator<-->Geographical coordinates (but this doesn't seem your case), you can use the ESRI out-of-the-box transformation methods.
0 Kudos
PaulHuppé
Deactivated User
I tried using a Geometry service to project the coordinates and that works.
Thanks,
Paul
0 Kudos
BarraLoubna
Deactivated User
Hello, I use "ZoomToLayerAction" action that is in a context menu at the right click each layer of a list of layers,

the action works very well when I specifies the ID of a Layer, but how to do a zoomtolayer each layer was chosen, I mean when I click on the menu for a layer that zooms me on this layer, how to manage the area change of layers.

this is my code from the list of layers:

<esri1:Legend Map="{Binding ElementName=MyMap}" LayerItemsMode="Tree" LayerIDs="MyFeatureLayer, Bloomfield Hills, DynamicLayer"
                ShowOnlyVisibleLayers="False" Refreshed="Legend_Refreshed" Margin="2,19,2,3" HorizontalAlignment="Left" Width="188" LegendItemTemplate="{Binding Customer}" >
            <esri1:Legend.MapLayerTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <CheckBox Content="{Binding Label}"
                            IsChecked="{Binding IsEnabled, Mode=TwoWay}"
                            IsEnabled="{Binding IsInScaleRange}">
                             <toolkit:ContextMenuService.ContextMenu>
                                    <toolkit:ContextMenu >
                                 <toolkit:MenuItem Header="Downoald" Click="Downoald_Click"/>
                                 <toolkit:MenuItem Header="DataGrid" Click="DataGrid_Click"/>
                                                        
                                 <toolkit:MenuItem Header="ZoomToLayer" Click="ZoomToLayer_Click" >
                                             <i:Interaction.Triggers>
                     <i:EventTrigger EventName="Click">
                     <esri1:ZoomToLayerAction LayerID="MyFeatureLayer" TargetName="MyMap" />
                     </i:EventTrigger>
                     </i:Interaction.Triggers>
                           
                                     </toolkit:MenuItem>
                                 </toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>

                        </CheckBox>   
                                       
                     </StackPanel>
                </DataTemplate>
            </esri1:Legend.MapLayerTemplate>
                               
        </esri1:Legend>



Please help me is very urgent
0 Kudos
BarraLoubna
Deactivated User
in c# my code is:
private void ZoomToLayer_Click(object sender, RoutedEventArgs e)
        {
    MyMap.ZoomTo(MyMap.Layers["MyFeatureLayer"].FullExtent);
    
        }


how to differentiate the action of a zoom layer has another different layer?

please help me, I'm beginner in programming.
0 Kudos
JenniferNery
Esri Regular Contributor
You can add highlighted line in the MapLayerTemplate of this SDK sample: http://help.arcgis.com/en/webapi/silverlight/samples/start.htm#LegendWithTemplates

                <esri:Legend.MapLayerTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <CheckBox Content="{Binding Label}"
                  IsChecked="{Binding IsEnabled, Mode=TwoWay}"
                  IsEnabled="{Binding IsInScaleRange}" >
                            </CheckBox>
                            <Slider Maximum="1" Value="{Binding Layer.Opacity, Mode=TwoWay}" Width="50" />
                            <Button Content="Zoom" Click="Button_Click" Tag="{Binding Layer.FullExtent}"/>
                        </StackPanel>
                    </DataTemplate>
                </esri:Legend.MapLayerTemplate>


        private void Button_Click(object sender, RoutedEventArgs e)
        {
            var extent = (sender as Button).Tag as Envelope;
            MyMap.ZoomTo(extent);
        }
0 Kudos
BarraLoubna
Deactivated User
Thank you Jenniferdnery for your reply, it works great, I do :
<esri1:Legend.MapLayerTemplate>
        <DataTemplate>
              <StackPanel Orientation="Horizontal">
                    <CheckBox Content="{Binding Label}" IsChecked="{Binding IsEnabled, Mode=TwoWay}" IsEnabled="{Binding IsInScaleRange}">
           <toolkit:ContextMenuService.ContextMenu>
    <toolkit:ContextMenu >
     <toolkit:MenuItem Header="Downoald" Click="Downoald_Click"/>
     <toolkit:MenuItem Header="DataGrid" Click="DataGrid_Click"/> 
     <toolkit:MenuItem Header="{Binding Label}" Click="ZoomToLayer_Click" Tag="{Binding Layer.FullExtent}">
                    </toolkit:MenuItem>
    </toolkit:ContextMenu>
   </toolkit:ContextMenuService.ContextMenu>
       </CheckBox>
</StackPanel>
        </DataTemplate>
</esri1:Legend.MapLayerTemplate>

in c#:
private void ZoomToLayer_Click(object sender, RoutedEventArgs e)
  {
   var extent = (sender as MenuItem ).Tag as Envelope;
                                             MyMap.ZoomTo(extent);
  }



for the context menu Download I used the following code:

private void Downoald_Click ( object sender, EventArgs e)
  {
   
     System.Windows.Browser.HtmlPage.Window.Navigate(new Uri("V:\\SIG\\DATA\\.....\\LuxembourgVille.SHP", UriKind.Absolute), "_newWindow");
  }
 

But I do not know how to get it every time I downloaded the file corresponding to each Layer



I would be grateful if you  can help me.

Thank you very much.
0 Kudos
JenniferNery
Esri Regular Contributor
I think you want to use SaveFileDialog: http://msdn.microsoft.com/en-us/library/system.windows.controls.savefiledialog%28v=vs.95%29.aspx or maybe WebClient.OpenReadAsync http://msdn.microsoft.com/en-us/library/ms144211%28v=vs.95%29.aspx? How does the shape file relate to your layer? HtmlPage.Navigate() needs a URL that can be opened in a browser.
0 Kudos