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
This commit is contained in:
Serge Noiraud 2018-01-18 09:11:51 +01:00 committed by GitHub
parent b54672d28d
commit 79ff9bc216
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 97 additions and 10 deletions

View File

@ -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
------------------------------------------------

View File

@ -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():

View File

@ -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('<span background="green">(.*)</span>')
PLACE_STRING = '<span background="green">%s</span>'
GEOCODE_REGEXP = re.compile('<span background="red">(.*)</span>')
GEOCODE_STRING = '<span background="red">%s</span>'
# 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'
mylabel = _('Choose the radius of the selection.\n'
'On the map you should see a circle or an'
' oval depending on the latitude.'))
' 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

View File

@ -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 (<F1>)\n"
" and search for 'build from source'")
if uistate:
MessageHideDialog(TITLE, MESSAGE,
'interface.ignore-osmgpsmap',