TBC Macros and Extensions

 View Only
Expand all | Collapse all

Linestring

  • 1.  Linestring

    Posted 10-24-2024 13:37
    Edited by Lance Crumbliss 10-24-2024 13:39

    Hello,

    I'm iterating over the WorldView and for right now, just observing properties of objects it contains.  In the project I'm using for testing there are some LineString types ( Trimble.Vce.Alignment.Linestring.Linestring ).  I find it interesting that there doesn't seem to be a way to actually iterate over the vertices of the line.  There is an Anchor point, but nothing else as far vertices go.  Why is that?  Am I missing something?

    Furthermore, in the ObjectBrowser it shows A LOT more public properties and methods than what shows in the QuickWatch window when debugging on a LineString.   Why is that?



    ------------------------------
    Lance Crumbliss
    ------------------------------



  • 2.  RE: Linestring

    Posted 10-25-2024 15:40

    I'd say the two lists object watcher and object browser look the same.

    The watcher won't show you methods, you'll have to look those up in the object browser.

    With Linestrings you usually don't work with the linestring itself. A linestring is made up of "Elements" which themselves are made up of vertices/length/pointnumber information etc., use "GetElements" to retrieve that list. A linestring is not necessarily made up of vertices only, it can have curves between the vertices, the vertices can be survey points with their own serial number. 

    You usually convert a linestring into a  Trimble.Vce.Geometry.PolySeg.PolySeg object first. This is very easy, the linestring itself provides this method.

    A PolySeg is an internal, computational object only and won't end up in the TBC project. It does offer much more methods, i.e. offset, trim, extend, computation to/from the line, intersect linearize, mirror, scale, transform (in other words translate/shift) ....

    What you're interested in would be one of those, Points3D, Nodes, ToNodeArray, ToPoint3DArray

    My usual copy/paste code is

    polyseg = l.ComputePolySeg()
    polyseg = polyseg.ToWorld() # in case the linestring has a localized user defined coordinate system
    polyseg_v = l.ComputeVerticalPolySeg()

    The vertical polyseg is the vertical profile of the linestring as in the standard TBC profile viewer. This can return empty, make sure to cover this exception in your code.

    you can create an empty PolySeg like this, and fill it

    from Trimble.Vce.Geometry import PolySeg
    
    polyseg = PolySeg.PolySeg()
    
    # you can add points one by one 
    polyseg.Add(Point3D.MidPoint(p1, p2))
    
    # or as list 
    corners = List[Point3D]()
    corners.Add(Point3D(0,0,0))
    polyseg.Add(corners)
    
    # or different types of segments
    from Trimble.Vce.Geometry.PolySeg.Segment import Segment, Line as SegmentLine, Arc as ArcSegment, Parabola as ParabolaSegment
    try:
        #2023.10
        from Trimble.Vce.Geometry import FergusonSpline
    except:
        #5.90
        from Trimble.Vce.Geometry.PolySeg.Segment import FergusonSpline
    
    
    	Line 260:                                 hogpolyseg.Add(ArcSegment(Point3D(startstation, 0), Point3D(endstation, 0), -1*hogradius))
    	Line 273:                                     hogpolyseg.Add(ArcSegment(Point3D(startstation - fulllength, 0), Point3D(endstation, 0), -1*hogradius))
    	Line 275:                                     hogpolyseg.Add(ArcSegment(Point3D(startstation, 0), Point3D(endstation + fulllength, 0), -1*hogradius))
    	Line 289:                                 hogpolyseg.Add(ParabolaSegment(Point3D(startstation, 0), Point3D(halflength, para_el), Point3D(fulllength, 0)))
    	Line 300:                                     hogpolyseg.Add(ParabolaSegment(Point3D(startstation - fulllength, 0), Point3D(startstation, para_el), Point3D(fulllength, 0)))
    	Line 302:                                     hogpolyseg.Add(ParabolaSegment(Point3D(startstation, 0), Point3D(fulllength, para_el), Point3D(endstation + fulllength, 0)))
    	Line 309:                                 hogpolyseg.Add(SegmentLine(Point3D(startstation, hog), Point3D(endstation, 0)))
    	Line 311:                                 hogpolyseg.Add(SegmentLine(Point3D(startstation, 0), Point3D(endstation, hog)))
    	Line 356:                                 hogpolyseg.Add(fixedfergusonpts)
    	Line 412:                                 finalhogpolyseg.Add(finalhogel)

    and once you are done you add that geometry to a linestring which is added to the project database and drawn on the screen.

    !!! if you want to manipulate an existing linestring, you'll have to empty it first using "RemoveElementAt" or use "ReplaceElementAt"

    A linestring can be created two ways.

    Either you add elements, like straight/curve/pointid to the linestring.

                            l = wv.Add(clr.GetClrType(Linestring))
                            l.Name = 'X-Axis'
                            l.Color = Color.LemonChiffon
                            l.Layer = self.layerpicker.SelectedSerialNumber
                            
                            e = ElementFactory.Create(clr.GetClrType(IStraightSegment), clr.GetClrType(IXYZLocation))
                            e.Position = draworigin
                            l.AppendElement(e)
    
                            e = ElementFactory.Create(clr.GetClrType(IStraightSegment), clr.GetClrType(IXYZLocation))
                            e.Position = draworigin + Vector3D(limits.X, 0, 0)
                            l.AppendElement(e)
    
    
    example from my convert to point based macro
                                    # create new elements
                                    if etype.Name == "XYZStraightElement":
                                        enew = ElementFactory.Create(clr.GetClrType(IStraightSegment), clr.GetClrType(IPointIdLocation))
                                    if etype.Name == "XYZSmoothCurveElement":
                                        enew = ElementFactory.Create(clr.GetClrType(ISmoothCurveSegment), clr.GetClrType(IPointIdLocation))
                                    if etype.Name == "XYZBestFitArcElement":
                                        enew = ElementFactory.Create(clr.GetClrType(IBestFitArcSegment), clr.GetClrType(IPointIdLocation))
                                    if etype.Name == "XYZArcElement":
                                        enew = ElementFactory.Create(clr.GetClrType(IArcSegment), clr.GetClrType(IPointIdLocation))
                                        enew.LargeSmall = e.LargeSmall
                                        enew.LeftRight = e.LeftRight
                                        enew.Radius = e.Radius
                                    if etype.Name == "XYZPIArcElement":
                                        enew = ElementFactory.Create(clr.GetClrType(IPIArcSegment), clr.GetClrType(IPointIdLocation))
                                        enew.Radius = e.Radius
                                    if etype.Name == "XYZTangentArcElement":
                                        enew = ElementFactory.Create(clr.GetClrType(ITangentArcSegment), clr.GetClrType(IPointIdLocation))
                                        enew.TangentType = e.TangentType
    
                                    l.AppendElement(enew)
    

    or you compose it from PolySegs

    l = wv.Add(clr.GetClrType(Linestring))
    l.Append(newpolyseg, newpolyseg_v, False, False)
    
    # you don't necessarily need a vertical profile, i.e. if you created the horizontal polyseg with 3D points
    l.Append(newpolyseg, None, False, False)

    https://github.com/RonnySchneider/SCR_Macros_Public

    My macros "SCR_MergeLineProfile" and "SCR_AddHogToLine" show multiple ways how to work with linestrings and polysegs. Was all derived through trial and fail from the original TBC sample macros.



    ------------------------------
    Ronny Schneider
    ------------------------------



  • 3.  RE: Linestring

    Posted 10-28-2024 05:00

    Thanks for that very detailed reply!  



    ------------------------------
    Lance Crumbliss
    ------------------------------



  • 4.  RE: Linestring

    Posted 10-31-2024 14:34

    I try to figure out as much as I can on my own so I don't spam the group with questions, but I've been trying to figure this particular thing out for a while now.  

    I can see the line, and the points that make up that line in the watch window.  But when I look at the values of the XYZ for the points, they don't match what is in the TBC property window for the same point.  My hunch is thats because of a difference in the coordinate system used in collection vs the coordinate system of the project?  But maybe not....

    In any case, how can I get the XYZ values for a point that match what is being show in the point property window?



    ------------------------------
    Lance
    ------------------------------



  • 5.  RE: Linestring

    Posted 10-31-2024 15:21
    Edited by Ronny Schneider 10-31-2024 16:05

    You seem to be operating in the US and hence use Feet as your distance units in the drawing windows.

    BUT, TBC uses internally always meters, and that's what you see in the object watcher. Everything you import or draft is converted to meters for the internal database and converted back for any unit displays i.e. in the properties pane.

    Usually you don't have to worry about it. i.e. when using coordinate input fields.

    But, you'll have to convert it when creating points with given coordinates/dimensions from within the macro itself. In that case you need to convert before adding to the database.

    See this thread, specifically post 15 and 19.

    https://community.trimble.com/discussion/unit-conversion-inside-tbc-conversion-factors-used-different-than-official-ones

    Try to get the dimensions from a Wpf:CoordinateEdit/DistanceEdit/ElevationEdit field in your user interface. Those will do the conversion for you automatically.



    ------------------------------
    Ronny Schneider
    ------------------------------



  • 6.  RE: Linestring

    Posted 10-31-2024 15:41

    Thanks Ronny.  What thread were you referring to above?



    ------------------------------
    Lance
    ------------------------------



  • 7.  RE: Linestring

    Posted 10-31-2024 16:06

    Sorry, forgot to paste the link. I've changed the post.



    ------------------------------
    Ronny Schneider
    ------------------------------



  • 8.  RE: Linestring

    Posted 11-01-2024 07:35

    Thank you.  That was a very helpful thread.



    ------------------------------
    Lance
    ------------------------------