ThinkGeo.com    |     Documentation    |     Premium Support

Some objects from SQL data not showing in map



Using ThinkGeo DeskTopEdition 7.0.0.0, I am trying to display points from a SQL Server database on the map and noticed not all of them are showing. I have created a small .Net project which replicates the problem and a screenshot which shows the problem.

Results.png shows 2 identical maps - everything is exactly the same apart from getting their data from different SQL tables. As can be seen, both the layers report that they have a FeatureSource count of 3 objects. But one map only shows 2 of the 3 objects. If I display the points in SQL Server Management Studio in the spatial results window I can see 3 objects each time. And the missing point is in the middle of the 2 visible points so it is not an extents problem - I am zooming to the layer boundary and even zooming out 50% just in case. The missing point is not ‘under’ a visible point and zooming in or out doesn’t make it visible.



VB.Net Project is Test3Points.zip - I had to remove the mapsuite.core file from the project to get it under your 2MB file size limit. 



Not quite sure how to include data in SQL format so I just extracted to CSV & attached in a zip file. Please let me know if there is a better way.

Test3Points.zip (949 KB)
002_001_Data.zip (1.42 KB)

Hi David,



Sorry I was unable to import the CSV into MsSqlServer 2008, but I tested the sample with our test data it worked well. According to the data you attached here I found that the features come from the two files are not the same, I guess it maybe the reason. The following is the screenshot I tested result.







Thanks,

Peter

Any idea how I can pass the data to you? I have the date in 2 small tables and definitely can confirm the results every time. Your shapes don’t appear to be making use of the rotating symbol class which I included - not sure if that is the cause… The symbols should rotate on the VCMG field. 
  
 Quite possibly it does work with your data - it works with 1 table of mine and doesn’t work with another, even though the data originally came from the same table and is the same format - only the lat & long are slightly different.

Hi David, 
  
 Please send the data to forumsupport@thinkgeo.com or ask sales@thinkgeo.com for a FTP address to upload large size data. 
  
 Thanks, 
 Peter

The problem isn’t the size of the data - in fact the data is sitting in a zip file 2 messages up in a standard SQL Server export to CSV but you say you can’t use that. We are only talking about 6 records in total. What format do you want the data in? I can post it here but if you can’t take CSV then what format will you accept?

Hi David, 
  
 The SQL Scripts will be better. 
  
 Thanks, 
 Peter

Ok, figured out how to do that - SQL files attached.



Thanks,



Dave

dbo.tmpTest2Vessels.Table.zip (3.07 KB)

Hi David, 
  
 Thanks for your share! Any question please let us know. 
  
 Regards, 
  
 Don

Actually my question still stands - why do I only see 2 of the 3 features with 1 table? I am hoping you can duplicate the problem now you have the sample code & data.

Hi David, 
  
 Thanks for your data and test project, I found if I get all the features then add them to other layer, I can shows all the 3 points on map. But if I render them via the SQLserver layer I missed the id 533057600 point, the problem is our MSSQL2008FeatureLayer render features by this SQL statement: 
  
 SELECT [WGS84Loc].STAsBinary() as [WGS84Loc],[ID] FROM tmpTest2Vessels WHERE (geography::STGeomFromText(‘POLYGON((100.681610107422 7.53803430125117,100.681610107422 7.3200822994113,102.952267706394 7.3200822994113,102.952267706394 7.53803430125117,100.681610107422 7.53803430125117))’,4326).STIntersects(WGS84Loc)=1); 
  
 When I tried it in MSSQL, it only return two result.  
  
 I think maybe the problem is the WGS84Loc for 533057600 have some problem, but it’s not saved as a readable format. I think maybe we can do further research about that after our MSSQL developer back office, but if you get any information from this SQL statement please let me know. 
  
 Regards, 
  
 Don

Ok, thanks - I hope you can find out why it isn’t showing as SQL Server Management Studio can show the spatial object with no problems. I am not doing anything different with that point - it is just being read in from a GPS device and INSERTed into the SQL Server table with a standard POINT() command, along with a few million other points. I have found a few missing points so far but only in ThinkGeo, not in SSMS.

Hi David, 
  
 Could you show me the Sal scripts that you are using in SSMS? I was just wondering what’s the difference between the one we are using. 
  
 Thanks, 
 Johnny

Just 'select * from tablename" and click on the “spatial” tab.

Just in case that wasn’t clear, here is the view from SQL Server Management Studio - the green circles are added by me as the dots are a bit difficult to see. But you can see both tables are showing 3 points spatially. If SSMS can show them, it is strange that MapSuite isn’t showing them.

SpatialResults.png (63 KB)

Hi David,  
  
 Just like my previous reply, our result related with the SQL query statement, so I think maybe the problem is related with the  query statement, our developer will try to find the reason about this problem, any update we will let you know. 
  
 Regards, 
  
 Don

Hi David,



Sorry for delay on this. The reason why it can’t display in MapSuite Map is that the missing point doesn’t intersect with the BoundingBox. The Map only draws the features intersect with the BoundingBox. In the table tmpTest2Vessels the record 533057600 doesn’t intersect with the BoundingBox so it draws 2 features. The following is the screenshot from the SSMS.







For the GetCount() method we don’t filter the data by the BoundingBox intersection and it returns the count of records in the data table. So it returns 3 as the result.



Hope it’s helpful.



Regards,

Peter

I will take a better look when I get to work, but I am confused as to why it isn’t in the bounding box when the code should be zooming the map out to the extents of the bounding box and then I even zoom out another 50% just to be on the safe side. 
  
 Dim mapOutline As New ThinkGeo.MapSuite.Core.RectangleShape 
 mapOutline = VesselLayerBad.GetBoundingBox 
 MapTwo.CurrentExtent = mapOutline 
 MapTwo.ZoomOut(50) 
  
 Can you tell me what query you are using to generate the Intersects value? I guess you typed in a bounding box polygon or something like that? 
  
 Thanks, 
  
 Dave

Hi David,



The first one is tracing by the SQL Server Profiler and the other one is modified based on the first one which will get the result as the screenshot I attached before.



SQL Server Profiler:

exec sp_executesql N’SELECT [VCMG],[WGS84Loc].STAsBinary() as [WGS84Loc],[ID] FROM tmpTest2Vessels WHERE (geography::STGeomFromText(@Geography,4326).STIntersects(WGS84Loc)=1);’,N’@Geography varchar(178)’,@Geography=‘POLYGON((100.681610107422 7.53803430125117,100.681610107422 7.3200822994113,102.952267706394 7.3200822994113,102.952267706394 7.53803430125117,100.681610107422 7.53803430125117))‘



SSMS:

exec sp_executesql N’SELECT [ID],[VLat],[VLon], (geography::STGeomFromText(@Geography,4326).STIntersects(WGS84Loc)) AS Intersects FROM tmpTest2Vessels;’,N’@Geography varchar(178)’,@Geography='POLYGON((100.681610107422 7.53803430125117,100.681610107422 7.3200822994113,102.952267706394 7.3200822994113,102.952267706394 7.53803430125117,100.681610107422 7.53803430125117))'



Thanks,

Peter

I am in the office now and had a better look at your SSMS output. The ‘missing point’ has a Longitude of 100.7623611 which is in between the other 2 points which are 100.68 and 102.95. The Latitude of the missing point is admittedly a tiny bit south of the other 2 points, but not enough to be outside the map area. So I don’t see how it can be outside the bounding box…



I just added a small bit of code:



pointLayer.FeatureSource.Projection = proj4
Dim missingfeature As New Feature(100.7623611, 7.3200833, “Point1”)
pointLayer.InternalFeatures.Add(“Point1”, missingfeature)
pointLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = PointStyles.CreateSimpleCircleStyle(GeoColor.FromHtml("#ED775B"), 10, GeoColor.FromHtml("#CA5B48"))
pointLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20



to the existing sample I gave you and the results show that the ‘missing point’ (or at least another point in the same place on the same map on a different layer) is in fact in the middle of the 2 points that are shown. So again, I don’t understand how it can be outside the bounding box.



Also, even if the point was outside the bounding box, when one zooms out (which is possible in the sample project) the point should be visible?



Actually after I put that orange point in I had a frame of reference and found that if I double click on the orange point 11 times (which zooms in each time) the ‘missing point’ actually does finally show up - right underneath the orange point.

So, why doesn’t it show normally? I typically have thousands of these green triangles on the map at once, overlapping very densely so I don’t think it is being trimmed because if an overlap…









Hi Dave,



I guess this issue is caused by the SQL Server spatial coordinate calculation precision.  The geography is used to represent geodetic data and the geometry is used to represent planar data.  The MsSqlFeatureLayer gets the intersection features by SQL Server spatial calculation which will project planer data to spherical by the geography::STGeomFromText(@Geography,4326). As you mentioned before the ‘missing point’ is in the boundingbox, this is true in the planar coordinate but may be not true in the spherical coordinate.



The InMemoryFeatureLayer gets the Intersection features just via mathematical calculation so the ‘missing point’ will be plot on the map.



There is a workaround, we can do the buffer operation before intersects by binding the  ExecutingSqlStatement event and rebuild the SQL statement in the event, the code snippet maybe like the following:



Bind event:


AddHandler (DirectCast(VesselLayerBad.FeatureSource, MsSql2008FeatureSource)).ExecutingSqlStatement, New EventHandler(Of ExecutingSqlStatementMsSql2008FeatureSourceEventArgs)(AddressOf OnExecutingSqlStatement)



Handler:




Private Sub OnExecutingSqlStatement(ByVal sender As Object, ByVal e As ExecutingSqlStatementMsSql2008FeatureSourceEventArgs)
       If (e.ExecutingSqlStatementType = ExecutingSqlStatementType.GetFeaturesInsideBoundingBoxEx) Then
           e.SqlStatement = e.SqlStatement.Replace(".STIntersects", “.STBuffer(22).STIntersects”)
       End If
   End Sub

NOTE: In STBuffer(buffer) method above, you can set the buffer to a proper value.



Regards,

Peter