线串到点

时间:2012-05-26 17:33:57

标签: sql-server tsql geospatial sql-server-2012

我需要使用SQL Server从Linestring中提取Points。我知道我可以看到geometry.ToString()的坐标,但我需要新的点几何。我怎么能这样做?

4 个答案:

答案 0 :(得分:14)

如果您使用的是SQL 2005+,我建议您使用CTE:

DECLARE @GeometryToConvert GEOMETRY
SET     @GeometryToConvert = 
    GEOMETRY::STGeomFromText('LINESTRING (-71.880713132200128 43.149953199689264, -71.88050339886712 43.149719933022993, -71.880331598867372 43.149278533023676, -71.88013753220099 43.147887799692512, -71.879965998867931 43.147531933026357, -71.879658998868422 43.147003933027179, -71.879539598868575 43.146660333027739, -71.879525332201979 43.145994399695439, -71.87959319886852 43.145452399696296, -71.879660598868384 43.14531113302985, -71.879915932201357 43.145025599696908, -71.879923198868028 43.1449217996971, -71.879885998868076 43.144850733030523, -71.879683932201715 43.144662333030851, -71.879601398868488 43.144565333030982, -71.879316798868956 43.144338333031328, -71.879092332202617 43.144019799698469, -71.8789277322029 43.143902533032019, -71.878747932203169 43.143911533031996, -71.878478132203554 43.14405779969843, -71.878328332203807 43.144066133031743, -71.878148732204068 43.144016599698489, -71.8772655988721 43.143174533033118, -71.876876198872708 43.142725133033821, -71.876801532206173 43.142654933033953, -71.876629398873092 43.142600733034044)', 4269)
;
WITH GeometryPoints(N, Point) AS  
( 
   SELECT 1,  @GeometryToConvert.STPointN(1)
   UNION ALL
   SELECT N + 1, @GeometryToConvert.STPointN(N + 1)
   FROM GeometryPoints GP
   WHERE N < @GeometryToConvert.STNumPoints()  
)

SELECT *, Point.STAsText() FROM GeometryPoints

文字结果

Text Results

空间结果 - STBuffer(.0001)

Spatial Results (Buffered)

答案 1 :(得分:6)

这是一个关于如何从LineString中提取点的小例子:

declare @LineString geography,
        @loop       int
declare @Points     table (Point geography)

set @LineString = geography::Parse('LINESTRING(
        -22.8317451477051 -43.4041786193848,-22.8308925628662 -43.4045524597168,-22.8314971923828 -43.404727935791, 
        -22.833927154541  -43.4069404602051,-22.8267574310303 -43.4071388244629)')

set @loop = @LineString.STNumPoints()

while @loop > 0
    begin
    insert into @Points values(@LineString.STPointN(@loop))
    set @loop = @loop -1
    end

select Point.Lat as Lat, Point.Long as Long from @Points

不要放弃:T-SQL中的空间数据有点棘手,但它有效!

答案 2 :(得分:1)

我几乎不了解几何数据类型,但documentation表示您使用STNumPoints获取对象中的点数,然后使用STPointN检索单个点。

答案 3 :(得分:0)

我知道这个非常老的问题,但是应该指出的是,可以不使用循环(或递归CTE,这是一种循环类型)来完成

DECLARE @GeometryToConvert GEOMETRY
SET     @GeometryToConvert = 
    GEOMETRY::STGeomFromText('LINESTRING (-71.880713132200128 43.149953199689264, -71.88050339886712 43.149719933022993, -71.880331598867372 43.149278533023676, -71.88013753220099 43.147887799692512, -71.879965998867931 43.147531933026357, -71.879658998868422 43.147003933027179, -71.879539598868575 43.146660333027739, -71.879525332201979 43.145994399695439, -71.87959319886852 43.145452399696296, -71.879660598868384 43.14531113302985, -71.879915932201357 43.145025599696908, -71.879923198868028 43.1449217996971, -71.879885998868076 43.144850733030523, -71.879683932201715 43.144662333030851, -71.879601398868488 43.144565333030982, -71.879316798868956 43.144338333031328, -71.879092332202617 43.144019799698469, -71.8789277322029 43.143902533032019, -71.878747932203169 43.143911533031996, -71.878478132203554 43.14405779969843, -71.878328332203807 43.144066133031743, -71.878148732204068 43.144016599698489, -71.8772655988721 43.143174533033118, -71.876876198872708 43.142725133033821, -71.876801532206173 43.142654933033953, -71.876629398873092 43.142600733034044)', 4269)
;WITH
    L0   AS(SELECT 1 AS c UNION ALL SELECT 1),
    L1   AS(SELECT 1 AS c FROM L0 AS A CROSS JOIN L0 AS B),
    L2   AS(SELECT 1 AS c FROM L1 AS A CROSS JOIN L1 AS B),
    L3   AS(SELECT 1 AS c FROM L2 AS A CROSS JOIN L2 AS B),
    L4   AS(SELECT 1 AS c FROM L3 AS A CROSS JOIN L3 AS B),
    L5   AS(SELECT 1 AS c FROM L4 AS A CROSS JOIN L4 AS B),
    Nums AS(SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS n FROM L5)
SELECT n, @GeometryToConvert.STPointN(n), @GeometryToConvert.STPointN(n).STAsText()
FROM Nums -- can be done with real numbers table
where n  <= @GeometryToConvert.STNumPoints ()
GO

或使用即时价值

DECLARE @GeometryToConvert GEOMETRY
SET     @GeometryToConvert = 
    GEOMETRY::STGeomFromText('LINESTRING (-71.880713132200128 43.149953199689264, -71.88050339886712 43.149719933022993, -71.880331598867372 43.149278533023676, -71.88013753220099 43.147887799692512, -71.879965998867931 43.147531933026357, -71.879658998868422 43.147003933027179, -71.879539598868575 43.146660333027739, -71.879525332201979 43.145994399695439, -71.87959319886852 43.145452399696296, -71.879660598868384 43.14531113302985, -71.879915932201357 43.145025599696908, -71.879923198868028 43.1449217996971, -71.879885998868076 43.144850733030523, -71.879683932201715 43.144662333030851, -71.879601398868488 43.144565333030982, -71.879316798868956 43.144338333031328, -71.879092332202617 43.144019799698469, -71.8789277322029 43.143902533032019, -71.878747932203169 43.143911533031996, -71.878478132203554 43.14405779969843, -71.878328332203807 43.144066133031743, -71.878148732204068 43.144016599698489, -71.8772655988721 43.143174533033118, -71.876876198872708 43.142725133033821, -71.876801532206173 43.142654933033953, -71.876629398873092 43.142600733034044)', 4269)
SELECT n, @GeometryToConvert.STPointN(n), @GeometryToConvert.STPointN(n).STAsText()
FROM (VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15),(16),(17),(18),(19),(20),(21),(22),(23),(24),(25),(26),(27),(28),(29)) Numbers (n) 
where n  <= @GeometryToConvert.STNumPoints ()
GO