Group by value and create a geographic polyline of points (latitude and longitude) for each group in T-SQL

A similar question is asked here:

Create a geographic polyline from points in T-SQL

Given this question, I have a table schema that looks like this:

CREATE TABLE [dbo].[LongAndLats](
[Longitude] [float] NULL,
[Latitude] [float] NULL,
[SortOrder] [bigint] NULL,
[SensorID] [bigint] NULL,
)

Sample data is as follows:

enter image description here

How to convert these points to a geography polyline for each SensorID using TSQL (so that I have a SensorID / Polyline entry for each SensorID)?

I tried using db_cursor, but I get a separate set of results for each group (and I think the geography may be the same). This code:

DECLARE @SensorID VARCHAR(2000)
DECLARE @LineFromPoints geography
DECLARE @BuildString NVARCHAR(MAX)

DECLARE db_cursor CURSOR FOR  
SELECT Distinct([SensorId]) 
FROM [dbo].[LongAndLats]

OPEN db_cursor   
FETCH NEXT FROM db_cursor INTO LongAndLats 

WHILE @@FETCH_STATUS = 0   
BEGIN   
       SELECT @BuildString = COALESCE(@BuildString + ',', '') + CAST([Longitude] AS NVARCHAR(50)) + ' ' + CAST([Latitude] AS NVARCHAR(50))
       FROM [LongAndLats]
       WHERE SensorID = @SensorID
       ORDER BY SortOrder            

       SET @BuildString = 'LINESTRING(' + @BuildString + ')';   
       SET @LineFromPoints = geography::STLineFromText(@BuildString, 4326);
       SELECT @LineFromPoints As 'Geomerty', @name As 'SensorID' 

       FETCH NEXT FROM db_cursor INTO @name   
END   

CLOSE db_cursor   
DEALLOCATE db_cursor

Results in this:

enter image description here

, , SensorID/Polyline. , . .

+1
1

SQL Server 2017+ :

SELECT geography::STLineFromText('LINESTRING(' + 
         STRING_AGG(CONCAT(Longitude, ' ' ,Latitude), ',') 
         WITHIN GROUP(ORDER BY SortOrder) + ')' , 4326) AS geometry
      ,SensorId
FROM dbo.LongAndLats
GROUP BY SensorId
HAVING COUNT(*) > 1;

DBFiddle Demo


db_cursor,

, , :

SELECT @BuildString = COALESCE(@BuildString + ',', '') 
       + CAST([Longitude] AS NVARCHAR(50)) + ' ' + CAST([Latitude] 
        AS NVARCHAR(50))
FROM [LongAndLats]
WHERE SensorID = @SensorID
ORDER BY SortOrder;  

, undefined. : nvarchar concatenation/index/nvarchar (max)

EDIT:

SQL Server 2012:

SELECT geography::STLineFromText('LINESTRING(' 
      + STUFF(
             (SELECT ',' + CONCAT(Longitude, ' ' ,Latitude) 
              FROM dbo.LongAndLats t2
              WHERE t1.SensorId = t2.SensorId 
              ORDER BY SortOrder
              FOR XML PATH (''))
             , 1, 1, '')
       + ')' 
       , 4326) AS geometry, SensorId
FROM dbo.LongAndLats t1
GROUP BY SensorId
HAVING COUNT(*) > 1;

DBFiddle Demo2

EDIT2:

:

.NET Framework "":

System.FormatException: 24117: LineString , . .

HAVING COUNT(*) > 1;

:

" ", ( CHECK ):

" -90 90 "

SELECT geography::STLineFromText('LINESTRING(' 
      + STUFF(
             (SELECT ',' + CONCAT(Longitude, ' ' ,Latitude) 
              FROM dbo.LongAndLats t2
              WHERE t1.SensorId = t2.SensorId 
                AND Latitude BETWEEN -90 and 90
                AND Longitude BETWEEN -180 AND 180
              ORDER BY SortOrder
              FOR XML PATH (''))
             , 1, 1, '')
       + ')' 
       , 4326) AS geometry, SensorId
FROM dbo.LongAndLats t1
WHERE Latitude BETWEEN -90 and 90
  AND Longitude BETWEEN -180 AND 180
GROUP BY SensorId
HAVING COUNT(*) > 1;

DBFiddle Demo3

+4

Source: https://habr.com/ru/post/1544874/


All Articles