[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Maposmatic-dev] [PATCH 2/2] Fix scale computations to ensure a minimum
From: |
gael . utard |
Subject: |
[Maposmatic-dev] [PATCH 2/2] Fix scale computations to ensure a minimum zoom level |
Date: |
Tue, 10 Apr 2012 15:48:41 +0200 |
From: Gael UTARD <address@hidden>
Signed-off-by: Gael UTARD <address@hidden>
---
ocitysmap2/layoutlib/abstract_renderer.py | 12 ++++----
ocitysmap2/layoutlib/multi_page_renderer.py | 25 ++++++++--------
ocitysmap2/layoutlib/single_page_renderers.py | 38 +++++++++++++-----------
3 files changed, 39 insertions(+), 36 deletions(-)
diff --git a/ocitysmap2/layoutlib/abstract_renderer.py
b/ocitysmap2/layoutlib/abstract_renderer.py
index 5517ab9..7103db1 100644
--- a/ocitysmap2/layoutlib/abstract_renderer.py
+++ b/ocitysmap2/layoutlib/abstract_renderer.py
@@ -60,9 +60,10 @@ class Renderer:
GRID_LEGEND_MARGIN_RATIO = .02
- # The DEFAULT_KM_IN_MM represents the minimum acceptable size in milimeters
- # on the rendered map of a kilometer
- DEFAULT_KM_IN_MM = 100
+ # The DEFAULT_KM_IN_MM represents the minimum acceptable mapnik scale
+ # 12000 ensures that the zoom level will be 16 or higher
+ # see entities.xml.inc file from osm style sheet
+ DEFAULT_SCALE = 12000
def __init__(self, db, rc, tmpdir, dpi):
"""
@@ -265,15 +266,14 @@ class Renderer:
return [ "png", "svgz", "pdf", "csv" ]
@staticmethod
- def get_compatible_paper_sizes(bounding_box, resolution_km_in_mm):
+ def get_compatible_paper_sizes(bounding_box, scale):
"""Returns a list of the compatible paper sizes for the given bounding
box. The list is sorted, smaller papers first, and a "custom" paper
matching the dimensions of the bounding box is added at the end.
Args:
bounding_box (coords.BoundingBox): the map geographic bounding box.
- resolution_km_in_mm (int): size of a geographic kilometer in
- milimeters on the rendered map.
+ scale (int): minimum mapnik scale of the map.
Returns a list of tuples (paper name, width in mm, height in
mm, portrait_ok, landscape_ok, is_default). Paper sizes are
diff --git a/ocitysmap2/layoutlib/multi_page_renderer.py
b/ocitysmap2/layoutlib/multi_page_renderer.py
index e41af24..3123593 100644
--- a/ocitysmap2/layoutlib/multi_page_renderer.py
+++ b/ocitysmap2/layoutlib/multi_page_renderer.py
@@ -78,7 +78,15 @@ class MultiPageRenderer(Renderer):
self._usable_area_height_pt = (self.paper_height_pt -
(2 * Renderer.PRINT_SAFE_MARGIN_PT))
- scale_denom = 10000
+ scale_denom = Renderer.DEFAULT_SCALE
+
+ # the mapnik scale depends on the latitude
+ lat = self.rc.bounding_box.get_top_left()[0]
+ scale_denom *= math.cos(math.radians(lat))
+
+ # by convention, mapnik uses 90 ppi whereas cairo uses 72 ppi
+ scale_denom *= float(72) / 90
+
GRAYED_MARGIN_MM = 10
OVERLAP_MARGIN_MM = 20
@@ -671,6 +679,8 @@ class MultiPageRenderer(Renderer):
for map_number, (canvas, grid) in enumerate(self.pages):
rendered_map = canvas.get_rendered_map()
+ LOG.debug('Mapnik scale: 1/%f' % rendered_map.scale_denominator())
+ LOG.debug('Actual scale: 1/%f' % canvas.get_actual_scale())
mapnik.render(rendered_map, ctx)
# Place the vertical and horizontal square labels
@@ -711,17 +721,6 @@ class MultiPageRenderer(Renderer):
cairo_surface.flush()
- # Convert a length in geometric meters (in the real life) into a
- # length in paper millimiters (as drawn on the map).
- def _geo_m_to_paper_mm(self, geo_m):
- return geo_m / 1000.0 * Renderer.DEFAULT_KM_IN_MM * 2
-
- def _paper_mm_to_geo_m(self, paper_mm):
- return paper_mm * 1000.0 / (Renderer.DEFAULT_KM_IN_MM * 2)
-
- def _paper_pt_to_geo_m(self, paper_pt):
- return self._paper_mm_to_geo_m(commons.convert_pt_to_mm(paper_pt))
-
# In multi-page mode, we only render pdf format
@staticmethod
def get_compatible_output_formats():
@@ -732,7 +731,7 @@ class MultiPageRenderer(Renderer):
# The default paper size is A4 portrait
@staticmethod
def get_compatible_paper_sizes(bounding_box,
-
resolution_km_in_mm=Renderer.DEFAULT_KM_IN_MM,
+ scale=Renderer.DEFAULT_SCALE,
index_position=None, hsplit=1, vsplit=1):
valid_sizes = []
acceptable_formats = [ 'A5', 'A4', 'US letter' ]
diff --git a/ocitysmap2/layoutlib/single_page_renderers.py
b/ocitysmap2/layoutlib/single_page_renderers.py
index 04b9938..aa71f06 100644
--- a/ocitysmap2/layoutlib/single_page_renderers.py
+++ b/ocitysmap2/layoutlib/single_page_renderers.py
@@ -454,15 +454,14 @@ class SinglePageRenderer(Renderer):
@staticmethod
def _generic_get_compatible_paper_sizes(bounding_box,
-
resolution_km_in_mm=Renderer.DEFAULT_KM_IN_MM, index_position = None):
+ scale=Renderer.DEFAULT_SCALE,
index_position = None):
"""Returns a list of the compatible paper sizes for the given bounding
box. The list is sorted, smaller papers first, and a "custom" paper
matching the dimensions of the bounding box is added at the end.
Args:
bounding_box (coords.BoundingBox): the map geographic bounding box.
- resolution_km_in_mm (int): size of a geographic kilometer in
- milimeters on the rendered map.
+ scale (int): minimum mapnik scale of the map.
index_position (str): None or 'side' (index on side),
'bottom' (index at bottom).
@@ -470,9 +469,17 @@ class SinglePageRenderer(Renderer):
mm, portrait_ok, landscape_ok, is_default). Paper sizes are
represented in portrait mode.
"""
+
+ # the mapnik scale depends on the latitude
+ lat = bounding_box.get_top_left()[0]
+ scale *= math.cos(math.radians(lat))
+
+ # by convention, mapnik uses 90 ppi whereas cairo uses 72 ppi
+ scale *= float(72) / 90
+
geo_height_m, geo_width_m = bounding_box.spheric_sizes()
- paper_width_mm = geo_width_m/1000.0 * resolution_km_in_mm
- paper_height_mm = geo_height_m/1000.0 * resolution_km_in_mm
+ paper_width_mm = geo_width_m * 1000 / scale
+ paper_height_mm = geo_height_m * 1000 / scale
LOG.debug('Map represents %dx%dm, needs at least %.1fx%.1fcm '
'on paper.' % (geo_width_m, geo_height_m,
@@ -543,22 +550,21 @@ class SinglePageRendererNoIndex(SinglePageRenderer):
@staticmethod
def get_compatible_paper_sizes(bounding_box,
-
resolution_km_in_mm=Renderer.DEFAULT_KM_IN_MM):
+ scale=Renderer.DEFAULT_SCALE):
"""Returns a list of the compatible paper sizes for the given bounding
box. The list is sorted, smaller papers first, and a "custom" paper
matching the dimensions of the bounding box is added at the end.
Args:
bounding_box (coords.BoundingBox): the map geographic bounding box.
- resolution_km_in_mm (int): size of a geographic kilometer in
- milimeters on the rendered map.
+ scale (int): minimum mapnik scale of the map.
Returns a list of tuples (paper name, width in mm, height in
mm, portrait_ok, landscape_ok). Paper sizes are represented in
portrait mode.
"""
return SinglePageRenderer._generic_get_compatible_paper_sizes(
- bounding_box, resolution_km_in_mm, None)
+ bounding_box, scale, None)
class SinglePageRendererIndexOnSide(SinglePageRenderer):
@@ -578,22 +584,21 @@ class SinglePageRendererIndexOnSide(SinglePageRenderer):
@staticmethod
def get_compatible_paper_sizes(bounding_box,
-
resolution_km_in_mm=Renderer.DEFAULT_KM_IN_MM):
+ scale=Renderer.DEFAULT_SCALE):
"""Returns a list of the compatible paper sizes for the given bounding
box. The list is sorted, smaller papers first, and a "custom" paper
matching the dimensions of the bounding box is added at the end.
Args:
bounding_box (coords.BoundingBox): the map geographic bounding box.
- resolution_km_in_mm (int): size of a geographic kilometer in
- milimeters on the rendered map.
+ scale (int): minimum mapnik scale of the map.
Returns a list of tuples (paper name, width in mm, height in
mm, portrait_ok, landscape_ok). Paper sizes are represented in
portrait mode.
"""
return SinglePageRenderer._generic_get_compatible_paper_sizes(
- bounding_box, resolution_km_in_mm, 'side')
+ bounding_box, scale, 'side')
class SinglePageRendererIndexBottom(SinglePageRenderer):
@@ -613,22 +618,21 @@ class SinglePageRendererIndexBottom(SinglePageRenderer):
@staticmethod
def get_compatible_paper_sizes(bounding_box,
-
resolution_km_in_mm=Renderer.DEFAULT_KM_IN_MM):
+ scale=Renderer.DEFAULT_SCALE):
"""Returns a list of the compatible paper sizes for the given bounding
box. The list is sorted, smaller papers first, and a "custom" paper
matching the dimensions of the bounding box is added at the end.
Args:
bounding_box (coords.BoundingBox): the map geographic bounding box.
- resolution_km_in_mm (int): size of a geographic kilometer in
- milimeters on the rendered map.
+ scale (int): minimum mapnik scale of the map.
Returns a list of tuples (paper name, width in mm, height in
mm, portrait_ok, landscape_ok). Paper sizes are represented in
portrait mode.
"""
return SinglePageRenderer._generic_get_compatible_paper_sizes(
- bounding_box, resolution_km_in_mm, 'bottom')
+ bounding_box, scale, 'bottom')
if __name__ == '__main__':
--
1.7.5.4