I had a go at finding the intersections but the problem is deciding what to do when they occur. There are so many combinations.The method I finally used was to buffer the line and then chop off the ends and the bottom.The code is (it could use some tidying): Public Sub createGraph(ByRef pInLine As IGeometry, ByVal dOffset As Double, ByRef pOutPoly As IGeometry, ByRef sError As String)
' Create the graph by creating a buffer around the line and then cutting it along the Input line and trimming the ends
Dim pTopo1 As ITopologicalOperator2
Dim pTopo2 As ITopologicalOperator2
Dim pTopo3 As ITopologicalOperator2
Dim pTopo4 As ITopologicalOperator2
Dim pGeomBuff As IGeometry
Dim pLineL As IPolyline
Dim pLineR As IPolyline
Dim pLine As ILine ' The line connecting the start and end points of pInLine
Dim pLineTmp As ILine
Dim pInPoly As IPolyline
Dim pGeomL1 As IGeometry
Dim pGeomR1 As IGeometry
Dim pGeomL2 As IGeometry
Dim pGeomR2 As IGeometry
Dim pGeomUP As IGeometry
Dim pGeomDOWN As IGeometry
Dim pPtFrom As IPoint
Dim pPtTo As IPoint
Dim dDX As Double
Dim dDY As Double
Dim bRLL As Boolean ' The cut sequence flag; RLL is Right-Left-Left otherwise LRR
Try
sError = ""
pOutPoly = New Polygon
If pInLine.IsEmpty Then Exit Sub
pOutPoly.SpatialReference = pInLine.SpatialReference
' Set the input polyline
pInPoly = New Polyline
pInPoly.SpatialReference = pInLine.SpatialReference
pInPoly = CType(pInLine, IPolyline)
' Set the Cut sequence flag
dDX = pInPoly.ToPoint.X - pInPoly.FromPoint.X
If dDX = 0 Then
' Vertical line; Use Y axis
dDX = pInPoly.ToPoint.Y - pInPoly.FromPoint.Y
End If
If dDX > 0 Then
bRLL = True
Else
bRLL = False
End If
' Create the buffer on the input line
pTopo1 = pInLine
pGeomBuff = pTopo1.Buffer(dOffset)
' Create the end cutting lines
' 1. Get the line between the polyline end-points
pLine = New Line
pLine.SpatialReference = pInLine.SpatialReference
pLine.FromPoint = pInPoly.FromPoint
pLine.ToPoint = pInPoly.ToPoint
'##TEST
'g_wLog.WriteLine("BASE From: " & pLine.FromPoint.X & ", " & pLine.FromPoint.Y & " To: " & pLine.ToPoint.X & ", " & pLine.ToPoint.Y)
' 2. Get the left and right end lines perpendicular to the line between the ends
pLineTmp = New Line
pLineTmp.SpatialReference = pInLine.SpatialReference
pLine.QueryNormal(esriSegmentExtension.esriExtendAtFrom, 0, False, dOffset * 2, pLineTmp)
' Extend the end lines to go right across the buffer
pPtTo = New ESRI.ArcGIS.Geometry.Point
pPtTo = pLineTmp.ToPoint
dDX = pLineTmp.ToPoint.X - pLineTmp.FromPoint.X
dDY = pLineTmp.ToPoint.Y - pLineTmp.FromPoint.Y
pPtFrom = New ESRI.ArcGIS.Geometry.Point
pPtFrom.X = pLineTmp.FromPoint.X - dDX
pPtFrom.Y = pLineTmp.FromPoint.Y - dDY
pLineL = New Polyline
pLineL.SpatialReference = pInLine.SpatialReference
pLineL.FromPoint = pPtFrom
pLineL.ToPoint = pPtTo
' Set the orientation of this line
dDY = pLineL.ToPoint.Y - pLineL.FromPoint.Y
If dDY = 0 Then
dDY = pLineL.ToPoint.X - pLineL.FromPoint.X
End If
If dDY < 0 Then
pLineL.ReverseOrientation()
End If
'##TEST
'g_wLog.WriteLine("CUT_L From: " & pLineL.FromPoint.X & ", " & pLineL.FromPoint.Y & " To: " & pLineL.ToPoint.X & ", " & pLineL.ToPoint.Y)
' Other End
pLineTmp = New Line
pLineTmp.SpatialReference = pInLine.SpatialReference
pLine.QueryNormal(esriSegmentExtension.esriExtendAtFrom, pLine.Length, False, dOffset * 2, pLineTmp)
pPtTo = New ESRI.ArcGIS.Geometry.Point
pPtTo = pLineTmp.ToPoint
dDX = pLineTmp.ToPoint.X - pLineTmp.FromPoint.X
dDY = pLineTmp.ToPoint.Y - pLineTmp.FromPoint.Y
pPtFrom = New ESRI.ArcGIS.Geometry.Point
pPtFrom.X = pLineTmp.FromPoint.X - dDX
pPtFrom.Y = pLineTmp.FromPoint.Y - dDY
pLineR = New Polyline
pLineR.SpatialReference = pInLine.SpatialReference
pLineR.FromPoint = pPtFrom
pLineR.ToPoint = pPtTo
' Get the orientation of this line
dDY = pLineR.ToPoint.Y - pLineR.FromPoint.Y
If dDY = 0 Then
dDY = pLineR.ToPoint.X - pLineR.FromPoint.X
End If
If dDY < 0 Then
pLineR.ReverseOrientation()
End If
'##TEST
'g_wLog.WriteLine("CUT_R From: " & pLineR.FromPoint.X & ", " & pLineR.FromPoint.Y & " To: " & pLineR.ToPoint.X & ", " & pLineR.ToPoint.Y)
' Chop the Left end off
Try
pTopo2 = pGeomBuff
pTopo2.Cut(pLineL, pGeomL1, pGeomR1)
' Get the resulting geometry depending on the flag
If bRLL = True Then
pTopo3 = pGeomR1
Else
pTopo3 = pGeomL1
End If
Catch ex1 As Exception
pOutPoly = CType(pGeomBuff, IPolygon)
g_wLog.WriteLine("CUT_L ERROR: " & ex1.Message)
Exit Sub
End Try
' And the Right end
Try
pTopo3.Cut(pLineR, pGeomL2, pGeomR2)
' Get the resulting geometry
If bRLL = True Then
pTopo4 = pGeomL2
Else
pTopo4 = pGeomR2
End If
Catch ex2 As Exception
If bRLL = True Then
pOutPoly = CType(pGeomR1, IPolygon)
Else
pOutPoly = CType(pGeomL1, IPolygon)
End If
g_wLog.WriteLine("CUT_R ERROR: " & ex2.Message)
Exit Sub
End Try
' And the bottom
Try
pTopo4.Cut(pInLine, pGeomUP, pGeomDOWN)
Catch ex3 As Exception
If bRLL = True Then
pOutPoly = CType(pGeomL2, IPolygon)
Else
pOutPoly = CType(pGeomR2, IPolygon)
End If
g_wLog.WriteLine("CUT_BOTTOM ERROR: " & ex3.Message)
Exit Sub
End Try
' Set the output
If bRLL = True Then
pOutPoly = CType(pGeomUP, IPolygon)
Else
pOutPoly = CType(pGeomDOWN, IPolygon)
End If
Catch ex As Exception
sError = "ERROR: createGraph; Line: " & Erl() & vbCrLf & ex.Message
Finally
pTopo1 = Nothing
pTopo2 = Nothing
pTopo3 = Nothing
pTopo4 = Nothing
pLineR = Nothing
pLineL = Nothing
End Try
End Sub