From 56f5d50003736a5e907e540ad7cae54ced28443a Mon Sep 17 00:00:00 2001 From: Serge Noiraud Date: Tue, 12 Jun 2012 21:27:17 +0000 Subject: [PATCH] Geography : New marker layer with variable marker size. svn: r19834 --- src/plugins/lib/maps/Makefile.am | 1 + src/plugins/lib/maps/geography.py | 29 ++--- src/plugins/lib/maps/markerlayer.py | 162 ++++++++++++++++++++++++++++ src/plugins/lib/maps/osmGps.py | 17 +++ 4 files changed, 196 insertions(+), 13 deletions(-) create mode 100644 src/plugins/lib/maps/markerlayer.py diff --git a/src/plugins/lib/maps/Makefile.am b/src/plugins/lib/maps/Makefile.am index be601801f..84af20848 100644 --- a/src/plugins/lib/maps/Makefile.am +++ b/src/plugins/lib/maps/Makefile.am @@ -9,6 +9,7 @@ pkgpython_PYTHON = \ geography.py\ __init__.py\ lifewaylayer.py\ + markerlayer.py\ osmGps.py\ placeselection.py\ selectionlayer.py diff --git a/src/plugins/lib/maps/geography.py b/src/plugins/lib/maps/geography.py index 5bd9e351e..df18a412f 100644 --- a/src/plugins/lib/maps/geography.py +++ b/src/plugins/lib/maps/geography.py @@ -144,13 +144,13 @@ class GeoGraphyView(OsmGps, NavigationView): self.places_found = [] self.select_fct = None self.geo_mainmap = gtk.gdk.pixbuf_new_from_file_at_size( - os.path.join(const.ROOT_DIR, "images", "22x22", + os.path.join(const.ROOT_DIR, "images", "48x48", ('gramps-geo-mainmap' + '.png' )), - 22, 22) + 48, 48) self.geo_altmap = gtk.gdk.pixbuf_new_from_file_at_size( - os.path.join(const.ROOT_DIR, "images", "22x22", + os.path.join(const.ROOT_DIR, "images", "48x48", ('gramps-geo-altmap' + '.png' )), - 22, 22) + 48, 48) if ( config.get('geography.map_service') in ( constants.OPENSTREETMAP, constants.OPENSTREETMAP_RENDERER )): default_image = self.geo_mainmap @@ -161,9 +161,9 @@ class GeoGraphyView(OsmGps, NavigationView): gen.lib.EventType.DEATH, gen.lib.EventType.MARRIAGE ): self.geo_othermap[ident] = gtk.gdk.pixbuf_new_from_file_at_size( - os.path.join(const.ROOT_DIR, "images", "22x22", + os.path.join(const.ROOT_DIR, "images", "48x48", (constants.ICONS.get(int(ident), default_image) + '.png' )), - 22, 22) + 48, 48) def change_page(self): """ @@ -385,7 +385,7 @@ class GeoGraphyView(OsmGps, NavigationView): """ self.osm.remove_layer(layer) - def add_marker(self, menu, event, lat, lon, event_type, differtype): + def add_marker(self, menu, event, lat, lon, event_type, differtype, count): """ Add a new marker """ @@ -400,8 +400,7 @@ class GeoGraphyView(OsmGps, NavigationView): value = self.geo_othermap.get(int(event_type), default_image) if differtype: # in case multiple evts value = default_image # we use default icon. - marker = self.osm.image_add_with_alignment(float(lat), - float(lon), value, 0.2, 1.0) + self.marker_layer.add_marker((float(lat), float(lon)), value, count) def remove_all_gps(self): """ @@ -489,6 +488,7 @@ class GeoGraphyView(OsmGps, NavigationView): lat = 0.0 lon = 0.0 icon = None + count = 0 self.uistate.set_busy_cursor(True) _LOG.debug("%s" % time.strftime("start create_marker : " "%a %d %b %Y %H:%M:%S", time.gmtime())) @@ -500,19 +500,22 @@ class GeoGraphyView(OsmGps, NavigationView): lon = mark[4] icon = mark[7] differtype = False + count = 1 continue if last != current: - self.add_marker(None, None, lat, lon, icon, differtype) + self.add_marker(None, None, lat, lon, icon, differtype, count) differtype = False + count = 1 last = current lat = mark[3] lon = mark[4] icon = mark[7] else: # This marker already exists. add info. + count += 1 if icon != mark[7]: differtype = True if ( lat != 0.0 and lon != 0.0 ): - self.add_marker(None, None, lat, lon, icon, differtype) + self.add_marker(None, None, lat, lon, icon, differtype, count) self._set_center_and_zoom() _LOG.debug("%s" % time.strftime(" stop create_marker : " "%a %d %b %Y %H:%M:%S", time.gmtime())) @@ -810,7 +813,7 @@ class GeoGraphyView(OsmGps, NavigationView): new_place.set_main_location(loc) try: EditPlace(self.dbstate, self.uistate, [], new_place) - self.add_marker(None, None, plat, plon, None, True) + self.add_marker(None, None, plat, plon, None, True, 0) except WindowActiveError: pass @@ -851,7 +854,7 @@ class GeoGraphyView(OsmGps, NavigationView): place.set_main_location(loc) try: EditPlace(self.dbstate, self.uistate, [], place) - self.add_marker(None, None, plat, plon, None, True) + self.add_marker(None, None, plat, plon, None, True, 0) except WindowActiveError: pass diff --git a/src/plugins/lib/maps/markerlayer.py b/src/plugins/lib/maps/markerlayer.py new file mode 100644 index 000000000..7975f8f38 --- /dev/null +++ b/src/plugins/lib/maps/markerlayer.py @@ -0,0 +1,162 @@ +# -*- python -*- +# -*- coding: utf-8 -*- +# +# Gramps - a GTK+/GNOME based genealogy program +# +# Copyright (C) 2011-2012 Serge Noiraud +# +# 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: grampsmaps.py 18399 2011-11-02 17:15:20Z noirauds $ + +#------------------------------------------------------------------------- +# +# Python modules +# +#------------------------------------------------------------------------- +import os +import gobject +from math import * + +#------------------------------------------------------------------------ +# +# Set up logging +# +#------------------------------------------------------------------------ +import logging +_LOG = logging.getLogger("maps.marker") + +#------------------------------------------------------------------------- +# +# GTK/Gnome modules +# +#------------------------------------------------------------------------- +import gtk + +#------------------------------------------------------------------------- +# +# Gramps Modules +# +#------------------------------------------------------------------------- +import const +import cairo + +#------------------------------------------------------------------------- +# +# osmGpsMap +# +#------------------------------------------------------------------------- + +try: + import osmgpsmap +except: + raise + +class MarkerLayer(gobject.GObject, osmgpsmap.GpsMapLayer): + """ + This is the layer used to display the markers. + """ + def __init__(self): + """ + Initialize the layer + """ + gobject.GObject.__init__(self) + self.markers = [] + self.max_references = 0 + self.max_places = 0 + self.nb_ref_by_places = 0 + self.max_value = 0 + self.min_value = 9999 + + def clear_markers(self): + """ + reset the layer attributes. + """ + self.markers = [] + self.max_references = 0 + self.max_places = 0 + self.nb_ref_by_places = 0 + self.max_value = 0 + self.min_value = 9999 + + def add_marker(self, points, image, count): + """ + Add a track or life marker. + """ + self.markers.append((points, image, count)) + self.max_references += count + self.max_places += 1 + if count > self.max_value: + self.max_value = count + if count < self.min_value: + self.min_value = count + self.nb_ref_by_places = self.max_references / self.max_places + + def do_draw(self, gpsmap, drawable): + """ + Draw all tracks or life markers. + """ + ctx = drawable.cairo_create() + max_interval = self.max_value - self.nb_ref_by_places + min_interval = self.nb_ref_by_places - self.min_value + if min_interval == 0: + min_interval = 0.01 + for marker in self.markers: + ctx.save() + # the icon size in 48, so the standard icon size is 0.6 * 48 = 28.8 + size = 0.6 + if float(marker[2]) > self.nb_ref_by_places: + # at maximum, we'll have an icon size = (0.6 + 0.3) * 48 = 43.2 + size += ( 0.3 * ( ( float(marker[2]) - self.nb_ref_by_places )/ max_interval) ) + else: + # at minimum, we'll have an icon size = (0.6 - 0.3) * 48 = 14.4 + size -= ( 0.3 * ( ( self.nb_ref_by_places - float(marker[2]) )/ min_interval) ) + + conv_pt = osmgpsmap.point_new_degrees(float(marker[0][0]), + float(marker[0][1])) + coord_x, coord_y = gpsmap.convert_geographic_to_screen(conv_pt) + ctx.translate(coord_x, coord_y) + ctx.scale( size, size) + # below, we must found one solution to place exactly the marker + # depending on its size. Normaly, the left top of the image is set to the coordinates + # The tip of the pin which should be at the marker position is at 3/18 of the width. + # rounding problem ? + posY = - (( 48 * size + 5 ) / ( 16.0 / 18.0 )) - 2 + posX = - (( 48 * size + 5 ) / 6 ) - 2 # 6 <= 3/18 = 1/6 + ctx.set_source_pixbuf(marker[1], posX, posY) + ctx.paint() + ctx.restore() + + def do_render(self, gpsmap): + """ + render the layer + """ + pass + + def do_busy(self): + """ + set the layer busy + """ + return False + + def do_button_press(self, gpsmap, gdkeventbutton): + """ + When we press a button. + """ + return False + +gobject.type_register(MarkerLayer) + diff --git a/src/plugins/lib/maps/osmGps.py b/src/plugins/lib/maps/osmGps.py index 9bac60c59..ae60ee24d 100644 --- a/src/plugins/lib/maps/osmGps.py +++ b/src/plugins/lib/maps/osmGps.py @@ -56,6 +56,7 @@ from dummylayer import DummyLayer from dummynogps import DummyMapNoGpsPoint from selectionlayer import SelectionLayer from lifewaylayer import LifeWayLayer +from markerlayer import MarkerLayer from datelayer import DateLayer from gen.ggettext import sgettext as _ from gen.config import config @@ -84,6 +85,7 @@ class OsmGps(): self.zone_selection = False self.selection_layer = None self.lifeway_layer = None + self.marker_layer = None self.date_layer = None self.context_id = 0 self.begin_selection = None @@ -138,6 +140,7 @@ class OsmGps(): self.osm.layer_add(DummyLayer()) self.selection_layer = self.add_selection_layer() self.lifeway_layer = self.add_lifeway_layer() + self.marker_layer = self.add_marker_layer() self.date_layer = self.add_date_layer() self.cross_map = osmgpsmap.GpsMapOsd( show_crosshair=False) self.set_crosshair(config.get("geography.show_cross")) @@ -181,6 +184,20 @@ class OsmGps(): """ return self.date_layer + def add_marker_layer(self): + """ + add the marker layer + """ + marker_layer = MarkerLayer() + self.osm.layer_add(marker_layer) + return marker_layer + + def get_marker_layer(self): + """ + get the marker layer + """ + return self.marker_layer + def add_lifeway_layer(self): """ add the track or life ways layer