English

How To: Make polyline features look smoother using Avenue

Summary

Polylines with very few vertices can look blocky. You can smooth the appearance of these lines by creating more gentle curves; this is know as a spline operation. Spline adds more vertices at places where the line changes direction. This article provides two Avenue scripts that spline selected polyline or polylinez features of the first active theme of the active view.

Procedure

  1. Open a new script window.

    A. Activate the Project window.
    B. Click the Scripts icon.
    C. Click New.


  2. Paste the following code into the new script window:

    Code:
    '-- SPLINE POLYLINE FEATURES
    '
    '-- spline_polyline.ave
    '
    '-- This script uses a basic combination of densifying the
    '-- polyline and implementing the Bezier's spline
    '-- method on the polyline. This script needs a view
    '-- and the target theme active.

    '-- A combination of these two variables will produce different
    '-- results depending on the nature and scale of the Polyline.
    densityfactor = 0.025 '-- 0.000 to 1.000 only
    iterations = 15 '-- 1 to 100 works best

    v = av.getactivedoc
    vg = v.getgraphics
    thm = v.getactivethemes.get(0)
    ftb = thm.getftab
    if(ftb.getshapeclass.getclassname <> "PolyLine") then
    msgbox.error("We can only spline PolyLine features.","")
    return nil
    end

    for each selrec in ftb.getselection

    thepolyline = ftb.returnvalue(ftb.findfield("Shape"),selrec)

    howdense = thepolyline.returnlength*densityfactor
    oldplist = thepolyline.returndensified(howdense).aslist

    newplist = {}
    for each apart in oldplist
    for each ap in apart
    newplist.add(ap)
    end
    end

    for each x in 1..iterations
    newerplist = {}
    for each i in 0..(newplist.count-1)
    if(i = 0) then
    newerplist.add(newplist.get(i))
    elseif(i = (newplist.count-1)) then
    newerplist.add(newplist.get(i))
    break
    end
    newp = line.make(newplist.get(i),newplist.get(i+1)).returncenter
    newerplist.add(newp)
    end
    newplist = newerplist.deepclone
    end

    newpolyline = polyline.make({newplist})

    gs = graphicshape.make(newpolyline)
    asymbol = symbol.make(#SYMBOL_PEN)
    asymbol.setsize(2)
    asymbol.setcolor(color.getred)
    gs.setsymbol(asymbol)
    vg.add(gs)
    end
    v.invalidate

  3. Attach the script to the button on the View GUI.

    A. Compile the script.
    B. Switch to the Project window.
    C. Select Customize from the Project menu.
    D. On the Customize dialog box, click the Type dropdown arrow and click View.
    E. Select Buttons under Category.
    F. Click the New button.
    G. Double-click the Click property in the Customize dialog box.
    H. Type the name of the script in the Script Manager and click Select.
    I. Close the Customize dialog box.

    For more information, see "Customize dialog box" in ArcView Help.

  4. Open the view and make the polyline theme active.
  5. Select the polyline features to spline.
  6. Click the new button. The script will create a graphic polyline.

    Note:
    For polylinez features, use the same steps above, except turn on the 3D Analyst extension and use the code below.


    Code:
    '-- SPLINE POLYLINE OR POLYLINEZ FEATURES:
    '
    '-- spline_polylinez.ave
    '
    '-- This script uses a basic combination of densifying the
    '-- polyline and implementing the Bezier's spline
    '-- method on the polyline. This script needs a view
    '-- and the target theme active.

    '-- Note: The 3D Analysis Extension must be loaded
    '

    '-- A combination of these two variables will produce
    '-- different results depending on the nature and scale of the Polyline.
    densityfactor = 0.025 '-- 0.000 to 1.000 only
    iterations = 15 '-- 1 to 100 works best

    v = av.getactivedoc
    vg = v.getgraphics
    thm = v.getactivethemes.get(0)
    ftb = thm.getftab
    if(ftb.getshapeclass.getclassname = "PolyLine") then
    hasz = false
    elseif(ftb.getshapeclass.getclassname = "PolyLineZ") then
    hasz = true
    else
    msgbox.error("We can only spline PolyLine of PolyLineZ features.","")
    return nil
    end

    for each selrec in ftb.getselection

    thepolyline = ftb.returnvalue(ftb.findfield("Shape"),selrec)

    howdense = thepolyline.returnlength*densityfactor
    oldplist = thepolyline.returndensified(howdense).aslist

    newplist = {}
    for each apart in oldplist
    for each ap in apart
    newplist.add(ap)
    end
    end

    for each x in 1..iterations
    newerplist = {}
    for each i in 0..(newplist.count-1)
    if(i = 0) then
    newerplist.add(newplist.get(i))
    elseif(i = (newplist.count-1)) then
    newerplist.add(newplist.get(i))
    break
    end
    if(hasz) then
    newp = linez.make(newplist.get(i),newplist.get(i+1)).returncenter
    else
    newp = line.make(newplist.get(i),newplist.get(i+1)).returncenter
    end
    newerplist.add(newp)
    end
    newplist = newerplist.deepclone
    end

    if(hasz) then
    newpolyline = polylinez.make({newplist})
    else
    newpolyline = polyline.make({newplist})
    end

    gs = graphicshape.make(newpolyline)
    asymbol = symbol.make(#SYMBOL_PEN)
    asymbol.setsize(2)
    asymbol.setcolor(color.getred)
    gs.setsymbol(asymbol)
    vg.add(gs)
    end
    v.invalidate