diff options
author | Matthias Baumgartner <dev@igsor.net> | 2023-01-29 12:01:11 +0100 |
---|---|---|
committer | Matthias Baumgartner <dev@igsor.net> | 2023-01-29 12:01:11 +0100 |
commit | bfb86bdd23c2fb7211636841545b4e003f07b643 (patch) | |
tree | cb0ddd9c8a5ecf84a52db9603e3a4009af32c4ef /tagit/tiles | |
parent | 0fe45bb93b7a62afa7b8b04145607aca9e57af13 (diff) | |
download | tagit-bfb86bdd23c2fb7211636841545b4e003f07b643.tar.gz tagit-bfb86bdd23c2fb7211636841545b4e003f07b643.tar.bz2 tagit-bfb86bdd23c2fb7211636841545b4e003f07b643.zip |
geo tile
Diffstat (limited to 'tagit/tiles')
-rw-r--r-- | tagit/tiles/__init__.py | 4 | ||||
-rw-r--r-- | tagit/tiles/geo.py | 140 |
2 files changed, 142 insertions, 2 deletions
diff --git a/tagit/tiles/__init__.py b/tagit/tiles/__init__.py index 7817339..40345b6 100644 --- a/tagit/tiles/__init__.py +++ b/tagit/tiles/__init__.py @@ -16,7 +16,7 @@ from .browser_tags import BrowserTags from .buttons import Buttons from .cursor_tags import CursorTags #from .entity_histogram import EntityHistogram -#from .geo import Map +from .geo import Map #from .hints import Hints from .info import Info #from .libsummary import LibSummary @@ -44,7 +44,7 @@ class TileBuilder(BuilderBase): 'Buttons': Buttons, 'CursorTags': CursorTags, # 'EntityHistogram': EntityHistogram, -# 'Geo': Map, + 'Geo': Map, # 'Hints': Hints, 'Info': Info, # 'LibSummary': LibSummary, diff --git a/tagit/tiles/geo.py b/tagit/tiles/geo.py new file mode 100644 index 0000000..796a1c2 --- /dev/null +++ b/tagit/tiles/geo.py @@ -0,0 +1,140 @@ +""" + +Part of the tagit module. +A copy of the license is provided with the project. +Author: Matthias Baumgartner, 2022 +""" +# standard imports +import os + +# kivy ipmorts +from kivy.lang import Builder +from kivy.uix.label import Label +import kivy.properties as kp + +# tagit imports +# NOTE: the following line segfaults: +# mapview.source.py:128:self.dp_tile_size = min(dp(self.tile_size), self.tile_size * 2) +# setting it to a static value (e.g. 256) works. +from tagit.external.kivy_garden.mapview import MapView, MapMarkerPopup +from tagit.utils import ns +from tagit.widgets.browser import BrowserAwareMixin + +# inner-module imports +from .tile import Tile + +# exports +__all__ = ('Map', ) + + +## code ## + +Builder.load_string(''' +<Map>: + # meta + title: "Map" + tooltip: 'Location of an item' + # content + map_: map_ + MapView: + id: map_ + zoom: 9 + +<MapLabel>: + size: self.texture_size + size_hint: None, None + padding: 5, 5 + font_size: '15sp' + + canvas.before: + # background + Color: + rgba: 0,0,0,0.6 + RoundedRectangle: + size: self.size + pos: self.pos + radius: [10] # keep in sync with the line's radius + # border + Color: + rgba: 0,0,0,1 + Line: + rounded_rectangle: self.x, self.y, self.width, self.height, 10 +''') + +class MapLabel(Label): + pass + +class Map(Tile, BrowserAwareMixin): + """Draw a map which indicates visible items' locations.""" + + # list of map markers + markers = kp.ListProperty() + + def on_browser(self, sender, browser): + """Bind to browser properties.""" + # remove old binding + if self.browser is not None: + self.browser.unbind(cursor=self.update) + self.browser.unbind(items=self.update_markers) + # add new binding + self.browser = browser + if self.browser is not None: + self.browser.bind(cursor=self.update) + self.browser.bind(items=self.update_markers) + # initial calls + self.update_markers() + self.update() + + def __del__(self): + if self.browser is not None: + self.browser.unbind(cursor=self.update) + self.browser.unbind(items=self.update_markers) + self.browser = None + + def update_markers(self, *args): + """Draw markers for all browser items.""" + # remove old markers + for mark in self.markers: + self.map_.remove_marker(mark) + self.markers.clear() + + # get view data + data = self.root.browser.unfold(self.root.browser.items).get( + ns.bse.filename, + ns.bse.latitude, + ns.bse.longitude, + node=True, + ) + + # draw new markers + for ent, vdict in data.items(): + if ns.bse.latitude not in vdict: + continue + if ns.bse.longitude not in vdict: + continue + # TODO: cluster points, one marker for multiple items + lat = vdict[ns.bse.latitude] + lon = vdict[ns.bse.longitude] + # create popup marker + mark = MapMarkerPopup(lat=lat, lon=lon) + text = vdict.get(ns.bse.filename, + ', '.join(os.path.basename(guid) for guid in ent.guids)) + mark.add_widget(MapLabel(text=text)) + # add marker + self.markers.append(mark) + self.map_.add_marker(mark) + + def update(self, *args): + """Focus the map on the cursor.""" + if not self.visible: + return + + cursor = self.root.browser.cursor + if cursor is not None: + coords = cursor.get(ns.bse.latitude, ns.bse.longitude) + if set(coords.keys()) == {ns.bse.latitude, ns.bse.longitude}: + lat = coords[ns.bse.latitude] + lon = coords[ns.bse.longitude] + self.map_.center_on(lat, lon) + +## EOF ## |