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