English

How To: Determine the bearing angle of all segments in a polyline theme

Summary

These scripts determine the bearing angle (or azimuth) of lines in a polyline theme.

Procedure

Use Avenue to calculate the bearing of a line using the following inverse trigonometric functions:

    
     angle = arcsine(opp/hyp) 
     angle = arccosecant(hyp/opp) 
     angle = arccosine(adj/hyp) 
     angle = arcsecant(hyp/adj) 
     angle = arctangent(opp/adj) 
     angle = arccotangent(adj/opp) 
Side Definitions
     (hyp) Hypotenuse - side opposite the right angle 
     (opp) Opposite - side opposite the angle of interest 
     (adj) Adjacent - remaining side

The difference in x,y location of each line's end-points represent the side.

To complete the calculation, a constant needs to be added to the angle. The value of the constant corresponds to the orientation of the line. The result will be a value between 0 and 360 degrees.

The following scripts create a copy of the original Polyline theme with an additional field containing the bearing value. The scripts use the necessary constant to calculate due north as 0 degrees, due east as 90 degrees, due south as 180 degrees, and due west as 270 degrees. To use the scripts:

1. Copy the Create Output, Bearing, and Explode scripts into separate Script Editors.
2. Assign each Script Editor document the respective name (i.e. 'Bearing'). Change document names using the Properties dialog box.

  • To rename a View document:

  1. Click View > Properties.
  2. Type a new name in the Name field.
  3. Click OK
  • To rename a Table document:
  1. Click Table > Properties.
  2. Type a new name in the Title field.
  3. Click OK
  • To rename a Chart document:
  1. Click Chart> Properties.
  2. Type a new name in the Name field.
  3. Click OK
  • To rename a Layout document:
  1. Click Layout > Properties.
  2. Type a new name in the Name field.
  3. Click OK
  • To rename a Script document:
  1. Click Script > Properties.
  2. Enter a new name in the Name field.
  3. Click OK
3. Attach the Create Output script to a button on the View GUI.
  1. Compile the script.
  2. Switch to the Project window.
  3. Select Customize from the Project menu.
  4. On the Customize dialog box, click the Type dropdown arrow and click View.
  5. Select Buttons under Category.
  6. Click the New button.
  7. Double-click the Click property in the Customize dialog box.
  8. Type the name of the script in the Script Manager and click Select.
  9. Close the Customize dialog box.
For more information, see "Customize dialog box" in ArcView Help.
 
4. Make the polyline theme active. The attribute table of the polyline theme must contain a field with a unique value.
Steps to add a unique values field to a table.
  1. Click Table > Start Editing.
    Note:
    ArcView cannot edit Delimited Text tables. You must convert Delimited Text tables to the dBase or INFO format. See Related Information below.
  2. Click Edit > Add Field.
  3. Type Unique_ID in the Name text box on the Field Definition dialog box.
  4. Select Number under the Type dropdown list.
  5. Type 10 in the Width text box.
  6. Type 0 (zero) in the Decimal Places text box.
  7. Click OK.
  8. Click Field > Calculate.
  9. Type rec in the large text box at the bottom of the Field Calculator.
    Field Calculator

    [O-Image] Field Calculator
  10. Click OK.
  11. Click Table > Stop Editing.
  12. Click Yes when asked to save edits.
5. Click the newly added button on the View GUI.
6. Specify a directory and filename for the new shapefile and click OK.
7. Select a unique ID field and click OK.
Code:
'--- Create output script

v = av.getactivedoc
t = v.getactivethemes.get(0)
ft = t.getftab
gl = v.getgraphics

def = av.GetProject.MakeFileName("theme", "shp")
def = FileDialog.Put(def, "*.shp", "Output Theme")
if (def = nil) then return nil end

idfield = msgbox.listasstring(ft.getfields,
  "The field must contain unique values", 
  "Select Join Field")
if (idfield = nil) then return nil end

tbl = FTab.MakeNew(def, polyline)
fld = idfield.clone
anglefld = Field.Make("bearing", #FIELD_DECIMAL, 8, 4)
fld.SetVisible( TRUE )
tbl.AddFields({fld, anglefld})
theTheme = FTheme.Make(tbl)

countlist = {}

if (ft.getselection.count = 0) then
  ft.getselection.setall
end

for each rec in ft.getselection
  id = ft.returnvalue(idfield, rec)
  pl = ft.returnvalue(ft.findfield("shape"),rec)
  plist = pl.asmultipoint.aslist
  
  for each i in 0..(plist.count - 2)
    tbl.addrecord       
    l = av.run("explode", {plist, i})
    thebearing = av.run("bearing", {plist, i})
    gs = graphicshape.make(l)
    tbl.setvalue(tbl.findfield("shape"), countlist.count, l)
    tbl.setvalue(fld, countlist.count, id)
    tbl.setvalue(tbl.findfield("bearing"), countlist.count, thebearing)
    countlist.add("added")
  end
end

v.addtheme(thetheme)

thetheme.stopediting(true)
tbl.seteditable(false)
v.invalidate

'--- End of script 
Code:
'--- Bearing script

plist = self.get(0)
i = self.get(1)
p1 = plist.get(i)
p2 = plist.get(i+1)

theX1 = p1.GetX
theY1 = p1.Gety
 
theX2 = p2.GetX
theY2 = p2.GetY
 
theH = theX2 - theX1  '--- where theH is the horizontal difference, or delta x
theV = theY2 - theY1  '--- where theV is the vertical difference, or delta y

theLength = ((theH * theH) + (theV * theV)).SQRT
theAngle = (theV/theLength).Abs.Acos.AsDegrees 

if ((theH = 0) and (theV > 0 ))  then
  constant = 0
  theBearing = constant - theAngle
end

if ((theH > 0 ) and (theV > 0)) then 
  constant = 0 
  theBearing = theAngle + constant
end '--- 1st quadrant

if ((theH < 0) and (theV  >= 0)) then '--- 2nd quadrant
  constant = 360
  theBearing = constant - theAngle.Abs
end 

if ((theH <= 0) and (theV <= 0)) then '--- 3rd quadrant
  constant = 180
  theBearing = theAngle.Abs + constant
end 

if ((theH >= 0) and (theV <= 0)) then 
  constant = 180 '--- 4th quadrantt 
  theBearing = constant - theAngle.abs
end

return thebearing

'--- End of script 
Code:
'--- Explode script

plist = self.get(0)
i = self.get(1)

p1 = plist.get(i)
p2 = plist.get(i+1)
l = polyline.make({{p1, p2}})

return l

'--- End of script 
Polylines that have more than one segment are exploded into the new shapefile with one record per line segment. You can use the unique ID field to join attribute information of the original shapefile to the new shapefile.