1# -*- python -*- 2# -*- coding: utf-8 -*- 3# 4# Gramps - a GTK+/GNOME based genealogy program 5# 6# Copyright (C) 2011-2016 Serge Noiraud 7# 8# This program is free software; you can redistribute it and/or modify 9# it under the terms of the GNU General Public License as published by 10# the Free Software Foundation; either version 2 of the License, or 11# (at your option) any later version. 12# 13# This program is distributed in the hope that it will be useful, 14# but WITHOUT ANY WARRANTY; without even the implied warranty of 15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16# GNU General Public License for more details. 17# 18# You should have received a copy of the GNU General Public License 19# along with this program; if not, write to the Free Software 20# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21# 22 23#------------------------------------------------------------------------- 24# 25# Python modules 26# 27#------------------------------------------------------------------------- 28from gi.repository import GObject 29from math import pi 30 31#------------------------------------------------------------------------ 32# 33# Set up logging 34# 35#------------------------------------------------------------------------ 36import logging 37_LOG = logging.getLogger("maps.lifeway") 38 39#------------------------------------------------------------------------- 40# 41# GTK/Gnome modules 42# 43#------------------------------------------------------------------------- 44from gi.repository import Gdk 45import cairo 46 47#------------------------------------------------------------------------- 48# 49# Gramps Modules 50# 51#------------------------------------------------------------------------- 52 53#------------------------------------------------------------------------- 54# 55# osmGpsMap 56# 57#------------------------------------------------------------------------- 58 59try: 60 import gi 61 gi.require_version('OsmGpsMap', '1.0') 62 from gi.repository import OsmGpsMap as osmgpsmap 63except: 64 raise 65 66# pylint: disable=unused-argument 67 68class LifeWayLayer(GObject.GObject, osmgpsmap.MapLayer): 69 """ 70 This is the layer used to display tracks or the life way for one or several 71 individuals. 72 """ 73 def __init__(self): 74 """ 75 Initialize the layer 76 """ 77 GObject.GObject.__init__(self) 78 self.lifeways_ref = [] 79 self.lifeways = [] 80 self.comments = [] 81 82 def clear_ways(self): 83 """ 84 reset the layer attributes. 85 """ 86 self.lifeways_ref = [] 87 self.lifeways = [] 88 self.comments = [] 89 90 def add_way_ref(self, points, color, radius): 91 """ 92 Add a track or life way. 93 alpha is the transparence 94 radius is the size of the track. 95 """ 96 if isinstance(color, str): 97 color = Gdk.color_parse(color) 98 self.lifeways_ref.append((points, color, radius)) 99 100 def add_way(self, points, color): 101 """ 102 Add a track or life way. 103 """ 104 if isinstance(color, str): 105 color = Gdk.color_parse(color) 106 self.lifeways.append((points, color)) 107 108 def do_draw(self, gpsmap, ctx): 109 """ 110 Draw all tracks or life ways. 111 """ 112 for lifeway in self.lifeways_ref: 113 ctx.set_line_cap(cairo.LINE_CAP_ROUND) 114 ctx.set_line_join(cairo.LINE_JOIN_ROUND) 115 ctx.set_line_width(3) 116 color = lifeway[1] 117 ctx.set_source_rgba(float(color.red / 65535.0), 118 float(color.green / 65535.0), 119 float(color.blue / 65535.0), 120 0.1) # transparency 121 rds = float(lifeway[2]) 122 for point in lifeway[0]: 123 conv_pt1 = osmgpsmap.MapPoint.new_degrees(point[0], point[1]) 124 coord_x1, coord_y1 = gpsmap.convert_geographic_to_screen( 125 conv_pt1) 126 conv_pt2 = osmgpsmap.MapPoint.new_degrees(point[0]+rds, 127 point[1]) 128 coord_x2, coord_y2 = gpsmap.convert_geographic_to_screen( 129 conv_pt2) 130 coy = abs(coord_y2-coord_y1) 131 conv_pt2 = osmgpsmap.MapPoint.new_degrees(point[0], 132 point[1]+rds) 133 coord_x2, coord_y2 = gpsmap.convert_geographic_to_screen( 134 conv_pt2) 135 cox = abs(coord_x2-coord_x1) 136 cox = cox if cox > 1.2 else 1.2 137 coy = coy if coy > 1.2 else 1.2 138 coz = abs(1.0 / float(cox) * float(coy)) 139 coz = coz if coz > 1.2 else 1.2 140 ctx.save() 141 ctx.scale(1.0, coz) 142 ctx.move_to(coord_x1, coord_y1) 143 ctx.translate(coord_x1, coord_y1/coz) 144 ctx.arc(0.0, 0.0, cox, 0.0, 2*pi) 145 ctx.fill() 146 ctx.set_source_rgba(1.0, 0.0, 0.0, 0.5) 147 ctx.set_line_width(2.0) 148 ctx.arc(0.0, 0.0, cox, 0.0, 2*pi) 149 ctx.stroke() 150 ctx.restore() 151 152 for lifeway in self.lifeways: 153 ctx.set_operator(cairo.OPERATOR_ATOP) 154 ctx.set_line_width(3.0) 155 map_points = [] 156 for point in lifeway[0]: 157 conv_pt = osmgpsmap.MapPoint.new_degrees(point[0], point[1]) 158 coord_x, coord_y = gpsmap.convert_geographic_to_screen(conv_pt) 159 map_points.append((coord_x, coord_y)) 160 color = lifeway[1] 161 ctx.set_source_rgb(float(color.red / 65535.0), 162 float(color.green / 65535.0), 163 float(color.blue / 65535.0)) 164 first = True 165 for idx_pt in range(0, len(map_points)): 166 if first: 167 first = False 168 ctx.move_to(map_points[idx_pt][0], map_points[idx_pt][1]) 169 else: 170 ctx.line_to(map_points[idx_pt][0], map_points[idx_pt][1]) 171 ctx.stroke() 172 if len(map_points) == 1: # We have only one point 173 crdx = map_points[0][0] 174 crdy = map_points[0][1] 175 ctx.move_to(crdx, crdy) 176 ctx.line_to(crdx + 1, crdy + 1) 177 ctx.stroke() 178 179 def do_render(self, gpsmap): 180 """ 181 render the layer 182 """ 183 pass 184 185 def do_busy(self): 186 """ 187 set the layer busy 188 """ 189 return False 190 191 def do_button_press(self, gpsmap, gdkeventbutton): 192 """ 193 When we press a button. 194 """ 195 return False 196 197GObject.type_register(LifeWayLayer) 198 199