MSSQL Spatial Çizgi İle Hat Kırma

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.

 

Add comment

Loading