Zoom to Selected Features

5309
10
Jump to solution
09-04-2014 08:17 AM
HabG_
by
Occasional Contributor

Hi

I have used the JavaScript code below and works well. What it does is, using the 'Select Fields' button I can draw a polygon to select features, and clear the selected features by clicking the 'Clear Selection' button. What I want now is to zoom to the selected features by clicking on the 'Zoom to Selected Features' (this is not in the code). Can anyone help me please with the write code?

map.on("load", initSelectToolbar);

var fieldsSelectionSymbol = new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID,

new SimpleLineSymbol(SimpleLineSymbol.STYLE_DASHDOT,

new Color([255, 0, 0]), 2), new Color([255, 255, 0, 0.5]));

var content = "<b>ID No: <a target='_blank' href=${xxxx}>${IDNo}</a></b><br/><b>Sv Type: ${Sv_type}</b>";

var infoTemplate = new InfoTemplate("HSB", content);

featureLayer = new FeatureLayer("http://localhost:6080/arcgis/rest/services/webmapping/newboundary/xxxxxx", {

    mode: FeatureLayer.MODE_ONDEMAND,

    infoTemplate: infoTemplate,

    outFields: ["*"]

});

featureLayer.setSelectionSymbol(fieldsSelectionSymbol);

featureLayer.on("selection-clear", function () {

});

map.addLayer(featureLayer);

on(dom.byId("selectFieldsButton"), "click", function () {

    selectionToolbar.activate(Draw.EXTENT);

});

on(dom.byId("clearSelectionButton"), "click", function () {

    featureLayer.clearSelection();

});

function initSelectToolbar(event) {

    selectionToolbar = new Draw(event.map);

    var selectQuery = new Query();

    on(selectionToolbar, "DrawEnd", function (geometry) {

        selectionToolbar.deactivate();

        selectQuery.geometry = geometry;

        featureLayer.selectFeatures(selectQuery,

        FeatureLayer.SELECTION_NEW);

    });

}

1 Solution

Accepted Solutions
KenBuja
MVP Honored Contributor

This code works. Note that you had left off the "Button" argument in the require function.

<!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.10/js/dojo/dijit/themes/claro/claro.css">

    <link rel="stylesheet" href="http://js.arcgis.com/3.10/js/esri/css/esri.css" />

    <style>

        html, body, #map {

            padding: 0;

            margin: 0;

            height: 100%;

        }

    </style>

    <script src="http://js.arcgis.com/3.10/"></script>

    <script>

        var map;

        require([

          "esri/InfoTemplate",

          "esri/map",

          "esri/dijit/Scalebar",

          "esri/dijit/BasemapGallery",

          "esri/layers/FeatureLayer",

          "esri/symbols/SimpleFillSymbol",

          "esri/symbols/SimpleLineSymbol",

          "esri/tasks/query",

          "esri/toolbars/draw",

          "dojo/dom",

          "dojo/on",

          "dojo/parser",

          "dojo/_base/array",

          "esri/Color",

          "dijit/form/Button",

          "esri/geometry/Extent",

          "esri/graphicsUtils",

          "dojo/domReady!"

        ],

          function (

            InfoTemplate, Map, Scalebar, BasemapGallery, FeatureLayer, SimpleFillSymbol, SimpleLineSymbol,

            Query, Draw, dom, on, parser, arrayUtil, Color, Button, Extent, graphicsUtils

          ) {

              parser.parse();

              var selectionToolbar, featureLayer;

              map = new Map("map", {

                  basemap: "topo",

                  center: [-97.33, 37.68], // longitude, latitude

                  zoom: 10,

                  sliderStyle: "medium"

              });

              var scalebar = new Scalebar({

                  map: map,

                  scalebarUnit: "dual",

                  attachTo: "bottom-left"

              });

              var basemapGallery = new BasemapGallery({

                  showArcGISBasemaps: true,

                  map: map

              }, "basemapGallery");

              basemapGallery.startup();

              basemapGallery.on("error", function (msg) {

                  console.log("basemap gallery error:  ", msg);

              });

              map.on("load", initSelectToolbar);

              var fieldsSelectionSymbol =

                new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID,

                  new SimpleLineSymbol(SimpleLineSymbol.STYLE_DASHDOT,

                new Color([255, 0, 0]), 2), new Color([255, 255, 0, 0.5]));

              var content = "<b>Status</b>: ${STATUS}" +

                            "<br><b>Cummulative Gas</b>: ${CUMM_GAS} MCF" +

                            "<br><b>Total Acres</b>: ${APPROXACRE}" +

                            "<br><b>Avg. Field Depth</b>: ${AVG_DEPTH} meters";

              var infoTemplate = new esri.InfoTemplate("${FIELD_NAME}", content);

              featureLayer = new FeatureLayer("http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/Petroleum/KSPetro/MapServer/1",

                {

                    mode: FeatureLayer.MODE_ONDEMAND,

                    infoTemplate: infoTemplate,

                    outFields: ["*"]

                });

              featureLayer.setSelectionSymbol(fieldsSelectionSymbol);

              featureLayer.on("selection-clear", function () {

              });

              map.addLayer(featureLayer);

              on(dom.byId("selectFieldsButton"), "click", function () {

                  selectionToolbar.activate(Draw.EXTENT);

              });

              on(dom.byId("clearSelectionButton"), "click", function () {

                  featureLayer.clearSelection();

              });

              function initSelectToolbar(event) {

                  selectionToolbar = new Draw(event.map);

                  var selectQuery = new Query();

                  on(selectionToolbar, "DrawEnd", function (geometry) {

                      selectionToolbar.deactivate();

                      selectQuery.geometry = geometry;

                      featureLayer.selectFeatures(selectQuery,

                        FeatureLayer.SELECTION_NEW, function () {

                            map.setExtent(graphicsUtils.graphicsExtent(featureLayer.getSelectedFeatures()), true);

                        });

                  });

              }

          });

    </script>

</head>

<body class="claro">

    <button id="selectFieldsButton" data-dojo-type="dijit/form/Button">Select Fields</button>

    <button id="clearSelectionButton" data-dojo-type="dijit/form/Button">Clear Selection</button>

    <button id="ZoomToSelectionButton" data-dojo-type="dijit/form/Button">Zoom to Selected Features</button><br>

    <div id="map" data-dojo-type="dijit/layout/ContentPane"

         data-dojo-props="region:'center'"

         style="padding:0;">

        <div style="position:absolute; right:20px; top:10px; z-Index:999;">

            <div data-dojo-type="dijit/TitlePane"

                 data-dojo-props="title:'Switch Basemap', closable:false, open:false">

                <div data-dojo-type="dijit/layout/ContentPane" style="width:380px; height:280px; overflow:auto;">

                    <div id="basemapGallery"></div>

                </div>

            </div>

        </div>

    </div>

</body>

</html>

View solution in original post

10 Replies
TimWitt2
MVP Regular Contributor

It would be something like this:

Create a button called ZoomToButton

  1. on(dom.byId("ZoomToButton"), "click", function () { 
  2.    var SelecFeatures = featureLayer.getSelectedFeatures();
  3.    var SelecExtent = SelecFeatures.geometry.getExtent();
  4.    map.setExtent(SelecExtent);
  5. }); 
KenBuja
MVP Honored Contributor

You could also use the graphicUtils class to put this into a single line

map.setExtent(graphicsUtils.graphicsExtent(featureLayer.getSelectedFeatures()), true);

DavidChrest
Occasional Contributor II

Thanks Ken, for this handy tip. Was just looking for this. Gotta love a one-line-of-code solution.

0 Kudos
HabG_
by
Occasional Contributor

Thanks Tim

I tried your code, however, I couldn't be able to zoom to the selected features. Do I need to put all 5 lines of codes together or in different places?

0 Kudos
williamcarr
Occasional Contributor II

Hab,

Dumb question, did you include "esri/geometry/Extent" ?

0 Kudos
ScottRutzmoser2
New Contributor III

I have had trouble with this as well, It seems like things should work but for some reason they don't.

In our case I created a little sub to build the extent from an array of graphics.

function getGraphicsExtent(graphics) {

    var geometry, extent, ext;

    dojo.forEach(graphics, function(graphic, i) {

        geometry = graphic.geometry;

        if (geometry instanceof esri.geometry.Point) {

            ext = new esri.geometry.Extent(geometry.x - 1, geometry.y - 1,

                    geometry.x + 1, geometry.y + 1, geometry.spatialReference);

        } else if (geometry instanceof esri.geometry.Extent) {

            ext = geometry;

        } else {

            ext = geometry.getExtent();

        }

        if (extent) {

            extent = extent.union(ext);

        } else {

            extent = new esri.geometry.Extent(ext);

        }

    });

    return extent;

}

Then you should be able to set the extent of the map using something like.

map.setExtent(getGraphicsExtent(featureLayer.getSelectedFeatures).expand(200));

BetsySchenck-Gardner
Occasional Contributor

I don't mean to sound stupid but are you returning more than 1 feature. If your polygon selection only returns one feature then I don't believe you can get an extent on a single point. In that case you would have to return the geometry of the point and could then use map.centerAndZoom otherwise Ken's suggestion of getting the graphicsExtent should work.

0 Kudos
HabG_
by
Occasional Contributor

Thanks everyone for your help. I tried to apply your suggestions, however, I couldn't solve it (I'm sure this is due to my lack of JavaScript knowledge). I changed my FeatureLayer source to that of Petroleum service from ArcGIS.com and posted the complete code below. Please place the working code (to zoom to the selected extent) in the right place.

Thanks

<!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.10/js/dojo/dijit/themes/claro/claro.css">

  <link rel="stylesheet" href="http://js.arcgis.com/3.10/js/esri/css/esri.css" />

  <style>

      html, body, #map {

        padding:0;

        margin:0;

        height:100%;

      }

   </style>

    <script src="http://js.arcgis.com/3.10/"></script>

  <script>

    var map;

    require([

      "esri/InfoTemplate",

      "esri/map",

   "esri/dijit/Scalebar",

   "esri/dijit/BasemapGallery",

      "esri/layers/FeatureLayer",

      "esri/symbols/SimpleFillSymbol",

      "esri/symbols/SimpleLineSymbol",

      "esri/tasks/query",

      "esri/toolbars/draw",

      "dojo/dom",

      "dojo/on",

      "dojo/parser",

      "dojo/_base/array",

      "esri/Color",

      "dijit/form/Button",

   "esri/geometry/Extent",

      "dojo/domReady!"

    ],

      function (

        InfoTemplate, Map, Scalebar, BasemapGallery, FeatureLayer, SimpleFillSymbol, SimpleLineSymbol,

        Query, Draw, dom, on, parser, arrayUtil, Color, Extent

      ) {

        parser.parse();

        var selectionToolbar, featureLayer;

        map = new Map("map", {

          basemap: "topo",

          center: [-97.33, 37.68], // longitude, latitude

          zoom: 10,

          sliderStyle: "medium"

        });

  var scalebar = new Scalebar({

  map: map,

  scalebarUnit: "dual",

  attachTo: "bottom-left"

  });

  var basemapGallery = new BasemapGallery({

  showArcGISBasemaps: true,

  map: map

   }, "basemapGallery");

   basemapGallery.startup();

  

   basemapGallery.on("error", function(msg) {

  console.log("basemap gallery error:  ", msg);

  });

        map.on("load", initSelectToolbar);

        var fieldsSelectionSymbol =

          new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID,

            new SimpleLineSymbol(SimpleLineSymbol.STYLE_DASHDOT,

          new Color([255, 0, 0]), 2), new Color([255, 255, 0, 0.5]));

        var content = "<b>Status</b>: ${STATUS}" +

                      "<br><b>Cummulative Gas</b>: ${CUMM_GAS} MCF" +

                      "<br><b>Total Acres</b>: ${APPROXACRE}" +

                      "<br><b>Avg. Field Depth</b>: ${AVG_DEPTH} meters";

        var infoTemplate = new esri.InfoTemplate("${FIELD_NAME}", content);

        featureLayer = new FeatureLayer("http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/Petroleum/KSPetro/MapServer/1",

          {

            mode: FeatureLayer.MODE_ONDEMAND,

            infoTemplate: infoTemplate,

            outFields: ["*"]

          });

       

        featureLayer.setSelectionSymbol(fieldsSelectionSymbol);       

        featureLayer.on("selection-clear", function () {

        

        });

        map.addLayer(featureLayer);

        on(dom.byId("selectFieldsButton"), "click", function () {

          selectionToolbar.activate(Draw.EXTENT);

        });

       

  on(dom.byId("clearSelectionButton"), "click", function () {

          featureLayer.clearSelection();

        });

        function initSelectToolbar (event) {

          selectionToolbar = new Draw(event.map);

          var selectQuery = new Query();

          on(selectionToolbar, "DrawEnd", function (geometry) {

            selectionToolbar.deactivate();

            selectQuery.geometry = geometry;

            featureLayer.selectFeatures(selectQuery,

              FeatureLayer.SELECTION_NEW); 

          });

        }

  });

  </script>

</head>

<body class="claro">

  <button id="selectFieldsButton" data-dojo-type="dijit/form/Button">Select Fields</button>

  <button id="clearSelectionButton" data-dojo-type="dijit/form/Button">Clear Selection</button>

  <button id="ZoomToSelectionButton" data-dojo-type="dijit/form/Button">Zoom to Selected Features</button><br>

  <div id="map"data-dojo-type="dijit/layout/ContentPane"

         data-dojo-props="region:'center'"

         style="padding:0;">

  <div style="position:absolute; right:20px; top:10px; z-Index:999;">

        <div data-dojo-type="dijit/TitlePane"

             data-dojo-props="title:'Switch Basemap', closable:false, open:false">

          <div data-dojo-type="dijit/layout/ContentPane" style="width:380px; height:280px; overflow:auto;">

            <div id="basemapGallery"></div>

        </div>

      </div>

  </div>

  </div>

</body>

</html>

0 Kudos
KenBuja
MVP Honored Contributor

This code works. Note that you had left off the "Button" argument in the require function.

<!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.10/js/dojo/dijit/themes/claro/claro.css">

    <link rel="stylesheet" href="http://js.arcgis.com/3.10/js/esri/css/esri.css" />

    <style>

        html, body, #map {

            padding: 0;

            margin: 0;

            height: 100%;

        }

    </style>

    <script src="http://js.arcgis.com/3.10/"></script>

    <script>

        var map;

        require([

          "esri/InfoTemplate",

          "esri/map",

          "esri/dijit/Scalebar",

          "esri/dijit/BasemapGallery",

          "esri/layers/FeatureLayer",

          "esri/symbols/SimpleFillSymbol",

          "esri/symbols/SimpleLineSymbol",

          "esri/tasks/query",

          "esri/toolbars/draw",

          "dojo/dom",

          "dojo/on",

          "dojo/parser",

          "dojo/_base/array",

          "esri/Color",

          "dijit/form/Button",

          "esri/geometry/Extent",

          "esri/graphicsUtils",

          "dojo/domReady!"

        ],

          function (

            InfoTemplate, Map, Scalebar, BasemapGallery, FeatureLayer, SimpleFillSymbol, SimpleLineSymbol,

            Query, Draw, dom, on, parser, arrayUtil, Color, Button, Extent, graphicsUtils

          ) {

              parser.parse();

              var selectionToolbar, featureLayer;

              map = new Map("map", {

                  basemap: "topo",

                  center: [-97.33, 37.68], // longitude, latitude

                  zoom: 10,

                  sliderStyle: "medium"

              });

              var scalebar = new Scalebar({

                  map: map,

                  scalebarUnit: "dual",

                  attachTo: "bottom-left"

              });

              var basemapGallery = new BasemapGallery({

                  showArcGISBasemaps: true,

                  map: map

              }, "basemapGallery");

              basemapGallery.startup();

              basemapGallery.on("error", function (msg) {

                  console.log("basemap gallery error:  ", msg);

              });

              map.on("load", initSelectToolbar);

              var fieldsSelectionSymbol =

                new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID,

                  new SimpleLineSymbol(SimpleLineSymbol.STYLE_DASHDOT,

                new Color([255, 0, 0]), 2), new Color([255, 255, 0, 0.5]));

              var content = "<b>Status</b>: ${STATUS}" +

                            "<br><b>Cummulative Gas</b>: ${CUMM_GAS} MCF" +

                            "<br><b>Total Acres</b>: ${APPROXACRE}" +

                            "<br><b>Avg. Field Depth</b>: ${AVG_DEPTH} meters";

              var infoTemplate = new esri.InfoTemplate("${FIELD_NAME}", content);

              featureLayer = new FeatureLayer("http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/Petroleum/KSPetro/MapServer/1",

                {

                    mode: FeatureLayer.MODE_ONDEMAND,

                    infoTemplate: infoTemplate,

                    outFields: ["*"]

                });

              featureLayer.setSelectionSymbol(fieldsSelectionSymbol);

              featureLayer.on("selection-clear", function () {

              });

              map.addLayer(featureLayer);

              on(dom.byId("selectFieldsButton"), "click", function () {

                  selectionToolbar.activate(Draw.EXTENT);

              });

              on(dom.byId("clearSelectionButton"), "click", function () {

                  featureLayer.clearSelection();

              });

              function initSelectToolbar(event) {

                  selectionToolbar = new Draw(event.map);

                  var selectQuery = new Query();

                  on(selectionToolbar, "DrawEnd", function (geometry) {

                      selectionToolbar.deactivate();

                      selectQuery.geometry = geometry;

                      featureLayer.selectFeatures(selectQuery,

                        FeatureLayer.SELECTION_NEW, function () {

                            map.setExtent(graphicsUtils.graphicsExtent(featureLayer.getSelectedFeatures()), true);

                        });

                  });

              }

          });

    </script>

</head>

<body class="claro">

    <button id="selectFieldsButton" data-dojo-type="dijit/form/Button">Select Fields</button>

    <button id="clearSelectionButton" data-dojo-type="dijit/form/Button">Clear Selection</button>

    <button id="ZoomToSelectionButton" data-dojo-type="dijit/form/Button">Zoom to Selected Features</button><br>

    <div id="map" data-dojo-type="dijit/layout/ContentPane"

         data-dojo-props="region:'center'"

         style="padding:0;">

        <div style="position:absolute; right:20px; top:10px; z-Index:999;">

            <div data-dojo-type="dijit/TitlePane"

                 data-dojo-props="title:'Switch Basemap', closable:false, open:false">

                <div data-dojo-type="dijit/layout/ContentPane" style="width:380px; height:280px; overflow:auto;">

                    <div id="basemapGallery"></div>

                </div>

            </div>

        </div>

    </div>

</body>

</html>

View solution in original post