Query Points contained within multipl polygons

725
5
Jump to solution
07-18-2013 10:43 AM
BrianLord1
Occasional Contributor
Hi,

I am trying to query all the points located within multiple polygons.  I have used the querytask many times to find features contained within a single polygon, but am having troubles accomplishing this with multiple polygons.

Basically, my app selects specific sites (points) and then applies a buffer around them.  From there I need to find all the addresses (points) located within all the buffer polygons (the number of buffer polygons varies based on the original search results).

The buffers are added to a graphics layer when drawn and then cleared out anytime there is a new search.

Can I query against the geometries of all the graphics in the buffer layer at once or do I need to loop through them running a seperate query each time and somehow combine all the results?

Thanks in advance for any help you can provide.

Thanks,
Mark
0 Kudos
1 Solution

Accepted Solutions
DianaBenedict
Occasional Contributor III
I agree with using the defferedList to query the results at one time ... however have you also considered using the different bufferParameters indicated here:
https://developers.arcgis.com/en/javascript/jsapi/bufferparameters.html

Looks like you have the option to
1) pass in multiple geometries
2) Union the results

If you union the results then you will only need to process the pass in the union geometry to the query and run it once. Just an alternate suggestion.

Diana

View solution in original post

0 Kudos
5 Replies
ChristopherBlinn1
Occasional Contributor III
I had a similar task for an application I built some time ago.  I used a different approach than queryTask however.

I first thought looping through each polygon, appending results to array would be the best way to go.  Until I tested and it took 45 seconds to get results.

I'm not sure if that works for you, and if so I can provide an example of what I tried, but for me that was not going to work.

Instead, I decided to deconstruct the actual intersect query that was needed to get all points contained in my buffered polygons.  Simply put, created a geometry string of all of the buffered polygon rings.  Most likely you are getting your buffers from a geometry service return.  The return from the geometry service are geometries, which you can simply view and convert into a string.  To work with the next step, you need the string to start with, "  [{"rings":  ".

I then added that string to a query URL for my point layer (I also had a whereClause, but you can simply make that 'OBJECTID > 0' or something similar to get all features).  With the dynamic URL, I used AJAX to GET the point data within the geometry I specified:

"http://www.myservice.com/ArcGIS/rest/services/Folder/Service/MapServer/LayerID/query?&geometry=" + geometryString + "&geometryType=esriGeometryPolygon&spatialRel=esriSpatialRelIntersects&where=" + whereClause + "&returnCountOnly=false&returnIdsOnly=false&returnGeometry=true&outFields=*&f=pjson"


This was the best way for me to get the results I was looking for.  Hope it provides you some direction and helps you get where you need to be.

All the best,
Chris B.
0 Kudos
BrianLord1
Occasional Contributor
Could you add some more code, specifically the part where you convert the geometries returned from the geometry service to a string?  I have not done that before and am having some issues implementing it.
0 Kudos
AdamSkoog
New Contributor III
Seems to me a dojo.DeferredList would help you out a lot.
dojo.require("dojo.DeferredList");


First build your deferred list of query tasks. The deferred list will return when all the deferreds have been completed and give you your results in an array. Hope this gets you on your way.
var defers = [];
dojo.forEach(arrayOfBufferedGeoms, function (bufferedGeom) {
    var query = new esri.tasks.Query();
    query.geometry = bufferedGeom;
    query.outSpatialReference = map.spatialReference;

    var queryTask = new esri.tasks.QueryTask(somelayerUrl);
    defers.push(queryTask.execute(query));
}));

var dl = new dojo.DeferredList(defers);

dojo.when(dl, function (results) {
    dojo.forEach(results, function(result) {
        //process your returned items.
    });
});
0 Kudos
DianaBenedict
Occasional Contributor III
I agree with using the defferedList to query the results at one time ... however have you also considered using the different bufferParameters indicated here:
https://developers.arcgis.com/en/javascript/jsapi/bufferparameters.html

Looks like you have the option to
1) pass in multiple geometries
2) Union the results

If you union the results then you will only need to process the pass in the union geometry to the query and run it once. Just an alternate suggestion.

Diana
0 Kudos
BrianLord1
Occasional Contributor
thanks Diana, that was exactly what I was looking for.  Thank you to everyone who helped!

Here is my code in case it can help someone else down the road...
function DoBuffer(bufferDistance) {
                //Selects the buffer unit based on user input
                var bufferUnit = selectbufferUnit.value;

                switch (bufferUnit) {
                    case 'Feet':
                        bufferUnit = [esri.tasks.GeometryService.UNIT_FOOT];
                        break;
                    case 'Miles':
                        bufferUnit = [esri.tasks.GeometryService.UNIT_STATUTE_MILE];
                        break;
                    case 'Meters':
                        bufferUnit = [esri.tasks.GeometryService.UNIT_METER];
                        break;
                    case 'Kilometers':
                        bufferUnit = [esri.tasks.GeometryService.UNIT_KILOMETER];
                        break;
                }

                var params = new esri.tasks.BufferParameters();

                //Sets the buffer distance based on user input
                params.distances = [bufferDistance];
                params.unit = [bufferUnit];
                params.bufferSpatialReference = map.spatialReference;
                params.outSpatialReference = map.spatialReference;

                //Gets the geometries for all the selected sites
                params.geometries = esri.getGeometries(map.graphics.graphics);

                //This parameter unions all the generated buffer polygons into a single multipart polygon
                params.unionResults = true;

                geometryService.buffer(params, ShowBuffer);
                features = [];
            }

            //function for Displaying the buffer
            function ShowBuffer(geometries) {
                
                //Creates the symbol for the buffer
                var lineColor = new dojo.Color();
                lineColor.setColor(rendererColor);
                var fillColor = new dojo.Color();
                fillColor.setColor(rendererColor);
                fillColor.a = 0.15;
                var symbol = new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_SOLID,
                        new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID,
                        lineColor, 2),
                        fillColor);
                
                var bufferLayer = map.getLayer(tempBufferLayer);

                //Adds the buffers to a graphics layer
                AddGraphic2(map.getLayer(tempBufferLayer), symbol, geometries[0]);

                //Sets the extent of the map so that the buffers are visible
                var bufferPolygon = bufferLayer.graphics[0];
                var bufferExtent = bufferPolygon.geometry.getExtent();
                var finalExtent2 = bufferExtent.expand(1.5);
                map.setExtent(finalExtent2);

                //Queries the address point layer for any points contained within the buffers
                var qTask = 'qTask';
                qTask = new esri.tasks.QueryTask("http://servername/arcgis/rest/services/foldername/servicename/MapServer/1");
                var query = new esri.tasks.Query();
                query.where = "1=1";
                query.geometry = geometries[0];
                query.outFields = ["*"];
                query.spatialRelationship = esri.tasks.Query.SPATIAL_REL_CONTAINS;
                query.returnGeometry = true;
                
                //All addresses returned from the query are shown on the map and also shown in a datagrid.
                qTask.execute(query, function (featureset) {
                    var addressGraphics = featureset.features;

                    //Creates the symbol for all the addresses returned from the query
                    var symbolAddress = new esri.symbol.SimpleMarkerSymbol(
                                            esri.symbol.SimpleMarkerSymbol.STYLE_CIRCLE, 12,
                                            new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_NULL,
                                            new dojo.Color([247, 34, 101, 0.9]), 1),
                                            new dojo.Color([207, 34, 171, 0.5])
                                        );
                    
                    //Creates the attributes for the addresses that will be added to a graphics layer
                    var attributes;
                    var a;
                    for (a = 0; a < addressGraphics.length; a++) {
                        attributes = { "OBJECTID": addressGraphics.attributes["OBJECTID"], "PIN": addressGraphics.attributes["PIN"], "BUSINESSNAME": addressGraphics.attributes["BUSINESSNAME"], "OWNAME": addressGraphics.attributes["OWNAME"], "PHYADDR1": addressGraphics.attributes["PHYADDR1"] };

                        //Adds the addresses to a graphics layer using t....geometry, attributes);
                    }

                    var results = map.getLayer(select...


thanks again.
Mark
0 Kudos