| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278 |
- from qgis.PyQt import QtWidgets
- from qgis.PyQt.QtCore import QThread, pyqtSignal, QTimer
- from qgis.PyQt.QtGui import QClipboard
- from qgis.PyQt.QtWidgets import QApplication
- from .mapmanager import MapManager
- from ...ui.setting import Ui_SettingDialog
- from ...utils import (
- tianditu_map_url,
- check_url_status,
- check_subdomains,
- PluginConfig,
- PluginDir,
- )
- 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)
- def __init__(self, conf):
- super().__init__()
- self.conf = conf
- self.key = ""
- def run(self):
- url = tianditu_map_url("vec", self.key, "t0")
- tile_url = url.format(x=0, y=0, z=0)
- check_msg = check_url_status(tile_url)
- if check_msg["code"] == 0:
- self.check_finished.emit("正常")
- self.conf.set_value("Tianditu/keyisvalid", True)
- else:
- error_msg = f"{check_msg['msg']}: {check_msg['resolve']}"
- self.check_finished.emit(error_msg)
- self.conf.set_value("Tianditu/keyisvalid", False)
- class PingUrlThread(QThread):
- ping_finished = pyqtSignal(list)
- def __init__(self, key):
- super().__init__()
- self.key = key
- def run(self):
- subdomain_list = ["t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7"]
- urls = [
- tianditu_map_url("vec", self.key, subdomain) for subdomain in subdomain_list
- ]
- status = check_subdomains(urls)
- self.ping_finished.emit(status)
- class SettingDialog(QtWidgets.QDialog, Ui_SettingDialog):
- def __init__(self, toolbar):
- super().__init__()
- self.check_thread = None
- self.mapm = None
- 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.initUI()
- def initUI(self):
- self.init_keyCombo()
- # 如果key输入框是空白的,则禁用保存按钮
- if len(self.mLineEdit_key.text()) == 0:
- self.saveButton.setEnabled(False)
- # 给控件添加事件
- self.mLineEdit_key.textChanged.connect(self.on_key_LineEdit_changed)
- 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)
- # 是否启用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")
- )
- self.checkBox_domain_rand.stateChanged.connect(self.enable_random)
- # subdomian 设置
- self.subdomainComboBox.addItems(self.subdomain_list)
- self.subdomainComboBox.setCurrentIndex(
- self.subdomain_list.index(self.conf.get_value("Tianditu/subdomain"))
- )
- 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)
- #
- self.tabWidget.currentChanged.connect(self.adjust_tab_height)
- def adjust_tab_height(self):
- current_index = self.tabWidget.currentIndex()
- if current_index == 0:
- self.setFixedHeight(312)
- else:
- self.setFixedHeight(500) # 根据内容计算高度
- def set_status_label(self, text: str):
- """
- 创建提示
- """
- 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]
- return ""
- 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)
- for i in range(8):
- self.comboBox.setItemText(i, f"t{i} {status[i]}")
- self.comboBox.setItemText(min_index, f"t{min_index} {status[min_index]}*")
- def on_key_LineEdit_changed(self):
- current_text = self.mLineEdit_key.text()
- # 删除key中的空格以及非打印字符
- filtered_text = "".join(
- [c for c in current_text if c.isprintable() and not c.isspace()]
- )
- if filtered_text != current_text:
- self.mLineEdit_key.setText(filtered_text)
- # 检查key格式
- 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.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_domain_rand.isChecked():
- self.conf.set_value("Tianditu/random", True)
- self.subdomainComboBox.setEnabled(False)
- self.set_status_label("设置 subdomain 为 随机")
- else:
- 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()
- self.toolbar.add_button.setup_action()
- event.accept() # 接受关闭事件,关闭对话框
|