Aşağıdaki kod ile bir hat başka bir hat ile iki parçaya bölünebilir.
USE [AKMERCAN]
GO
/****** Object: UserDefinedFunction [dbo].[STSplitLine] Script Date: 26.02.2021 11:58:44 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER function [dbo].[STSplitLine](@orjLineString nvarchar(MAX),@cutGeomString nvarchar(MAX),@srid int)
returns nvarchar(MAX)
as
begin
declare @cutGeom geometry;
declare @orjGeom geometry;
declare @intersectionGeom geometry;
declare @nodeCount int=0;
declare @i int=1;
declare @intersectedNodeIndex int=-1;
declare @newLine nvarchar(MAX)='';
declare @line1 nvarchar(MAX)='';
declare @line2 nvarchar(MAX)='';
declare @returnData nvarchar(MAX)='';
declare @geom1 geometry;
declare @geom2 geometry;
declare @segmentIndex int =0;
declare @tmpLine nvarchar(MAX);
declare @cur cursor;
declare @tbl_segments table(
StartPoint geometry,
EndPoint geometry,
NewPoint geometry,
Segment geometry,
SegmentIndex int
);
Set @orjGeom=geometry::STGeomFromText(@orjLineString,@srid);
set @cutGeom=geometry::STGeomFromText(@cutGeomString,@srid);
Set @intersectionGeom=@orjGeom.STIntersection(@cutGeom);
if @intersectionGeom.STGeometryType()='MultiPoint' begin
set @returnData='{Status:false,StatusMessage:"Çiziminiz kırmak istediğiniz hattın birden fazla noktası ile kesişiyor",Line1Wkt:"'+@line1+'",Line2Wkt:"'+@line2+'"}';
return @returnData;
end;
if @orjGeom.STStartPoint().STIntersects(@intersectionGeom.STBuffer(0.001))=1 begin
set @returnData='{Status:false,StatusMessage:"Kırmak istediğiniz hattın başlangıç noktasından kıramazsınız..",Line1Wkt:"'+@line1+'",Line2Wkt:"'+@line2+'"}';
return @returnData;
end;
if @orjGeom.STEndPoint().STIntersects(@intersectionGeom.STBuffer(0.001))=1 begin
set @returnData='{Status:false,StatusMessage:"Kırmak istediğiniz hattın bitiş noktasından kıramazsınız..",Line1Wkt:"'+@line1+'",Line2Wkt:"'+@line2+'"}';
return @returnData;
end;
Set @nodeCount=@orjGeom.STNumPoints ();
set @i=1;
while (@i<@nodeCount)
begin
insert into @tbl_segments(StartPoint,EndPoint,Segment,SegmentIndex)
Values(@orjGeom.STPointN(@i),
@orjGeom.STPointN(@i+1),
geometry::STGeomFromText('LINESTRING('+STR(@orjGeom.STPointN(@i).STX,18,8)+' '+STR(@orjGeom.STPointN(@i).STY,18,8)+','+STR(@orjGeom.STPointN(@i+1).STX,18,8)+' '+STR(@orjGeom.STPointN(@i+1).STY,18,8)+')',@srid),
@i);
set @i=@i+1;
end;
select @segmentIndex=t.SegmentIndex from @tbl_segments t where t.Segment.STBuffer(0.01).STIntersects(@intersectionGeom)=1;
if (Select Count(*) from @tbl_segments t
where t.SegmentIndex=@segmentIndex
and (t.StartPoint.STBuffer(0.1).STIntersects(@intersectionGeom)=1 or t.EndPoint.STBuffer(0.1).STIntersects(@intersectionGeom)=1))<=0
begin
update @tbl_segments set NewPoint=@intersectionGeom where SegmentIndex=@segmentIndex;
end
else
begin
if (Select Count(*) from @tbl_segments t
where t.SegmentIndex=@segmentIndex
and t.StartPoint.STBuffer(0.1).STIntersects(@intersectionGeom)=1)>0
begin
update @tbl_segments set NewPoint=StartPoint where SegmentIndex=@segmentIndex;
end
else
begin
update @tbl_segments set NewPoint=EndPoint where SegmentIndex=@segmentIndex;
end
end
set @i=1;
set @cur=cursor for
(select case
when t.NewPoint is null then
STR(t.StartPoint.STX,18,8)+' '+STR(t.StartPoint.STY,18,8)+','+STR(t.EndPoint.STX,18,8)+' '+STR(t.EndPoint.STY,18,8)
else
STR(t.StartPoint.STX,18,8)+' '+STR(t.StartPoint.STY,18,8)+','+STR(t.NewPoint.STX,18,8)+' '+STR(t.NewPoint.STY,18,8)
end as LineWkt
from @tbl_segments t where t.SegmentIndex<=@segmentIndex)
open @cur
FETCH NEXT
from @cur into @tmpLine
WHILE @@FETCH_STATUS=0
BEGIN
set @line1=@line1+','+TRIM(@tmpLine);
FETCH NEXT
FROM @cur into @tmpLine
END
close @cur;
set @cur=cursor for
(select case
when t.NewPoint is null then
STR(t.StartPoint.STX,18,8)+' '+STR(t.StartPoint.STY,18,8)+','+STR(t.EndPoint.STX,18,8)+' '+STR(t.EndPoint.STY,18,8)
else
+STR(t.NewPoint.STX,18,8)+' '+STR(t.NewPoint.STY,18,8)+','+STR(t.EndPoint.STX,18,8)+' '+STR(t.EndPoint.STY,18,8)
end as LineWkt
from @tbl_segments t where t.SegmentIndex>=@segmentIndex)
open @cur
FETCH NEXT
from @cur into @tmpLine
WHILE @@FETCH_STATUS=0
BEGIN
set @line2=@line2+','+TRIM(@tmpLine);
FETCH NEXT
FROM @cur into @tmpLine
END
close @cur;
set @line1= 'LINESTRING ('+SUBSTRING(@line1,2,LEN(@line1)-1)+')';
set @line2= 'LINESTRING ('+SUBSTRING(@line2,2,LEN(@line2)-1)+')';
set @geom1=geometry::STGeomFromText(@line1,@srid).MakeValid().Reduce(0);
set @geom2=geometry::STGeomFromText(@line2,@srid).MakeValid().Reduce(0);
set @line1=@geom1.STAsText();
set @line2=@geom2.STAsText();
set @returnData='{Status:true,StatusMessage:"İşlem Başarılı",Line1Wkt:"'+@line1+'",Line2Wkt:"'+@line2+'"}';
return @returnData;
end;
Aşağıdaki örnek ile denendiğinde ekran görüntüsündeki gibi sonuç elde edilmektedir.
Select dbo.STSplitLine('LINESTRING (3918330.9493079544 5131284.8657211363, 3918329.6669074208 5131285.4668463869)',
'LINESTRING(3918331.024705282 5131286.203856818,3918329.41982627 5131283.777876917)',3857)
Resimdeki mavi çizgi hat kırmanın yapılacağı çizgi.
Mor ve yeşil çizgiler kırma işlemi sonrasında oluşan çizgileri göstermektedir.