ESRI point clustering example using featurelayer or querytask as input?

16701
42
Jump to solution
10-05-2012 08:32 AM
TracySchloss
Frequent Contributor
I have tried to implement the ESRI forum example for clustering "Clustering with Javascript API" http://www.arcgis.com/home/item.html?id=c546bc8d4f0b4c0fbdf149b92223e681 with mixed results.  Sometimes the cluster layer draws fine and sometimes it doesn't draw at all.  Even when it draws it's very slow and I'm not sure the users will be satisfied.  There seems to be mixed reviews on this.  The fact that it's display seem to be intermittent for me is enough for me to look to another clustering solution. 

More recently, the ESRI sample "Point Clustering" was posted. http://help.arcgis.com/en/webapi/javascript/arcgis/help/jssamples_start.htm#jssamples/layers_point_c... I like the way this looks, but I'm having a hard time understanding how to make it work with a layer as input, since my data is already in a service.  It seems like either I should add a function to step through all my features to create properly formatted input data, or I should edit the custom layer to handle features of a featureset or featurelayer instead.

Has anyone modified ESRI's point clustering example to use something besides the input JSON file?
1 Solution

Accepted Solutions
TracySchloss
Frequent Contributor
I can't believe I got it work!  This method executes much faster than the forum example, so I'm glad I switched.

Here's the function that creates the cluster layer. I have an init function that calls it, and that is where infoTemplate is defined.

function runQuery(){     // layer 1 in the service contains all server locations and will be used to cluster     var queryTask = new esri.tasks.QueryTask("http://<myserver>/ArcGIS/rest/services/ITSD/serverLocations/MapServer/1");     var query = new esri.tasks.Query();     query.returnGeometry = true;     query.where = '1=1';     query.outFields = ["*"];          dojo.connect(queryTask, "onComplete", function(featureSet){         var inputInfo = {};         inputInfo.data = dojo.map(featureSet.features, function(feature){             var pointX = feature.geometry.x;             var pointY = feature.geometry.y;             var att = feature.attributes;             return {                 "x": pointX,                 "y": pointY,                 "attributes": att             };         });                  // cluster layer that uses OpenLayers style clustering          clusterLayer = new extras.ClusterLayer({             "data": inputInfo.data,             "distance": 100,             "id": "clusters",             "labelColor": "#fff",             "labelOffset": 10,             "resolution": map.extent.getWidth() / map.width,             "singleColor": "#888",             "singleTemplate": infoTemplate         });         var defaultSym = new esri.symbol.SimpleMarkerSymbol().setSize(4);         var renderer = new esri.renderer.ClassBreaksRenderer(defaultSym, "clusterCount");         var blue = new esri.symbol.PictureMarkerSymbol("http://static.arcgis.com/images/Symbols/Shapes/BluePin1LargeB.png", 32, 32).setOffset(0, 15);         var green = new esri.symbol.PictureMarkerSymbol("http://static.arcgis.com/images/Symbols/Shapes/GreenPin1LargeB.png", 64, 64).setOffset(0, 15);         var red = new esri.symbol.PictureMarkerSymbol("http://static.arcgis.com/images/Symbols/Shapes/RedPin1LargeB.png", 72, 72).setOffset(0, 15);         renderer.addBreak(0, 2, blue);         renderer.addBreak(2, 200, green);         renderer.addBreak(200, 1001, red);                  clusterLayer.setRenderer(renderer);         map.addLayer(clusterLayer);                  // close the info window when the map is clicked          // dojo.connect(map, "onClick", cleanUp);          // close the info window when esc is pressed          dojo.connect(map, "onKeyDown", function(e){             if (e.keyCode == 27) {                 cleanUp();             }         });         dojo.connect(queryTask, "onError", function(err){             alert(err.details);         });                       });     queryTask.execute(query); }   

View solution in original post

42 Replies
GordonBooth
New Contributor III
Having the same problem. Please help.
0 Kudos
derekswingley1
Frequent Contributor
One of the parameters for cluster layer is "data". As noted in the sample description, data is an array of objects and each object has the following properties:  x, y and attributes.

Here's the workflow to get data from a layer in a map service or feature service in this format:

  • send a request to the layer's query endpoint with esri.request

  • when data comes back, use dojo.map to create an array of objects with x, y and attributes properties

  • pass the result from dojo.map to the cluster layer


That's a high level overview. Can one of you take a crack at coding it up and post back here? I can provide further help if you can't make it work.
0 Kudos
StephenLead
Regular Contributor III
Sometimes the cluster layer draws fine and sometimes it doesn't draw at all


Note that by default, ArcGIS Server only returns 1,000 features as a result of a query. In the problem above, it may be the case that you're zooming to an extent which doesn't contain any returned features (depending on how you're structuring the query).
0 Kudos
TracySchloss
Frequent Contributor
I"m not sure why I would use an esri.request to the query endpoint as opposed to executing a standard query task.  I usually execute my query tasks with a callback to generate my featureset.  Is is faster to request the data or formatted differently if I use esri.request instead?
0 Kudos
derekswingley1
Frequent Contributor
I"m not sure why I would use an esri.request to the query endpoint as opposed to executing a standard query task.  I usually execute my query tasks with a callback to generate my featureset.  Is is faster to request the data or formatted differently if I use esri.request instead?


You could use a QueryTask to pull your features out. I said esri.request because it's always available (no additional modules to load) and you don't need any of Query's special functionality. I wouldn't expect a noticeable performance difference between the two.
0 Kudos
TracySchloss
Frequent Contributor
I'll just stick with my standard query task syntax then, which I'm more familiar with.

I'm getting stuck at the very beginning with the dojo.Config, which is generating an error in Aptana (version 2).  I got this error when I loaded the sample too: 

    <script> 
        var dojoConfig = {  
        parseOnLoad: true, 
        packages: [{ 
         "name": "extras", 
          "location": location.pathname.replace(/\/[^/]+$/, '') + "/extras" }] 
      }; 
</script>


The error:
Multiple items missing at this position:
missing ) after argument list
Bad regular expression:
\/[^/]+$/, '') + "/extras"

In the ESRI example, I changed this to have the location as just "/extras", which got rid of the error and then the sample ran.

When I made the same changes in my own code for dojo.Config, it errors on the line
dojo.require("extras,ClusterLayer); 

The error in Firebug is 'url is undefined', which I take to mean it's not finding ClusterLayer.js after all.

I wouldn't call myself a novice programmer, but I am relatively new to JavaScript.  I'm pretty comfortable with the coding of the functions, so probably the error toward the top.  I don't know if my query task function is correct because it's not making it that far before it blows up!
0 Kudos
TracySchloss
Frequent Contributor
I see now that I still had all my references to version 2.5 of the API because that's what the forum post for clusters used.  I changed my API references to 3.2 and I'm not getting the error on the dojo.require("extras.ClusterLayer").

The code still isn't working right, but at least I'm past the first error.
0 Kudos
derekswingley1
Frequent Contributor

I see now that I still had all my references to version 2.5 <snip>


That will make a big difference. Glad you moved up to 3.2.


The code still isn't working right, but at least I'm past the first error.


Post the code you're currently using and a description of what isn't working?
0 Kudos
TracySchloss
Frequent Contributor
I can't believe I got it work!  This method executes much faster than the forum example, so I'm glad I switched.

Here's the function that creates the cluster layer. I have an init function that calls it, and that is where infoTemplate is defined.

function runQuery(){     // layer 1 in the service contains all server locations and will be used to cluster     var queryTask = new esri.tasks.QueryTask("http://<myserver>/ArcGIS/rest/services/ITSD/serverLocations/MapServer/1");     var query = new esri.tasks.Query();     query.returnGeometry = true;     query.where = '1=1';     query.outFields = ["*"];          dojo.connect(queryTask, "onComplete", function(featureSet){         var inputInfo = {};         inputInfo.data = dojo.map(featureSet.features, function(feature){             var pointX = feature.geometry.x;             var pointY = feature.geometry.y;             var att = feature.attributes;             return {                 "x": pointX,                 "y": pointY,                 "attributes": att             };         });                  // cluster layer that uses OpenLayers style clustering          clusterLayer = new extras.ClusterLayer({             "data": inputInfo.data,             "distance": 100,             "id": "clusters",             "labelColor": "#fff",             "labelOffset": 10,             "resolution": map.extent.getWidth() / map.width,             "singleColor": "#888",             "singleTemplate": infoTemplate         });         var defaultSym = new esri.symbol.SimpleMarkerSymbol().setSize(4);         var renderer = new esri.renderer.ClassBreaksRenderer(defaultSym, "clusterCount");         var blue = new esri.symbol.PictureMarkerSymbol("http://static.arcgis.com/images/Symbols/Shapes/BluePin1LargeB.png", 32, 32).setOffset(0, 15);         var green = new esri.symbol.PictureMarkerSymbol("http://static.arcgis.com/images/Symbols/Shapes/GreenPin1LargeB.png", 64, 64).setOffset(0, 15);         var red = new esri.symbol.PictureMarkerSymbol("http://static.arcgis.com/images/Symbols/Shapes/RedPin1LargeB.png", 72, 72).setOffset(0, 15);         renderer.addBreak(0, 2, blue);         renderer.addBreak(2, 200, green);         renderer.addBreak(200, 1001, red);                  clusterLayer.setRenderer(renderer);         map.addLayer(clusterLayer);                  // close the info window when the map is clicked          // dojo.connect(map, "onClick", cleanUp);          // close the info window when esc is pressed          dojo.connect(map, "onKeyDown", function(e){             if (e.keyCode == 27) {                 cleanUp();             }         });         dojo.connect(queryTask, "onError", function(err){             alert(err.details);         });                       });     queryTask.execute(query); }