fix several overlay plugin rendering glitches (Issue #103)

pull/106/head
Hartmut Holzgraefe 2023-11-25 17:29:45 +00:00
rodzic 471e535697
commit 1468c04d0d
6 zmienionych plików z 42 dodań i 44 usunięć

Wyświetl plik

@ -422,11 +422,9 @@ class Renderer:
y = bbox.get_top_left()[0] - lat y = bbox.get_top_left()[0] - lat
y*= (dpi/72.0) * self._map_coords[3] / horiz_angle_span y*= (dpi/72.0) * self._map_coords[3] / horiz_angle_span
y+= (dpi/72.0) * self._map_coords[1]
x = lon - bbox.get_top_left()[1] x = lon - bbox.get_top_left()[1]
x*= (dpi/72.0) * self._map_coords[2] / vert_angle_span x*= (dpi/72.0) * self._map_coords[2] / vert_angle_span
x+= (dpi/72.0) * self._map_coords[0]
return x,y return x,y

Wyświetl plik

@ -367,7 +367,6 @@ class MultiPageRenderer(Renderer):
plugin_name = path.lstrip('internal:') plugin_name = path.lstrip('internal:')
LOG.warning("plugin: %s - %s" % (path, plugin_name)) LOG.warning("plugin: %s - %s" % (path, plugin_name))
if plugin_name == 'qrcode': if plugin_name == 'qrcode':
# QRcode should not be rendered on actual map pages here
if not self.rc.qrcode_text: if not self.rc.qrcode_text:
self.rc.qrcode_text = self.rc.origin_url self.rc.qrcode_text = self.rc.origin_url
else: else:
@ -425,10 +424,8 @@ class MultiPageRenderer(Renderer):
for overlay in self._overlays: for overlay in self._overlays:
path = overlay.path.strip() path = overlay.path.strip()
if path.startswith('internal:'): if path.startswith('internal:'):
if plugin_name != 'qrcode': plugin_name = path.lstrip('internal:')
# ignore QRcode plugin overlay_effects[plugin_name] = self.get_plugin(plugin_name)
plugin_name = path.lstrip('internal:')
overlay_effects[plugin_name] = self.get_plugin(plugin_name)
else: else:
overlay_canvases.append(MapCanvas(overlay, overlay_canvases.append(MapCanvas(overlay,
bb, self._usable_area_width_pt, bb, self._usable_area_width_pt,
@ -649,8 +646,7 @@ class MultiPageRenderer(Renderer):
path = overlay.path.strip() path = overlay.path.strip()
if path.startswith('internal:'): if path.startswith('internal:'):
plugin_name = path.lstrip('internal:') plugin_name = path.lstrip('internal:')
if plugin_name != "qrcode": self._frontpage_overlay_effects[plugin_name] = self.get_plugin(plugin_name)
self._frontpage_overlay_effects[plugin_name] = self.get_plugin(plugin_name)
else: else:
ov_canvas = MapCanvas(overlay, ov_canvas = MapCanvas(overlay,
self.rc.bounding_box, self.rc.bounding_box,
@ -693,18 +689,19 @@ class MultiPageRenderer(Renderer):
rendered_map = ov_canvas.get_rendered_map() rendered_map = ov_canvas.get_rendered_map()
mapnik.render(rendered_map, ctx) mapnik.render(rendered_map, ctx)
# TODO offsets are not correct here, so we skip overlay plugins for now
# apply effect overlays # apply effect overlays
ctx.save() # ctx.save()
# we have to undo border adjustments here # we have to undo border adjustments here
ctx.translate(0, -(0.3 * h + Renderer.PRINT_SAFE_MARGIN_PT)) # ctx.translate(0, -(0.3 * h + Renderer.PRINT_SAFE_MARGIN_PT))
self._map_canvas = self._front_page_map; # self._map_canvas = self._front_page_map;
for plugin_name, effect in self._frontpage_overlay_effects.items(): # for plugin_name, effect in self._frontpage_overlay_effects.items():
try: # try:
effect.render(self, ctx) # effect.render(self, ctx)
except Exception as e: # except Exception as e:
# TODO better logging # # TODO better logging
LOG.warning("Error while rendering overlay: %s\n%s" % (plugin_name, e)) # LOG.warning("Error while rendering overlay: %s\n%s" % (plugin_name, e))
ctx.restore() # ctx.restore()
@ -910,10 +907,6 @@ class MultiPageRenderer(Renderer):
# apply effect overlays # apply effect overlays
ctx.save() ctx.save()
# we have to undo border adjustments here
ctx.translate(
-commons.convert_pt_to_dots(Renderer.PRINT_SAFE_MARGIN_PT),
-commons.convert_pt_to_dots(Renderer.PRINT_SAFE_MARGIN_PT))
self._map_canvas = self.overview_canvas; self._map_canvas = self.overview_canvas;
for plugin_name, effect in self.overview_overlay_effects.items(): for plugin_name, effect in self.overview_overlay_effects.items():
try: try:
@ -1178,18 +1171,14 @@ class MultiPageRenderer(Renderer):
# apply effect overlays # apply effect overlays
ctx.save() ctx.save()
# we have to undo border adjustments here
ctx.translate(-commons.convert_pt_to_dots(self.grayed_margin_pt)/2,
-commons.convert_pt_to_dots(self.grayed_margin_pt)/2)
self._map_canvas = canvas;
for plugin_name, effect in overlay_effects.items(): for plugin_name, effect in overlay_effects.items():
self.grid = grid self.grid = grid
self._map_canvas = canvas
try: try:
effect.render(self, ctx) effect.render(self, ctx)
except Exception as e: except Exception as e:
# TODO better logging # TODO better logging
LOG.warning("Error while rendering overlay: %s\n%s" % (plugin_name, e)) LOG.warning("Error while rendering overlay: %s\n%s" % (plugin_name, e))
effect.render(self, ctx)
ctx.restore() ctx.restore()

Wyświetl plik

@ -42,19 +42,14 @@ def render(renderer, ctx):
# load and scale the SVG image # load and scale the SVG image
rose_grp, rose_width = Renderer._get_svg(ctx, svg_path, h) rose_grp, rose_width = Renderer._get_svg(ctx, svg_path, h)
# determine image position depending on renderer used
if type(renderer).__name__ == "MultiPageRenderer":
x = 0
y = 0
else:
x = convert_pt_to_dots(renderer._map_coords[0], renderer.dpi)
y = convert_pt_to_dots(renderer._map_coords[1], renderer.dpi)
# output image on top of the current cairo context # output image on top of the current cairo context
ctx.save() ctx.save()
ctx.translate(x + h/2, y + h/2)
ctx.translate(h/10, h/10) # leave a bit of space to the map border
ctx.set_source(rose_grp) ctx.set_source(rose_grp)
ctx.paint_with_alpha(0.75) ctx.paint_with_alpha(0.75)
ctx.stroke() ctx.stroke()
ctx.restore() ctx.restore()

Wyświetl plik

@ -16,6 +16,11 @@ import logging
LOG = logging.getLogger('ocitysmap') LOG = logging.getLogger('ocitysmap')
def render(renderer, ctx): def render(renderer, ctx):
if type(renderer).__name__ == "MultiPageRenderer":
# the multi page renderer has the QR code in the front page footer
# no need to also have it repeated on all individual map pages
return
if renderer.rc.qrcode_text: if renderer.rc.qrcode_text:
qrcode_text = renderer.rc.qrcode_text qrcode_text = renderer.rc.qrcode_text
else: else:
@ -24,8 +29,8 @@ def render(renderer, ctx):
if not qrcode_text: if not qrcode_text:
return return
x = convert_pt_to_dots(renderer._map_coords[0], renderer.dpi) x = 0
y = convert_pt_to_dots(renderer._map_coords[1], renderer.dpi) y = 0
w = convert_pt_to_dots(renderer._map_coords[2], renderer.dpi) w = convert_pt_to_dots(renderer._map_coords[2], renderer.dpi)
h = convert_pt_to_dots(renderer._map_coords[3], renderer.dpi) h = convert_pt_to_dots(renderer._map_coords[3], renderer.dpi)
W = convert_pt_to_dots(renderer.paper_width_pt) W = convert_pt_to_dots(renderer.paper_width_pt)
@ -54,6 +59,9 @@ def render(renderer, ctx):
svg = rsvg.new_from_data(svg_val) svg = rsvg.new_from_data(svg_val)
svgstr.close() svgstr.close()
ctx.save()
ctx.push_group()
ctx.save() ctx.save()
ctx.translate(x + w - size, ctx.translate(x + w - size,
y + h - size) y + h - size)
@ -62,3 +70,9 @@ def render(renderer, ctx):
ctx.scale(factor, factor) ctx.scale(factor, factor)
svg.render_cairo(ctx) svg.render_cairo(ctx)
ctx.restore() ctx.restore()
ctx.set_source(ctx.pop_group())
ctx.paint_with_alpha(0.75)
ctx.stroke()
ctx.restore()

Wyświetl plik

@ -9,6 +9,8 @@ from ocitysmap.layoutlib.commons import convert_pt_to_dots
from ocitysmap.layoutlib.abstract_renderer import Renderer from ocitysmap.layoutlib.abstract_renderer import Renderer
from math import floor, log10 from math import floor, log10
LOG = logging.getLogger('ocitysmap')
def render(renderer, ctx): def render(renderer, ctx):
def pt2px(dot): def pt2px(dot):
return dot * renderer.dpi / 72.0 return dot * renderer.dpi / 72.0
@ -29,7 +31,7 @@ def render(renderer, ctx):
dots = map_coords_dots[2] dots = map_coords_dots[2]
if type(renderer).__name__ == "MultiPageRenderer": if type(renderer).__name__ == "MultiPageRenderer":
dots = dots - 2 * renderer.PRINT_SAFE_MARGIN_PT dots = dots - 2 * renderer.grayed_margin_pt
step_horiz = dots / renderer.grid.horiz_count step_horiz = dots / renderer.grid.horiz_count
@ -46,12 +48,11 @@ def render(renderer, ctx):
tickHeight = pt2px(15) # height of the tick marks tickHeight = pt2px(15) # height of the tick marks
x = barBuffer x = barBuffer
x+= map_coords_dots[0]
if type(renderer).__name__ == "MultiPageRenderer": if type(renderer).__name__ == "MultiPageRenderer":
x += renderer.PRINT_SAFE_MARGIN_PT # TODO more perfectly align actual scale bar with grid here?
x += renderer.grayed_margin_pt
y = m.height y = m.height
y+= map_coords_dots[1]
y-= barBuffer+lBuffer+lBuffer+tickHeight y-= barBuffer+lBuffer+lBuffer+tickHeight
w = pxScaleBar + 2*lBuffer w = pxScaleBar + 2*lBuffer

Wyświetl plik

@ -605,7 +605,8 @@ class SinglePageRenderer(Renderer):
# make sure that plugins do not render outside the actual map area # make sure that plugins do not render outside the actual map area
ctx.save() ctx.save()
ctx.rectangle(map_coords_dots[0], map_coords_dots[1], map_coords_dots[2], map_coords_dots[3]) ctx.translate(map_coords_dots[0], map_coords_dots[1])
ctx.rectangle(0, 0, map_coords_dots[2], map_coords_dots[3])
ctx.clip() ctx.clip()
# apply effect plugin overlays # apply effect plugin overlays