Zoom to features in feature layer

4164
6
02-03-2014 02:43 PM
RowanWinsemius
New Contributor II
Hi there,

Noob question here... I've managed to get my map going which is consuming a feature layer over a basemap, all working fine so far!

I've got a definition expression on my feature so that I'm only returning a few polygons. I'm now trying to work out how to make the map automatically zoom to the extent of the returned polygons.

Any tips would appreciated.

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <!--The viewport meta tag is used to improve the presentation and behavior of the samples 
      on iOS devices-->
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
    <title>Layer in a map service - [ON-DEMAND]</title>

    <link rel="stylesheet" href="http://js.arcgis.com/3.8/js/dojo/dijit/themes/soria/soria.css"> 
    <link rel="stylesheet" href="http://js.arcgis.com/3.8/js/esri/css/esri.css">
    <style>
    html, body, #mapDiv, .map.container {
      padding:0;
      margin:0;
      height:100%;
    }




    </style>
    
    <script>var dojoConfig = { parseOnLoad:true };</script>
    <script src="http://js.arcgis.com/3.8/"></script>
    <script>
      dojo.require("esri.map");
      dojo.require("esri.layers.FeatureLayer");
      dojo.require("dijit.TooltipDialog");

      var map;

      function init() {
        map = new esri.Map("mapDiv", { 
          basemap: "hybrid",
        });

        var featureLayer = new esri.layers.FeatureLayer("http://####/ArcGIS/rest/services/###/####/MapServer/2",{
          mode: esri.layers.FeatureLayer.MODE_ONDEMAND,
          outFields: ["*"],
          opacity:.50
        });

        featureLayer.on("mouse-over", showTooltip);
        featureLayer.on("mouse-out", closeDialog);

        featureLayer.setDefinitionExpression("OBJECTID ='612485'");
        map.addLayer(featureLayer);
      }

      
      function showTooltip(evt){
        closeDialog();
        var tipContent = "<b>LMID</b>: " + evt.graphic.attributes.LMID +
          "<br><b>Area</b>: " + evt.graphic.attributes.QUANTITY ;
          
        var dialog = new dijit.TooltipDialog({
          id: "tooltipDialog",
          content: tipContent,
          style: "position: absolute; width: 250px; font: normal normal bold 6pt Tahoma;z-index:100"
        });
        dialog.startup();

        dojo.style(dialog.domNode, "opacity", 0.85);
        dijit.placeOnScreen(dialog.domNode, {x: evt.pageX, y: evt.pageY}, ["TL", "BL"], {x: 10, y: 10});
      }

      function closeDialog() {
        var widget = dijit.byId("tooltipDialog");
        if (widget) {
          widget.destroy();
        }
      }


    dojo.ready(init);
  </script>
</head>

<body class="soria">
  <div id="mapDiv"></div>

</body>

</html>
0 Kudos
6 Replies
JohnathanBarclay
Occasional Contributor
The best way to achieve this is by using the Feature Layer's queryFeatures method, then graphicsUtils graphicsExtent method.

As you are using legacy style coding, the following should work for you:

dojo.require("esri.tasks.query");


var query = new esri.tasks.query();
query.where = "OBJECTID ='612485'";
featureLayer.queryFeatures(query, function(result){
  var extent = esri.graphicsExtent(result.features);
  map.setExtent(extent,true);
});
0 Kudos
RowanWinsemius
New Contributor II
Hi Jonathon,

Thanks for your suggestion however I couldn't get it work.

I took the following out of my code
featureLayer.setDefinitionExpression("LOCAL_PROJECT_NAME ='MU7901'");
     map.addLayer(featureLayer);


and replaced it with your code however obviously I haven't put it in the right place...

If you could post the full code so that I can see where Im supposed to be putting it that would be great 🙂

Thanks,
Rowan

PS Really need to book myself in for a javascript course 🙂
0 Kudos
JohnathanBarclay
Occasional Contributor
You shouldn't have taken that bit of code out, try this:

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <!--The viewport meta tag is used to improve the presentation and behavior of the samples 
      on iOS devices-->
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
    <title>Layer in a map service - [ON-DEMAND]</title>

    <link rel="stylesheet" href="http://js.arcgis.com/3.8/js/dojo/dijit/themes/soria/soria.css"> 
    <link rel="stylesheet" href="http://js.arcgis.com/3.8/js/esri/css/esri.css">
    <style>
    html, body, #mapDiv, .map.container {
      padding:0;
      margin:0;
      height:100%;
    }




    </style>
    
    <script>var dojoConfig = { parseOnLoad:true };</script>
    <script src="http://js.arcgis.com/3.8/"></script>
    <script>
      dojo.require("esri.map");
      dojo.require("esri.layers.FeatureLayer");
      dojo.require("dijit.TooltipDialog");
      dojo.require("esri.tasks.query");

      var map;

      function init() {
        map = new esri.Map("mapDiv", { 
          basemap: "hybrid",
        });

        var featureLayer = new esri.layers.FeatureLayer("http://####/ArcGIS/rest/services/###/####/MapServer/2",{
          mode: esri.layers.FeatureLayer.MODE_ONDEMAND,
          outFields: ["*"],
          opacity:.50
        });

        featureLayer.on("mouse-over", showTooltip);
        featureLayer.on("mouse-out", closeDialog);

        featureLayer.setDefinitionExpression("LOCAL_PROJECT_NAME ='MU7901'");
        map.addLayer(featureLayer);

        var query = new esri.tasks.query();
        query.where = "LOCAL_PROJECT_NAME ='MU7901'";
        featureLayer.queryFeatures(query, function(result){
          var extent = esri.graphicsExtent(result.features);
          map.setExtent(extent,true);
        });
      }

      
      function showTooltip(evt){
        closeDialog();
        var tipContent = "<b>LMID</b>: " + evt.graphic.attributes.LMID +
          "<br><b>Area</b>: " + evt.graphic.attributes.QUANTITY ;
          
        var dialog = new dijit.TooltipDialog({
          id: "tooltipDialog",
          content: tipContent,
          style: "position: absolute; width: 250px; font: normal normal bold 6pt Tahoma;z-index:100"
        });
        dialog.startup();

        dojo.style(dialog.domNode, "opacity", 0.85);
        dijit.placeOnScreen(dialog.domNode, {x: evt.pageX, y: evt.pageY}, ["TL", "BL"], {x: 10, y: 10});
      }

      function closeDialog() {
        var widget = dijit.byId("tooltipDialog");
        if (widget) {
          widget.destroy();
        }
      }


    dojo.ready(init);
  </script>
</head>

<body class="soria">
  <div id="mapDiv"></div>

</body>

</html>
0 Kudos
RowanWinsemius
New Contributor II
Still no joy Im afraid. Everything loads including the correct polygon but its still not zooming. Could it be a problem to do with the WKID?  My layer uses the 4283 projection. Thanks for all your help, its been awesome, even if it hasnt quite worked yet!
0 Kudos
JohnathanBarclay
Occasional Contributor
You are correct, the differing spatial reference is the issue (although there was also a typo in my code, should be new esri.tasks.Query() not new esri.tasks.query(), not used legacy for a while!)

You will need to re-project the geometry into WKID: 102100 (the SR of the basemap), which can be done using a geometry service.

I've tested this code and it works for me, although I projected a layer from British National Grid (WKID: 27700). I've highlighted the bits I've changed:

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <!--The viewport meta tag is used to improve the presentation and behavior of the samples 
      on iOS devices-->
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
    <title>Layer in a map service - [ON-DEMAND]</title>

    <link rel="stylesheet" href="http://js.arcgis.com/3.8/js/dojo/dijit/themes/soria/soria.css"> 
    <link rel="stylesheet" href="http://js.arcgis.com/3.8/js/esri/css/esri.css">
    <style>
    html, body, #mapDiv, .map.container {
      padding:0;
      margin:0;
      height:100%;
    }




    </style>
    
    <script>var dojoConfig = { parseOnLoad:true };</script>
    <script src="http://js.arcgis.com/3.8/"></script>
    <script>
      dojo.require("esri.map");
      dojo.require("esri.layers.FeatureLayer");
      dojo.require("dijit.TooltipDialog");
      dojo.require("esri.tasks.query");
      dojo.require("esri.tasks.geometry");
      dojo.require("esri.SpatialReference");
      var map;

      function init() {
        map = new esri.Map("mapDiv", { 
          basemap: "hybrid"
        });

        var featureLayer = new esri.layers.FeatureLayer("http://####/ArcGIS/rest/services/###/####/MapServer/2",{
          mode: esri.layers.FeatureLayer.MODE_ONDEMAND,
          outFields: ["*"],
          opacity:.50
        });

        featureLayer.on("mouse-over", showTooltip);
        featureLayer.on("mouse-out", closeDialog);

        featureLayer.setDefinitionExpression("LOCAL_PROJECT_NAME ='MU7901'");
        map.addLayer(featureLayer);
        var query = new esri.tasks.Query();
        query.where = "LOCAL_PROJECT_NAME ='MU7901'";
        featureLayer.queryFeatures(query, function(result){
          var extent = esri.graphicsExtent(result.features);
          var geoService = new esri.tasks.GeometryService("http://####/ArcGIS/rest/services/###/####/GeometryServer");
          var params = new esri.tasks.ProjectParameters();
          params.geometries = [extent];
          params.outSR = new esri.SpatialReference({wkid:102100});
          params.transformation = 1150;//Check this transformation, I think it's right for you
          params.transformForward = false;
          geoService.project(params, function(projection){
            map.setExtent(projection[0],true);
          });
        });
      }

      function showTooltip(evt){
        closeDialog();
        var tipContent = "<b>LMID</b>: " + evt.graphic.attributes.LMID +
          "<br><b>Area</b>: " + evt.graphic.attributes.QUANTITY ;
          
        var dialog = new dijit.TooltipDialog({
          id: "tooltipDialog",
          content: tipContent,
          style: "position: absolute; width: 250px; font: normal normal bold 6pt Tahoma;z-index:100"
        });
        dialog.startup();

        dojo.style(dialog.domNode, "opacity", 0.85);
        dijit.placeOnScreen(dialog.domNode, {x: evt.pageX, y: evt.pageY}, ["TL", "BL"], {x: 10, y: 10});
      }

      function closeDialog() {
        var widget = dijit.byId("tooltipDialog");
        if (widget) {
          widget.destroy();
        }
      }

    dojo.ready(init);
  </script>
</head>

<body class="soria">
  <div id="mapDiv"></div>

</body>

</html>


You can check this documentation for the transformations.
0 Kudos
RowanWinsemius
New Contributor II
Hi Johnothan,

Thanks for your efforts but its still doesn't seem to work *sigh* The transformation you suggested was indeed correct.

I tried to read through your code and added a few other bits to the dojo.require to see if that made a difference but alas.

I think I'll go back to the drawing board and try to work from scratch with the new code rather than the legacy.

It's a bit frustrating that throughout the samples provided by esri there is old and new stuff, its makes it very hard to learn.

Anyway thanks for all your help, I really appreciate it.

Cheers
Rowan
0 Kudos