Multiple query tasks

5274
20
07-06-2015 06:37 AM
OliviaGill1
New Contributor

Hi, I have carried out a queryTask on a map service that returns a polygon when I input a postcode. Within the same service, there is an additional layer where I want to query a local authority name on. I would like to carry out a querytask on this layer at the same time so that the map returns a polygon relating to the postcode input and also tells me what local authority it is contained within. I will ultimately show the local authority as text in a separate widget. Can anyone help please? Here's my code so far with the second queryTask cancelled out near the middle as I'm not sure where it should go??

var query = new Query();
  query.returnGeometry = true;
  query.outFields = [
  "POSTCODE"
  ];

  on(dom.byId("execute"), "click", execute);

  function execute() {
  query.text = dom.byId("Postcode").value;
  queryTask.execute(query, showResults);
  }
  function showResults(results) {
  var resultItems = [];
  var resultCount = results.features.length;
  for (var i = 0; i < resultCount; i++) {
  var featureAttributes = results.features.attributes;

  var graphic = results.features;
  graphic.setSymbol(symbol);
  map.graphics.add(graphic);

  //var queryTask2 = new QueryTask("http://rest/services/live/SEARCH/MapServer/15");
  //query2 = new.esri.tasks.Query();
  //query2.returnGeometry - false;
  //query2.where = ""
var strNum = 100;
  var newExtent = graphic.geometry.getExtent();
  newExtent.xmin = newExtent.xmin - strNum;
  newExtent.ymin = newExtent.ymin - strNum;
  newExtent.xmax = newExtent.xmax + strNum;
  newExtent.ymax = newExtent.ymax + strNum;
  map.setExtent(newExtent);

  for (var attr in featureAttributes) {
  resultItems.push("<b>" + attr + ":</b> " + featureAttributes[attr] + "<br>");
  }
  resultItems.push("<br>");
  }
  dom.byId("info").innerHTML = resultItems.join("");

  }
  dom.byId("results")

  function addToMap(result) {
  debugger;
  }
 });
Tags (1)
0 Kudos
20 Replies
OliviaGill1
New Contributor

Yes, I have carried out an initial queryTask on the first services layer, here:

var queryTask = new QueryTask("http://rest/services/live/SEARCH/MapServer/2");

This returns a polygon. Within the same service but within another layer I want to use this polygon geometry to carry out another query so that it will return the name of the local authority where that postcode is found..

I hope this make sense??

0 Kudos
Steveway1
New Contributor II

You can do this in the code, your second query at the end of your first showResults function.  But the simpler option is if you have access to the data, then to modify your feature classes to hold that information as an attribute of the polygon, then republish your map service.

That will provide you better performance, and reliability then executing dependant query Tasks.

What ever approach you take, you should ensure that the postcode area (polygon) you are retrieving, is fully contained within the local authority area (polygon) you are querying.

Are you UK based? Just guessing from your terminology this is a possibility - there is a free data product from OS called codepoint that has postcode unit points which could return you a safer results than postcode polygon.

OliviaGill1
New Contributor

I'm using an OS services layer so there is no opportunity for me to amend the features in the layer unfortunately. I really need a layer that includes the postcode and the local authority but unfortunately they are held separately. I will keep plodding on and also have a look at codepoint as you suggest. Thank you.

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Olivia,

  See if this helps:

         function showResults(results) {
            var resultItems = [];
            var inBuffer = [];
            var resultCount = results.features.length;
            for (var i = 0; i < resultCount; i++) {
                inBuffer.push(results.features.geometry);
                var featureAttributes = results.features.attributes;
                var graphic = results.features;
                graphic.setSymbol(symbol);
                map.graphics.add(graphic);
               
                var strNum = 100;
                var newExtent = graphic.geometry.getExtent();
                newExtent.xmin = newExtent.xmin - strNum;
                newExtent.ymin = newExtent.ymin - strNum;
                newExtent.xmax = newExtent.xmax + strNum;
                newExtent.ymax = newExtent.ymax + strNum;
                map.setExtent(newExtent);

                for (var attr in featureAttributes) {
                    resultItems.push("<b>" + attr + ":</b>  " + featureAttributes[attr] + "<br>");
                }
                resultItems.push("<br>");
            }
            var query2 = new Query();
            query2.geometry = geometryEngine.union(inBuffer);
            query2.returnGeometry = false;
            query2.outFields = ["NAME"];
            var queryTask2 = new QueryTask("http://rest/services/live/SEARCH/MapServer/15");
            queryTask2.execute(query2, function(results2){
              for (var j = 0; j < results2.features.length; j++) {
                resultItems.push("<b>Local Authority:</b>  " + results2.features.attributes.NAME + "<br>");
              }
            });
            dom.byId("info").innerHTML = resultItems.join("");
        }
OliviaGill1
New Contributor

Hi Robert

I added the geometryEngine module but I am still not getting back a local authority. I'm wondering if it's something to do with my html now?? The attached code returns the polygon showing the postcode polygon but still no local authority??

0 Kudos
Steveway1
New Contributor II

Hi Olivia,

Robert's code should work.  Can you try this, on the line directly after

dom.byId("info").innerHTML = resultItems.join("");

Add the following line:

console.log(resultItems);

On the line in your query2 execute callback function,before the FOR loop, add:

console.log(results2);

Then, using chrome or IE, press F12, go to console and look through the Object that has been logged.

OliviaGill1
New Contributor

Hi Steve

Thank you for the help. I added the console.log as you suggested and I got this:

Hopefully you can make out the attributes: Object

NAME: Glasgow City' so yes it works. Just need to work out how to get that onto the screen as a widget now! Lots to learn...

Olivia

0 Kudos
Steveway1
New Contributor II

OK I think what is happening, is that the results are being put into the div before the seconds query has finished executing (JS is asynchronous).

Replace your callback function for the query2 execute with this one:

queryTask2.execute(query2, function (results2) {

                 for (var j = 0; j < results2.features.length; j++) {

                     resultItems.push("<b>Local Authority:</b>  " + results2.features.attributes.NAME + "<br>");

                 }

     dom.byId("info").innerHTML = resultItems.join("");

             });

       

Also noticed in the console, there is an exception being thrown, but cannot see what line that is happening.

OliviaGill1
New Contributor

Afraid it doesn't seem to return anything?:

var query2 = new Query();

             query2.geometry = geometryEngine.union(inBuffer);

             query2.returnGeometry = false;

             query2.outFields = ["NAME"];

             var queryTask2 = new QueryTask("http://rest/services/live/SEARCH/MapServer/15");

            

             queryTask2.execute(query2, function (results2) {

                 for (var j = 0; j < results2.features.length; j++) {

                     resultItems.push("<b>Local Authority:</b>  " + results2.features.attributes.NAME + "<br>");

                 }

                 dom.byId("info").innerHTML = resultItems.join("");

                 console.log();

             });

             dom.byId("results")

             function addToMap(result) {

            }

my html:

<body>

   Postcode :

    <input type="text" id="Postcode" value="">

    <input id="execute" type="button" value="Get Details">

    <br />

    <br />

    <div id="info" style="padding:5px; margin:5px; background-color:#eee;">

    </div>

    <table id="mapTable"><tr><td><div id="map"></div></td></tr>

        </table>

     <div id="result" style="padding:5px; margin:5px; background-color:#00ff90;">

    </div>

     

</body>

0 Kudos
Steveway1
New Contributor II

Hi Olivia,

The code I sent you works for me (I am using County and region polygon data in my case).

However, i see from the code you pasted, you have an erraneous console.log() in your query 2 call back function - just remove this.  That should do it.

Also, if you are looking to add the polygon to the map, I recommend adding the graphics to a graphics layer, then adding the graphics layer to the map.  Early in your showResults function you are trying to add graphics directly to the map graphics object - this wont work.

Steve