Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 71 additions & 6 deletions src/clusterfeaturelayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ define([
'dojo/_base/Color',
'dojo/_base/connect',
'dojo/on',
'dojo/Deferred',
'dojo/promise/all',

'esri/SpatialReference',
Expand Down Expand Up @@ -35,7 +36,7 @@ define([
'esri/tasks/QueryTask'

], function (
declare, arrayUtils, lang, Color, connect, on, all,
declare, arrayUtils, lang, Color, connect, on, Deferred, all,
SpatialReference, Point, Polygon, Multipoint, Extent, Graphic,
esriConfig, normalizeUtils,
SimpleMarkerSymbol, SimpleLineSymbol, SimpleFillSymbol, TextSymbol, Font,
Expand Down Expand Up @@ -143,6 +144,10 @@ define([
// Optional. Defines the OBJECTID field of service. Default is 'OBJECTID'.
// where: String?
// Optional. Where clause for query.
// queryAttachments: Boolean?
// Optional. If true, features within the current extent will have their attachments queried and an "attachmentInfos" object will be added to the feature object.
// filterFeaturesOnResponse: false or function(features) {return features}
// Optional. If a function, this function will be called with the current feature array before if is added to the map and exects an array of features to be returned.
// useDefaultSymbol: Boolean?
// Optional. Use the services default symbology for single features.
// returnLimit: Number?
Expand Down Expand Up @@ -203,6 +208,8 @@ define([
this._outFields = options.outFields || ['*'];
this.queryTask = new QueryTask(this.url);
this._where = options.where || null;
this._queryAttachments = options.queryAttachments || false;
this._filterFeaturesOnResponse = options.filterFeaturesOnResponse || false;
this._useDefaultSymbol = options.hasOwnProperty('useDefaultSymbol') ? options.useDefaultSymbol : false;
this._returnLimit = options.returnLimit || 1000;
this._singleRenderer = options.singleRenderer;
Expand Down Expand Up @@ -466,17 +473,18 @@ define([
},

_onIdsReturned: function (results) {
this.emit('ids-returned',{results: results});
var uncached = difference(results, this._objectIdCache.length, this._objectIdHash);
this._objectIdCache = concat(this._objectIdCache, uncached);
if (uncached && uncached.length) {
this._query.where = null;
this._query.geometry = null;
var queries = [];
if (uncached.length > this._returnLimit) {
while(uncached.length) {
while (uncached.length) {
// Improve performance by just passing list of IDs
this._query.objectIds = uncached.splice(0, this._returnLimit - 1);
queries.push(this.queryTask.execute(this._query));
queries.push(this._queryFeatures());
}
all(queries).then(lang.hitch(this, function(res) {
var features = arrayUtils.map(res, function(r) {
Expand All @@ -489,7 +497,7 @@ define([
} else {
// Improve performance by just passing list of IDs
this._query.objectIds = uncached.splice(0, this._returnLimit - 1);
this.queryTask.execute(this._query).then(
this._queryFeatures().then(
lang.hitch(this, '_onFeaturesReturned'), this._onError
);
}
Expand All @@ -503,6 +511,56 @@ define([
}
},

_queryFeatures: function() {
var deferred = new Deferred();
var queries = {
features: this.queryTask.execute(this._query),
};

if (this._queryAttachments) {
var attachmentQueryUrl = this.url + (this.url.substr(-1) === '/' ? '' : '/') + 'queryAttachments';
var attachmentQuery = esriRequest({
url: attachmentQueryUrl,
content: {
objectIds: this._query.objectIds,
f: 'json'
},
handleAs: 'json'
},{
usePost: true
});

queries.attachments = attachmentQuery;
}

all(queries).then(lang.hitch(this,function(result) {
var objectIdField = lang.getObject('features.objectIdFieldName',false,result);
var features = lang.getObject('features.features',false,result);
var attachments = lang.getObject('attachments.attachmentGroups',false,result);

if (this._queryAttachments && objectIdField && features && attachments) {
// extend features with corresponding attachments
arrayUtils.forEach(features,function(ftr) {
var ftrId = ftr.attributes[objectIdField];
var ftrAttachments = arrayUtils.filter(attachments, function(attachment) {
return attachment.parentObjectId === ftrId;
})[0];

lang.mixin(ftr,{
attachmentInfos: lang.getObject('attachmentInfos',false,ftrAttachments)
});
});
deferred.resolve(result.features);
} else if (!this._queryAttachments && features) {
deferred.resolve(result.features);
} else {
deferred.reject(result.features);
}
}),deferred.reject);

return deferred;
},

// Return a cache of features in the current extent
_inExtent: function() {
// debug
Expand All @@ -516,7 +574,7 @@ define([
while (len--) {
var oid = this._objectIdCache[len];
var cached = this._clusterCache[oid];
if (cached && ext.contains(cached.geometry)) {
if (cached && cached.geometry && cached.geometry.spatialReference && ext.contains(cached.geometry)) {
valid.push(cached);
}
}
Expand All @@ -540,6 +598,11 @@ define([
} else {
features = results.features;
}

if (typeof this._filterFeaturesOnResponse === 'function') {
features = this._filterFeaturesOnResponse(features) || features;
}

var len = features.length;
//this._clusterData.length = 0;
//this.clear();
Expand Down Expand Up @@ -659,14 +722,15 @@ define([
this._map.infoWindow.show(e.graphic.geometry);
this._map.infoWindow.show(e.graphic.geometry);
}
this.emit('singles-click',{singles: singles});
}
// Multi-cluster click, super zoom to cluster
else if (this._zoomOnClick && e.graphic.attributes.clusterCount > 1 && this._map.getZoom() !== this._map.getMaxZoom())
{
// Zoom to level that shows all points in cluster, not necessarily the extent
var extent = this._getClusterExtent(e.graphic);
if (extent.getWidth()) {
this._map.setExtent(extent.expand(1.5), true);
this._map.setExtent(extent.expand(1.15), true);
} else {
this._map.centerAndZoom(e.graphic.geometry, this._map.getMaxZoom());
}
Expand All @@ -693,6 +757,7 @@ define([
this._map.infoWindow.show(e.graphic.geometry);
this._map.infoWindow.show(e.graphic.geometry);
}
this.emit('singles-click',{singles: singles});
}
}
},
Expand Down