2015-07-21 37 views
0

我寫了這個基本的代碼,這首先提取從多面對應於內圓和外圓的多邊形,然後將特定的LineString:可靠的方式來確定是否線段形式是多邊形的內圓

DECLARE @SomeMultiPolygon GEOGRAPHY = 'MULTIPOLYGON (
((-2 -2, 2 -2, 2 2, -2 2, -2 -2), (-1 -0.5, 0 -0.5, 0 -1.5, -1 -1.5, -1 -0.5), (0 1, 1 1, 1 0, 0 0, 0 1)) 
, ((-4 -3, -4 -5, 0 -5, 0 -3, -4 -3)))'; 
SET @SomeMultiPolygon.STSrid = 4326; 

DECLARE @i int = 1 
DECLARE @Results TABLE (Id INT IDENTITY(1,1), PolygonData GEOGRAPHY) 
WHILE @i <= @SomeMultiPolygon.STNumGeometries() 
    BEGIN 
     INSERT INTO @Results VALUES (@SomeMultiPolygon.STGeometryN(@i)) 
     SET @i = @i + 1 
    END 

SELECT 
    Id, 
    PolygonData.STGeometryType(), 
    PolygonData, 
    PolygonData.STAsText() AS PolygonWkt, 
    PolygonData.NumRings() AS NumberOfRings 
FROM @Results 

IF OBJECT_ID('tempdb..#Temp') IS NOT NULL 
    DROP TABLE #Temp 

CREATE TABLE #Temp 
(
    ParentId INT, 
    SubPolygon GEOGRAPHY 
) 

DECLARE @Id INT, @InnerLoop INT, @SubPolygon GEOGRAPHY; 
SELECT @Id = MAX(Id) FROM @Results  
WHILE @Id >= 1 
    BEGIN 
     SELECT @InnerLoop = PolygonData.NumRings() FROM @Results WHERE Id = @Id 
     WHILE @InnerLoop > 0 
      BEGIN 
       SELECT @SubPolygon = PolygonData.RingN(@InnerLoop) FROM @Results WHERE Id = @Id 

       INSERT INTO #Temp 
         (ParentId, SubPolygon) 
       VALUES (@Id, 
          @SubPolygon 
         ) 

       SET @InnerLoop = @InnerLoop - 1; 
      END 

     SET @Id = @Id - 1        
    END 

SELECT 
    *, 
    SubPolygon.STAsText() AS SubPolygonText, 
    SubPolygon.EnvelopeAngle() AS EnvelopeAngle 
FROM #Temp 

我是正確假設,如果EnvelopeAngle小於1度,LineString對應於一個內圓?

順便說一句,有沒有一個基於集合的方法來實現上述 - 我不是真正的TSQL循環粉絲。

PS:

這是上面的例子中的可視化:

enter image description here

回答

1

回答您的問題依次是:

我是正確的假設,如果EnvelopeAngle LineString是否小於1度對應於內圈?

不是。這是您的測試數據的人爲因素,但是您無法做出一般的斷言。你的問題是在好的時候發佈的,因爲我前幾天才瞭解到EnvelopeAngle。我喜歡把它想成「這個物體有多寬(以度爲單位)?」。如果您重新縮放了所有對象,則EnvelopeAngle啓發式不再適用。

但是,我可能嘗試的啓發式是針對結果表中給定的ID,最大的(按區域)是包含其他的。你也可以玩STDifference,但區域似乎是最直接的。

[I]是否有一套基於上述方法來實現上述目標? - 我不是TSql中循環的粉絲。

是的!這裏是:

DECLARE @SomeMultiPolygon GEOGRAPHY = 'MULTIPOLYGON (
    (
     (-2 -2, 2 -2, 2 2, -2 2, -2 -2), 
     (-1 -0.5, 0 -0.5, 0 -1.5, -1 -1.5, -1 -0.5), 
     (0 1, 1 1, 1 0, 0 0, 0 1) 
    ) 
    , (
     (-4 -3, -4 -5, 0 -5, 0 -3, -4 -3) 
    ) 
)'; 
SET @SomeMultiPolygon.STSrid = 4326; 

DECLARE @Results TABLE ( 
    Id INT IDENTITY(1,1), 
    PolygonData GEOGRAPHY 
); 

INSERT INTO @Results 
     ([PolygonData]) 
SELECT @SomeMultiPolygon.STGeometryN([n].[n]) 
FROM Util.dbo.[Numbers] AS [n] 
WHERE n <= @SomeMultiPolygon.STNumGeometries(); 

SELECT 
    Id, 
    PolygonData.STGeometryType(), 
    PolygonData, 
    PolygonData.STAsText() AS PolygonWkt, 
    PolygonData.NumRings() AS NumberOfRings 
FROM @Results; 

CREATE TABLE #Temp (
    ParentId INT, 
    SubPolygon GEOGRAPHY 
); 

INSERT INTO [#Temp] 
     ([ParentId], [SubPolygon]) 
SELECT r.ID, rings.[ring] 
FROM @Results AS [r] 
CROSS APPLY (
    SELECT r.[PolygonData].RingN(n) AS ring 
    FROM [Util].[dbo].[Numbers] AS [n] 
    WHERE n <= r.[PolygonData].NumRings() 
) AS rings; 

SELECT 
    *, 
    SubPolygon.STAsText() AS SubPolygonText, 
    SubPolygon.EnvelopeAngle() AS EnvelopeAngle 
FROM #Temp 
+0

謝謝。太好了,明天再來看看。 – cs0815