awkgawk

convert co-ordinate d-m-s to decimal degrees using awk


My input is a tab-separated text file with lat long in D-M-S. I require output to be in decimal degrees I have code in php, but this is very slow to calculate. Can this be done quicker using awk?

node    name    id  latitude    longitude   seq
nodex   name1   70  N53-24-31.126   W6-20-46.982    59126
nodex   name2   173 N53-20-28.885   W6-14-52.400    16190X
nodex   name3   173 N53-20-28.885   W6-14-52.400    16191T

My PHP code with Formula:

if ($dirLat == 'N') {$signLat = '+';} Else {$signLat = '-';}
if ($dirLat == 'E') {$signLon = '+';} Else {$signLon = '-';}
$latitudeDecimalDeg = $signLat . ($degLat + ($minLat/60) + ($secLat/3600));
$longitudeDecimalDeg = $signLon . ($degLon + ($minLon/60) + ($secLon/3600));

Solution

  • I am pretty certain that awk would be quicker. This is fairly easily accomplished with awk, split each field with substr and split. I turned it into a function for easier reuse:

    function dms2deg(s) {
      dir = (substr(s, 1, 1) ~ /^[NE]/) ? 1 : -1
      dms =  substr(s, 2)
      split(dms, arr, "-")
      return dir * (arr[1] + arr[2]/60 + arr[3]/3600)
    }
    

    If you have put the above into dms2deg and the data is in infile, you would use awk like this:

    awk -f dms2deg -e 'NR>1 { print dms2deg($4), dms2deg($5) }' infile
    

    Output:

    53.4086 -6.34638
    53.3414 -6.24789
    53.3414 -6.24789
    

    Or if you wanted to replace the existing fields:

    awk -f dms2deg -e 'NR>1 { $4 = dms2deg($4); $5 = dms2deg($5) } $1=$1' infile
    

    Output:

    node name id latitude longitude seq
    nodex name1 70 53.4086 -6.34638 59126
    nodex name2 173 53.3414 -6.24789 16190X
    nodex name3 173 53.3414 -6.24789 16191T
    

    Note that this does not preserve white-space, however column would take care of that:

    awk -f dms2deg -e 'NR>1 { $4 = dms2deg($4); $5 = dms2deg($5) } $1=$1' infile | column -t
    

    Output:

    node   name   id   latitude  longitude  seq
    nodex  name1  70   53.4086   -6.34638   59126
    nodex  name2  173  53.3414   -6.24789   16190X
    nodex  name3  173  53.3414   -6.24789   16191T