如何解决SQL Server GEOGRAPHY STIntersection 更改点顺序
是否有可能以与原始对象相同的点顺序获得STIntersection()
的结果?
DECLARE @g geography;
DECLARE @h geography;
SET @g = geography::STGeomFromText('polyGON((25.84568061650872 49.69890972163677,25.844941083373904 49.69189373653131,25.900405504271674 49.69173426681988,25.900898532630585 49.69667747509544,25.84568061650872 49.69890972163677))',4326);
SET @h = geography::STGeomFromText('LInesTRING(25.84863871143376 49.68886378946257,25.85578746277756 49.702736200117556,25.874275603076814 49.69013957742882,25.88117784964471 49.696518021079896,25.890791686361744 49.693647826244444)',4326);
SELECT @g.STIntersection(@h)
-- output is MULTILInesTRING ((25.890791686361744 49.693647826244444,25.881177849644711 49.696518021079896,25.876080243405344 49.691807467094165),(25.871810347453074 49.691819790540073,25.862392696595393 49.698236908740775),(25.85364996544109 49.698589185269235,25.8501925460631 49.691879772894147))
我不知道它是否真的颠倒了,它是点和线段的随机顺序,但我需要它们以“原始”顺序保存线方向。
有什么解决办法吗?
谢谢。
解决方法
... 将@h 线串拆分为单条线的有序列表(每条线的起点是线的参考点),将每条单线与多边形@g 相交,并将交点拆分为单独的行(如果不止一个)。如果交点的起点更接近参考点,则保持交点不变,否则将其反转(交点的终点成为起点,反之亦然)。最后按顺序聚合几何集合中的交点(参考点/线序,相交线序)
DECLARE @g geography;
DECLARE @h geography;
SET @g = geography::STGeomFromText('POLYGON((25.84568061650872 49.69890972163677,25.844941083373904 49.69189373653131,25.900405504271674 49.69173426681988,25.900898532630585 49.69667747509544,25.84568061650872 49.69890972163677))',4326);
SET @h = geography::STGeomFromText('LINESTRING(25.84863871143376 49.68886378946257,25.85578746277756 49.702736200117556,25.874275603076814 49.69013957742882,25.88117784964471 49.696518021079896,25.890791686361744 49.693647826244444)',4326);
--reverse linestring..test
--SET @h = geography::STGeomFromText('LINESTRING(25.890791686361744 49.693647826244444,25.84863871143376 49.68886378946257)',4326);
select
concat(
'GEOMETRYCOLLECTION(',string_agg(directionline.ToString(),',') within group (order by pnum,ilnum),')'
) as geometrycollection_string
--geography::CollectionAggregate(directionline) -- no option for order...
from
(
select
p.pnum,io.ilnum,case when
--reverse the interection when starting point is farther to the reference point
io.iline.STStartPoint().STDistance(p.spoint) > io.iline.STEndPoint().STDistance(p.spoint)
then
--...assume intersection is linestring since @h is linestring
cast(
replace(
concat( --lazy...string manipulation
cast('linestring(' as varchar(4000)),translate(io.iline.STEndPoint().ToString(),'()',' '),translate(io.iline.STStartPoint().ToString(),')'
),'point','')
as geography)
--if the starting point of the intesection is closer to the reference point then keep the intersection as is
--this also covers if intersection is point (when @h is tangent to @g)
else io.iline end as directionline
from
(
select
@h.STPointN(n.pnum) as spoint,--starting point of each line/reference
n.pnum,--starting point ordinal
--linestring starting from spoint till the next point
cast(
replace(
concat(
cast('linestring(' as varchar(4000)),--lazy...
translate(@h.STPointN(n.pnum).ToString(),translate(@h.STPointN(n.pnum+1).ToString(),')'
),'')
as geography) as thelines --each line of the @h linestring
from
(
--points (excluding the last) of the @h linestring
select top (@h.STNumPoints()-1) row_number() over(order by @@spid) as pnum --point number
from (values(1),(1),(1)) as a(n)
cross join (values(1),(1)) as b(n)
) as n
) as p
--get each intersection "object" of each line (in the @h linestring) with @g
cross apply
(
--intersection of each line (of the @h linestring) with the polygon @g
--the intersection could be multiple "objects",get each object
select p.thelines.STIntersection(@g).STGeometryN(n.ilnum) as iline,ilnum
from
(
--split any multi-object intersection into individual objects
select top (p.thelines.STIntersection(@g).STNumGeometries()) row_number() over(order by @@spid) as ilnum
from (values(1),(1)) as b(n)
) as n
) as io
) as src
--order by pnum,ilnum
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。