[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Maposmatic-dev] [PATCH 5/5] multi-page: add page number on overview pag
From: |
Étienne Loks |
Subject: |
[Maposmatic-dev] [PATCH 5/5] multi-page: add page number on overview page |
Date: |
Fri, 30 Mar 2012 18:51:21 +0200 |
---
ocitysmap2/coords.py | 21 ++++++++++++++
ocitysmap2/layoutlib/abstract_renderer.py | 41 +++++++++++++++++++++++++++
ocitysmap2/layoutlib/multi_page_renderer.py | 21 ++++++++------
ocitysmap2/maplib/overview_grid.py | 4 +-
4 files changed, 76 insertions(+), 11 deletions(-)
diff --git a/ocitysmap2/coords.py b/ocitysmap2/coords.py
index cad307f..3050c71 100644
--- a/ocitysmap2/coords.py
+++ b/ocitysmap2/coords.py
@@ -25,6 +25,15 @@
import math
import shapely.wkt
+try:
+ import mapnik2 as mapnik
+except ImportError:
+ import mapnik
+
+_MAPNIK_PROJECTION = "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 " \
+ "+lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m " \
+ "address@hidden +no_defs +over"
+
EARTH_RADIUS = 6370986 # meters
@@ -155,6 +164,18 @@ class BoundingBox:
return (int(math.ceil(pix_y)), int(math.ceil(pix_x)))
+ def to_mercator(self):
+ envelope = mapnik.Box2d(self.get_top_left()[1],
+ self.get_top_left()[0],
+ self.get_bottom_right()[1],
+ self.get_bottom_right()[0])
+ _proj = mapnik.Projection(_MAPNIK_PROJECTION)
+ bottom_left = _proj.forward(mapnik.Coord(envelope.minx, envelope.miny))
+ top_right = _proj.forward(mapnik.Coord(envelope.maxx, envelope.maxy))
+ top_left = mapnik.Coord(bottom_left.x, top_right.y)
+ bottom_right = mapnik.Coord(top_right.x, bottom_left.y)
+ return (bottom_right, bottom_left, top_left, top_right)
+
def as_javascript(self, name=None, color=None):
if name:
name_str = ", \"%s\"" % name
diff --git a/ocitysmap2/layoutlib/abstract_renderer.py
b/ocitysmap2/layoutlib/abstract_renderer.py
index 4f7083f..a3feb7e 100644
--- a/ocitysmap2/layoutlib/abstract_renderer.py
+++ b/ocitysmap2/layoutlib/abstract_renderer.py
@@ -26,6 +26,10 @@ import math
import os
import sys
import cairo
+try:
+ import mapnik2 as mapnik
+except ImportError:
+ import mapnik
import pango
import re
@@ -39,6 +43,8 @@ import logging
LOG = logging.getLogger('ocitysmap')
+OVERVIEW_PAGE_STR = "Page %(page_number)d"
+
class Renderer:
"""
The job of an OCitySMap layout renderer is to lay out the resulting map and
@@ -213,6 +219,41 @@ class Renderer:
ctx.restore()
+ @staticmethod
+ def _draw_overview_labels(ctx, map_canvas, overview_grid,
+ area_width_dots, area_height_dots):
+ """
+ Draw the page numbers for the overview grid.
+
+ Args:
+ ctx (cairo.Context): The cairo context to use to draw.
+ overview_grid (OverViewGrid): the overview grid object
+ area_width_dots/area_height_dots (numbers): size of the
+ drawing area (cairo units).
+ """
+ ctx.save()
+
+ ctx.set_font_size(18)
+
+ bbox = map_canvas.get_actual_bounding_box()
+ bottom_right, bottom_left, top_left, top_right = bbox.to_mercator()
+ bottom, left = bottom_right.y, top_left.x
+ coord_delta_y = top_left.y - bottom_right.y
+ coord_delta_x = bottom_right.x - top_left.x
+ for idx, page_bb in enumerate(overview_grid._pages_bbox):
+ p_bottom_right, p_bottom_left, p_top_left, p_top_right = \
+ page_bb.to_mercator()
+ center_x = p_top_left.x+(p_top_right.x-p_top_left.x)/2
+ center_y = p_bottom_left.y+(p_top_right.y-p_bottom_right.y)/2
+ y_percent = 100 - 100.0*(center_y - bottom)/coord_delta_y
+ y = int(area_height_dots*y_percent/100)
+
+ x_percent = 100.0*(center_x - left)/coord_delta_x
+ x = int(area_width_dots*x_percent/100)
+ Renderer._draw_centered_text(ctx,
+ OVERVIEW_PAGE_STR % {'page_number':idx+2}, x,
y)
+ ctx.restore()
+
def _create_map_canvas(self, width, height, dpi,
draw_contour_shade = True):
"""
diff --git a/ocitysmap2/layoutlib/multi_page_renderer.py
b/ocitysmap2/layoutlib/multi_page_renderer.py
index b69fd3a..5f57816 100644
--- a/ocitysmap2/layoutlib/multi_page_renderer.py
+++ b/ocitysmap2/layoutlib/multi_page_renderer.py
@@ -55,10 +55,6 @@ from indexlib.commons import IndexCategory
LOG = logging.getLogger('ocitysmap')
PAGE_STR = " - Page %(page_number)d"
-_MAPNIK_PROJECTION = "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 " \
- "+lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m " \
- "address@hidden +no_defs +over"
-
class MultiPageRenderer(Renderer):
"""
This Renderer creates a multi-pages map, with all the classic overlayed
@@ -90,7 +86,7 @@ class MultiPageRenderer(Renderer):
# print self.rc.bounding_box.as_javascript("original", "#00ff00")
# Convert the original Bounding box into Mercator meters
- self._proj = mapnik.Projection(_MAPNIK_PROJECTION)
+ self._proj = mapnik.Projection(coords._MAPNIK_PROJECTION)
orig_envelope = self._project_envelope(self.rc.bounding_box)
# Extend the bounding box to take into account the lost outter
@@ -222,7 +218,7 @@ class MultiPageRenderer(Renderer):
self.rc.stylesheet.grid_line_width)
map_canvas.render()
- self.pages.append((map_canvas, None))
+ self.pages.append((map_canvas, None, map_grid))
# Create the map canvas for each page
indexes = []
@@ -255,7 +251,7 @@ class MultiPageRenderer(Renderer):
self.rc.stylesheet.grid_line_width)
map_canvas.render()
- self.pages.append((map_canvas, map_grid))
+ self.pages.append((map_canvas, map_grid, None))
# Create the index for the current page
index = StreetIndex(self.db,
@@ -352,7 +348,7 @@ class MultiPageRenderer(Renderer):
def render(self, cairo_surface, dpi, osm_date):
ctx = cairo.Context(cairo_surface)
- for i, (canvas, grid) in enumerate(self.pages):
+ for i, (canvas, grid, overview_grid) in enumerate(self.pages):
ctx.save()
# Prepare to draw the map at the right location
@@ -373,8 +369,15 @@ class MultiPageRenderer(Renderer):
ctx.translate(commons.convert_pt_to_dots(self.grayed_margin_pt),
commons.convert_pt_to_dots(self.grayed_margin_pt))
- # Place the vertical and horizontal square labels
+ if overview_grid:
+ # draw pages numbers
+ self._draw_overview_labels(ctx, canvas, overview_grid,
+ commons.convert_pt_to_dots(self._usable_area_width_pt) \
+ - 2 *
commons.convert_pt_to_dots(self.grayed_margin_pt),
+ commons.convert_pt_to_dots(self._usable_area_height_pt) \
+ - 2 *
commons.convert_pt_to_dots(self.grayed_margin_pt))
if grid:
+ # Place the vertical and horizontal square labels
self._draw_labels(ctx, grid,
commons.convert_pt_to_dots(self._usable_area_width_pt) \
- 2 *
commons.convert_pt_to_dots(self.grayed_margin_pt),
diff --git a/ocitysmap2/maplib/overview_grid.py
b/ocitysmap2/maplib/overview_grid.py
index fdde50a..c45762c 100644
--- a/ocitysmap2/maplib/overview_grid.py
+++ b/ocitysmap2/maplib/overview_grid.py
@@ -34,8 +34,6 @@ class OverviewGrid:
l.info('Laying out of overview grid on %.1fx%.1fm area...' %
(self._width_m, self._height_m))
- self._pages_wkt = [bb.as_wkt() for bb in self._pages_bbox]
-
def generate_shape_file(self, filename):
"""Generates the grid shapefile with all the horizontal and
vertical lines added.
@@ -53,6 +51,8 @@ class OverviewGrid:
map(g.add_box, self._pages_bbox)
return g
+
+
if __name__ == "__main__":
logging.basicConfig(level=logging.DEBUG)
pass
--
1.7.9.1