IdentifyTask, QueryTask and MaxAllowableOffset - after setting it does not get reset

3209
5
02-22-2012 12:07 AM
AndrewBiggins
New Contributor III
Hello,

I am having a problem with using the IdentifyTask in conjunction with a QueryTask and the MaxAllowableOffset option.

I am first using the IdentifyTask to find features in a dynamic map service layer that intersect a given graphics layer feature.
Then if any of the features have more than a certain number of vertices I am running a QueryTask and setting MaxAllowableOffset to generalise the feature, but only for those features.

This works fine the first time it is run, but after the first run the IdentifyTask appears to be using the MaxAllowableOffset value that was set by the QueryTask, so all the features are generalised by the IdentifyTask!
I have tried setting MaxAllowableOffset for the IdentifyTask to zero (via IdentifyParameters.MaxAllowableOffset) and this didn't fix the problem.
However, when I set IdentifyParameters.MaxAllowableOffset to a small value (0.001 metres) it fixed the problem.

This doesn't seem like a nice workaround, so I'm hoping someone can explain why this is happening, or whether this is a bug?

Cheers,
Andrew

Here's a summary of the code:

 IdentifyParameters sitesQueryIdentifyParams = new IdentifyParameters();
 sitesQueryIdentifyParams.Geometry = selectedUnionedGeometry;
 sitesQueryIdentifyParams.MapExtent = _map.Extent;
 sitesQueryIdentifyParams.Width = (int)_map.ActualWidth;
 sitesQueryIdentifyParams.Height = (int)_map.ActualHeight;
 // Set sites query identify tolerance to 0 pixels
 sitesQueryIdentifyParams.Tolerance = 0;
 sitesQueryIdentifyParams.LayerOption = LayerOption.all;
 
 // Perform identify on Sites layer
 sitesQueryIdentifyParams.LayerIds.Add(Convert.ToInt16(_sitesLayerId));
 sitesQueryIdentifyParams.SpatialReference = _map.SpatialReference;
 
 // TEST - Explicitly set MaxAllowableOffset - this only works when set to a small value
 sitesQueryIdentifyParams.MaxAllowableOffset = 0.001;
 
 // Perform Sites Query Identify operation (asynchronously)
 IdentifyTask sitesQueryIdentifyTask = new IdentifyTask(_ahelpPilotMapUrl);
 
 // Disable caching identify results
 sitesQueryIdentifyTask.DisableClientCaching = true;
 
 sitesQueryIdentifyTask.ExecuteCompleted += SitesQueryIdentifyTask_ExecuteCompleted;
 sitesQueryIdentifyTask.Failed += SitesQueryIdentifyTask_Failed;
 sitesQueryIdentifyTask.ExecuteAsync(sitesQueryIdentifyParams, graphicsLayerLabel);
 
 ...

private void SitesQueryIdentifyTask_ExecuteCompleted(object sender, IdentifyEventArgs args)
{
 _identifyGraphics = new List<Graphic>();
 foreach (IdentifyResult result in args.IdentifyResults)
 {
  _identifyGraphics.Add(result.Feature);
 }
 
 // Loop through graphics, for each graphic count number of vertices (polygons/lines only) and if greater than a threshold generalise
 _identifyGraphicsToGeneralise = new List<Graphic>();
 _identifyGeneraliseCompleteCount = 0;
 foreach (Graphic identifyGraphic in _identifyGraphics)
 {
  int identifyVerticeCount = 0;
  if (identifyGraphic.Geometry is ESRI.ArcGIS.Client.Geometry.Polygon)
  {
   ESRI.ArcGIS.Client.Geometry.Polygon identifyPolygon = (ESRI.ArcGIS.Client.Geometry.Polygon)identifyGraphic.Geometry;
   ObservableCollection<ESRI.ArcGIS.Client.Geometry.PointCollection> identifyPolyRings = identifyPolygon.Rings;
   foreach (ESRI.ArcGIS.Client.Geometry.PointCollection identifyRing in identifyPolyRings)
   {
    identifyVerticeCount += identifyRing.Count;
   }
  }
  else if (identifyGraphic.Geometry is ESRI.ArcGIS.Client.Geometry.Polyline)
  {
   ESRI.ArcGIS.Client.Geometry.Polyline identifyPolyline = (ESRI.ArcGIS.Client.Geometry.Polyline)identifyGraphic.Geometry;
   foreach (ESRI.ArcGIS.Client.Geometry.PointCollection identifyPath in identifyPolyline.Paths)
   {
    identifyVerticeCount += identifyPath.Count;
   }
  }
  if (identifyVerticeCount > _MAX_VERTICES)
  {
   // Add to list of graphics to generalise
   _identifyGraphicsToGeneralise.Add(identifyGraphic);
  }
 }
 foreach (Graphic identifyGeneraliseGraphic in _identifyGraphicsToGeneralise)
 {
  // Use QueryTask to run query for this graphic, set MaxAllowableOffset to reduce vertices
  QueryTask identifyQueryGeneralizeTask = new QueryTask(_ahelpPilotMapUrl + "/" + _sitesLayerId);
 
  // Disable caching query results
  identifyQueryGeneralizeTask.DisableClientCaching = true;
 
  identifyQueryGeneralizeTask.ExecuteCompleted += IdentifyQueryTaskGeneralize_ExecuteCompleted;
  identifyQueryGeneralizeTask.Failed += IdentifyQueryTaskGeneralize_Failed;
 
  ESRI.ArcGIS.Client.Tasks.Query identifyQueryGeneralize = new ESRI.ArcGIS.Client.Tasks.Query();
 
  // Set up query for given feature
  identifyQueryGeneralize.Where = _OBJECTID_FIELD_NAME + "=" + identifyGeneraliseGraphic.Attributes[_OBJECTID_FIELD_NAME].ToString();
  // Specify same projection as first layer of map, as this will determine overall spatial projection
  identifyQueryGeneralize.OutSpatialReference = _map.SpatialReference;
  identifyQueryGeneralize.ReturnGeometry = true;
 
  // Set max allowable offset for sites with a lot of vertices, to reduce size of geometry returned
  identifyQueryGeneralize.MaxAllowableOffset = _MAX_ALLOWABLE_OFFSET;
 
  // Add all fields to query so they are all returned with geometry
  identifyQueryGeneralize.OutFields.Add("*");
  identifyQueryGeneralizeTask.ExecuteAsync(identifyQueryGeneralize, identifyGeneraliseGraphic);
 }
 ...
0 Kudos
5 Replies
JenniferNery
Esri Regular Contributor
Can you run your code without workaround and run Fiddler? You should be able to see if IdentifyTask pass MaxAllowableOffset even if you did not set it. If it was never set and the request still sends it, then it must be a bug in our API. I do not find us setting this to a default value though. It is only when IdentifyParameters.MaxAllowableOffset > 0 that we send it. So maybe if you need to set it at some point but succeeding request should clear it then reset by setting to a negative value?
0 Kudos
AndrewBiggins
New Contributor III
Hi Jennifer,

Thanks for your reply.

I have looked at what gets passed to the IdentifyTask via Fiddler (minus the workaround). The MaxAllowableOffset never gets set by the IdentifyTask if it is not set in the code.
However, on subsequent runs of the IdentifyTask the geometry that is returned has been generalised, even though in my code MaxAllowableOffset only ever gets set by the QueryTask, not by the IdentifyTask.

Does this mean that MaxAllowableOffset is a global setting that is read by all geometry tasks, and has to be reset every time?


Also, there does not seem to be a way to set MaxAllowableOffset back to zero, as setting it to either zero or a negative value is ignored (I checked this via Fiddler - MaxAllowableOffset is not passed if set to a value <= 0).
So at the moment the only workaround I have found is to set it to a small value.


Cheers
Andrew
0 Kudos
JenniferNery
Esri Regular Contributor
IdentifyTask and QueryTask do not share parameters, so setting MaxAllowableOffset in one should not affect the other. Negative MaxAllowableOffset is not sent in the request so if the service use some MaxAllowableOffset when your app did not send it, it sounds like server issue. Do you get the same results when you run Identify and Query using REST end point from web browser?
0 Kudos
AndrewBiggins
New Contributor III
Hi Jennifer,

I'm not sure, how do I run Identify and Query using REST end point from a web browser?

Cheers, Andrew
0 Kudos
JenniferNery
Esri Regular Contributor
You can run Fiddler to see what parameters your app has for Identify and use them when you go to the IdentifyTask URL: http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer/id....
0 Kudos