diff --git a/gramps/plugins/lib/maps/geography.py b/gramps/plugins/lib/maps/geography.py index 2dfd92a5b..d493dbd8f 100644 --- a/gramps/plugins/lib/maps/geography.py +++ b/gramps/plugins/lib/maps/geography.py @@ -526,7 +526,8 @@ class GeoGraphyView(OsmGps, NavigationView): """ self.osm.remove_layer(layer) - def add_marker(self, menu, event, lat, lon, event_type, differtype, count): + def add_marker(self, menu, event, lat, lon, event_type, differtype, + count, color=None): """ Add a new marker """ @@ -541,7 +542,8 @@ 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. - self.marker_layer.add_marker((float(lat), float(lon)), value, count) + self.marker_layer.add_marker((float(lat), float(lon)), value, + count, color=color) def remove_all_gps(self): """ @@ -570,7 +572,8 @@ class GeoGraphyView(OsmGps, NavigationView): def _append_to_places_list(self, place, evttype, name, lat, longit, descr, year, icontype, - gramps_id, place_id, event_id, family_id + gramps_id, place_id, event_id, family_id, + color=None ): """ Create a list of places with coordinates. @@ -585,7 +588,8 @@ class GeoGraphyView(OsmGps, NavigationView): self.places_found.append([place, lat, longit]) self.place_list.append([place, name, evttype, lat, longit, descr, year, icontype, - gramps_id, place_id, event_id, family_id + gramps_id, place_id, event_id, family_id, + color ]) self.nbmarkers += 1 tfa = float(lat) @@ -650,7 +654,8 @@ class GeoGraphyView(OsmGps, NavigationView): count = 1 continue if last != current: - self.add_marker(None, None, lat, lon, icon, differtype, count) + self.add_marker(None, None, lat, lon, icon, differtype, + count, color=mark[12]) differtype = False count = 1 last = current @@ -662,7 +667,8 @@ class GeoGraphyView(OsmGps, NavigationView): if icon != mark[7]: differtype = True if lat != 0.0 and lon != 0.0: - self.add_marker(None, None, lat, lon, icon, differtype, count) + self.add_marker(None, None, lat, lon, icon, differtype, + count, color=mark[12]) self._set_center_and_zoom() _LOG.debug("%s", time.strftime(" stop create_marker : " "%a %d %b %Y %H:%M:%S", time.gmtime())) diff --git a/gramps/plugins/lib/maps/markerlayer.py b/gramps/plugins/lib/maps/markerlayer.py index ff5fe8916..ec5c071c7 100644 --- a/gramps/plugins/lib/maps/markerlayer.py +++ b/gramps/plugins/lib/maps/markerlayer.py @@ -26,7 +26,10 @@ # #------------------------------------------------------------------------- from gi.repository import GObject +from gi.repository import Gdk import time +from math import pi as PI + #------------------------------------------------------------------------ # @@ -90,14 +93,14 @@ class MarkerLayer(GObject.GObject, osmgpsmap.MapLayer): self.max_value = 0 self.min_value = 9999 - def add_marker(self, points, image, count): + def add_marker(self, points, image, count, color=None): """ Add a marker. Set minimum value, maximum value for the markers Set the average value too. We calculate that here, to minimize the overhead at markers drawing """ - self.markers.append((points, image, count)) + self.markers.append((points, image, count, color)) self.max_references += count self.max_places += 1 if count > self.max_value: @@ -121,7 +124,6 @@ class MarkerLayer(GObject.GObject, osmgpsmap.MapLayer): _LOG.debug("%s", time.strftime("start drawing : " "%a %d %b %Y %H:%M:%S", time.gmtime())) 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 mark = float(marker[2]) @@ -137,18 +139,25 @@ class MarkerLayer(GObject.GObject, osmgpsmap.MapLayer): conv_pt = osmgpsmap.MapPoint.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 try to place exactly the marker depending on its size. - # The left top corner 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 and to the height of the image. - # So we shift the image position. - pos_y = - int(48 * size + 0.5) - 10 - pos_x = - int((48 * size) / 6 + 0.5) - 10 - ctx.set_source_surface(marker[1], pos_x, pos_y) - ctx.paint() - ctx.restore() + if marker[3] == None: + # We use the standard icons. + ctx.save() + ctx.translate(coord_x, coord_y) + ctx.scale(size, size) + # below, we try to place exactly the marker depending on its + # size. The left top corner 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 and to the height of the + # image. So we shift the image position. + pos_y = - int(48 * size + 0.5) - 10 + pos_x = - int((48 * size) / 6 + 0.5) - 10 + ctx.set_source_surface(marker[1], pos_x, pos_y) + ctx.paint() + ctx.restore() + else: + # We use colored icons. + draw_marker(ctx, float(coord_x), float(coord_y), + size, marker[3][1]) _LOG.debug("%s", time.strftime("end drawing : " "%a %d %b %Y %H:%M:%S", time.gmtime())) @@ -172,3 +181,47 @@ class MarkerLayer(GObject.GObject, osmgpsmap.MapLayer): GObject.type_register(MarkerLayer) +def draw_marker(ctx, x1, y1, size, color): + width = 48.0 * size + height = width / 2 + color = Gdk.color_parse(color) + ctx.set_source_rgba(float(color.red / 65535.0), + float(color.green / 65535.0), + float(color.blue / 65535.0), + 1.0) # transparency + ctx.set_line_width (2.0); + ctx.move_to(x1, y1) + ctx.line_to((x1 + (height/3)), (y1 - height*2)) + ctx.line_to((x1 - (height/3)), (y1 - height*2)) + ctx.fill() + ctx.set_source_rgba(1.0, 0.0, 0.0, 0.5) + ctx.move_to(x1, y1) + ctx.line_to((x1 + (height/3)), (y1 - height*2)) + ctx.line_to((x1 - (height/3)), (y1 - height*2)) + ctx.line_to(x1, y1) + ctx.stroke() + ctx.save() + ctx.translate(x1 + width/4 - (width/4) , y1 - height*2 - (width/4)) + ctx.scale(width / 2., height / 2.) + ctx.arc(0., 0., 1., 0., 2 * PI) + ctx.fill_preserve() + ctx.set_source_rgba(1.0, 0.0, 0.0, 0.5) + ctx.set_line_width (2.0); + ctx.arc(0., 0., 1., 0., 2 * PI) + ctx.restore() + ctx.stroke(); + ctx.save() + ctx.set_source_rgba(float(color.red / 65535.0), + float(color.green / 65535.0), + float(color.blue / 65535.0), + 1.0) # transparency + #ctx.translate(x1 + width/4 - 12.0 , y1 - height*2 - 12.0) + ctx.translate(x1 + width/4 - (width/4) , y1 - height*2 - (width/4)) + ctx.scale(width / 2., height / 2.) + ctx.arc(0., 0., 1., 0., 2 * PI) + ctx.fill_preserve() + ctx.set_source_rgba(1.0, 0.0, 0.0, 0.5) + ctx.set_line_width (2.0); + ctx.arc(0., 0., 1., 0., 2 * PI) + ctx.restore() + ctx.stroke(); diff --git a/gramps/plugins/view/geoplaces.py b/gramps/plugins/view/geoplaces.py index d9349a796..b7af83eb1 100644 --- a/gramps/plugins/view/geoplaces.py +++ b/gramps/plugins/view/geoplaces.py @@ -50,11 +50,13 @@ _LOG = logging.getLogger("GeoGraphy.geoplaces") from gramps.gen.const import GRAMPS_LOCALE as glocale _ = glocale.translation.gettext from gramps.gen.lib import EventType +from gramps.gen.lib import PlaceType from gramps.gen.config import config from gramps.gen.display.place import displayer as _pd from gramps.gen.utils.place import conv_lat_lon from gramps.gui.views.bookmarks import PlaceBookmarks from gramps.plugins.lib.maps.geography import GeoGraphyView +from gramps.plugins.lib.maps import constants from gramps.gui.utils import ProgressMeter #------------------------------------------------------------------------- @@ -111,6 +113,45 @@ class GeoPlaces(GeoGraphyView): """ The view used to render places map. """ + CONFIGSETTINGS = ( + ('geography.path', constants.GEOGRAPHY_PATH), + + ('geography.zoom', 10), + ('geography.zoom_when_center', 12), + ('geography.show_cross', True), + ('geography.lock', False), + ('geography.center-lat', 0.0), + ('geography.center-lon', 0.0), + + ('geography.map_service', constants.OPENSTREETMAP), + ('geography.max_places', 5000), + ('geography.use-keypad', True), + + # specific to geoplaces : + + ('geography.color.unknown', '#008b00'), + ('geography.color.custom', '#008b00'), + ('geography.color.country', '#008b00'), + ('geography.color.county', '#008b00'), + ('geography.color.state', '#008b00'), + ('geography.color.city', '#008b00'), + ('geography.color.parish', '#008b00'), + ('geography.color.locality', '#008b00'), + ('geography.color.street', '#008b00'), + ('geography.color.province', '#008b00'), + ('geography.color.region', '#008b00'), + ('geography.color.department', '#008b00'), + ('geography.color.neighborhood', '#008b00'), + ('geography.color.district', '#008b00'), + ('geography.color.borough', '#008b00'), + ('geography.color.municipality', '#008b00'), + ('geography.color.town', '#008b00'), + ('geography.color.village', '#008b00'), + ('geography.color.hamlet', '#008b00'), + ('geography.color.farm', '#008b00'), + ('geography.color.building', '#008b00'), + ('geography.color.number', '#008b00'), + ) def __init__(self, pdata, dbstate, uistate, nav_group=0): self.window_name = _('Places map') @@ -135,6 +176,7 @@ class GeoPlaces(GeoGraphyView): self.itemoption = None self.menu = None self.cal = config.get('preferences.calendar-format-report') + self.plc_color = [] def get_title(self): """ @@ -219,7 +261,8 @@ class GeoPlaces(GeoGraphyView): None, # person.gramps_id place.gramps_id, None, # event.gramps_id - None # family.gramps_id + None, # family.gramps_id + color=self.plc_color[int(place.get_type())+1] ) def _createmap(self, place_x): @@ -245,6 +288,31 @@ class GeoPlaces(GeoGraphyView): self.message_layer.clear_messages() self.message_layer.clear_font_attributes() self.no_show_places_in_status_bar = False + _col = self._config.get + self.plc_color = [ + (PlaceType.UNKNOWN, _col('geography.color.unknown')), + (PlaceType.CUSTOM, _col('geography.color.custom')), + (PlaceType.COUNTRY, _col('geography.color.country')), + (PlaceType.STATE, _col('geography.color.state')), + (PlaceType.COUNTY, _col('geography.color.county')), + (PlaceType.CITY, _col('geography.color.city')), + (PlaceType.PARISH, _col('geography.color.parish')), + (PlaceType.LOCALITY, _col('geography.color.locality')), + (PlaceType.STREET, _col('geography.color.street')), + (PlaceType.PROVINCE, _col('geography.color.province')), + (PlaceType.REGION, _col('geography.color.region')), + (PlaceType.DEPARTMENT, _col('geography.color.department')), + (PlaceType.NEIGHBORHOOD, _col('geography.color.neighborhood')), + (PlaceType.DISTRICT, _col('geography.color.district')), + (PlaceType.BOROUGH, _col('geography.color.borough')), + (PlaceType.MUNICIPALITY, _col('geography.color.municipality')), + (PlaceType.TOWN, _col('geography.color.town')), + (PlaceType.VILLAGE, _col('geography.color.village')), + (PlaceType.HAMLET, _col('geography.color.hamlet')), + (PlaceType.FARM, _col('geography.color.farm')), + (PlaceType.BUILDING, _col('geography.color.building')), + (PlaceType.NUMBER, _col('geography.color.number')) + ] # base "villes de france" : 38101 places : # createmap : 8'50"; create_markers : 1'23" # base "villes de france" : 38101 places : @@ -439,3 +507,80 @@ class GeoPlaces(GeoGraphyView): """ return (("Place Filter",), ()) + + def specific_options(self, configdialog): + """ + Add specific entry to the preference menu. + Must be done in the associated view. + """ + grid = Gtk.Grid() + grid.set_border_width(12) + grid.set_column_spacing(6) + grid.set_row_spacing(6) + configdialog.add_color(grid, + _("Unknown"), + 1, 'geography.color.unknown', col=1) + configdialog.add_color(grid, + _("Custom"), + 2, 'geography.color.custom', col=1) + configdialog.add_color(grid, + _("Locality"), + 3, 'geography.color.locality', col=1) + configdialog.add_color(grid, + _("Street"), + 4, 'geography.color.street', col=1) + configdialog.add_color(grid, + _("Neighborhood"), + 5, 'geography.color.neighborhood', col=1) + configdialog.add_color(grid, + _("Borough"), + 6, 'geography.color.borough', col=1) + configdialog.add_color(grid, + _("Village"), + 7, 'geography.color.village', col=1) + configdialog.add_color(grid, + _("Hamlet"), + 8, 'geography.color.hamlet', col=1) + configdialog.add_color(grid, + _("Farm"), + 9, 'geography.color.farm', col=1) + configdialog.add_color(grid, + _("Building"), + 10, 'geography.color.building', col=1) + configdialog.add_color(grid, + _("Number"), + 11, 'geography.color.number', col=1) + configdialog.add_color(grid, + _("Country"), + 1, 'geography.color.country', col=4) + configdialog.add_color(grid, + _("State"), + 2, 'geography.color.state', col=4) + configdialog.add_color(grid, + _("County"), + 3, 'geography.color.county', col=4) + configdialog.add_color(grid, + _("Province"), + 4, 'geography.color.province', col=4) + configdialog.add_color(grid, + _("Region"), + 5, 'geography.color.region', col=4) + configdialog.add_color(grid, + _("Department"), + 6, 'geography.color.department', col=4) + configdialog.add_color(grid, + _("District"), + 7, 'geography.color.district', col=4) + configdialog.add_color(grid, + _("Parish"), + 8, 'geography.color.parish', col=4) + configdialog.add_color(grid, + _("City"), + 9, 'geography.color.city', col=4) + configdialog.add_color(grid, + _("Town"), + 10, 'geography.color.town', col=4) + configdialog.add_color(grid, + _("Municipality"), + 11, 'geography.color.municipality', col=4) + return _('The places marker color'), grid