rm print
This commit is contained in:
parent
30ceccbd49
commit
4bb6417131
@ -1,4 +1,5 @@
|
||||
nuitka run.py --standalone --plugin-enable=qt-plugins --plugin-enable=numpy --show-progress --include-package=qgis --plugin-enable=pylint-warnings --output-dir=package --windows-disable-console --windows-icon-from-ico=logo.ico --no-pyi-file
|
||||
nuitka RSCDer.py --standalone --plugin-enable=qt-plugins --plugin-enable=numpy --show-progress --include-package=qgis --plugin-enable=pylint-warnings --output-dir=package --windows-disable-console --windows-icon-from-ico=logo.ico --no-pyi-file
|
||||
@REM nuitka keygen.py --standalone --plugin-enable=qt-plugins --plugin-enable=numpy --show-progress --include-package=qgis --plugin-enable=pylint-warnings --output-dir=package --windows-disable-console --windows-icon-from-ico=logo.ico --no-pyi-file
|
||||
|
||||
|
||||
REM Win7 with console
|
||||
|
BIN
icons/logo.png
Normal file
BIN
icons/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 997 B |
BIN
icons/splash.png
BIN
icons/splash.png
Binary file not shown.
Before Width: | Height: | Size: 93 KiB After Width: | Height: | Size: 699 KiB |
9
keygen.py
Normal file
9
keygen.py
Normal file
@ -0,0 +1,9 @@
|
||||
from rscder.gui.keygen import LicenseGen
|
||||
from PyQt5.QtWidgets import QApplication
|
||||
import sys
|
||||
|
||||
if __name__ == "__main__":
|
||||
app =QApplication(sys.argv)
|
||||
license = LicenseGen()
|
||||
license.show()
|
||||
sys.exit(app.exec_())
|
@ -1 +1 @@
|
||||
pGZJMmJtule8fwDCz4mnyHoQa7N6pl5GRdLqfoXREBqG4Xb1jbvgf7RmC8f1+sNpiCFSIt7NgvU362tKhB5UBXn/vUAadG1lOGC70dUhprGzBoqJN7VkAHkNGg0XjoE8H0SCVynr8To7ciwcnmK6HJXre6i+mBdTjACmKseTMlWp480XOt7uHysltORbTA3J
|
||||
IieXktda+1nRK9zLwe87uPPn2VpCwmUrEOPfyenaW/Sek70/CqqbCr7nangL1+pVXSkzDELia7Qq8e+pDMuHCXzxyJOALRj4j3bhFVExwqSTLuXwdev1e26nr7vnECl7H0SCVynr8To7ciwcnmK6HJXre6i+mBdTjACmKseTMlWp480XOt7uHysltORbTA3J
|
1
lic_t.lic
Normal file
1
lic_t.lic
Normal file
@ -0,0 +1 @@
|
||||
IieXktda+1nRK9zLwe87uPPn2VpCwmUrEOPfyenaW/Sek70/CqqbCr7nangL1+pVXSkzDELia7Qq8e+pDMuHCXzxyJOALRj4j3bhFVExwqSTLuXwdev1e26nr7vnECl7H0SCVynr8To7ciwcnmK6HJXre6i+mBdTjACmKseTMlWp480XOt7uHysltORbTA3J
|
BIN
logo.ico
BIN
logo.ico
Binary file not shown.
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
@ -63,6 +63,6 @@ class AboutPlugin(BasicPlugin):
|
||||
menu.addAction(action)
|
||||
|
||||
def on_about(self):
|
||||
print('on_about')
|
||||
# print('on_about')
|
||||
dialog = AboutDialog(self.ctx['mainwindow'])
|
||||
dialog.show()
|
@ -10,7 +10,7 @@ from rscder.gui.layercombox import LayerCombox
|
||||
from osgeo import gdal, gdal_array
|
||||
from threading import Thread
|
||||
import numpy as np
|
||||
|
||||
from basic_change.otsu import OTSU
|
||||
class MyDialog(QDialog):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
@ -154,7 +154,7 @@ class BasicMethod(BasicPlugin):
|
||||
|
||||
out_normal_tif = os.path.join(out, 'diff_0_255.tif')
|
||||
out_normal_ds = driver.Create(out_normal_tif, xsize, ysize, 1, gdal.GDT_Byte)
|
||||
|
||||
hist = np.zeros(256, dtype=np.int32)
|
||||
for j in range(yblocks):
|
||||
block_xy = (0, j * cell_size[1])
|
||||
block_size = (xsize, cell_size[1])
|
||||
@ -164,6 +164,12 @@ class BasicMethod(BasicPlugin):
|
||||
block_data = (block_data - min_diff) / (max_diff - min_diff) * 255
|
||||
block_data = block_data.astype(np.uint8)
|
||||
out_normal_ds.GetRasterBand(1).WriteArray(block_data, *block_xy)
|
||||
hist_t, _ = np.histogram(block_data, bins=256)
|
||||
hist += hist_t
|
||||
|
||||
self.gap = OTSU(hist)
|
||||
|
||||
self.message_send.emit('OTSU:' + str(self.gap))
|
||||
|
||||
out_normal_ds.FlushCache()
|
||||
del out_normal_ds
|
||||
@ -194,7 +200,7 @@ class BasicMethod(BasicPlugin):
|
||||
center_y = j * cell_size[1] + cell_size[1] // 2
|
||||
center_x = center_x * geo[1] + geo [0]
|
||||
center_y = center_y * geo[5] + geo [3]
|
||||
f.write(f'{center_x},{center_y},{block_data_xy.mean() / 255},1\n')
|
||||
f.write(f'{center_x},{center_y},{block_data_xy.mean() / 255 * 100},1\n')
|
||||
|
||||
|
||||
self.result_ok.emit({
|
||||
|
1
plugins/export_to/__init__.py
Normal file
1
plugins/export_to/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
from export_to.main import *
|
100
plugins/export_to/main.py
Normal file
100
plugins/export_to/main.py
Normal file
@ -0,0 +1,100 @@
|
||||
import shutil
|
||||
from rscder.utils.project import Project, PairLayer, ResultLayer
|
||||
from rscder.plugins.basic import BasicPlugin
|
||||
from PyQt5.QtWidgets import QDialog, QHBoxLayout, QFileDialog, QComboBox, QVBoxLayout, QPushButton, QLabel, QLineEdit, QAction
|
||||
from PyQt5.QtGui import QIcon
|
||||
class ExportDialog(QDialog):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
|
||||
self.setWindowTitle('Export')
|
||||
self.setWindowIcon(QIcon(":/icons/logo.png"))
|
||||
|
||||
self.out_path = None
|
||||
self.result_layer = None
|
||||
|
||||
result_layer_select_label = QLabel('选择结果:')
|
||||
|
||||
result_layer_select = QComboBox(self)
|
||||
|
||||
result_layer_select.addItem('---', None)
|
||||
for layer in Project().layers.values():
|
||||
for result_layer in layer.results:
|
||||
if result_layer.layer_type == ResultLayer.POINT:
|
||||
result_layer_select.addItem( layer.name[5:] + '-' + result_layer.name, result_layer)
|
||||
|
||||
for i in range(result_layer_select.count() - 1):
|
||||
result_layer_select.setItemIcon(i + 1, QIcon(":/icons/layer.png"))
|
||||
|
||||
|
||||
def on_result_layer_select(index):
|
||||
self.result_layer = result_layer_select.currentData()
|
||||
|
||||
result_layer_select.currentIndexChanged.connect(on_result_layer_select)
|
||||
|
||||
out_path_label = QLabel('输出路径:')
|
||||
out_path_text = QLineEdit(self)
|
||||
out_path_text.setReadOnly(True)
|
||||
out_path_text.setPlaceholderText('选择输出路径')
|
||||
|
||||
def on_out_path_btn():
|
||||
select_file = QFileDialog.getSaveFileName(self, '选择输出路径', '', '*.txt')
|
||||
if select_file[0]:
|
||||
out_path_text.setText(select_file[0])
|
||||
self.out_path = select_file[0]
|
||||
out_path_btn = QPushButton('...', self)
|
||||
out_path_btn.clicked.connect(on_out_path_btn)
|
||||
|
||||
ok_btn = QPushButton('OK', self)
|
||||
ok_btn.clicked.connect(self.accept)
|
||||
cancel_btn = QPushButton('Cancel', self)
|
||||
cancel_btn.clicked.connect(self.reject)
|
||||
|
||||
|
||||
hbox1 = QHBoxLayout()
|
||||
hbox1.addWidget(result_layer_select_label)
|
||||
hbox1.addWidget(result_layer_select)
|
||||
|
||||
hbox2 = QHBoxLayout()
|
||||
hbox2.addWidget(out_path_label)
|
||||
hbox2.addWidget(out_path_text)
|
||||
hbox2.addWidget(out_path_btn)
|
||||
|
||||
hbox3 = QHBoxLayout()
|
||||
hbox3.addWidget(ok_btn)
|
||||
hbox3.addWidget(cancel_btn)
|
||||
|
||||
vbox = QVBoxLayout()
|
||||
vbox.addLayout(hbox1)
|
||||
vbox.addLayout(hbox2)
|
||||
vbox.addLayout(hbox3)
|
||||
|
||||
self.setLayout(vbox)
|
||||
|
||||
class ExportPlugin(BasicPlugin):
|
||||
|
||||
@staticmethod
|
||||
def info():
|
||||
return {
|
||||
'name': 'Export',
|
||||
'description': 'Export to other format',
|
||||
'author': 'RSCDER',
|
||||
}
|
||||
|
||||
def set_action(self):
|
||||
self.export_txt = QAction(QIcon(":/icons/document.png"), '导出为 Arcgis 兼容的TXT', self.mainwindow)
|
||||
self.export_txt.triggered.connect(self.export_txt_action)
|
||||
|
||||
self.ctx['postop_menu'].addAction(self.export_txt)
|
||||
|
||||
self.ctx['toolbar'].addAction(self.export_txt)
|
||||
|
||||
def export_txt_action(self):
|
||||
dialog = ExportDialog(self.mainwindow)
|
||||
if dialog.exec_():
|
||||
result = dialog.result_layer
|
||||
out = dialog.out_path
|
||||
if result:
|
||||
shutil.copy(result.path, out)
|
||||
self.message_box.info('导出成功')
|
@ -3,12 +3,19 @@
|
||||
enabled: true
|
||||
module: about
|
||||
name: "\u5173\u4E8E"
|
||||
path: ./plugin-build\about
|
||||
path: ./plugin\about
|
||||
version: 1.0.0
|
||||
- author: RSCDER
|
||||
description: BasicMethod
|
||||
enabled: true
|
||||
module: basic_change
|
||||
name: BasicMethod
|
||||
path: ./plugin-build\basic_change
|
||||
path: ./plugin\basic_change
|
||||
version: 1.0.0
|
||||
- author: RSCDER
|
||||
description: ExportTo
|
||||
enabled: true
|
||||
module: export_to
|
||||
name: ExportTo
|
||||
path: ./plugin\export_to
|
||||
version: 1.0.0
|
2
res.qrc
2
res.qrc
@ -28,7 +28,7 @@
|
||||
<file>icons\zoom_out.png</file>
|
||||
<file>icons\zoom_to.png</file>
|
||||
<file>icons\load.svg</file>
|
||||
<file>icons\logo.svg</file>
|
||||
<file>icons\logo.png</file>
|
||||
<file>icons\model.svg</file>
|
||||
<file>icons\ok.svg</file>
|
||||
<file>icons\outline.svg</file>
|
||||
|
83
rscder/gui/keygen.py
Normal file
83
rscder/gui/keygen.py
Normal file
@ -0,0 +1,83 @@
|
||||
from PyQt5.QtWidgets import QDialog, QLineEdit, QDateTimeEdit, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QTextEdit, QFileDialog, QMessageBox
|
||||
from PyQt5 import QtCore
|
||||
from PyQt5.QtGui import QIcon
|
||||
|
||||
from rscder.utils.license import LicenseHelper
|
||||
import re
|
||||
class LicenseGen(QDialog):
|
||||
|
||||
def __init__(self, parent = None, flags = QtCore.Qt.WindowFlags() ) -> None:
|
||||
super().__init__(parent, flags)
|
||||
|
||||
self.setWindowTitle("License Generator")
|
||||
self.setWindowIcon(QIcon(':/icons/logo.png'))
|
||||
|
||||
mac_address_label = QLabel("MAC Address:")
|
||||
self.mac_address_text = QLineEdit()
|
||||
|
||||
hbox1 = QHBoxLayout()
|
||||
hbox1.addWidget(mac_address_label)
|
||||
hbox1.addWidget(self.mac_address_text)
|
||||
|
||||
end_date_label = QLabel("End Date:")
|
||||
self.end_date_text = QDateTimeEdit()
|
||||
|
||||
hbox2 = QHBoxLayout()
|
||||
hbox2.addWidget(end_date_label)
|
||||
hbox2.addWidget(self.end_date_text)
|
||||
|
||||
|
||||
self.license_file_path_text = QLineEdit()
|
||||
self.license_file_path_text.setReadOnly(True)
|
||||
|
||||
btn_open = QPushButton("Open")
|
||||
btn_open.clicked.connect(self.open_file)
|
||||
|
||||
hbox3 = QHBoxLayout()
|
||||
hbox3.addWidget(btn_open)
|
||||
hbox3.addWidget(self.license_file_path_text)
|
||||
# hbox3.addWidget(btn_open)
|
||||
|
||||
|
||||
self.btn_generate = QPushButton("Generate")
|
||||
self.btn_generate.clicked.connect(self.generate_license)
|
||||
|
||||
self.btn_cancel = QPushButton("Cancel")
|
||||
self.btn_cancel.clicked.connect(self.reject)
|
||||
|
||||
hbox4 = QHBoxLayout()
|
||||
hbox4.addWidget(self.btn_generate, alignment = QtCore.Qt.AlignRight, stretch= 0)
|
||||
hbox4.addWidget(self.btn_cancel, alignment = QtCore.Qt.AlignRight, stretch= 0)
|
||||
|
||||
vbox = QVBoxLayout()
|
||||
vbox.addLayout(hbox1)
|
||||
vbox.addLayout(hbox2)
|
||||
vbox.addLayout(hbox3)
|
||||
vbox.addLayout(hbox4)
|
||||
|
||||
self.setLayout(vbox)
|
||||
|
||||
def open_file(self) -> None:
|
||||
file_path, _ = QFileDialog.getSaveFileName(self, "Save License File", "", "License Files (*.lic)")
|
||||
if file_path:
|
||||
self.license_file_path_text.setText(file_path)
|
||||
|
||||
def isValidMac(self,mac):
|
||||
if re.match(r"^\s*([0-9a-fA-F]{2,2}:){5,5}[0-9a-fA-F]{2,2}\s*$", mac):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def generate_license(self) -> None:
|
||||
if self.mac_address_text.text() and self.license_file_path_text.text() and \
|
||||
self.end_date_text.dateTime().isValid():
|
||||
if not self.isValidMac(self.mac_address_text.text()):
|
||||
QMessageBox.warning(self, "Warning", "Invalid MAC Address")
|
||||
|
||||
end_date = self.end_date_text.dateTime().toPyDateTime().strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
lic = LicenseHelper().generate_license(end_date, self.mac_address_text.text())
|
||||
with open(self.license_file_path_text.text(), 'w') as f:
|
||||
f.write(lic[::-1])
|
||||
|
||||
QMessageBox.information(self, "Information", "License Generated")
|
@ -1,8 +1,9 @@
|
||||
|
||||
import logging
|
||||
import pdb
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
from PyQt5.QtCore import Qt,QModelIndex
|
||||
from PyQt5.QtGui import QStandardItemModel, QStandardItem, QCursor
|
||||
from PyQt5.QtGui import QStandardItemModel, QStandardItem, QCursor, QIcon
|
||||
from PyQt5.QtWidgets import (QTreeView, QTreeWidgetItem, QAbstractItemView, QHeaderView, QStyleFactory)
|
||||
from rscder.gui.actions import get_action_manager
|
||||
|
||||
@ -18,6 +19,7 @@ class LayerTree(QtWidgets.QWidget):
|
||||
GRID = 3
|
||||
|
||||
tree_changed = QtCore.pyqtSignal(str)
|
||||
zoom_to_layer_signal = QtCore.pyqtSignal(str)
|
||||
result_clicked = QtCore.pyqtSignal(str, int)
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
@ -52,6 +54,7 @@ class LayerTree(QtWidgets.QWidget):
|
||||
self.setLayout(layout)
|
||||
self.setLayoutDirection(Qt.LeftToRight)
|
||||
self.is_in_add_layer = False
|
||||
self.current_item = None
|
||||
|
||||
def onItemClicked(self, item:QtWidgets.QTreeWidgetItem, column):
|
||||
if item == self.root:
|
||||
@ -153,7 +156,7 @@ class LayerTree(QtWidgets.QWidget):
|
||||
if item_root.data(0, Qt.UserRole + 1) == layer.id:
|
||||
layer_root = item_root
|
||||
break
|
||||
print(layer_root.text(0))
|
||||
logging.info(layer_root.text(0))
|
||||
if layer_root is None:
|
||||
self.add_layer(layer.id)
|
||||
return
|
||||
@ -172,37 +175,71 @@ class LayerTree(QtWidgets.QWidget):
|
||||
self.root.setText(0,'图层')
|
||||
self.tree.addTopLevelItem(self.root)
|
||||
|
||||
def delete_layer(self):
|
||||
item = self.current_item
|
||||
if item is None:
|
||||
return
|
||||
if item == self.root:
|
||||
return
|
||||
root = item
|
||||
if item.data(0, Qt.UserRole) != LayerTree.LAYER_TOOT:
|
||||
root = item.parent()
|
||||
|
||||
if item.data(0, Qt.UserRole) == LayerTree.LAYER_TOOT:
|
||||
self.root.takeChild(self.root.indexOfChild(item))
|
||||
del Project().layers[root.data(0, Qt.UserRole + 1)]
|
||||
elif item.data(0, Qt.UserRole) == LayerTree.SUB_RASTER:
|
||||
return
|
||||
elif item.data(0, Qt.UserRole) == LayerTree.GRID:
|
||||
return
|
||||
elif item.data(0, Qt.UserRole) == LayerTree.RESULT:
|
||||
root.takeChild(root.indexOfChild(item))
|
||||
del Project().layers[root.data(0, Qt.UserRole + 1)].results[item.data(0, Qt.UserRole + 1)]
|
||||
self.update_layer(root.data(0, Qt.UserRole + 1))
|
||||
self.tree_changed.emit(root.data(0, Qt.UserRole + 1))
|
||||
|
||||
def zoom_to_layer(self):
|
||||
item = self.current_item
|
||||
if item is None:
|
||||
return
|
||||
if item == self.root:
|
||||
return
|
||||
root = item
|
||||
if item.data(0, Qt.UserRole) != LayerTree.LAYER_TOOT:
|
||||
root = item.parent()
|
||||
|
||||
self.zoom_to_layer_signal.emit(root.data(0, Qt.UserRole + 1))
|
||||
|
||||
|
||||
def right_menu_show(self, position):
|
||||
rightMenu = QtWidgets.QMenu(self)
|
||||
# QAction = QtWidgets.QAction(self.menuBar1)
|
||||
item = self.tree.itemAt(position)
|
||||
|
||||
self.current_item = item
|
||||
action_manager = get_action_manager()
|
||||
actions = []
|
||||
data_load_action = action_manager.get_action('&数据加载', 'File')
|
||||
actions.append(data_load_action)
|
||||
zoom_to_action = QtWidgets.QAction(QIcon(':/icons/full.svg'), '&缩放至该图层', self)
|
||||
del_action = QtWidgets.QAction(QIcon(':/icons/delete.png'), '&删除该图层', self)
|
||||
zoom_to_action.triggered.connect(self.zoom_to_layer)
|
||||
del_action.triggered.connect(self.delete_layer)
|
||||
if item is None:
|
||||
print('nothing')
|
||||
logging.info('nothing')
|
||||
else:
|
||||
if item == self.root:
|
||||
pass
|
||||
elif item.data(0, Qt.UserRole) == LayerTree.LAYER_TOOT:
|
||||
actions.append(QtWidgets.QAction('&缩放至该图层', self))
|
||||
|
||||
actions.append(zoom_to_action)
|
||||
actions.append(QtWidgets.QAction('&重命名', self))
|
||||
actions.append(QtWidgets.QAction('&删除', self))
|
||||
actions.append(del_action)
|
||||
elif item.data(0, Qt.UserRole) == LayerTree.SUB_RASTER:
|
||||
actions.append(QtWidgets.QAction('&缩放至该图层', self))
|
||||
|
||||
actions.append(zoom_to_action)
|
||||
actions.append(QtWidgets.QAction('&重命名', self))
|
||||
actions.append(QtWidgets.QAction('&删除', self))
|
||||
elif item.data(0, Qt.UserRole) == LayerTree.RESULT:
|
||||
actions.append(QtWidgets.QAction('&缩放至该图层', self))
|
||||
|
||||
actions.append(zoom_to_action)
|
||||
actions.append(QtWidgets.QAction('&重命名', self))
|
||||
actions.append(QtWidgets.QAction('&导出', self))
|
||||
actions.append(QtWidgets.QAction('&删除', self))
|
||||
|
||||
actions.append(del_action)
|
||||
|
||||
|
||||
for action in actions:
|
||||
|
@ -11,7 +11,7 @@ class License(QtWidgets.QDialog):
|
||||
def __init__(self, parent = None, flags = QtCore.Qt.WindowFlags() ) -> None:
|
||||
super().__init__(parent, flags)
|
||||
self.setWindowTitle("License")
|
||||
self.setWindowIcon(QIcon(':/icons/license.png'))
|
||||
self.setWindowIcon(QIcon(':/icons/logo.png'))
|
||||
self.setWindowFlags(QtCore.Qt.WindowCloseButtonHint)
|
||||
self.setFixedSize(600, 400)
|
||||
|
||||
|
@ -37,6 +37,7 @@ class MainWindow(QMainWindow):
|
||||
self.layer_tree.result_clicked.connect(self.result_box.on_result)
|
||||
self.result_box.on_item_click.connect(self.double_map.zoom_to_result)
|
||||
self.result_box.on_item_changed.connect(Project().change_result)
|
||||
self.layer_tree.zoom_to_layer_signal.connect(self.double_map.zoom_to_layer)
|
||||
|
||||
self.action_manager = ActionManager(
|
||||
self.double_map,
|
||||
|
@ -1,6 +1,7 @@
|
||||
|
||||
# from alg.utils import random_color
|
||||
# from mul.mulgrubcut import GrabCut
|
||||
import logging
|
||||
import multiprocessing
|
||||
# from alg.grubcut import grubcut
|
||||
# from gui.layerselect import LayerSelect
|
||||
@ -82,24 +83,27 @@ class DoubleCanvas(QWidget):
|
||||
zoom_out.triggered.connect( self.set_zoom_out)
|
||||
|
||||
def set_pan_tool(self, s):
|
||||
print('set pan tool')
|
||||
# print('set pan tool')
|
||||
if s:
|
||||
self.mapcanva1.setMapTool(QgsMapToolPan(self.mapcanva1))
|
||||
self.mapcanva2.setMapTool(QgsMapToolPan(self.mapcanva2))
|
||||
|
||||
def set_zoom_in(self, s):
|
||||
print('set zoom in')
|
||||
# print('set zoom in')
|
||||
if s:
|
||||
self.mapcanva1.setMapTool(QgsMapToolZoom(self.mapcanva1, False))
|
||||
self.mapcanva2.setMapTool(QgsMapToolZoom(self.mapcanva2, False))
|
||||
|
||||
def set_zoom_out(self, s):
|
||||
print('set zoom out')
|
||||
# print('set zoom out')
|
||||
if s:
|
||||
self.mapcanva1.setMapTool(QgsMapToolZoom(self.mapcanva1, True))
|
||||
self.mapcanva2.setMapTool(QgsMapToolZoom(self.mapcanva2, True))
|
||||
|
||||
def add_layer(self, layer:str):
|
||||
if not layer in Project().layers:
|
||||
self.clear()
|
||||
return
|
||||
layer:PairLayer = Project().layers[layer]
|
||||
if not layer.enable:
|
||||
return
|
||||
@ -210,430 +214,3 @@ class CanvasWidget(QgsMapCanvas):
|
||||
return self.update_coordinates_text.emit("X: {:.5f}, Y: {:.5f}".format(pt.x(), pt.y()))
|
||||
self.xyCoordinates.connect(coordinates2text)
|
||||
self.scaleChanged.connect(lambda _ : self.update_scale_text.emit("1 : {:.3f}".format(self.scale())))
|
||||
|
||||
self.total_f = 0
|
||||
self.start_extract = False
|
||||
self.label_pal = None
|
||||
# self.result_layers = []
|
||||
|
||||
def dragEnterEvent(self, e:QDragEnterEvent) -> None:
|
||||
'''
|
||||
Can drag
|
||||
'''
|
||||
candidates = [".tif", ".tiff", ".jpg", ".jpeg", ".bmp", ".png"]
|
||||
|
||||
if e.mimeData().hasUrls():
|
||||
if Path(e.mimeData().urls()[0].toLocalFile()).suffix in candidates:
|
||||
e.accept()
|
||||
return
|
||||
|
||||
e.ignore()
|
||||
|
||||
def dropEvent(self, e:QDropEvent) -> None:
|
||||
'''
|
||||
Drop image to the canvas
|
||||
'''
|
||||
url_path = e.mimeData().urls()[0]
|
||||
image_path = QUrl(url_path).toLocalFile()
|
||||
self.load_image(image_path)
|
||||
|
||||
def load_image(self, path) -> None:
|
||||
if not Path(path).exists():
|
||||
return
|
||||
|
||||
raster_layer = QgsRasterLayer(path, Path(path).name)
|
||||
if not raster_layer.isValid():
|
||||
print("栅格图层加载失败!")
|
||||
raster_layer.file_path = path
|
||||
|
||||
# self.layers.insert(0, raster_layer)
|
||||
# self.layers.insert(0, vector_layer)
|
||||
# if self.current_raster_layer:
|
||||
# del self.current_raster_layer
|
||||
# if self.current_vector_layer:
|
||||
# del self.current_vector_layer
|
||||
|
||||
QgsProject.instance().addMapLayer(raster_layer)
|
||||
self.current_raster_layer = raster_layer
|
||||
# self.current_vector_layer = vector_layer
|
||||
self.setExtent(raster_layer.extent())
|
||||
# self.setLayers([vector_layer, raster_layer])
|
||||
self.zoomToFeatureExtent(raster_layer.extent())
|
||||
self.have_current_image.emit(True)
|
||||
|
||||
def load_result_from_txt(self, path) -> None:
|
||||
if not Path(path).exists():
|
||||
return
|
||||
# vector_layer = QgsVectorLayer("Polygon?field=category:string(20)&field=confidence:double", Path(path).name, "memory")
|
||||
vector_layer = QgsVectorLayer("Polygon?field=category:string(20)&field=confidence:double&field=renderkey:string(32)&field=isman:boolean&field=isauto:boolean&field=label:string(64)", Path(path).name + ' outline', "memory")
|
||||
|
||||
if not vector_layer.isValid():
|
||||
print("矢量图层加载失败!")
|
||||
vector_layer.setLabelsEnabled(True)
|
||||
lyr = QgsPalLayerSettings()
|
||||
lyr.enabled = True
|
||||
lyr.fieldName = 'label' # default in data sources
|
||||
# lyr.textFont = self._TestFont
|
||||
lyr.textNamedStyle = 'Medium'
|
||||
text_format = QgsTextFormat()
|
||||
text_format.color = QColor('#ffffff')
|
||||
text_format.background().color = QColor('#000000')
|
||||
text_format.buffer().setEnabled(True)
|
||||
text_format.buffer().setSize(1)
|
||||
text_format.buffer().setOpacity(0.5)
|
||||
lyr.setFormat(text_format)
|
||||
self.label_pal = lyr
|
||||
root = QgsRuleBasedLabeling.Rule(QgsPalLayerSettings())
|
||||
rule = QgsRuleBasedLabeling.Rule(lyr)
|
||||
rule.setDescription('label')
|
||||
root.appendChild(rule)
|
||||
#Apply label configuration
|
||||
rules = QgsRuleBasedLabeling(root)
|
||||
vector_layer.setLabeling(rules)
|
||||
vector_layer.triggerRepaint()
|
||||
# lyr.writeToLayer(vector_layer)
|
||||
vector_layer.setRenderer(self.__get_categorical_renderer("renderkey"))
|
||||
QgsProject.instance().addMapLayer(vector_layer)
|
||||
self.current_vector_layer = vector_layer
|
||||
# provider = self.current_vector_layer.dataProvider()
|
||||
# provider.truncate()
|
||||
self.current_vector_layer.startEditing()
|
||||
# objects = []
|
||||
features = []
|
||||
with open(path) as f:
|
||||
for line in f.readlines():
|
||||
item_data = line.split("\n")[0].split(" ")
|
||||
if len(item_data) == 1 + 4 * 2:
|
||||
cls_name = item_data[0]
|
||||
item_data[2] = -1.0 * float(item_data[2])
|
||||
item_data[4] = -1.0 * float(item_data[4])
|
||||
item_data[6] = -1.0 * float(item_data[6])
|
||||
item_data[8] = -1.0 * float(item_data[8])
|
||||
wkt = "POLYGON (({} {}, {} {}, {} {}, {} {}))".format(*item_data[1:])
|
||||
conf = 1.0
|
||||
else:
|
||||
cls_name = item_data[8]
|
||||
# print(cls_name)
|
||||
# print(cls_name[0])
|
||||
# print(cls_name[0].isalpha())
|
||||
if cls_name[0].isalpha():
|
||||
item_data[1] = -1.0 * float(item_data[1])
|
||||
item_data[3] = -1.0 * float(item_data[3])
|
||||
item_data[5] = -1.0 * float(item_data[5])
|
||||
item_data[7] = -1.0 * float(item_data[7])
|
||||
conf = 1.0
|
||||
wkt = "POLYGON (({} {}, {} {}, {} {}, {} {}))".format(*item_data[:8])
|
||||
else:
|
||||
cls_name = item_data[0]
|
||||
conf = float(item_data[1])
|
||||
item_data[3] = -1.0 * float(item_data[3])
|
||||
item_data[5] = -1.0 * float(item_data[5])
|
||||
item_data[7] = -1.0 * float(item_data[7])
|
||||
item_data[9] = -1.0 * float(item_data[9])
|
||||
wkt = "POLYGON (({} {}, {} {}, {} {}, {} {}))".format(*item_data[2:])
|
||||
|
||||
feat = QgsFeature(self.current_vector_layer.fields())
|
||||
feat.setGeometry(QgsGeometry.fromWkt(wkt))
|
||||
feat.setAttribute('category', cls_name)
|
||||
feat.setAttribute('confidence', conf)
|
||||
feat.setAttribute('renderkey', cls_name)
|
||||
feat.setAttribute('isman', False)
|
||||
feat.setAttribute('isauto', True)
|
||||
feat.setAttribute('label', f'{ cls_name},{conf:.3f}')
|
||||
features.append(feat)
|
||||
# objects.append({
|
||||
# "category": item_data[0],
|
||||
# "confidence": item_data[1],
|
||||
# "fid": feat.id()
|
||||
# })
|
||||
self.current_vector_layer.addFeatures(features)
|
||||
self.current_vector_layer.commitChanges()
|
||||
self.have_current_vector.emit(True)
|
||||
self.layer_update()
|
||||
|
||||
def clear_vector(self):
|
||||
if self.current_vector_layer is not None:
|
||||
provider = self.current_vector_layer.dataProvider()
|
||||
provider.truncate()
|
||||
self.layer_update()
|
||||
|
||||
def change_current_vector_layer(self, vector_layer):
|
||||
if self.current_vector_layer is not None:
|
||||
self.current_vector_layer.removeSelection()
|
||||
self.current_vector_layer = vector_layer
|
||||
|
||||
self.layer_update()
|
||||
|
||||
def layer_update(self):
|
||||
if self.current_vector_layer is None:
|
||||
self.object_updated.emit([])
|
||||
return
|
||||
self.current_vector_layer.updateExtents()
|
||||
self.refresh()
|
||||
objects = []
|
||||
for feature in self.current_vector_layer.getFeatures():
|
||||
objects.append({
|
||||
"category": feature['category'],
|
||||
"confidence": feature['confidence'],
|
||||
"renderkey": feature['renderkey'],
|
||||
'isman': feature['isman'],
|
||||
'isauto': feature['isauto'],
|
||||
"fid": feature.id()
|
||||
})
|
||||
self.object_updated.emit(objects)
|
||||
|
||||
def selectd_changed(self, items:list):
|
||||
if len(items) == 0:
|
||||
self.current_vector_layer.removeSelection()
|
||||
else:
|
||||
self.current_vector_layer.selectByIds(list(item['fid'] for item in items))
|
||||
|
||||
def item_change(self, items:list):
|
||||
self.current_vector_layer.startEditing()
|
||||
features = list(self.current_vector_layer.getFeatures())
|
||||
for f in features:
|
||||
has_f = False
|
||||
for item in items:
|
||||
if f.id() == item['fid']:
|
||||
# f = QgsFeature(f)
|
||||
has_f = True
|
||||
f.setAttribute('category', item['category'])
|
||||
f.setAttribute('confidence', item['confidence'])
|
||||
f.setAttribute('renderkey', item['renderkey'])
|
||||
f.setAttribute('isman', item['isman'])
|
||||
f.setAttribute('isauto', item['isauto'])
|
||||
self.current_vector_layer.updateFeature(f)
|
||||
break
|
||||
if has_f:
|
||||
continue
|
||||
|
||||
self.current_vector_layer.deleteFeature(f.id())
|
||||
|
||||
self.current_vector_layer.commitChanges()
|
||||
self.current_vector_layer.updateExtents()
|
||||
# print(self.current_vector_layer.fields())
|
||||
|
||||
self.refresh()
|
||||
|
||||
def zoom_to_full_extent(self) -> None:
|
||||
if self.current_raster_layer:
|
||||
self.zoomToFeatureExtent(self.current_raster_layer.extent())
|
||||
|
||||
def __get_categorical_renderer(self, fieldname:str) -> QgsCategorizedSymbolRenderer:
|
||||
settings = QSettings(self)
|
||||
|
||||
category_keys = settings.value("keys", get_default_category_keys())
|
||||
category_colors = settings.value("colors", get_default_category_colors())
|
||||
|
||||
settings.beginGroup("Category")
|
||||
if len(category_colors) < len(category_keys):
|
||||
for _ in range(len(category_keys) - len(category_colors)):
|
||||
category_colors.append(random_color())
|
||||
settings.setValue('colors', category_colors)
|
||||
settings.endGroup()
|
||||
categorized_renderer = QgsCategorizedSymbolRenderer()
|
||||
for key, color in zip(category_keys, category_colors):
|
||||
fill_color = QColor(color)
|
||||
fill_color.setAlphaF(0.3)
|
||||
categorized_renderer.addCategory(\
|
||||
QgsRendererCategory(
|
||||
key,
|
||||
QgsFillSymbol.createSimple(
|
||||
{"color":fill_color.name(QColor.HexArgb),"outline_color":color, "outline_width":"1"}), ''))
|
||||
categorized_renderer.setClassAttribute(fieldname)
|
||||
return categorized_renderer
|
||||
|
||||
def export_to_raster(self, path) -> None:
|
||||
if self.current_vector_layer is None:
|
||||
return
|
||||
|
||||
def load_extract_result(self, res):
|
||||
r = self.current_raster_layer
|
||||
vector_layer = QgsVectorLayer("Polygon?field=category:string(20)&field=confidence:double&field=renderkey:string(32)&field=isman:boolean&field=isauto:boolean", Path(r.file_path).name + ' outline', "memory")
|
||||
# vector_layer = QgsVectorLayer(tempfile)
|
||||
if not vector_layer.isValid():
|
||||
print("矢量图层加载失败!")
|
||||
|
||||
vector_layer.setRenderer(self.__get_categorical_renderer("renderkey"))
|
||||
lyr = QgsPalLayerSettings()
|
||||
lyr.enabled = True
|
||||
lyr.fieldName = 'label' # default in data sources
|
||||
# lyr.textFont = self._TestFont
|
||||
lyr.textNamedStyle = 'Medium'
|
||||
text_format = QgsTextFormat()
|
||||
text_format.color = QColor('#ffffff')
|
||||
text_format.background().color = QColor('#000000')
|
||||
text_format.buffer().setEnabled(True)
|
||||
text_format.buffer().setSize(1)
|
||||
text_format.buffer().setOpacity(0.5)
|
||||
lyr.setFormat(text_format)
|
||||
self.label_pal = lyr
|
||||
root = QgsRuleBasedLabeling.Rule(QgsPalLayerSettings())
|
||||
rule = QgsRuleBasedLabeling.Rule(lyr)
|
||||
rule.setDescription('label')
|
||||
root.appendChild(rule)
|
||||
#Apply label configuration
|
||||
rules = QgsRuleBasedLabeling(root)
|
||||
vector_layer.setLabeling(rules)
|
||||
vector_layer.triggerRepaint()
|
||||
vector_layer.startEditing()
|
||||
features = []
|
||||
for f in res:
|
||||
pts = f[0]
|
||||
prop = f[1]
|
||||
# pts = grubcut(img_path, pts, False, True, False )
|
||||
pts = list( f'{p[0]} {p[1]}' for p in pts )
|
||||
wkt = f'POLYGON (( {",".join(pts)} ))'
|
||||
# geometry = QgsGeometry.fromWkt(wkt)
|
||||
feat = QgsFeature(vector_layer.fields())
|
||||
feat.setGeometry(QgsGeometry.fromWkt(wkt))
|
||||
feat.setAttribute('category', prop['category'])
|
||||
feat.setAttribute('confidence', prop['confidence'])
|
||||
feat.setAttribute('renderkey', prop['category'])
|
||||
feat.setAttribute('isman', False)
|
||||
feat.setAttribute('isauto', True)
|
||||
features.append(feat)
|
||||
|
||||
vector_layer.addFeatures(features)
|
||||
vector_layer.commitChanges()
|
||||
QgsProject.instance().addMapLayer(vector_layer)
|
||||
self.process_end.emit()
|
||||
r.has_extract = True
|
||||
self.start_extract = False
|
||||
r.extract_layer = vector_layer
|
||||
self.layer_update()
|
||||
|
||||
def run_thread(self, conn, pp):
|
||||
all_ok = False
|
||||
# print(pp.is_alive)
|
||||
while pp.is_alive:
|
||||
r = conn.recv()
|
||||
# print(r)
|
||||
if all_ok:
|
||||
self.extract_end.emit(r)
|
||||
break
|
||||
if int(r) == self.total_f - 1:
|
||||
all_ok = True
|
||||
self.process_update.emit(r)
|
||||
# print(conn.recv())
|
||||
def grubcut(self, v, r):
|
||||
# for f in v.getFeatures():
|
||||
if self.start_extract:
|
||||
return
|
||||
self.current_raster_layer = r
|
||||
img_path = r.file_path
|
||||
if getattr(r, 'has_extract', False):
|
||||
vector_layer = r.extract_layer
|
||||
try:
|
||||
QgsProject.instance().removeMapLayer(vector_layer)
|
||||
except:
|
||||
pass
|
||||
|
||||
# self.current_vector_layer = vector_layer
|
||||
features = []
|
||||
points = []
|
||||
for f in v.getFeatures():
|
||||
pts = f.geometry().vertices()
|
||||
pts = list([ vr.x(), vr.y() ] for vr in pts)
|
||||
points.append(pts)
|
||||
features.append({
|
||||
'category': f['category'],
|
||||
'confidence': f['confidence']
|
||||
})
|
||||
self.total_f = len(points)
|
||||
self.start_extract = True
|
||||
self.process_start.emit([0, self.total_f])
|
||||
parent_conn, child_conn = multiprocessing.Pipe()
|
||||
t = GrabCut(child_conn, img_path, points, features)
|
||||
p = threading.Thread(target=self.run_thread, args=(parent_conn,t))
|
||||
t.start()
|
||||
p.start()
|
||||
|
||||
def export_to(self, path, filter_name) -> None:
|
||||
if filter_name == 'Shp (*.shp)':
|
||||
if self.current_vector_layer is None:
|
||||
return
|
||||
ls = LayerSelect(self)
|
||||
ls.show()
|
||||
ls.exec()
|
||||
if ls.result() == LayerSelect.OK:
|
||||
save_options = QgsVectorFileWriter.SaveVectorOptions()
|
||||
save_options.driverName = "ESRI Shapefile"
|
||||
save_options.fileEncoding = "UTF-8"
|
||||
transform_context = QgsProject.instance().transformContext()
|
||||
error = QgsVectorFileWriter.writeAsVectorFormatV2(ls.value,
|
||||
path,
|
||||
transform_context,
|
||||
save_options)
|
||||
if error[0] == QgsVectorFileWriter.NoError:
|
||||
print("又成功了!")
|
||||
else:
|
||||
print(error)
|
||||
|
||||
if filter_name == 'JPEG Images(*.jpg)':
|
||||
file_name = path + '.tif'
|
||||
extent = self.current_raster_layer.extent()
|
||||
width, height = self.current_raster_layer.width(), self.current_raster_layer.height()
|
||||
|
||||
pipe = QgsRasterPipe()
|
||||
provider = self.current_raster_layer.dataProvider()
|
||||
pipe.set(provider.clone())
|
||||
|
||||
file_writer = QgsRasterFileWriter(file_name)
|
||||
error = file_writer.writeRaster(pipe,
|
||||
width,
|
||||
height,
|
||||
extent,
|
||||
self.current_raster_layer.crs())
|
||||
|
||||
target_img = cv2.imread(file_name)
|
||||
jpg_file_name = path + '.jpg'
|
||||
cv2.imwrite(jpg_file_name, target_img)
|
||||
os.remove(file_name)
|
||||
if error == QgsRasterFileWriter.NoError:
|
||||
QMessageBox.about(self, 'Export Files', '导出JPEG图像成功!')
|
||||
else:
|
||||
QMessageBox.about(self, 'Export Files', '导出JPEG图像失败!')
|
||||
|
||||
if filter_name == 'TIFF Images(*.tif)':
|
||||
file_name = path + '.tif'
|
||||
extent = self.current_raster_layer.extent()
|
||||
width, height = self.current_raster_layer.width(), self.current_raster_layer.height()
|
||||
|
||||
pipe = QgsRasterPipe()
|
||||
provider = self.current_raster_layer.dataProvider()
|
||||
pipe.set(provider.clone())
|
||||
|
||||
file_writer = QgsRasterFileWriter(file_name)
|
||||
error = file_writer.writeRaster(pipe,
|
||||
width,
|
||||
height,
|
||||
extent,
|
||||
self.current_raster_layer.crs())
|
||||
if error == QgsRasterFileWriter.NoError:
|
||||
QMessageBox.about(self, 'Export Files', '导出TIFF图像成功!')
|
||||
else:
|
||||
QMessageBox.about(self, 'Export Files', '导出TIFF图像失败!')
|
||||
if filter_name == 'PNG Images(*.png)':
|
||||
file_name = path + '.tif'
|
||||
extent = self.current_raster_layer.extent()
|
||||
width, height = self.current_raster_layer.width(), self.current_raster_layer.height()
|
||||
|
||||
pipe = QgsRasterPipe()
|
||||
provider = self.current_raster_layer.dataProvider()
|
||||
pipe.set(provider.clone())
|
||||
|
||||
file_writer = QgsRasterFileWriter(file_name)
|
||||
error = file_writer.writeRaster(pipe,
|
||||
width,
|
||||
height,
|
||||
extent,
|
||||
self.current_raster_layer.crs())
|
||||
target_img = cv2.imread(file_name)
|
||||
jpg_file_name = path + '.png'
|
||||
cv2.imwrite(jpg_file_name, target_img)
|
||||
os.remove(file_name)
|
||||
if error == QgsRasterFileWriter.NoError:
|
||||
QMessageBox.about(self, 'Export Files', '导出PNG图像成功!')
|
||||
else:
|
||||
QMessageBox.about(self, 'Export Files', '导出PNG图像失败!')
|
@ -1,6 +1,6 @@
|
||||
from PyQt5.QtWidgets import QTextEdit
|
||||
from PyQt5 import QtWidgets
|
||||
from PyQt5.QtGui import QTextCursor
|
||||
from PyQt5.QtGui import QTextCursor, QIcon
|
||||
from PyQt5.QtCore import Qt
|
||||
from datetime import datetime, time
|
||||
class MessageBox(QTextEdit):
|
||||
@ -24,7 +24,7 @@ class MessageBox(QTextEdit):
|
||||
def right_menu_show(self, position):
|
||||
rightMenu = QtWidgets.QMenu(self)
|
||||
# QAction = QtWidgets.QAction(self.menuBar1)
|
||||
action = QtWidgets.QAction('清空')
|
||||
action = QtWidgets.QAction(QIcon(':/icons/exit.png'), '清空')
|
||||
action.triggered.connect(self.clear)
|
||||
rightMenu.addAction(action)
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
from PyQt5.QtWidgets import *
|
||||
@ -11,7 +12,7 @@ class PluginDialog(QDialog):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.setWindowTitle('Plugins')
|
||||
self.setWindowIcon(QIcon(":/icons/logo.svg"))
|
||||
self.setWindowIcon(QIcon(":/icons/logo.png"))
|
||||
self.setMinimumWidth(900)
|
||||
self.setMinimumHeight(600)
|
||||
self.plugins = list(Settings.Plugin().plugins)
|
||||
@ -57,7 +58,7 @@ class PluginDialog(QDialog):
|
||||
plugin_directory = QFileDialog.getExistingDirectory(self, 'Select Plugin Directory', '.')
|
||||
if plugin_directory is not None:
|
||||
info = PluginLoader.load_plugin_info(plugin_directory)
|
||||
print(info)
|
||||
logging.info(info)
|
||||
|
||||
if info is not None:
|
||||
try:
|
||||
@ -73,6 +74,7 @@ class PluginDialog(QDialog):
|
||||
|
||||
self.plugin_table.insertRow(self.plugin_table.rowCount())
|
||||
name_item = QTableWidgetItem(info['name'])
|
||||
name_item.setIcon(QIcon(':/icons/tools.png'))
|
||||
module_item = QTableWidgetItem(info['module'])
|
||||
enabled_item = QTableWidgetItem('启用')
|
||||
enabled_item.setCheckState(Qt.Checked)
|
||||
@ -94,7 +96,8 @@ class PluginDialog(QDialog):
|
||||
try:
|
||||
shutil.rmtree(info['path'])
|
||||
except Exception as e:
|
||||
print(e)
|
||||
# logging
|
||||
logging.info(e)
|
||||
pass
|
||||
# for idx in self.plugins
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
|
||||
import logging
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
from PyQt5.QtCore import Qt,QModelIndex, pyqtSignal
|
||||
from PyQt5.QtGui import QStandardItemModel, QStandardItem
|
||||
@ -47,7 +48,8 @@ class ResultTable(QtWidgets.QWidget):
|
||||
self.tablewidget.item(row, col).setBackground(Qt.yellow)
|
||||
else:
|
||||
self.tablewidget.item(row, col).setBackground(Qt.green)
|
||||
print(item_idx, item_status)
|
||||
# logging
|
||||
logging.info(item_idx, item_status)
|
||||
self.result.update({'row':item_idx, 'value':item_status})
|
||||
self.no_change = False
|
||||
|
||||
|
@ -39,12 +39,16 @@ class MulStart:
|
||||
sys.exit(0)
|
||||
# Create and display the splash screen
|
||||
splash_pix = QPixmap(':/icons/splash.png')
|
||||
# splash_pix.scaledToWidth(800)
|
||||
# splash_pix.scaledToHeight(600)
|
||||
|
||||
splash = QSplashScreen(splash_pix, Qt.WindowStaysOnTopHint)
|
||||
# splash
|
||||
# splash.setFixedSize(800, 600)
|
||||
progressBar = QProgressBar(splash)
|
||||
progressBar.setMaximum(10)
|
||||
progressBar.setTextVisible(False)
|
||||
progressBar.setGeometry(46, splash_pix.height() - 60, splash_pix.width()-92, 10)
|
||||
progressBar.setGeometry(106, splash_pix.height() - 60, splash_pix.width()-212, 10)
|
||||
|
||||
splash.show()
|
||||
for i in range(1, 11):
|
||||
|
@ -1,3 +1,4 @@
|
||||
import logging
|
||||
import shutil
|
||||
from rscder.utils.setting import Settings
|
||||
from PyQt5.QtWidgets import QMessageBox
|
||||
@ -34,12 +35,13 @@ class PluginLoader(QObject):
|
||||
module = importlib.import_module(os.path.basename(path))
|
||||
mes = inspect.getmembers(module)
|
||||
for name, obj in mes:
|
||||
print(name, obj)
|
||||
# logging
|
||||
logging.info(name, obj)
|
||||
if inspect.isclass(obj) and issubclass(obj, BasicPlugin):
|
||||
info = obj.info()
|
||||
break
|
||||
except Exception as e:
|
||||
print(e)
|
||||
logging.info(str(e))
|
||||
QMessageBox.critical(None, 'Error', f'{path} load error: {e}')
|
||||
finally:
|
||||
sys.path.pop(0)
|
||||
|
@ -1,4 +1,5 @@
|
||||
import base64
|
||||
import logging
|
||||
from Crypto.Cipher import AES
|
||||
import uuid
|
||||
import hashlib
|
||||
@ -78,7 +79,7 @@ def get_aes():
|
||||
|
||||
class LicenseHelper(object):
|
||||
def generate_license(self, end_date, mac_addr):
|
||||
print("Received end_date: {}, mac_addr: {}".format(end_date, mac_addr))
|
||||
logging.info("Received end_date: {}, mac_addr: {}".format(end_date, mac_addr))
|
||||
psw = self.hash_msg('smartant' + str(mac_addr))
|
||||
license_str = {}
|
||||
license_str['mac'] = mac_addr
|
||||
@ -110,8 +111,8 @@ class LicenseHelper(object):
|
||||
lic_date_array = datetime.datetime.strptime(lic_date, "%Y-%m-%d %H:%M:%S")
|
||||
remain_days = lic_date_array - current_time_array
|
||||
remain_days = remain_days.days
|
||||
print('lic data:{}'.format(lic_date))
|
||||
print('remain_days: {}'.format(remain_days))
|
||||
logging.info('lic data:{}'.format(lic_date))
|
||||
logging.info('remain_days: {}'.format(remain_days))
|
||||
if remain_days < 0 or remain_days == 0:
|
||||
return False
|
||||
else:
|
||||
@ -138,6 +139,6 @@ if __name__ == '__main__':
|
||||
|
||||
license_dic = LicenseHelper().read_license(license_result)
|
||||
|
||||
print(license_dic)
|
||||
logging.info(license_dic)
|
||||
|
||||
|
19
使用手册.txt
Normal file
19
使用手册.txt
Normal file
@ -0,0 +1,19 @@
|
||||
1. lic文件生成
|
||||
点击RSCDer.exe,复制所显示的mac地址
|
||||
点击keygen.exe,粘贴mac地址,设置截止日期,并选择保存路径(无需输入后缀名)
|
||||
点击Generate
|
||||
|
||||
2. lic文件导入
|
||||
点击RSCDer.exe,点击Open,选择生成的lic文件
|
||||
点击OK
|
||||
|
||||
3. 新建项目与数据导入
|
||||
点击RSCDer.exe
|
||||
点击新建项目
|
||||
选择路径、名称
|
||||
将会在路径下看到与名称相同的文件夹
|
||||
|
||||
点击载入数据
|
||||
选择两幅不同时相的影像
|
||||
|
||||
4. 基本变化检测
|
Loading…
x
Reference in New Issue
Block a user