How to count features in a polygon

4347
12
Jump to solution
03-24-2014 11:24 PM
ChristianDebono
New Contributor II
I have published two layers. One containing points and the other containing polygons.

I would like to count the number of points belonging to a polygon when the user clicks it using ArcGIS Javascript API. I have already done the functionality of highlighting the polygon when the user clicks it. Now I want that an alert message will show up with the number of features in that polygon when the polygon is clicked. I already tried to do some code but its not giving the correct answer.

function selectByCouncil() {                 var localCouncils = new FeatureLayer("feature layer with polygons", {                     mode: FeatureLayer.MODE_SNAPSHOT,                     outFields: ["*"]                 });                  map.addLayer(localCouncils);                  var highlightSymbol = new SimpleFillSymbol(                   SimpleFillSymbol.STYLE_SOLID,                   new SimpleLineSymbol(                     SimpleLineSymbol.STYLE_SOLID,                     new Color([255, 0, 0]), 1),                   new Color([125, 125, 125, 0.35])                 );                  map.on("load", function () {                     map.graphics.enableMouseEvents();                 });                  localCouncils.on("click", function (evt) {                     map.graphics.clear();                     var highlightGraphic = new Graphic(evt.graphic.geometry, highlightSymbol);                     map.graphics.add(highlightGraphic);                      var query = new Query();                     var queryTask = new QueryTask(feature layer with points);                     query.geometry = evt.graphic.geometry;                     query.returnGeometry = true;                      var countOfFeatures = 0;                      queryTask.execute(query, function (results) {                         dojo.forEach(results.features, function (feature) {                             countOfFeatures++;                                                     });                          alert("Number of points in polygon " + countOfFeatures);                     });                                      });             }


Any ideas on how this could be done are much appreciated. Thanks
0 Kudos
1 Solution

Accepted Solutions
JakeSkinner
Esri Esteemed Contributor
You can use the following function to report how many points are within each polygon once the map is loaded:

var polygonFeature= new FeatureLayer(my feature layer with polygons, {                     mode: FeatureLayer.MODE_ONDEMAND,                     outFields: ["*"]                 });  map.addLayer(polygonFeature);  map.on("update-end", function(){     array.forEach(polygonFeature.graphics, function(feature){         var OID = feature.attributes.OBJECTID;         var query = new Query();         var queryTask = new QueryTask("url to points");         query.geometry = feature.geometry         query.returnGeometry = true;                         queryTask.executeForCount(query, function(count){             console.log("ObjectID " + OID + " has " + count + " points");         })     }) })


You will need to add the dojo/_base/array module to your code.  For adding the text to your map, take a look at the TextSymbol class.

View solution in original post

0 Kudos
12 Replies
ØyvindIdland
New Contributor III
Hi,

i think the terms are a little bit mixed together here: A feature is (in the ESRI world) a set of attributes and a geometry. The geometry may be a polyline, polygon or point. In addition there are multi-versions of these, multipoint, multiline and multipolygon.

In the case of polygons, these have one or more rings. The first ring is the outer ring, the other ones (if present), are "holes" (polygons with holes are often referred to as "donut polygons").

Each ring consists of vertices (points). Note that these points are not features, they are just components.

In the JavaScript API, features are represented as "Graphic" objects, which is the same thing. These have .attributes and .geometry members. Geometries are implemented as multidimensional arrays.

Here is a simple example in pure JS:


function showPolyVertices(graphic) {
  var geom = graphic.geometry;
  var output = "";
  for (var ringNum = 0; ringNum < geom.rings.length; ringNum++) {
  output += "ring number: " + ringNum + "\n";
  var ring = geom.rings[ringNum];
  for (var vertexNum = 0; vertexNum < ring.length; vertexNum++) {
  var vertex = ring[vertexNum];
  output += vertex[0] + ", " + vertex[1];
  output += "\n";
  }
  }
  alert(output);
}
0 Kudos
ChristianDebono
New Contributor II
Thanks for your explanation. But I don't really this will help me in my problem. I have a polygon
[ATTACH=CONFIG]32469[/ATTACH]
which is a feature layer service. Another feature layer contains points ("M")
[ATTACH=CONFIG]32470[/ATTACH].
I want that when a polygon is selected the number of points ("M") found in that polygon are displayed for the user.
0 Kudos
ØyvindIdland
New Contributor III
Ah, ok. I thought you ment the vertices in the polygon.

You seem to be very close already, using the polygon as the query geometry. Also, you need to specify the spatial relationship. The default is SPATIAL_REL_INTERSECTS, but you can specify this (read docs on the various operators):

query.spatialRelationship = esri.tasks.Query.SPATIAL_REL_CONTAINS;

Then create the QueryTask using the URL to the service containing points.
0 Kudos
ManishkumarPatel
Occasional Contributor II
You can refer to the sample link below:
https://developers.arcgis.com/javascript/jssamples/query_buffer.html

it looks like something similar to your requirement.

Hope this helps.
Regards,
Manish
0 Kudos
ChristianDebono
New Contributor II
Thanks for your help manish_patel, I have followed this sample before I've done the one posted above, and it didn't work.
0 Kudos
JakeSkinner
Esri Esteemed Contributor
Hi Christian,

You can use the executeForCount method to achieve this.  Ex:

localCouncils.on("click", function (evt) {
    map.graphics.clear();
    var highlightGraphic = new Graphic(evt.graphic.geometry, highlightSymbol);
    map.graphics.add(highlightGraphic);
    
    var query = new Query();
    var queryTask = new QueryTask("feature layer with points");
    query.geometry = evt.graphic.geometry;
    query.returnGeometry = true;       
    
    queryTask.executeForCount(query, function(count){
        alert(count);
    })
})
0 Kudos
ChristianDebono
New Contributor II
Thanks Jake Skinner, its all what I needed 🙂
0 Kudos
ChristianDebono
New Contributor II
Is it possible to do the same procedure i.e. count all points in the polygon, but rather than clicking it, the points are counted for each polygon when the map is loaded and the result of each polygon is displayed on the map on its corresponding polygon. I have done this but it is not working properly.

on(map, "load", selectByPolygon);

            function selectByPolygon() {
                
                var polygonFeature= new FeatureLayer(my feature layer with polygons, {
                    mode: FeatureLayer.MODE_ONDEMAND,
                    outFields: ["*"]
                });

                map.addLayer(polygonFeature);

             
                polygonFeature.on("graphic-draw", function (evt) {
                    var query = new Query();
                    var queryTask = new QueryTask(my feature layer with points);
                    query.geometry = evt.graphic.geometry;
                    query.returnGeometry = true;
                    query.outSpatialReference = map.spatialReference;
                    query.outFields = ["*"];

                    queryTask.execute(query, function (results) {
                        console.log(results.features.length);
                    });
                });
            }
0 Kudos
JakeSkinner
Esri Esteemed Contributor
You can use the following function to report how many points are within each polygon once the map is loaded:

var polygonFeature= new FeatureLayer(my feature layer with polygons, {                     mode: FeatureLayer.MODE_ONDEMAND,                     outFields: ["*"]                 });  map.addLayer(polygonFeature);  map.on("update-end", function(){     array.forEach(polygonFeature.graphics, function(feature){         var OID = feature.attributes.OBJECTID;         var query = new Query();         var queryTask = new QueryTask("url to points");         query.geometry = feature.geometry         query.returnGeometry = true;                         queryTask.executeForCount(query, function(count){             console.log("ObjectID " + OID + " has " + count + " points");         })     }) })


You will need to add the dojo/_base/array module to your code.  For adding the text to your map, take a look at the TextSymbol class.
0 Kudos