polyline轉polygon不同情況buffer的實現方法

 

做一個運輸署的project時需要實現一個線轉面(polyline to polygon)的函數,有點像buffer,有個buffer distance, 但是在頭尾兩邊不能是圓弧,而是直線.(確實夠搞得...)參考了一下網上的資料,將幾種類似的buffer做了一下,效果如下圖。

(左上角為polyline,用它生成其他3種buffer.注意三個polygon紅色框框位置的差別 )

 

先說最簡單的,直接利用ITopologicalOperator.Buffer,設定一個buffer distance就

能得到左下角的polygon, 生成的polygon在結點位置都是圓弧.

Private Function ConvertPolylineToPolygon(pPolyline As IPolyline, pDist As DoubleAs IPolygon
 
   
Dim pPolygon As IPolygon
   
Set pPolygon = New Polygon
 
   
Dim pTopo As ITopologicalOperator
   
Set pTopo = pPolyline
   
Set pPolygon = pTopo.Buffer(pDist)
  
   pPolygon.Densify pPolygon.Length, 
360
 
   
Set ConvertPolylineToPolygon = pPolygon
End Function

 

如果希望首尾兩點位置上是squre buffer,則可以用下面的函數操作

Public Function TrySquareBufferByDifference(pPolyline As IPolyline, bufDist As DoubleAs IPolygon
  
Dim pResult As IPolygon
  
Dim pTopoIn As ITopologicalOperator
  
Set pTopoIn = pPolyline
  
Set pResult = pTopoIn.Buffer(bufDist)
  
Dim pTopoOut As ITopologicalOperator
  
Set pTopoOut = pResult
  
  
Dim pNorm1 As ILine, pNorm2 As ILine, pNorm3 As ILine, pNorm4 As ILine
  
Dim pCloser As ILine
  
Dim pDiffSegs As ISegmentCollection
  
Dim pDiffer As IPolygon
  
Dim pDiffTopo As ITopologicalOperator
  
  
Set pNorm1 = New Line
  
Set pNorm2 = New Line
  
Set pNorm3 = New Line
  
Set pNorm4 = New Line
  
Set pCloser = New Line
  pPolyline.QueryNormal esriNoExtension, 
0True, bufDist, pNorm1
  pPolyline.QueryNormal esriNoExtension, 
0True-bufDist, pNorm2
  
'on the next two lines, you may need to reverse the signs of the "length" arguments
  pNorm1.QueryNormal esriNoExtension, 1True, bufDist, pNorm3
  pNorm2.QueryNormal esriNoExtension, 
1True-bufDist, pNorm4
  pCloser.PutCoords pNorm3.ToPoint, pNorm4.ToPoint
  
  
Set pDiffer = New Polygon
  
Set pDiffSegs = pDiffer
  
Set pDiffTopo = pDiffer
  
Set pDiffer.SpatialReference = pPolyline.SpatialReference
  pDiffSegs.AddSegment pNorm1
  pDiffSegs.AddSegment pNorm2
  pDiffSegs.AddSegment pNorm3
  pDiffSegs.AddSegment pNorm4
  pDiffSegs.AddSegment pCloser
  pDiffTopo.Simplify
  
  
Dim pTemp As IGeometry
  
Set pTemp = pTopoOut.Difference(pDiffer)
  
Set pTopoOut = pTemp
  
  
Set pNorm1 = New Line
  
Set pNorm2 = New Line
  
Set pNorm3 = New Line
  
Set pNorm4 = New Line
  
Set pCloser = New Line
  pPolyline.QueryNormal esriNoExtension, 
1True, bufDist, pNorm1
  pPolyline.QueryNormal esriNoExtension, 
1True-bufDist, pNorm2
  
'on the next two lines, you may need to reverse the signs of the "length" arguments
  pNorm1.QueryNormal esriNoExtension, 1True-bufDist, pNorm3
  pNorm2.QueryNormal esriNoExtension, 
1True, bufDist, pNorm4
  pCloser.PutCoords pNorm3.ToPoint, pNorm4.ToPoint
  
  
Set pDiffer = New Polygon
  
Set pDiffSegs = pDiffer
  
Set pDiffTopo = pDiffer
  
Set pDiffer.SpatialReference = pPolyline.SpatialReference
  pDiffSegs.AddSegment pNorm1
  pDiffSegs.AddSegment pNorm2
  pDiffSegs.AddSegment pNorm3
  pDiffSegs.AddSegment pNorm4
  pDiffSegs.AddSegment pCloser
  pDiffTopo.Simplify
  
  
Set TrySquareBufferByDifference = pTopoOut.Difference(pDiffer)
End Function

 

如果希望節點位置不出現圓弧,可以用以下的方法

Public Function TrySquareBufferByOffset(pPolyline As IPolyline, bufDist As DoubleAs IPolygon
   
    
    
Dim pOffset1 As IConstructCurve, pOffset2 As IConstructCurve
    
Set pOffset1 = New Polyline
    
Set pOffset2 = New Polyline
    
    
Dim pOffCurve1 As ICurve, pOffCurve2 As ICurve
    
Set pOffCurve1 = pOffset1
    
Set pOffCurve2 = pOffset2
    
    pOffset1.ConstructOffset pPolyline, bufDist, esriConstructOffsetSimple  
    pOffset2.ConstructOffset pPolyline, 
-bufDist, esriConstructOffsetSimple
    
    
Dim pLine1 As ILine, pLine2 As ILine
    
Set pLine1 = New Line
    
Set pLine2 = New Line
    pLine1.PutCoords pOffCurve1.FromPoint, pOffCurve2.FromPoint
    pLine2.PutCoords pOffCurve1.ToPoint, pOffCurve2.ToPoint
    
    
Dim pResult As IPolygon
    
Set pResult = New Polygon
    
Set pResult.SpatialReference = pPolyline.SpatialReference
    
    
Dim pSegCol As ISegmentCollection
    
Set pSegCol = pResult
    pSegCol.AddSegment pLine1
    pSegCol.AddSegment pLine2
    pSegCol.AddSegmentCollection pOffset1
    pSegCol.AddSegmentCollection pOffset2
    pResult.SimplifyPreserveFromTo
    
    
Set TrySquareBufferByOffset = pResult
  
End Function

 

posted on 2009-04-21 15:24  炜升  阅读(707)  评论(0编辑  收藏  举报