summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xxgps37
-rwxr-xr-xxgpsspeed75
2 files changed, 67 insertions, 45 deletions
diff --git a/xgps b/xgps
index 066401f2..44ea0628 100755
--- a/xgps
+++ b/xgps
@@ -3,7 +3,7 @@
'''
xgps -- test client for gpsd
-usage: xgps [-D level] [-hV?] [-l degmfmt] [-u units] [server[:port[:device]]]
+usage: xgps [-D level] [-hV?] [-l degmfmt] [-u units] [-r rotation] [server[:port[:device]]]
'''
# This code runs compatibly under Python 2 and 3.x for x >= 2.
@@ -95,7 +95,7 @@ class SkyView(Gtk.DrawingArea):
HORIZON_PAD = 40 # How much whitespace to leave around horizon
SAT_RADIUS = 5 # Diameter of satellite circle
- def __init__(self):
+ def __init__(self, rotate=0.0):
GObject.GObject.__init__(self)
self.set_size_request(400, 400)
self.cr = None # New cairo context for each expose event
@@ -104,6 +104,7 @@ class SkyView(Gtk.DrawingArea):
self.connect('draw', self.on_draw)
self.satellites = []
self.center_x = self.center_y = self.radius = None
+ self.rotate = rotate
def on_size_allocate(self, _unused, allocation):
width = allocation.width
@@ -181,6 +182,7 @@ class SkyView(Gtk.DrawingArea):
def pol2cart(self, az, el):
"Polar to Cartesian coordinates within the horizon circle."
+ az = (az - self.rotate) % 360.0
az *= (math.pi / 180) # Degrees to radians
# Exact spherical projection would be like this:
# el = sin((90.0 - el) * DEG_2_RAD);
@@ -223,14 +225,14 @@ class SkyView(Gtk.DrawingArea):
self.draw_line(x1, y1, x2, y2)
# The compass-point letters
- (x, y) = self.pol2cart(0, 0)
- self.draw_string(x, y - 10, "N")
- (x, y) = self.pol2cart(90, 0)
- self.draw_string(x + 10, y, "E")
- (x, y) = self.pol2cart(180, 0)
- self.draw_string(x, y + 10, "S")
- (x, y) = self.pol2cart(270, 0)
- self.draw_string(x - 10, y, "W")
+ (x, y) = self.pol2cart(0, -5)
+ self.draw_string(x, y, "N")
+ (x, y) = self.pol2cart(90, -5)
+ self.draw_string(x, y, "E")
+ (x, y) = self.pol2cart(180, -5)
+ self.draw_string(x, y, "S")
+ (x, y) = self.pol2cart(270, -5)
+ self.draw_string(x, y, "W")
# The satellites
self.cr.set_line_width(2)
@@ -460,8 +462,9 @@ class Base(object):
("EPD", lambda s, r: s.update_err_degrees(r, "epd")),
)
- def __init__(self, deg_type):
+ def __init__(self, deg_type, rotate=0.0):
self.deg_type = deg_type
+ self.rotate = rotate
self.conversions = unit_adjustments()
self.saved_mode = -1
self.ais_latch = False
@@ -579,7 +582,7 @@ class Base(object):
viewframe = Gtk.Frame(label="Skyview")
self.satbox.add(viewframe)
- self.skyview = SkyView()
+ self.skyview = SkyView(self.rotate)
viewframe.add(self.skyview)
self.rawdisplay = Gtk.Entry()
@@ -869,11 +872,12 @@ class Base(object):
if __name__ == "__main__":
try:
import getopt
- (options, arguments) = getopt.getopt(sys.argv[1:], "D:hl:u:V?",
+ (options, arguments) = getopt.getopt(sys.argv[1:], "D:hl:u:r:V?",
['verbose'])
debug = 0
degreefmt = 'd'
unit_system = None
+ rotate = 0.0
for (opt, val) in options:
if opt in '-D':
debug = int(val)
@@ -881,6 +885,11 @@ if __name__ == "__main__":
degreeformat = val
elif opt == '-u':
unit_system = val
+ elif opt == '-r':
+ try:
+ rotate = float(val)
+ except ValueError:
+ rotate = 0.0
elif opt in ('-?', '-h', '--help'):
print(__doc__)
sys.exit(0)
@@ -902,7 +911,7 @@ if __name__ == "__main__":
if len(args) >= 3:
device = args[2]
- base = Base(deg_type=degreefmt)
+ base = Base(deg_type=degreefmt, rotate=rotate)
base.set_units(unit_system)
try:
daemon = gps.gps(host=host,
diff --git a/xgpsspeed b/xgpsspeed
index 277b575a..29a6fc7d 100755
--- a/xgpsspeed
+++ b/xgpsspeed
@@ -228,7 +228,7 @@ class NauticalSpeedometer(Speedometer):
HEADING_SAT_GAP = 0.8
SAT_SIZE = 10 # radius of the satellite circle in skyview
- def __init__(self, speed_unit=None, maxspeed=100):
+ def __init__(self, speed_unit=None, maxspeed=100, rotate=0.0):
Speedometer.__init__(self, speed_unit)
self.connect('size-allocate', self.on_size_allocate)
self.width = self.height = 0
@@ -240,9 +240,9 @@ class NauticalSpeedometer(Speedometer):
self.satellites = []
self.last_heading = 0
self.maxspeed = int(maxspeed)
+ self.rotate = radians(rotate)
- @staticmethod
- def polar2xy(radius, angle, polex, poley):
+ def polar2xy(self, radius, angle, polex, poley):
'''convert Polar coordinate to Cartesian coordinate system
the y axis in pygtk points downward
Args:
@@ -250,6 +250,7 @@ class NauticalSpeedometer(Speedometer):
angle: azimuth from from Polar coordinate system, in radian
polex and poley are the Cartesian coordinate of the pole
return a tuple contains (x, y)'''
+ angle = (angle + self.rotate) % (pi * 2) # Note reversed sense
return (polex + cos(angle) * radius, poley - sin(angle) * radius)
def on_size_allocate(self, _unused, allocation):
@@ -306,12 +307,12 @@ class NauticalSpeedometer(Speedometer):
for i in range(11):
# draw the large ticks
alpha = (8 - i) * pi / 6
- self.cr.move_to(*NauticalSpeedometer.polar2xy(rspeed, alpha, x, y))
+ self.cr.move_to(*self.polar2xy(rspeed, alpha, x, y))
self.cr.set_line_width(radius / 100)
- self.cr.line_to(*NauticalSpeedometer.polar2xy(rspeed - s_long, alpha, x, y))
+ self.cr.line_to(*self.polar2xy(rspeed - s_long, alpha, x, y))
self.cr.stroke()
self.cr.set_line_width(radius / 200)
- xf, yf = NauticalSpeedometer.polar2xy(rspeed + 10, alpha, x, y)
+ xf, yf = self.polar2xy(rspeed + 10, alpha, x, y)
stxt = (self.maxspeed // 10) * i
self.draw_text(xf, yf, stxt, fontsize=radius / 15)
@@ -319,14 +320,14 @@ class NauticalSpeedometer(Speedometer):
# middle tick
alpha = (8 - i) * pi / 6
beta = (17 - 2 * i) * pi / 12
- self.cr.move_to(*NauticalSpeedometer.polar2xy(rspeed, beta, x, y))
- self.cr.line_to(*NauticalSpeedometer.polar2xy(rspeed - s_middle, beta, x, y))
+ self.cr.move_to(*self.polar2xy(rspeed, beta, x, y))
+ self.cr.line_to(*self.polar2xy(rspeed - s_middle, beta, x, y))
# short tick
for n in range(10):
gamma = alpha + n * pi / 60
- self.cr.move_to(*NauticalSpeedometer.polar2xy(rspeed, gamma, x, y))
- self.cr.line_to(*NauticalSpeedometer.polar2xy(rspeed - s_short, gamma, x, y))
+ self.cr.move_to(*self.polar2xy(rspeed, gamma, x, y))
+ self.cr.line_to(*self.polar2xy(rspeed - s_short, gamma, x, y))
# draw the heading arc
self.cr.new_sub_path()
@@ -342,7 +343,7 @@ class NauticalSpeedometer(Speedometer):
label = str(n * 90)
# self.cr.set_source_rgba(0, 1, 0)
# radius * (1 + NauticalSpeedometer.HEADING_SAT_GAP),
- tbox_x, tbox_y = NauticalSpeedometer.polar2xy(
+ tbox_x, tbox_y = self.polar2xy(
radius * 0.88,
(1 - n) * pi / 2,
x, y)
@@ -359,13 +360,14 @@ class NauticalSpeedometer(Speedometer):
self.cr.set_source_rgba(0, 0, 0)
self.cr.arc(x, y, skyradius * 2 / 3, 0, 2 * pi)
+ self.cr.move_to(x + skyradius / 3, y) # Avoid line connecting circles
self.cr.arc(x, y, skyradius / 3, 0, 2 * pi)
# draw the cross hair
- self.cr.move_to(x - skyradius, y)
- self.cr.line_to(x + skyradius, y)
- self.cr.move_to(x, y - skyradius)
- self.cr.line_to(x, y + skyradius)
+ self.cr.move_to(*self.polar2xy(skyradius, 1.5 * pi, x, y))
+ self.cr.line_to(*self.polar2xy(skyradius, 0.5 * pi, x, y))
+ self.cr.move_to(*self.polar2xy(skyradius, 0.0, x, y))
+ self.cr.line_to(*self.polar2xy(skyradius, pi, x, y))
self.cr.set_line_width(radius / 200)
self.cr.stroke()
@@ -376,22 +378,22 @@ class NauticalSpeedometer(Speedometer):
# draw the large ticks
for i in range(12):
agllong = i * pi / 6
- self.cr.move_to(*NauticalSpeedometer.polar2xy(radius - long_inset, agllong, x, y))
- self.cr.line_to(*NauticalSpeedometer.polar2xy(radius, agllong, x, y))
+ self.cr.move_to(*self.polar2xy(radius - long_inset, agllong, x, y))
+ self.cr.line_to(*self.polar2xy(radius, agllong, x, y))
self.cr.set_line_width(radius / 100)
self.cr.stroke()
self.cr.set_line_width(radius / 200)
# middle tick
aglmid = (i + 0.5) * pi / 6
- self.cr.move_to(*NauticalSpeedometer.polar2xy(radius - mid_inset, aglmid, x, y))
- self.cr.line_to(*NauticalSpeedometer.polar2xy(radius, aglmid, x, y))
+ self.cr.move_to(*self.polar2xy(radius - mid_inset, aglmid, x, y))
+ self.cr.line_to(*self.polar2xy(radius, aglmid, x, y))
# short tick
for n in range(1, 10):
aglshrt = agllong + n * pi / 60
- self.cr.move_to(*NauticalSpeedometer.polar2xy(radius - short_inset, aglshrt, x, y))
- self.cr.line_to(*NauticalSpeedometer.polar2xy(radius, aglshrt, x, y))
+ self.cr.move_to(*self.polar2xy(radius - short_inset, aglshrt, x, y))
+ self.cr.line_to(*self.polar2xy(radius, aglshrt, x, y))
self.cr.stroke()
def draw_heading(self, trig_height, heading, radius, x, y):
@@ -419,16 +421,16 @@ class NauticalSpeedometer(Speedometer):
self.cr.stroke()
# heading text
- (tbox_x, tbox_y) = NauticalSpeedometer.polar2xy(radius * 1.1, h, x, y)
+ (tbox_x, tbox_y) = self.polar2xy(radius * 1.1, h, x, y)
self.draw_text(tbox_x, tbox_y, int(heading), fontsize=radius / 15)
# the ship shape, based on test and try
shiplen = radius * NauticalSpeedometer.HEADING_SAT_GAP / 4
- xh, yh = NauticalSpeedometer.polar2xy(shiplen * 2.3, h, x, y)
- xa, ya = NauticalSpeedometer.polar2xy(shiplen * 2.2, h + pi - 0.3, x, y)
- xb, yb = NauticalSpeedometer.polar2xy(shiplen * 2.2, h + pi + 0.3, x, y)
- xc, yc = NauticalSpeedometer.polar2xy(shiplen * 1.4, h - pi / 5, x, y)
- xd, yd = NauticalSpeedometer.polar2xy(shiplen * 1.4, h + pi / 5, x, y)
+ xh, yh = self.polar2xy(shiplen * 2.3, h, x, y)
+ xa, ya = self.polar2xy(shiplen * 2.2, h + pi - 0.3, x, y)
+ xb, yb = self.polar2xy(shiplen * 2.2, h + pi + 0.3, x, y)
+ xc, yc = self.polar2xy(shiplen * 1.4, h - pi / 5, x, y)
+ xd, yd = self.polar2xy(shiplen * 1.4, h + pi / 5, x, y)
self.cr.set_source_rgba(0, 0.3, 0.2, 0.5)
self.cr.move_to(xa, ya)
@@ -460,7 +462,7 @@ class NauticalSpeedometer(Speedometer):
self.cr.set_line_width(2)
self.cr.set_source_rgb(0, 0, 0)
- x0, y0 = NauticalSpeedometer.polar2xy(radius * (90 - el) // 90, h, x, y)
+ x0, y0 = self.polar2xy(radius * (90 - el) // 90, h, x, y)
self.cr.new_sub_path()
if gps.is_sbas(satsoup['PRN']):
@@ -515,7 +517,7 @@ class NauticalSpeedometer(Speedometer):
class Main(object):
def __init__(self, host='localhost', port='2947', device=None, debug=0,
- speed_unit=None, maxspeed=0, nautical=False):
+ speed_unit=None, maxspeed=0, nautical=False, rotate=0.0):
self.host = host
self.port = port
self.device = device
@@ -523,6 +525,7 @@ class Main(object):
self.speed_unit = speed_unit
self.maxspeed = maxspeed
self.nautical = nautical
+ self.rotate = rotate
self.window = Gtk.Window(Gtk.WindowType.TOPLEVEL)
if not self.window.get_display():
raise Exception("Can't open display")
@@ -531,7 +534,8 @@ class Main(object):
self.window.set_size_request(500, 550)
self.widget = NauticalSpeedometer(
speed_unit=self.speed_unit,
- maxspeed=self.maxspeed)
+ maxspeed=self.maxspeed,
+ rotate=self.rotate)
else:
self.widget = LandSpeedometer(speed_unit=self.speed_unit)
self.window.connect('delete_event', self.delete_event)
@@ -735,6 +739,14 @@ if __name__ == '__main__':
type='int',
help='Set level of debug. Must be integer. [Default 0]'
)
+ parser.add_option(
+ '--rotate',
+ dest='rotate',
+ default=0,
+ action='store',
+ type='float',
+ help='Rotation of skyview ("up" direction) in degrees. [Default 0]'
+ )
(options, args) = parser.parse_args()
if args:
arg = args[0].split(':')
@@ -755,5 +767,6 @@ if __name__ == '__main__':
speed_unit=options.speedunits,
maxspeed=options.maxspeed,
nautical=options.nautical,
- debug=options.debug
+ debug=options.debug,
+ rotate=options.rotate,
).run()