You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SQL Server中裁剪geometry线段至原线段范围内?

需求说明

我不想把数据库中的geometry数据提取到C#变量处理后再写回,希望直接用SQL实现需求。

数据库表结构

CREATE TABLE dbo.MyTable (
   [Name] nvarchar(250),
   [From] numeric(21,6),
   [To] numeric(21,6),
   [Mapping] geometry,
   [Cost] float
);

现有处理逻辑

现有脚本会从该表读取数据,计算出新的From和To值(始终满足[From] < [To] AND @newFrom >= [From] AND @newFrom < @newTo AND @newTo <= [To]),然后写入同结构的新表(原表保持不变)。其中Cost值已通过公式((@newTo-@newFrom)/([To]-[From]))*[Cost]完成正确调整。

需要实现的Geometry裁剪需求

现在要通过SQL调整geometry字段:原geometry为连续线段(不一定是直线),需按比例裁剪掉原线段从[From]到@newFrom的起始部分,以及从@newTo到[To]的结束部分。对应的裁剪比例分别是(@newFrom-[From])/([To]-[From])和([To]-@newTo)/([To]-[From]),数据SRID为3857。

举个例子:10公里长的曲线道路,需获取2公里到8公里段的geometry数据。以下是数据前后示例(结果由现有C#代码生成):

DECLARE @newFrom NUMERIC(21,6)
DECLARE @newTo NUMERIC(21,6)
SET @newFrom = 957
SET @newTo = 963

CREATE TABLE [MySourceTable] (
   [Name] nvarchar(250),
   [From] numeric(21,6),
   [To] numeric(21,6),
   [Mapping] geometry,
   [Cost] float
)

INSERT INTO [MySourceTable] VALUES ('MS Segment 1', 955, 965, 0x110F0000010403000000A4BB379356C260C18E0893A6DFC754413C4CBF5856C260C11E20FCC9DFC754413FD76FE054C260C177001A57E0C7544101000000010000000001000000FFFFFFFF0000000002, 990)

SELECT TOP(0) * INTO [MyTargetTable] FROM [MySourceTable]

INSERT INTO [MyTargetTable] SELECT [Name], @newFrom, @newTo, 0x110F00000114C347863D56C260C18C8531D4DFC75441AF40AE3755C260C10D9A6236E0C75441, ((@newTo-@newFrom)/([To]-[From]))*[Cost] FROM [MySourceTable]

注:@newFrom和@newTo并非硬编码,而是在复杂SQL脚本中动态计算得到。

SQL解决方案

可以利用SQL Server的STLineSubstring方法实现线段的比例截取,具体代码如下:

DECLARE @newFrom NUMERIC(21,6)
DECLARE @newTo NUMERIC(21,6)
SET @newFrom = 957
SET @newTo = 963

-- 若目标表不存在则创建
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'MyTargetTable')
SELECT TOP(0) * INTO [MyTargetTable] FROM [MySourceTable]

-- 插入裁剪后的数据
INSERT INTO [MyTargetTable]
SELECT 
    [Name],
    @newFrom,
    @newTo,
    -- 按比例截取子线段,确保几何有效性并设置SRID
    [Mapping].STLineSubstring(
        (@newFrom - [From])/([To] - [From]),
        (@newTo - [From])/([To] - [From])
    ).MakeValid().SetSRID(3857) AS [Mapping],
    ((@newTo-@newFrom)/([To]-[From]))*[Cost] AS [Cost]
FROM [MySourceTable]

关键说明

  • STLineSubstring(startRatio, endRatio):接受0-1之间的两个比例值,分别对应原线段起始到截取起点的比例、原线段起始到截取终点的比例,完全匹配需求中的裁剪逻辑。
  • MakeValid():避免截取操作产生无效几何对象,保证数据合法性。
  • SetSRID(3857):显式设置坐标系,确保输出的geometry数据SRID正确。

内容的提问来源于stack exchange,提问作者ysi_d

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 17:39:56