annotate make-tile @ 12:698b3335a63d default tip

Fix leading comment.
author David Barts <n5jrn@me.com>
date Thu, 26 Aug 2021 23:06:33 -0700
parents 6e4a8ddacf61
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
1 #!/usr/bin/env python3
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
2 # -*- coding: utf-8 -*-
12
698b3335a63d Fix leading comment.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
3 # Make a tileable GeoTIFF from a USGS National Map GeoPDF.
0
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
4
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
5 # I m p o r t s
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
6
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
7 import os, sys
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
8 import argparse
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
9 import json
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
10 import subprocess, shutil
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
11 import locale
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
12 from abc import abstractmethod
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
13 from enum import IntEnum
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
14 from tempfile import TemporaryDirectory
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
15
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
16 # PIL is ...weird... and needs both of these.
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
17 import PIL
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
18 from PIL import Image
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
19
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
20 # V a r i a b l e s
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
21
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
22 MYNAME = os.path.basename(sys.argv[0])
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
23 estat = 0
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
24 ENCODING = "UTF-8"
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
25 ENVIRON = os.environ.copy()
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
26 for k in ENVIRON.keys():
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
27 if k.startswith("LC_"): del(ENVIRON[k])
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
28 ENVIRON["LANG"] = ENVIRON["LC_ALL"] = "C." + ENCODING
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
29
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
30 # C l a s s e s
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
31
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
32 # A horizontal or vertical strip of an image. Assumes RGB images with 8-bit
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
33 # color.
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
34 class Strip:
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
35 def __init__(self, based_on, index):
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
36 if not isinstance(based_on, PIL.Image.Image):
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
37 raise TypeError("Expecting RGB PIL.Image object for based_on.")
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
38 if based_on.mode != "RGB":
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
39 raise ValueError("Expecting RGB PIL.Image object for based_on.")
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
40 self._index = index
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
41 self._based_on = based_on
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
42
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
43 @property
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
44 def index(self):
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
45 return self._index
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
46
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
47 @abstractmethod
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
48 def __len__(self):
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
49 pass
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
50
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
51 @abstractmethod
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
52 def __getitem__(self, key):
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
53 pass
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
54
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
55 @abstractmethod
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
56 def __setitem__(self, key, value):
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
57 pass
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
58
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
59 def is_all_white(self):
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
60 for i in range(len(self)):
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
61 if self[i] != (255, 255, 255):
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
62 return False
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
63 return True
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
64
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
65 # A horizontal strip of an image.
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
66 class Row(Strip):
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
67 def __len__(self):
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
68 return self._based_on.width
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
69
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
70 def __getitem__(self, key):
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
71 return self._based_on.getpixel((key, self._index))
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
72
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
73 def __setitem__(self, key, value):
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
74 self._based_on.setpixel((key, self._index), value)
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
75
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
76 # A vertical strip of an image.
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
77 class Column(Strip):
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
78 def __len__(self):
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
79 return self._based_on.height
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
80
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
81 def __getitem__(self, key):
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
82 return self._based_on.getpixel((self._index, key))
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
83
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
84 def __setitem__(self, key, value):
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
85 self._based_on.setpixel((self._index, key), value)
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
86
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
87 # A direction in which to search.
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
88 class Direction(IntEnum):
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
89 DESCENDING = -1
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
90 ASCENDING = 1
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
91
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
92 # An orientation in which to search.
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
93 class Orientation(IntEnum):
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
94 VERTICAL = 0
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
95 HORIZONTAL = 1
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
96
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
97 class TopoTilerException(Exception):
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
98 pass
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
99
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
100 # F u n c t i o n s
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
101
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
102 def find_edge(image, orientation, direction):
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
103 """
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
104 Find an edge in an image with a white border.
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
105 """
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
106 if orientation == Orientation.VERTICAL:
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
107 what = "column"
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
108 strip = Column
11
6e4a8ddacf61 Fix very minor bug.
David Barts <n5jrn@me.com>
parents: 10
diff changeset
109 maxn = image.width
0
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
110 else:
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
111 what = "row"
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
112 strip = Row
11
6e4a8ddacf61 Fix very minor bug.
David Barts <n5jrn@me.com>
parents: 10
diff changeset
113 maxn = image.height
0
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
114 # Establish outer bound and sanity-check it.
11
6e4a8ddacf61 Fix very minor bug.
David Barts <n5jrn@me.com>
parents: 10
diff changeset
115 outer = 0 if direction == Direction.ASCENDING else maxn - 1
0
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
116 if not strip(image, outer).is_all_white():
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
117 raise TopoTilerException("Unexpected nonwhite edge ({0} = {1})!".format(what, outer))
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
118 # Establish inner bound and sanity-check it.
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
119 inner = outer + direction * maxn // 4
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
120 if strip(image, inner).is_all_white():
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
121 raise TopoTilerException("Unexpected white strip ({0} = {1})!".format(what, inner))
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
122 while abs(outer - inner) > 1:
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
123 new = (outer + inner) // 2
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
124 if strip(image, new).is_all_white():
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
125 outer = new
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
126 else:
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
127 inner = new
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
128 return inner
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
129
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
130 def positive_int(string):
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
131 """
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
132 Specify a positive integer argument.
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
133 """
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
134 try:
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
135 ret = int(string)
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
136 except ValueError as e:
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
137 raise argparse.ArgumentTypeError(e.message)
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
138 if ret <= 0:
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
139 raise argparse.ArgumentTypeError("%r is 0 or negative" % string)
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
140 return ret
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
141
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
142 def gdalcmd(command, *args):
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
143 """
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
144 Build gdal command vector for subprocess.Popen
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
145 """
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
146 # print('$', command, ' '.join(args)) # debug
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
147 gdalbin = os.environ.get("GDALBIN")
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
148 cmd = shutil.which(command) if gdalbin is None else os.path.join(gdalbin, command)
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
149 ret = list(args)
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
150 ret.insert(0, cmd)
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
151 return ret
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
152
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
153 _MUZZLE = [
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
154 "insufficient arguments for Marked Content",
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
155 "More than 1000 errors or warnings have been reported."
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
156 ]
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
157 def drainout(stream):
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
158 """
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
159 Drain an output/error stream, muzzling the meaningless babble.
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
160 """
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
161 for line in stream:
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
162 printit = True
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
163 for m in _MUZZLE:
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
164 if m in line:
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
165 printit = False
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
166 break
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
167 if printit:
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
168 sys.stderr.write(line)
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
169
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
170 def waitfor(proc):
1
d268ae31f94b Add docstring.
David Barts <n5jrn@me.com>
parents: 0
diff changeset
171 """
d268ae31f94b Add docstring.
David Barts <n5jrn@me.com>
parents: 0
diff changeset
172 Wait for a GDAL command to finish.
d268ae31f94b Add docstring.
David Barts <n5jrn@me.com>
parents: 0
diff changeset
173 """
0
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
174 global estat
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
175 command_name = os.path.basename(proc.args[0])
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
176 status = proc.wait()
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
177 if status < 0:
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
178 sys.stderr.write("{0}: {1} killed by signal {2}\n".format(MYNAME, command_name, -status))
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
179 estat = 1
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
180 elif status > 0:
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
181 sys.stderr.write("{0}: {1} exited with status {2}\n".format(MYNAME, command_name, status))
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
182 estat = 1
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
183
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
184 _BLACKLIST = set(["Map_Frame.Projection_and_Grids", "Map_Frame.Terrain.Shaded_Relief"])
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
185 def get_default_layers(name):
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
186 """
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
187 Given a file, analyze it, and get the list of layers to not include
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
188 when rendering it.
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
189 """
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
190 proc = subprocess.Popen(
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
191 gdalcmd("gdalinfo", "-json", "-mdd", "LAYERS", name),
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
192 stdout=subprocess.PIPE, stderr=sys.stderr, env=ENVIRON, encoding=ENCODING)
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
193 data = json.load(proc.stdout)
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
194 waitfor(proc)
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
195 layers = set(["Map_Frame"])
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
196 for layer in data["metadata"]["LAYERS"].values():
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
197 if layer.startswith("Map_Frame.") and layer not in _BLACKLIST:
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
198 layers.add(layer)
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
199 return ",".join(layers)
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
200
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
201 # M a i n P r o g r a m
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
202
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
203 # Parse command-line arguments.
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
204 parser = argparse.ArgumentParser(description='Render GeoPDF into GeoTIFF suitable for tiling.')
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
205 parser.add_argument('--layers', '-l', type=str,
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
206 help='List of layers to include (see documentation for default).')
10
1944acce0e6f Add --output= option.
David Barts <n5jrn@me.com>
parents: 2
diff changeset
207 parser.add_argument('--output', '-o', type=str,
1944acce0e6f Add --output= option.
David Barts <n5jrn@me.com>
parents: 2
diff changeset
208 help='Name of output file (default: *.tiff).')
0
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
209 parser.add_argument('--resolution', '-r', type=positive_int, default=300,
2
94762476b171 Add default resolution to help.
David Barts <n5jrn@me.com>
parents: 1
diff changeset
210 help='Resolution to render at in DPI (default: 300).')
0
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
211 parser.add_argument('file', nargs=1,
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
212 help='File to read (must be a GeoPDF).')
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
213 try:
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
214 args = parser.parse_args()
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
215 except SystemExit:
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
216 sys.exit(2)
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
217
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
218 # File must end with '.pdf' (case insensitive), or else!
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
219 if not isinstance(args.file, str):
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
220 # How silly, it gave us a list or a tuple, despite only one of them!
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
221 args.file = args.file[0]
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
222 if not args.file.lower().endswith('.pdf'):
10
1944acce0e6f Add --output= option.
David Barts <n5jrn@me.com>
parents: 2
diff changeset
223 sys.stderr.write("{0}: input file must end with .pdf (case insensitive)\n".format(MYNAME))
1944acce0e6f Add --output= option.
David Barts <n5jrn@me.com>
parents: 2
diff changeset
224 sys.exit(2)
0
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
225
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
226 # Default the set of layers to delete, if necessary
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
227 if args.layers is None:
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
228 args.layers = get_default_layers(args.file)
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
229
10
1944acce0e6f Add --output= option.
David Barts <n5jrn@me.com>
parents: 2
diff changeset
230 # Default the output file, if necessary
1944acce0e6f Add --output= option.
David Barts <n5jrn@me.com>
parents: 2
diff changeset
231 if args.output is None:
1944acce0e6f Add --output= option.
David Barts <n5jrn@me.com>
parents: 2
diff changeset
232 args.output = os.path.splitext(args.file)[0] + ".tiff"
1944acce0e6f Add --output= option.
David Barts <n5jrn@me.com>
parents: 2
diff changeset
233 elif os.path.splitext(args.output)[1].lower() not in set([".tif", ".tiff"]):
1944acce0e6f Add --output= option.
David Barts <n5jrn@me.com>
parents: 2
diff changeset
234 sys.stderr.write("{0}: output file must end with .tif or .tiff (case insensitive)\n".format(MYNAME))
1944acce0e6f Add --output= option.
David Barts <n5jrn@me.com>
parents: 2
diff changeset
235 sys.exit(2)
1944acce0e6f Add --output= option.
David Barts <n5jrn@me.com>
parents: 2
diff changeset
236
0
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
237 with TemporaryDirectory() as td:
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
238 # Get scratch file name. This goes under TMPDIR; if the default temporary
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
239 # area is too small, set that environment variable accordingly!
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
240 tf = os.path.join(td, "temp.tiff")
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
241
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
242 # Render. The result will have undesired margins.
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
243 sys.stdout.write("Rendering (may take a while)...\n")
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
244 sys.stdout.flush()
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
245 proc = subprocess.Popen(
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
246 gdalcmd("gdal_translate", "-q", args.file, tf, "-of", "GTiff", "--config", "GDAL_PDF_LAYERS", args.layers, "--config", "GDAL_PDF_DPI", str(args.resolution)),
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
247 stdout=subprocess.DEVNULL, stderr=subprocess.PIPE, env=ENVIRON, encoding=ENCODING)
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
248 drainout(proc.stderr)
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
249 waitfor(proc)
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
250 sys.stdout.write("Done!\n")
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
251
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
252 # Determine crop marquee.
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
253 with Image.open(tf) as im:
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
254 minx = find_edge(im, Orientation.VERTICAL, Direction.ASCENDING)
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
255 maxx = find_edge(im, Orientation.VERTICAL, Direction.DESCENDING)
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
256 miny = find_edge(im, Orientation.HORIZONTAL, Direction.ASCENDING)
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
257 maxy = find_edge(im, Orientation.HORIZONTAL, Direction.DESCENDING)
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
258
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
259 # Crop.
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
260 proc = subprocess.Popen(
10
1944acce0e6f Add --output= option.
David Barts <n5jrn@me.com>
parents: 2
diff changeset
261 gdalcmd("gdal_translate", "-q", tf, args.output, "-of", "GTiff", "-srcwin", str(minx), str(miny), str(maxx-minx+1), str(maxy-miny+1)),
0
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
262 stdout=subprocess.DEVNULL, stderr=sys.stderr)
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
263 waitfor(proc)
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
264
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
265 # AMF...
c20b5314774f Initial commit.
David Barts <n5jrn@me.com>
parents:
diff changeset
266 sys.exit(estat)