From 79ff9bc21622ccc1334b932b59c58f5ef2358efe Mon Sep 17 00:00:00 2001 From: Serge Noiraud Date: Thu, 18 Jan 2018 09:11:51 +0100 Subject: [PATCH] Geocoding: associate a lat/lon to a place name (#515) * Geocoding: associate a lat/lon to a place name Fixes #09642 * Some cleanup * update README.md * Remove url from message dialog --- README.md | 12 ++++++ gramps/plugins/lib/maps/geography.py | 31 ++++++++++++++ gramps/plugins/lib/maps/placeselection.py | 51 +++++++++++++++++++++-- gramps/plugins/view/geography.gpr.py | 13 +++--- 4 files changed, 97 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index c2dccf476..5b91c5e62 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,18 @@ The following packages are optional: More font support in the reports +* **geocodeglib** + + A library use to associate a geographical position (latitude, longitude) + to a place name. This is used if you already have osmgpsmap installed. + If installed, when you add or link a place from the map, you have a red line + at the end of the table for selection. + Debian, Ubuntu, ... : gir1.2-geocodeglib-1.0 + Fedora, Redhat, ... : geocode-glib + openSUSE : geocode-glib + ArchLinux : geocode-glib + ... + Optional packages required by Third-party Addons ------------------------------------------------ diff --git a/gramps/plugins/lib/maps/geography.py b/gramps/plugins/lib/maps/geography.py index 1b5d3e3f3..a15d09592 100644 --- a/gramps/plugins/lib/maps/geography.py +++ b/gramps/plugins/lib/maps/geography.py @@ -1034,6 +1034,19 @@ class GeoGraphyView(OsmGps, NavigationView): pass kml.destroy() + def place_exists(self, place_name): + """ + Do we have already this place in our database ? + return the handle for this place. + """ + found = None + place_name = place_name.replace('-', ' ').lower() + for place in self.dbstate.db.iter_places(): + if place.name.get_value().lower() == place_name: + found = place.handle + break + return found + def link_place(self, menu, event, lat, lon): """ Link an existing place using longitude and latitude of location centered @@ -1108,6 +1121,24 @@ class GeoGraphyView(OsmGps, NavigationView): placeref = PlaceRef() placeref.ref = parent new_place.add_placeref(placeref) + elif isinstance(parent, gi.overrides.Gtk.TreeModelRow): + # We are here because we selected a place from geocoding + # parent[0] : country + # parent[1] : state + # parent[2] : town + # parent[3] : name + value = PlaceSelection.untag_text(parent[2], 1) + plname = PlaceName() + plname.set_value(value) + handle = self.place_exists(value) + if handle: + # The town already exists. We create a place with name + placeref = PlaceRef() + placeref.ref = handle + new_place.add_placeref(placeref) + value = PlaceSelection.untag_text(parent[3], 1) + plname.set_value(value) + new_place.set_name(plname) else: found = None for place in self.dbstate.db.iter_places(): diff --git a/gramps/plugins/lib/maps/placeselection.py b/gramps/plugins/lib/maps/placeselection.py index a9e9c2904..08f2a1d96 100644 --- a/gramps/plugins/lib/maps/placeselection.py +++ b/gramps/plugins/lib/maps/placeselection.py @@ -43,7 +43,14 @@ _LOG = logging.getLogger("maps.placeselection") # GTK/Gnome modules # #------------------------------------------------------------------------- +import gi from gi.repository import Gtk +try: + gi.require_version('GeocodeGlib', '1.0') + from gi.repository import GeocodeGlib + GEOCODEGLIB = True +except: + GEOCODEGLIB = False #------------------------------------------------------------------------- # @@ -66,6 +73,8 @@ from gramps.gen.display.place import displayer as _pd #------------------------------------------------------------------------- PLACE_REGEXP = re.compile('(.*)') PLACE_STRING = '%s' +GEOCODE_REGEXP = re.compile('(.*)') +GEOCODE_STRING = '%s' # pylint: disable=unused-argument # pylint: disable=no-member @@ -110,9 +119,14 @@ class PlaceSelection(ManagedWindow, OsmGps): Gtk.Dialog(_('Place Selection in a region'), uistate.window, buttons=(_('_Close'), Gtk.ResponseType.CLOSE)), None, _('Place Selection in a region'), None) - label = Gtk.Label(label=_('Choose the radius of the selection.\n' - 'On the map you should see a circle or an' - ' oval depending on the latitude.')) + mylabel = _('Choose the radius of the selection.\n' + 'On the map you should see a circle or an' + ' oval depending on the latitude.') + mylabel += _('\nIn the following table you may have :' + '\n - a green row related to a selected place.') + if GEOCODEGLIB: + mylabel += _('\n - a red row related to a geocoding result.') + label = Gtk.Label(label=mylabel) label.set_valign(Gtk.Align.END) self.window.vbox.pack_start(label, False, True, 0) adj = Gtk.Adjustment(value=1.0, lower=0.1, upper=3.0, @@ -193,6 +207,17 @@ class PlaceSelection(ManagedWindow, OsmGps): self.plist.append((place[0], place[1], place[2], place[3], place[4])) # here, we could add value from geography names services ... + if GEOCODEGLIB: + loc = GeocodeGlib.Location.new(lat, lon, 0) + obj = GeocodeGlib.Reverse.new_for_location(loc) + try: + result = GeocodeGlib.Reverse.resolve(obj) + self.plist.append((GEOCODE_STRING % result.get_country(), + GEOCODE_STRING % result.get_state(), + GEOCODE_STRING % result.get_town(), + GEOCODE_STRING % result.get_name(), '')) + except: + pass # if we found no place, we must create a default place. self.plist.append((_("New place with empty fields"), "", @@ -299,4 +324,22 @@ class PlaceSelection(ManagedWindow, OsmGps): """ get location values and call the real function : add_place, edit_place """ - self.function(self.plist[index][3], self.lat, self.lon) + self.function(self.plist[index], self.lat, self.lon) + + def untag_text(text, tag): + """ + suppress the green or red color tag. + if tag = 0 : PLACE_REGEXP + if tag = 1 : GEOCODE_REGEXP + """ + + if tag: + regtag = GEOCODE_REGEXP + else: + regtag = PLACE_REGEXP + + match = regtag.match(text) + if match: + without_tags = match.groups()[0] + return without_tags + return text diff --git a/gramps/plugins/view/geography.gpr.py b/gramps/plugins/view/geography.gpr.py index fb2a9db5d..eea606ba2 100644 --- a/gramps/plugins/view/geography.gpr.py +++ b/gramps/plugins/view/geography.gpr.py @@ -64,14 +64,15 @@ if not OSMGPSMAP: if has_display(): from gramps.gui.dialog import MessageHideDialog from gramps.gen.const import URL_WIKISTRING - OSMGPS_DICT = {'gramps_wiki_build_osmgps_url' : - URL_WIKISTRING + - "GEPS_029:_GTK3-GObject_introspection" - "_Conversion#OsmGpsMap_for_Geography"} TITLE = _("OsmGpsMap module not loaded.") MESSAGE = _("Geography functionality will not be available.\n" - "To build it for Gramps see " - "%(gramps_wiki_build_osmgps_url)s") % OSMGPS_DICT + "Try to install:\n" + " gir1.2-osmgpsmap-1.0 (debian, ubuntu, ...)\n" + " osm-gps-map-gobject-1.0.1 for fedora, ...\n" + " typelib-1_0-OsmGpsMap-1_0 for openSuse\n" + " ...\n" + "To build it for Gramps see the Wiki ()\n" + " and search for 'build from source'") if uistate: MessageHideDialog(TITLE, MESSAGE, 'interface.ignore-osmgpsmap',