# -*- python -*-
# -*- coding: utf-8 -*-
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2007-2008 Serge Noiraud
# Copyright (C) 2008 Benny Malengier
#
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# $Id$
#-------------------------------------------------------------------------
#
# Python modules
#
#-------------------------------------------------------------------------
from gettext import gettext as _
from cgi import escape
import math
import os
import tempfile
import urlparse
import const
import gobject
import threading
import time
import operator
#-------------------------------------------------------------------------
#
# GTK/Gnome modules
#
#-------------------------------------------------------------------------
import gtk
#-------------------------------------------------------------------------
#
# Set up logging
#
#-------------------------------------------------------------------------
import logging
LOG = logging.getLogger(".GeoView")
#LOG.setLevel(logging.DEBUG)
#-------------------------------------------------------------------------
#
# Gramps Modules
#
#-------------------------------------------------------------------------
import gen.lib
import PageView
import Utils
import Config
from const import TEMP_DIR
from BasicUtils import name_displayer as _nd
from PlaceUtils import conv_lat_lon
#-------------------------------------------------------------------------
#
# Web interfaces
#
#-------------------------------------------------------------------------
NOWEB = 0
WEBKIT = 1
MOZIL = 2
WebKit = NOWEB
try:
import webkit
WebKit = WEBKIT
except:
pass
if WebKit == NOWEB:
try:
import gtkmozembed
WebKit = MOZIL
except:
pass
#no interfaces present, raise Error so that options for GeoView do not show
if WebKit == NOWEB :
Config.set(Config.GEOVIEW, False)
raise ImportError, 'No GTK html plugin found'
#-------------------------------------------------------------------------
#
# Gramps Modules
#
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
#
# Constants
#
#-------------------------------------------------------------------------
# I think we should set the two following variable in const.py
# They are used only with gtkmozembed.
MOZEMBED_PATH = TEMP_DIR
MOZEMBED_SUBPATH = Utils.get_empty_tempdir('mozembed_gramps')
GEOVIEW_SUBPATH = Utils.get_empty_tempdir('geoview')
NB_MARKERS_PER_PAGE = 200
#-------------------------------------------------------------------------
#
# Renderer
#
#-------------------------------------------------------------------------
class Renderer():
"""
Renderer renders the webpage. Several backend implementations are
possible
"""
def __init__(self):
self.window = None
self.fct = None
def get_window(self):
"""
Returns a container class with the widget that contains browser
window
"""
return self.window
def get_uri(self):
raise NotImplementedError
def show_all(self):
self.window.show_all()
def open(self, url):
""" open the webpage at url
"""
raise NotImplementedError
def refresh(self):
raise NotImplementedError
def go_back(self):
self.window.go_back();
def can_go_back(self):
return self.window.can_go_back()
def go_forward(self):
self.window.go_forward();
def can_go_forward(self):
return self.window.can_go_forward()
def execute_script(self, url):
""" execute script in the current html page
"""
raise NotImplementedError
def page_loaded(self):
raise NotImplementedError
def page_begin_load(self):
raise NotImplementedError
def set_button_sensitivity(self):
"""
We must set the back and forward button in the HtmlView class.
"""
self.fct()
#-------------------------------------------------------------------------
#
# Renderer with WebKit
#
#-------------------------------------------------------------------------
class RendererWebkit(Renderer):
"""
Implementation of Renderer with Webkit
"""
def __init__(self):
Renderer.__init__(self)
self.window = webkit.WebView()
self.browser = WEBKIT
self.frame = self.window.get_main_frame()
self.frame.connect("load-done", self.page_loaded)
self.window.connect("load-started", self.page_begin_load)
self.window.connect("hovering-over-link", self.hover_link_cb)
#self.window.connect("navigation-requested", self.navigation)
self.window.connect("load-progress-changed", self.load_progress)
#self.window.connect("script-alert", self.script_alert_cb)
#self.window.connect("script-confirm", self.script_confirm_cb)
#self.window.connect("script-prompt", self.script_prompt_cb)
def page_loaded(self,obj,status):
self.set_button_sensitivity()
def page_begin_load(self,view,frame):
if frame is self.frame:
LOG.debug(_("load-started : %s") % self.get_uri())
pass
def navigation(self,view,frame,networkrequest):
LOG.debug(_("navigation-requested : %s") % frame.get_uri())
return 1
def load_progress(self,view,percent):
#LOG.debug(_("load-progress-changed : load %s : %s%%") % (view.get_main_frame().get_uri(), percent))
pass
def hover_link_cb(self,view,title,url):
if view and url:
LOG.debug(_("hovering-over-link : %s - %s") % (title, url))
def script_confirm_cb(self, view, frame, message, isConfirmed):
LOG.debug("script confirm")
pass
def window_event_cb(self, view, event, message, fromwindow):
LOG.debug("event!", event, view, message )
LOG.debug(event.get_event_type() )
return True
def script_prompt_cb(self, view, frame, message, default, text):
LOG.debug("script prompt")
pass
def open(self, url):
self.window.open(url)
def refresh(self):
self.window.reload();
def execute_script(self,url):
self.window.execute_script(url);
def get_uri(self):
return self.window.get_main_frame().get_uri()
class RendererMozilla(Renderer):
"""
Implementation of Renderer with gtkmozembed
"""
def __init__(self):
Renderer.__init__(self)
if hasattr(gtkmozembed, 'set_profile_path'):
set_profile_path = gtkmozembed.set_profile_path
else:
set_profile_path = gtkmozembed.gtk_moz_embed_set_profile_path
set_profile_path(MOZEMBED_PATH, MOZEMBED_SUBPATH)
self.__set_mozembed_proxy()
self.window = gtkmozembed.MozEmbed()
self.browser = MOZIL
self.handler = self.window.connect("net-stop", self.page_loaded)
self.handler = self.window.connect("net-start", self.page_begin_load)
def page_loaded(self,obj):
self.set_button_sensitivity()
def page_begin_load(self,obj):
LOG.debug(_("Loading - %s") % self.get_uri())
pass
def open(self, url):
self.window.load_url(url)
def execute_script(self,url):
self.window.load_url(url);
def get_uri(self):
return self.window.get_location()
def refresh(self):
self.window.reload(0);
def __set_mozembed_proxy(self):
"""
Try to see if we have some proxy environment variable.
http_proxy in our case.
The standard format is : http://[user:password@]proxy:port/
"""
try:
proxy = os.environ['http_proxy']
if proxy:
host_port = None
prefs = open(MOZEMBED_SUBPATH+"/prefs.js","w+")
parts = urlparse.urlparse(proxy)
if not parts[0] or parts[0] == 'http':
host_port = parts[1]
t = host_port.split(':')
host = t[0].strip()
if host:
try:
port = int(t[1])
except:
user = host
u = t[1].split('@')
password = u[0]
host = u[1]
port = int(t[2])
if port and host:
port = str(port)
prefs.write('user_pref("network.proxy.type", 1);\r\n')
prefs.write('user_pref("network.proxy.http", "'+host+'");\r\n')
prefs.write('user_pref("network.proxy.http_port", '+port+');\r\n')
prefs.write('user_pref("network.proxy.no_proxies_on", '\
'"127.0.0.1,localhost,localhost.localdomain");\r\n')
prefs.write('user_pref("network.proxy.share_proxy_settings", true);\r\n')
prefs.write('user_pref("network.http.proxy.pipelining", true);\r\n')
prefs.write('user_pref("network.http.proxy.keep-alive", true);\r\n')
prefs.write('user_pref("network.http.proxy.version", 1.1);\r\n')
prefs.write('user_pref("network.http.sendRefererHeader, 0);\r\n')
prefs.close()
except:
try: # trying to remove pref.js in case of proxy change.
os.remove(MOZEMBED_SUBPATH+"/prefs.js")
except:
pass
pass # We don't use a proxy or the http_proxy variable is not set.
#-------------------------------------------------------------------------
#
# HtmlView
#
#-------------------------------------------------------------------------
class HtmlView(PageView.PageView):
"""
HtmlView is a view showing a top widget with controls, and a bottom part
with an embedded webbrowser showing a given URL
"""
def __init__(self, dbstate, uistate, title=_('HtmlView')):
PageView.PageView.__init__(self, title, dbstate, uistate)
self.dbstate = dbstate
self.external_url = False
self.need_to_resize = False
def build_widget(self):
"""
Builds the interface and returns a gtk.Container type that
contains the interface. This containter will be inserted into
a gtk.Notebook page.
"""
global WebKit
self.box = gtk.VBox(False, 4)
#top widget at the top
self.box.pack_start(self.top_widget(), False, False,0 )
#web page under it in a scrolled window
self.table = gtk.Table(1, 1, False)
frame = gtk.ScrolledWindow(None, None)
frame.set_shadow_type(gtk.SHADOW_NONE)
frame.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
frame.add_with_viewport(self.table)
self.bootstrap_handler = self.box.connect("size-request", self.init_parent_signals_for_map)
self.table.get_parent().set_shadow_type(gtk.SHADOW_NONE)
self.table.set_row_spacings(1)
self.table.set_col_spacings(0)
if (WebKit == WEBKIT) :
# We use webkit
self.renderer = RendererWebkit()
elif (WebKit == MOZIL) :
# We use gtkmozembed
self.renderer = RendererMozilla()
self.table.add(self.renderer.get_window())
self.box.pack_start(frame, True, True, 0)
# this is used to activate the back and forward button from the renderer class.
self.renderer.fct = self.set_button_sensitivity
self.renderer.show_all()
#load a welcome html page
urlhelp = self.create_start_page()
self.open(urlhelp)
return self.box
def top_widget(self):
"""
The default class gives a widget where user can type an url
"""
hbox = gtk.HBox(False,4)
self.urlfield = gtk.Entry()
self.urlfield.set_text("http://gramps-project.org")
self.urlfield.connect('activate', self._on_activate);
hbox.pack_start(self.urlfield, True, True, 4)
button = gtk.Button(stock=gtk.STOCK_APPLY)
button.connect('clicked', self._on_activate)
hbox.pack_start(button, False, False, 4)
return hbox
def set_button_sensitivity(self):
self.forward_action.set_sensitive(self.renderer.can_go_forward())
self.back_action.set_sensitive(self.renderer.can_go_back())
def open(self, url):
""" open an url
"""
self.renderer.open(url)
def go_back(self, button):
self.renderer.go_back();
self.set_button_sensitivity()
self.external_uri()
def go_forward(self, button):
self.renderer.go_forward();
self.set_button_sensitivity()
self.external_uri()
def refresh(self,button):
self.renderer.refresh();
def external_uri(self):
uri = self.renderer.get_uri()
if self.external_url:
self.external_url = False
self.need_to_resize = True
else:
try:
if uri.find(self.htmlfile) == -1:
# external web page or start_page
self.need_to_resize = True
else:
self.need_to_resize = False
except:
pass
def _on_activate(self, object):
url = self.urlfield.get_text()
if url.find('://') == -1:
url = 'http://'+ url
self.external_url = True
self.open(url)
def build_tree(self):
"""
Rebuilds the current display. Called from ViewManager
"""
pass #htmlview is build on click and startup
def get_stock(self):
"""
Returns the name of the stock icon to use for the display.
This assumes that this icon has already been registered with
GNOME as a stock icon.
"""
return 'gramps-geo'
def ui_definition(self):
"""
Specifies the UIManager XML code that defines the menus and buttons
associated with the interface.
"""
return '''
'''
def define_actions(self):
"""
Required define_actions function for PageView. Builds the action
group information required.
"""
HtmlView._define_actions_fw_bw(self)
def _define_actions_fw_bw(self):
# add the Backward action to handle the Backward button
# accel doesn't work in webkit and gtkmozembed !
# we must do that ...
self.back_action = gtk.ActionGroup(self.title + '/Back')
self.back_action.add_actions([
('Back', gtk.STOCK_GO_BACK, _("_Back"),
"Left", _("Go to the previous page in the history"),
self.go_back)
])
self._add_action_group(self.back_action)
# add the Forward action to handle the Forward button
self.forward_action = gtk.ActionGroup(self.title + '/Forward')
self.forward_action.add_actions([
('Forward', gtk.STOCK_GO_FORWARD, _("_Forward"),
"Right", _("Go to the next page in the history"),
self.go_forward)
])
self._add_action_group(self.forward_action)
# add the Refresh action to handle the Refresh button
self._add_action('Refresh', gtk.STOCK_REFRESH, _("_Refresh"),
callback=self.refresh,
accel="R",
tip=_("Stop and reload the page."))
def init_parent_signals_for_map(self, widget, event):
# required to properly bootstrap the signal handlers.
# This handler is connected by build_widget. After the outside ViewManager
# has placed this widget we are able to access the parent container.
pass
def create_start_page(self):
"""
This command creates a default start page, and returns the URL of this
page.
"""
tmpdir = GEOVIEW_SUBPATH
data = """
%(title)s
%(content)s
""" % { 'height' : 600,
'title' : _('Start page for the Html View'),
'content': _('Type an webpage address at the top, and hit'
' the execute button to load a webpage in this'
' page\n
\n'
'For example: http://gramps-project.org
')
}
filename = os.path.join(tmpdir, 'startpage')
fd = file(filename,"w+")
fd.write(data)
fd.close()
return 'file://'+filename
#-------------------------------------------------------------------------
#
# GeoView
#
#-------------------------------------------------------------------------
class GeoView(HtmlView):
def __init__(self,dbstate,uistate):
HtmlView.__init__(self, dbstate, uistate, title=_('GeoView'))
self.usedmap = "openstreetmap"
self.displaytype = "person"
self.nbmarkers = 0
self.without = 0
self.nbpages = 0
def top_widget(self):
"""
The top widget to use, for GeoView, none
"""
return gtk.Label()
def on_delete(self):
"""
We need to suppress temporary files here.
"""
pass
def init_parent_signals_for_map(self, widget, event):
# required to properly bootstrap the signal handlers.
# This handler is connected by build_widget. After the outside ViewManager
# has placed this widget we are able to access the parent container.
self.box.disconnect(self.bootstrap_handler)
self.box.parent.connect("size-allocate", self.size_request_for_map)
self.size_request_for_map(widget.parent,event)
def size_request_for_map(self, widget, event, data=None):
v = widget.get_allocation()
self.width = v.width
self.height = v.height
uri = self.renderer.get_uri()
self.external_uri()
if self.need_to_resize != True:
try:
self.geo_places(self.displaytype)
except:
pass
def set_active(self):
self.key_active_changed = self.dbstate.connect('active-changed',
self.goto_active_person)
def set_inactive(self):
HtmlView.set_inactive(self)
self.dbstate.disconnect(self.key_active_changed)
def get_stock(self):
"""
Returns the name of the stock icon to use for the display.
This assumes that this icon has already been registered with
GNOME as a stock icon.
"""
return 'gramps-geo'
def change_map(self,usedmap):
self.renderer.execute_script("javascript:mapstraction.swap(map,'"+usedmap+"')");
def ui_definition(self):
"""
Specifies the UIManager XML code that defines the menus and buttons
associated with the interface.
"""
if Config.get(Config.GEOVIEW_GOOGLEMAPS):
alternate_map = "GoogleMaps"
elif Config.get(Config.GEOVIEW_OPENLAYERS):
alternate_map = "OpenLayersMaps"
elif Config.get(Config.GEOVIEW_YAHOO):
alternate_map = "YahooMaps"
elif Config.get(Config.GEOVIEW_MICROSOFT):
alternate_map = "MicrosoftMaps"
return '''
''' % alternate_map
def define_actions(self):
"""
Required define_actions function for PageView. Builds the action
group information required.
"""
HtmlView._define_actions_fw_bw(self)
self.forward_action.set_sensitive(False)
self.back_action.set_sensitive(False)
self._add_action('OpenStreetMap', 'gramps-openstreetmap', _('_OpenStreetMap'),
callback=self.select_OpenStreetMap_map,
tip=_("Select OpenStreetMap Maps"))
if Config.get(Config.GEOVIEW_GOOGLEMAPS):
self._add_action('GoogleMaps', 'gramps-alternate-map',
_('_Google Maps'),
callback=self.select_google_map,
tip=_("Select Google Maps. If possible, "
"choose OpenStreetMap!"))
elif Config.get(Config.GEOVIEW_OPENLAYERS):
self._add_action('OpenLayersMaps', 'gramps-alternate-map',
_('_OpenLayers Maps'),
callback=self.select_openlayers_map,
tip=_("Select OpenLayers Maps. If possible,"
" choose OpenStreetMap"))
elif Config.get(Config.GEOVIEW_YAHOO):
self._add_action('YahooMaps', 'gramps-alternate-map',
_('_Yahoo! Maps'),
callback=self.select_yahoo_map,
tip=_("Select Yahoo Maps. If possible, choose"
" OpenStreetMap"))
elif Config.get(Config.GEOVIEW_MICROSOFT):
self._add_action('MicrosoftMaps', 'gramps-alternate-map',
_('_Microsoft Maps'),
callback=self.select_microsoft_map,
tip=_("Select Microsoft Maps. If possible,"
" choose OpenStreetMap"))
self._add_action('AllPlacesMaps', gtk.STOCK_HOME, _('_AllPlacesMaps'),
callback=self.all_places,
tip=_("Attempt to view all database places on the Map."))
self._add_action('PersonMaps', 'gramps-person', _('_Person'),
callback=self.person_places,
tip=_("Attempt to view all the places where lived the selected people."))
self._add_action('FamilyMaps', 'gramps-parents-add', _('_Family'),
callback=self.family_places,
tip=_("Attempt to view places on the Map of the selected people's family."))
self._add_action('EventMaps', 'gramps-event', _('_Event'),
callback=self.event_places,
tip=_("Attempt to view places on the Map for all events."))
def goto_active_person(self,handle=None):
self.geo_places(self.displaytype)
def all_places(self,handle=None):
"""
Specifies the place for the home person to display with mapstraction.
"""
self.displaytype = "places"
self.geo_places(self.displaytype)
def person_places(self,handle=None):
"""
Specifies the person places.
"""
self.displaytype = "person"
self.geo_places(self.displaytype)
def family_places(self,handle=None):
"""
Specifies the family places to display with mapstraction.
"""
self.displaytype = "family"
self.geo_places(self.displaytype)
def event_places(self,handle=None):
"""
Specifies all event places to display with mapstraction.
"""
self.displaytype = "event"
self.geo_places(self.displaytype)
def geo_places(self,displaytype):
"""
Specifies the places to display with mapstraction.
"""
self.external_url = False
self.nbmarkers = 0
self.without = 0
self.createMapstraction(displaytype)
self.open("file://"+self.htmlfile)
def select_OpenStreetMap_map(self,handle=None):
self.change_map("openstreetmap")
def select_openlayers_map(self,handle=None):
self.change_map("openlayers")
def select_google_map(self,handle=None):
self.change_map("google")
def select_yahoo_map(self,handle=None):
self.change_map("yahoo")
def select_microsoft_map(self,handle=None):
self.change_map("microsoft")
def set_mozembed_proxy(self):
"""
Try to see if we have some proxy environment variable.
http_proxy in our case.
The standard format is : http://[user:password@]proxy:port/
This function is only used with gtkmozembed.
"""
try:
proxy = os.environ['http_proxy']
data = ""
if proxy:
prefs = open(MOZEMBED_PATH+MOZEMBED_SUBPATH+"/prefs.js","w")
host_port = None
parts = urlparse.urlparse(proxy)
if not parts[0] or parts[0] == 'http':
host_port = parts[1]
t = host_port.split(':')
host = t[0].strip()
if host:
try:
port = int(t[1])
except:
user = host
u = t[1].split('@')
password = u[0]
host = u[1]
port = int(t[2])
if port and host:
port = str(port)
prefs.write('user_pref("network.proxy.type", 1);\r\n')
prefs.write('user_pref("network.proxy.http", "'+host+'");\r\n')
prefs.write('user_pref("network.proxy.http_port", '+port+');\r\n')
prefs.write('user_pref("network.proxy.no_proxies_on", "127.0.0.1,localhost,localhost.localdomain");\r\n')
prefs.write('user_pref("network.proxy.share_proxy_settings", true);\r\n')
prefs.write('user_pref("network.http.proxy.pipelining", true);\r\n')
prefs.write('user_pref("network.http.proxy.keep-alive", true);\r\n')
prefs.write('user_pref("network.http.proxy.version", 1.1);\r\n')
prefs.write('user_pref("network.http.sendRefererHeader, 0);\r\n')
prefs.close()
except:
try: # trying to remove pref.js in case of proxy change.
os.remove(MOZEMBED_PATH+MOZEMBED_SUBPATH+"/prefs.js")
except:
pass
pass # We don't use a proxy or the http_proxy variable is not set.
def create_page_for_places_without_coordinates(self):
"""
This command creates a page with the list of all places without coordinates
page.
"""
data = """
%(title)s
%(content)s
""" % { 'title' : _('List of places without coordinates'),
'content': _('Here is the list of all places in the databases'
' for which we have no coordinates.
'
' This means no longitude or latitude.')
}
end = """
"""
fd = open(self.without_coord_file,"w+")
fd.write(data)
self.places = sorted(self.place_without_coordinates)
i = 1
fd.write("
NB | Gramps ID | Place | ")
for place in self.places:
fd.write("%d | %s | %s | " % ( i, place[0], place[1] ))
i += 1
fd.write(end)
fd.close()
def createMapstractionPostHeader(self,h3mess,h4mess,maxpages,curpage,ftype):
self.maxgen=Config.get(Config.GENERATION_DEPTH)
if self.maxyear == 0:
self.maxyear=2100
if self.minyear == 9999:
self.minyear=1500
period = (self.maxyear-self.minyear)
intvl = (period/self.maxgen)
modulo = intvl - ( intvl % 10 )
if modulo == 0:
modulo = 10
self.minyear=( self.minyear - ( self.minyear % 10 ) )
self.maxyear=( self.maxyear - ( self.maxyear % 10 ) )
self.yearint=(self.maxyear-self.minyear)/self.maxgen
self.yearint=( self.yearint - ( self.yearint % modulo ) )
if self.yearint == 0:
self.yearint=10
self.mapview.write(" var step = %s;\n" % self.yearint)
self.mapview.write(" \n")
self.mapview.write(" \n")
self.mapview.write(" \n")
if maxpages > 1:
message = _("We have %d markers, so I split this document in %d pages of %d markers : " % (self.nbmarkers, maxpages, NB_MARKERS_PER_PAGE))
self.mapview.write(" %s
\n" % message)
if curpage != 1:
priorfile=GEOVIEW_SUBPATH+"/GeoV-%c-%05d.html" % (ftype,curpage-1)
self.mapview.write("
--" % priorfile)
else:
self.mapview.write(" --")
for page in range(1,maxpages+1,1):
if page == curpage:
self.mapview.write(" %d" % page)
else:
if ( page < curpage + 11 ) and ( page > curpage - 11 ):
nextfile=GEOVIEW_SUBPATH+"/GeoV-%c-%05d.html" % (ftype,page)
self.mapview.write("
%d" % (nextfile, page))
if curpage != maxpages:
nextfile=GEOVIEW_SUBPATH+"/GeoV-%c-%05d.html" % (ftype,curpage+1)
self.mapview.write("
++" % nextfile)
else:
self.mapview.write(" ++")
self.mapview.write("\n
\n")
if self.without != 0:
self.without_coord_file = GEOVIEW_SUBPATH+"/without_coord.html"
self.mapview.write("\n" )
self.create_page_for_places_without_coordinates()
if self.displaytype != "places":
self.mapview.write(" \n")
self.mapview.write("
\n")
self.mapview.write("%s
" % h3mess)
if h4mess:
self.mapview.write("%s
" % h4mess)
def createMapstractionHeader(self,filename):
self.mapview = open(filename,"w+")
self.mapview.write("\n")
self.mapview.write("\n")
self.mapview.write(" \n")
self.mapview.write(" \n")
self.mapview.write(" Geo Maps JavaScript API for Gramps\n")
self.mapview.write(" \n")
self.mapview.write(" \n")
if self.usedmap == "microsoft":
self.mapview.write(" \n")
elif self.usedmap == "yahoo":
self.mapview.write(" \n")
elif self.usedmap == "openlayers":
self.mapview.write(" \n")
else: # openstreetmap and google
self.mapview.write(" \n")
self.mapview.write(" \n")
def createPersonMarkers(self,db,person,comment):
"""
This function create all markers for the specified person.
"""
latitude = ""
longitude = ""
if person:
birth_ref = person.get_birth_ref()
if birth_ref:
birth = db.db.get_event_from_handle(birth_ref.ref)
birthdate = birth.get_date_object()
birthyear = birthdate.get_year()
bplace_handle = birth.get_place_handle()
if bplace_handle:
place = db.db.get_place_from_handle(bplace_handle)
longitude = place.get_longitude()
latitude = place.get_latitude()
latitude, longitude = conv_lat_lon(latitude, longitude, "D.D8")
if comment:
descr1=comment+" : "+_("birth place.")
else:
descr1=_("birth place.")
descr = place.get_title()
city = place.get_main_location().get_city()
country = place.get_main_location().get_country()
# place.get_longitude and place.get_latitude return one string.
# We have coordinates when the two values contains non null string.
if ( longitude and latitude ):
self.append_to_places_list(descr, gen.lib.EventType.BIRTH,
_nd.display(person), latitude, longitude,
descr1, int(self.center), birthyear)
self.center = False
else:
self.append_to_places_without_coordinates(place.gramps_id,descr)
latitude = ""
longitude = ""
death_ref = person.get_death_ref()
if death_ref:
death = db.db.get_event_from_handle(death_ref.ref)
deathdate = death.get_date_object()
deathyear = deathdate.get_year()
dplace_handle = death.get_place_handle()
if dplace_handle:
place = db.db.get_place_from_handle(dplace_handle)
longitude = place.get_longitude()
latitude = place.get_latitude()
latitude, longitude = conv_lat_lon(latitude, longitude, "D.D8")
descr = place.get_title()
if comment:
descr1=comment+" : "+_("death place.")
else:
descr1=_("death place.")
city = place.get_main_location().get_city()
country = place.get_main_location().get_country()
# place.get_longitude and place.get_latitude return one string.
# We have coordinates when the two values contains non null string.
if ( longitude and latitude ):
self.append_to_places_list(descr, gen.lib.EventType.DEATH,
_nd.display(person), latitude, longitude,
descr1, int(self.center), deathyear)
self.center = False
else:
self.append_to_places_without_coordinates(place.gramps_id,descr)
def createMapstractionPlaces(self,db):
"""
This function create the marker for each place in the database
which has a lat/lon.
"""
self.place_list = []
self.place_without_coordinates = []
self.minlat = float(0.0)
self.maxlat = float(0.0)
self.minlon = float(0.0)
self.maxlon = float(0.0)
self.minyear = int(9999)
self.maxyear = int(0)
latitude = ""
longitude = ""
self.center = True
for place_handle in db.db.get_place_handles():
place = db.db.get_place_from_handle( place_handle)
if place:
descr = place.get_title()
descr1 = _("Id : %s")%place.gramps_id
longitude = place.get_longitude()
latitude = place.get_latitude()
latitude, longitude = conv_lat_lon(latitude, longitude, "D.D8")
city = place.get_main_location().get_city()
country = place.get_main_location().get_country()
# place.get_longitude and place.get_latitude return one string.
# We have coordinates when the two values contains non null string.
if ( longitude and latitude ):
self.append_to_places_list(descr, None,
"",
latitude, longitude,
descr1, self.center, None)
self.center = False
else:
self.append_to_places_without_coordinates(place.gramps_id,descr)
if self.center:
mess = _("Cannot center the map. No location with coordinates.")
else:
mess = ""
self.create_pages(1,_("All places in the database with coordinates."),mess)
def createMapstractionEvents(self,db):
"""
This function create one marker for each place associated with an event in the database
which has a lat/lon.
"""
self.place_list = []
self.place_without_coordinates = []
self.minlat = float(0.0)
self.maxlat = float(0.0)
self.minlon = float(0.0)
self.maxlon = float(0.0)
self.minyear = int(9999)
self.maxyear = int(0)
latitude = ""
longitude = ""
self.center = True
for event_handle in db.db.get_event_handles():
event = db.db.get_event_from_handle( event_handle)
if event:
pl_id = event.get_place_handle()
eventdate = event.get_date_object()
eventyear = eventdate.get_year()
descr1 = _("Id : %s (%s)")%(event.gramps_id,eventyear)
if pl_id:
place = db.db.get_place_from_handle(pl_id)
longitude = place.get_longitude()
latitude = place.get_latitude()
latitude, longitude = conv_lat_lon(latitude, longitude, "D.D8")
city = place.get_main_location().get_city()
country = place.get_main_location().get_country()
descr2 = "%s; %s" % (city,country)
# place.get_longitude and place.get_latitude return one string.
# We have coordinates when the two values contains non null string.
if ( longitude and latitude ):
person_list = [ db.db.get_person_from_handle(ref_handle)
for (ref_type, ref_handle) in db.db.find_backlink_handles(event_handle)
if ref_type == 'Person'
]
if person_list:
descr = "
"
for person in person_list:
descr = _("%s%s
") % (descr, _nd.display(person))
descr = _("%s; %s%s") % (gen.lib.EventType(event.get_type()),place.get_title(), descr)
else:
descr = _("%s; %s
") % (gen.lib.EventType(event.get_type()),place.get_title())
self.append_to_places_list(descr1, descr,
descr,
latitude, longitude,
descr2, self.center, eventyear)
self.center = False
else:
self.append_to_places_without_coordinates(place.gramps_id,descr)
if self.center:
mess = _("Cannot center the map. No location with coordinates.")
else:
mess = ""
self.create_pages(2,_("All events in the database with coordinates."),mess)
def createMapstractionFamily(self,db):
"""
This function create all markers for each people of a family
in the database which has a lat/lon.
"""
self.place_list = []
self.place_without_coordinates = []
self.minlat = float(0.0)
self.maxlat = float(0.0)
self.minlon = float(0.0)
self.maxlon = float(0.0)
self.minyear = int(9999)
self.maxyear = int(0)
self.center = True
person = None
if db.active:
person = db.active
if person is not None:
family_list = person.get_family_handle_list()
if len(family_list) > 0:
fhandle = family_list[0] # first is primary
fam = db.db.get_family_from_handle(fhandle)
father_handle = fam.get_father_handle()
father = db.db.get_person_from_handle(father_handle)
if father:
comment = "Id : %s : %s"%(father.gramps_id,_("Father"))
self.createPersonMarkers(db,father,comment)
mother_handle = fam.get_mother_handle()
mother = db.db.get_person_from_handle(mother_handle)
if mother:
comment = "Id : %s : %s"%(mother.gramps_id,_("Mother"))
self.createPersonMarkers(db,mother,comment)
index = 0
child_ref_list = fam.get_child_ref_list()
if child_ref_list:
for child_ref in child_ref_list:
child = db.db.get_person_from_handle(child_ref.ref)
if child:
index += 1
comment = "Id : %s : %s %d"%(child.gramps_id,
_("Child"),index)
self.createPersonMarkers(db,child,comment)
if self.center:
mess = _("Cannot center the map. No location with coordinates.")
if person is not None:
self.create_pages(3, _("The active person's family members have no places with coordinates."), mess)
else:
self.create_pages(3, _("You have no active person to see this person's family places."), mess)
else:
mess = ""
self.create_pages(3, ( _("All %s people's family places in the database with coordinates.") %
_nd.display(person) ),
mess)
def createMapstractionPerson(self,db):
"""
This function create all markers for each people's event
in the database which has a lat/lon.
"""
self.place_list = []
self.place_without_coordinates = []
self.minlat = float(0.0)
self.maxlat = float(0.0)
self.minlon = float(0.0)
self.maxlon = float(0.0)
self.minyear = int(9999)
self.maxyear = int(0)
latitude = ""
longitude = ""
person = None
if db.active:
person = db.active
self.center = True
if person is not None:
# For each event, if we have a place, set a marker.
for event_ref in person.get_event_ref_list():
if not event_ref:
continue
if event_ref.role != gen.lib.EventRoleType.PRIMARY:
# Only match primaries, no witnesses
continue
event = db.db.get_event_from_handle(event_ref.ref)
eventdate = event.get_date_object()
eventyear = eventdate.get_year()
place_handle = event.get_place_handle()
if place_handle:
place = db.db.get_place_from_handle(place_handle)
longitude = place.get_longitude()
latitude = place.get_latitude()
latitude, longitude = conv_lat_lon(latitude, longitude, "D.D8")
descr = place.get_title()
city = place.get_main_location().get_city()
country = place.get_main_location().get_country()
evt=gen.lib.EventType(event.get_type())
descr1=_("%s : %s")%(evt,_nd.display(person))
# place.get_longitude and place.get_latitude return one string.
# We have coordinates when the two values contains non null string.
if ( longitude and latitude ):
self.append_to_places_list(descr, evt,
_nd.display(person),
latitude, longitude,
descr1, self.center, eventyear)
self.center = False
else:
self.append_to_places_without_coordinates(place.gramps_id,descr)
if self.center:
mess = _("Cannot center the map. No location with coordinates.")
if person is not None:
self.create_pages(4, _("The active person has no places with coordinates."), mess)
else:
self.create_pages(4, _("You have no active person to see this person's places."), mess)
else:
mess = ""
self.create_pages(4,( _("All event places for %s.") % _nd.display(person) ), mess)
def createMapstractionNotImplemented(self,db):
"""
This function is used to inform the user this work is not implemented.
"""
self.mapview.write(" %s ...
"%_("Not yet implemented"))