Polygon Bowties

Discussion created by navjohn on Dec 19, 2010
Latest reply on Dec 21, 2010 by navjohn

I am creating a 'Graph' of an attribute of a polyline by taking each point on the line and offsetting it by the (scaled) value.

This all works fine except where there are bends (not curves) in the line. At these points I get bowties in the polygon.

I tried a convex hull on the polygon but that removed all the concave parts. I also tried unioning the polygon with itself but that didn't work either.

I have enclosed a picture of the problem because they may be called something other than bowties elsewhere.

Does anyone have an idea for what else I could try?



The Code is:

 Public Sub createGraph(ByRef pInLine As IGeometry, ByVal dOffset As Double, ByRef pOutPoly As IGeometry, ByRef sError As String)
        ' Create a graph polygon as an offset of the polyline pInLine
        Dim pBridge As IGeometryBridge2
        Dim pSC As ISegmentCollection
        Dim pNewGC As IGeometryCollection
        Dim pEnumSegs As IEnumSegment
        Dim pS As ISegment
        Dim pPoly As IPolygon = New Polygon
        Dim iPart As Integer
        Dim iSeg As Integer
        Dim pN As ILine
        Dim dX() As Double
        Dim dY() As Double
        Dim X As Double
        Dim Y As Double
        Dim i As Integer
        Dim j As Integer
        Dim iSegTot As Integer
        Dim pWKS() As WKSPoint
        Dim dDist As Double
        Dim pCol As New StringCollection
        Dim a() As String
        Dim s As String

            sError = ""
            pOutPoly = New Polygon
            pOutPoly.SpatialReference = pInLine.SpatialReference
            pPoly.SpatialReference = pInLine.SpatialReference

            If pInLine.IsEmpty Then Exit Sub

            pBridge = New ESRI.ArcGIS.Geometry.GeometryEnvironment
            ' Get the offset distance
            dDist = dOffset

            ' Set the input segment collection
            pSC = pInLine
            iSegTot = 1 + 2 * pSC.SegmentCount
            i = iSegTot + 1
            ReDim dX(i)
            ReDim dY(i)
            pNewGC = pOutPoly
            ' Enumerate over the input segments adding points at i and at iSegTot - i
            pEnumSegs = pSC.EnumSegments
            pEnumSegs.Next(pS, iPart, iSeg)
            i = 0
            While IsNothing(pS) = False
                X = pS.FromPoint.X
                Y = pS.FromPoint.Y
                dX(iSegTot - i) = X
                dY(iSegTot - i) = Y
                ' Get the offset point
                pN = New Line
                pS.QueryNormal(esriSegmentExtension.esriNoExtension, 0, False, dDist, pN)
                X = pN.ToPoint.X
                Y = pN.ToPoint.Y
                dX(i) = X
                dY(i) = Y
                pEnumSegs.Next(pS, iPart, iSeg)
                i = i + 1
            End While
            ' Add the last point
            dX(UBound(dX)) = dX(0)
            dY(UBound(dY)) = dY(0)
            ' Remove nulls
            For i = 0 To UBound(dX)
                If IsNothing(dX(i)) = False AndAlso IsNumeric(dX(i)) AndAlso dX(i) <> 0 Then
                    If IsNothing(dY(i)) = False AndAlso IsNumeric(dY(i)) AndAlso dY(i) <> 0 Then
                        pCol.Add(dX(i).ToString & "," & dY(i).ToString)
                    End If
                End If
            Next i
            ReDim dX(pCol.Count - 1)
            ReDim dY(pCol.Count - 1)
            For i = 0 To pCol.Count - 1
                s = pCol.Item(i)
                a = Split(s, ",")
                dX(i) = CType(a(0), Double)
                dY(i) = CType(a(1), Double)
            Next i

            ' Assemble the points into a polygon
            ReDim pWKS(UBound(dX))

            j = 0
            For i = 0 To UBound(dX)
                pWKS(i).X = dX(i)
                pWKS(i).Y = dY(i)
            Next i
            pBridge.AddWKSPoints(pOutPoly, pWKS)

            '' Simplify the polygon and union it with itself to get rid of any slivers and bowties
            'Dim topologicalOperator2 As ITopologicalOperator2 = CType(pOutPoly, ITopologicalOperator2)
            'topologicalOperator2.IsKnownSimple_2 = False
            'Dim pGeometry As IGeometry = topologicalOperator2.Union(pOutPoly)
            'pOutPoly = CType(pGeometry, IPolygon)

        Catch ex As Exception
            sError = "ERROR: createGraph; Line: " & Erl() & vbCrLf & ex.Message
        End Try

    End Sub