ThinkGeo.com    |     Documentation    |     Premium Support

OgcApiFeatureLayer and LayerOverlay

Hi,

We have been using OgcApiFeatureLayer with LayerOverlay but with 14.3.1 release OgcApiFeatureSource implementation seems to be changed so that if network is disconnected after initial drawing next drawing causes infinite loop in GetFeaturesInsideBoundingBoxCore method.

Problem seems to be this while loop (exception is thrown and text2 is string.Empty => text is string.Empty => text != null is always false):

 protected override Collection<Feature> GetFeaturesInsideBoundingBoxCore(RectangleShape boundingBox, IEnumerable<string> returningColumnNames)
 {
     Collection<Feature> collection = new Collection<Feature>();
     string text = GetRequestUrlForFeatures(boundingBox, BulkSize);
     while (text != null)
     {
         string text2 = string.Empty;
         Collection<Feature> collection2 = new Collection<Feature>();
         ThinkGeoDebugger.Log("Sending Request to " + text, ThinkGeoLogType.WebRequest);
         try
         {
             (text2, collection2) = lSM_003D(text);
         }
         catch (Exception)
         {
         }

         collection.ixU_003D(collection2);
         text = text2;
     }

     return collection;
 }

This can be easily re-produced with OGCAPIFeatureServer HowDol sample by changing OgcApiFeaturesOverlay to LayerOverlay.

Is there any way to fix this issue since that infinite loop causes that OgcApiFeatureLayer stops working totally and do not recover even if network connection is restored. (We are using other layers on same LayerOverlay with OgcApiFeatureLayer so using OgcApiFeaturesOverlay is not viable option)

Br, Simo

Hi Simo,

This issue was recreated and fixed in the latest beta 14.5.0-beta057 and will be in the next stable release v14.5.0 in May. I’m afraid there’s no good way to work around it in v14.3.1 though.

Also just FYI we are planning to add the Async version sometime in the near future OgcApiAsyncLayer, and obsolete the current version gradually.

Thanks,
Ben

Hi,

I did check that fix and it works but since it catches the exception and returns empty collection if there is connection problem it will cause that empty tile is stored to tile cache (if used). I think that GetFeaturesInsideBoundingBoxCore should throw exception instead of suppressing it so that it could be then properly used by caller (drawn/suppressed/handled otherwise) ?

BTW, It seems that if I override GetFeaturesInsideBoundingBoxCore in v14.3 like this it would fix the infinite loop. (OgcApiFeaturesOverlay::DrawAsyncCore seems to use something like this. I just had to do some hack with ProjectionConverter so that it is not used on GetFeatures())

 protected override Collection<Feature> GetFeaturesInsideBoundingBoxCore(RectangleShape boundingBox, IEnumerable<string> returningColumnNames)
 {
     // Store converter so that it's not used inside GetFeatures()
     ProjectionConverter originalConverter = null;
     if (base.ProjectionConverter != null)
     {
         originalConverter = base.ProjectionConverter;
         base.ProjectionConverter = null;
     }

     Collection<Feature> collection = new Collection<Feature>();
     string text = base.GetRequestUrlForFeatures(boundingBox, base.BulkSize);

     try
     {
         while (text != null)
         {
             string text2 = string.Empty;
             Collection<Feature> collection2 = new Collection<Feature>();
             (text2, collection2) = base.GetFeatures(text);

             collection = new Collection<Feature>(collection.Concat(collection2).ToList());
             text = text2;
         }
     }
     finally
     {
         // Set converter back if it was used
         if (originalConverter != null)
             base.ProjectionConverter = originalConverter;
     }

     return collection;
 }

Do you see any problems in this kind of solution ? This does not catch the exception thrown by GetFeatures() so in our case exception is drawn correctly and no empty tiles on cache.

Br, Simo

Hi, Simo

Good Catch. Yes, it’s better to throw the exception in the layer/FeatureSource level instead of just swallowing it. I’ve updated the source and this change will be available in the next beta version. And your workaround code looks good as well!

A quick note here: By default the layer will draw and throw the internal exception. You can change it by setting layer.DrawingExceptionMode. For example you can set it to layer.DrawingExceptionMode = DrawingExceptionMode.ThrowException to avoid drawing the exception message on the map.

Thanks,
Ben