ThinkGeo.com    |     Documentation    |     Premium Support

MsSql2008FeatureLayer geography problem - any way to see more details?

I have a SQL Server 2008 table with geography. I can open the table in Microsoft SQL Server Management Studio & it shows that I have a geography data type as one of the fields.


I can also open the table in Sql Spatial Query Visualizer which I found here (as I couldn't get Map Suite Explorer to show SQL Server spatial data):


sharpgis.net/page/sql-server-2008-spatial-tools.aspx


The screen dump shows that the spatial data is good. I even took the precaution of making all the points <= 90° in both Lat & Long just in case I mixed them up somewhere later in the code. Each small '+' indicates one of my 362 rows in the table.



Now comes the problem - when I try to open up the table & view it in ThinkGeo desktop, the following line:


WinformsMap1.Refresh()


gives me an error:


A first chance exception of type 'System.Data.SqlClient.SqlException' occurred in MapSuiteCore.dll

03/11/2010 12:39:30 - LoadSQL2008Layer(): A .NET Framework error occurred during execution of user-defined routine or aggregate "geography": 

System.FormatException: 24201: Latitude values must be between -90 and 90 degrees.

System.FormatException: 

   at Microsoft.SqlServer.Types.GeographyValidator.ValidatePoint(Double x, Double y, Nullable`1 z, Nullable`1 m)

   at Microsoft.SqlServer.Types.Validator.BeginFigure(Double x, Double y, Nullable`1 z, Nullable`1 m)

   at Microsoft.SqlServer.Types.ForwardingGeoDataSink.BeginFigure(Double x, Double y, Nullable`1 z, Nullable`1 m)

   at Microsoft.SqlServer.Types.CoordinateReversingGeoDataSink.BeginFigure(Double x, Double y, Nullable`1 z, Nullable`1 m)

   at Microsoft.SqlServer.Types.OpenGisWktReader.ParseLineStringText()

   at Microsoft.SqlServer.Types.OpenGisWktReader.ParsePolygonText()

   at Microsoft.SqlServer.Types.OpenGisWktReader.ParseTaggedText(OpenGisType type)

   at Microsoft.SqlServer.Types.OpenGisWktReader.Read(OpenGisType type, Int32 srid)

   at Microsoft.SqlServer.Types.SqlGeography.GeographyFromText(OpenGisType type, SqlChars taggedText, Int32 srid)


I am pretty sure the geography is ok otherwise the other application would have spotted it and my code deliberately keeps everything within the proper bounds. Is there some way I can 'drill down' to find that actual Latitude value that is causing the problem in this WinformsMap1.Refresh()? Preferably also the record number, etc?


Thanks,


Dave




Just to confirm that there isn’t any bad geography I added the following code: 
  
 Dim OneFeature As Feature
Dim cownt As Integer
Dim fCollection As Collection(Of Feature) = sql2008Layer.FeatureSource.GetAllFeatures(ReturningColumnsType.AllColumns)
sql2008Layer.Open()
For cownt = 0 To fCollection.Count - 1
     OneFeature = fCollection.Item(cownt)
     If OneFeature.GetShape.GetCenterPoint.X > 90 Or OneFeature.GetShape.GetCenterPoint.X < -90 Then
          Debug.Print(OneFeature.GetShape.ToString)
     End If
     If OneFeature.GetShape.GetCenterPoint.Y > 90 Or OneFeature.GetShape.GetCenterPoint.Y < -90 Then
          Debug.Print(OneFeature.GetShape.ToString)
     End If
Next
sql2008Layer.Close()
 
  
 No debug info is printed - there are no Lat & Long outside +/-90°. Any other reason this error would appear?

David,


Thanks for your post.


Do you provide the full content of exception stack-trace? it seems they're only .Net framework call strack, I can find any clues for MapSuiteCore. Please provide more information and we will be easier to debug to find which method throw exception.


At the other hand, you can do the following test, you get all features from sql server and assign to a in memory layer to render.


            Dim inMemoryLayer As InMemoryFeatureLayer = New InMemoryFeatureLayer()
            inMemoryLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle.SymbolPen = New GeoPen(GeoColor.FromArgb(255, GeoColor.StandardColors.Green), 8)
            inMemoryLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20

            sql2008Layer.Open()
            Dim fCollection As Collection(Of Feature) = sql2008Layer.FeatureSource.GetAllFeatures(ReturningColumnsType.AllColumns)
            For Each feature As Feature In fCollection
                inMemoryLayer.InternalFeatures.Add(feature)
            Next
            sql2008Layer.Close()

            Dim inMemoryOverlay As New LayerOverlay()
            inMemoryOverlay.Layers.Add("InMemoryFeatureLayer", inMemoryLayer)
            winformsMap1.Overlays.Add("InMemoryOverlay", inMemoryOverlay)

            winformsMap1.Refresh()

Let us know if you find more clues


Thanks


James



Ok, when I add in your code I can actually see the geography though it is all shoved up in the top left corner of the map instead of in the middle which looks a bit suspicious, but it doesn't crash until later on when I have put the layer into the map window. This is a screen dump if I remove my line that does cause the crash (which also means I can't refresh the map every 1 second when the data changes).






Private Sub LoadSQL2008Layer()



        WinformsMap1.MapUnit = GeographyUnit.DecimalDegree

        WinformsMap1.CurrentExtent = New RectangleShape(-180, 90, -180, -90)

        WinformsMap1.BackgroundOverlay.BackgroundBrush = New GeoSolidBrush(GeoColor.GeographicColors.ShallowOcean)



        Dim connectString As String = "Integrated Security=SSPI;" + "Initial Catalog=Vessels2;" + "Data Source=CM\SQLEXPRESS;"

        Dim sql2008Layer As New MsSql2008FeatureLayer(connectString, "Vessels", "ID") 

        sql2008Layer.Srid = 4326

        sql2008Layer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.Country1

        sql2008Layer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20



        Dim inMemoryLayer As InMemoryFeatureLayer = New InMemoryFeatureLayer()

        inMemoryLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle.SymbolPen = New GeoPen(GeoColor.FromArgb(255, GeoColor.StandardColors.Green), 8)

        inMemoryLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20

        sql2008Layer.Open()

        Dim fCollection As Collection(Of Feature) = sql2008Layer.FeatureSource.GetAllFeatures(ReturningColumnsType.AllColumns)

        For Each feature As Feature In fCollection

            inMemoryLayer.InternalFeatures.Add(feature)

        Next

        sql2008Layer.Close()

        Dim inMemoryOverlay As New LayerOverlay()

        inMemoryOverlay.Layers.Add("InMemoryFeatureLayer", inMemoryLayer)

        WinformsMap1.Overlays.Add("InMemoryOverlay", inMemoryOverlay)

        WinformsMap1.Refresh() ' DOESN'T CRASH HERE



        Dim staticOverlay As New LayerOverlay()

        staticOverlay.Layers.Add("Sql2008Layer", sql2008Layer)

        WinformsMap1.Overlays.Add(staticOverlay)



        WinformsMap1.Refresh() ' STILL CRASHES HERE!!!!!!!!!!!



    End Sub




If I comment out the line:

WinformsMap1.Overlays.Add(staticOverlay)

then it doesn't crash.


When it does crash, here is the full crash dump:


A first chance exception of type 'System.Data.SqlClient.SqlException' occurred in MapSuiteCore.dll

System.Transactions Critical: 0 : <TraceRecord xmlns="schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Critical"><TraceIdentifier>msdn.microsoft.com/TraceCodes/System/ActivityTracing/2004/07/Reliability/Exception/Unhandled</TraceIdentifier><Description>Unhandled exception</Description><AppDomain>TestSQLServer2.vshost.exe</AppDomain><Exception><ExceptionType>System.Data.SqlClient.SqlException, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType><Message>A .NET Framework error occurred during execution of user-defined routine or aggregate "geography": 

System.FormatException: 24201: Latitude values must be between -90 and 90 degrees.

System.FormatException: 

   at Microsoft.SqlServer.Types.GeographyValidator.ValidatePoint(Double x, Double y, Nullable`1 z, Nullable`1 m)

   at Microsoft.SqlServer.Types.Validator.BeginFigure(Double x, Double y, Nullable`1 z, Nullable`1 m)

   at Microsoft.SqlServer.Types.ForwardingGeoDataSink.BeginFigure(Double x, Double y, Nullable`1 z, Nullable`1 m)

   at Microsoft.SqlServer.Types.CoordinateReversingGeoDataSink.BeginFigure(Double x, Double y, Nullable`1 z, Nullable`1 m)

   at Microsoft.SqlServer.Types.OpenGisWktReader.ParseLineStringText()

   at Microsoft.SqlServer.Types.OpenGisWktReader.ParsePolygonText()

   at Microsoft.SqlServer.Types.OpenGisWktReader.ParseTaggedText(OpenGisType type)

   at Microsoft.SqlServer.Types.OpenGisWktReader.Read(OpenGisType type, Int32 srid)

   at Microsoft.SqlServer.Types.SqlGeography.GeographyFromText(OpenGisType type, SqlChars taggedText, Int32 srid)

.</Message><StackTrace>   at ThinkGeo.MapSuite.Core.MsSql2008FeatureSource.x1e8067e880a0b849(RectangleShape x05576ac689f0c0df, Int32 x4a30a6ec9c7ff851, IEnumerable`1 x8ad42fcdfcf2a001)

   at ThinkGeo.MapSuite.Core.MsSql2008FeatureSource.GetFeaturesInsideBoundingBoxCore(RectangleShape boundingBox, IEnumerable`1 returningColumnNames)

   at ThinkGeo.MapSuite.Core.FeatureSource.GetFeaturesForDrawingCore(RectangleShape boundingBox, Double screenWidth, Double screenHeight, IEnumerable`1 returningColumnNames)

   at ThinkGeo.MapSuite.Core.FeatureSource.GetFeaturesForDrawing(RectangleShape boundingBox, Double screenWidth, Double screenHeight, IEnumerable`1 returningColumnNames)

   at ThinkGeo.MapSuite.Core.FeatureLayer.DrawCore(GeoCanvas canvas, Collection`1 labelsInAllLayers)

   at ThinkGeo.MapSuite.Core.Layer.Draw(GeoCanvas canvas, Collection`1 labelsInAllLayers)

   at ThinkGeo.MapSuite.DesktopEdition.LayerOverlay.DrawCore(GeoCanvas canvas)

   at ThinkGeo.MapSuite.DesktopEdition.Overlay.MainDraw(GeoCanvas canvas)

   at ThinkGeo.MapSuite.DesktopEdition.Overlay.Draw(GeoCanvas canvas)

   at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.x03e3d48bcfe7bb6c(IEnumerable`1 xa6f0db4f183189f1)

   at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.xff5b27c00f9678c2(RectangleShape x178b193eec228e6e)

   at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.xe3cee4adb9c72451()

   at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.x9ac8c50f434f4b39(Int32 xb565f4681f05557a)

   at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.Refresh()

   at WindowsApplication1.Form1.LoadSQL2008Layer() in C:\Users\User\documents\visual studio 2010\Projects\TestSQLServer2\TestSQLServer2\Form1.vb:line 339

   at WindowsApplication1.Form1.CheckBox1_CheckedChanged(Object sender, EventArgs e) in C:\Users\User\documents\visual studio 2010\Projects\TestSQLServer2\TestSQLServer2\Form1.vb:line 276

   at System.Windows.Forms.CheckBox.set_CheckState(CheckState value)

   at System.Windows.Forms.CheckBox.OnClick(EventArgs e)

   at System.Windows.Forms.CheckBox.OnMouseUp(MouseEventArgs mevent)

   at System.Windows.Forms.Control.WmMouseUp(Message&amp;amp; m, MouseButtons button, Int32 clicks)

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

   at System.Windows.Forms.ButtonBase.WndProc(Message&amp;amp; m)

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

   at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG&amp;amp; msg)

   at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)

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

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

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

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

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

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

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

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

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

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

   at System.Threading.ThreadHelper.ThreadStart()</StackTrace><ExceptionString>System.Data.SqlClient.SqlException (0x80131904): A .NET Framework error occurred during execution of user-defined routine or aggregate "geography": 

System.FormatException: 24201: Latitude values must be between -90 and 90 degrees.

System.FormatException: 

   at Microsoft.SqlServer.Types.GeographyValidator.ValidatePoint(Double x, Double y, Nullable`1 z, Nullable`1 m)

   at Microsoft.SqlServer.Types.Validator.BeginFigure(Double x, Double y, Nullable`1 z, Nullable`1 m)

   at Microsoft.SqlServer.Types.ForwardingGeoDataSink.BeginFigure(Double x, Double y, Nullable`1 z, Nullable`1 m)

   at Microsoft.SqlServer.Types.CoordinateReversingGeoDataSink.BeginFigure(Double x, Double y, Nullable`1 z, Nullable`1 m)

   at Microsoft.SqlServer.Types.OpenGisWktReader.ParseLineStringText()

   at Microsoft.SqlServer.Types.OpenGisWktReader.ParsePolygonText()

   at Microsoft.SqlServer.Types.OpenGisWktReader.ParseTaggedText(OpenGisType type)

   at Microsoft.SqlServer.Types.OpenGisWktReader.Read(OpenGisType type, Int32 srid)

   at Microsoft.SqlServer.Types.SqlGeography.GeographyFromText(OpenGisType type, SqlChars taggedText, Int32 srid)

.

   at ThinkGeo.MapSuite.Core.MsSql2008FeatureSource.x1e8067e880a0b849(RectangleShape x05576ac689f0c0df, Int32 x4a30a6ec9c7ff851, IEnumerable`1 x8ad42fcdfcf2a001)

   at ThinkGeo.MapSuite.Core.MsSql2008FeatureSource.GetFeaturesInsideBoundingBoxCore(RectangleShape boundingBox, IEnumerable`1 returningColumnNames)

   at ThinkGeo.MapSuite.Core.FeatureSource.GetFeaturesForDrawingCore(RectangleShape boundingBox, Double screenWidth, Double screenHeight, IEnumerable`1 returningColumnNames)

   at ThinkGeo.MapSuite.Core.FeatureSource.GetFeaturesForDrawing(RectangleShape boundingBox, Double screenWidth, Double screenHeight, IEnumerable`1 returningColumnNames)

   at ThinkGeo.MapSuite.Core.FeatureLayer.DrawCore(GeoCanvas canvas, Collection`1 labelsInAllLayers)

   at ThinkGeo.MapSuite.Core.Layer.Draw(GeoCanvas canvas, Collection`1 labelsInAllLayers)

   at ThinkGeo.MapSuite.DesktopEdition.LayerOverlay.DrawCore(GeoCanvas canvas)

   at ThinkGeo.MapSuite.DesktopEdition.Overlay.MainDraw(GeoCanvas canvas)

   at ThinkGeo.MapSuite.DesktopEdition.Overlay.Draw(GeoCanvas canvas)

   at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.x03e3d48bcfe7bb6c(IEnumerable`1 xa6f0db4f183189f1)

   at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.xff5b27c00f9678c2(RectangleShape x178b193eec228e6e)

   at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.xe3cee4adb9c72451()

   at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.x9ac8c50f434f4b39(Int32 xb565f4681f05557a)

   at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.Refresh()

   at WindowsApplication1.Form1.LoadSQL2008Layer() in C:\Users\User\documents\visual studio 2010\Projects\TestSQLServer2\TestSQLServer2\Form1.vb:line 339

   at WindowsApplication1.Form1.CheckBox1_CheckedChanged(Object sender, EventArgs e) in C:\Users\User\documents\visual studio 2010\Projects\TestSQLServer2\TestSQLServer2\Form1.vb:line 276

   at System.Windows.Forms.CheckBox.set_CheckState(CheckState value)

   at System.Windows.Forms.CheckBox.OnClick(EventArgs e)

   at System.Windows.Forms.CheckBox.OnMouseUp(MouseEventArgs mevent)

   at System.Windows.Forms.Control.WmMouseUp(Message&amp;amp; m, MouseButtons button, Int32 clicks)

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

   at System.Windows.Forms.ButtonBase.WndProc(Message&amp;amp; m)

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

   at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG&amp;amp; msg)

   at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)

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

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

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

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

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

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

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

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

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

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

   at System.Threading.ThreadHelper.ThreadStart()</ExceptionString><DataItems><Data><Key>HelpLink.ProdName</Key><Value>Microsoft SQL Server</Value></Data><Data><Key>HelpLink.ProdVer</Key><Value>10.50.1600</Value></Data><Data><Key>HelpLink.EvtSrc</Key><Value>MSSQLServer</Value></Data><Data><Key>HelpLink.EvtID</Key><Value>6522</Value></Data><Data><Key>HelpLink.BaseHelpUrl</Key><Value>go.microsoft.com/fwlink</Value></Data><Data><Key>HelpLink.LinkId</Key><Value>20476</Value></Data></DataItems></Exception></TraceRecord>

 



(Sorry about the code formatting mess there! I can see how to add code in Quick Reply but decided I wanted to add a picture & did a normal reply after copy/paste. Now I can’t edit the code block n my own message!) 
  
 Private Sub LoadSQL2008Layer()

        WinformsMap1.MapUnit = GeographyUnit.DecimalDegree

        WinformsMap1.CurrentExtent = New RectangleShape(-180, 90, -180, -90)
        WinformsMap1.BackgroundOverlay.BackgroundBrush = New GeoSolidBrush(GeoColor.GeographicColors.ShallowOcean)

        Dim connectString As String = “Integrated Security=SSPI;” + “Initial Catalog=Vessels2;” + “Data Source=CM\SQLEXPRESS;”
        Dim sql2008Layer As New MsSql2008FeatureLayer(connectString, “Vessels”, “ID”)
        sql2008Layer.Srid = 4326
        sql2008Layer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.Country1
        sql2008Layer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20

        Dim inMemoryLayer As InMemoryFeatureLayer = New InMemoryFeatureLayer()
        inMemoryLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle.SymbolPen = New GeoPen(GeoColor.FromArgb(255, GeoColor.StandardColors.Green), 8)
        inMemoryLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20
        sql2008Layer.Open()
        Dim fCollection As Collection(Of Feature) = sql2008Layer.FeatureSource.GetAllFeatures(ReturningColumnsType.AllColumns)
        For Each feature As Feature In fCollection
            inMemoryLayer.InternalFeatures.Add(feature)
        Next
        sql2008Layer.Close()
        Dim inMemoryOverlay As New LayerOverlay()
        inMemoryOverlay.Layers.Add(“InMemoryFeatureLayer”, inMemoryLayer)
        WinformsMap1.Overlays.Add(“InMemoryOverlay”, inMemoryOverlay)
        WinformsMap1.Refresh() ’ DOESN’T CRASH HERE

        Dim staticOverlay As New LayerOverlay()
        staticOverlay.Layers.Add(“Sql2008Layer”, sql2008Layer)
        WinformsMap1.Overlays.Add(staticOverlay)

        WinformsMap1.Refresh() ’ CRASHES HERE!!!

    End Sub


David,


Thanks for your post and code snippets to help us to understand the problem.
I think the data stored in the SQL server should be some points, while I see in the code provided you set the AreaStyle for your sql2008Layer instead of PointStyle, am I misunderstanding something here?
Can you have a quick test against the following code snippet to see if any debug info was ouput?

 

Dim connectString As String = "Integrated Security=SSPI;" + "Initial Catalog=Vessels2;" + "Data Source=CM\SQLEXPRESS;"
Dim sql2008Layer As New MsSql2008FeatureLayer(connectString, "Vessels", "ID")
sql2008Layer.Srid = 4326
sql2008Layer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.Country1
sql2008Layer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20
sql2008Layer.Open()
Dim fCollection1 As Collection(Of Feature) = sql2008Layer.FeatureSource.GetAllFeatures(ReturningColumnsType.AllColumns)
For Each feature As Feature In fCollection1
    Dim pointShape As PointShape = DirectCast(feature.GetShape(), PointShape)
    If pointShape.X > 90 Or pointShape.X < -90 Then
        Debug.Print(pointShape.ToString)
    End If
    If pointShape.Y > 90 Or pointShape.Y < -90 Then
        Debug.Print(pointShape.ToString)
    End If
Next
 
Dim fCollection2 As Collection(Of Feature) = sql2008Layer.FeatureSource.GetFeaturesForDrawing(winformsMap1.CurrentExtent, winformsMap1.Width, winformsMap1.Height, ReturningColumnsType.AllColumns)
For Each feature As Feature In fCollection2
    Dim pointShape As PointShape = DirectCast(feature.GetShape(), PointShape)
    If pointShape.X > 90 Or pointShape.X < -90 Then
        Debug.Print(pointShape.ToString)
    End If
    If pointShape.Y > 90 Or pointShape.Y < -90 Then
        Debug.Print(pointShape.ToString)
    End If
Next
 
sql2008Layer.Close()

Any more questions please feel free to let me know.



Thanks.
Yale

Oops - I did miss out the point style - I added that in: 
  
 sql2008Layer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle.SymbolPen = New GeoPen(GeoColor.FromArgb(255, GeoColor.StandardColors.Green), 8) 
  
 but it didn’t make any difference - still crashes with same symptoms. 
  
 That snippet you provided above crashes at the line: 
  
 Dim fCollection2 As Collection(Of Feature) = sql2008Layer.FeatureSource.GetFeaturesForDrawing(winformsMap1.CurrentExtent, winformsMap1.Width, winformsMap1.Height, ReturningColumnsType.AllColumns) 
  
 with the same error as before: 
  
 A first chance exception of type ‘System.Data.SqlClient.SqlException’ occurred in System.Data.dll 
 A first chance exception of type ‘System.Data.SqlClient.SqlException’ occurred in MapSuiteCore.dll 
 System.Transactions Critical: 0 : <TraceRecord xmlns=“schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord” Severity=“Critical”><TraceIdentifier>msdn.microsoft.com/TraceCodes/System/ActivityTracing/2004/07/Reliability/Exception/Unhandled</TraceIdentifier><Description>Unhandled exception</Description><AppDomain>TestSQLServer2.vshost.exe</AppDomain><Exception><ExceptionType>System.Data.SqlClient.SqlException, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType><Message>A .NET Framework error occurred during execution of user-defined routine or aggregate “geography”:  
 System.FormatException: 24201: Latitude values must be between -90 and 90 degrees. 
 System.FormatException:  
    at Microsoft.SqlServer.Types.GeographyValidator.ValidatePoint(Double x, Double y, Nullable`1 z, Nullable`1 m) 
    at Microsoft.SqlServer.Types.Validator.AddLine(Double x, Double y, Nullable`1 z, Nullable`1 m) 
    at Microsoft.SqlServer.Types.ForwardingGeoDataSink.AddLine(Double x, Double y, Nullable`1 z, Nullable`1 m) 
    at Microsoft.SqlServer.Types.CoordinateReversingGeoDataSink.AddLine(Double x, Double y, Nullable`1 z, Nullable`1 m) 
    at Microsoft.SqlServer.Types.OpenGisWktReader.ParseLineStringText() 
    at Microsoft.SqlServer.Types.OpenGisWktReader.ParsePolygonText() 
    at Microsoft.SqlServer.Types.OpenGisWktReader.ParseTaggedText(OpenGisType type) 
    at Microsoft.SqlServer.Types.OpenGisWktReader.Read(OpenGisType type, Int32 srid) 
    at Microsoft.SqlServer.Types.SqlGeography.GeographyFromText(OpenGisType type, SqlChars taggedText, Int32 srid) 
 .</Message><StackTrace>   at ThinkGeo.MapSuite.Core.MsSql2008FeatureSource.x1e8067e880a0b849(RectangleShape x05576ac689f0c0df, Int32 x4a30a6ec9c7ff851, IEnumerable`1 x8ad42fcdfcf2a001) 
    at ThinkGeo.MapSuite.Core.MsSql2008FeatureSource.GetFeaturesInsideBoundingBoxCore(RectangleShape boundingBox, IEnumerable`1 returningColumnNames) 
    at ThinkGeo.MapSuite.Core.FeatureSource.GetFeaturesForDrawingCore(RectangleShape boundingBox, Double screenWidth, Double screenHeight, IEnumerable`1 returningColumnNames) 
    at ThinkGeo.MapSuite.Core.FeatureSource.GetFeaturesForDrawing(RectangleShape boundingBox, Double screenWidth, Double screenHeight, IEnumerable`1 returningColumnNames) 
    at ThinkGeo.MapSuite.Core.FeatureSource.GetFeaturesForDrawing(RectangleShape boundingBox, Double screenWidth, Double screenHeight, ReturningColumnsType returningColumnNamesType) 
    at WindowsApplication1.Form1.testsub() in C:\Users\User\documents\visual studio 2010\Projects\TestSQLServer2\TestSQLServer2\Form1.vb:line 369 
    at WindowsApplication1.Form1.CheckBox1_CheckedChanged(Object sender, EventArgs e) in C:\Users\User\documents\visual studio 2010\Projects\TestSQLServer2\TestSQLServer2\Form1.vb:line 276 
    at System.Windows.Forms.CheckBox.set_CheckState(CheckState value) 
    at System.Windows.Forms.CheckBox.OnClick(EventArgs e) 
    at System.Windows.Forms.CheckBox.OnMouseUp(MouseEventArgs mevent) 
    at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks) 
    at System.Windows.Forms.Control.WndProc(Message& m) 
    at System.Windows.Forms.ButtonBase.WndProc(Message& m) 
    at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) 
    at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) 
    at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData) 
    at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context) 
    at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context) 
    at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun() 
    at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel() 
    at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine) 
    at WindowsApplication1.My.MyApplication.Main(String[] Args) in 17d14f5c-a337-4978-8281-53493378c1071.vb:line 81 
    at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) 
    at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
    at System.Threading.ThreadHelper.ThreadStart()</StackTrace><ExceptionString>System.Data.SqlClient.SqlException (0x80131904): A .NET Framework error occurred during execution of user-defined routine or aggregate “geography”:  
 System.FormatException: 24201: Latitude values must be between -90 and 90 degrees. 
 System.FormatException:  
    at Microsoft.SqlServer.Types.GeographyValidator.ValidatePoint(Double x, Double y, Nullable`1 z, Nullable`1 m) 
    at Microsoft.SqlServer.Types.Validator.AddLine(Double x, Double y, Nullable`1 z, Nullable`1 m) 
    at Microsoft.SqlServer.Types.ForwardingGeoDataSink.AddLine(Double x, Double y, Nullable`1 z, Nullable`1 m) 
    at Microsoft.SqlServer.Types.CoordinateReversingGeoDataSink.AddLine(Double x, Double y, Nullable`1 z, Nullable`1 m) 
    at Microsoft.SqlServer.Types.OpenGisWktReader.ParseLineStringText() 
    at Microsoft.SqlServer.Types.OpenGisWktReader.ParsePolygonText() 
    at Microsoft.SqlServer.Types.OpenGisWktReader.ParseTaggedText(OpenGisType type) 
    at Microsoft.SqlServer.Types.OpenGisWktReader.Read(OpenGisType type, Int32 srid) 
    at Microsoft.SqlServer.Types.SqlGeography.GeographyFromText(OpenGisType type, SqlChars taggedText, Int32 srid) 
 . 
    at ThinkGeo.MapSuite.Core.MsSql2008FeatureSource.x1e8067e880a0b849(RectangleShape x05576ac689f0c0df, Int32 x4a30a6ec9c7ff851, IEnumerable`1 x8ad42fcdfcf2a001) 
    at ThinkGeo.MapSuite.Core.MsSql2008FeatureSource.GetFeaturesInsideBoundingBoxCore(RectangleShape boundingBox, IEnumerable`1 returningColumnNames) 
    at ThinkGeo.MapSuite.Core.FeatureSource.GetFeaturesForDrawingCore(RectangleShape boundingBox, Double screenWidth, Double screenHeight, IEnumerable`1 returningColumnNames) 
    at ThinkGeo.MapSuite.Core.FeatureSource.GetFeaturesForDrawing(RectangleShape boundingBox, Double screenWidth, Double screenHeight, IEnumerable`1 returningColumnNames) 
    at ThinkGeo.MapSuite.Core.FeatureSource.GetFeaturesForDrawing(RectangleShape boundingBox, Double screenWidth, Double screenHeight, ReturningColumnsType returningColumnNamesType) 
    at WindowsApplication1.Form1.testsub() in C:\Users\User\documents\visual studio 2010\Projects\TestSQLServer2\TestSQLServer2\Form1.vb:line 369 
    at WindowsApplication1.Form1.CheckBox1_CheckedChanged(Object sender, EventArgs e) in C:\Users\User\documents\visual studio 2010\Projects\TestSQLServer2\TestSQLServer2\Form1.vb:line 276 
    at System.Windows.Forms.CheckBox.set_CheckState(CheckState value) 
    at System.Windows.Forms.CheckBox.OnClick(EventArgs e) 
    at System.Windows.Forms.CheckBox.OnMouseUp(MouseEventArgs mevent) 
    at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks) 
    at System.Windows.Forms.Control.WndProc(Message& m) 
    at System.Windows.Forms.ButtonBase.WndProc(Message& m) 
    at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) 
    at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) 
    at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData) 
    at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context) 
    at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context) 
    at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun() 
    at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel() 
    at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine) 
    at WindowsApplication1.My.MyApplication.Main(String[] Args) in 17d14f5c-a337-4978-8281-53493378c1071.vb:line 81 
    at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) 
    at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
    at System.Threading.ThreadHelper.ThreadStart()</ExceptionString><DataItems><Data><Key>HelpLink.ProdName</Key><Value>Microsoft SQL Server</Value></Data><Data><Key>HelpLink.ProdVer</Key><Value>10.50.1600</Value></Data><Data><Key>HelpLink.EvtSrc</Key><Value>MSSQLServer</Value></Data><Data><Key>HelpLink.EvtID</Key><Value>6522</Value></Data><Data><Key>HelpLink.BaseHelpUrl</Key><Value>go.microsoft.com/fwlink</Value></Data><Data><Key>HelpLink.LinkId</Key><Value>20476</Value></Data></DataItems></Exception></TraceRecord> 
  
 (Note that all of this topic is using VB 2010 with ThinkGeo 4.5.0.0 - I upgraded from 4.0 since my previous problem which was solved this morning.)

David,


Just curious how the table was created and how those features was imported? Did you get it indexed on the SQL server?
Thanks.
Yale

The database & table were created using VB2010 also. I got some of the code from here: 
 vbdotnetheaven.com/UploadFile/mahesh/CreateSQLDatabase04252005064419AM/CreateSQLDatabase.aspx 
 and added in the geography parts myself. I haven’t done any indexing but have a primary key. 
  
 Private Sub CreateDBBtn_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CreateDBBtn.Click

        ‘This method creates a new SQL Server database

        ’ Create a connection
        conn = New SqlConnection(ConnectionString)
        ’ Open the connection
        If conn.State <> ConnectionState.Open Then
            conn.Open()
        End If
        Dim sql As String = “CREATE DATABASE Vessels2 ON PRIMARY” + “(Name=test_data, filename = ‘C:\mysql\Vessels2_data.mdf’, size=3,” + “maxsize=5, filegrowth=10%)log on” + “(name=Vessels2b_log, filename=‘C:\mysql\Vessels2_log.ldf’,size=3,” + “maxsize=20,filegrowth=1)”
        ExecuteSQLStmt(sql)

End Sub

Private Sub CreateTableBtn_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CreateTableBtn.Click

        Dim cownt As Integer
        Dim cownt1 As Integer
        Dim cownt2 As Integer

        ’ Open the connection
        If conn.State = ConnectionState.Open Then
            conn.Close()
        End If
        ConnectionString = “Integrated Security=SSPI;” + “Initial Catalog=Vessels2;” + “Data Source=CM\SQLEXPRESS;”
        conn.ConnectionString = ConnectionString
        conn.Open()
        sql = “CREATE TABLE Vessels” + "(ID INTEGER CONSTRAINT PKeyMyId PRIMARY KEY, " + “Name CHAR(254), UseMe BIT, VLat FLOAT, VLon FLOAT, VDateTime datetime, VSpd FLOAT, VCMG FLOAT, MaxSpeedEver FLOAT, WGS84Loc Geography)”
        cmd = New SqlCommand(sql, conn)
        cmd.ExecuteNonQuery()

        For cownt = -90 To 90
            cownt1 = cownt + 90
            cownt2 = -cownt
            sql = "INSERT INTO Vessels(ID, Name, UseMe, VLon, VLat, VCMG, VDateTime, WGS84Loc) " + “VALUES (0” + cownt1.ToString(“000”) + ", ‘Vessel " + cownt1.ToString + "a’, 1, " + (2 * cownt).ToString + ", " + cownt.ToString + ", " + cownt1.ToString + “, '” + DateTime.UtcNow.ToString(“s”) + "’, ‘POINT(" + (2 * cownt).ToString + " " + cownt.ToString + ")’) "
            sql = "INSERT INTO Vessels(ID, Name, UseMe, VLon, VLat, VCMG, VDateTime, WGS84Loc) " + “VALUES (0” + cownt1.ToString(“000”) + ", ‘Vessel " + cownt1.ToString + "a’, 1, " + (1 * cownt).ToString + ", " + cownt.ToString + ", " + cownt.ToString + “, '” + DateTime.UtcNow.ToString(“s”) + “’, 'POINT(” + (1 * cownt).ToString + " " + cownt.ToString + ")’) "
            cmd = New SqlCommand(sql, conn)
            cmd.ExecuteNonQuery()
            sql = "INSERT INTO Vessels(ID, Name, UseMe, VLon, VLat, VCMG, VDateTime, WGS84Loc) " + “VALUES (1” + cownt1.ToString(“000”) + ", ‘Vessel " + cownt1.ToString + "b’, 1, " + (2 * cownt).ToString + ", " + cownt2.ToString + ", " + cownt1.ToString + “, '” + DateTime.UtcNow.ToString(“s”) + “’, 'POINT(” + (2 * cownt).ToString + " " + cownt2.ToString + ")’) "
            sql = "INSERT INTO Vessels(ID, Name, UseMe, VLon, VLat, VCMG, VDateTime, WGS84Loc) " + “VALUES (1” + cownt1.ToString(“000”) + ", ‘Vessel " + cownt1.ToString + "b’, 1, " + (1 * cownt).ToString + ", " + cownt.ToString + “, " + cownt.ToString + “, '” + DateTime.UtcNow.ToString(“s”) + “’, 'POINT(” + (1 * cownt).ToString + " " + cownt2.ToString + “)’) "
            cmd = New SqlCommand(sql, conn)
            cmd.ExecuteNonQuery()
        Next

        MessageBox.Show(“CreateTableBtn_Click done”)

End Sub
 
  
 I have another routine which moves all the points around randomly: 
  
 Private Sub btnChangePositions_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnChangePositions.Click

        Dim cownt As Integer

        Dim SQLString As String

        If conn.State = ConnectionState.Open Then
            conn.Close()
        End If
        ‘ConnectionString = “Integrated Security=SSPI;” + “Initial Catalog=Vessels2;” + “Data Source=localhost;”
        ConnectionString = “Integrated Security=SSPI;” + “Initial Catalog=Vessels2;” + “Data Source=CM\SQLEXPRESS;”
        conn.ConnectionString = ConnectionString
        conn.Open()

        ’ Change the positions of the spatial data in the table.
        ’ Do we have to do it one row at a time? Probably best to do it that way as that is the way it will be done in MVMSuite anyway.
        ’ We have ID of 0 to 180 and 1000 to 1180
        For cownt = 0 To 180
            SQLString = “'POINT(” + (-180 + Rnd() * 360).ToString + " " + (-90 + Rnd() * 180).ToString + ")’”
            SQLString = “'POINT(” + (-90 + Rnd() * 180).ToString + " " + (-90 + Rnd() * 180).ToString + “)’”
            sql = “UPDATE Vessels SET WGS84Loc=” + SQLString + “, VCMG=” + cownt.ToString + " WHERE ID=” + cownt.ToString
            cmd = New SqlCommand(sql, conn)
            cmd.ExecuteNonQuery()
        Next
        For cownt = 1000 To 1180
            SQLString = “'POINT(” + (-180 + Rnd() * 360).ToString + " " + (-90 + Rnd() * 180).ToString + “)’”
            SQLString = “'POINT(” + (-90 + Rnd() * 180).ToString + " " + (-90 + Rnd() * 180).ToString + “)’”
            sql = “UPDATE Vessels SET WGS84Loc = " + SQLString + “, VCMG=” + (-1000 + cownt).ToString + " WHERE ID=” + cownt.ToString
            cmd = New SqlCommand(sql, conn)
            cmd.ExecuteNonQuery()
        Next

End Sub


I have attached the whole project. It is a bit messy as I only made it to test creating a SQL Server spatial database & to display it in a Thinkgeo map, all in code.


To use it, run it & click 'Create DB'. If the database already exists it will tell you. Once the database is created it is not necessary to press that button in subsequent runs. Initially the data is created in 2 long lines & can be viewed by SQL Spatial Query Visualizer which is refered to a few times in this forum.


You can press View Data at any time to view the table data.


Checking the 'Change positions every 1 second' checkbox causes the table to have the 362 points change their geography position every 1 second. The idea was to have the map similarly update every 1 second to reflect the change in data.


If I get it working it might make a nice self-contained project to allow creation & display of MS SQL 2008 data using VB 2010. I don't think there are any similar projects online.


Dave



TestSQLServer2.zip (339 KB)

David, 
  
 Could you check the attached TestSQLServer.zip? It’s just a form without any code, I think probably you upload the wrong file. 
  
 Thanks 
 James 
  


Oops - I was wondering why it was so small! Correct version attached now - I had to remove the 2 thinkgeo dll & xml files to make it small enough to attach.

David, 
  
 Thanks for your update, I got the corrent one right now. We are working on this issue and I will let you know if we fix it. 
  
 James

David,


We found the reason, actually there are a couple things caused your problem.


First, your code is wrong WinformsMap1.CurrentExtent = New RectangleShape(-180, 90, -180, -90), the minX is equal to maxX.


Second, even change to (-180, 90, 180, -90), the result of current extent will be different from input, because it will keep the same ratio as map width/height, if you call ExtentHelper.GetDrawingExtent(extent, (float)WinformsMap1.Width, (float)WinformsMap1.Height)) to get the value.


Thrid, it still not the final result of current extent, because this drawing extent might not on a certain zoom level, you call ExtentHelper.SnapToZoomLevel(extent, GeographyUnit.DecimalDegree, (float)WinformsMap1.Width, (float)WinformsMap1.Height, new ZoomLevelSet()), at this time, you can check the value, it might greater than 90.


Why InMemoryLayer is working? Because there is no validator to check the input bounding box, but in MsSql2008Layer, it will input bounding box to MS SQL server to get data, at this time, microsoft validates the value and throw exception like you see.


My suggestion is that you set to correct current extent to pass the sql server validator, you can call WinformsMap1.CurrentExtent.ZoomIn(50) or set smaller extent directly.


Please let me know if you have better idea.


Thanks


James


 



Ok, I did a quick test by changing the extents to: 
  
 WinformsMap1.CurrentExtent = New RectangleShape(-90, 55, 90, -55) 
  
 That works (until I zoom out too far). Now I have to figure out these Extents - I am coming from 15 years with MapInfo and a few with Manifold so Extents are new to me and I haven’t quite got my head around them yet.

David,


I noticed we are having a hot discussion in the following post regarding the extent, and I think our GIS expert Val gave a very detailed description about it, I really learnt a lot from it.
gis.thinkgeo.com/Support/DiscussionForums/tabid/143/aff/21/aft/8313/afv/topic/Default.aspx
Any more questions please feel free to let me know.
Thanks.
Yale

James, could you please elaborate on that a little more? What is considered the “correct current extent”?

What if the current extent is showing somewhere off the edge of the world? I am not really sure what us being passed to the SQL server validator & why. My points are not changing - only the map extents are changing and it would not be unusual for the operator to pan off the edge of the world occasionally.

I am interested in what is going on ‘behind the scenes’ here.

Thanks,

Dave



 Posted By James on 11-04-2010 03:15 AM 

My suggestion is that you set to correct current extent to pass the sql server validator, you can call WinformsMap1.CurrentExtent.ZoomIn(50) or set smaller extent directly.

Please let me know if you have better idea.


Thanks


James


 



 



David,


Thanks for your patience, Please look at this post:


gis.thinkgeo.com/Support/Dis...fault.aspx


Any more questions please feel free to let me know.


Thanks.


James