[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Maposmatic-dev] [PATCH 1/5] Add an overview page in the multi-page rend
From: |
Étienne Loks |
Subject: |
[Maposmatic-dev] [PATCH 1/5] Add an overview page in the multi-page renderer. |
Date: |
Fri, 30 Mar 2012 18:51:17 +0200 |
* get the right bounding box
* create the overview canvas
* draw the map and the appropriate shade
* draw boxes for each pages (OverwiewGrid)
* add the overview to the list of pages to be rendered
Signed-off-by: Étienne Loks <address@hidden>
---
ocitysmap2/layoutlib/multi_page_renderer.py | 47 +++++++++++-
ocitysmap2/maplib/overview_grid.py | 103 +++++++++++++++++++++++++++
ocitysmap2/maplib/shapes.py | 29 ++++++++
3 files changed, 176 insertions(+), 3 deletions(-)
create mode 100644 ocitysmap2/maplib/overview_grid.py
diff --git a/ocitysmap2/layoutlib/multi_page_renderer.py
b/ocitysmap2/layoutlib/multi_page_renderer.py
index 7645ed1..288f956 100644
--- a/ocitysmap2/layoutlib/multi_page_renderer.py
+++ b/ocitysmap2/layoutlib/multi_page_renderer.py
@@ -28,7 +28,10 @@ import tempfile
import math
import sys
import cairo
-import mapnik
+try:
+ import mapnik2 as mapnik
+except ImportError:
+ import mapnik
import coords
import locale
@@ -38,6 +41,7 @@ from abstract_renderer import Renderer
from ocitysmap2.maplib.map_canvas import MapCanvas
from ocitysmap2.maplib.grid import Grid
+from ocitysmap2.maplib.overview_grid import OverviewGrid
from indexlib.indexer import StreetIndex
from indexlib.multi_page_renderer import MultiPageStreetIndexRenderer
@@ -130,7 +134,7 @@ class MultiPageRenderer(Renderer):
self._usable_area_height_pt + (self._usable_area_height_pt -
overlap_margin_pt) * (nb_pages_height - 1)
# Convert this paper area available in the number of Mercator
- # meters that can we rendered on the map
+ # meters that can be rendered on the map
total_width_merc = \
commons.convert_pt_to_mm(total_width_pt_after_extension) *
scale_denom / 1000
total_height_merc = \
@@ -183,8 +187,45 @@ class MultiPageRenderer(Renderer):
# for i, (bb, bb_inner) in enumerate(bboxes):
# print bb.as_javascript(name="p%d" % i)
- # Create the map canvas for each page
self.pages = []
+ # Create an overview map
+
+ # Create the gray shape around the map
+ first_bbox, last_bbox = bboxes[0][0], bboxes[-1][0]
+ overview_coord = list(first_bbox.get_top_left()) + \
+ list(last_bbox.get_bottom_right())
+ overview_bb = coords.BoundingBox(*overview_coord
+ ).create_expanded(0.001, 0.001)
+
+ exterior = shapely.wkt.loads(overview_bb.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.shp'),
+ 'shade-overview')
+ shade.add_shade_from_wkt(shade_wkt)
+
+ # Create the grid
+ map_grid = OverviewGrid(overview_bb,
+ [bb for bb, bb_inner in bboxes], self.rc.i18n.isrtl())
+
+ grid_shape = map_grid.generate_shape_file(
+ os.path.join(self.tmpdir, 'grid_overview.shp'))
+
+ # Create one canvas for the current page
+ map_canvas = MapCanvas(self.rc.stylesheet,
+ overview_bb, graphical_ratio=None)
+
+ map_canvas.add_shape_file(shade)
+ map_canvas.add_shape_file(grid_shape,
+ self.rc.stylesheet.grid_line_color,
+ self.rc.stylesheet.grid_line_alpha,
+ self.rc.stylesheet.grid_line_width)
+
+ map_canvas.render()
+ self.pages.append((map_canvas, map_grid))
+
+ # Create the map canvas for each page
indexes = []
for i, (bb, bb_inner) in enumerate(bboxes):
diff --git a/ocitysmap2/maplib/overview_grid.py
b/ocitysmap2/maplib/overview_grid.py
new file mode 100644
index 0000000..d196036
--- /dev/null
+++ b/ocitysmap2/maplib/overview_grid.py
@@ -0,0 +1,103 @@
+# -*- coding: utf-8 -*-
+
+# ocitysmap, city map and street index generator from OpenStreetMap data
+
+import logging
+import math
+
+import shapes
+
+l = logging.getLogger('ocitysmap')
+
+class OverviewGrid:
+ """
+ The OverviewGrid class draw the grid overlayed on the overview map of a
+ multi-page render.
+ """
+
+ def __init__(self, bounding_box, pages_bounding_boxes, rtl=False):
+ """Creates a new grid for the given bounding boxes.
+
+ Args:
+ bounding_box (coords.BoundingBox): the map bounding box.
+ bounding_box (list of coords.BoundingBox): bounding boxes of the
+ pages.
+ rtl (boolean): whether the map is rendered in right-to-left mode or
+ not. Defaults to False.
+ """
+
+ self._bbox = bounding_box
+ self._pages_bbox = pages_bounding_boxes
+ self.rtl = rtl
+ self._height_m, self._width_m = bounding_box.spheric_sizes()
+
+ 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]
+
+ self.horiz_count = 1
+ self.vert_count = 1
+ self.horizontal_labels = ['plouf']
+ self.vertical_labels = ['plouf']
+
+ def generate_shape_file(self, filename):
+ """Generates the grid shapefile with all the horizontal and
+ vertical lines added.
+
+ Args:
+ filename (string): path to the temporary shape file that will be
+ generated.
+ Returns the ShapeFile object.
+ """
+
+ # Use a slightly larger bounding box for the shape file to accomodate
+ # for the small imprecisions of re-projecting.
+ g = shapes.BoxShapeFile(self._bbox.create_expanded(0.001, 0.001),
+ filename, 'grid')
+ map(g.add_box, self._pages_bbox)
+ return g
+
+ def _gen_horizontal_square_label(self, x):
+ """Generates a human-readable label for the given horizontal square
+ number. For example:
+ 1 -> A
+ 2 -> B
+ 26 -> Z
+ 27 -> AA
+ 28 -> AB
+ ...
+ """
+ if self.rtl:
+ x = len(self._vertical_lines) - x
+
+ label = ''
+ while x != -1:
+ label = chr(ord('A') + x % 26) + label
+ x = x/26 - 1
+ return label
+
+ def _gen_vertical_square_label(self, x):
+ """Generate a human-readable label for the given vertical square
+ number. Since we put numbers verticaly, this is simply x+1."""
+ return str(x + 1)
+
+ def get_location_str(self, lattitude, longitude):
+ """
+ Translate the given lattitude/longitude (EPSG:4326) into a
+ string of the form "CA42"
+ """
+ hdelta = min(abs(longitude - self._bbox.get_top_left()[1]),
+ self._horiz_angle_span)
+ hlabel = self.horizontal_labels[int(hdelta / self._horiz_unit_angle)]
+
+ vdelta = min(abs(lattitude - self._bbox.get_top_left()[0]),
+ self._vert_angle_span)
+ vlabel = self.vertical_labels[int(vdelta / self._vert_unit_angle)]
+
+ return "%s%s" % (hlabel, vlabel)
+
+
+if __name__ == "__main__":
+ logging.basicConfig(level=logging.DEBUG)
+ pass
diff --git a/ocitysmap2/maplib/shapes.py b/ocitysmap2/maplib/shapes.py
index a4739f1..fe915fd 100644
--- a/ocitysmap2/maplib/shapes.py
+++ b/ocitysmap2/maplib/shapes.py
@@ -125,6 +125,35 @@ class LineShapeFile(_ShapeFile):
self._add_feature(line)
return self
+class BoxShapeFile(LineShapeFile):
+ """
+ Shape file for Box geometries.
+ """
+
+ def add_box(self, box):
+ top_left, bottom_right = box.get_top_left(), box.get_bottom_right()
+
+ line = ogr.Geometry(type = ogr.wkbLineString)
+ line.AddPoint_2D(*list(reversed(top_left)))
+ line.AddPoint_2D(bottom_right[1], top_left[0])
+ self._add_feature(line)
+
+ line = ogr.Geometry(type = ogr.wkbLineString)
+ line.AddPoint_2D(bottom_right[1], top_left[0])
+ line.AddPoint_2D(*list(reversed(bottom_right)))
+ self._add_feature(line)
+
+ line = ogr.Geometry(type = ogr.wkbLineString)
+ line.AddPoint_2D(*list(reversed(bottom_right)))
+ line.AddPoint_2D(top_left[1], bottom_right[0])
+ self._add_feature(line)
+
+ line = ogr.Geometry(type = ogr.wkbLineString)
+ line.AddPoint_2D(top_left[1], bottom_right[0])
+ line.AddPoint_2D(*list(reversed(top_left)))
+ self._add_feature(line)
+ return self
+
class PolyShapeFile(_ShapeFile):
"""
Shape file for Polygon geometries.
--
1.7.9.1
- [Maposmatic-dev] [PATCH 1/5] Add an overview page in the multi-page renderer.,
Étienne Loks <=
- [Maposmatic-dev] [PATCH 2/5] multi-page: fix grey shape around the overview map, Étienne Loks, 2012/03/30
- [Maposmatic-dev] [PATCH 3/5] multi-page: fix pages box in the overview page, Étienne Loks, 2012/03/30
- [Maposmatic-dev] [PATCH 5/5] multi-page: add page number on overview page, Étienne Loks, 2012/03/30
- [Maposmatic-dev] [PATCH 4/5] multi-page: some clean-up, Étienne Loks, 2012/03/30
- Re: [Maposmatic-dev] [PATCH 1/5] Add an overview page in the multi-page renderer., Thomas Petazzoni, 2012/03/30