locked
Reduce() reduces too much RRS feed

  • Question

  •  
    DECLARE @g geometry;  
    SET @g = geometry::STGeomFromText('POLYGON((0 0, 0 1, 2 2, 3 1, 2 1, 0 0))', 0);  
    SELECT @g.Reduce(.75); 
    Hi,

    I use the Sql geometry datatype to store polygons which have been created with a GPS receiver in SQL Server 2008. These polygons consist of mostly several hundreds or even several thousands of points. When I display these polygons via Virtual Earth they are displayed perfectly but the performance is poor because of the many points.
    This is why I try to use the Reduce() method to reduce the ammount of point I get a strange behaviour: The result of the Reduce()-call is always a single point. The example works well, but with my "real" polygons it does not work. What could be a reason for that behaviour? Does this mean that something is wrong with my polygons?

    Best regards,
    Michael

    Monday, January 26, 2009 8:55 AM

Answers

  • Hi there,

    The Reduce() method accepts a single argument that determines by how much the resulting shape is simplified. You don't specify what value you are using, but I'm willing to make a guess as to where you're going wrong, based on the following sentence:

    MG_ said:

     I use the Sql geometry datatype to store polygons which have been created with a GPS receiver in SQL Server 2008.

    GPS co-ordinates are latitude/longitude values, measured in degrees, and methods for the geometry datatype generally operate using the unit of measure in which coordinate values are specified So, if you use Reduce(0.75) to simplify an instance of the geometry datatype, you're simplifying it to the nearest 0.75 of a degree. Now exactly what distance is covered by 0.75 of a degree of latitude/longitude depends on where you are on the Earth's surface, but it's something of the order of 50 miles. So, if the points of your polygon are less than 50 miles across, if you were to reduce them using Reduce(0.75) they'll be reduced to a single point.
    Unless you actually want to specify the appropriate distance in degrees, I think you might want to consider using the geography datatype to store your GPS coordinates instead, which accepts latitude/longitude coordinates in degrees, but operates using the unit of measurement specified in the sys.spatial_reference_systems table for the SRID in question (normally, this is metres).

    • Marked as answer by MG_ Tuesday, January 27, 2009 8:12 AM
    Monday, January 26, 2009 11:56 AM
    Answerer
  • Michael:

    Reduce() simplifies your shape by reducing the number of points in such a way that the distance from any new point to the original shape is within the provided tolerance (distance).

    I'm assuming based on the fact that you're able to plot these onto Virtual Earth that your polygon is made up of Lat/Long values (i.e., -180 to 180 in the X direction, -90 to 90 in the Y direction).  At this resolution, 0.75 degrees can be a very large distance, depending on where you measure on the globe (but, think 60-100km).  If your polygon represents an area smaller than 60km across, for example, it makes perfect sense that it would be reduced to a single point given a tolerance of 0.75.

    You should be able to find a smaller tolerance that reduces the number of points, but maintains a close resemblence to the original shape.  Try 0.001 for starters.  You can also measure your progress by using the STNumPoints() function

    select 'orig', @g, @g.STNumPoints()  
    union all 
    select '0.1', @g.Reduce(0.1), @g.Reduce(0.1).STNumPoints()  
    union all 
    select '0.01', @g.Reduce(0.01), @g.Reduce(0.01).STNumPoints()  
    union all 
    select '0.001', @g.Reduce(0.001), @g.Reduce(0.001).STNumPoints()  
    union all 
    select '0.0001', @g.Reduce(0.0001), @g.Reduce(0.0001).STNumPoints()  
    union all 
    select '0.00001', @g.Reduce(0.00001), @g.Reduce(0.00001).STNumPoints() 


    (Edit: Looks like I need to learn to type faster than Alastair when replying here.  ;-)

    • Marked as answer by MG_ Tuesday, January 27, 2009 8:12 AM
    Monday, January 26, 2009 12:18 PM

All replies

  • Hi there,

    The Reduce() method accepts a single argument that determines by how much the resulting shape is simplified. You don't specify what value you are using, but I'm willing to make a guess as to where you're going wrong, based on the following sentence:

    MG_ said:

     I use the Sql geometry datatype to store polygons which have been created with a GPS receiver in SQL Server 2008.

    GPS co-ordinates are latitude/longitude values, measured in degrees, and methods for the geometry datatype generally operate using the unit of measure in which coordinate values are specified So, if you use Reduce(0.75) to simplify an instance of the geometry datatype, you're simplifying it to the nearest 0.75 of a degree. Now exactly what distance is covered by 0.75 of a degree of latitude/longitude depends on where you are on the Earth's surface, but it's something of the order of 50 miles. So, if the points of your polygon are less than 50 miles across, if you were to reduce them using Reduce(0.75) they'll be reduced to a single point.
    Unless you actually want to specify the appropriate distance in degrees, I think you might want to consider using the geography datatype to store your GPS coordinates instead, which accepts latitude/longitude coordinates in degrees, but operates using the unit of measurement specified in the sys.spatial_reference_systems table for the SRID in question (normally, this is metres).

    • Marked as answer by MG_ Tuesday, January 27, 2009 8:12 AM
    Monday, January 26, 2009 11:56 AM
    Answerer
  • Michael:

    Reduce() simplifies your shape by reducing the number of points in such a way that the distance from any new point to the original shape is within the provided tolerance (distance).

    I'm assuming based on the fact that you're able to plot these onto Virtual Earth that your polygon is made up of Lat/Long values (i.e., -180 to 180 in the X direction, -90 to 90 in the Y direction).  At this resolution, 0.75 degrees can be a very large distance, depending on where you measure on the globe (but, think 60-100km).  If your polygon represents an area smaller than 60km across, for example, it makes perfect sense that it would be reduced to a single point given a tolerance of 0.75.

    You should be able to find a smaller tolerance that reduces the number of points, but maintains a close resemblence to the original shape.  Try 0.001 for starters.  You can also measure your progress by using the STNumPoints() function

    select 'orig', @g, @g.STNumPoints()  
    union all 
    select '0.1', @g.Reduce(0.1), @g.Reduce(0.1).STNumPoints()  
    union all 
    select '0.01', @g.Reduce(0.01), @g.Reduce(0.01).STNumPoints()  
    union all 
    select '0.001', @g.Reduce(0.001), @g.Reduce(0.001).STNumPoints()  
    union all 
    select '0.0001', @g.Reduce(0.0001), @g.Reduce(0.0001).STNumPoints()  
    union all 
    select '0.00001', @g.Reduce(0.00001), @g.Reduce(0.00001).STNumPoints() 


    (Edit: Looks like I need to learn to type faster than Alastair when replying here.  ;-)

    • Marked as answer by MG_ Tuesday, January 27, 2009 8:12 AM
    Monday, January 26, 2009 12:18 PM
  • Heya guys!

     

    What happens if MG_ transforms his Geometries to Geographies? would the same problem still exist and he would need to reduce his tolerance argument, as suggested by Jason?
    -Pure Krome-
    Monday, January 26, 2009 11:58 PM
  • Hi Krome,

    You can use Reduce() with the geography datatype, but Reduce(0.75) would simplify the supplied instance to the nearest 0.75 of a metre (assuming that the instance uses SRID 4326) rather than 0.75 of a degree.

    Tuesday, January 27, 2009 8:13 AM
    Answerer