Query a WFS Layer with Feature Reduction Cluster

674
2
Jump to solution
06-23-2022 05:30 AM
ShariMeier
New Contributor II

Hi there, 

I'm currently working with a WFS Layer with a feature reduction to create clusters. 

Now I need to identify on which cluster a user has clicked on the map and which objects are included in this cluster. As I made the feature reduction on the client-side - I assumed that I needed to choose a query method that does the query on client-side. I tried it directly on the layerView and the WFS layer ( see code example below).

However, both ways don't recognize the cluster. But they return the points behind the cluster or, more precisely, in the cluster if I accidentally click on the exact spot where original points were when I'm trying to select the cluster. What am I missing here?

Thanks in advance for your tips and help!

Best wishes, 
Shari


//query on WFSLayerView
const query = (layerView.layer as WFSLayer).createQuery();
query.geometry = point;
query.distance = distance;
query.units = 'meters';
query.spatialRelationship = 'intersects';
query.returnGeometry = true;
query.outFields = ['*'];

(layerView as WFSLayerView).queryFeatures(query).then(function (results) {
console.log(results.features);
});

//query on WFSLayer
return fromPromise(
(layer as WFSLayer).queryFeatures({
geometry: point,
distance: distance,
units: 'meters',
spatialRelationship: 'intersects',
returnGeometry: true,
outFields: ['*'],
}),
).pipe(
map((featureSet: FeatureSet) => {
console.log(featureSet.features);
}),
);

 

0 Kudos
1 Solution

Accepted Solutions
ShariMeier
New Contributor II

We solved this as follows: with a hit test, we ask for the clicked clusters and then execute a query on the WFSLayerView with the "aggregateIds". This returns all objects within the cluster, which we then can use for other stuff. 

switchMap(([layerView]) => {
wfsLayerView = layerView;
const opts = { include: layer };
return from(this.mainMapService.mapView.hitTest(screenPoint, opts)).pipe(
map((response: HitTestResult) => {
return response;
}),
);
}),
switchMap((response) => {
if (response.results.length) {
const graphic = response.results[0].graphic;
if (graphic.isAggregate) {
//cluster is clicked, we need to query for all objects inside the cluster
const query = wfsLayerView.createQuery();
query.aggregateIds = [graphic.getObjectId()];
return from(wfsLayerView.queryFeatures(query)).pipe(
map((result) => {
console.log(result.features);
return result.features;
}),
);
} else {
// single point is clicked
return of([graphic]);
}
}
return of(null);
}),

View solution in original post

0 Kudos
2 Replies
ShariMeier
New Contributor II

We solved this as follows: with a hit test, we ask for the clicked clusters and then execute a query on the WFSLayerView with the "aggregateIds". This returns all objects within the cluster, which we then can use for other stuff. 

switchMap(([layerView]) => {
wfsLayerView = layerView;
const opts = { include: layer };
return from(this.mainMapService.mapView.hitTest(screenPoint, opts)).pipe(
map((response: HitTestResult) => {
return response;
}),
);
}),
switchMap((response) => {
if (response.results.length) {
const graphic = response.results[0].graphic;
if (graphic.isAggregate) {
//cluster is clicked, we need to query for all objects inside the cluster
const query = wfsLayerView.createQuery();
query.aggregateIds = [graphic.getObjectId()];
return from(wfsLayerView.queryFeatures(query)).pipe(
map((result) => {
console.log(result.features);
return result.features;
}),
);
} else {
// single point is clicked
return of([graphic]);
}
}
return of(null);
}),
0 Kudos
RoyJackson_AlertMedia
New Contributor III

Very nice!   Note if you do not pass aggregateIds as an array of values, and only have a single objectId value, you will get every feature in the layer back 🙂

0 Kudos