133 lines
4.8 KiB
Python
133 lines
4.8 KiB
Python
#
|
|
# Gramps - a GTK+/GNOME based genealogy program
|
|
#
|
|
# Copyright (C) 2013-2015 Nick Hall
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software
|
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
#
|
|
|
|
"""
|
|
Location utility functions
|
|
"""
|
|
from ..lib.date import Today
|
|
|
|
#-------------------------------------------------------------------------
|
|
#
|
|
# get_location_list
|
|
#
|
|
#-------------------------------------------------------------------------
|
|
def get_location_list(db, place, date=None, lang=''):
|
|
"""
|
|
Return a list of place names for display.
|
|
"""
|
|
if date is None:
|
|
date = Today()
|
|
visited = [place.handle]
|
|
lines = [(__get_name(place, date, lang), place.get_type())]
|
|
while True:
|
|
handle = None
|
|
for placeref in place.get_placeref_list():
|
|
ref_date = placeref.get_date_object()
|
|
if ref_date.is_empty() or date.match_exact(ref_date):
|
|
handle = placeref.ref
|
|
break
|
|
if handle is None or handle in visited:
|
|
break
|
|
place = db.get_place_from_handle(handle)
|
|
if place is None:
|
|
break
|
|
visited.append(handle)
|
|
lines.append((__get_name(place, date, lang), place.get_type()))
|
|
return lines
|
|
|
|
def __get_name(place, date, lang):
|
|
names = {}
|
|
for place_name in place.get_all_names():
|
|
name_date = place_name.get_date_object()
|
|
if name_date.is_empty() or date.match_exact(name_date):
|
|
name_lang = place_name.get_language()
|
|
if name_lang not in names:
|
|
names[name_lang] = place_name.get_value()
|
|
return names.get(lang, names.get('', '?'))
|
|
|
|
#-------------------------------------------------------------------------
|
|
#
|
|
# get_main_location
|
|
#
|
|
#-------------------------------------------------------------------------
|
|
def get_main_location(db, place, date=None):
|
|
"""
|
|
Find all places in the hierarchy above the given place, and return the
|
|
result as a dictionary of place types and names.
|
|
"""
|
|
return dict([(int(place_type), name)
|
|
for name, place_type
|
|
in get_location_list(db, place, date)
|
|
if not place_type.is_custom()])
|
|
|
|
#-------------------------------------------------------------------------
|
|
#
|
|
# get_locations
|
|
#
|
|
#-------------------------------------------------------------------------
|
|
def get_locations(db, place):
|
|
"""
|
|
Determine each possible route up the place hierarchy, and return a list
|
|
containing dictionaries of place types and names.
|
|
"""
|
|
locations = []
|
|
todo = [(place, [(int(place.get_type()), __get_all_names(place))],
|
|
[place.handle])]
|
|
while len(todo):
|
|
place, tree, visited = todo.pop()
|
|
for parent in place.get_placeref_list():
|
|
if parent.ref not in visited:
|
|
parent_place = db.get_place_from_handle(parent.ref)
|
|
if parent_place is not None:
|
|
parent_tree = tree + [(int(parent_place.get_type()),
|
|
__get_all_names(parent_place))]
|
|
parent_visited = visited + [parent.ref]
|
|
todo.append((parent_place, parent_tree, parent_visited))
|
|
if len(place.get_placeref_list()) == 0:
|
|
locations.append(dict(tree))
|
|
return locations
|
|
|
|
def __get_all_names(place):
|
|
return [name.get_value() for name in place.get_all_names()]
|
|
|
|
#-------------------------------------------------------------------------
|
|
#
|
|
# located_in
|
|
#
|
|
#-------------------------------------------------------------------------
|
|
def located_in(db, handle1, handle2):
|
|
"""
|
|
Determine if the place identified by handle1 is located within the place
|
|
identified by handle2.
|
|
"""
|
|
place = db.get_place_from_handle(handle1)
|
|
todo = [(place, [handle1])]
|
|
while len(todo):
|
|
place, visited = todo.pop()
|
|
for parent in place.get_placeref_list():
|
|
if parent.ref == handle2:
|
|
return True
|
|
if parent.ref not in visited:
|
|
parent_place = db.get_place_from_handle(parent.ref)
|
|
if parent_place is not None:
|
|
parent_visited = visited + [parent.ref]
|
|
todo.append((parent_place, parent_visited))
|
|
return False
|