Select to view content in your preferred language

bug in/ or wrong usage of Navigation control using FullExtent button

1662
11
03-21-2011 12:18 PM
BKuiper
Frequent Contributor
Hi,

I'm doing the following

I've cleared the Map layers collection, set the map extent to the extent and spatialreference of my second layer. Then add both my layers. The first layer originally has a different spatialreference but now is reprojected by the Map control to match the spatialreference of my second layer.

Now, my program will crash if I click "FullExtent" in the Navigation control.

Looking at the code the following happens:

FullExtent Button Click handler:
  private void ZoomFullExtent_Click(object sender, RoutedEventArgs e)
  {
   if (Map != null)
    Map.ZoomTo(Map.Layers.GetFullExtent());
  }


this calls Map.Layers.GetFullExtent() where the "error" occurs:
public Envelope GetFullExtent()
{
    if (base.Count == 0)
    {
        return null;
    }
    Envelope extent = null;
    SpatialReference spatialReference = null;
    foreach (Layer layer in this)
    {
        if ((layer != null) && (layer.SpatialReference != null))
        {
            spatialReference = layer.SpatialReference;
            break;
        }
    }
    foreach (Layer layer2 in this)
    {
        Envelope fullExtent = layer2.FullExtent;
        if (((fullExtent != null) && SpatialReference.AreEqual(fullExtent.SpatialReference, spatialReference, true)) && (fullExtent != null))
        {
            extent = fullExtent.Union(extent);
        }
    }
    return extent;
}


The following piece of code sets the extent to which the map should zoom to but uses the original spatialreference of the first layer:
        if ((layer != null) && (layer.SpatialReference != null))
        {
            spatialReference = layer.SpatialReference;
            break;
        }


Shouldn't this code get the spatialreference from the Map control itself (when it contains layers)
spatialReference = Map.FullExtent.SpatialReference


?

I'm I correct or just doing stuff the wrong way?

My idea was that the Map control would do the reprojection of the basemap for me, so i don't have to create a basemap for each different spatialreference.


EDIT:

I forgot to mention that the Map.ZoomTo() operation will fail because the SpatialReference doesn't match the spatial reference currently used by the map, thus crashing the app.
0 Kudos
11 Replies
JenniferNery
Esri Regular Contributor
Are you using Toolkit.Navigation http://help.arcgis.com/en/webapi/silverlight/samples/start.htm#Navigation?

I have the following code for switching base layer of different spatial reference. I am able to use the Navigation control to pan, rotate and zoom without problem.
private void RadioButton_Click(object sender, RoutedEventArgs e)
{
 ArcGISTiledMapServiceLayer layer = this.LayoutRoot.Resources[((RadioButton)sender).Tag] as ArcGISTiledMapServiceLayer;
 if (layer.IsInitialized)
  UpdateMap(layer);
 else
 {
  layer.Initialized += (s, a) => { UpdateMap(s as ArcGISTiledMapServiceLayer); };
  layer.Initialize();
 }
}

private void UpdateMap(ArcGISTiledMapServiceLayer layer)
{
 MyMap.Layers.Clear();
 MyMap.Extent = new Envelope()
 {
  XMin = layer.FullExtent.XMin,
  YMin = layer.FullExtent.YMin,
  XMax = layer.FullExtent.XMax,
  YMax = layer.FullExtent.YMax,
  SpatialReference = layer.SpatialReference
 };
 MyMap.Layers.Add(layer);
}


<Grid.Resources>
 <esri:ArcGISTiledMapServiceLayer x:Key="Base3857"  ID="Base3857" 
                  Url="http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer"/>
 <esri:ArcGISTiledMapServiceLayer x:Key="Base4326"  ID="Base4326"
    Url="http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/TaxParcel/AssessorsBasemap/MapServer"/>
</Grid.Resources>
0 Kudos
BKuiper
Frequent Contributor
Hi Jennifer, thanks for taking the time to answer my question,

Your response made me rethink what i'm doing and I want to try explain a bit more on what i'm trying to achieve.

I have two different layers
1. usa basemap, spatialreference wkid: 102100 (3857)
2. national park, spatialreference wkid: 26912

I want to add both layers to a Map control and then zoom to the extent of the second (2) layer.

I'm currently achieving this by reading the spatial reference of layer 2, clearing the Map layers collection, setting the extent and spatialreference of the Map control to that of layer 2 and then adding both layers and zooming to the extent of layer 2. This works, but breaks the "Zoom to Fullextent" button (right bottom corner) of the Navigation control (part of the toolkit).

It crashes the application because it tries to use the spatialreference of the first layer in the collection, but this spatialreference doesn't match the spatialreference of the Map. Therefore I think this is a bug and should use the spatialreference of the Map when the Map control contains items in the Layer collection.

So to summarize it:
- Is there an easier way to add two layers with different spatial references and zooming in to the extent of the second layer, or is my proposed solution the way to do it.

- If my proposed solution is correct, then there is possibly a bug in the code when clicking "Zoom to Full extent" of the Navigation Control which is part of the Toolkit.

Hope this better explains what i'm trying to do

Thanks again for the time and effort to help me out
0 Kudos
JenniferNery
Esri Regular Contributor
You can look at this documentation: http://help.arcgis.com/en/webapi/silverlight/apiref/ESRI.ArcGIS.Client~ESRI.ArcGIS.Client.Map~Spatia...

The Map's Spatial Reference is determined by the first layer with Spatial Reference. So if you want layer 2's Spatial Reference, you need to clear Map.Layers first, and add layer 2 as the first layer.

EDIT: Thank you for reporting this bug. We'll try to get it fixed in future versions of our API. For the time-being, you can re-arrange your layers so that the first layer has the desired spatial reference.
0 Kudos
BKuiper
Frequent Contributor
Hi Jennifer, thanks again for your reply.

Adding layer 2 first and then layer 1 is not an option. Layer 1 is a basemap and will cover layer 2 making it invisible.

You could then consider moving (switching) the layers after the map is initialized, but that will re-introduce the same problem again, the "Zoom to Full Extent" button will fail because it will use the SR of layer 1 which is different then the SR of the Map.

I think the Map.ZoomTo(Map.Layers.GetFullExtent()) in the click event of the "Zoom to Full Extent" button should be checking if the layer is matching the SR of the Map and use that extent.

I could log a proper bug report if you want? So we can take it offline from the forum and discuss and track it there? What is the best place to do this?

I posted it here first to check if I was using the right approach or not.
0 Kudos
JenniferNery
Esri Regular Contributor
I had just created a work item for this to fix Layers.GetFullExtent() so that it uses the map's spatial reference if it had already been set, otherwise, use the first layer with spatial reference.

You don't need to create a bug report unless you want to. You can submit through our tech support. http://support.esri.com/en/

Thanks!
0 Kudos
BKuiper
Frequent Contributor
Great, thanks! Feel free to contact me if you or any of the other developers wants to recreate the problem when fixing this issue.
0 Kudos
SangamLama
Emerging Contributor
I was wondering if this bug has been fixed? I'm going through the exact same issue ie I have two layers, and the map needs to be able to zoom to full extent w.r.t. the secondary layer. I assign the full extent of the secondary map layer to the map before any layers are added. Everything else works in the navigation control except for the full extent button.

If it hasn't been fixed, is there a way to remove the full extent button from the control?

Thanks,
0 Kudos
BKuiper
Frequent Contributor
Not sure if there is a fix, but you can just edit the default style or make your own style that doesn't include the "FullExtent" button.

I made the following changes to the default style:

I commented the following
         
 <!--<Button x:Name="ZoomFullExtent" Height="25" FontSize="8" Width="25" ToolTipService.ToolTip="Full Extent" Margin="2,2,2,0" Style="{StaticResource NavButtonStyle}">
            <Button.Content>
                                                    <Image Source="/ATMPWeb.Silverlight.Library;component/Images/i_globe.png" Stretch="Fill" />
            </Button.Content>
           </Button>-->


And changed -125 to -100 (how high the popup should go)

       
 <DoubleAnimation x:Name="showButtonsAnim" Duration="00:00:00.3" 
               Storyboard.TargetName="PopoutGrid" 
               Storyboard.TargetProperty="(Canvas.Top)" To="-100" /> <!-- -125 -->
         </Storyboard>


Hope that helps
0 Kudos
SangamLama
Emerging Contributor
where is this code that you're editing? all I do to use the navigation control is

<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Grid.Row="2" VerticalAlignment="Bottom">
                        <esri2:Navigation x:Name="MyNavigation" Margin="5"></esri2:Navigation>
                    </StackPanel>

and I assign the map from the codebehind.

Not sure if there is a fix, but you can just edit the default style or make your own style that doesn't include the "FullExtent" button.

I made the following changes to the default style:

I commented the following
         
 <!--<Button x:Name="ZoomFullExtent" Height="25" FontSize="8" Width="25" ToolTipService.ToolTip="Full Extent" Margin="2,2,2,0" Style="{StaticResource NavButtonStyle}">
            <Button.Content>
                                                    <Image Source="/ATMPWeb.Silverlight.Library;component/Images/i_globe.png" Stretch="Fill" />
            </Button.Content>
           </Button>-->


And changed -125 to -100 (how high the popup should go)

       
 <DoubleAnimation x:Name="showButtonsAnim" Duration="00:00:00.3" 
               Storyboard.TargetName="PopoutGrid" 
               Storyboard.TargetProperty="(Canvas.Top)" To="-100" /> <!-- -125 -->
         </Storyboard>


Hope that helps
0 Kudos