Hide Table of Contents
View Select graphic points within an extent sample in sandbox
Select graphic points within an extent

Description

This sample demonstrates how to use graphics to display query results, how to use a draw toolbar to select graphics on the map, and how to change graphic symbology to "highlight" certain graphics.

Draw a rectangle on the map to highlight cities within the rectangle's extent. The application sums the count of highlighted cities and lists the city names. You can draw another rectangle to change the set of highlighted cities.

The initial set of cities you see on the map is the result of a query that occurs when the application loads. The query finds all cities in the state of Washington from the Cities layer of the ESRI_StatesCitiesRivers_USA map service. The cities are then added to the map's GraphicsLayer.

A draw toolbar helps you draw the rectangle on the map. The toolbar is not a user interface component; it's just a helper class that saves you the work of coding the JavaScript for displaying the rectangle and capturing the extent. Typically you create the toolbar, activate a certain type of drawing, then provide an event listener to do something when the drawing is complete. In this sample, all of this is accomplished in the initToolbar function:

function initToolbar(map) {
var tb = new esri.toolbars.Draw(map);
dojo
.connect(tb, "onDrawEnd", findPointsInExtent);
tb
.activate(esri.toolbars.Draw.EXTENT);
}

The callback function findPointsInExtent is called when you finish drawing the rectangle. This function loops through every city graphic in the map and determines whether it falls within the extent returned from the draw toolbar. If it does, the code changes the city's graphic to the highlight symbol and adds the city's information to a results array. This array is used to create the list of city names that you see below the map.

Note the use of HTML in the InfoTemplate to put each result in a table row. The results.join() method concatenates all the elements in the results array into a string. The string can then be placed inside <table> tags to create a table.

Code

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
    <title>Points in Extent</title>

    <link rel="stylesheet" href="https://js.arcgis.com/3.22/dijit/themes/claro/claro.css">
    <link rel="stylesheet" href="https://js.arcgis.com/3.22/esri/css/esri.css">

    <script src="https://js.arcgis.com/3.22/"></script>
    <script>
      dojo.require("esri.map");
      dojo.require("esri.toolbars.draw");
      dojo.require("esri.tasks.query");

      //global variables
      var map, defaultSymbol, highlightSymbol, resultTemplate;

      function init() {
        //create map, set initial extent and disable default info window behavior
        map = new esri.Map("map", {
          basemap: "streets",
          center: [-120.275, 47.485],
          zoom: 6,
          slider: false,
          showInfoWindowOnClick:false
        });
        dojo.connect(map, "onLoad", initToolbar);

        //initialize symbology
        defaultSymbol = new esri.symbol.SimpleMarkerSymbol().setColor(new dojo.Color([0,0,255]));
        highlightSymbol = new esri.symbol.SimpleMarkerSymbol().setColor(new dojo.Color([255,0,0]));

        //initialize & execute query
        var queryTask = new esri.tasks.QueryTask("https://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Specialty/ESRI_StatesCitiesRivers_USA/MapServer/0");
        var query = new esri.tasks.Query();
        query.where = "STATE_NAME = 'Washington'";
        query.outSpatialReference = {wkid:102100}; 
        query.returnGeometry = true;
        query.outFields = ["CITY_NAME"];
        queryTask.execute(query, addPointsToMap);

        //info template for points returned
        resultTemplate = new esri.InfoTemplate("City", "<tr><td>${CITY_NAME}</tr></td>");
      }

      //initialize drawing toolbar
      function initToolbar(map) {
        var tb = new esri.toolbars.Draw(map);

        //find points in Extent when user completes drawing extent
        dojo.connect(tb, "onDrawEnd", findPointsInExtent);

        //set drawing mode to extent
        tb.activate(esri.toolbars.Draw.EXTENT);
      }

      //add points to map and set their symbology + info template
      function addPointsToMap(featureSet) {
        dojo.forEach(featureSet.features,function(feature){
          map.graphics.add(feature.setSymbol(defaultSymbol).setInfoTemplate(resultTemplate));
        });
      }

      //find all points within argument extent
      function findPointsInExtent(extent) {
        var results = [];
        dojo.forEach(map.graphics.graphics,function(graphic){
          if (extent.contains(graphic.geometry)) {
            graphic.setSymbol(highlightSymbol);
            results.push(graphic.getContent());
          }
          //else if point was previously highlighted, reset its symbology
          else if (graphic.symbol == highlightSymbol) {
            graphic.setSymbol(defaultSymbol);
          }
        });
   
        //display number of points in extent
        dojo.byId("inextent").innerHTML = results.length;

        //display list of points in extent
        dojo.byId("results").innerHTML = "<table><tbody>" + results.join("") + "</tbody></table>";
      }

      dojo.addOnLoad(init);
    </script>

  </head>
  <body class="claro">
    Draw an Extent on the map to find all points within this extent

    
    <div id="map" style="width:800px; height:400px; border:1px solid #000;"></div>
    <br />

    
    <b># of points in extent = <span id="inextent">0</span></b>

    
    <div id="results" style="width:400px; height:200px; border:1px solid #000; overflow:auto;">
    </div>
  </body>
</html>