sql-serverspatialspatial-query

Getting list of spatial points from polygon within query


I have a database with various defined polygons which represent the outer boundarys of buildings on a map of a business park.

If I perform a Select within Management Studio, I get a result similar to the following:

LocationCode    LocationPolygon
1               POLYGON((1 1, 2 1, 2 2, 1 2, 1 1))
2               POLYGON((10 10, 20 10, 20 20, 10 20, 10 10))

What I would like to get is the following:

LocationCode    PointX    PointY
1               1         1
1               2         1
1               2         2
1               1         2
2               10        10
etc             etc       etc

I cannot see anywhere where I can extract the points from the Polygon using SQL Server from within a SQL Query? I can evidentally take the whole polygon and then do the rest on the client, but I would rather deal in SQL if possible.

Any help appreciated in pointing me in the right direction.


Solution

  • I've answered a similar question before and that time I used a user defined function to extract the points and return a table. Assuming a table Locations defined as: (LocationCode int, LocationPolygon geometry) then the following function:

    CREATE FUNCTION dbo.GetPoints()
    RETURNS @ret TABLE (LocationCode INT, PointX INT, PointY INT)
    AS
    BEGIN
        DECLARE @max INT
        SET @max = (SELECT MAX(LocationPolygon.STNumPoints()) FROM Locations) 
    
        ;WITH Sequence(Number) AS
        (
            SELECT 1 AS Number
            UNION ALL
            SELECT Number + 1
            FROM Sequence
            WHERE Number < @max
        )
        INSERT INTO @ret 
        SELECT
            l.LocationCode
            ,l.LocationPolygon.STPointN(nums.number).STX AS PointX
            ,l.LocationPolygon.STPointN(nums.number).STY AS PointY
        FROM Locations l, Sequence nums
        WHERE nums.number <= l.LocationPolygon.STNumPoints()
        RETURN
    END;
    

    When executed as SELECT DISTINCT * FROM dbo.GetPoints() ORDER BY LocationCode; will give the following result (using your sample data):

    | LOCATIONCODE | POINTX | POINTY |
    |--------------|--------|--------|
    |            1 |      1 |      1 |
    |            1 |      1 |      2 |
    |            1 |      2 |      1 |
    |            1 |      2 |      2 |
    |            2 |     10 |     10 |
    |            2 |     10 |     20 |
    |            2 |     20 |     10 |
    |            2 |     20 |     20 |
    

    I'm sure the function can be improved, but it should give you some ideas on how this problem can be solved.

    Sample SQL Fiddle