22
33"""Mapnik classes to assist in creating printable maps."""
44
5- from __future__ import absolute_import , print_function
6-
75import logging
86import math
9-
10- from mapnik import Box2d , Coord , Geometry , Layer , Map , Projection , Style , render
7+ from mapnik import Box2d , Coord , Geometry , Layer , Map , Projection , ProjTransform , Style , render
118from mapnik .printing .conversions import m2pt , m2px
129from mapnik .printing .formats import pagesizes
1310from mapnik .printing .scales import any_scale , default_scale , deg_min_sec_scale , sequence_scale
2522 HAS_PANGOCAIRO_MODULE = False
2623
2724try :
28- from PyPDF2 import PdfFileReader , PdfFileWriter
29- from PyPDF2 .generic import (ArrayObject , DecodedStreamObject , DictionaryObject , FloatObject , NameObject ,
30- NumberObject , TextStringObject )
31- HAS_PYPDF2 = True
25+ from pypdf import PdfReader , PdfWriter
26+ from pypdf .generic import (ArrayObject , DecodedStreamObject , DictionaryObject , FloatObject , NameObject ,
27+ NumberObject , TextStringObject )
28+ HAS_PYPDF = True
3229except ImportError :
33- HAS_PYPDF2 = False
30+ HAS_PYPDF = False
3431
3532"""
3633Style of centering to use with the map.
@@ -90,7 +87,7 @@ def __init__(self,
9087 Args:
9188 pagesize: tuple of page size in meters, see predefined sizes in mapnik.formats module
9289 margin: page margin in meters
93- box: the box to render the map into. Must be within page area, margin excluded.
90+ box: the box to render the map into. Must be within page area, margin excluded.
9491 This should be a Mapnik Box2d object. Default is the full page without margin.
9592 percent_box: similar to box argument but specified as a percent (0->1) of the full page size.
9693 If both box and percent_box are specified percent_box will be used.
@@ -104,7 +101,7 @@ def __init__(self,
104101 be a value from the mapnik.utils.centering class. The default is to center on the maps constrained
105102 axis. Typically this will be horizontal for portrait pages and vertical for landscape pages.
106103 is_latlon: whether the map is in lat lon degrees or not.
107- use_ocg_layers: create OCG layers in the PDF, requires PyPDF2
104+ use_ocg_layers: create OCG layers in the PDF, requires pypdf
108105 font_name: the font name used each time text is written (e.g., legend titles, representative fraction, etc.)
109106 """
110107 self ._pagesize = pagesize
@@ -563,7 +560,7 @@ def render_scale(self, m, ctx=None, width=0.05, num_divisions=3, bar_size=8.0, w
563560
564561 Args:
565562 m: the Map object to render the scale for
566- ctx: A cairo context to render the scale into. If this is None, we create a context and find out
563+ ctx: A cairo context to render the scale into. If this is None, we create a context and find out
567564 the best location for the scale bar
568565 width: the width of area available for rendering the scale bar (in meters)
569566 num_divisions: the number of divisions for the scale bar
@@ -737,7 +734,7 @@ def render_graticule_on_map(self, m, dec_degrees=True, grid_layer_name="Graticul
737734
738735 # renders the vertical graticule axes
739736 self ._render_graticule_axes_and_text (
740- m ,
737+ m ,
741738 p2 ,
742739 latlon_bounds ,
743740 latlon_buffer ,
@@ -1119,7 +1116,7 @@ def convert_pdf_pages_to_layers(self, filename, layer_names=None, reverse_all_bu
11191116 Takes a multi pages PDF as input and converts each page to a layer in a single page PDF.
11201117
11211118 Note:
1122- requires PyPDF2 to be available
1119+ requires pypdf to be available
11231120
11241121 Args:
11251122 layer_names should be a sequence of the user visible names of the layers, if not given
@@ -1128,17 +1125,17 @@ def convert_pdf_pages_to_layers(self, filename, layer_names=None, reverse_all_bu
11281125 if output_name is not provided a temporary file will be used for the conversion which
11291126 will then be copied back over the source file.
11301127 """
1131- if not HAS_PYPDF2 :
1132- raise RuntimeError ("PyPDF2 not available; PyPDF2 required to convert pdf pages to layers" )
1128+ if not HAS_PYPDF :
1129+ raise RuntimeError ("pypdf not available; pypdf required to convert pdf pages to layers" )
11331130
11341131 with open (filename , "rb+" ) as f :
1135- file_reader = PdfFileReader (f )
1136- file_writer = PdfFileWriter ()
1132+ file_reader = PdfReader (f )
1133+ file_writer = PdfWriter ()
11371134
1138- template_page_size = file_reader .pages [0 ].mediaBox
1139- output_pdf = file_writer .addBlankPage (
1140- width = template_page_size .getWidth () ,
1141- height = template_page_size .getHeight () )
1135+ template_page_size = file_reader .pages [0 ].mediabox
1136+ output_pdf = file_writer .add_blank_page (
1137+ width = template_page_size .width ,
1138+ height = template_page_size .height )
11421139
11431140 content_key = NameObject ('/Contents' )
11441141 output_pdf [content_key ] = ArrayObject ()
@@ -1149,15 +1146,15 @@ def convert_pdf_pages_to_layers(self, filename, layer_names=None, reverse_all_bu
11491146 (properties , ocgs ) = self ._make_ocg_layers (file_reader , file_writer , output_pdf , layer_names )
11501147
11511148 properties_key = NameObject ('/Properties' )
1152- output_pdf [resource_key ][properties_key ] = file_writer ._addObject (properties )
1149+ output_pdf [resource_key ][properties_key ] = file_writer ._add_object (properties )
11531150
11541151 ocproperties = DictionaryObject ()
11551152 ocproperties [NameObject ('/OCGs' )] = ocgs
11561153
11571154 default_view = self ._get_pdf_default_view (ocgs , reverse_all_but_last )
1158- ocproperties [NameObject ('/D' )] = file_writer ._addObject (default_view )
1155+ ocproperties [NameObject ('/D' )] = file_writer ._add_object (default_view )
11591156
1160- file_writer ._root_object [NameObject ('/OCProperties' )] = file_writer ._addObject (ocproperties )
1157+ file_writer ._root_object [NameObject ('/OCProperties' )] = file_writer ._add_object (ocproperties )
11611158
11621159 f .seek (0 )
11631160 file_writer .write (f )
@@ -1189,7 +1186,7 @@ def _make_ocg_layers(self, file_reader, file_writer, output_pdf, layer_names=Non
11891186 page [NameObject (
11901187 '/Contents' )] = ArrayObject ((ocgs_start , page ['/Contents' ], ocg_end ))
11911188
1192- output_pdf .mergePage (page )
1189+ output_pdf .merge_page (page )
11931190
11941191 ocg = DictionaryObject ()
11951192 ocg [NameObject ('/Type' )] = NameObject ('/OCG' )
@@ -1199,7 +1196,7 @@ def _make_ocg_layers(self, file_reader, file_writer, output_pdf, layer_names=Non
11991196 else :
12001197 ocg [NameObject ('/Name' )] = TextStringObject ('Layer %d' % (idx + 1 ))
12011198
1202- indirect_ocg = file_writer ._addObject (ocg )
1199+ indirect_ocg = file_writer ._add_object (ocg )
12031200 properties [ocg_name ] = indirect_ocg
12041201 ocgs .append (indirect_ocg )
12051202
@@ -1238,20 +1235,20 @@ def add_geospatial_pdf_header(self, m, filename, epsg=None, wkt=None):
12381235 The epsg code or the wkt text of the projection must be provided.
12391236 Must be called *after* the page has had .finish() called.
12401237 """
1241- if not HAS_PYPDF2 :
1242- raise RuntimeError ("PyPDF2 not available; PyPDF2 required to add geospatial header to PDF" )
1238+ if not HAS_PYPDF :
1239+ raise RuntimeError ("pypdf not available; pypdf required to add geospatial header to PDF" )
12431240
12441241 if not any ((epsg ,wkt )):
12451242 raise RuntimeError ("EPSG or WKT required to add geospatial header to PDF" )
12461243
12471244 with open (filename , "rb+" ) as f :
1248- file_reader = PdfFileReader (f )
1249- file_writer = PdfFileWriter ()
1245+ file_reader = PdfReader (f )
1246+ file_writer = PdfWriter ()
12501247
12511248 # preserve OCProperties at document root if we have one
1252- if file_reader .trailer ['/Root' ]. has_key ( NameObject ( '/OCProperties' )) :
1249+ if NameObject ( '/OCProperties' ) in file_reader .trailer ['/Root' ]:
12531250 file_writer ._root_object [NameObject ('/OCProperties' )] = file_reader .trailer [
1254- '/Root' ].getObject ()[NameObject ('/OCProperties' )]
1251+ '/Root' ].get_object ()[NameObject ('/OCProperties' )]
12551252
12561253 for page in file_reader .pages :
12571254 gcs = DictionaryObject ()
@@ -1265,7 +1262,7 @@ def add_geospatial_pdf_header(self, m, filename, epsg=None, wkt=None):
12651262 measure = self ._get_pdf_measure (m , gcs )
12661263 page [NameObject ('/VP' )] = self ._get_pdf_vp (measure )
12671264
1268- file_writer .addPage (page )
1265+ file_writer .add_page (page )
12691266
12701267 f .seek (0 )
12711268 file_writer .write (f )
@@ -1318,11 +1315,11 @@ def _get_pdf_gpts(self, m):
13181315 """
13191316 gpts = ArrayObject ()
13201317
1321- proj = Projection (m .srs )
1318+ tr = ProjTransform ( Projection (m .srs ), Projection ( "epsg:4326" ) )
13221319 env = m .envelope ()
1323- for x in ((env .minx , env .miny ), (env .minx , env .maxy ),
1320+ for p in ((env .minx , env .miny ), (env .minx , env .maxy ),
13241321 (env .maxx , env .maxy ), (env .maxx , env .miny )):
1325- latlon_corner = proj . inverse (Coord (* x ))
1322+ latlon_corner = tr . forward (Coord (* p ))
13261323 # these are in lat,lon order according to the specification
13271324 gpts .append (FloatObject (str (latlon_corner .y )))
13281325 gpts .append (FloatObject (str (latlon_corner .x )))
0 commit comments