2
2
3
3
"""Mapnik classes to assist in creating printable maps."""
4
4
5
- from __future__ import absolute_import , print_function
6
-
7
5
import logging
8
6
import 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
11
8
from mapnik .printing .conversions import m2pt , m2px
12
9
from mapnik .printing .formats import pagesizes
13
10
from mapnik .printing .scales import any_scale , default_scale , deg_min_sec_scale , sequence_scale
25
22
HAS_PANGOCAIRO_MODULE = False
26
23
27
24
try :
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
32
29
except ImportError :
33
- HAS_PYPDF2 = False
30
+ HAS_PYPDF = False
34
31
35
32
"""
36
33
Style of centering to use with the map.
@@ -90,7 +87,7 @@ def __init__(self,
90
87
Args:
91
88
pagesize: tuple of page size in meters, see predefined sizes in mapnik.formats module
92
89
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.
94
91
This should be a Mapnik Box2d object. Default is the full page without margin.
95
92
percent_box: similar to box argument but specified as a percent (0->1) of the full page size.
96
93
If both box and percent_box are specified percent_box will be used.
@@ -104,7 +101,7 @@ def __init__(self,
104
101
be a value from the mapnik.utils.centering class. The default is to center on the maps constrained
105
102
axis. Typically this will be horizontal for portrait pages and vertical for landscape pages.
106
103
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
108
105
font_name: the font name used each time text is written (e.g., legend titles, representative fraction, etc.)
109
106
"""
110
107
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
563
560
564
561
Args:
565
562
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
567
564
the best location for the scale bar
568
565
width: the width of area available for rendering the scale bar (in meters)
569
566
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
737
734
738
735
# renders the vertical graticule axes
739
736
self ._render_graticule_axes_and_text (
740
- m ,
737
+ m ,
741
738
p2 ,
742
739
latlon_bounds ,
743
740
latlon_buffer ,
@@ -1119,7 +1116,7 @@ def convert_pdf_pages_to_layers(self, filename, layer_names=None, reverse_all_bu
1119
1116
Takes a multi pages PDF as input and converts each page to a layer in a single page PDF.
1120
1117
1121
1118
Note:
1122
- requires PyPDF2 to be available
1119
+ requires pypdf to be available
1123
1120
1124
1121
Args:
1125
1122
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
1128
1125
if output_name is not provided a temporary file will be used for the conversion which
1129
1126
will then be copied back over the source file.
1130
1127
"""
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" )
1133
1130
1134
1131
with open (filename , "rb+" ) as f :
1135
- file_reader = PdfFileReader (f )
1136
- file_writer = PdfFileWriter ()
1132
+ file_reader = PdfReader (f )
1133
+ file_writer = PdfWriter ()
1137
1134
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 )
1142
1139
1143
1140
content_key = NameObject ('/Contents' )
1144
1141
output_pdf [content_key ] = ArrayObject ()
@@ -1149,15 +1146,15 @@ def convert_pdf_pages_to_layers(self, filename, layer_names=None, reverse_all_bu
1149
1146
(properties , ocgs ) = self ._make_ocg_layers (file_reader , file_writer , output_pdf , layer_names )
1150
1147
1151
1148
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 )
1153
1150
1154
1151
ocproperties = DictionaryObject ()
1155
1152
ocproperties [NameObject ('/OCGs' )] = ocgs
1156
1153
1157
1154
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 )
1159
1156
1160
- file_writer ._root_object [NameObject ('/OCProperties' )] = file_writer ._addObject (ocproperties )
1157
+ file_writer ._root_object [NameObject ('/OCProperties' )] = file_writer ._add_object (ocproperties )
1161
1158
1162
1159
f .seek (0 )
1163
1160
file_writer .write (f )
@@ -1189,7 +1186,7 @@ def _make_ocg_layers(self, file_reader, file_writer, output_pdf, layer_names=Non
1189
1186
page [NameObject (
1190
1187
'/Contents' )] = ArrayObject ((ocgs_start , page ['/Contents' ], ocg_end ))
1191
1188
1192
- output_pdf .mergePage (page )
1189
+ output_pdf .merge_page (page )
1193
1190
1194
1191
ocg = DictionaryObject ()
1195
1192
ocg [NameObject ('/Type' )] = NameObject ('/OCG' )
@@ -1199,7 +1196,7 @@ def _make_ocg_layers(self, file_reader, file_writer, output_pdf, layer_names=Non
1199
1196
else :
1200
1197
ocg [NameObject ('/Name' )] = TextStringObject ('Layer %d' % (idx + 1 ))
1201
1198
1202
- indirect_ocg = file_writer ._addObject (ocg )
1199
+ indirect_ocg = file_writer ._add_object (ocg )
1203
1200
properties [ocg_name ] = indirect_ocg
1204
1201
ocgs .append (indirect_ocg )
1205
1202
@@ -1238,20 +1235,20 @@ def add_geospatial_pdf_header(self, m, filename, epsg=None, wkt=None):
1238
1235
The epsg code or the wkt text of the projection must be provided.
1239
1236
Must be called *after* the page has had .finish() called.
1240
1237
"""
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" )
1243
1240
1244
1241
if not any ((epsg ,wkt )):
1245
1242
raise RuntimeError ("EPSG or WKT required to add geospatial header to PDF" )
1246
1243
1247
1244
with open (filename , "rb+" ) as f :
1248
- file_reader = PdfFileReader (f )
1249
- file_writer = PdfFileWriter ()
1245
+ file_reader = PdfReader (f )
1246
+ file_writer = PdfWriter ()
1250
1247
1251
1248
# 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' ]:
1253
1250
file_writer ._root_object [NameObject ('/OCProperties' )] = file_reader .trailer [
1254
- '/Root' ].getObject ()[NameObject ('/OCProperties' )]
1251
+ '/Root' ].get_object ()[NameObject ('/OCProperties' )]
1255
1252
1256
1253
for page in file_reader .pages :
1257
1254
gcs = DictionaryObject ()
@@ -1265,7 +1262,7 @@ def add_geospatial_pdf_header(self, m, filename, epsg=None, wkt=None):
1265
1262
measure = self ._get_pdf_measure (m , gcs )
1266
1263
page [NameObject ('/VP' )] = self ._get_pdf_vp (measure )
1267
1264
1268
- file_writer .addPage (page )
1265
+ file_writer .add_page (page )
1269
1266
1270
1267
f .seek (0 )
1271
1268
file_writer .write (f )
@@ -1318,11 +1315,11 @@ def _get_pdf_gpts(self, m):
1318
1315
"""
1319
1316
gpts = ArrayObject ()
1320
1317
1321
- proj = Projection (m .srs )
1318
+ tr = ProjTransform ( Projection (m .srs ), Projection ( "epsg:4326" ) )
1322
1319
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 ),
1324
1321
(env .maxx , env .maxy ), (env .maxx , env .miny )):
1325
- latlon_corner = proj . inverse (Coord (* x ))
1322
+ latlon_corner = tr . forward (Coord (* p ))
1326
1323
# these are in lat,lon order according to the specification
1327
1324
gpts .append (FloatObject (str (latlon_corner .y )))
1328
1325
gpts .append (FloatObject (str (latlon_corner .x )))
0 commit comments