Community
Civil 3D Customization
Welcome to Autodesk’s AutoCAD Civil 3D Forums. Share your knowledge, ask questions, and explore popular AutoCAD Civil 3D Customization topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Drainage Network Anaylsis with BW-tree alogthirm or simpler

3 REPLIES 3
Reply
Message 1 of 4
ralstogj
379 Views, 3 Replies

Drainage Network Anaylsis with BW-tree alogthirm or simpler

Hi

 

I am trying to extend some earlier code I have written to quickly design drainage works in Civil3d without going outside the program.

 

The reason I want to do this is when initally designing a new  network we do not need a full blown SSA analysis or storm sewer analysis besides neither of these programs import and export process have ever worked well in the metric world or us anyway.

 

So what I do at the moment is have  parcels with userdefined properties for all my catchment drainage information and use area label expressions to calculate out my flows from each catchment.  I link these parcels to structures by changing the name of the parcel to the strucutre it is going to and just adding a counter along the lines of -(1) to the end of the name of each addition parcel that needs to drain to the same structure.

 

This gives me a nice table of data in the toolspace vista for the parcels for all the catchment data and flows as per the image below. The last colum being named test but is actually the flow in l/s for the wastewater in this image.

2014-05-02_1347.png

 

On the pipes in the network I have expressions that calculate the basic flow capacity of each pipe using manning or cole-brook white equation and display that data in a pipe label.

 

So at the moment to check the cumvlative flow at each structure I just right click and copy the Parcel (Catchment) data from the toolspace vista and paste it into excel and then if all the catchments are labelled sequencially tally up the flows above a certain structure number. Then jump back into civi3d and check the pipe capacity in that location is ok.

 

Now what I want to do is eliminate this step with some code that  does this for me. Basically I am wanting to load the drainage network layout data in to some kind of class that I can quickly search and do some of the basic things SSA does like.

 

1.  Highlight all pipes and structures connected to this structure upstream.

2. Highlight all the parcels catchments connected above this point.

3. Accumalate all the catchment flows from parcels above a certain point and assign it to a property of the structures out going pipe so it can be seen in a pipe label.

 

Now I have done some googling and it looks like a BW-tree alogthirm is the sort of thing I need. Has any one done something along these lines in Civil3d or using functionalility build into the Civil3d the API. From memory I few years ago the only thing you could find was the shortest path.

 

Any thoughts and suggestions appriciated.

 

Regards

 

Justin Ralston

 

 

Regards

Justin Ralston
http://c3dxtreme.blogspot.com/
3 REPLIES 3
Message 2 of 4
Jeff_M
in reply to: ralstogj

Justin, this is something I have looked into as well, for different purposes. Due to my work schedule I've not been able to pursue it, so my current routine only works from upstream to downstream. I hope to be able to spend more time on this in the near future.
Jeff_M, also a frequent Swamper
EESignature
Message 3 of 4
ralstogj
in reply to: Jeff_M

Jeff

 

Thanks for the reply this should be reasonable easy without having to reinvent the wheel.

 

Since posting this on Saturday moring I have done some more research over the weekend and think the name of the alogthrim we are after in a class is a N-ary tree as  from each outlet in the drianage system you have a tree that can have multipile childern. Althrough in each drawing you may have multipile trees.

 

I did find that the C# Cookbook has an example of an N-ary tree and you can download the code examples from the book here.

 

Now just how you load the drainage network data into the tree and search and find paths in it is another problem.

 

Maybe one of the Autodesk Infrastrucutre Modeeling Devblog guys like Augusto or Partha may like to take on the challenge and help us out with an example and a blog post which would make interesting reading.

 

Justin

Regards

Justin Ralston
http://c3dxtreme.blogspot.com/
Message 4 of 4

Hi Justin,

 

This sounds interesting and tricky... 🙂

 

Playing with Pipe Networks can take some cool directions, like this http://adndevblog.typepad.com/infrastructure/2013/03/pipe-network-along-water-drop-path.html and a sample I did for AU2010 (CP322) that you can find below.

 

This AU sample may help on your point #1 and get started on point #2, although the Parcel API requires some COM objects, but it's there. The #3 seems more a result of the first two points... am I right?

 

Finally, the image you send is a little difficult to read, can you submit as an attachment (in full resolution)? Will give some extra thinking time 🙂

 

Cheers!

Augusto

 

 

 

 

Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.EditorInput

Imports Autodesk.Civil.ApplicationServices
Imports Autodesk.Civil.PipeNetwork.DatabaseServices
Imports Autodesk.Civil.PipeNetwork.DatabaseServices.Styles

Imports Autodesk.AutoCAD.GraphicsInterface
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.Geometry

''' <summary>
''' Show the pipe network flow based on Pipe.FlowDirection and Pipe/Structure connections.
''' How to use: run 'SHOWFLOW' command, mouse over a pipe/structure, it will appear some
''' arrows (FlowDirection to one structure to another) or lines (FlowDirection bidirectional)
''' </summary>
''' <remarks></remarks>
Public Class ShowPipeNetworkFlow
    <CommandMethod("showFlow")> _
    Public Sub showFlowDirection()
        Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor

        'start the point monitor
        AddHandler ed.PointMonitor, New PointMonitorEventHandler(AddressOf pointMonitorFlowDirection)

        'trick to let the point monitor running
        ed.GetPoint("Click on screen to exit")

        'finish the point monitor
        RemoveHandler ed.PointMonitor, AddressOf pointMonitorFlowDirection
    End Sub

    Private geo As ViewportGeometry
    Private trans As Transaction

    Public Sub pointMonitorFlowDirection(ByVal sender As Object, ByVal e As PointMonitorEventArgs)
        'get the entity over the aperture
        Dim pickEnts As FullSubentityPath() = e.Context.GetPickedEntities()
        If (pickEnts.Length = 0) Then Return

        Dim entIds As ObjectId() = pickEnts(0).GetObjectIds()
        If (entIds.Length = 0) Then Return

        Dim db As Database = Application.DocumentManager.MdiActiveDocument.Database
        Try
            trans = db.TransactionManager.StartTransaction

            'is it a pipe or structure?
            Dim p As Part = TryCast(trans.GetObject(entIds(0), OpenMode.ForRead), Part)
            If (p Is Nothing) Then
                trans.Commit() 'faster than abort
                Return
            End If

            'store the curret draw context (will be used later)
            geo = e.Context.DrawContext.Geometry

            If (p.Domain = DomainType.Pipe) Then
                NextPipe(p, e.Context.RawPoint)
            Else
                NextStruct(p)
            End If

            trans.Commit() 'faster than abort
        Finally
            'always dispose
            'as we store and reuse the transaction, we cannot use the Using keyword here
            'so it is required an explicit dispose
            trans.Dispose()
        End Try
    End Sub

    Public Sub NextPipe(ByVal p As Pipe, ByVal drawFlowFrom As Point3d)
        'get the base curve that represents this pipe
        'unfortunatelly the Pipe.BaseCurve property is not working yet,
        'therefore this is not working for curved pipes.
        'let's create a base LINE
        Dim baseCurve As Curve
        If p.FlowDirection = FlowDirectionType.StartToEnd Then
            baseCurve = New Line(p.StartPoint, p.EndPoint)
        Else
            baseCurve = New Line(p.EndPoint, p.StartPoint)
        End If

        'get the length of the curve
        Dim length As Double = baseCurve.GetDistanceAtParameter(baseCurve.EndParam)
        'determine where start drawing the arrows, close to the mouse cursor (aperture)
        Dim startLength As Double = baseCurve.GetDistAtPoint(baseCurve.GetClosestPointTo(drawFlowFrom, False))
        'if this pipe is bidirectional, then start at 0 (ignore line above)
        If (p.FlowDirection = FlowDirectionType.Bidirectional) Then startLength = 0.0

        'iterate through the pipe length
        For i As Double = startLength To length Step 2.0
            Dim pointOverPipe As Point3d = baseCurve.GetPointAtDist(i)
            Dim directionAtPoint As Vector3d = baseCurve.GetFirstDerivative(pointOverPipe)
            Select Case p.FlowDirection
                Case FlowDirectionType.Bidirectional
                    DrawLineAtPoint(geo, pointOverPipe, directionAtPoint)
                Case FlowDirectionType.StartToEnd
                    DrawArrowAtPoint(pointOverPipe, directionAtPoint)
                Case FlowDirectionType.EndToStart
                    DrawArrowAtPoint(pointOverPipe, directionAtPoint)
            End Select
        Next

        'determine the next structure, following the flow
        Select Case p.FlowDirection
            Case FlowDirectionType.Bidirectional 'both directions
                NextStruct(trans.GetObject(p.EndStructureId, OpenMode.ForRead))
                NextStruct(trans.GetObject(p.StartStructureId, OpenMode.ForRead))
            Case FlowDirectionType.StartToEnd
                NextStruct(trans.GetObject(p.EndStructureId, OpenMode.ForRead))
            Case FlowDirectionType.EndToStart
                NextStruct(trans.GetObject(p.StartStructureId, OpenMode.ForRead))
        End Select
    End Sub

    Public Sub DrawArrowAtPoint(ByVal p As Point3d, ByVal v As Vector3d)
        v = v.MultiplyBy(1 / v.Length) 'turn into unit length vector
        'directions of the arrow
        Dim leftSide As Vector3d = v.RotateBy(2 * Math.PI / 3, Vector3d.ZAxis)
        Dim rightSide As Vector3d = v.RotateBy(4 * Math.PI / 3, Vector3d.ZAxis)
        'draw the arrow
        geo.WorldLine(p, p.Add(leftSide))
        geo.WorldLine(p, p.Add(rightSide))
    End Sub

    Public Sub DrawLineAtPoint(ByVal geo As ViewportGeometry, ByVal p As Point3d, ByVal v As Vector3d)
        v = v.MultiplyBy(1 / v.Length) 'turn into unit length vector
        'two perpendicular vectos
        Dim leftSide As Vector3d = v.RotateBy(Math.PI / 2, Vector3d.ZAxis)
        Dim rightSide As Vector3d = v.RotateBy(3 * Math.PI / 2, Vector3d.ZAxis)
        'draw the line
        geo.WorldLine(p.Add(rightSide), p.Add(leftSide))
    End Sub

    Public Sub NextStruct(ByVal s As [Structure])
        'find the next pipe for each connected pipe
        For pIndex As Integer = 0 To s.ConnectedPipesCount - 1
            Dim p As Pipe = trans.GetObject(s.ConnectedPipe(pIndex), OpenMode.ForRead)

            'determine where will flow from this pipe
            'these 2 'ifs' could be one, but left as two to understanding it better
            If p.StartStructureId.Equals(s.ObjectId) And p.FlowDirection = FlowDirectionType.StartToEnd Then
                NextPipe(p, s.Location)
            ElseIf p.EndStructureId.Equals(s.ObjectId) And p.FlowDirection = FlowDirectionType.EndToStart Then
                NextPipe(p, s.Location)
            End If
        Next
    End Sub
End Class

Regards,



Augusto Goncalves
Twitter @augustomaia
Autodesk Developer Network

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Rail Community


 

Autodesk Design & Make Report