11# -*- coding: utf-8 -*-
22
33import argparse
4- import math
4+ import logging
55import mapnik
6+ import math
7+ import re
8+ from nik4 .paper_size import get_paper_size
69
710
811VERSION = '1.7'
1518
1619class Nik4Image :
1720
18- def __init__ (self , options ):
21+ def __init__ (self , options , has_cairo ):
1922 self .options = options
23+ self .has_cairo = has_cairo
2024 self .need_cairo = False
2125 self .fmt = None
2226 self .ppmm = None
2327 self .scale = None
28+ self .fix_scale = False
2429 self .scale_factor = None
2530 self .size = None
2631 self .bbox = None
@@ -29,7 +34,7 @@ def __init__(self, options):
2934 self .rotate = None
3035
3136
32- def parse_url ( url , options ):
37+ def _parse_url ( self , url , options ):
3338 """Parse map URL into options map"""
3439 lat = None
3540 lon = None
@@ -81,11 +86,34 @@ def _set_ppm_and_scale_factor(self):
8186 self .ppmm = 90.7 / 25.4 * self .scale_factor
8287
8388 # svg / pdf can be scaled only in cairo mode
84- if self .scale_factor != 1 and self .need_cairo and not HAS_CAIRO :
89+ if self .scale_factor != 1 and self .need_cairo and not self . has_cairo :
8590 logging .error ('Warning: install pycairo for using --factor or --ppi' )
8691 self .scale_factor = 1
8792 self .ppmm = 90.7 / 25.4
8893
94+ def _set_projections_and_transform (self ):
95+ if self .options .projection .isdigit ():
96+ self .proj_target = mapnik .Projection ('+init=epsg:{}' .format (self .options .projection ))
97+ else :
98+ self .proj_target = mapnik .Projection (self .options .projection )
99+ self .transform = mapnik .ProjTransform (PROJ_LONLAT , self .proj_target )
100+
101+ def _set_bbox_with_center_scale_and_size (self ):
102+ # We don't know over which latitude range the bounding box spans, so we
103+ # first do everything in Web Mercator.
104+ center = TRANSFORM_LONLAT_WEBMERC .forward (mapnik .Coord (* self .options .center ))
105+ w = self .size [0 ] * self .scale / 2
106+ h = self .size [1 ] * self .scale / 2
107+ bbox_web_merc = mapnik .Box2d (center .x - w , center .y - h , center .x + w , center .y + h )
108+ self .bbox = TRANSFORM_LONLAT_WEBMERC .backward (bbox_web_merc )
109+ self .bbox = self .transform .forward (self .bbox )
110+ # now correct the scale
111+ self .correct_scale (bbox_web_merc )
112+ center = self .transform .forward (mapnik .Coord (* self .options .center ))
113+ w = self .size [0 ] * self .scale / 2
114+ h = self .size [1 ] * self .scale / 2
115+ self .bbox = mapnik .Box2d (center .x - w , center .y - h , center .x + w , center .y + h )
116+
89117 def setup_options (self ):
90118 dim_mm = None
91119 self .rotate = not self .options .norotate
@@ -98,14 +126,10 @@ def setup_options(self):
98126 self ._set_format ()
99127
100128 if self .options .url :
101- parse_url (self .options .url , self .options )
129+ self . _parse_url (self .options .url , self .options )
102130
103131 # output projection
104- if self .options .projection .isdigit ():
105- self .proj_target = mapnik .Projection ('+init=epsg:{}' .format (self .options .projection ))
106- else :
107- self .proj_target = mapnik .Projection (self .options .projection )
108- self .transform = mapnik .ProjTransform (PROJ_LONLAT , self .proj_target )
132+ self ._set_projections_and_transform ()
109133
110134 # get image size in millimeters
111135 if self .options .paper :
@@ -145,7 +169,6 @@ def setup_options(self):
145169 self .bbox = self .options .bbox
146170
147171 # scale can be specified with zoom or with 1:NNN scale
148- fix_scale = False
149172 if self .options .zoom :
150173 self .scale = 2 * 3.14159 * 6378137 / 2 ** (self .options .zoom + 8 ) / self .scale_factor
151174 elif self .options .scale :
@@ -157,7 +180,7 @@ def setup_options(self):
157180 elif self .options .bbox :
158181 self .scale = self .scale / math .cos (math .radians ((self .options .bbox [3 ] + self .options .bbox [1 ]) / 2 ))
159182 else :
160- fix_scale = True
183+ self . fix_scale = True
161184
162185 # all calculations are in EPSG:3857 projection (it's easier)
163186 if self .bbox :
@@ -168,20 +191,7 @@ def setup_options(self):
168191
169192 # calculate bbox through center, zoom and target size
170193 if not self .bbox and self .options .center and self .size and self .size [0 ] > 0 and self .size [1 ] > 0 and self .scale :
171- # We don't know over which latitude range the bounding box spans, so we
172- # first do everything in Web Mercator.
173- center = TRANSFORM_LONLAT_WEBMERC .forward (mapnik .Coord (* self .options .center ))
174- w = self .size [0 ] * self .scale / 2
175- h = self .size [1 ] * self .scale / 2
176- bbox_web_merc = mapnik .Box2d (center .x - w , center .y - h , center .x + w , center .y + h )
177- self .bbox = TRANSFORM_LONLAT_WEBMERC .backward (bbox_web_merc )
178- self .bbox = self .transform .forward (self .bbox )
179- # now correct the scale
180- self .correct_scale (bbox_web_merc )
181- center = self .transform .forward (mapnik .Coord (* self .options .center ))
182- w = self .size [0 ] * self .scale / 2
183- h = self .size [1 ] * self .scale / 2
184- self .bbox = mapnik .Box2d (center .x - w , center .y - h , center .x + w , center .y + h )
194+ self ._set_bbox_with_center_scale_and_size ()
185195
186196 def correct_scale (self , bbox_web_merc ):
187197 # correct scale if output projection is not EPSG:3857
0 commit comments