Cross section river profiles

Post here for help on using FreeCAD's graphical user interface (GUI).
Forum rules
and Helpful information
IMPORTANT: Please click here and read this first, before asking for help

Also, be nice to others! Read the FreeCAD code of conduct!
CanisLupus
Posts: 8
Joined: Thu Nov 30, 2017 1:32 pm

Re: Cross section river profiles

Post by CanisLupus »

Thank, now it works. :)
CanisLupus
Posts: 8
Joined: Thu Nov 30, 2017 1:32 pm

Re: Cross section river profiles

Post by CanisLupus »

So does someone has an idea how I can create such profile drawings...

example_profile.jpg
example_profile.jpg (55.58 KiB) Viewed 2983 times
[url=https://picload.org/view/drcwgall/examp ... e.jpg.html]

...from the sucessfull imported data?

RiverCrossSection.png
RiverCrossSection.png (290.52 KiB) Viewed 2983 times
User avatar
microelly2
Veteran
Posts: 4691
Joined: Tue Nov 12, 2013 4:06 pm
Contact:

Re: Cross section river profiles

Post by microelly2 »

Look at TechDraw or drawing WB

an other way:
in Draft there is a shape2dView method to get mappings into the drawing plane
So you can compose your drawing

bp_651.png
bp_651.png (1.18 KiB) Viewed 2979 times

http://freecadbuch.de/doku.php?id=blog: ... e_pyramide
User avatar
chakkree
Posts: 327
Joined: Tue Jun 30, 2015 12:58 am
Location: Bangkok Thailand

Re: Cross section river profiles

Post by chakkree »

I'm using python macro for reading data and generate the SVG string, then insert to ViewSymbol in TechDraw.


Code: Select all

"""
RiverCrossSectionSVG.py
"""
import csv
import tempfile

from FreeCAD import Vector
from xml.etree import ElementTree as et
from math import sqrt


def getBorder(w,h):
    return '''<svg xmlns="http://www.w3.org/2000/svg" width="%d" height="%d" viewBox="0 0 %d %d">
 <rect x="10" y="10" width="%d" height="%d" stroke="black" stroke-width="0.5" fill="none"/>
<text x="10" y="%d" font-size="4">Department of Civil Engineering, Southeast Asia University, Thailand</text>
</svg>
'''%(w,h,w,h,w-20,h-20, h-5)



if open.__module__ in ['__builtin__','io']:
    pyopen = open # because we'll redefine open below

templatefilehandle,templatefile = tempfile.mkstemp(suffix=".svg")
of = pyopen(templatefile,"wb")
of.write( getBorder(297,210) )
of.close()

path = 'D:\\Data\\RiverCrossSection\\'
fName = path+'example_data.csv'
CrossSection = {}




with open(fName, 'rb') as csvfile:
    data = csv.reader(csvfile, delimiter=',')
    count = 1
    for row in data:
        #Msg(row); Msg('\n')
        if count>1:
            name = row[0]
            str1 = name.split('q')
            id = str1[0]
            pointName = str1[1]
            x  = row[1]
            y  = row[2]
            z  = row[3]
            pointData = (x,y,z)
            if CrossSection.has_key(id):                
                #CrossSection[id].append( pointData )
                CrossSection[id][pointName]= pointData 
            else:
                pointData = {pointName:pointData}
                CrossSection[id] = pointData
        count+=1 

Msg(CrossSection); Msg('\n')

# Find Min
minX = 10000000
minY = 10000000
minZ = 10000000
for iSection in CrossSection:
    #Msg(iSection); Msg('\n\n')
    #Msg(CrossSection[iSection]); Msg('\n\n')
    for iPoint in CrossSection[iSection]:
        #Msg(CrossSection[iSection][iPoint]); Msg('\n')
        x = float( CrossSection[iSection][iPoint][0] )
        y = float( CrossSection[iSection][iPoint][1] )
        z = float( CrossSection[iSection][iPoint][2] )
        if x<minX: minX = x
        if y<minY: minY = y
        if z<minZ: minZ = z
    #Msg('\n')


doc = FreeCAD.newDocument()
scaleX=1/50.0
scaleY=1/50.0
for iSection in CrossSection:

    drawing=doc.addObject('TechDraw::DrawPage',"Section%s"%iSection)
    template = doc.addObject('TechDraw::DrawSVGTemplate','Template')
    template.Template = templatefile
    drawing.Template = template
    svgSymbol = doc.addObject('TechDraw::DrawViewSymbol','CutSection%s'%iSection)
    drawing.addView(svgSymbol)
    svg = et.Element('svg' )
    svg.set('xmlns',"http://www.w3.org/2000/svg" )
    svg.set('version',"1.1" )
    group = et.Element('g' , fill='black' ,stroke='black')
    group.set('stroke-width' , '0.25')  
    svg.append( group )
    data = {}
    oldX =0
    for i in range(0,len(CrossSection[iSection])):
        if i==0:
            z = float( CrossSection[iSection]['p01'][2] )
            data['p'+str(1).zfill(2)] = (0.0 , z)  
            oldX = 0.0
        else:
            x1 = float( CrossSection[iSection]['p'+str(i).zfill(2)][0] )
            x2 = float( CrossSection[iSection]['p'+str(i+1).zfill(2)][0] )
            y1 = float( CrossSection[iSection]['p'+str(i).zfill(2)][1] )
            y2 = float( CrossSection[iSection]['p'+str(i+1).zfill(2)][1] )
            z = float( CrossSection[iSection]['p'+str(i+1).zfill(2)][2] )
            dx = x2-x1; dy=y2-y1
            L = sqrt(dx*dx + dy*dy)
            oldX+=L
            data['p'+str(i+1).zfill(2)] = (oldX , z)  
    #Msg("Section%s: "%iSection)
    #Msg(data);Msg('\n')

    datum =  ( float(data['p01'][1]) -2 ) *1000
    # Vertical Line
    for i in range(1,len(data)+1):
        x = (float( data[ 'p'+str(i).zfill(2) ][0] ))*1000
        y = (float( data[ 'p'+str(i).zfill(2) ][1] ))*1000
        line1 =  et.Element('line' , x1='%g'%(x*scaleX) ,y1='%g'%(-y*scaleY) ,
                                  x2='%g'%(x*scaleX) ,y2='%g'%( (-datum)*scaleY),
                 stroke= 'blue' )
        group.append(line1)
        line2 =  et.Element('line' , x1='%g'%(x*scaleX) ,y1='%g'%((-datum)*scaleY) ,
                                  x2='%g'%(x*scaleX) ,y2='%g'%( (-datum+750)*scaleY),
                 stroke= 'black' )
        group.append(line2)
    # Contour Line
    for i in range(2,len(data)+1):
        x1 = (float( data[ 'p'+str(i-1).zfill(2) ][0] ))*1000
        y1 = (float( data[ 'p'+str(i-1).zfill(2) ][1] ))*1000
        x2 = (float( data[ 'p'+str(i).zfill(2) ][0] ))*1000
        y2 = (float( data[ 'p'+str(i).zfill(2) ][1] ))*1000
        line1 =  et.Element('line' , x1='%g'%(x1*scaleX) ,y1='%g'%(-y1*scaleY) ,
                                  x2='%g'%(x2*scaleX) ,y2='%g'%(-y2*scaleY),
                 stroke= 'green' )
        group.append(line1)
    y = (float( data[ 'p'+str(i-1).zfill(2) ][1] ))*1000 
    text1 = et.Element('text' ,x='0' ,y='%f'%( -y*scaleY-5))
    text1.set('font-size' , str(4))
    text1.text = 'Section%s'%iSection
    group.append(text1)

    x1 = -1000
    x2 = (float( data[ 'p'+str( len(data)  ).zfill(2) ][0] ))*1000 +500
    baseline1 =  et.Element('line' , x1='%g'%(x1*scaleX) ,y1='%g'%(-datum*scaleY) ,
                                  x2='%g'%(x2*scaleX) ,y2='%g'%(-datum*scaleY),
                 stroke= 'black' )
    baseline1.set('stroke-width' , '0.5') 
    group.append(baseline1)

    step = 250
    for i in range(0,4):
        y2 = datum-step*i
        baseline2 =  et.Element('line' , x1='%g'%(x1*scaleX) ,y1='%g'%(-y2*scaleY) ,
                                      x2='%g'%(x2*scaleX) ,y2='%g'%(-y2*scaleY),
                     stroke= 'black' )
        baseline2.set('stroke-width' , '0.25') 
        group.append(baseline2)


    #Msg(et.tostring(svg)  )
    svgSymbol.Symbol=et.tostring(svg)    
RiverCrossSectionSVG.png
RiverCrossSectionSVG.png (193.35 KiB) Viewed 2926 times
User avatar
chakkree
Posts: 327
Joined: Tue Jun 30, 2015 12:58 am
Location: Bangkok Thailand

Re: Cross section river profiles

Post by chakkree »

Add axis and x,y data label to svg string.

Code: Select all

"""
RiverCrossSectionSVG.py
"""
import csv
import tempfile

from xml.etree import ElementTree as et
from math import sqrt


def getBorder(w,h):
    return '''<svg xmlns="http://www.w3.org/2000/svg" width="%d" height="%d" viewBox="0 0 %d %d">
 <rect x="10" y="10" width="%d" height="%d" stroke="black" stroke-width="0.5" fill="none"/>
<text x="10" y="%d" font-size="4">Department of Civil Engineering, Southeast Asia University, Thailand</text>
</svg>
'''%(w,h,w,h,w-20,h-20, h-5)



if open.__module__ in ['__builtin__','io']:
    pyopen = open # because we'll redefine open below

templatefilehandle,templatefile = tempfile.mkstemp(suffix=".svg")
of = pyopen(templatefile,"wb")
of.write( getBorder(297,210) )
of.close()

path = 'D:\\Data\\RiverCrossSection\\'
fName = path+'example_data.csv'
CrossSection = {}




with open(fName, 'rb') as csvfile:
    data = csv.reader(csvfile, delimiter=',')
    count = 1
    for row in data:
        #Msg(row); Msg('\n')
        if count>1:
            name = row[0]
            str1 = name.split('q')
            id = str1[0]
            pointName = str1[1]
            x  = row[1]
            y  = row[2]
            z  = row[3]
            pointData = (x,y,z)
            if CrossSection.has_key(id):                
                #CrossSection[id].append( pointData )
                CrossSection[id][pointName]= pointData 
            else:
                pointData = {pointName:pointData}
                CrossSection[id] = pointData
        count+=1 

Msg(CrossSection); Msg('\n')

# Find Min
minX = 10000000
minY = 10000000
minZ = 10000000
for iSection in CrossSection:
    #Msg(iSection); Msg('\n\n')
    #Msg(CrossSection[iSection]); Msg('\n\n')
    for iPoint in CrossSection[iSection]:
        #Msg(CrossSection[iSection][iPoint]); Msg('\n')
        x = float( CrossSection[iSection][iPoint][0] )
        y = float( CrossSection[iSection][iPoint][1] )
        z = float( CrossSection[iSection][iPoint][2] )
        if x<minX: minX = x
        if y<minY: minY = y
        if z<minZ: minZ = z
    #Msg('\n')


doc = FreeCAD.newDocument()
scaleX=1/50.0
scaleY=1/50.0
step = 600.0

for iSection in CrossSection:
    
    drawing=doc.addObject('TechDraw::DrawPage',"Section%s"%iSection)
    template = doc.addObject('TechDraw::DrawSVGTemplate','Template')
    template.Template = templatefile
    drawing.Template = template
    svgSymbol = doc.addObject('TechDraw::DrawViewSymbol','CutSection%s'%iSection)
    drawing.addView(svgSymbol)
    svg = et.Element('svg' )
    svg.set('xmlns',"http://www.w3.org/2000/svg" )
    svg.set('version',"1.1" )
    group = et.Element('g' , fill='black' ,stroke='black')
    group.set('stroke-width' , '0.25')  
    svg.append( group )
    data = {}
    oldX =0
    for i in range(0,len(CrossSection[iSection])):
        if i==0:
            z = float( CrossSection[iSection]['p01'][2] )
            data['p'+str(1).zfill(2)] = (0.0 , z)  
            oldX = 0.0
        else:
            x1 = float( CrossSection[iSection]['p'+str(i).zfill(2)][0] )
            x2 = float( CrossSection[iSection]['p'+str(i+1).zfill(2)][0] )
            y1 = float( CrossSection[iSection]['p'+str(i).zfill(2)][1] )
            y2 = float( CrossSection[iSection]['p'+str(i+1).zfill(2)][1] )
            z = float( CrossSection[iSection]['p'+str(i+1).zfill(2)][2] )
            dx = x2-x1; dy=y2-y1
            L = sqrt(dx*dx + dy*dy)
            oldX+=L
            data['p'+str(i+1).zfill(2)] = (oldX , z)  
    #Msg("Section%s: "%iSection)
    #Msg(data);Msg('\n')
    
    datum =  ( float(data['p01'][1]) -2 ) 
    n = int ( round( (datum/10) , 0 ) )
    datum = n*10 
    datum -= 2
    datum *=1000
    # Vertical Line
    for i in range(1,len(data)+1):
        x = (float( data[ 'p'+str(i).zfill(2) ][0] ))*1000
        y = (float( data[ 'p'+str(i).zfill(2) ][1] ))*1000
        line1 =  et.Element('line' , x1='%g'%(x*scaleX) ,y1='%g'%(-y*scaleY) ,
                                  x2='%g'%(x*scaleX) ,y2='%g'%( (-datum)*scaleY),
                 stroke= 'blue' )
        group.append(line1)
        line2 =  et.Element('line' , x1='%g'%(x*scaleX) ,y1='%g'%((-datum)*scaleY) ,
                                  x2='%g'%(x*scaleX) ,y2='%g'%( (-datum+3*step)*scaleY),
                 stroke= 'black' )
        group.append(line2)
        
        z = datum-1.5*step
        x_offset = 0.5
        textX = et.Element('text' ,x='%g'%(x*scaleX-x_offset) ,y='%g'%(-(z)*scaleY+5))
        textX.set('font-size' , str(2.5))
        textX.set('text-anchor' , "start" )
        textX.set('fill' , "green" )
        textX.set('stroke' , "none" )
        textX.set('transform' , 'rotate(-90 %g,%g)'%(x*scaleX-x_offset,-z*scaleY+5))
        textX.text ='%.3f'%(x/1000.0)
        group.append(textX)
        
        z = datum-0.5*step
        textY = et.Element('text' ,x='%g'%(x*scaleX-x_offset) ,y='%g'%(-(z)*scaleY+5))
        textY.set('font-size' , str(2.5))
        textY.set('text-anchor' , "start" )
        textY.set('fill' , "green" )
        textY.set('stroke' , "none" )
        textY.set('transform' , 'rotate(-90 %g,%g)'%(x*scaleX-x_offset,-z*scaleY+5))
        textY.text ='%.3f'%(y/1000.0)
        group.append(textY)
        
        
        z = datum-2.25*step
        textAttr = et.Element('text' ,x='%g'%(x*scaleX-x_offset) ,y='%g'%(-(z)*scaleY+5))
        textAttr.set('font-size' , str(2.5))
        textAttr.set('text-anchor' , "start" )
        textAttr.set('fill' , "green" )
        textAttr.set('stroke' , "none" )
        textAttr.set('transform' , 'rotate(-90 %g,%g)'%(x*scaleX-x_offset,-z*scaleY+5))
        textAttr.text ='%s'%('p'+str(i).zfill(2))
        group.append(textAttr)
    
    # Contour Line
    for i in range(2,len(data)+1):
        x1 = (float( data[ 'p'+str(i-1).zfill(2) ][0] ))*1000
        y1 = (float( data[ 'p'+str(i-1).zfill(2) ][1] ))*1000
        x2 = (float( data[ 'p'+str(i).zfill(2) ][0] ))*1000
        y2 = (float( data[ 'p'+str(i).zfill(2) ][1] ))*1000
        line1 =  et.Element('line' , x1='%g'%(x1*scaleX) ,y1='%g'%(-y1*scaleY) ,
                                  x2='%g'%(x2*scaleX) ,y2='%g'%(-y2*scaleY),
                 stroke= 'green' )
        line1.set('stroke-width' , '0.55') 
        group.append(line1)
    y = (float( data[ 'p'+str(i-1).zfill(2) ][1] ))*1000 
    text1 = et.Element('text' ,x='0' ,y='%f'%( -y*scaleY-10))
    text1.set('font-size' , str(4))
    text1.text = 'Section%s'%iSection
    group.append(text1)
    
    x1 = -1250
    x2 = (float( data[ 'p'+str( len(data)  ).zfill(2) ][0] ))*1000 +500
    baseline1 =  et.Element('line' , x1='%g'%(x1*scaleX) ,y1='%g'%(-datum*scaleY) ,
                                  x2='%g'%(x2*scaleX) ,y2='%g'%(-datum*scaleY),
                 stroke= 'black' )
    baseline1.set('stroke-width' , '0.5') 
    group.append(baseline1)
    
    
    for i in range(0,4):
        y2 = datum-step*i
        baseline2 =  et.Element('line' , x1='%g'%(x1*scaleX) ,y1='%g'%(-y2*scaleY) ,
                                      x2='%g'%(x2*scaleX) ,y2='%g'%(-y2*scaleY),
                     stroke= 'black' )
        baseline2.set('stroke-width' , '0.25') 
        group.append(baseline2)
    
    x = -1200
    z = datum-0.25*step
    textYLabel = et.Element('text' ,x='%g'%(x*scaleX) ,y='%g'%(-(z)*scaleY+5))
    textYLabel.set('font-size' , str(3.5))
    textYLabel.set('text-anchor' , "start" )
    textYLabel.set('fill' , "green" )
    textYLabel.set('stroke' , "none" )
    textYLabel.text ='Y(m)'
    group.append(textYLabel)
    
    z = datum-1.25*step
    textXLabel = et.Element('text' ,x='%g'%(x*scaleX) ,y='%g'%(-(z)*scaleY+5))
    textXLabel.set('font-size' , str(3.5))
    textXLabel.set('text-anchor' , "start" )
    textXLabel.set('fill' , "green" )
    textXLabel.set('stroke' , "none" )
    textXLabel.text ='X(m)'
    group.append(textXLabel)
    
    z = datum-2.25*step
    textAttrLabel = et.Element('text' ,x='%g'%(x*scaleX) ,y='%g'%(-(z)*scaleY+5))
    textAttrLabel.set('font-size' , str(3.5))
    textAttrLabel.set('text-anchor' , "start" )
    textAttrLabel.set('fill' , "green" )
    textAttrLabel.set('stroke' , "none" )
    textAttrLabel.text ='Attributes'
    group.append(textAttrLabel)
    
    # x-ticks
    xMax = float( data[ 'p'+str( len(data)  ).zfill(2) ][0] )
    n = int( round((xMax*10)/25 ,0) )
    z = datum-3*step
    for i in range(0,n+1):
        x = i*2.5 *1000
        if (x/1000)<(xMax+0.75):
            tick = et.Element('line' , x1='%g'%(x*scaleX) ,y1='%g'%(-(z)*scaleY) ,
                                          x2='%g'%(x*scaleX) ,y2='%g'%(-(z)*scaleY+3),
                         stroke= 'black' )
            tick.set('stroke-width' , '0.25') 
            group.append(tick)
            text2 = et.Element('text' ,x='%g'%(x*scaleX) ,y='%g'%(-(z)*scaleY+6))
            text2.set('font-size' , str(2.5))
            text2.set('text-anchor' , "middle" )
            text2.text ='%.1f'%(x/1000)
            group.append(text2)
    
    # y-tick
    #Msg("mixZ=%f\n"%minZ)
    x = -0.25 *1000
    z1 = datum -3*step
    Msg('datum=%f\n'%datum)
    axisY =  et.Element('line' , x1='%g'%(x*scaleX) ,y1='%g'%(-z1*scaleY) ,
                                  x2='%g'%(x*scaleX) ,y2='%g'%(-(z1+4000)*scaleY) ,
                 stroke= 'black' )
    axisY.set('stroke-width' , '0.25') 
    group.append(axisY)
    x=-250
    for i in range(1,5):
        z= float(datum)+i*500
        tick = et.Element('line' , x1='%g'%(x*scaleX) ,y1='%g'%(-(z)*scaleY) ,
                                      x2='%g'%(x*scaleX-3) ,y2='%g'%(-(z)*scaleY),
                     stroke= 'black' )
        tick.set('stroke-width' , '0.25') 
        group.append(tick)
        text3 = et.Element('text' ,x='%g'%(x*scaleX-4) ,y='%g'%(-(z)*scaleY))
        text3.set('font-size' , str(2.5))
        text3.set('text-anchor' , "end" )
        text3.set('alignment-baseline' , "middle" )
        text3.text ='%.1f'%(z/1000)
        group.append(text3)
        # check dashed line
        if True:
            tickDashed = et.Element('line' , x1='-4' ,y1='%g'%(-(z)*scaleY) ,
                                      x2='%g'%(x2*scaleX) ,y2='%g'%(-(z)*scaleY),
                     stroke= 'blue' )
            tickDashed.set('stroke-width' , '0.18')
            tickDashed.set('stroke-dasharray' , '2 1 0.5 1')
            #tickDashed.set('stroke-dasharray' , '1 0.5 0.25 0.5')
            group.append(tickDashed)
    
    
    
    #Msg(et.tostring(svg)  )
    svgSymbol.Symbol=et.tostring(svg)    
RiverCrossSectionSVG2.png
RiverCrossSectionSVG2.png (163.98 KiB) Viewed 2858 times
RiverCrossSectionSVG2pdf.png
RiverCrossSectionSVG2pdf.png (96.94 KiB) Viewed 2858 times
User avatar
microelly2
Veteran
Posts: 4691
Joined: Tue Nov 12, 2013 4:06 pm
Contact:

Re: Cross section river profiles

Post by microelly2 »

chakkree wrote: Wed Jan 03, 2018 3:54 am Add axis and x,y data label to svg string.
Looks good, may I add your script with some parameterisation into my geodat workbench?
User avatar
chakkree
Posts: 327
Joined: Tue Jun 30, 2015 12:58 am
Location: Bangkok Thailand

Re: Cross section river profiles

Post by chakkree »

microelly2 wrote: Wed Jan 03, 2018 9:40 am Looks good, may I add your script with some parameterisation into my geodat workbench?
Thank you. :D
I'm very glad, if this macro is used in geodat wb.
thschrader
Veteran
Posts: 3006
Joined: Sat May 20, 2017 12:06 pm
Location: Germany

Re: Cross section river profiles

Post by thschrader »

I could not resist...CcfOF-wb
here_comes_the_flood.gif
here_comes_the_flood.gif (261.86 KiB) Viewed 2801 times
User avatar
chakkree
Posts: 327
Joined: Tue Jun 30, 2015 12:58 am
Location: Bangkok Thailand

Re: Cross section river profiles

Post by chakkree »

thschrader wrote: Wed Jan 03, 2018 6:53 pm I could not resist...CcfOF-wb
Wow! Cool! :o
User avatar
Kunda1
Veteran
Posts: 13447
Joined: Thu Jan 05, 2017 9:03 pm

Re: Cross section river profiles

Post by Kunda1 »

thschrader wrote: Wed Jan 03, 2018 6:53 pm I could not resist...CcfOF-wb
here_comes_the_flood.gif
@thschader for posterity, do you mind leaving a step-by-step instruction of how you achieved this thing of awesomeness?
Alone you go faster. Together we go farther
Please mark thread [Solved]
Want to contribute back to FC? Checkout:
'good first issues' | Open TODOs and FIXMEs | How to Help FreeCAD | How to report Bugs
Post Reply