Home Forums SQL Server 2008 T-SQL (SS2K8) Question about rounding the points in a Geometry. RE: Question about rounding the points in a Geometry.

  • If I understand the Geometry construct correctly, (and I'm not claiming to be an expert here, this is just based on frustrating experiences) the latitude and longitude values are stored internally as 'float', and reducing the accuracy is not going to solve your 'overhead' problem. I think there is a different issue here that you may want to address, and that is the number of additional points introduced into a geography/geometry by using STBuffer() - as a quick example try running the following code:

    DECLARE @g geometry;

    SET @g = geometry::STGeomFromText('POLYGON((0 2, 2 0, 4 2, 0 2))', 0);

    SELECT @g.STNumPoints() as PointCount,

    @g.STBuffer(0.00001).STNumPoints() as countAfterBuffer;

    One solution to your 'overhead' could be to just rein in the number of points created by the .STBuffer() function by following it with .Reduce(n) (depending on your requirements for using STBuffer in the first place, you will need to play around with values of n to get a reasonable number of points without sacrificing accuracy of the geometry)

    DECLARE @g geometry;

    SET @g = geometry::STGeomFromText('POLYGON((0 2, 2 0, 4 2, 0 2))', 0);

    SELECT @g.STNumPoints() as PointCount,

    @g.STBuffer(0.00001).STNumPoints() as countAfterBuffer,

    @g.STBuffer(0.00001).Reduce(0.01).STNumPoints() as countAfterReduce;

    I suspect that reducing the number of points in your buffered geometries will give a better performance increase than rounding the accuracy of the points. See how it goes, if it is still necessary to truncate the points after trying this, then maybe I can help. I am currently working on 'dismantling' aggregated geometries to feed into HTML for google maps, and encountered a similar issue. I used the following code snippet to generate the HTML string to create the polygon, with accuracy of the points rounded to 6 decimal places by converting float to STR ... which is also the only way I could find to get a FLOAT value into a CHAR format.

    DECLARE @g geometry;

    SET @g = geometry::STGeomFromText('POLYGON((0 2, 2 0, 4 2, 0 2))', 0);

    SELECT 'var L=google.maps.LatLng;'

    UNION ALL

    SELECT 'var polyg = ['

    UNION ALL

    SELECT 'new L(' + str(@g.STPointN(n).STY, 10,6)+','

    + str(@g.STPointN(n).STX, 10,6) +'),'

    from dbo.Tally where N < @g.STNumPoints()

    UNION ALL

    SELECT 'new L(' + str(@g.STPointN(n).STY, 10,6)+','

    + str(@g.STPointN(n).STX, 10,6) +')'

    from dbo.Tally where N = @g.STNumPoints()

    UNION ALL

    SELECT '];'

    Note: the code snippet above uses a 'tally table' to walk through the points of the geometry, but it is only working for geometries with a single polygon - ie @g.STNumGeometries() = 1 ... if anyone could point me to a way of using tally tables to process nested loops I would be very grateful. I need to generate the above sequence for each polygon in @g.STGeometryN(x) (where x <= @g.STNumGeometries()) then add a couple of lines of code after each polygon to add it to the map. Thanks.