[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Maposmatic-dev] [PATCH] multi-page: finalize and refactor code for fro
From: |
Thomas Petazzoni |
Subject: |
[Maposmatic-dev] [PATCH] multi-page: finalize and refactor code for front page generation |
Date: |
Fri, 30 Mar 2012 23:41:38 +0200 |
Signed-off-by: Thomas Petazzoni <address@hidden>
---
ocitysmap2/layoutlib/multi_page_renderer.py | 177 +++++++++++++++++++++------
1 files changed, 137 insertions(+), 40 deletions(-)
diff --git a/ocitysmap2/layoutlib/multi_page_renderer.py
b/ocitysmap2/layoutlib/multi_page_renderer.py
index 7baac31..e214860 100644
--- a/ocitysmap2/layoutlib/multi_page_renderer.py
+++ b/ocitysmap2/layoutlib/multi_page_renderer.py
@@ -33,6 +33,7 @@ import coords
import locale
import pangocairo
import pango
+import datetime
from itertools import groupby
@@ -230,6 +231,9 @@ class MultiPageRenderer(Renderer):
# Merge all indexes
self.index_categories = self._merge_page_indexes(indexes)
+ # Prepare the small map for the front page
+ self._front_page_map = self._prepare_front_page_map(dpi)
+
def _merge_page_indexes(self, indexes):
# First, we split street categories and "other" categories,
# because we sort them and we don't want to have the "other"
@@ -312,32 +316,40 @@ class MultiPageRenderer(Renderer):
c1 = self._proj.inverse(mapnik.Coord(envelope.maxx, envelope.maxy))
return coords.BoundingBox(c0.y, c0.x, c1.y, c1.x)
- def _render_front_page(self, ctx, cairo_surface, dpi):
-
- ctx.save()
-
- # Draw a nice grey rectangle covering the whole page
- ctx.set_source_rgb(.85,.85,.85)
- ctx.rectangle(Renderer.PRINT_SAFE_MARGIN_PT,
- Renderer.PRINT_SAFE_MARGIN_PT,
- self._usable_area_width_pt,
- self._usable_area_height_pt)
- ctx.fill()
+ def _prepare_front_page_map(self, dpi):
+ front_page_map_w = \
+ self._usable_area_width_pt - 2 * Renderer.PRINT_SAFE_MARGIN_PT
+ front_page_map_h = \
+ (self._usable_area_height_pt - 2 * Renderer.PRINT_SAFE_MARGIN_PT)
/ 2
- ctx.save()
+ # Create the nice small map
+ front_page_map = \
+ MapCanvas(self.rc.stylesheet,
+ self.rc.bounding_box,
+ front_page_map_w,
+ front_page_map_h,
+ dpi,
+ extend_bbox_to_ratio=True)
- # Translate into the working area, taking another
- # PRINT_SAFE_MARGIN_PT inside the grey area.
- ctx.translate(2 * Renderer.PRINT_SAFE_MARGIN_PT,
- 2 * Renderer.PRINT_SAFE_MARGIN_PT)
- w = self._usable_area_width_pt - 2 * Renderer.PRINT_SAFE_MARGIN_PT
- h = self._usable_area_height_pt - 2 * Renderer.PRINT_SAFE_MARGIN_PT
+ # Add the shape that greys out everything that is outside of
+ # the administrative boundary.
+ exterior =
shapely.wkt.loads(front_page_map.get_actual_bounding_box().as_wkt())
+ interior = shapely.wkt.loads(self.rc.polygon_wkt)
+ shade_wkt = exterior.difference(interior).wkt
+ shade = maplib.shapes.PolyShapeFile(self.rc.bounding_box,
+ os.path.join(self.tmpdir, 'shape_overview_cover.shp'),
+ 'shade-overview-cover')
+ shade.add_shade_from_wkt(shade_wkt)
+ front_page_map.add_shape_file(shade)
+ front_page_map.render()
+ return front_page_map
+ def _render_front_page_header(self, ctx, w, h):
# Draw a light blue block which will contain the name of the
# city being rendered.
blue_w = w
blue_h = 0.3 * h
- ctx.set_source_rgb(0.807, 0.898, 0.964)
+ ctx.set_source_rgb(.80,.80,.80)
ctx.rectangle(0, 0, blue_w, blue_h)
ctx.fill()
@@ -361,31 +373,116 @@ class MultiPageRenderer(Renderer):
pc.show_layout(layout)
ctx.restore()
- # Create the nice small map
- map_canvas = MapCanvas(self.rc.stylesheet,
- self.rc.bounding_box,
- w, 0.5 * h, dpi,
- extend_bbox_to_ratio=True)
-
- # We will render it slightly below the title
+ def _render_front_page_map(self, ctx, dpi, w, h):
+ # We will render the map slightly below the title
+ ctx.save()
ctx.translate(0, 0.3 * h + Renderer.PRINT_SAFE_MARGIN_PT)
- # Add the shape that greys out everything that is outside of
- # the administrative boundary.
- exterior =
shapely.wkt.loads(map_canvas.get_actual_bounding_box().as_wkt())
- interior = shapely.wkt.loads(self.rc.polygon_wkt)
- shade_wkt = exterior.difference(interior).wkt
- shade = maplib.shapes.PolyShapeFile(self.rc.bounding_box,
- os.path.join(self.tmpdir, 'shape_overview_cover.shp'),
- 'shade-overview-cover')
- shade.add_shade_from_wkt(shade_wkt)
- map_canvas.add_shape_file(shade)
-
# Render the map !
- map_canvas.render()
- mapnik.render(map_canvas.get_rendered_map(), ctx)
+ mapnik.render(self._front_page_map.get_rendered_map(), ctx)
+ ctx.restore()
+
+ def _render_front_page_footer(self, ctx, w, h, osm_date):
+ ctx.save()
+
+ # Draw the footer
+ ctx.translate(0, 0.8 * h + 2 * Renderer.PRINT_SAFE_MARGIN_PT)
+
+ # Display a nice grey rectangle as the background of the
+ # footer
+ footer_w = w
+ footer_h = 0.2 * h - 2 * Renderer.PRINT_SAFE_MARGIN_PT
+ ctx.set_source_rgb(.80,.80,.80)
+ ctx.rectangle(0, 0, footer_w, footer_h)
+ ctx.fill()
+
+ # Draw the OpenStreetMap logo to the right of the footer
+ logo_height = footer_h / 2
+ grp, logo_width = self._get_osm_logo(ctx, logo_height)
+ if grp:
+ ctx.save()
+ ctx.translate(w - logo_width - Renderer.PRINT_SAFE_MARGIN_PT,
+ logo_height / 2)
+ ctx.set_source(grp)
+ ctx.paint_with_alpha(0.8)
+ ctx.restore()
+
+ # Prepare the text for the left of the footer
+ today = datetime.date.today()
+ notice = \
+ _(u'Copyright © %(year)d MapOSMatic/OCitySMap developers.\n'
+ u'http://www.maposmatic.org\n\n'
+ u'Map data © %(year)d OpenStreetMap.org '
+ u'and contributors (cc-by-sa).\n'
+ u'http://www.openstreetmap.org\n\n'
+ u'Map rendered on: %(date)s. OSM data updated on: %(osmdate)s.\n'
+ u'The map may be incomplete or inaccurate. '
+ u'You can contribute to improve this map.\n'
+ u'See http://wiki.openstreetmap.org')
+
+ # We need the correct locale to be set for strftime().
+ prev_locale = locale.getlocale(locale.LC_TIME)
+ locale.setlocale(locale.LC_TIME, self.rc.i18n.language_code())
+ try:
+ if osm_date is None:
+ osm_date_str = _(u'unknown')
+ else:
+ osm_date_str = osm_date.strftime("%d %B %Y %H:%M")
+
+ notice = notice % {'year': today.year,
+ 'date': today.strftime("%d %B %Y"),
+ 'osmdate': osm_date_str}
+ finally:
+ locale.setlocale(locale.LC_TIME, prev_locale)
+
+ # Render the text
+ pc = pangocairo.CairoContext(ctx)
+ layout = pc.create_layout()
+ layout.set_width(int(footer_w * 0.7) * pango.SCALE)
+ layout.set_alignment(pango.ALIGN_LEFT)
+ fd = pango.FontDescription("Georgia Bold")
+ fd.set_size(pango.SCALE)
+ layout.set_font_description(fd)
+ layout.set_text(notice)
+ self._adjust_font_size(layout, fd, footer_w * 0.7, footer_h * 0.8)
+
+ text_x, text_y, text_w, text_h = layout.get_extents()[1]
+ ctx.save()
+ ctx.set_source_rgb(0,0,0)
+ ctx.translate(Renderer.PRINT_SAFE_MARGIN_PT,
+ (footer_h / 2) - (text_h / 2.0 / pango.SCALE))
+ # Hack to workaround what appears to be a Cairo bug: without
+ # drawing a rectangle here, the translation above is not taken
+ # into account for rendering the text.
+ ctx.rectangle(0, 0, 0, 0)
+ pc.show_layout(layout)
+ ctx.restore()
ctx.restore()
+
+ def _render_front_page(self, ctx, cairo_surface, dpi, osm_date):
+ # Draw a nice grey rectangle covering the whole page
+ ctx.save()
+ ctx.set_source_rgb(.95,.95,.95)
+ ctx.rectangle(Renderer.PRINT_SAFE_MARGIN_PT,
+ Renderer.PRINT_SAFE_MARGIN_PT,
+ self._usable_area_width_pt,
+ self._usable_area_height_pt)
+ ctx.fill()
+ ctx.restore()
+
+ # Translate into the working area, taking another
+ # PRINT_SAFE_MARGIN_PT inside the grey area.
+ ctx.save()
+ ctx.translate(2 * Renderer.PRINT_SAFE_MARGIN_PT,
+ 2 * Renderer.PRINT_SAFE_MARGIN_PT)
+ w = self._usable_area_width_pt - 2 * Renderer.PRINT_SAFE_MARGIN_PT
+ h = self._usable_area_height_pt - 2 * Renderer.PRINT_SAFE_MARGIN_PT
+
+ self._render_front_page_header(ctx, w, h)
+ self._render_front_page_map(ctx, dpi, w, h)
+ self._render_front_page_footer(ctx, w, h, osm_date)
+
ctx.restore()
cairo_surface.show_page()
@@ -393,7 +490,7 @@ class MultiPageRenderer(Renderer):
def render(self, cairo_surface, dpi, osm_date):
ctx = cairo.Context(cairo_surface)
- self._render_front_page(ctx, cairo_surface, dpi)
+ self._render_front_page(ctx, cairo_surface, dpi, osm_date)
for i, (canvas, grid) in enumerate(self.pages):
ctx.save()
--
1.7.4.1
- [Maposmatic-dev] [PATCH] multi-page: finalize and refactor code for front page generation,
Thomas Petazzoni <=