From 8b916dcb953995b10c5349d8999581291f7eee0a Mon Sep 17 00:00:00 2001 From: liuxsdev Date: Sun, 14 Jan 2024 23:46:04 +0800 Subject: [PATCH 1/6] =?UTF-8?q?Feat:=20=E5=8F=AF=E4=BB=A5=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E5=A4=9A=E4=B8=AAkey?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tianditu_tools/ui/search.py | 2 +- tianditu_tools/ui/setting.ui | 93 ++++++++--- tianditu_tools/utils.py | 57 ++++--- tianditu_tools/widgets/AddMap/main.py | 13 +- tianditu_tools/widgets/Search/main.py | 6 +- tianditu_tools/widgets/Setting/dialog.py | 199 +++++++++++++++++------ 6 files changed, 259 insertions(+), 111 deletions(-) diff --git a/tianditu_tools/ui/search.py b/tianditu_tools/ui/search.py index 9c8e56e..71f3890 100644 --- a/tianditu_tools/ui/search.py +++ b/tianditu_tools/ui/search.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'search.ui' # -# Created by: PyQt5 UI code generator 5.15.9 +# Created by: PyQt5 UI code generator 5.15.4 # # WARNING: Any manual changes made to this file will be lost when pyuic5 is # run again. Do not edit this file unless you know what you are doing. diff --git a/tianditu_tools/ui/setting.ui b/tianditu_tools/ui/setting.ui index f67d32c..0b438af 100644 --- a/tianditu_tools/ui/setting.ui +++ b/tianditu_tools/ui/setting.ui @@ -45,7 +45,7 @@ - Key: + 添加 Key: @@ -68,27 +68,62 @@ - + - 保存并检查有效性 + 保存 - + - Key状态: + 选择 Key: - + + + + Consolas + + + + + + + + 随机 + + + + + + + + 50 + 16777215 + + + + 复制 + + + + + + + + 50 + 16777215 + + - 未知 + 删除 @@ -99,7 +134,7 @@ - 子域: + 子域 Subdomain: @@ -117,20 +152,10 @@ - - - <html><head/><body><p><span style=" font-size:10pt;">添加底图时随机选择子域名,可减轻服务器压力,</span>提高可用性。</p></body></html> - - - 随机 - - - - - + - 90 + 80 0 @@ -148,6 +173,16 @@ + + + + <html><head/><body><p><span style=" font-size:10pt;">添加底图时随机选择子域名,可减轻服务器压力,</span>提高可用性。</p></body></html> + + + 随机 + + + @@ -156,7 +191,7 @@ - <html><head/><body><p><span style=" font-size:8pt;">没有Key?</span><a href="https://console.tianditu.gov.cn/api/key"><span style=" font-size:8pt; text-decoration: underline; color:#0000ff;">点击此处去申请</span></a></p></body></html> + <html><head/><body><p><span style=" font-weight:600; color:#808080;">没有Key?</span><a href="https://console.tianditu.gov.cn/api/key"><span style=" font-weight:600; text-decoration: underline; color:#808080;">点击此处去申请</span></a></p></body></html> true @@ -176,6 +211,22 @@ + + + + + 微软雅黑 + 8 + + + + color: rgb(128, 128, 128); + + + + + + diff --git a/tianditu_tools/utils.py b/tianditu_tools/utils.py index 6952b05..bc236ea 100644 --- a/tianditu_tools/utils.py +++ b/tianditu_tools/utils.py @@ -1,6 +1,7 @@ import json from multiprocessing.dummy import Pool as ThreadPool from pathlib import Path +from random import choice import requests import yaml @@ -30,22 +31,33 @@ class PluginConfig: def __init__(self): self.conf = QgsSettings() self.conf_name = "tianditu-tools" + self.section_tianditu = f"{self.conf_name}/Tianditu" def init_config(self): # 初始化配置文件 if not self.conf.contains("tianditu-tools/Tianditu/key"): print("初始化配置文件") # 初始化 - self.conf.setValue(f"{self.conf_name}/Tianditu/key", "") - self.conf.setValue(f"{self.conf_name}/Tianditu/keyisvalid", False) - self.conf.setValue(f"{self.conf_name}/Tianditu/random", True) - self.conf.setValue(f"{self.conf_name}/Tianditu/subdomain", "t0") - self.conf.setValue(f"{self.conf_name}/Other/extramap", False) + self.conf.setValue(f"{self.section_tianditu}/key", "") + self.conf.setValue(f"{self.section_tianditu}/keyList", "") + self.conf.setValue(f"{self.section_tianditu}/random", True) + self.conf.setValue(f"{self.section_tianditu}/subdomain", "t0") if not self.conf.contains("tianditu-tools/Other/extramap_status"): print("初始化 extra map 文件") self.conf.setValue( f"{self.conf_name}/Other/extramap_status", str(get_extramap_status()) ) + if not self.conf.contains(f"{self.section_tianditu}/keyList"): + self.conf.setValue(f"{self.section_tianditu}/keyList", "") + + def get_key_list(self): + data_str = self.get_value("/Tianditu/keyList") + if data_str == "": + return [] + return data_str.split(",") + + def save_key_list(self, data_list): + self.conf.setValue(f"{self.section_tianditu}/keyList", ",".join(data_list)) def get_extra_maps_status(self): data = self.get_value("Other/extramap_status") @@ -66,6 +78,19 @@ def set_value(self, name, value): def get_key(self): return self.get_value("Tianditu/key") + def get_random_key(self): + key_list = self.get_key_list() + if len(key_list) > 0: + return choice(key_list) + + def set_key(self, key): + key_to_set = "" + if key is None: + key_to_set = "" + else: + key_to_set = key + self.conf.setValue(f"{self.section_tianditu}/key", key_to_set) + def got(url, headers=None, timeout=6): try: @@ -162,28 +187,6 @@ def check_subdomains(url_list: list) -> list: return ["❌" if x == -1 else f"{x} ms" for x in ping_list] -def check_key_format(key: str) -> object: - """检查key格式 - - Args: - key (str): 天地图key - - Returns: - object: - "key_length_error": key的长度有误, - "has_special_character": 含有除字母数字外的其他字符 - """ - correct_length = 32 - key_length = len(key) - key_length_error = False - if key_length != correct_length: - key_length_error = True - return { - "key_length_error": key_length_error, - "has_special_character": not key.isalnum(), - } - - def load_yaml(file_path: Path): """ 读取YAML文件 diff --git a/tianditu_tools/widgets/AddMap/main.py b/tianditu_tools/widgets/AddMap/main.py index 8c2efd4..c772b24 100644 --- a/tianditu_tools/widgets/AddMap/main.py +++ b/tianditu_tools/widgets/AddMap/main.py @@ -47,8 +47,6 @@ def setup_action(self): # 天地图省级节点 add_tianditu_province_menu(menu) # 其他图源 - # extra = menu.addAction(icons["other"], "其他图源") - # extra_map_menu = QMenu() add_extra_map_menu(menu) self.setMenu(menu) self.setPopupMode(QToolButton.MenuButtonPopup) @@ -56,8 +54,7 @@ def setup_action(self): def add_tianditu_basemap(self, maptype): key = conf.get_key() - keyisvalid = conf.get_bool_value("Tianditu/keyisvalid") - if key == "" or keyisvalid is False: + if key == "": QMessageBox.warning( self, "错误", "天地图Key未设置或Key无效", QMessageBox.Yes, QMessageBox.Yes ) @@ -65,6 +62,8 @@ def add_tianditu_basemap(self, maptype): random_enabled = conf.get_bool_value("Tianditu/random") if random_enabled: subdomain = f"t{random.randint(0, 7)}" - map_url = tianditu_map_url(maptype, key, subdomain) - uri = get_map_uri(map_url, 1, 18, TIANDITU_HOME_URL) - add_raster_layer(uri, tianditu_map_info[maptype]) + else: + subdomain = conf.get_value("Tianditu/subdomain") + map_url = tianditu_map_url(maptype, key, subdomain) + uri = get_map_uri(map_url, 1, 18, TIANDITU_HOME_URL) + add_raster_layer(uri, tianditu_map_info[maptype]) diff --git a/tianditu_tools/widgets/Search/main.py b/tianditu_tools/widgets/Search/main.py index faab109..4474ac0 100644 --- a/tianditu_tools/widgets/Search/main.py +++ b/tianditu_tools/widgets/Search/main.py @@ -15,6 +15,7 @@ def __init__( parent=None, ): super().__init__(parent) + self.parent = parent self.iface = iface self.setIcon(icons["search"]) self.setText("搜索") @@ -26,10 +27,9 @@ def __init__( def openSearch(self): key = conf.get_key() - keyisvalid = conf.get_bool_value("Tianditu/keyisvalid") - if key == "" or keyisvalid is False: + if key == "": QMessageBox.warning( - self.toolbar, "错误", "天地图Key未设置或Key无效", QMessageBox.Yes, QMessageBox.Yes + self.parent, "错误", "天地图Key未设置或Key无效", QMessageBox.Yes, QMessageBox.Yes ) else: if self.searchdockwidget.isHidden(): diff --git a/tianditu_tools/widgets/Setting/dialog.py b/tianditu_tools/widgets/Setting/dialog.py index bbefb7b..7a204e5 100644 --- a/tianditu_tools/widgets/Setting/dialog.py +++ b/tianditu_tools/widgets/Setting/dialog.py @@ -1,18 +1,41 @@ from qgis.PyQt import QtWidgets -from qgis.PyQt.QtCore import QThread, pyqtSignal +from qgis.PyQt.QtCore import QThread, pyqtSignal, QTimer +from qgis.PyQt.QtGui import QClipboard +from qgis.PyQt.QtWidgets import QApplication from tianditu_tools.ui.setting import Ui_SettingDialog from tianditu_tools.utils import ( tianditu_map_url, check_url_status, check_subdomains, - check_key_format, PluginConfig, PluginDir, ) from .mapmanager import MapManager +def check_key_format(key: str) -> object: + """检查key格式 + + Args: + key (str): 天地图key + + Returns: + object: + "key_length_error": key的长度有误, + "has_special_character": 含有除字母数字外的其他字符 + """ + correct_length = 32 + key_length = len(key) + key_length_error = False + if key_length != correct_length: + key_length_error = True + return { + "key_length_error": key_length_error, + "has_special_character": not key.isalnum(), + } + + class CheckThread(QThread): check_finished = pyqtSignal(str) @@ -58,40 +81,121 @@ def __init__(self, toolbar): self.toolbar = toolbar # 读取配置 self.conf = PluginConfig() + self.subdomain_list = [f"t{i}" for i in range(8)] + # 设置 status label 的定时器 + self.timer = QTimer(self) + self.timer.timeout.connect(self.clear_status_label) # 设置界面 self.setupUi(self) - self.mLineEdit_key.setText(self.conf.get_key()) + self.initUI() + + def initUI(self): + self.init_keyCombo() + # 如果key输入框是空白的,则禁用保存按钮 if len(self.mLineEdit_key.text()) == 0: - self.pushButton.setEnabled(False) + self.saveButton.setEnabled(False) + # 给控件添加事件 self.mLineEdit_key.textChanged.connect(self.on_key_LineEdit_changed) - keyisvalid = self.conf.get_bool_value("Tianditu/keyisvalid") - if keyisvalid: - self.label_keystatus.setText("正常") - else: - self.label_keystatus.setText("无效") - self.pushButton.clicked.connect(self.check) - self.checkBox_2.setChecked(self.conf.get_bool_value("Tianditu/random")) - self.checkBox_2.stateChanged.connect(self.enable_random) + self.saveButton.clicked.connect(self.save_key) + self.pushButton_copy.clicked.connect(self.copy_key) + self.pushButton_delete.clicked.connect(self.del_key) + self.keyComboBox.currentIndexChanged.connect(self.select_key) + # subdomain 选择 + self.checkBox_domain_rand.setChecked( + self.conf.get_bool_value("Tianditu/random") + ) + self.checkBox_domain_rand.stateChanged.connect(self.enable_random) # subdomian 设置 - self.subdomain_list = ["t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7"] - self.comboBox.addItems(self.subdomain_list) - self.comboBox.setCurrentIndex( + self.subdomainComboBox.addItems(self.subdomain_list) + self.subdomainComboBox.setCurrentIndex( self.subdomain_list.index(self.conf.get_value("Tianditu/subdomain")) ) - self.comboBox.setEnabled(not self.conf.get_value("Tianditu/random")) - self.comboBox.currentIndexChanged.connect(self.handle_comboBox_index_changed) - if not self.conf.get_bool_value("Tianditu/random") and self.conf.get_bool_value( - "Tianditu/keyisvalid" - ): - self.ping_thread = PingUrlThread(self.conf.get_key()) - self.ping_thread.ping_finished.connect(self.handle_ping_finished) - self.ping_thread.start() + self.subdomainComboBox.setEnabled(not self.conf.get_value("Tianditu/random")) + self.subdomainComboBox.currentIndexChanged.connect(self.select_subdomain) # init map manager map_folder = PluginDir.joinpath("maps") self.mapm = MapManager(map_folder=map_folder, parent=self.tab_map) self.verticalLayout_6.addWidget(self.mapm) self.pushButton_2.clicked.connect(self.mapm.check_update) + def set_status_label(self, text): + """ + 创建提示 + """ + self.info_status.setText(text) + self.timer.start(2000) + + def clear_status_label(self): + self.info_status.clear() + self.timer.stop() + + def get_key_by_masked(self, masked): + key_list = self.conf.get_key_list() + filtered_items = [key for key in key_list if key.startswith(masked[:8])] + if len(filtered_items) > 0: + return filtered_items[0] + + def init_keyCombo(self): + self.keyComboBox.clear() # 先清除 + # 如果 key 列表中没有值, keyComboBox 添加提示 + key_list = self.conf.get_key_list() + if len(key_list) == 0: + self.keyComboBox.addItem("请添加 key") + self.pushButton_delete.setEnabled(False) + self.pushButton_copy.setEnabled(False) + else: + self.keyComboBox.addItems([f"{key[:8]}****" for key in key_list]) + # 将 keyComboBox 的当前值改为当前选用的 key + current_key = self.conf.get_key() + index = key_list.index(current_key) + self.keyComboBox.setCurrentIndex(index) + self.pushButton_delete.setEnabled(True) + self.pushButton_copy.setEnabled(True) + + def copy_key(self): + current_key = self.keyComboBox.currentText() + full_key = self.get_key_by_masked(current_key) + clipboard = QApplication.clipboard() + clipboard.setText(full_key, QClipboard.Clipboard) + self.set_status_label(f"已复制{current_key}到剪贴板") + + def save_key(self): + key = self.mLineEdit_key.text() + key_list = self.conf.get_key_list() + if key not in key_list: + url = tianditu_map_url("vec", key, "t0") + tile_url = url.format(x=0, y=0, z=0) + check_msg = check_url_status(tile_url) + if check_msg["code"] == 0: + if self.keyComboBox.itemText(0) == "请添加 key": + self.keyComboBox.removeItem(0) + self.mLineEdit_key.setText("") + key_list.append(key) + self.conf.save_key_list(key_list) + self.saveButton.setEnabled(False) + self.set_status_label("保存成功") + self.init_keyCombo() + else: + error_msg = f"{check_msg['msg']}: {check_msg['resolve']}" + self.set_status_label(error_msg) + else: + self.set_status_label("key 已存在") + + def select_key(self): + if self.keyComboBox.count() > 0: + masked_key = self.keyComboBox.currentText() + key = self.get_key_by_masked(masked_key) + self.conf.set_key(key) + self.set_status_label(f"设置当前 key 为{masked_key}") + + def del_key(self): + current_index = self.keyComboBox.currentIndex() + key_list = self.conf.get_key_list() + del key_list[current_index] + self.conf.save_key_list(key_list) + self.set_status_label("已删除") + self.init_keyCombo() + def handle_ping_finished(self, status): min_time = min(status) min_index = status.index(min_time) @@ -100,7 +204,6 @@ def handle_ping_finished(self, status): self.comboBox.setItemText(min_index, f"t{min_index} {status[min_index]}*") def on_key_LineEdit_changed(self): - # self.pushButton.setEnabled(True) current_text = self.mLineEdit_key.text() # 删除key中的空格以及非打印字符 filtered_text = "".join( @@ -109,42 +212,34 @@ def on_key_LineEdit_changed(self): if filtered_text != current_text: self.mLineEdit_key.setText(filtered_text) # 检查key格式 - key_format = check_key_format(self.mLineEdit_key.text()) - if key_format["key_length_error"]: - self.label_keystatus.setText("无效key: 格式错误(长度不对)") - self.pushButton.setEnabled(False) - elif key_format["has_special_character"]: - self.label_keystatus.setText("无效key: 含非常规字符") - self.pushButton.setEnabled(False) + if len(self.mLineEdit_key.text()) > 0: + key_format = check_key_format(self.mLineEdit_key.text()) + if key_format["key_length_error"]: + self.info_status.setText("无效key: 格式错误(长度不对)") + self.saveButton.setEnabled(False) + elif key_format["has_special_character"]: + self.info_status.setText("无效key: 含非常规字符") + self.saveButton.setEnabled(False) + else: + self.info_status.setText("点击保存") + self.saveButton.setEnabled(True) else: - self.label_keystatus.setText("未知") - self.pushButton.setEnabled(True) - - def check(self): - """检查key是否有效""" - self.conf.set_value("Tianditu/key", self.mLineEdit_key.text()) - self.label_keystatus.setText("检查中...") - self.check_thread = CheckThread(self.conf) - self.check_thread.key = self.mLineEdit_key.text() - self.check_thread.check_finished.connect(self.label_keystatus.setText) - self.check_thread.start() - - def handle_comboBox_index_changed(self): - selected_index = self.comboBox.currentIndex() + self.info_status.clear() + + def select_subdomain(self): + selected_index = self.subdomainComboBox.currentIndex() selected_domain = self.subdomain_list[selected_index] self.conf.set_value("Tianditu/subdomain", selected_domain) + self.set_status_label(f"设置 subdomain 为 {selected_domain}") def enable_random(self): - if self.checkBox_2.isChecked(): + if self.checkBox_domain_rand.isChecked(): self.conf.set_value("Tianditu/random", True) - self.comboBox.setEnabled(False) + self.subdomainComboBox.setEnabled(False) + self.set_status_label("设置 subdomain 为 随机") else: self.conf.set_value("Tianditu/random", False) - self.comboBox.setEnabled(True) - if self.conf.get_bool_value("Tianditu/keyisvalid"): - self.ping_thread = PingUrlThread(self.conf.get_key()) - self.ping_thread.ping_finished.connect(self.handle_ping_finished) - self.ping_thread.start() + self.subdomainComboBox.setEnabled(True) def closeEvent(self, event): # 在对话框关闭时触发的事件 From d58a95cc31ef88c621574d229e7d541746647ea5 Mon Sep 17 00:00:00 2001 From: liuxsdev Date: Mon, 15 Jan 2024 11:21:35 +0800 Subject: [PATCH 2/6] fix:update missing ui trans file --- tianditu_tools/ui/setting.py | 76 ++++++++++++++++++++++++------------ 1 file changed, 52 insertions(+), 24 deletions(-) diff --git a/tianditu_tools/ui/setting.py b/tianditu_tools/ui/setting.py index 5e0b38b..1d7bc02 100644 --- a/tianditu_tools/ui/setting.py +++ b/tianditu_tools/ui/setting.py @@ -46,9 +46,9 @@ def setupUi(self, SettingDialog): self.mLineEdit_key.setShowLockIcon(False) self.mLineEdit_key.setObjectName("mLineEdit_key") self.horizontalLayout.addWidget(self.mLineEdit_key) - self.pushButton = QtWidgets.QPushButton(self.groupBox) - self.pushButton.setObjectName("pushButton") - self.horizontalLayout.addWidget(self.pushButton) + self.saveButton = QtWidgets.QPushButton(self.groupBox) + self.saveButton.setObjectName("saveButton") + self.horizontalLayout.addWidget(self.saveButton) self.horizontalLayout.setStretch(0, 1) self.horizontalLayout.setStretch(1, 10) self.horizontalLayout.setStretch(2, 2) @@ -58,9 +58,26 @@ def setupUi(self, SettingDialog): self.label_2 = QtWidgets.QLabel(self.groupBox) self.label_2.setObjectName("label_2") self.horizontalLayout_2.addWidget(self.label_2) - self.label_keystatus = QtWidgets.QLabel(self.groupBox) - self.label_keystatus.setObjectName("label_keystatus") - self.horizontalLayout_2.addWidget(self.label_keystatus) + self.keyComboBox = QtWidgets.QComboBox(self.groupBox) + font = QtGui.QFont() + font.setFamily("Consolas") + self.keyComboBox.setFont(font) + self.keyComboBox.setObjectName("keyComboBox") + self.horizontalLayout_2.addWidget(self.keyComboBox) + self.checkBox_key_rand = QtWidgets.QCheckBox(self.groupBox) + self.checkBox_key_rand.setObjectName("checkBox_key_rand") + self.horizontalLayout_2.addWidget(self.checkBox_key_rand) + self.pushButton_copy = QtWidgets.QPushButton(self.groupBox) + self.pushButton_copy.setMaximumSize(QtCore.QSize(50, 16777215)) + self.pushButton_copy.setObjectName("pushButton_copy") + self.horizontalLayout_2.addWidget(self.pushButton_copy) + self.pushButton_delete = QtWidgets.QPushButton(self.groupBox) + self.pushButton_delete.setMaximumSize(QtCore.QSize(50, 16777215)) + self.pushButton_delete.setObjectName("pushButton_delete") + self.horizontalLayout_2.addWidget(self.pushButton_delete) + self.horizontalLayout_2.setStretch(0, 1) + self.horizontalLayout_2.setStretch(1, 10) + self.horizontalLayout_2.setStretch(4, 2) self.verticalLayout_2.addLayout(self.horizontalLayout_2) self.horizontalLayout_3 = QtWidgets.QHBoxLayout() self.horizontalLayout_3.setObjectName("horizontalLayout_3") @@ -69,16 +86,16 @@ def setupUi(self, SettingDialog): self.horizontalLayout_3.addWidget(self.label_3) spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.horizontalLayout_3.addItem(spacerItem) - self.checkBox_2 = QtWidgets.QCheckBox(self.groupBox) - self.checkBox_2.setObjectName("checkBox_2") - self.horizontalLayout_3.addWidget(self.checkBox_2) - self.comboBox = QtWidgets.QComboBox(self.groupBox) - self.comboBox.setMinimumSize(QtCore.QSize(90, 0)) - self.comboBox.setBaseSize(QtCore.QSize(200, 0)) - self.comboBox.setCurrentText("") - self.comboBox.setInsertPolicy(QtWidgets.QComboBox.InsertAtTop) - self.comboBox.setObjectName("comboBox") - self.horizontalLayout_3.addWidget(self.comboBox) + self.subdomainComboBox = QtWidgets.QComboBox(self.groupBox) + self.subdomainComboBox.setMinimumSize(QtCore.QSize(80, 0)) + self.subdomainComboBox.setBaseSize(QtCore.QSize(200, 0)) + self.subdomainComboBox.setCurrentText("") + self.subdomainComboBox.setInsertPolicy(QtWidgets.QComboBox.InsertAtTop) + self.subdomainComboBox.setObjectName("subdomainComboBox") + self.horizontalLayout_3.addWidget(self.subdomainComboBox) + self.checkBox_domain_rand = QtWidgets.QCheckBox(self.groupBox) + self.checkBox_domain_rand.setObjectName("checkBox_domain_rand") + self.horizontalLayout_3.addWidget(self.checkBox_domain_rand) self.verticalLayout_2.addLayout(self.horizontalLayout_3) self.horizontalLayout_4 = QtWidgets.QHBoxLayout() self.horizontalLayout_4.setObjectName("horizontalLayout_4") @@ -89,6 +106,15 @@ def setupUi(self, SettingDialog): self.verticalLayout_2.addWidget(self.label_4) spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) self.verticalLayout_2.addItem(spacerItem1) + self.info_status = QtWidgets.QLabel(self.groupBox) + font = QtGui.QFont() + font.setFamily("微软雅黑") + font.setPointSize(8) + self.info_status.setFont(font) + self.info_status.setStyleSheet("color: rgb(128, 128, 128);") + self.info_status.setText("") + self.info_status.setObjectName("info_status") + self.verticalLayout_2.addWidget(self.info_status) self.verticalLayout_4.addWidget(self.groupBox) self.tabWidget.addTab(self.tab_keyset, "") self.tab_map = QtWidgets.QWidget() @@ -117,15 +143,17 @@ def retranslateUi(self, SettingDialog): _translate = QtCore.QCoreApplication.translate SettingDialog.setWindowTitle(_translate("SettingDialog", "设置")) self.groupBox.setTitle(_translate("SettingDialog", "Key 设置")) - self.label.setText(_translate("SettingDialog", "Key:")) + self.label.setText(_translate("SettingDialog", "添加 Key:")) self.mLineEdit_key.setPlaceholderText(_translate("SettingDialog", "输入天地图key")) - self.pushButton.setText(_translate("SettingDialog", "保存并检查有效性")) - self.label_2.setText(_translate("SettingDialog", "Key状态:")) - self.label_keystatus.setText(_translate("SettingDialog", "未知")) - self.label_3.setText(_translate("SettingDialog", "子域:")) - self.checkBox_2.setToolTip(_translate("SettingDialog", "

添加底图时随机选择子域名,可减轻服务器压力,提高可用性。

")) - self.checkBox_2.setText(_translate("SettingDialog", "随机")) - self.label_4.setText(_translate("SettingDialog", "

没有Key?点击此处去申请

")) + self.saveButton.setText(_translate("SettingDialog", "保存")) + self.label_2.setText(_translate("SettingDialog", "选择 Key:")) + self.checkBox_key_rand.setText(_translate("SettingDialog", "随机")) + self.pushButton_copy.setText(_translate("SettingDialog", "复制")) + self.pushButton_delete.setText(_translate("SettingDialog", "删除")) + self.label_3.setText(_translate("SettingDialog", "子域 Subdomain:")) + self.checkBox_domain_rand.setToolTip(_translate("SettingDialog", "

添加底图时随机选择子域名,可减轻服务器压力,提高可用性。

")) + self.checkBox_domain_rand.setText(_translate("SettingDialog", "随机")) + self.label_4.setText(_translate("SettingDialog", "

没有Key?点击此处去申请

")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_keyset), _translate("SettingDialog", "天地图设置")) self.pushButton_2.setText(_translate("SettingDialog", "检查更新")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_map), _translate("SettingDialog", "地图管理")) From f0ce43cc552ecfa0698b900cde708cee06d6c559 Mon Sep 17 00:00:00 2001 From: liuxsdev Date: Mon, 15 Jan 2024 11:22:07 +0800 Subject: [PATCH 3/6] fix: add missing toolbar name --- tianditu_tools/widgets/toolbar.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tianditu_tools/widgets/toolbar.py b/tianditu_tools/widgets/toolbar.py index 9ae1d28..7ac1997 100644 --- a/tianditu_tools/widgets/toolbar.py +++ b/tianditu_tools/widgets/toolbar.py @@ -10,7 +10,7 @@ class TiandituToolbar(QToolBar): def __init__(self, iface, parent=None) -> None: - super().__init__(parent) + super().__init__("Tianditu Tools 工具栏",parent) self.iface = iface self.icons = icons self.conf = PluginConfig() From 1031f264a72f364062f9bb99708a0f2dfbd6e40a Mon Sep 17 00:00:00 2001 From: liuxsdev Date: Mon, 15 Jan 2024 17:11:05 +0800 Subject: [PATCH 4/6] Chroe: remove unnecessary code --- tianditu_tools/utils.py | 16 ++++++++++------ tianditu_tools/widgets/Setting/dialog.py | 3 ++- tianditu_tools/widgets/toolbar.py | 2 +- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/tianditu_tools/utils.py b/tianditu_tools/utils.py index bc236ea..d5b8baa 100644 --- a/tianditu_tools/utils.py +++ b/tianditu_tools/utils.py @@ -41,14 +41,21 @@ def init_config(self): self.conf.setValue(f"{self.section_tianditu}/key", "") self.conf.setValue(f"{self.section_tianditu}/keyList", "") self.conf.setValue(f"{self.section_tianditu}/random", True) + self.conf.setValue(f"{self.section_tianditu}/random_key", False) self.conf.setValue(f"{self.section_tianditu}/subdomain", "t0") if not self.conf.contains("tianditu-tools/Other/extramap_status"): print("初始化 extra map 文件") self.conf.setValue( f"{self.conf_name}/Other/extramap_status", str(get_extramap_status()) ) + # 升级到保存多个key的版本 if not self.conf.contains(f"{self.section_tianditu}/keyList"): - self.conf.setValue(f"{self.section_tianditu}/keyList", "") + self.conf.setValue(f"{self.section_tianditu}/random_key", False) + # 保存原来的key + if self.get_key() != "": + self.conf.setValue(f"{self.section_tianditu}/keyList", self.get_key()) + else: + self.conf.setValue(f"{self.section_tianditu}/keyList", "") def get_key_list(self): data_str = self.get_value("/Tianditu/keyList") @@ -80,14 +87,11 @@ def get_key(self): def get_random_key(self): key_list = self.get_key_list() - if len(key_list) > 0: - return choice(key_list) + return choice(key_list) def set_key(self, key): key_to_set = "" - if key is None: - key_to_set = "" - else: + if key is not None: key_to_set = key self.conf.setValue(f"{self.section_tianditu}/key", key_to_set) diff --git a/tianditu_tools/widgets/Setting/dialog.py b/tianditu_tools/widgets/Setting/dialog.py index 7a204e5..faaa664 100644 --- a/tianditu_tools/widgets/Setting/dialog.py +++ b/tianditu_tools/widgets/Setting/dialog.py @@ -76,8 +76,8 @@ def run(self): class SettingDialog(QtWidgets.QDialog, Ui_SettingDialog): def __init__(self, toolbar): super().__init__() - self.ping_thread = None self.check_thread = None + self.mapm = None self.toolbar = toolbar # 读取配置 self.conf = PluginConfig() @@ -134,6 +134,7 @@ def get_key_by_masked(self, masked): filtered_items = [key for key in key_list if key.startswith(masked[:8])] if len(filtered_items) > 0: return filtered_items[0] + return "" def init_keyCombo(self): self.keyComboBox.clear() # 先清除 diff --git a/tianditu_tools/widgets/toolbar.py b/tianditu_tools/widgets/toolbar.py index 7ac1997..81f6451 100644 --- a/tianditu_tools/widgets/toolbar.py +++ b/tianditu_tools/widgets/toolbar.py @@ -10,7 +10,7 @@ class TiandituToolbar(QToolBar): def __init__(self, iface, parent=None) -> None: - super().__init__("Tianditu Tools 工具栏",parent) + super().__init__("Tianditu Tools 工具栏", parent) self.iface = iface self.icons = icons self.conf = PluginConfig() From 02ebd3f9f679b427c1e0f3d7325abd88634342dd Mon Sep 17 00:00:00 2001 From: liuxsdev Date: Mon, 15 Jan 2024 23:28:18 +0800 Subject: [PATCH 5/6] Chore: key random --- tianditu_tools/widgets/AddMap/main.py | 3 +++ tianditu_tools/widgets/Setting/dialog.py | 22 +++++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/tianditu_tools/widgets/AddMap/main.py b/tianditu_tools/widgets/AddMap/main.py index c772b24..7997017 100644 --- a/tianditu_tools/widgets/AddMap/main.py +++ b/tianditu_tools/widgets/AddMap/main.py @@ -60,10 +60,13 @@ def add_tianditu_basemap(self, maptype): ) else: random_enabled = conf.get_bool_value("Tianditu/random") + key_random_enabled = conf.get_bool_value("Tianditu/random_key") if random_enabled: subdomain = f"t{random.randint(0, 7)}" else: subdomain = conf.get_value("Tianditu/subdomain") + if key_random_enabled: + key = conf.get_random_key() map_url = tianditu_map_url(maptype, key, subdomain) uri = get_map_uri(map_url, 1, 18, TIANDITU_HOME_URL) add_raster_layer(uri, tianditu_map_info[maptype]) diff --git a/tianditu_tools/widgets/Setting/dialog.py b/tianditu_tools/widgets/Setting/dialog.py index faaa664..6a65950 100644 --- a/tianditu_tools/widgets/Setting/dialog.py +++ b/tianditu_tools/widgets/Setting/dialog.py @@ -100,6 +100,13 @@ def initUI(self): self.pushButton_copy.clicked.connect(self.copy_key) self.pushButton_delete.clicked.connect(self.del_key) self.keyComboBox.currentIndexChanged.connect(self.select_key) + # 是否启用key随机 + if self.conf.get_bool_value("Tianditu/random_key"): + self.checkBox_key_rand.setChecked(True) + self.keyComboBox.setEnabled(False) + self.pushButton_copy.setEnabled(False) + self.pushButton_delete.setEnabled(False) + self.checkBox_key_rand.stateChanged.connect(self.enable_key_random) # subdomain 选择 self.checkBox_domain_rand.setChecked( self.conf.get_bool_value("Tianditu/random") @@ -118,7 +125,7 @@ def initUI(self): self.verticalLayout_6.addWidget(self.mapm) self.pushButton_2.clicked.connect(self.mapm.check_update) - def set_status_label(self, text): + def set_status_label(self, text: str): """ 创建提示 """ @@ -242,6 +249,19 @@ def enable_random(self): self.conf.set_value("Tianditu/random", False) self.subdomainComboBox.setEnabled(True) + def enable_key_random(self): + if self.checkBox_key_rand.isChecked(): + self.conf.set_value("Tianditu/random_key", True) + self.keyComboBox.setEnabled(False) + self.pushButton_copy.setEnabled(False) + self.pushButton_delete.setEnabled(False) + self.set_status_label("设置 key 为 随机") + else: + self.conf.set_value("Tianditu/random_key", False) + self.keyComboBox.setEnabled(True) + self.pushButton_copy.setEnabled(True) + self.pushButton_delete.setEnabled(True) + def closeEvent(self, event): # 在对话框关闭时触发的事件 self.mapm.update_map_enable_state() From 9aca09fe47f0966b7c306131f04bdc15df324f06 Mon Sep 17 00:00:00 2001 From: liuxsdev Date: Tue, 16 Jan 2024 11:38:49 +0800 Subject: [PATCH 6/6] Fix: extra map dont show --- run.py | 2 +- tianditu_tools/metadata.txt | 7 +++++-- tianditu_tools/widgets/AddMap/extra_map.py | 5 ++++- tianditu_tools/widgets/Setting/mapmanager.py | 16 +++++++--------- 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/run.py b/run.py index bc801b3..6c18fd5 100644 --- a/run.py +++ b/run.py @@ -8,7 +8,7 @@ cwd = Path.cwd() source_dir = cwd.joinpath("tianditu_tools") dist_dir = cwd.joinpath("dist") -dist_source_dir = dist_dir.joinpath("tianditu-tools") +dist_source_dir = dist_dir.joinpath("tianditu_tools") # Other necessary files other_files = ["README.md", "LICENSE"] diff --git a/tianditu_tools/metadata.txt b/tianditu_tools/metadata.txt index 1d71e22..5fd5bf3 100644 --- a/tianditu_tools/metadata.txt +++ b/tianditu_tools/metadata.txt @@ -3,17 +3,20 @@ name=TianDiTu Tools qgisMinimumVersion=3.4 description=天地图底图加载 about=QGIS 天地图工具,方便进行天地图瓦片底图的添加以及简单实现了部分天地图 Web 服务 API(地名搜索、地理编码查询、逆地理编码查询) -version=0.3.1 +version=0.4.0 tags=basemap, xyz, tianditu, geocoder, 天地图 icon=images/icon.png experimental=False deprecated=False author=liuxspro email=liuxspro@gmail.com -homepage=https://github.com/liuxsdev/qgis-plugin-tianditu +homepage=https://qgis-plugin-tianditu.liuxs.pro/ tracker=https://github.com/liuxsdev/qgis-plugin-tianditu/issues repository=https://github.com/liuxsdev/qgis-plugin-tianditu changelog= + Version 0.4.0 2024/01/16: + * ✨ 新增功能: 支持多个天地图key + * ✨ 新增功能: 地图管理和更新 Version 0.3.1 2023/11/17: * 🐛 修复3.34版本上无法加载地图 Version 0.3.0 2023/7/1: diff --git a/tianditu_tools/widgets/AddMap/extra_map.py b/tianditu_tools/widgets/AddMap/extra_map.py index a4b54e6..74f745c 100644 --- a/tianditu_tools/widgets/AddMap/extra_map.py +++ b/tianditu_tools/widgets/AddMap/extra_map.py @@ -46,7 +46,10 @@ def add_extra_map_menu(parent_menu: QMenu): maps = extra_maps.keys() extra_maps_status = conf.get_extra_maps_status() for map_name in maps: - if map_name in extra_maps_status["tianditu_province"]: + if ( + map_name in extra_maps_status["tianditu_province"] + or map_name in extra_maps_status["extra"] + ): map_data = extra_maps[map_name] sub_menu = extra_root_menu.addAction(icons["other"], map_name) sub_sub_menu = QMenu() diff --git a/tianditu_tools/widgets/Setting/mapmanager.py b/tianditu_tools/widgets/Setting/mapmanager.py index e916072..eeb7f2b 100644 --- a/tianditu_tools/widgets/Setting/mapmanager.py +++ b/tianditu_tools/widgets/Setting/mapmanager.py @@ -14,9 +14,9 @@ class MapManager(QTreeWidget): """ def __init__( - self, - map_folder: Path, - parent=None, + self, + map_folder: Path, + parent=None, ): super().__init__(parent) self.map_folder = map_folder @@ -24,7 +24,7 @@ def __init__( self.font.setFamily("微软雅黑") self.font.setPointSize(8) self.setFont(self.font) - self.update_host = "https://maps-tan-phi.vercel.app/dist/" + self.update_host = "https://maps.liuxs.pro/dist/" self.update_url = f"{self.update_host}summary.yml" self.conf = PluginConfig() # self.check_update() @@ -57,9 +57,7 @@ def get_summary(self): return load_yaml(summary_path) def get_map_id_by_name(self, name): - """ - 通过地图名称获取id - """ + """通过地图名称获取 id""" summary = self.get_summary() for item in summary.values(): if item["name"] == name: @@ -117,7 +115,7 @@ def download_map_conf(self, map_id): summary_data = got(self.update_url) if summary_data.ok: with open( - self.map_folder.joinpath("summary.yml"), "w", encoding="utf-8" + self.map_folder.joinpath("summary.yml"), "w", encoding="utf-8" ) as f: f.write(summary_data.text) conf_data = got(download_url) @@ -139,7 +137,6 @@ def check_update(self): def update_map_enable_state(self): top_level_item_count = self.topLevelItemCount() - checked_item = [] current_status = {} for i in range(top_level_item_count): top_level_item = self.topLevelItem(i) @@ -148,6 +145,7 @@ def update_map_enable_state(self): # 获取子项的数量 child_count = top_level_item.childCount() # 遍历子项 + checked_item = [] for j in range(child_count): child_item = top_level_item.child(j) if child_item.checkState(0) == 2: