82 lines
2.4 KiB
Python
82 lines
2.4 KiB
Python
# Copyright 2021-2023 Teemu Ikonen
|
|
# SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
import os
|
|
from datetime import datetime, timezone
|
|
|
|
import gi
|
|
gi.require_version('Gdk', '3.0')
|
|
from gi.repository import Gdk # noqa: E402
|
|
|
|
gps_epoch = datetime(1980, 1, 6, 0, 0, tzinfo=timezone.utc)
|
|
now = datetime.now(timezone.utc)
|
|
one_week = 7 * 24 * 60 * 60
|
|
week_now = int((now.timestamp() - gps_epoch.timestamp()) / one_week)
|
|
|
|
|
|
def have_touchscreen():
|
|
"""Return True if the default seat of default display has touch capability."""
|
|
return bool(Gdk.Display.get_default_seat(
|
|
Gdk.Display.get_default()).get_capabilities() & Gdk.SeatCapabilities.TOUCH)
|
|
|
|
|
|
def datetime_from_gpstime(week, millisecs, fix_week=False):
|
|
"""Return a datetime from GPS week number and milliseconds from week start.
|
|
|
|
If fix_week is True, set the bits above 10 in week number from
|
|
current date, see
|
|
https://en.wikipedia.org/wiki/GPS_week_number_rollover
|
|
"""
|
|
if fix_week:
|
|
week = (week & 0b1111111111) + ((week_now >> 10) << 10)
|
|
return datetime.fromtimestamp(
|
|
gps_epoch.timestamp() + week * one_week + (millisecs / 1000),
|
|
timezone.utc)
|
|
|
|
|
|
def gpstime_from_datetime(dt):
|
|
"""Return a (gps_week, millisec) tuple from a datetime object."""
|
|
if dt < gps_epoch:
|
|
raise ValueError("Time cannot be less than GPS epoch")
|
|
ts = dt.timestamp()
|
|
epoch_ts = gps_epoch.timestamp()
|
|
gps_week = int((ts - epoch_ts) / one_week)
|
|
millisecs = 1000 * int(ts - epoch_ts - (gps_week * one_week))
|
|
return gps_week, millisecs
|
|
|
|
|
|
def unique_filename(namestem, ext, timestamp=False):
|
|
if timestamp:
|
|
namestem += "-" + datetime.now().isoformat(
|
|
'_', 'seconds').replace(':', '.')
|
|
name = None
|
|
for count in ('~%d' % n if n > 0 else '' for n in range(100)):
|
|
test = namestem + count + ext
|
|
if os.path.exists(test):
|
|
continue
|
|
else:
|
|
name = test
|
|
break
|
|
|
|
return name
|
|
|
|
|
|
def bearing_to_arrow(bearing):
|
|
# Arrows in bearing order, with up arrow (north) repeating at the end
|
|
arrows = [
|
|
'\u2191',
|
|
'\u2197',
|
|
'\u2192',
|
|
'\u2198',
|
|
'\u2193',
|
|
'\u2199',
|
|
'\u2190',
|
|
'\u2196',
|
|
'\u2191',
|
|
]
|
|
edges = [22.5 + 45.0 * n for n in range(0, 8)] + [360.0]
|
|
|
|
angle = bearing - (bearing // 360) * 360
|
|
index = next(ind for (ind, e) in enumerate(edges) if angle < e)
|
|
return arrows[index]
|