ThinkGeo.com    |     Documentation    |     Premium Support

GetBoundingBox intermittent exception

Hello,



I get this exception around ~10% of the time I run the application:



MapSuiteSetup failedSystem.InvalidOperationException: The FeatureSource is not open.   Please call the Open method before calling this method.



   at ThinkGeo.MapSuite.Core.InMemoryFeatureSource.GetAllFeaturesCore(IEnumerable`1 returningColumnNames)



   at ThinkGeo.MapSuite.Core.FeatureSource.GetBoundingBoxCore()



   at ThinkGeo.MapSuite.Core.FeatureSource.GetBoundingBox()



   at ThinkGeo.MapSuite.Core.FeatureLayer.GetBoundingBoxCore()



   at ThinkGeo.MapSuite.Core.Layer.GetBoundingBox()



   at ThinkGeo.MapSuite.WpfDesktopEdition.LayerOverlay.GetBoundingBoxCore()



   at ThinkGeo.MapSuite.WpfDesktopEdition.Overlay.GetBoundingBox()



This is the code it's running: 

totalBoundingBox1 = layerOverlayForGraphics.GetBoundingBox();

Where layerOverlayForGraphics is LayerOverlay with 3 InMemoryLayers added like this:

                layerOverlayForGraphics.Layers.Add("inmem2", inMemoryLayer2);

                layerOverlayForGraphics.Layers.Add("inmem3", inMemoryLayer3);

                layerOverlayForGraphics.Layers.Add("inmem", inMemoryLayer);



I then tried opening all of the and still get the same error once in a while

                layerOverlayForGraphics.Layers[0].Open();

                layerOverlayForGraphics.Layers[1].Open();

                layerOverlayForGraphics.Layers[2].Open();

                totalBoundingBox1 = layerOverlayForGraphics.GetBoundingBox();

                layerOverlayForGraphics.Layers[0].Close();

                layerOverlayForGraphics.Layers[1].Close();

                layerOverlayForGraphics.Layers[2].Close();



I'm on Map Suite Wpf Desktop Full Edition 5.0

any ideas?



thanks

Thomas

 



Thomas, 
  
 I just want to verify if this problem is caused by multi-threading cross calling, so that could you set layerOverlayForGraphics.TileType = TileType.SingleTile; and have another try. Please let me know your testing result. 
  
 Thanks, 
 James

James,


Thanks.  That seems to fix it.  I presume this change impacts performance?  What could be causing this?  Any other work-arounds?


thanks


Thomas



Thomas, 
  
 I think when you use LayerOverlay, the default setting is MultiTile which using multi-threadings, to avoid threading crossing call, you can add lock() block the GetBoundingBox method. 
  
 Thanks, 
  
 James

James,


Thanks.  But why is that?  I mean it seems to occur only at start of the application.  Do I have to lock every time I call that function?


thanks


Thomas



Thomas, 
  
 I think the reason that the error only occur at start of the application is that when you start application, it will draw tiles with multi-threading, each tile will open and close layer in worker threading, meanwhile you can layer.GetBoundingBox. After that you call layer.GetBoundingBox after each operation such as pan, zoom in/out finished, you can try to call it during the map drawing, I think it will has the same error. 
  
 You don’t need to call that function every time, you can set overlay.LockLayerMode = LockLayerMode.Lock; 
  
 Thanks, 
  
 James

James,


I tried locking on the overlay and it still has the exception sometimes at the start.


I will try overlay.LockLayerMode = LockLayerMode.Lock;


thanks


Thomas



Thomas, 



Could you try to do like this, override the GetAllFeaturesCore method as following code:



    public class CustomInMemoryFeatureSource : InMemoryFeatureSource


    {


        protected override Collection<Feature> GetAllFeaturesCore(IEnumerable<string> returningColumnNames)


        {


            Collection<Feature> returnFeatures = new Collection<Feature>();


            foreach (Feature feature in InternalFeatures)


            {


                Feature newFeature = GetClonedFeature(feature, returningColumnNames);


                returnFeatures.Add(newFeature);


            }


 


            return returnFeatures;


        }


 


        private static Feature GetClonedFeature(Feature feature, IEnumerable<string> returningColumnNames)


        {


            Dictionary<string, string> columnValues = new Dictionary<string, string>();


            foreach (string columnName in returningColumnNames)


            {


                if (feature.ColumnValues.ContainsKey(columnName))


                {


                    columnValues.Add(columnName, feature.ColumnValues[columnName]);


                }


                else


                {


                    columnValues.Add(columnName, string.Empty);


                }


            }


            byte[] wellKnownBinary = feature.GetWellKnownBinary();


            byte[] projectedWellKnownBinary = new byte[wellKnownBinary.Length];


            Buffer.BlockCopy(wellKnownBinary, 0, projectedWellKnownBinary, 0, wellKnownBinary.Length);


            Feature insideFeature = new Feature(projectedWellKnownBinary, feature.Id, columnValues);


            insideFeature.Tag = feature.Tag;


            return insideFeature;


        }


    }


Thanks,


James


<string></string>



James,


Thanks I will.  Am I doing something unusual for this to occur?


thanks


Thomas



James, 
  
 I also sometimes get it when loading a shapefile and getting its bounding box 
  
 ShapeFileFeatureLayer x= new ShapeFileFeatureLayer(dlg.FileName); 
 … 
 rs = x.GetBoundingBox(); 
 … 
 thanks 
 Thomas

Thomas, 
  
 The code you provided is usual, but I don’t know there is any other unusual code to cause this problem. 
  
 About ShapeFileFeatureLayer, I think you get another problem, because GetBoundingBox() of it won’t call GetAllFeatureCore, the stack-trace should be different. 
  
 Just keep in communication to figure out the really problem eventually. 
  
 Thanks, 
 James