ThinkGeo.com    |     Documentation    |     Premium Support

MsSql2008FeatureLayer SQL Error - Latitude values must be between -90 and 90 degrees

Hi,


I have a question about using the MsSQL2008FeatureLayer.  I'm encountoring an unhandled exception and wondered if it is something that I'm doing wrong or possibly a code issue.  The layer appears to connect to the database and work correctly except when the user pans the map to the north or south extent of the map.  At that point Map Suite will throw a SQL exception indicating that SQL Server is expecting latitude values between 90 and -90 degrees (full details at end of post below.)  I ran a trace on the SQL server and this is the query coming from Map Suite that is triggering the error:


exec sp_executesql N'SELECT GeographySpatial.STAsBinary() as GeographySpatial,ID FROM GeoTable WHERE (geometry::STGeomFromWKB(GeographySpatial.STAsBinary(),4326).STIsValid()=1 AND geography::STGeomFromText(@geography,4326).STIntersects(GeographySpatial)=1) OR geometry::STGeomFromWKB(geography::STGeomFromText(@geography,4326).STAsBinary() ,4326).STIntersects(geometry::STGeomFromWKB(GeographySpatial.STAsBinary(),4326).MakeValid())=1;',N'@Geography varchar(141)',@Geography='POLYGON((-139.297265625 122.8359375,-139.297265625 76.4296875,-74.258203125 76.4296875,-74.258203125 122.8359375,-139.297265625 122.8359375))'


When I first create the layer I set the current extent with the code



WinformsMap1.CurrentExtent = New RectangleShape(-90.2, 42, -80, 30)

The full error details are below.  Please let me know if you need any other information.  Any help or suggestions are appreciated.


Thanks,

Mark


System.Data.SqlClient.SqlException was unhandled

  Class=16

  ErrorCode=-2146232060

  LineNumber=1

  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) ."

  Number=6522

  Procedure=""

  Server="SERVERSQL\SQL2008"

  Source=".Net SqlClient Data Provider"

  State=1

  StackTrace:

       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.x742ba885258f6c2c(RectangleShape xb35a33b423b17f65, Overlay x99251f66cdabc2ad, Int32 xa209325f5c895f7e, Int32 x7454a0d1965919b1, GeographyUnit xbb704b4400ce6f76)

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

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

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

       at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.x4eb49068e137ed8f(InteractionArguments x195facd4ef5d753d)

       at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.xfeca3317d3c75bbb(Object xd9272088e65bd176, x6a8380ab1a7ebb4c xc2fd4c0ed406cdb7)

       at ThinkGeo.MapSuite.DesktopEdition.x5cd462d41be2f68a.OnMouseEvent(x6a8380ab1a7ebb4c e)

       at ThinkGeo.MapSuite.DesktopEdition.x5cd462d41be2f68a.AnalyseMouseUp(Double screenX, Double screenY, Double worldX, Double worldY, MapMouseButton mouseButton)

       at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.xd1e58e0ca2447b93(Object xd9272088e65bd176, MouseEventArgs xc2fd4c0ed406cdb7)

       at System.Windows.Forms.Control.OnMouseUp(MouseEventArgs e)

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

       at System.Windows.Forms.Control.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.UnsafeNativeMethods.DispatchMessageW(MSG& msg)

       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 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 System.Windows.Forms.Application.Run(Form mainForm)

       at VBSampleApps.VBSampleApps.Samples.Main() in C:\SSIWorkCopies\ResearchProjects\ThinkGeo\MapSuiteDesktopEval\Samples\VB Winforms How Do I Samples\Samples.Designer.vb:line 2

       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: 

 



Mark,


Welcome you to ThinkGeo discussion forum, this is Yale, hope my following answer can give you some help.
 
When the data is in Decimal Degree, the latitude value is expected to be between -90 ~90, and the longitude value is expected to be between -180~180. In our component, we have a very strict validation for this.
 
So, if I am not misunderstanding anything, your data stored in SQLServer is expected in Decimal Degree, and then its value should confirm that limitation. It seems that some data on the boundary is out of it.
 
Any more questions just feel free to let me know.
 
Thanks.
 
Yale

 Hi Yale,



Thanks for the quick reply and the help with this.  What you said makes sense and I agree that SQL Server is expecting decimal degrees in the ranges you describe.  Currently for testing purposes the table has only one record.  I double checked the coordinates for that record and they are all within the -90 ~90 range for latitude, and the -180~180 range for longitude.  When the Map Suite control is first instantiated, the polygon is displayed in the correct location and I'm able to zoom and pan the Map Suite control without any problems.  However, as soon as I pan the control to the far north or far south, to a location where the top or bottom of the Map Suite control goes past the north or south pole, that is when the error occurs.  The SQL query that I included in the first post is the actual SQL query that the Map Suite control is sending to SQL server whenever I pan the control that far.  The Map Suite control is asking SQL to return objects that intersect the polygon defined in the query as "POLYGON((-139.297265625 122.8359375,-139.297265625 76.4296875,-74.258203125 76.4296875,-74.258203125 122.8359375,-139.297265625 122.8359375))"  which I think is what the Map Suite control believes are its current display extents.

  

In my method I am setting the MapUnit of the control to decimal degrees with




WinformsMap1.MapUnit = GeographyUnit.DecimalDegree
 

Thanks for your help with this.

Mark



Mark, 
  
 Thanks for your reply. 
  
 Sorry for the delay. 
  
 Could you try on the Countries02.shp? First you could import the data Countries02.shp to your sql server and then have a try to zoom out very far (out of world extent) to see if this problem still exists? 
  
 Besides, how many data is it in your current Table? 
  
 Thanks. 
  
 Yale 


Hi Yale,


I imported the Countries02.shp file to our SQL server and I see the same behavior.  The countries map displays correctly, but then throws the error when I zoom out too far.  It looks like the DesktopEdition.dll that I'm referencing is the one with Runtime Version v2.0.50727 if that helps.  The other table that I was using only had one record in it.  I manually checked all of the points in that record to confirm that they were valid and did not go beyond 90 degrees of latitude.  Below is the code that I'm using. 


 



            WinformsMap1.MapUnit = GeographyUnit.DecimalDegree
            'WinformsMap1.CurrentExtent = New RectangleShape(-139.2, 92.4, 120.9, -93.2)
            WinformsMap1.CurrentExtent = New RectangleShape(-45, 45, 45, -45)
            WinformsMap1.BackgroundOverlay.BackgroundBrush = New GeoSolidBrush(GeoColor.GeographicColors.ShallowOcean)

            Dim connectString As String = "Data Source=SERVERSQL\SQL2008;Initial Catalog=MarkThinkGeo;Persist Security Info=True;User ID=sa;Password=*********"
            Dim sql2008Layer As New MsSql2008FeatureLayer(connectString, "countries02", "ISO_3DIGIT")
            sql2008Layer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.Country1
            sql2008Layer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20
            Dim staticOverlay As New LayerOverlay()
            staticOverlay.Layers.Add("Sql2008Layer", sql2008Layer)

            WinformsMap1.Overlays.Add(staticOverlay)

            WinformsMap1.Refresh()

 


Please let me know if you need anything else.  I can get details on our SQL Server install and configuration if you need them. 


Thank you,


Mark



Mark, 
  
 I cannot recreate your problem. I imported cntry02 to Sql Server 2008 and consume it using Desktop Edition, it works fine. I can zoom out to the very end. Could you let me know the version of your DesktopEdition, it cannot be v2.0 as our version starts from 3. from the following code you can see how to get the version number.  
  
 Here is my code, almost the same as yours: 
 
        private void LoadSQL2008Layer()
        {
            string version = WinformsMap.GetVersion();
            // "MapSuiteCore:3.1.299;DesktopEdition:3.1.299"

            winformsMap1.MapUnit = GeographyUnit.DecimalDegree;

            winformsMap1.CurrentExtent = new RectangleShape(-126.4, 48.8, -67.0, 19.0);
            winformsMap1.BackgroundOverlay.BackgroundBrush = new GeoSolidBrush(GeoColor.GeographicColors.ShallowOcean);

            string connectString = "Data Source=192.168.0.227;Initial Catalog=InternalDB;Persist Security Info=True;User ID=sa;Password=*******";
            MsSql2008FeatureLayer sql2008Layer = new MsSql2008FeatureLayer(connectString, "cntry02", "ID");
            sql2008Layer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.Country1;
            sql2008Layer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

            LayerOverlay staticOverlay = new LayerOverlay();
            staticOverlay.Layers.Add("Sql2008Layer", sql2008Layer);
            winformsMap1.Overlays.Add(staticOverlay);

            winformsMap1.Refresh();
        }
 
 Thanks, 
  
 Ben 


Hi Ben,


You're correct, when I use the GetVersion method it returns the string "MapSuiteCore:3.1.299;DesktopEdition:3.1.299."  The property I was looking at actually referred to the required .Net runtime version.  Sorry for the confusion.  


I just discovered something interesting.   The SQL trace file above shows that the ThinkGeo code is sending a  latitude value in the query that is beyond 90 degrees, "POLYGON((-139.297265625  122.8359375," which is what the SQL server is complaining about. However, when I import the shapefile to a SQL Server Geometry column instead of a Geography column, everything works fine.  So SQL Server is able to accept latitude values beyond 90 degrees for Geometry columns but not Geography columns.  


Mark


 


 


 



Mark,


That is interesting. Thanks for reminding and I just noticed that. Here is an aticle talking the difference between the geometry and geography, just share it with you.


conceptdev.blogspot.com/2007...metry.html

 


Thanks,


Ben



Ben, 
  
 That is very good article.  Thanks for passing that along and for your help on this. 
  
 Mark

Thank you, Mark! for raising this up so I now know the difference between Geometry and Geography in Sql Server:-)