pep8 formatting

This commit is contained in:
Dane Springmeyer 2012-03-13 08:22:34 -07:00
parent 5601731a89
commit 9cbef60595
2 changed files with 111 additions and 111 deletions

View file

@ -120,7 +120,7 @@ class _Coord(Coord,_injector):
Returns the easting (x) and northing (y) as a Returns the easting (x) and northing (y) as a
coordinate pair. coordinate pair.
Example: Project the geographic coordinates of the Example: Project the geographic coordinates of the
city center of Stuttgart into the local city center of Stuttgart into the local
map projection (GK Zone 3/DHDN, EPSG 31467) map projection (GK Zone 3/DHDN, EPSG 31467)
@ -136,7 +136,7 @@ class _Coord(Coord,_injector):
into the geographic space. The x component is into the geographic space. The x component is
considered to be the easting, the y component considered to be the easting, the y component
to be the northing. to be the northing.
Returns the longitude (x) and latitude (y) as a Returns the longitude (x) and latitude (y) as a
coordinate pair. coordinate pair.
@ -153,8 +153,8 @@ class _Coord(Coord,_injector):
class _Box2d(Box2d,_injector): class _Box2d(Box2d,_injector):
""" """
Represents a spatial envelope (i.e. bounding box). Represents a spatial envelope (i.e. bounding box).
Following operators are defined for Box2d: Following operators are defined for Box2d:
Addition: Addition:
@ -285,12 +285,12 @@ def Datasource(**keywords):
Create a Mapnik Datasource using a dictionary of parameters. Create a Mapnik Datasource using a dictionary of parameters.
Keywords must include: Keywords must include:
type='plugin_name' # e.g. type='gdal' type='plugin_name' # e.g. type='gdal'
See the convenience factory methods of each input plugin for See the convenience factory methods of each input plugin for
details on additional required keyword arguments. details on additional required keyword arguments.
""" """
return CreateDatasource(keywords) return CreateDatasource(keywords)
@ -322,7 +322,7 @@ def PostGIS(**keywords):
Required keyword arguments: Required keyword arguments:
dbname -- database name to connect to dbname -- database name to connect to
table -- table name or subselect query table -- table name or subselect query
*Note: if using subselects for the 'table' value consider also *Note: if using subselects for the 'table' value consider also
passing the 'geometry_field' and 'srid' and 'extent_from_subquery' passing the 'geometry_field' and 'srid' and 'extent_from_subquery'
options and/or specifying the 'geometry_table' option. options and/or specifying the 'geometry_table' option.

View file

@ -43,7 +43,7 @@ except ImportError:
class centering: class centering:
"""Style of centering to use with the map, the default is constrained """Style of centering to use with the map, the default is constrained
none: map will be placed flush with the margin/box in the top left corner none: map will be placed flush with the margin/box in the top left corner
constrained: map will be centered on the most constrained axis (for a portrait page constrained: map will be centered on the most constrained axis (for a portrait page
and a square map this will be horizontally) and a square map this will be horizontally)
@ -167,7 +167,7 @@ def sequence_scale(scale,scale_sequence):
"""Default scale helper, this rounds scale to a 'sensible' value""" """Default scale helper, this rounds scale to a 'sensible' value"""
factor = math.floor(math.log10(scale)) factor = math.floor(math.log10(scale))
norm = scale/(10**factor) norm = scale/(10**factor)
for s in scale_sequence: for s in scale_sequence:
if norm <= s: if norm <= s:
return s*10**factor return s*10**factor
@ -199,7 +199,7 @@ def deg_min_sec_scale(scale):
return x return x
else: else:
return x return x
def format_deg_min_sec(value): def format_deg_min_sec(value):
deg = math.floor(value) deg = math.floor(value)
min = math.floor((value-deg)/(1.0/60)) min = math.floor((value-deg)/(1.0/60))
@ -219,12 +219,12 @@ def convert_pdf_pages_to_layers(filename,output_name=None,layer_names=(),reverse
opens the given multipage PDF and converts each page to be a layer in a single page PDF opens the given multipage PDF and converts each page to be a layer in a single page PDF
layer_names should be a sequence of the user visible names of the layers, if not given layer_names should be a sequence of the user visible names of the layers, if not given
or if shorter than num pages generic names will be given to the unnamed layers or if shorter than num pages generic names will be given to the unnamed layers
if output_name is not provided a temporary file will be used for the conversion which if output_name is not provided a temporary file will be used for the conversion which
will then be copied back over the source file. will then be copied back over the source file.
requires pyPdf >= 1.13 to be available""" requires pyPdf >= 1.13 to be available"""
if not HAS_PYPDF: if not HAS_PYPDF:
raise Exception("pyPdf Not available") raise Exception("pyPdf Not available")
@ -235,13 +235,13 @@ def convert_pdf_pages_to_layers(filename,output_name=None,layer_names=(),reverse
else: else:
(outfd,outfilename) = tempfile.mkstemp(dir=os.path.dirname(filename)) (outfd,outfilename) = tempfile.mkstemp(dir=os.path.dirname(filename))
outfile = os.fdopen(outfd,'wb') outfile = os.fdopen(outfd,'wb')
i = pyPdf.PdfFileReader(infile) i = pyPdf.PdfFileReader(infile)
o = pyPdf.PdfFileWriter() o = pyPdf.PdfFileWriter()
template_page_size = i.pages[0].mediaBox template_page_size = i.pages[0].mediaBox
op = o.addBlankPage(width=template_page_size.getWidth(),height=template_page_size.getHeight()) op = o.addBlankPage(width=template_page_size.getWidth(),height=template_page_size.getHeight())
contentkey = pyPdf.generic.NameObject('/Contents') contentkey = pyPdf.generic.NameObject('/Contents')
resourcekey = pyPdf.generic.NameObject('/Resources') resourcekey = pyPdf.generic.NameObject('/Resources')
propertieskey = pyPdf.generic.NameObject('/Properties') propertieskey = pyPdf.generic.NameObject('/Properties')
@ -249,7 +249,7 @@ def convert_pdf_pages_to_layers(filename,output_name=None,layer_names=(),reverse
op[resourcekey] = pyPdf.generic.DictionaryObject() op[resourcekey] = pyPdf.generic.DictionaryObject()
properties = pyPdf.generic.DictionaryObject() properties = pyPdf.generic.DictionaryObject()
ocgs = pyPdf.generic.ArrayObject() ocgs = pyPdf.generic.ArrayObject()
for (i, p) in enumerate(i.pages): for (i, p) in enumerate(i.pages):
# first start an OCG for the layer # first start an OCG for the layer
ocgname = pyPdf.generic.NameObject('/oc%d' % i) ocgname = pyPdf.generic.NameObject('/oc%d' % i)
@ -262,9 +262,9 @@ def convert_pdf_pages_to_layers(filename,output_name=None,layer_names=(),reverse
p[pyPdf.generic.NameObject('/Contents')].append(ocgend) p[pyPdf.generic.NameObject('/Contents')].append(ocgend)
else: else:
p[pyPdf.generic.NameObject('/Contents')] = pyPdf.generic.ArrayObject((ocgstart,p['/Contents'],ocgend)) p[pyPdf.generic.NameObject('/Contents')] = pyPdf.generic.ArrayObject((ocgstart,p['/Contents'],ocgend))
op.mergePage(p) op.mergePage(p)
ocg = pyPdf.generic.DictionaryObject() ocg = pyPdf.generic.DictionaryObject()
ocg[pyPdf.generic.NameObject('/Type')] = pyPdf.generic.NameObject('/OCG') ocg[pyPdf.generic.NameObject('/Type')] = pyPdf.generic.NameObject('/OCG')
if len(layer_names) > i: if len(layer_names) > i:
@ -274,9 +274,9 @@ def convert_pdf_pages_to_layers(filename,output_name=None,layer_names=(),reverse
indirect_ocg = o._addObject(ocg) indirect_ocg = o._addObject(ocg)
properties[ocgname] = indirect_ocg properties[ocgname] = indirect_ocg
ocgs.append(indirect_ocg) ocgs.append(indirect_ocg)
op[resourcekey][propertieskey] = o._addObject(properties) op[resourcekey][propertieskey] = o._addObject(properties)
ocproperties = pyPdf.generic.DictionaryObject() ocproperties = pyPdf.generic.DictionaryObject()
ocproperties[pyPdf.generic.NameObject('/OCGs')] = ocgs ocproperties[pyPdf.generic.NameObject('/OCGs')] = ocgs
defaultview = pyPdf.generic.DictionaryObject() defaultview = pyPdf.generic.DictionaryObject()
@ -289,16 +289,16 @@ def convert_pdf_pages_to_layers(filename,output_name=None,layer_names=(),reverse
else: else:
defaultview[pyPdf.generic.NameObject('/Order')] = pyPdf.generic.ArrayObject(reversed(ocgs)) defaultview[pyPdf.generic.NameObject('/Order')] = pyPdf.generic.ArrayObject(reversed(ocgs))
defaultview[pyPdf.generic.NameObject('/OFF')] = pyPdf.generic.ArrayObject() defaultview[pyPdf.generic.NameObject('/OFF')] = pyPdf.generic.ArrayObject()
ocproperties[pyPdf.generic.NameObject('/D')] = o._addObject(defaultview) ocproperties[pyPdf.generic.NameObject('/D')] = o._addObject(defaultview)
o._root.getObject()[pyPdf.generic.NameObject('/OCProperties')] = o._addObject(ocproperties) o._root.getObject()[pyPdf.generic.NameObject('/OCProperties')] = o._addObject(ocproperties)
o.write(outfile) o.write(outfile)
outfile.close() outfile.close()
infile.close() infile.close()
if not output_name: if not output_name:
os.rename(outfilename, filename) os.rename(outfilename, filename)
@ -318,7 +318,7 @@ class PDFPrinter:
is_latlon=False, is_latlon=False,
use_ocg_layers=False): use_ocg_layers=False):
"""Creates a cairo surface and context to render a PDF with. """Creates a cairo surface and context to render a PDF with.
pagesize: tuple of page size in meters, see predefined sizes in pagessizes dict (default a4) pagesize: tuple of page size in meters, see predefined sizes in pagessizes dict (default a4)
margin: page margin in meters (default 0.01) margin: page margin in meters (default 0.01)
box: box within the page to render the map into (will not render over margin). This should be box: box within the page to render the map into (will not render over margin). This should be
@ -348,54 +348,54 @@ class PDFPrinter:
self._centering = centering self._centering = centering
self._is_latlon = is_latlon self._is_latlon = is_latlon
self._use_ocg_layers = use_ocg_layers self._use_ocg_layers = use_ocg_layers
self._s = None self._s = None
self._layer_names = [] self._layer_names = []
self._filename = None self._filename = None
self.map_box = None self.map_box = None
self.scale = None self.scale = None
# don't both to round the scale if they are not preserving the aspect ratio # don't both to round the scale if they are not preserving the aspect ratio
if not preserve_aspect: if not preserve_aspect:
self._scale = any_scale self._scale = any_scale
if percent_box: if percent_box:
self._box = Box2d(percent_box[0]*pagesize[0],percent_box[1]*pagesize[1], self._box = Box2d(percent_box[0]*pagesize[0],percent_box[1]*pagesize[1],
percent_box[2]*pagesize[0],percent_box[3]*pagesize[1]) percent_box[2]*pagesize[0],percent_box[3]*pagesize[1])
if not HAS_PYCAIRO_MODULE: if not HAS_PYCAIRO_MODULE:
raise Exception("PDF rendering only available when pycairo is available") raise Exception("PDF rendering only available when pycairo is available")
self.font_name = "DejaVu Sans" self.font_name = "DejaVu Sans"
def finish(self): def finish(self):
if self._s: if self._s:
self._s.finish() self._s.finish()
self._s = None self._s = None
if self._use_ocg_layers: if self._use_ocg_layers:
convert_pdf_pages_to_layers(self._filename,layer_names=self._layer_names + ["Legend and Information"],reverse_all_but_last=True) convert_pdf_pages_to_layers(self._filename,layer_names=self._layer_names + ["Legend and Information"],reverse_all_but_last=True)
def add_geospatial_pdf_header(self,m,filename,epsg=None,wkt=None): def add_geospatial_pdf_header(self,m,filename,epsg=None,wkt=None):
""" Postprocessing step to add geospatial PDF information to PDF file as per """ Postprocessing step to add geospatial PDF information to PDF file as per
PDF standard 1.7 extension level 3 (also in draft PDF v2 standard at time of writing) PDF standard 1.7 extension level 3 (also in draft PDF v2 standard at time of writing)
one of either the epsg code or wkt text for the projection must be provided one of either the epsg code or wkt text for the projection must be provided
Should be called *after* the page has had .finish() called""" Should be called *after* the page has had .finish() called"""
if HAS_PYPDF and (epsg or wkt): if HAS_PYPDF and (epsg or wkt):
infile=file(filename,'rb') infile=file(filename,'rb')
(outfd,outfilename) = tempfile.mkstemp(dir=os.path.dirname(filename)) (outfd,outfilename) = tempfile.mkstemp(dir=os.path.dirname(filename))
outfile = os.fdopen(outfd,'wb') outfile = os.fdopen(outfd,'wb')
i=pyPdf.PdfFileReader(infile) i=pyPdf.PdfFileReader(infile)
o=pyPdf.PdfFileWriter() o=pyPdf.PdfFileWriter()
# preserve OCProperties at document root if we have one # preserve OCProperties at document root if we have one
if i.trailer['/Root'].has_key(pyPdf.generic.NameObject('/OCProperties')): if i.trailer['/Root'].has_key(pyPdf.generic.NameObject('/OCProperties')):
o._root.getObject()[pyPdf.generic.NameObject('/OCProperties')] = i.trailer['/Root'].getObject()[pyPdf.generic.NameObject('/OCProperties')] o._root.getObject()[pyPdf.generic.NameObject('/OCProperties')] = i.trailer['/Root'].getObject()[pyPdf.generic.NameObject('/OCProperties')]
for p in i.pages: for p in i.pages:
gcs = pyPdf.generic.DictionaryObject() gcs = pyPdf.generic.DictionaryObject()
gcs[pyPdf.generic.NameObject('/Type')]=pyPdf.generic.NameObject('/PROJCS') gcs[pyPdf.generic.NameObject('/Type')]=pyPdf.generic.NameObject('/PROJCS')
@ -403,7 +403,7 @@ class PDFPrinter:
gcs[pyPdf.generic.NameObject('/EPSG')]=pyPdf.generic.NumberObject(int(epsg)) gcs[pyPdf.generic.NameObject('/EPSG')]=pyPdf.generic.NumberObject(int(epsg))
if wkt: if wkt:
gcs[pyPdf.generic.NameObject('/WKT')]=pyPdf.generic.TextStringObject(wkt) gcs[pyPdf.generic.NameObject('/WKT')]=pyPdf.generic.TextStringObject(wkt)
measure = pyPdf.generic.DictionaryObject() measure = pyPdf.generic.DictionaryObject()
measure[pyPdf.generic.NameObject('/Type')]=pyPdf.generic.NameObject('/Measure') measure[pyPdf.generic.NameObject('/Type')]=pyPdf.generic.NameObject('/Measure')
measure[pyPdf.generic.NameObject('/Subtype')]=pyPdf.generic.NameObject('/GEO') measure[pyPdf.generic.NameObject('/Subtype')]=pyPdf.generic.NameObject('/GEO')
@ -414,7 +414,7 @@ class PDFPrinter:
measure[pyPdf.generic.NameObject('/Bounds')]=bounds measure[pyPdf.generic.NameObject('/Bounds')]=bounds
measure[pyPdf.generic.NameObject('/LPTS')]=bounds measure[pyPdf.generic.NameObject('/LPTS')]=bounds
gpts=pyPdf.generic.ArrayObject() gpts=pyPdf.generic.ArrayObject()
proj=Projection(m.srs) proj=Projection(m.srs)
env=m.envelope() env=m.envelope()
for x in ((env.minx, env.miny), (env.minx, env.maxy), (env.maxx, env.maxy), (env.maxx, env.miny)): for x in ((env.minx, env.miny), (env.minx, env.maxy), (env.maxx, env.maxy), (env.maxx, env.miny)):
@ -423,31 +423,31 @@ class PDFPrinter:
gpts.append(pyPdf.generic.FloatObject(str(latlon_corner.y))) gpts.append(pyPdf.generic.FloatObject(str(latlon_corner.y)))
gpts.append(pyPdf.generic.FloatObject(str(latlon_corner.x))) gpts.append(pyPdf.generic.FloatObject(str(latlon_corner.x)))
measure[pyPdf.generic.NameObject('/GPTS')]=gpts measure[pyPdf.generic.NameObject('/GPTS')]=gpts
vp=pyPdf.generic.DictionaryObject() vp=pyPdf.generic.DictionaryObject()
vp[pyPdf.generic.NameObject('/Type')]=pyPdf.generic.NameObject('/Viewport') vp[pyPdf.generic.NameObject('/Type')]=pyPdf.generic.NameObject('/Viewport')
bbox=pyPdf.generic.ArrayObject() bbox=pyPdf.generic.ArrayObject()
for x in self.map_box: for x in self.map_box:
bbox.append(pyPdf.generic.FloatObject(str(x))) bbox.append(pyPdf.generic.FloatObject(str(x)))
vp[pyPdf.generic.NameObject('/BBox')]=bbox vp[pyPdf.generic.NameObject('/BBox')]=bbox
vp[pyPdf.generic.NameObject('/Measure')]=measure vp[pyPdf.generic.NameObject('/Measure')]=measure
vpa = pyPdf.generic.ArrayObject() vpa = pyPdf.generic.ArrayObject()
vpa.append(vp) vpa.append(vp)
p[pyPdf.generic.NameObject('/VP')]=vpa p[pyPdf.generic.NameObject('/VP')]=vpa
o.addPage(p) o.addPage(p)
o.write(outfile) o.write(outfile)
infile=None infile=None
outfile.close() outfile.close()
os.rename(outfilename,filename) os.rename(outfilename,filename)
def get_context(self): def get_context(self):
"""allow access so that extra 'bits' can be rendered to the page directly""" """allow access so that extra 'bits' can be rendered to the page directly"""
return cairo.Context(self._s) return cairo.Context(self._s)
def get_width(self): def get_width(self):
return self._pagesize[0] return self._pagesize[0]
@ -456,7 +456,7 @@ class PDFPrinter:
def get_margin(self): def get_margin(self):
return self._margin return self._margin
def write_text(self,ctx,text,box_width=None,size=10, fill_color=(0.0, 0.0, 0.0), alignment=None): def write_text(self,ctx,text,box_width=None,size=10, fill_color=(0.0, 0.0, 0.0), alignment=None):
if HAS_PANGOCAIRO_MODULE: if HAS_PANGOCAIRO_MODULE:
(attr,t,accel) = pango.parse_markup(text) (attr,t,accel) = pango.parse_markup(text)
@ -474,7 +474,7 @@ class PDFPrinter:
pctx.set_source_rgb(*fill_color) pctx.set_source_rgb(*fill_color)
pctx.show_layout(l) pctx.show_layout(l)
return l.get_pixel_extents()[0] return l.get_pixel_extents()[0]
else: else:
ctx.rel_move_to(0,size) ctx.rel_move_to(0,size)
ctx.select_font_face(self.font_name, cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) ctx.select_font_face(self.font_name, cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
@ -489,18 +489,18 @@ class PDFPrinter:
elif HAS_PYCAIRO_MODULE: elif HAS_PYCAIRO_MODULE:
return cairo.Context(self._s) return cairo.Context(self._s)
return None return None
def _get_render_area(self): def _get_render_area(self):
"""return a bounding box with the area of the page we are allowed to render out map to """return a bounding box with the area of the page we are allowed to render out map to
in page coordinates (i.e. meters) in page coordinates (i.e. meters)
""" """
# take off our page margins # take off our page margins
render_area = Box2d(self._margin,self._margin,self._pagesize[0]-self._margin,self._pagesize[1]-self._margin) render_area = Box2d(self._margin,self._margin,self._pagesize[0]-self._margin,self._pagesize[1]-self._margin)
#then if user specified a box to render get intersection with that #then if user specified a box to render get intersection with that
if self._box: if self._box:
return render_area.intersect(self._box) return render_area.intersect(self._box)
return render_area return render_area
def _get_render_area_size(self): def _get_render_area_size(self):
@ -513,7 +513,7 @@ class PDFPrinter:
available_area = self._get_render_area_size() available_area = self._get_render_area_size()
map_aspect = m.envelope().width()/m.envelope().height() map_aspect = m.envelope().width()/m.envelope().height()
page_aspect = available_area[0]/available_area[1] page_aspect = available_area[0]/available_area[1]
return map_aspect > page_aspect return map_aspect > page_aspect
def _get_meta_info_corner(self,render_size,m): def _get_meta_info_corner(self,render_size,m):
@ -526,7 +526,7 @@ class PDFPrinter:
else: else:
x += render_size[0]+0.005 x += render_size[0]+0.005
y = self._margin y = self._margin
return (x,y) return (x,y)
def _get_render_corner(self,render_size,m): def _get_render_corner(self,render_size,m):
@ -535,9 +535,9 @@ class PDFPrinter:
x=available_area[0] x=available_area[0]
y=available_area[1] y=available_area[1]
h_is_contrained = self._is_h_contrained(m) h_is_contrained = self._is_h_contrained(m)
if (self._centering == centering.both or if (self._centering == centering.both or
self._centering == centering.horizontal or self._centering == centering.horizontal or
(self._centering == centering.constrained and h_is_contrained) or (self._centering == centering.constrained and h_is_contrained) or
@ -550,26 +550,26 @@ class PDFPrinter:
(self._centering == centering.unconstrained and h_is_contrained)): (self._centering == centering.unconstrained and h_is_contrained)):
y+=(available_area.height()-render_size[1])/2 y+=(available_area.height()-render_size[1])/2
return (x,y) return (x,y)
def _get_map_pixel_size(self, width_page_m, height_page_m): def _get_map_pixel_size(self, width_page_m, height_page_m):
"""for a given map size in paper coordinates return a tuple of the map 'pixel' size we """for a given map size in paper coordinates return a tuple of the map 'pixel' size we
should create at the defined resolution""" should create at the defined resolution"""
return (int(m2px(width_page_m,self._resolution)), int(m2px(height_page_m,self._resolution))) return (int(m2px(width_page_m,self._resolution)), int(m2px(height_page_m,self._resolution)))
def render_map(self,m, filename): def render_map(self,m, filename):
"""Render the given map to filename""" """Render the given map to filename"""
# store this for later so we can post process the PDF # store this for later so we can post process the PDF
self._filename = filename self._filename = filename
# work out the best scale to render out map at given the available space # work out the best scale to render out map at given the available space
(eff_width,eff_height) = self._get_render_area_size() (eff_width,eff_height) = self._get_render_area_size()
map_aspect = m.envelope().width()/m.envelope().height() map_aspect = m.envelope().width()/m.envelope().height()
page_aspect = eff_width/eff_height page_aspect = eff_width/eff_height
scalex=m.envelope().width()/eff_width scalex=m.envelope().width()/eff_width
scaley=m.envelope().height()/eff_height scaley=m.envelope().height()/eff_height
scale=max(scalex,scaley) scale=max(scalex,scaley)
rounded_mapscale=self._scale(scale) rounded_mapscale=self._scale(scale)
@ -581,26 +581,26 @@ class PDFPrinter:
maph=mapw*(1/map_aspect) maph=mapw*(1/map_aspect)
else: else:
mapw=maph*map_aspect mapw=maph*map_aspect
# set the map size so that raster elements render at the correct resolution # set the map size so that raster elements render at the correct resolution
m.resize(*self._get_map_pixel_size(mapw,maph)) m.resize(*self._get_map_pixel_size(mapw,maph))
# calculate the translation for the map starting point # calculate the translation for the map starting point
(tx,ty) = self._get_render_corner((mapw,maph),m) (tx,ty) = self._get_render_corner((mapw,maph),m)
# create our cairo surface and context and then render the map into it # create our cairo surface and context and then render the map into it
self._s = cairo.PDFSurface(filename, m2pt(self._pagesize[0]),m2pt(self._pagesize[1])) self._s = cairo.PDFSurface(filename, m2pt(self._pagesize[0]),m2pt(self._pagesize[1]))
ctx=cairo.Context(self._s) ctx=cairo.Context(self._s)
for l in m.layers: for l in m.layers:
# extract the layer names for naming layers if we use OCG # extract the layer names for naming layers if we use OCG
self._layer_names.append(l.name) self._layer_names.append(l.name)
layer_map = Map(m.width,m.height,m.srs) layer_map = Map(m.width,m.height,m.srs)
layer_map.layers.append(l) layer_map.layers.append(l)
for s in l.styles: for s in l.styles:
layer_map.append_style(s,m.find_style(s)) layer_map.append_style(s,m.find_style(s))
layer_map.zoom_to_box(m.envelope()) layer_map.zoom_to_box(m.envelope())
def render_map(): def render_map():
ctx.save() ctx.save()
ctx.translate(m2pt(tx),m2pt(ty)) ctx.translate(m2pt(tx),m2pt(ty))
@ -608,7 +608,7 @@ class PDFPrinter:
ctx.scale(72.0/self._resolution,72.0/self._resolution) ctx.scale(72.0/self._resolution,72.0/self._resolution)
render(layer_map, ctx) render(layer_map, ctx)
ctx.restore() ctx.restore()
# antimeridian # antimeridian
render_map() render_map()
if self._is_latlon and (m.envelope().minx < -180 or m.envelope().maxx > 180): if self._is_latlon and (m.envelope().minx < -180 or m.envelope().maxx > 180):
@ -621,10 +621,10 @@ class PDFPrinter:
render_map() render_map()
# restore the original env # restore the original env
m.zoom_to_box(old_env) m.zoom_to_box(old_env)
if self._use_ocg_layers: if self._use_ocg_layers:
self._s.show_page() self._s.show_page()
self.scale = rounded_mapscale self.scale = rounded_mapscale
self.map_box = Box2d(tx,ty,tx+mapw,ty+maph) self.map_box = Box2d(tx,ty,tx+mapw,ty+maph)
@ -640,7 +640,7 @@ class PDFPrinter:
if p2.inverse(m.envelope().center()).y > latlon_bounds.maxy: if p2.inverse(m.envelope().center()).y > latlon_bounds.maxy:
latlon_bounds = Box2d(latlon_bounds.miny,latlon_bounds.maxy,latlon_bounds.maxx,latlon_bounds.miny+360) latlon_bounds = Box2d(latlon_bounds.miny,latlon_bounds.maxy,latlon_bounds.maxx,latlon_bounds.miny+360)
latlon_mapwidth = latlon_bounds.width() latlon_mapwidth = latlon_bounds.width()
# render an extra 20% so we generally won't miss the ends of lines # render an extra 20% so we generally won't miss the ends of lines
latlon_buffer = 0.2*latlon_mapwidth latlon_buffer = 0.2*latlon_mapwidth
@ -649,7 +649,7 @@ class PDFPrinter:
else: else:
latlon_divsize = deg_min_sec_scale(latlon_mapwidth/7.0) latlon_divsize = deg_min_sec_scale(latlon_mapwidth/7.0)
latlon_interpsize = latlon_mapwidth/m.width latlon_interpsize = latlon_mapwidth/m.width
self._render_lat_lon_axis(m,p2,latlon_bounds.minx,latlon_bounds.maxx,latlon_bounds.miny,latlon_bounds.maxy,latlon_buffer,latlon_interpsize,latlon_divsize,dec_degrees,True) self._render_lat_lon_axis(m,p2,latlon_bounds.minx,latlon_bounds.maxx,latlon_bounds.miny,latlon_bounds.maxy,latlon_buffer,latlon_interpsize,latlon_divsize,dec_degrees,True)
self._render_lat_lon_axis(m,p2,latlon_bounds.miny,latlon_bounds.maxy,latlon_bounds.minx,latlon_bounds.maxx,latlon_buffer,latlon_interpsize,latlon_divsize,dec_degrees,False) self._render_lat_lon_axis(m,p2,latlon_bounds.miny,latlon_bounds.maxy,latlon_bounds.minx,latlon_bounds.maxx,latlon_buffer,latlon_interpsize,latlon_divsize,dec_degrees,False)
@ -658,21 +658,21 @@ class PDFPrinter:
ctx.set_source_rgb(1,0,0) ctx.set_source_rgb(1,0,0)
ctx.set_line_width(1) ctx.set_line_width(1)
latlon_labelsize = 6 latlon_labelsize = 6
ctx.translate(m2pt(self.map_box.minx),m2pt(self.map_box.miny)) ctx.translate(m2pt(self.map_box.minx),m2pt(self.map_box.miny))
ctx.rectangle(0,0,m2pt(self.map_box.width()),m2pt(self.map_box.height())) ctx.rectangle(0,0,m2pt(self.map_box.width()),m2pt(self.map_box.height()))
ctx.clip() ctx.clip()
ctx.select_font_face("DejaVu", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) ctx.select_font_face("DejaVu", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
ctx.set_font_size(latlon_labelsize) ctx.set_font_size(latlon_labelsize)
box_top = self.map_box.height() box_top = self.map_box.height()
if not is_x_axis: if not is_x_axis:
ctx.translate(m2pt(self.map_box.width()/2),m2pt(self.map_box.height()/2)) ctx.translate(m2pt(self.map_box.width()/2),m2pt(self.map_box.height()/2))
ctx.rotate(-math.pi/2) ctx.rotate(-math.pi/2)
ctx.translate(-m2pt(self.map_box.height()/2),-m2pt(self.map_box.width()/2)) ctx.translate(-m2pt(self.map_box.height()/2),-m2pt(self.map_box.width()/2))
box_top = self.map_box.width() box_top = self.map_box.width()
for xvalue in round_grid_generator(x1 - latlon_buffer,x2 + latlon_buffer,latlon_divsize): for xvalue in round_grid_generator(x1 - latlon_buffer,x2 + latlon_buffer,latlon_divsize):
yvalue = y1 - latlon_buffer yvalue = y1 - latlon_buffer
start_cross = None start_cross = None
@ -693,12 +693,12 @@ class PDFPrinter:
ctx.move_to(start.x,start.y) ctx.move_to(start.x,start.y)
ctx.line_to(end.x,end.y) ctx.line_to(end.x,end.y)
ctx.stroke() ctx.stroke()
if cmp(start.y, 0) != cmp(end.y,0): if cmp(start.y, 0) != cmp(end.y,0):
start_cross = end.x start_cross = end.x
if cmp(start.y,m2pt(self.map_box.height())) != cmp(end.y, m2pt(self.map_box.height())): if cmp(start.y,m2pt(self.map_box.height())) != cmp(end.y, m2pt(self.map_box.height())):
end_cross = end.x end_cross = end.x
if dec_degrees: if dec_degrees:
line_text = "%g" % (xvalue) line_text = "%g" % (xvalue)
else: else:
@ -712,19 +712,19 @@ class PDFPrinter:
def render_on_map_scale(self,m): def render_on_map_scale(self,m):
(div_size,page_div_size) = self._get_sensible_scalebar_size(m) (div_size,page_div_size) = self._get_sensible_scalebar_size(m)
first_value_x = (math.floor(m.envelope().minx / div_size) + 1) * div_size first_value_x = (math.floor(m.envelope().minx / div_size) + 1) * div_size
first_value_x_percent = (first_value_x-m.envelope().minx)/m.envelope().width() first_value_x_percent = (first_value_x-m.envelope().minx)/m.envelope().width()
self._render_scale_axis(first_value_x,first_value_x_percent,self.map_box.minx,self.map_box.maxx,page_div_size,div_size,self.map_box.miny,self.map_box.maxy,True) self._render_scale_axis(first_value_x,first_value_x_percent,self.map_box.minx,self.map_box.maxx,page_div_size,div_size,self.map_box.miny,self.map_box.maxy,True)
first_value_y = (math.floor(m.envelope().miny / div_size) + 1) * div_size first_value_y = (math.floor(m.envelope().miny / div_size) + 1) * div_size
first_value_y_percent = (first_value_y-m.envelope().miny)/m.envelope().height() first_value_y_percent = (first_value_y-m.envelope().miny)/m.envelope().height()
self._render_scale_axis(first_value_y,first_value_y_percent,self.map_box.miny,self.map_box.maxy,page_div_size,div_size,self.map_box.minx,self.map_box.maxx,False) self._render_scale_axis(first_value_y,first_value_y_percent,self.map_box.miny,self.map_box.maxy,page_div_size,div_size,self.map_box.minx,self.map_box.maxx,False)
if self._use_ocg_layers: if self._use_ocg_layers:
self._s.show_page() self._s.show_page()
self._layer_names.append("Coordinate Grid Overlay") self._layer_names.append("Coordinate Grid Overlay")
def _get_sensible_scalebar_size(self,m,width=-1): def _get_sensible_scalebar_size(self,m,width=-1):
# aim for about 8 divisions across the map # aim for about 8 divisions across the map
# also make sure we can fit the bar with in page area width if specified # also make sure we can fit the bar with in page area width if specified
@ -744,7 +744,7 @@ class PDFPrinter:
ctx.set_source_rgb(*stroke_color) ctx.set_source_rgb(*stroke_color)
ctx.rectangle(x,y,w,h) ctx.rectangle(x,y,w,h)
ctx.stroke() ctx.stroke()
if text: if text:
ctx.move_to(x+1,y) ctx.move_to(x+1,y)
self.write_text(ctx,text,fill_color=[1-z for z in fill_color],size=h-2) self.write_text(ctx,text,fill_color=[1-z for z in fill_color],size=h-2)
@ -758,14 +758,14 @@ class PDFPrinter:
label_value = first-div_size label_value = first-div_size
if self._is_latlon and label_value < -180: if self._is_latlon and label_value < -180:
label_value += 360 label_value += 360
ctx=cairo.Context(self._s) ctx=cairo.Context(self._s)
if not is_x_axis: if not is_x_axis:
ctx.translate(m2pt(self.map_box.center().x),m2pt(self.map_box.center().y)) ctx.translate(m2pt(self.map_box.center().x),m2pt(self.map_box.center().y))
ctx.rotate(-math.pi/2) ctx.rotate(-math.pi/2)
ctx.translate(-m2pt(self.map_box.center().y),-m2pt(self.map_box.center().x)) ctx.translate(-m2pt(self.map_box.center().y),-m2pt(self.map_box.center().x))
while value < end: while value < end:
ctx.move_to(m2pt(value),m2pt(boundary_start)) ctx.move_to(m2pt(value),m2pt(boundary_start))
ctx.line_to(m2pt(value),m2pt(boundary_end)) ctx.line_to(m2pt(value),m2pt(boundary_end))
@ -775,7 +775,7 @@ class PDFPrinter:
for bar in (m2pt(boundary_start)-border_size,m2pt(boundary_end)): for bar in (m2pt(boundary_start)-border_size,m2pt(boundary_end)):
self._render_box(ctx,m2pt(prev),bar,m2pt(value-prev),border_size,text,fill_color=fill) self._render_box(ctx,m2pt(prev),bar,m2pt(value-prev),border_size,text,fill_color=fill)
prev = value prev = value
value+=page_div_size value+=page_div_size
fill = [1-z for z in fill] fill = [1-z for z in fill]
@ -787,18 +787,18 @@ class PDFPrinter:
for bar in (m2pt(boundary_start)-border_size,m2pt(boundary_end)): for bar in (m2pt(boundary_start)-border_size,m2pt(boundary_end)):
self._render_box(ctx,m2pt(prev),bar,m2pt(end-prev),border_size,fill_color=fill) self._render_box(ctx,m2pt(prev),bar,m2pt(end-prev),border_size,fill_color=fill)
def render_scale(self,m,ctx=None,width=0.05): def render_scale(self,m,ctx=None,width=0.05):
""" m: map to render scale for """ m: map to render scale for
ctx: A cairo context to render the scale to. If this is None (the default) then ctx: A cairo context to render the scale to. If this is None (the default) then
automatically create a context and choose the best location for the scale bar. automatically create a context and choose the best location for the scale bar.
width: Width of area available to render scale bar in (in m) width: Width of area available to render scale bar in (in m)
will return the size of the rendered scale block in pts will return the size of the rendered scale block in pts
""" """
(w,h) = (0,0) (w,h) = (0,0)
# don't render scale if we are lat lon # don't render scale if we are lat lon
# dont report scale if we have warped the aspect ratio # dont report scale if we have warped the aspect ratio
if self._preserve_aspect and not self._is_latlon: if self._preserve_aspect and not self._is_latlon:
@ -808,15 +808,15 @@ class PDFPrinter:
ctx=cairo.Context(self._s) ctx=cairo.Context(self._s)
(tx,ty) = self._get_meta_info_corner((self.map_box.width(),self.map_box.height()),m) (tx,ty) = self._get_meta_info_corner((self.map_box.width(),self.map_box.height()),m)
ctx.translate(tx,ty) ctx.translate(tx,ty)
(div_size,page_div_size) = self._get_sensible_scalebar_size(m, width/box_count) (div_size,page_div_size) = self._get_sensible_scalebar_size(m, width/box_count)
div_unit = "m" div_unit = "m"
if div_size > 1000: if div_size > 1000:
div_size /= 1000 div_size /= 1000
div_unit = "km" div_unit = "km"
text = "0%s" % div_unit text = "0%s" % div_unit
ctx.save() ctx.save()
if width > 0: if width > 0:
@ -846,7 +846,7 @@ class PDFPrinter:
text_ext=self.write_text(ctx,"Scale 1:%d" % self.scale,box_width=box_width,size=font_size, alignment=alignment) text_ext=self.write_text(ctx,"Scale 1:%d" % self.scale,box_width=box_width,size=font_size, alignment=alignment)
h+=text_ext[3]+2 h+=text_ext[3]+2
return (w,h) return (w,h)
def render_legend(self,m, page_break=False, ctx=None, collumns=1,width=None, height=None, item_per_rule=False, attribution={}, legend_item_box_size=(0.015,0.0075)): def render_legend(self,m, page_break=False, ctx=None, collumns=1,width=None, height=None, item_per_rule=False, attribution={}, legend_item_box_size=(0.015,0.0075)):
@ -858,7 +858,7 @@ class PDFPrinter:
collumns: number of collumns available in legend box collumns: number of collumns available in legend box
attribution: additional text that will be rendered in gray under the layer name. keyed by layer name attribution: additional text that will be rendered in gray under the layer name. keyed by layer name
legend_item_box_size: two tuple with width and height of legend item box size in meters legend_item_box_size: two tuple with width and height of legend item box size in meters
will return the size of the rendered block in pts will return the size of the rendered block in pts
""" """
@ -879,7 +879,7 @@ class PDFPrinter:
else: else:
cwidth = None cwidth = None
current_collumn = 0 current_collumn = 0
processed_layers = [] processed_layers = []
for l in reversed(m.layers): for l in reversed(m.layers):
have_layer_header = False have_layer_header = False
@ -888,7 +888,7 @@ class PDFPrinter:
if layer_title in processed_layers: if layer_title in processed_layers:
continue continue
processed_layers.append(layer_title) processed_layers.append(layer_title)
# check through the features to find which combinations of styles are active # check through the features to find which combinations of styles are active
# for each unique combination add a legend entry # for each unique combination add a legend entry
for f in l.datasource.all_features(): for f in l.datasource.all_features():
@ -913,20 +913,20 @@ class PDFPrinter:
active_rules = tuple(active_rules) active_rules = tuple(active_rules)
if added_styles.has_key(active_rules): if added_styles.has_key(active_rules):
continue continue
added_styles[active_rules] = (f,rule_text) added_styles[active_rules] = (f,rule_text)
if not item_per_rule: if not item_per_rule:
break break
else: else:
added_styles[l] = (None,None) added_styles[l] = (None,None)
legend_items = added_styles.keys() legend_items = added_styles.keys()
legend_items.sort() legend_items.sort()
for li in legend_items: for li in legend_items:
if True: if True:
(f,rule_text) = added_styles[li] (f,rule_text) = added_styles[li]
legend_map_size = (int(m2pt(legend_item_box_size[0])),int(m2pt(legend_item_box_size[1]))) legend_map_size = (int(m2pt(legend_item_box_size[0])),int(m2pt(legend_item_box_size[1])))
lemap=Map(legend_map_size[0],legend_map_size[1],srs=m.srs) lemap=Map(legend_map_size[0],legend_map_size[1],srs=m.srs)
if m.background: if m.background:
@ -967,11 +967,11 @@ class PDFPrinter:
for s in l.styles: for s in l.styles:
lelayer.styles.append(s) lelayer.styles.append(s)
lemap.layers.append(lelayer) lemap.layers.append(lelayer)
if f is None or f.envelope().width() != 0: if f is None or f.envelope().width() != 0:
lemap.zoom_all() lemap.zoom_all()
lemap.zoom(1.1) lemap.zoom(1.1)
item_size = legend_map_size[1] item_size = legend_map_size[1]
if not have_layer_header: if not have_layer_header:
item_size += 8 item_size += 8
@ -998,7 +998,7 @@ class PDFPrinter:
ctx.save() ctx.save()
render(lemap, ctx) render(lemap, ctx)
ctx.restore() ctx.restore()
ctx.rectangle(0,0,*legend_map_size) ctx.rectangle(0,0,*legend_map_size)
ctx.set_source_rgb(0.5,0.5,0.5) ctx.set_source_rgb(0.5,0.5,0.5)
ctx.set_line_width(1) ctx.set_line_width(1)
@ -1017,12 +1017,12 @@ class PDFPrinter:
if attribution.has_key(layer_title): if attribution.has_key(layer_title):
e=self.write_text(ctx, attribution[layer_title], m2pt(cwidth-legend_item_box_size[0]-0.005), 6, fill_color=(0.5,0.5,0.5)) e=self.write_text(ctx, attribution[layer_title], m2pt(cwidth-legend_item_box_size[0]-0.005), 6, fill_color=(0.5,0.5,0.5))
legend_text_size += e[3] legend_text_size += e[3]
if legend_text_size > legend_entry_size: if legend_text_size > legend_entry_size:
legend_entry_size=legend_text_size legend_entry_size=legend_text_size
y+=legend_entry_size +2 y+=legend_entry_size +2
if y > h: if y > h:
h = y h = y
return (w,h) return (w,h)