做一個運輸署的project時需要實現一個線轉面(polyline to polygon)的函數,有點像buffer,有個buffer distance, 但是在頭尾兩邊不能是圓弧,而是直線.(確實夠搞得...)參考了一下網上的資料,將幾種類似的buffer做了一下,效果如下圖。
(左上角為polyline,用它生成其他3種buffer.注意三個polygon紅色框框位置的差別 )
先說最簡單的,直接利用ITopologicalOperator.Buffer,設定一個buffer distance就
能得到左下角的polygon, 生成的polygon在結點位置都是圓弧.
复制代码
如果希望首尾兩點位置上是squre buffer,則可以用下面的函數操作
复制代码
如果希望節點位置不出現圓弧,可以用以下的方法
复制代码
希望對大家有幫助.....
(左上角為polyline,用它生成其他3種buffer.注意三個polygon紅色框框位置的差別 )
先說最簡單的,直接利用ITopologicalOperator.Buffer,設定一個buffer distance就
能得到左下角的polygon, 生成的polygon在結點位置都是圓弧.
- Private Function ConvertPolylineToPolygon(pPolyline As IPolyline, pDist As Double) As 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 Double) As 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, 0, True, bufDist, pNorm1
- pPolyline.QueryNormal esriNoExtension, 0, True, -bufDist, pNorm2
- 'on the next two lines, you may need to reverse the signs of the "length" arguments
- pNorm1.QueryNormal esriNoExtension, 1, True, bufDist, pNorm3
- pNorm2.QueryNormal esriNoExtension, 1, True, -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, 1, True, bufDist, pNorm1
- pPolyline.QueryNormal esriNoExtension, 1, True, -bufDist, pNorm2
- 'on the next two lines, you may need to reverse the signs of the "length" arguments
- pNorm1.QueryNormal esriNoExtension, 1, True, -bufDist, pNorm3
- pNorm2.QueryNormal esriNoExtension, 1, True, 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 Double) As 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 'modify offsethow and bevelratio if desired
- 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
希望對大家有幫助.....