管道基础大数据平台系统开发-【CS】-ExportMap
1
13693261870
2024-09-05 95d9356edef73a1ad5b04e62b7aef6b77697a226
ExportMap/Sources/xyz.py
@@ -1,7 +1,12 @@
#!/usr/bin/env
# -*- coding: utf-8 -*-
import os
import sys
import time
sys.path.append(r"C:\Program Files\QGIS 3.16\apps\qgis-ltr\python\plugins")
import math
import argparse
from qgis.core import *
@@ -9,7 +14,7 @@
from qgis.PyQt.QtGui import *
from qgis.PyQt.QtCore import *
from qgis.PyQt.QtWidgets import *
from qgis.PyQt.QtXml import *
from processing.core.Processing import Processing
# 获取完整路径
@@ -22,112 +27,162 @@
    print("argv = ", sys.argv[1:])
    parser = argparse.ArgumentParser(description='ArgUtils')
    parser.add_argument("-src", type=str, default=get_full_path(), required=False)
    parser.add_argument("-qgz", type=str, default="Test.qgz", required=False)
    parser.add_argument("-qpt", type=str, default="Test.qpt", required=False)
    parser.add_argument("-qgz", type=str, default=r"xyz.qgz", required=False)
    parser.add_argument("-file", type=str, default=r"D:\xyz\dom0.2m\tif.txt", required=False)
    parser.add_argument("-out", type=str, default=r"D:\xyz\dom0.2m\png", required=False)
    parser.add_argument("-min", type=int, default=12, required=False)
    parser.add_argument("-max", type=int, default=15, required=False)
    parser.add_argument("-noData", type=int, default=0, required=False)
    return parser.parse_args()
# 设置图层可用性
def set_layers_valid(prj, show_layers):
# 读取文本文件
def read_txt(path):
    f = open(path, encoding="utf-8")
    lines = f.readlines()
    f.close()
    for i in range(0, len(lines)):
        lines[i] = lines[i].replace('\n', '')
    return lines
# 加载图层
def load_layers(prj, args):
    for layer in prj.mapLayers().values():
        flag = layer.name() in show_layers
        print(layer.name() + ": " + str(flag))
        # if not flag:
        # project.removeMapLayer(layer)
        layer.setValid(flag)
        prj.removeMapLayer(layer)
    args.crs = None
    lines = read_txt(args.file)
    for i in range(0, len(lines)):
        if len(lines[i]) == 0:
            continue
        print("layer_" + str(i) + ": " + lines[i])
        layer = QgsRasterLayer(lines[i], "layer_" + str(i))
        if not layer.isValid() or layer.crs() is None:
            print("layer_" + str(i) + ": failed to load!")
            continue
        if len(prj.mapLayers()) == 0:
            args.crs = layer.crs()
            print("authid: " + args.crs.authid())
            prj.setCrs(layer.crs())
        for j in range(1, layer.bandCount() + 1):
            try:
                layer.dataProvider().setNoDataValue(j, args.noData)
            except Exception as e:
                print(e)
        prj.addMapLayer(layer)
# 设置图层可见性
def set_item_visibility(root_node, show_layers):
    print(root_node.name() + ': Group')
    for node in root_node.children():
        # QgsLayerTreeLayer
        if isinstance(node, QgsLayerTreeGroup):
            set_item_visibility(node, show_layers)
        # QgsRasterLayer, QgsVectorLayer
# 边界类
class Rectangle:
    def __init__(self, xmin, xmax, ymin, ymax):
        self.xmin = xmin
        self.xmax = xmax
        self.ymin = ymin
        self.ymax = ymax
# 获取边界
def get_extent(prj, args):
    ex = None
    for layer in prj.mapLayers().values():
        rect = layer.extent()
        if ex is None:
            # print(layer.extent().asWktCoordinates()); geo = QgsGeometry.fromWkt(layer.extent().asWktPolygon())
            ex = Rectangle(rect.xMinimum(), rect.xMaximum(), rect.yMinimum(), rect.yMaximum())
            continue
        if args.crs.authid() != layer.crs().authid():
            transform = QgsCoordinateTransform(layer.crs(), args.crs, prj)
            min = QgsPoint(rect.xMinimum(), rect.yMinimum())
            max = QgsPoint(rect.xMaximum(), rect.yMaximum())
            min.transform(transform)
            max.transform(transform)
            set_rect_bound(ex, min.x(), min.y(), max.x(), max.y())
        else:
            name = node.layer().name()
            flag = name in showLayers
            print(name + ": " + str(flag))
            # if not flag:
            # root_node.removeLayer(node.layer())
            # node.layer().setValid(False)
            node.setItemVisibilityChecked(flag)
            set_rect_bound(ex, rect.xMinimum(), rect.yMinimum(), rect.xMaximum(), rect.yMaximum())
    # 123543.6722,2730986.0671,2732253.9315,3552923.0518 [EPSG:32643]
    # return '38400309.1314,38403253.7083,3559920.4768,3561690.3144 [CGCS2000 / 3-degree Gauss-Kruger zone 38]'
    return str(ex.xmin) + "," + str(ex.xmax) + "," + str(ex.ymin) + "," + str(ex.ymax) + ' [' + args.crs.authid() + "]"
# 设置矩形边界
def set_rect_bound(ex, xmin, ymin, xmax, ymax):
    if xmin < ex.xmin:
        ex.xmin = xmin
    if ymin < ex.ymin:
        ex.ymin = ymin
    if xmax > ex.xmax:
        ex.xmax = xmax
    if ymax > ex.ymax:
        ex.ymax = ymax
# 获取XYZ参数
def get_xyz_ops(args):
    ops = {
        'BACKGROUND_COLOR': QColor(0, 0, 0, 0),
        'DPI': 96,
        'EXTENT': args.ext,
        'METATILESIZE': 4,
        'OUTPUT_DIRECTORY': args.out,
        # 'OUTPUT_HTML': 'TEMPORARY_OUTPUT',
        'OUTPUT_HTML': args.out + "\\view.html",
        'QUALITY': 100,
        'TILE_FORMAT': 0,
        'TILE_HEIGHT': 256,
        'TILE_WIDTH': 256,
        'TMS_CONVENTION': False,
        'ZOOM_MAX': args.max,
        'ZOOM_MIN': args.min
    }
    print(ops)
    return ops
# 创建XYZ瓦片
def create_xyz(args):
    import processing
    ops = get_xyz_ops(args)
    processing.run("qgis:tilesxyzdirectory", ops)
# 初始化
# QgsApplication.setPrefixPath(r"E:/terrait/TianJin/LFServer/QGIS/", True)
qgs = QgsApplication([], True)
qgs.initQgis()
def init():
    # QgsApplication.setPrefixPath("C:\Program Files\QGIS 3.16", True)
    qgs = QgsApplication([], False)
    qgs.initQgis()
    Processing.initialize()
# 加载工程
args = get_args()
project = QgsProject.instance()
# project.read(r'Test.qgz')
project.read(os.path.join(args.src, args.qgz))
print("FileName: " + project.fileName())
    args = get_args()
    prj = QgsProject.instance()
    prj.read(os.path.join(args.src, args.qgz))
    # prj.read(args.qgz)
    print("FileName: " + prj.fileName())
# layout = QgsPrintLayout(project)
layout = QgsLayout(project)
# layout.initializeDefaults()
    load_layers(prj, args)
    # prj.write(args.file.replace(".txt", ".qgz"))
# 加载模板
# with open(r'Test.qpt', 'r', encoding='utf-8') as f:
with open(os.path.join(args.src, args.qpt), 'r', encoding='utf-8') as f:
    template_content = f.read()
doc = QDomDocument()
doc.setContent(template_content)
layout.loadFromTemplate(doc, QgsReadWriteContext(), True)
    args.ext = get_extent(prj, args)
    create_xyz(args)
# map = layout.itemById(r'地图')
map = layout.referenceMap()
map.zoomToExtent(map.extent())
scale = '1:' + str(math.ceil(map.scale() / 100) * 100)
print(scale)
    qgs.exitQgis()
# template_content = template_content.replace('1:25万', scale)
# doc.setContent(template_content)
# layout.loadFromTemplate(doc, QgsReadWriteContext(), True)
# map = layout.referenceMap()
# map.zoomToExtent(map.extent())
size = map.sizeWithUnits()
print('size: ' + str(size.width()) + " * " + str(size.height()) + " mm")
if size.width() > 280 or size.height() > 174:
    map.attemptResize(QgsLayoutSize(280, 174, QgsUnitTypes.LayoutMillimeters))
    print('size: ' + str(map.sizeWithUnits().width()) + " * " + str(map.sizeWithUnits().height()) + " mm")
# 设置图层
# "阀室", "站场", "管道中心线", "矢量注记", "矢量图", "高德影像注记", "高德影像", "影像注记", "影像图"
# showLayers = ["阀室", "管道中心线", "矢量注记", "矢量图"]
showLayers = layout.customProperty("layers").split(',')
root = project.layerTreeRoot()
# set_layers_valid(project, showLayers)
set_item_visibility(root, showLayers)
# sm = layout.itemById(r'说明')
table = layout.multiFrames()[0]
contents = table.tableContents()
contents[1][1] = scale
table.refreshAttributes()
table.refresh()
# collection = layout.pageCollection()
# page = collection.page(0)
# page.refreshItemSize()
# 刷新
map.refresh()
# layout.updateBounds()
layout.renderContext()
layout.refresh()
# 导出
exporter = QgsLayoutExporter(layout)
# img_path = os.path.join(r"E:/terrait/TianJin/LFServer/QGIS", "render.png")
img_path = layout.customProperty("imgPath")
exporter.exportToImage(img_path, QgsLayoutExporter.ImageExportSettings())
# 退出
qgs.exitQgis()
# main
if __name__ == '__main__':
    timer = time.time()
    init()
    print(f'耗时:{time.time() - timer:.2f}s')