mirror of
https://github.com/liberatedsystems/Sideband_CE.git
synced 2024-09-03 04:13:27 +02:00
Added map settings and layer switching
This commit is contained in:
parent
0a2a87775e
commit
86e053cdb9
203
sbapp/main.py
203
sbapp/main.py
@ -15,6 +15,7 @@ import RNS
|
|||||||
import LXMF
|
import LXMF
|
||||||
import time
|
import time
|
||||||
import os
|
import os
|
||||||
|
import pathlib
|
||||||
import plyer
|
import plyer
|
||||||
import base64
|
import base64
|
||||||
import threading
|
import threading
|
||||||
@ -149,7 +150,11 @@ class SidebandApp(MDApp):
|
|||||||
|
|
||||||
self.conversations_view = None
|
self.conversations_view = None
|
||||||
self.messages_view = None
|
self.messages_view = None
|
||||||
|
self.map = None
|
||||||
|
self.map_layer = None
|
||||||
self.map_screen = None
|
self.map_screen = None
|
||||||
|
self.offline_source = None
|
||||||
|
self.map_settings_screen = None
|
||||||
self.object_details_screen = None
|
self.object_details_screen = None
|
||||||
self.sync_dialog = None
|
self.sync_dialog = None
|
||||||
self.settings_ready = False
|
self.settings_ready = False
|
||||||
@ -3278,71 +3283,155 @@ class SidebandApp(MDApp):
|
|||||||
|
|
||||||
def map_fm_got_path(self, path):
|
def map_fm_got_path(self, path):
|
||||||
self.map_fm_exited()
|
self.map_fm_exited()
|
||||||
# TODO: Remove
|
|
||||||
toast(path)
|
|
||||||
###
|
|
||||||
try:
|
try:
|
||||||
source = MBTilesMapSource(path)
|
source = MBTilesMapSource(path)
|
||||||
self.map_update_source(source)
|
self.map_update_source()
|
||||||
self.sideband.config["map_storage_file"] = path
|
self.sideband.config["map_storage_file"] = path
|
||||||
|
self.sideband.config["map_storage_path"] = str(pathlib.Path(path).parent.resolve())
|
||||||
self.sideband.save_configuration()
|
self.sideband.save_configuration()
|
||||||
|
toast("Using \""+os.path.basename(path)+"\" as offline map")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
RNS.log(f"Error while loading map \"{path}\": "+str(e), RNS.LOG_ERROR)
|
RNS.log(f"Error while loading map \"{path}\": "+str(e), RNS.LOG_ERROR)
|
||||||
selfmap_update_source()
|
toast("Could not load map \""+os.path.basename(path)+"\"")
|
||||||
|
self.sideband.config["map_storage_file"] = None
|
||||||
|
self.sideband.config["map_use_offline"] = False
|
||||||
|
self.sideband.config["map_use_online"] = True
|
||||||
|
self.map_settings_load_states()
|
||||||
|
self.map_update_source()
|
||||||
|
|
||||||
def map_fm_exited(self, *args):
|
def map_fm_exited(self, *args):
|
||||||
RNS.log("Closing file manager", RNS.LOG_DEBUG)
|
|
||||||
self.sideband.config["map_storage_file"] = None
|
|
||||||
self.sideband.save_configuration()
|
|
||||||
self.manager_open = False
|
self.manager_open = False
|
||||||
self.file_manager.close()
|
self.file_manager.close()
|
||||||
self.map_update_source()
|
self.map_update_source()
|
||||||
|
|
||||||
def map_get_source(self):
|
def map_get_offline_source(self):
|
||||||
current_map_path = self.sideband.config["map_storage_file"]
|
if self.offline_source != None:
|
||||||
source = None
|
return self.offline_source
|
||||||
|
else:
|
||||||
if current_map_path:
|
|
||||||
try:
|
try:
|
||||||
|
current_map_path = self.sideband.config["map_storage_file"]
|
||||||
|
if current_map_path == None:
|
||||||
|
raise ValueError("Map path cannot be None")
|
||||||
source = MBTilesMapSource(current_map_path)
|
source = MBTilesMapSource(current_map_path)
|
||||||
|
self.offline_source = source
|
||||||
|
return self.offline_source
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
RNS.log(f"Error while loading map from \"{current_map_path}\": "+str(e))
|
RNS.log(f"Error while loading map from \"{current_map_path}\": "+str(e))
|
||||||
self.sideband.config["map_storage_file"] = None
|
self.sideband.config["map_storage_file"] = None
|
||||||
|
self.sideband.config["map_use_offline"] = False
|
||||||
|
self.sideband.config["map_use_online"] = True
|
||||||
self.sideband.save_configuration()
|
self.sideband.save_configuration()
|
||||||
|
self.map_settings_load_states()
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
def map_get_source(self):
|
||||||
|
source = None
|
||||||
|
if self.sideband.config["map_use_offline"]:
|
||||||
|
source = self.map_get_offline_source()
|
||||||
|
|
||||||
if source == None:
|
if source == None:
|
||||||
source = MapSource.from_provider("osm")
|
source = MapSource.from_provider("osm", quad_key=False)
|
||||||
|
|
||||||
return source
|
return source
|
||||||
|
|
||||||
def map_update_source(self, source=None):
|
def map_update_source(self, source=None):
|
||||||
ns = source or self.map_get_source()
|
ns = source or self.map_get_source()
|
||||||
if self.map != None:
|
if self.map != None:
|
||||||
|
|
||||||
|
if source != None:
|
||||||
|
maxz = source.max_zoom
|
||||||
|
minz = source.min_zoom
|
||||||
|
if self.map.zoom > maxz:
|
||||||
|
self.map.zoom = maxz
|
||||||
|
|
||||||
|
if self.map.zoom < minz:
|
||||||
|
self.map.zoom = minz
|
||||||
|
|
||||||
|
m = self.map
|
||||||
|
RNS.log(f"Map {m.lat} {m.lon} {m.zoom}")
|
||||||
|
nlat = self.map.lat
|
||||||
|
nlon = self.map.lon
|
||||||
|
if nlat < -89: nlat = -89
|
||||||
|
if nlat > 89: nlat = 89
|
||||||
|
if nlon < -179: nlon = -179
|
||||||
|
if nlon > 179: nlon = 179
|
||||||
|
self.map.center_on(nlat,nlon)
|
||||||
|
|
||||||
|
|
||||||
self.map.map_source = ns
|
self.map.map_source = ns
|
||||||
|
|
||||||
def map_test_action(self, sender=None):
|
def map_layers_action(self, sender=None):
|
||||||
|
try:
|
||||||
|
ml = self.map_layer
|
||||||
|
layers = []
|
||||||
|
if self.sideband.config["map_use_offline"]:
|
||||||
|
layers.append("offline")
|
||||||
|
|
||||||
|
if self.sideband.config["map_use_online"]:
|
||||||
|
layers.append("osm")
|
||||||
|
layers.append("ve")
|
||||||
|
|
||||||
|
if ml == None: ml = layers[0]
|
||||||
|
|
||||||
|
if not ml in layers:
|
||||||
|
ml = layers[0]
|
||||||
|
|
||||||
|
mli = layers.index(ml)
|
||||||
|
mli = (mli+1)%len(layers)
|
||||||
|
ml = layers[mli]
|
||||||
|
|
||||||
|
source = None
|
||||||
|
if ml == "offline": source = self.map_get_offline_source()
|
||||||
|
if ml == "osm": source = MapSource.from_provider("osm", quad_key=False)
|
||||||
|
if ml == "ve": source = MapSource.from_provider("ve", quad_key=True)
|
||||||
|
|
||||||
|
if source != None:
|
||||||
|
self.map_layer = ml
|
||||||
|
self.map_update_source(source)
|
||||||
|
except Exception as e:
|
||||||
|
RNS.log("Error while switching map layer: "+str(e), RNS.LOG_ERROR)
|
||||||
|
|
||||||
|
def map_select_file_action(self, sender=None):
|
||||||
perm_ok = False
|
perm_ok = False
|
||||||
if RNS.vendor.platformutils.is_android():
|
if self.sideband.config["map_storage_path"] == None:
|
||||||
perm_ok = self.check_storage_permission()
|
if RNS.vendor.platformutils.is_android():
|
||||||
|
perm_ok = self.check_storage_permission()
|
||||||
|
|
||||||
|
if self.sideband.config["map_storage_external"]:
|
||||||
|
path = secondary_external_storage_path()
|
||||||
|
if path == None: path = primary_external_storage_path()
|
||||||
|
else:
|
||||||
|
path = primary_external_storage_path()
|
||||||
|
|
||||||
if self.sideband.config["map_storage_external"]:
|
|
||||||
path = secondary_external_storage_path()
|
|
||||||
if path == None: path = primary_external_storage_path()
|
|
||||||
else:
|
else:
|
||||||
path = primary_external_storage_path()
|
perm_ok = True
|
||||||
|
if self.sideband.config["map_storage_external"]:
|
||||||
|
path = "/"
|
||||||
|
else:
|
||||||
|
path = os.path.expanduser("~")
|
||||||
else:
|
else:
|
||||||
perm_ok = True
|
perm_ok = True
|
||||||
path = os.path.expanduser("~")
|
path = self.sideband.config["map_storage_path"]
|
||||||
|
|
||||||
if perm_ok and path != None:
|
if perm_ok and path != None:
|
||||||
self.file_manager = MDFileManager(
|
try:
|
||||||
exit_manager=self.map_fm_exited,
|
self.file_manager = MDFileManager(
|
||||||
select_path=self.map_fm_got_path,
|
exit_manager=self.map_fm_exited,
|
||||||
)
|
select_path=self.map_fm_got_path,
|
||||||
self.file_manager.ext = [".mbtiles"]
|
)
|
||||||
self.file_manager.show(path)
|
self.file_manager.ext = [".mbtiles"]
|
||||||
|
self.file_manager.show(path)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
self.sideband.config["map_storage_path"] = None
|
||||||
|
self.sideband.save_configuration()
|
||||||
|
toast("Error reading directory, check permissions!")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
self.sideband.config["map_storage_path"] = None
|
||||||
|
self.sideband.save_configuration()
|
||||||
toast("No file access, check permissions!")
|
toast("No file access, check permissions!")
|
||||||
|
|
||||||
def map_action(self, sender=None, direction="left"):
|
def map_action(self, sender=None, direction="left"):
|
||||||
@ -3371,6 +3460,60 @@ class SidebandApp(MDApp):
|
|||||||
self.map_update_markers()
|
self.map_update_markers()
|
||||||
Clock.schedule_once(am_job, 0.6)
|
Clock.schedule_once(am_job, 0.6)
|
||||||
|
|
||||||
|
def map_settings_load_states(self):
|
||||||
|
if self.map_settings_screen != None:
|
||||||
|
self.map_settings_screen.ids.map_use_online.active = self.sideband.config["map_use_online"]
|
||||||
|
self.map_settings_screen.ids.map_use_offline.active = self.sideband.config["map_use_offline"]
|
||||||
|
self.map_settings_screen.ids.map_storage_external.active = self.sideband.config["map_storage_external"]
|
||||||
|
|
||||||
|
def map_settings_init(self):
|
||||||
|
self.map_settings_load_states()
|
||||||
|
def map_settings_save(sender=None, event=None):
|
||||||
|
self.sideband.config["map_storage_external"] = self.map_settings_screen.ids.map_storage_external.active
|
||||||
|
self.sideband.config["map_use_online"] = self.map_settings_screen.ids.map_use_online.active
|
||||||
|
self.sideband.config["map_use_offline"] = self.map_settings_screen.ids.map_use_offline.active
|
||||||
|
self.sideband.save_configuration()
|
||||||
|
|
||||||
|
def external_toggle(sender=None, event=None):
|
||||||
|
self.sideband.config["map_storage_path"] = None
|
||||||
|
map_settings_save()
|
||||||
|
|
||||||
|
def offline_toggle(sender=None, event=None):
|
||||||
|
if self.map_settings_screen.ids.map_use_offline.active:
|
||||||
|
# self.map_settings_screen.ids.map_use_online.active = False
|
||||||
|
if self.sideband.config["map_storage_file"] == None:
|
||||||
|
self.map_select_file_action()
|
||||||
|
else:
|
||||||
|
self.map_settings_screen.ids.map_use_online.active = True
|
||||||
|
map_settings_save(); self.map_update_source()
|
||||||
|
|
||||||
|
def online_toggle(sender=None, event=None):
|
||||||
|
if self.map_settings_screen.ids.map_use_online.active:
|
||||||
|
# self.map_settings_screen.ids.map_use_offline.active = False
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
self.map_settings_screen.ids.map_use_offline.active = True
|
||||||
|
map_settings_save(); self.map_update_source()
|
||||||
|
|
||||||
|
|
||||||
|
self.map_settings_screen.ids.map_use_offline.bind(active=offline_toggle)
|
||||||
|
self.map_settings_screen.ids.map_use_online.bind(active=online_toggle)
|
||||||
|
self.map_settings_screen.ids.map_storage_external.bind(active=external_toggle)
|
||||||
|
|
||||||
|
def map_settings_action(self, sender=None, direction="left"):
|
||||||
|
if not self.root.ids.screen_manager.has_screen("map_settings_screen"):
|
||||||
|
self.map_settings_screen = Builder.load_string(layout_map_settings_screen)
|
||||||
|
self.map_settings_screen.app = self
|
||||||
|
self.root.ids.screen_manager.add_widget(self.map_settings_screen)
|
||||||
|
self.map_settings_screen.ids.map_config_info.text = "\n\nSideband can use map sources from the Internet, or a map source stored locally on this device in MBTiles format."
|
||||||
|
self.map_settings_screen.ids.map_settings_scrollview.effect_cls = ScrollEffect
|
||||||
|
self.map_settings_init()
|
||||||
|
|
||||||
|
self.root.ids.screen_manager.transition.direction = direction
|
||||||
|
self.root.ids.screen_manager.current = "map_settings_screen"
|
||||||
|
self.root.ids.nav_drawer.set_state("closed")
|
||||||
|
self.sideband.setstate("app.displaying", self.root.ids.screen_manager.current)
|
||||||
|
|
||||||
def close_location_error_dialog(self, sender=None):
|
def close_location_error_dialog(self, sender=None):
|
||||||
if hasattr(self, "location_error_dialog") and self.location_error_dialog != None:
|
if hasattr(self, "location_error_dialog") and self.location_error_dialog != None:
|
||||||
self.location_error_dialog.dismiss()
|
self.location_error_dialog.dismiss()
|
||||||
@ -3391,7 +3534,7 @@ class SidebandApp(MDApp):
|
|||||||
if not location:
|
if not location:
|
||||||
self.location_error_dialog = MDDialog(
|
self.location_error_dialog = MDDialog(
|
||||||
title="No Location",
|
title="No Location",
|
||||||
text="During the last 24 hours, no location updates have been received from this peer. You can use the the [b]Situation Map[/b] to manually search for earlier telemetry.",
|
text="No location updates have been received from this peer. You can use the the [b]Situation Map[/b] to manually search for earlier telemetry.",
|
||||||
buttons=[
|
buttons=[
|
||||||
MDRectangleFlatButton(
|
MDRectangleFlatButton(
|
||||||
text="OK",
|
text="OK",
|
||||||
|
@ -171,8 +171,13 @@ class SidebandCore():
|
|||||||
try:
|
try:
|
||||||
if not os.path.isfile(self.config_path):
|
if not os.path.isfile(self.config_path):
|
||||||
self.__init_config()
|
self.__init_config()
|
||||||
else:
|
|
||||||
self.__load_config()
|
self.__load_config()
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
self.__load_config()
|
||||||
|
except Exception as e:
|
||||||
|
self.__init_config()
|
||||||
|
self.__load_config()
|
||||||
self.first_run = False
|
self.first_run = False
|
||||||
|
|
||||||
if self.config["debug"]:
|
if self.config["debug"]:
|
||||||
@ -533,6 +538,13 @@ class SidebandCore():
|
|||||||
self.config["map_zoom"] = 3
|
self.config["map_zoom"] = 3
|
||||||
if not "map_storage_external" in self.config:
|
if not "map_storage_external" in self.config:
|
||||||
self.config["map_storage_external"] = False
|
self.config["map_storage_external"] = False
|
||||||
|
if not "map_use_offline" in self.config:
|
||||||
|
self.config["map_use_offline"] = False
|
||||||
|
if not "map_use_online" in self.config:
|
||||||
|
self.config["map_use_online"] = True
|
||||||
|
if not "map_layer" in self.config:
|
||||||
|
self.config["map_layer"] = None
|
||||||
|
|
||||||
if not "map_storage_path" in self.config:
|
if not "map_storage_path" in self.config:
|
||||||
self.config["map_storage_path"] = None
|
self.config["map_storage_path"] = None
|
||||||
if not "map_storage_file" in self.config:
|
if not "map_storage_file" in self.config:
|
||||||
@ -814,7 +826,7 @@ class SidebandCore():
|
|||||||
return []
|
return []
|
||||||
|
|
||||||
def peer_location(self, context_dest):
|
def peer_location(self, context_dest):
|
||||||
after_time = time.time()-24*60*60
|
after_time = time.time()-3*30*24*60*60
|
||||||
pts = self.peer_telemetry(context_dest, after=after_time)
|
pts = self.peer_telemetry(context_dest, after=after_time)
|
||||||
for pt in pts:
|
for pt in pts:
|
||||||
try:
|
try:
|
||||||
|
@ -851,6 +851,117 @@ MDScreen:
|
|||||||
height: dp(256)
|
height: dp(256)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
layout_map_settings_screen = """
|
||||||
|
MDScreen:
|
||||||
|
name: "map_settings_screen"
|
||||||
|
|
||||||
|
BoxLayout:
|
||||||
|
orientation: "vertical"
|
||||||
|
|
||||||
|
MDTopAppBar:
|
||||||
|
title: "Map Configuration"
|
||||||
|
anchor_title: "left"
|
||||||
|
elevation: 0
|
||||||
|
left_action_items:
|
||||||
|
[['menu', lambda x: root.app.nav_drawer.set_state("open")]]
|
||||||
|
right_action_items:
|
||||||
|
[
|
||||||
|
['close', lambda x: root.app.close_sub_map_action(self)],
|
||||||
|
]
|
||||||
|
|
||||||
|
ScrollView:
|
||||||
|
id: map_settings_scrollview
|
||||||
|
|
||||||
|
MDBoxLayout:
|
||||||
|
orientation: "vertical"
|
||||||
|
size_hint_y: None
|
||||||
|
height: self.minimum_height
|
||||||
|
padding: [dp(28), dp(48), dp(28), dp(16)]
|
||||||
|
|
||||||
|
MDLabel:
|
||||||
|
text: "Configure Map"
|
||||||
|
font_style: "H6"
|
||||||
|
|
||||||
|
MDLabel:
|
||||||
|
id: map_config_info
|
||||||
|
markup: True
|
||||||
|
text: ""
|
||||||
|
size_hint_y: None
|
||||||
|
text_size: self.width, None
|
||||||
|
height: self.texture_size[1]
|
||||||
|
|
||||||
|
MDLabel:
|
||||||
|
markup: True
|
||||||
|
text: "\\n"
|
||||||
|
size_hint_y: None
|
||||||
|
text_size: self.width, None
|
||||||
|
height: self.texture_size[1]
|
||||||
|
|
||||||
|
MDBoxLayout:
|
||||||
|
orientation: "horizontal"
|
||||||
|
padding: [0,0,dp(24),0]
|
||||||
|
size_hint_y: None
|
||||||
|
height: dp(48)
|
||||||
|
|
||||||
|
MDLabel:
|
||||||
|
text: "Use online map sources"
|
||||||
|
font_style: "H6"
|
||||||
|
|
||||||
|
MDSwitch:
|
||||||
|
id: map_use_online
|
||||||
|
pos_hint: {"center_y": 0.3}
|
||||||
|
active: False
|
||||||
|
|
||||||
|
MDBoxLayout:
|
||||||
|
orientation: "horizontal"
|
||||||
|
padding: [0,0,dp(24),0]
|
||||||
|
size_hint_y: None
|
||||||
|
height: dp(48)
|
||||||
|
|
||||||
|
MDLabel:
|
||||||
|
text: "Use offline map source"
|
||||||
|
font_style: "H6"
|
||||||
|
|
||||||
|
MDSwitch:
|
||||||
|
id: map_use_offline
|
||||||
|
pos_hint: {"center_y": 0.3}
|
||||||
|
active: False
|
||||||
|
|
||||||
|
MDBoxLayout:
|
||||||
|
orientation: "horizontal"
|
||||||
|
padding: [0,0,dp(24),0]
|
||||||
|
size_hint_y: None
|
||||||
|
height: dp(48)
|
||||||
|
|
||||||
|
MDLabel:
|
||||||
|
id: map_storage_external_label
|
||||||
|
text: "Use external storage path"
|
||||||
|
font_style: "H6"
|
||||||
|
|
||||||
|
MDSwitch:
|
||||||
|
id: map_storage_external
|
||||||
|
pos_hint: {"center_y": 0.3}
|
||||||
|
active: False
|
||||||
|
|
||||||
|
MDBoxLayout:
|
||||||
|
orientation: "vertical"
|
||||||
|
size_hint_y: None
|
||||||
|
height: self.minimum_height
|
||||||
|
padding: [0, dp(24), 0, 0]
|
||||||
|
|
||||||
|
MDRectangleFlatIconButton:
|
||||||
|
id: telemetry_icons_button
|
||||||
|
icon: "list-box-outline"
|
||||||
|
text: "Select MBTiles Map"
|
||||||
|
padding: [dp(0), dp(14), dp(0), dp(14)]
|
||||||
|
icon_size: dp(24)
|
||||||
|
font_size: dp(16)
|
||||||
|
size_hint: [1.0, None]
|
||||||
|
on_release: root.app.map_select_file_action(self)
|
||||||
|
disabled: False
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
layout_map_screen = """
|
layout_map_screen = """
|
||||||
MDScreen:
|
MDScreen:
|
||||||
name: "map_screen"
|
name: "map_screen"
|
||||||
@ -869,7 +980,8 @@ MDScreen:
|
|||||||
['format-list-bulleted-type', lambda x: root.app.map_object_list(self)],
|
['format-list-bulleted-type', lambda x: root.app.map_object_list(self)],
|
||||||
['arrow-down-bold-hexagon-outline', lambda x: root.app.telemetry_request_action(self)],
|
['arrow-down-bold-hexagon-outline', lambda x: root.app.telemetry_request_action(self)],
|
||||||
['upload-lock', lambda x: root.app.telemetry_send_update(self)],
|
['upload-lock', lambda x: root.app.telemetry_send_update(self)],
|
||||||
['wrench-cog', lambda x: root.app.map_test_action(self)],
|
['layers', lambda x: root.app.map_layers_action(self)],
|
||||||
|
['wrench-cog', lambda x: root.app.map_settings_action(self)],
|
||||||
['close', lambda x: root.app.close_any_action(self)],
|
['close', lambda x: root.app.close_any_action(self)],
|
||||||
]
|
]
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user