Skip to content

Commit 2f5fc9a

Browse files
authored
Merge pull request #22 from Kanahiro/async
fix: mbtiles metadata, mvt mbtiles must be gzipped
2 parents de5213c + 0d2b614 commit 2f5fc9a

File tree

4 files changed

+53
-25
lines changed

4 files changed

+53
-25
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "tileget"
3-
version = "1.0.0"
3+
version = "1.0.1"
44
description = "Tile download utility - easily download xyz-tile data"
55
readme = "README.md"
66
requires-python = ">= 3.14"

tileget/__main__.py

Lines changed: 43 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import asyncio
2+
import gzip
23
import os
34
import random
45
import signal
@@ -45,6 +46,20 @@ async def acquire(self) -> bool:
4546
return True
4647

4748

49+
def normalize_format(ext: str, default: str | None = None) -> str:
50+
"""拡張子をMBTiles仕様のformat値に正規化"""
51+
ext = ext.lower().lstrip(".")
52+
if not ext:
53+
if default is None:
54+
raise ValueError("format must be specified when url has no extension")
55+
return normalize_format(default)
56+
if ext in ("jpeg", "jpg"):
57+
return "jpg"
58+
if ext in ("mvt", "pbf"):
59+
return "pbf"
60+
return ext
61+
62+
4863
def is_retryable_error(e: Exception) -> bool:
4964
if isinstance(e, httpx.TimeoutException):
5065
return True
@@ -165,6 +180,11 @@ async def download_mbtiles(
165180
if data is None:
166181
return
167182

183+
# MVT(pbf)はgzip圧縮して保存する必要がある
184+
ext = os.path.splitext(tileurl.split("?")[0])[-1].lower().lstrip(".")
185+
if ext in ("mvt", "pbf") and data[:2] != b"\x1f\x8b":
186+
data = gzip.compress(data)
187+
168188
if overwrite:
169189
c.execute(
170190
"DELETE FROM tiles WHERE zoom_level = ? AND tile_column = ? AND tile_row = ?",
@@ -184,7 +204,7 @@ def create_mbtiles(output_file: str):
184204
c.execute(
185205
"""
186206
CREATE TABLE metadata (
187-
name TEXT,
207+
name TEXT PRIMARY KEY,
188208
value TEXT
189209
)
190210
"""
@@ -232,32 +252,32 @@ def handle_sigint():
232252

233253
conn = None
234254
if params.mode == "mbtiles":
235-
if not os.path.exists(params.output_path):
255+
is_new = not os.path.exists(params.output_path)
256+
if is_new:
236257
create_mbtiles(params.output_path)
237258

238259
conn = sqlite3.connect(params.output_path, check_same_thread=False)
239260

240-
c = conn.cursor()
241-
c.execute(
242-
"INSERT INTO metadata (name, value) VALUES (?, ?)",
243-
("name", os.path.basename(params.output_path)),
244-
)
245-
c.execute(
246-
"INSERT INTO metadata (name, value) VALUES (?, ?)",
247-
(
248-
"format",
249-
os.path.splitext(params.tileurl.split("?")[0])[-1].replace(".", ""),
250-
),
251-
)
252-
c.execute(
253-
"INSERT INTO metadata (name, value) VALUES (?, ?)",
254-
("minzoom", params.minzoom),
255-
)
256-
c.execute(
257-
"INSERT INTO metadata (name, value) VALUES (?, ?)",
258-
("maxzoom", params.maxzoom),
259-
)
260-
conn.commit()
261+
if is_new:
262+
ext = os.path.splitext(params.tileurl.split("?")[0])[-1]
263+
c = conn.cursor()
264+
c.execute(
265+
"INSERT INTO metadata (name, value) VALUES (?, ?)",
266+
("name", os.path.basename(params.output_path)),
267+
)
268+
c.execute(
269+
"INSERT INTO metadata (name, value) VALUES (?, ?)",
270+
("format", normalize_format(ext, params.format)),
271+
)
272+
c.execute(
273+
"INSERT INTO metadata (name, value) VALUES (?, ?)",
274+
("minzoom", params.minzoom),
275+
)
276+
c.execute(
277+
"INSERT INTO metadata (name, value) VALUES (?, ?)",
278+
("maxzoom", params.maxzoom),
279+
)
280+
conn.commit()
261281

262282
tilescheme = (
263283
tiletanic.tileschemes.WebMercatorBL()

tileget/arg.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ class RunParams:
2121
tms: bool
2222
retries: int
2323
retry_delay: float
24+
format: str | None
2425

2526

2627
def parse_arg() -> RunParams:
@@ -39,6 +40,7 @@ def parse_arg() -> RunParams:
3940
)
4041
parser.add_argument("--minzoom", default=0, type=int, help="default to 0")
4142
parser.add_argument("--maxzoom", default=16, type=int, help="default to 16")
43+
4244
def positive_int(value: str) -> int:
4345
ivalue = int(value)
4446
if ivalue <= 0:
@@ -73,6 +75,11 @@ def positive_int(value: str) -> int:
7375
type=float,
7476
help="base delay in seconds for exponential backoff, default to 1.0",
7577
)
78+
parser.add_argument(
79+
"--format",
80+
type=str,
81+
help="tile format for mbtiles metadata (e.g. png, jpg, pbf). used when url has no extension",
82+
)
7683
args = parser.parse_args()
7784

7885
if args.output_dir is None and args.output_file is None:
@@ -131,6 +138,7 @@ def positive_int(value: str) -> int:
131138
tms=args.tms,
132139
retries=args.retries,
133140
retry_delay=args.retry_delay,
141+
format=args.format,
134142
)
135143

136144
return params

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)