Hello,
I'm customizing the layers list widget and I'm applying filters to the layers by using the FilterManager from library.
It works like a charm, however, I'm trying to take it a step further by applying an extent filter.
My application has one map service with number of layers, which are all query layers.
The service was created in ArcGIS Pro and all layers are simple select statements of views in a PostgresSQL.
What I'm trying to achieve is a query that returns data only based on the extent.
At first I've tried adding the query filter on ArcGIS Pro but it fails.. The syntax is as follow -
ST_Contains(ST_GeomFromText(::view_extent, 4283), shape)
When trying to add it to the view on the database it fails, since view_extent is not supported and the default value is null.
When trying to add it to ArcGIS Pro, it accepts it, but then can't read the spatial reference or time-aware data..
I also tried adding it as a query definition but it throws a sytax error message.
So now I'd like to try and add it at the client side, but I'm applying the query by using the FilterManager - when adding the above line to the query, it just doesn't show anything (I'm guessing it behaves as a query definion and therefore doesn't work).
The only option I can think of is to build a query and pass the geometry parameter dynamically, but that's a very long workaround and still I can't see how I can apply it through the FilterManager this way..
Anyone ever did something like that before?
Based on the attached article, ArcGIS does support the ::view_extent parameter, yet it doesn't seem to play nice on the web -
Define parameters in a query layer—Query layers | ArcGIS Desktop
Thanks,
Shay.
Solved! Go to Solution.
Shay,
Yes a QueryTask returns a FeatureSet of the results but you can use QueryTask.executeForIds and then use the result array to set the layers layerDefinition property.
var qTask = new QueryTask("your url");
var query = new Query();
query.geometry = this.map.extent;
query.where = "your SQL statement";
qTask.executeForIds(lang.hitch(this, function(results){
var whereClause = yourLayer.objectIdField + " IN (" + results.join() + ")";
}));
yourLayer.setDefinitionExpression(whereClause); //Assuming the layer is a FeatureLayer
// or if the layer is an ArcGISDyanmicMapServiceLayer then
//var layerDefinitions = [];
//layerDefinitions[0] = whereClause;
//dynamicMapServiceLayer.setLayerDefinitions(layerDefinitions);
Shay,
The FilterManager is applying the filter to the layer using the definition expression so you will not have the option of using a spatial component like an extent filter. The only option I know of is to build an actual query task using the maps extent and complete get away from using the FilterManager.
Thank you Robert, I was affraid that might be the answer.. if I do choose to implement it that way, do you know if the behaviour of the filter will be the same as using the FilterManager? (will it be consistent thoughout the use of the app and layer?)
I'm not sure I fully understand the differences of using the FilterManager rather than a query task.. I assume that the FilterManager is just a wrapper to a query task.
Shay,
No the FilterManager is just a wrapper for the layers definition query (i.e. a where clause that is applied to the layer). When using a QueryTask you will specify the Queries where property and the queries.geometry (with your extent). The where portion is going to be similar to how you used the FilterManager (i.e. passing it a SQL statement for the where clause).
Sounds good, thanks a lot! I'm about to give it a go. I'll report back once it's done.
Robert,
Once I execute a query task, the results I'm getting are completely separate from my activity.. it's just a set of results and not considered to be part of the active layer.
Is there a way to run the query task on a layer from the layer list without managing the results in a separate manner? I'm basically trying to filter the existing layer without creating a new one.
Shay,
Yes a QueryTask returns a FeatureSet of the results but you can use QueryTask.executeForIds and then use the result array to set the layers layerDefinition property.
var qTask = new QueryTask("your url");
var query = new Query();
query.geometry = this.map.extent;
query.where = "your SQL statement";
qTask.executeForIds(lang.hitch(this, function(results){
var whereClause = yourLayer.objectIdField + " IN (" + results.join() + ")";
}));
yourLayer.setDefinitionExpression(whereClause); //Assuming the layer is a FeatureLayer
// or if the layer is an ArcGISDyanmicMapServiceLayer then
//var layerDefinitions = [];
//layerDefinitions[0] = whereClause;
//dynamicMapServiceLayer.setLayerDefinitions(layerDefinitions);
Genius! thank you
Don’t forget to mark this question as answered.