summaryrefslogtreecommitdiff
path: root/ipl/gpacks/tiger/tgrtrack.icn
blob: 07a25f2d0c8a3aece751b88d12bc0cdd54fbc2d1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
############################################################################
#
#	File:     tgrtrack.icn
#
#	Subject:  Program to translate "track log" files into TIGER chains
#
#	Author:   William S. Evans and Gregg M. Townsend
#
#	Date:     June 9, 2000
#
############################################################################
#
#  tgrtrack reads a fixed field length file containing track data from
#  a GPS receiver and outputs a "line chain" (.lch) format file (see
#  tgrprep) that can then be viewed using tgrmap.
#
#  Usage:  tgrtrack file
#
#	Input is a text file of coordinates such as those from a GPS
#	receiver.  Lines ending with two decimal values are interpreted
#	as specifying latitude and longitude in that order.
#	Lines without data indicate breaks between paths.
#
#	Output is a line chain file
#
############################################################################
#
#  Links:  numbers, strings
#
############################################################################

link numbers
link strings

global deltas
global curlon, curlat
global maxlon, minlon, maxlat, minlat

procedure main(args)
   local n, trackfile

   *args = 1 | stop("usage: ", &progname, " GPStrackfile")
   trackfile := open(args[1]) | stop("can't open ", args[1])
   n := llrange(trackfile)
   write("        ", rz(convertLon(minlon)), rz(convertLat(maxlat)))
   write("        ", rz(convertLon(maxlon)), rz(convertLat(minlat)))
   writeLCH(trackfile)
   return
end

procedure convertLat(n)
#  convert latitude from decimal degrees to fraction of semicircle
#  south of North Pole, as 0000000 to 9999999.
   static m
   initial m := 9999999 / 180.0
   return round(m * (90.0 - n))
end

procedure convertLon(n)
#  convert longitude to fraction of circle east of Greenwich,
#  as 0000000 to 9999999.
   static m
   initial m := 9999999 / 360.0

   n := real(n)
   if n < 0 then
      n +:= 360.0
   return round(m * n)
end


procedure writeLCH(trackfile)
   local x, y, line, n, trackPts, dim, startlon, startlat, lon, lat, w

   n := 1
   trackPts := 0
   deltas := ""

   seek(trackfile, 1) | fail
   repeat {
      line := read(trackfile) | "stop"
      every put(w := [], words(line))
      if (lat := real(w[-2])) & (lon := real(w[-1])) &
         (-90. <= lat <= 90.) & (-180. <= lon <= 180.) then {
            y := convertLat(lat)
            x := convertLon(lon)
            if (trackPts = 0) then {	# starting a new track
               deltas := ""
               startlon := minlon := maxlon := curlon := x
               startlat := minlat := maxlat := curlat := y
               }
            else {
               drawto(x, y)
               }
            trackPts +:= 1
            }
         else {
            if trackPts >= 2 then {
               dim := startlon - minlon
               dim <:= maxlon - startlon
               dim <:= startlat - minlat
               dim <:= maxlat - startlat
               dim >:= 9999
               write("T000|GPS Track ", n, "|", right(dim, 4),
                     rz(startlon), rz(startlat), deltas)
               n +:= 1
               }
            trackPts := 0
            }
      if w[1] == "stop" then break
      }
   return
end

procedure drawto(lon, lat)
   local dlon, dlat

   dlon := lon - curlon
   dlat := lat - curlat

   if abs(dlon | dlat) >= 5000 then {
      drawto(curlon + dlon / 2, curlat + dlat / 2)
      drawto(lon, lat)
      }
   else {
      deltas ||:= rz(dlon + 5000, 4)
      deltas ||:= rz(dlat + 5000, 4)
      curlon := lon
      curlat := lat
      minlon >:= lon
      maxlon <:= lon
      minlat >:= lat
      maxlat <:= lat
      }
   return
end


procedure rz(v, n)
#  right-justify value in n digits with zero fill
   /n := 7
   return right(v, n, "0")
end


procedure llrange(f)
#  scan f to set min/max lon/lat, returning record count
   local line, n, lon, lat, w

   minlon := +180.0
   maxlon := -180.0
   minlat := +90.0
   maxlat := -90.0
   n := 0

   seek(f, 1)
   while line := read(f) do line ? {
      every put(w := [], words(line))
      if (lat := real(w[-2])) & (lon := real(w[-1])) &
         (-90. <= lat <= 90.) & (-180. <= lon <= 180.) then {
            minlon >:= lon
            maxlon <:= lon 
            minlat >:= lat 
            maxlat <:= lat
            }
      }
   return n
end