如何将 mbtile 转换为 .osm.pbf

问题描述 投票:0回答:2

我正在编写一个 Qt 应用程序,该应用程序应该在其视图之一中显示特定地理区域的地理地图,我需要能够在其上绘制各种其他图形元素。

要求所有地图图块必须预先下载以供离线使用,因为在使用应用程序期间不会有互联网连接。

经过漫长的搜索,我可以链接到我的 Qt 项目来支持我的需求(离线图块加载、在 Qt 框架中渲染和绘制地图、非 QML 仅 C++ 集成)的合适库之后,我认为 libOsmScout 会完成工作。

但是,我设法从 OpenMapTiles 下载我所在区域的 .mbtiles 文件,只是为了意识到 libOsmScout 本身无法使用 .mbtiles。 该库只能与 .osm.pbf 文件一起使用(“导入”后间接使用)。 (http://libosmscout.sourceforge.net/tutorials/importing/)

我在网上进行了广泛的搜索,但所有结果都指向相反方向的转换过程,即转换为 .mbtiles。

所以我的问题是:是否可以将 .mbtiles 文件转换为 .osm.pbf 格式,以便我可以将 import 到 libOsmScout 兼容的内部文件集? 如果可以的话,流程是怎样的?

任何帮助或指导将不胜感激。 谢谢。

qt mbtiles osm.pbf
2个回答
1
投票

最简单的方法是使用 ogr2ogr 转换为

pbf
格式。

 ogr2ogr -f MVT output_dir_name input.mbtiles -dsco MAXZOOM=2

这将创建一个目录结构,每个缩放级别都有一个目录和根据图块位置命名的

pbf
文件。

或者

使用名为 MBUtil 的工具。

您可以从 github 存储库中执行一些步骤。 之后,您可以使用以下命令将每个图块转换为

pbf
格式的目录结构。

mb-util input.mbtiles output_dir_name image_format=pbf

其中

tiles
是你想要的目录名称


0
投票

过去,我使用过 mb-utils 方法。然而,跨平台和使用多个版本的 Python 工作,它变得非常耗时。我建议使用 ogr2ogr (如 Aman Bagrecha 发布的)。这是一个脚本,它将转换目录中的每个 .mbtiles 文件。 (注意:它会删除 .mbtile 文件,因此如果您不需要,请进行修改)。

import os
import sqlite3


def get_zoom_levels(filename):
    # Connect to the SQLite database file
    conn = sqlite3.connect(filename)
    cursor = conn.cursor()

    # Fetch minzoom and maxzoom from metadata
    cursor.execute("SELECT value FROM metadata WHERE name='minzoom';")
    minzoom = cursor.fetchone()[0]
    cursor.execute("SELECT value FROM metadata WHERE name='maxzoom';")
    maxzoom = cursor.fetchone()[0]

    # Close the connection
    conn.close()
    
    return minzoom, maxzoom


new_line = "\r\n"

print("Requires Python 3! Use python3 from the command line if needed.")

srcDir = os.getcwd()

mbtilesFileCount = 0

# Counting mbtiles files
for file in os.listdir(srcDir):
    if file.endswith(".mbtiles"):
        mbtilesFileCount += 1

print(f"{mbtilesFileCount} mbtiles file(s) found{new_line}")

# Processing each mbtiles file
for file in os.listdir(srcDir):
    if file.endswith(".mbtiles"):
        newDirName = os.path.basename(file).split('.')[0]

        # Check if the directory already exists
        if os.path.exists(newDirName):
            print(f"Error: Directory '{newDirName}' already exists. Skipping command.")
            continue  # Skip to the next iteration of the loop

        # This gets the actual zoom levels needed to correctly output the sub-directories
        minzoom, maxzoom = get_zoom_levels(file)

        command = f'ogr2ogr -f MVT {newDirName} {file} -dsco MINZOOM={minzoom} -dsco MAXZOOM={maxzoom}'
        print(f'Running {command}')
        result = os.system(command)

        # If command was successful, delete the file
        if result == 0:
            print(f"Deleting {file} after successful processing.")
            os.remove(file)
        else:
            print(f"Failed to process {file}. File not deleted.")
© www.soinside.com 2019 - 2024. All rights reserved.