ThinkGeo.com    |     Documentation    |     Premium Support

Problem with GetBoundingBox on MsSql2008FeatureLayer

Hi,


I am using the full version of MSD, 5.0.0.0.


Ever since I upgraded to this version I get the following error when I try to use method GetBoundingBox on MsSql2008FeatureLayer:


System.InvalidCastException was unhandled

  Message=Unable to cast object of type 'System.DBNull' to type 'System.Byte[]'.

  Source=MapSuiteCore

  StackTrace:

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

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

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

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

       at Post7709Sample.Form1.Form1_Load(Object sender, EventArgs e) in C:\Users\steller\Documents\Visual Studio 2010\Projects\ThinkGeo\7709 Sample\Post7709Sample\Form1.vb:line 19

       at System.EventHandler.Invoke(Object sender, EventArgs e)

       at System.Windows.Forms.Form.OnLoad(EventArgs e)

       at System.Windows.Forms.Form.OnCreateControl()

       at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)

       at System.Windows.Forms.Control.CreateControl()

       at System.Windows.Forms.Control.WmShowWindow(Message& m)

       at System.Windows.Forms.Control.WndProc(Message& m)

       at System.Windows.Forms.ScrollableControl.WndProc(Message& m)

       at System.Windows.Forms.ContainerControl.WndProc(Message& m)

       at System.Windows.Forms.Form.WmShowWindow(Message& m)

       at System.Windows.Forms.Form.WndProc(Message& m)

       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)

       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)

       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

       at System.Windows.Forms.SafeNativeMethods.ShowWindow(HandleRef hWnd, Int32 nCmdShow)

       at System.Windows.Forms.Control.SetVisibleCore(Boolean value)

       at System.Windows.Forms.Form.SetVisibleCore(Boolean value)

       at System.Windows.Forms.Control.set_Visible(Boolean value)

       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)

       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)

       at System.Windows.Forms.Application.Run(ApplicationContext context)

       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()

       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()

       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)

       at Post7709Sample.My.MyApplication.Main(String[] Args) in 17d14f5c-a337-4978-8281-53493378c1071.vb:line 81

       at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)

       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)

       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()

       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)

       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)

       at System.Threading.ThreadHelper.ThreadStart()

  InnerException:


Here is the code:



Dim sConnect As String = "SERVER=server;Database=database;UID=sa;PWD=pwd"
Dim oSQLLayer As New MsSql2008FeatureLayer(sConnect, "TRACT", "OBJECTID", 26916)

oSQLLayer.Open()

Dim staticOverlay As New LayerOverlay()
staticOverlay.Layers.Add("TRACT", oSQLLayer)
WinformsMap1.Overlays.Add(staticOverlay)
WinformsMap1.CurrentExtent = oSQLLayer.GetBoundingBox()
   Is this a bug?  


Thanks,  


Steve



 Steve,


 
Thanks for your questions!
 
According to the stack track, I guessed maybe there are any records is invalid or null. So it caused the System.DBNull exception, I reviewed the core code according to the stack trace what you provided and I found out where is the code to cause this exception, here is the code line below:
 
while (dataReader.Read())
{
      shape.LoadFromWellKnownData((byte[])dataReader[0]);
}
 
Obviously, when executing the cast operation, it found out the dataReader[0] object is null object so it caused the InvalidCast exception. Please review your source data again and make sure the source data is correct completely.
 
Thanks,
 
Scott,

Hi Scott,


Thanks for the reply!


I checked my data and it turns out that some of the features in my MsSql2008FeatureLayer have null for shape. So now I understand why I'm getting the exception when I call GetBoundingBox.


However, that's not how I think it should work. I would suggest that when the core code executes it should check for null values and eliminate them, returning a bounding box consisting of all features that have spatial data that is not null. We have applications in which we often have some tabular data for a geographical location long before we can define its shape. Therefore, for us, having a null for spatial data is not an error condition. I'm sure you'll find that's true for many of your customers.


And that brings me to another discovery I made while investigation this issue. I devised a workaround for when GetBoundingBox throws and exception. Here it is:



Private Function mBoundingBoxFromFeatureExtents() As RectangleShape
   Dim oFeatures As Collection(Of Feature) = QueryTools.GetAllFeatures(ReturningColumnsType.NoColumns)
   Dim oBoundingBox As RectangleShape = Nothing

   For Each oFeature As Feature In oFeatures
      If oBoundingBox Is Nothing Then
         oBoundingBox = oFeature.GetBoundingBox
      Else
         oBoundingBox.ExpandToInclude(oFeature.GetBoundingBox)
      End If
   Next oFeature
   Return oBoundingBox
End Function


The reason this works is that when I use GetAllFeatures the collection of Features it returns only has features with spatial data that is not null. This surprised me a little as I would expect ALL features to be returned, not just thos with spatial data, in case I need to add spatial data to a feature that does not have it yet. Again, it would be nice if GetAllFeatures could reteurn all the features and not just those with spatial data.


These suggetions are not meant as a complaint. I like the ThinkGEO products very much, only making some observations based on our needs.


Thanks!


Steve


 


 



 "However, that’s not how I think it should work. I would suggest that when the core code executes it should check for null values and eliminate them, returning a bounding box consisting of all features that have spatial data that is not null."

I will second that!



Steven & David, 
  
 Thanks for your suggestions! 
  
 I think it is a great suggestion and improvement for us and I just added it to our issue list, our development team will work on it. Any updates I will let you know, 
  
 Thanks, 
  
 Scott,

Steven & David, 
  
 The problem had been fixed yet, please get the latest version to try again,  
  
 In addition, thanks for your good suggestions for this part, 
  
 Any more questions please let me know, 
  
 Scott,