How to use QueryParameters to get features contained in an area?

1130
3
09-16-2017 06:37 AM
GaelDurand
New Contributor

I would like to select features according to a QueryParameters object.

I don't understand why I get all features when I call queryFeaturesAsync whereas I expect a subset of it. 

I tried in vain to change the value of SpatialRelationship, set an envelope or set max features.

Point gps = new Point(-1.640235, 48.127568, SpatialReferences.getWgs84());
final Polygon searchGeometry = GeometryEngine.buffer(gps, 500);

QueryParameters queryParams = new QueryParameters();
queryParams.setGeometry(searchGeometry);
queryParams.setMaxFeatures(500);
queryParams.setOutSpatialReference(SpatialReferences.getWgs84());
queryParams.setSpatialRelationship(QueryParameters.SpatialRelationship.CONTAINS);

final ListenableFuture<FeatureQueryResult> results = geoDbTable.queryFeaturesAsync(queryParams);

results.addDoneListener(new Runnable() {

@Override public void run() {
try {
final FeatureQueryResult fqr = results.get();

List result = new ArrayList();
int counter = 0;
while (fqr.iterator().hasNext()){
counter+=1;
if (counter%100 == 0) {
Log.d("FeatureQueryResult", Long.toString(counter));
}
}
}
}
0 Kudos
3 Replies
AlexanderNohe1
Occasional Contributor III

I believe that your searchGeometry takes on the spatial reference of the point that you are buffering.  Therefore, I believe you created a 500 degree buffer which will encompass the globe twice over.  You may want to pick a different spatial reference to use like web mercator which is measured in meters.

0 Kudos
GaelDurand
New Contributor

Hi Alexander,

I followed your advice by converting from WGS 84 to Web Mercator, but the result is the same.

It's as if queryParams was useless whichever Spatial Reference I chose.

Moreover, I got more than 500 features while this method should only return 500 features because of setMaxFeatures(500).

Do you see what's wrong with my code?

Point gps = new Point(-1.640235, 48.127568, SpatialReferences.getWgs84());
Point mercator = CoordinateFormatter.fromUtm(CoordinateFormatter.toUtm(gps, CoordinateFormatter.UtmConversionMode.LATITUDE_BAND_INDICATORS, true), 
                                             SpatialReferences.getWebMercator(), CoordinateFormatter.UtmConversionMode.LATITUDE_BAND_INDICATORS);

TextSymbol textSymbol =
    new TextSymbol(20, "Test", Color.rgb(255, 0, 0),
                  TextSymbol.HorizontalAlignment.CENTER, TextSymbol.VerticalAlignment.BOTTOM);
Graphic textGraphic = new Graphic(mercator, textSymbol);
mGraphicsOverlayETARE.getGraphics().add(textGraphic);

final Polygon searchGeometry = GeometryEngine.buffer(mercator, 500);

// create a query to find which features are contained by the query geometry
QueryParameters queryParams = new QueryParameters();
queryParams.setGeometry(searchGeometry);
queryParams.setMaxFeatures(500);
queryParams.setOutSpatialReference(SpatialReferences.getWebMercator());
queryParams.setSpatialRelationship(QueryParameters.SpatialRelationship.CONTAINS);
0 Kudos
AlexanderNohe1
Occasional Contributor III

Rather than doing the CoordinateFormatter class, I would encourage you to use GeometryEngine::Project().  This will project the point to the correct spatial reference which you can then pass in (might be a little more straightforward than what you have there).  When doing this, are you seeing different results?

Where are you executing this query?  Can we see that line of code?