QueryTask, Query, and FeatureSet are used together to query a layer in a map and display the results.
The input into the process is Query. A user provides input to the query. This input might include selecting features on a map, selecting a value from a list, or typing in a value. The input is used to create a query filter. In the next step of the process, the QueryTask is executed based on the query filter. In the final step of the process, the results are returned in a FeatureSet. These results include the geometry of each feature selected for highlighting the features on the map. It also includes the tablular data for display in an InfoWindow or an HTML table.
The following discussion assumes you are already familiar with the basic concepts of the JavaScript API and Dojo, and you understand the basic patterns of how the JavaScript API works within an HTML page. For more information, see Adding a map and Adding a task.
// AMD require([ "esri/map", "esri/layers/ArcGISDynamicMapServiceLayer", "esri/tasks/QueryTask", "esri/tasks/query", "esri/symbols/SimpleMarkerSymbol", "esri/InfoTemplate", "dojo/_base/Color", "dojo/dom", "dojo/on", "dojo/domReady!" ], function(Map, ArcGISDynamicMapServiceLayer, QueryTask, Query, SimpleMarkerSymbol, InfoTemplate, Color, dom, on) { //create map and add layer map = new Map("mapDiv"); var layer = new ArcGISDynamicMapServiceLayer( "http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Specialty/ESRI_StatesCitiesRivers_USA/MapServer"); map.addLayer(layer); //initialize query task queryTask = new QueryTask("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Specialty/ESRI_StatesCitiesRivers_USA/MapServer/0"); //initialize query query = new Query(); query.returnGeometry = true; query.outFields = ["CITY_NAME", "STATE_NAME", "POP1990"]; //initialize InfoTemplate infoTemplate = new InfoTemplate("${CITY_NAME}", "Name : ${CITY_NAME}<br/> State : ${STATE_NAME}<br />Population : ${POP1990}"); //create symbol for selected features symbol = new SimpleMarkerSymbol(); symbol.setStyle(SimpleMarkerSymbol.STYLE_SQUARE); symbol.setSize(10); symbol.setColor(new Color([255,255,0,0.5])); //write "Get Details" button's click event on(dom.byId("runQuery"), "click", executeQueryTask); });
The callback function is the function referenced from the input in the HTML page. In this example, a function named "executeQueryTask" is called after a user types in a population value and clicks the "Get Details" button.
The "population" value is plugged into Query.where. The where attribute is one of three filters you can use with Query:
query.where = "NAME = '" + stateName + "'";
query.where = "POP1990 > " + population;
query.text = stateName;
query.geometry = evt.mapPoint;
function executeQueryTask() { //set query based on what user typed in for population; query.where = "POP1990 > " + dom.byId("population").value; //execute query queryTask.execute(query,showResults); }
function showResults(featureSet) { //remove all graphics on the maps graphics layer map.graphics.clear(); //Performance enhancer - assign featureSet array to a single variable. var resultFeatures = featureSet.features; //Loop through each feature returned for (var i=0, il=resultFeatures.length; i<il; i++) { //Get the current feature from the featureSet. //Feature is a graphic var graphic = resultFeatures[i]; graphic.setSymbol(symbol); //Set the infoTemplate. graphic.setInfoTemplate(infoTemplate); //Add graphic to the map graphics layer. map.graphics.add(graphic); } }
body
The body
section contains what the user sees on the HTML page.
<body> <br/> US city population greater than : <input type="text" id="population" value="500000" /> <input type="button" value="Get Details" id="runQuery" /> <div id="mapDiv" style="width:600px; height:600px; border:1px solid #000;"></div> Click on a city once it's highlighted to get an InfoWindow. </body>
You need to be careful that the query you are constructing is reasonable. Your audience will not understand the data as well as you. As a result, users may make queries that are unrealistic or request too much data. There is a direct correlation between performance and the number of features selected.
Queries on cached layers do not have scale dependencies. This means that features for a layer can be queried even if the layer is not displayed on the map for a given scale. Thus, your query should not be accessible for a layer if displaying the results does not make sense to the end user.
You should also consider that users can inadvertently or maliciously request unlimited numbers of features. The maximum number of features returned can be specified in the properties for each map service. By default, this maximum is set to 1000 features. Some common ways a user can request the maximum number of records for a layer are:
You can trap for these types of queries in your application. If you are hosting services that other users may include in their application, you may want to protect your site from multiple large requests by limiting the number of features that can be returned in a query response by setting a reasonable value in MaxRecordCount.