Select to view content in your preferred language

ArcGis "Zoom To Layer" functionality in ESRI Silverlight API

4613
12
07-28-2010 12:03 PM
AlexanderOvsyankin
Deactivated User
Hello Experts,

I have sde database and I published a dynamic service with 1 layer in it. The layer displaying data from sde spatial view.

When my map is initializing I want to zoom to the layer extent (extent of all features in this layer).

I have some options on how to do it:
1. Set full extent for the Data Frame in mxd before publishing and then zoom to
ArcGISDynamicMapServiceLayer.FullExtent. It's not a good aproach for me since it is a dynamic service and data are loading to sde by another application, so after data will arrive this extent will not be actual.

2. Set current extent in mxd to full layer extent before publishing and then zoom to
ArcGISDynamicMapServiceLayer.InitialExtent. It's not a good aproach again due to the same reason as described above.

3. Run query against the layer, get features, go throw the list of results and using feature.geometry - create an extent. But layer contains much more than 500 (recommended by ESRI amount of features to be returned by the query ) objects (~100 000) and in result my calculated extent will not present the real extent of data, but just a portion of it. Of course I can change the maximum amount of features to be returned by the query ;), but my map will be extremely slow since I will need to load all 100 000 features on the client side :(...

Additionally, I am filtering my layer using LayerDefinition and I want to be able to zoom into filtered layer too (in this case aproaches 1 and 2 don't work at all)...

4. Not sure, but: I can create my own geoprocessing service to get the extent of the layer on the server side and use it on the client side to zoom.

So the question is: Is there any other possibilities to Zoom to extent of all features in the layer? May be I missed something in the API reference?
0 Kudos
12 Replies
egismazeika
Emerging Contributor
What about this:
Map.Extent = yourLayer.FullExtent;
?
0 Kudos
AlexanderOvsyankin
Deactivated User
What about this:
Map.Extent = yourLayer.FullExtent;
?


Thank you for your reply, but I have a question: when you are saying yourLayer.FullExtent under yourLayer you mean service? or separate layer in the particular service?

If you mean service then it is similar case to #1 of my initial post and it will zoom to full extent for the Data Frame that was set in mxd before publishing...

If you mean separate layer, could you, please, provide some portion of code how to get to this particular layer.FullExtent property?
0 Kudos
ChristopherHill
Deactivated User
Is this what you need or do you need?

[HTML]
        <!--Map Control-->
        <esri:Map x:Name="esriMap">

            <!--Base Layer-->
            <esri:ArcGISTiledMapServiceLayer ID="baseLayer"
                Url="http://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer"/>

            <!--Dynamic Layer-->
            <esri:ArcGISDynamicMapServiceLayer ID="dynamicLayer"
               Url="..."
               Initialized="ArcGISDynamicMapServiceLayer_Initialized"/>
           
        </esri:Map>
[/HTML]
private void ArcGISDynamicMapServiceLayer_Initialized(object sender, EventArgs e)
{
   ArcGISDynamicMapServiceLayer dynamicLayer = esriMap.Layers["dynamicLayer"] as ArcGISDynamicMapServiceLayer;
   esriMap.Extent = dynamicLayer.FullExtent;
}
0 Kudos
AlexanderOvsyankin
Deactivated User
Is this what you need or do you need?

[HTML]
        <!--Map Control-->
        <esri:Map x:Name="esriMap">

            <!--Base Layer-->
            <esri:ArcGISTiledMapServiceLayer ID="baseLayer"
                Url="http://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer"/>

            <!--Dynamic Layer-->
            <esri:ArcGISDynamicMapServiceLayer ID="dynamicLayer"
               Url="..."
               Initialized="ArcGISDynamicMapServiceLayer_Initialized"/>
           
        </esri:Map>
[/HTML]
private void ArcGISDynamicMapServiceLayer_Initialized(object sender, EventArgs e)
{
   ArcGISDynamicMapServiceLayer dynamicLayer = esriMap.Layers["dynamicLayer"] as ArcGISDynamicMapServiceLayer;
   esriMap.Extent = dynamicLayer.FullExtent;
}


Thank you for the example, but again this example about service, not particular sublayer inside service...

So I am interesting in functionality on how to zoom to particular sublayer in the service, not the service itself... Is it possible?
0 Kudos
DominiqueBroux
Esri Frequent Contributor

So I am interesting in functionality on how to zoom to particular sublayer in the service, not the service itself... Is it possible?


I don't think it's possible if you are using MapServiceLayer.

You could either develop your own web service to calculate the extent or load the sublayer as FeatureLayer instead of MapServiceLayer (but there is a big cost specially if the only goal is to get the extent).
0 Kudos
AlexanderOvsyankin
Deactivated User
I don't think it's possible if you are using MapServiceLayer.

You could either develop your own web service to calculate the extent or load the sublayer as FeatureLayer instead of MapServiceLayer (but there is a big cost specially if the only goal is to get the extent).


Dominique! Thank you for the confirmation...
0 Kudos
priyajain
Emerging Contributor
Dominique! Thank you for the confirmation...


Hi ,

i also need to get into the sublayer of the service regardless of the effort needed .....

if anybody knows pls help

thanks in advance
priya
0 Kudos
DominiqueBroux
Esri Frequent Contributor

i also need to get into the sublayer of the service regardless of the effort needed .....



I have to clarify what I said in this thread because it could be confusing.

If your data are dynamic either because the data are loaded by other applications or because you are filtering at the client side (using layerdefs), it's not possible to easily know the extent at the client side (this was the initial subject of this thread).

Now if your data are static and that you can rely on the extent provided by the service, it's possible to get the extent of layer and sublayers at the client side:
- for a layer, there is a 'FullExtent' property
- for a sublayer, you can deserialize the info provided by the sublayer rest resource. For example, look at the extent info provided by this sublayer.

Hope this help.
0 Kudos
NickArnold
New Contributor
I have to clarify what I said in this thread because it could be confusing.

If your data are dynamic either because the data are loaded by other applications or because you are filtering at the client side (using layerdefs), it's not possible to easily know the extent at the client side (this was the initial subject of this thread).

Now if your data are static and that you can rely on the extent provided by the service, it's possible to get the extent of layer and sublayers at the client side:
- for a layer, there is a 'FullExtent' property
- for a sublayer, you can deserialize the info provided by the sublayer rest resource. For example, look at the extent info provided by this sublayer.


I'm not sure about doing this in Silverlight, but I had the exact same problem using the JSAPI and I solved it using an AJAX call to the server hosting the map services. (Caveat: This will only work if the map services are hosted on the same server as the web app.)  Here's my code:

function zoomToLayer(id) {
        //first, try the layer.fullExtent property
 var layer = map.getLayer(id);
 if (layer != null) {
  map.setExtent(layer.fullExtent);
 }
 else {
  //the layer is a sublayer, so we must dig deeper
  dojo.forEach(map.layerIds, function(layerId) {
   layer = map.getLayer(layerId);
   dojo.forEach(layer.layerInfos, function(layerInfo) {
    if (layerInfo.name == id) {
     //now we have a match, so make an AJAX request to the server to get the
     //json description of this sublayer, which contains the extent 
     //so f'ing dumb that the LayerInfo object doesn't wrap this for us...
     var args = {
      url: "/arcgis/rest/services/Foo/Bar/MapServer/"+layerInfo.id,
      handleAs: "json",
      content: {f:"pjson"},
      load:function(data) {
       var extent = data.extent;
       var sr = data.extent.spatialReference;
       map.setExtent(new esri.geometry.Extent(extent.xmin,extent.ymin,extent.xmax,extent.ymax,sr));
      }
     };
     var deferred = dojo.xhrGet(args);
    }
   });
  });
 }
}


Problem solved. I'm sure there's a way to do this in Silverlight, but I literally have zero experience with it. I hope this saves someone some time.
0 Kudos