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
|
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)
|
menu.addAction(action)
|
||||||
|
|
||||||
def on_about(self):
|
def on_about(self):
|
||||||
print('on_about')
|
# print('on_about')
|
||||||
dialog = AboutDialog(self.ctx['mainwindow'])
|
dialog = AboutDialog(self.ctx['mainwindow'])
|
||||||
dialog.show()
|
dialog.show()
|
@ -10,7 +10,7 @@ from rscder.gui.layercombox import LayerCombox
|
|||||||
from osgeo import gdal, gdal_array
|
from osgeo import gdal, gdal_array
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
from basic_change.otsu import OTSU
|
||||||
class MyDialog(QDialog):
|
class MyDialog(QDialog):
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
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_tif = os.path.join(out, 'diff_0_255.tif')
|
||||||
out_normal_ds = driver.Create(out_normal_tif, xsize, ysize, 1, gdal.GDT_Byte)
|
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):
|
for j in range(yblocks):
|
||||||
block_xy = (0, j * cell_size[1])
|
block_xy = (0, j * cell_size[1])
|
||||||
block_size = (xsize, 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 - min_diff) / (max_diff - min_diff) * 255
|
||||||
block_data = block_data.astype(np.uint8)
|
block_data = block_data.astype(np.uint8)
|
||||||
out_normal_ds.GetRasterBand(1).WriteArray(block_data, *block_xy)
|
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()
|
out_normal_ds.FlushCache()
|
||||||
del out_normal_ds
|
del out_normal_ds
|
||||||
@ -194,7 +200,7 @@ class BasicMethod(BasicPlugin):
|
|||||||
center_y = j * cell_size[1] + cell_size[1] // 2
|
center_y = j * cell_size[1] + cell_size[1] // 2
|
||||||
center_x = center_x * geo[1] + geo [0]
|
center_x = center_x * geo[1] + geo [0]
|
||||||
center_y = center_y * geo[5] + geo [3]
|
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({
|
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
|
enabled: true
|
||||||
module: about
|
module: about
|
||||||
name: "\u5173\u4E8E"
|
name: "\u5173\u4E8E"
|
||||||
path: ./plugin-build\about
|
path: ./plugin\about
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
- author: RSCDER
|
- author: RSCDER
|
||||||
description: BasicMethod
|
description: BasicMethod
|
||||||
enabled: true
|
enabled: true
|
||||||
module: basic_change
|
module: basic_change
|
||||||
name: BasicMethod
|
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
|
version: 1.0.0
|
2
res.qrc
2
res.qrc
@ -28,7 +28,7 @@
|
|||||||
<file>icons\zoom_out.png</file>
|
<file>icons\zoom_out.png</file>
|
||||||
<file>icons\zoom_to.png</file>
|
<file>icons\zoom_to.png</file>
|
||||||
<file>icons\load.svg</file>
|
<file>icons\load.svg</file>
|
||||||
<file>icons\logo.svg</file>
|
<file>icons\logo.png</file>
|
||||||
<file>icons\model.svg</file>
|
<file>icons\model.svg</file>
|
||||||
<file>icons\ok.svg</file>
|
<file>icons\ok.svg</file>
|
||||||
<file>icons\outline.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
|
import pdb
|
||||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
from PyQt5.QtCore import Qt,QModelIndex
|
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 PyQt5.QtWidgets import (QTreeView, QTreeWidgetItem, QAbstractItemView, QHeaderView, QStyleFactory)
|
||||||
from rscder.gui.actions import get_action_manager
|
from rscder.gui.actions import get_action_manager
|
||||||
|
|
||||||
@ -18,6 +19,7 @@ class LayerTree(QtWidgets.QWidget):
|
|||||||
GRID = 3
|
GRID = 3
|
||||||
|
|
||||||
tree_changed = QtCore.pyqtSignal(str)
|
tree_changed = QtCore.pyqtSignal(str)
|
||||||
|
zoom_to_layer_signal = QtCore.pyqtSignal(str)
|
||||||
result_clicked = QtCore.pyqtSignal(str, int)
|
result_clicked = QtCore.pyqtSignal(str, int)
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
@ -52,6 +54,7 @@ class LayerTree(QtWidgets.QWidget):
|
|||||||
self.setLayout(layout)
|
self.setLayout(layout)
|
||||||
self.setLayoutDirection(Qt.LeftToRight)
|
self.setLayoutDirection(Qt.LeftToRight)
|
||||||
self.is_in_add_layer = False
|
self.is_in_add_layer = False
|
||||||
|
self.current_item = None
|
||||||
|
|
||||||
def onItemClicked(self, item:QtWidgets.QTreeWidgetItem, column):
|
def onItemClicked(self, item:QtWidgets.QTreeWidgetItem, column):
|
||||||
if item == self.root:
|
if item == self.root:
|
||||||
@ -153,7 +156,7 @@ class LayerTree(QtWidgets.QWidget):
|
|||||||
if item_root.data(0, Qt.UserRole + 1) == layer.id:
|
if item_root.data(0, Qt.UserRole + 1) == layer.id:
|
||||||
layer_root = item_root
|
layer_root = item_root
|
||||||
break
|
break
|
||||||
print(layer_root.text(0))
|
logging.info(layer_root.text(0))
|
||||||
if layer_root is None:
|
if layer_root is None:
|
||||||
self.add_layer(layer.id)
|
self.add_layer(layer.id)
|
||||||
return
|
return
|
||||||
@ -172,37 +175,71 @@ class LayerTree(QtWidgets.QWidget):
|
|||||||
self.root.setText(0,'图层')
|
self.root.setText(0,'图层')
|
||||||
self.tree.addTopLevelItem(self.root)
|
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):
|
def right_menu_show(self, position):
|
||||||
rightMenu = QtWidgets.QMenu(self)
|
rightMenu = QtWidgets.QMenu(self)
|
||||||
# QAction = QtWidgets.QAction(self.menuBar1)
|
# QAction = QtWidgets.QAction(self.menuBar1)
|
||||||
item = self.tree.itemAt(position)
|
item = self.tree.itemAt(position)
|
||||||
|
self.current_item = item
|
||||||
action_manager = get_action_manager()
|
action_manager = get_action_manager()
|
||||||
actions = []
|
actions = []
|
||||||
data_load_action = action_manager.get_action('&数据加载', 'File')
|
data_load_action = action_manager.get_action('&数据加载', 'File')
|
||||||
actions.append(data_load_action)
|
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:
|
if item is None:
|
||||||
print('nothing')
|
logging.info('nothing')
|
||||||
else:
|
else:
|
||||||
if item == self.root:
|
if item == self.root:
|
||||||
pass
|
pass
|
||||||
elif item.data(0, Qt.UserRole) == LayerTree.LAYER_TOOT:
|
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(QtWidgets.QAction('&删除', self))
|
actions.append(del_action)
|
||||||
elif item.data(0, Qt.UserRole) == LayerTree.SUB_RASTER:
|
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))
|
||||||
actions.append(QtWidgets.QAction('&删除', self))
|
|
||||||
elif item.data(0, Qt.UserRole) == LayerTree.RESULT:
|
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)
|
||||||
actions.append(QtWidgets.QAction('&删除', self))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for action in actions:
|
for action in actions:
|
||||||
|
@ -11,7 +11,7 @@ class License(QtWidgets.QDialog):
|
|||||||
def __init__(self, parent = None, flags = QtCore.Qt.WindowFlags() ) -> None:
|
def __init__(self, parent = None, flags = QtCore.Qt.WindowFlags() ) -> None:
|
||||||
super().__init__(parent, flags)
|
super().__init__(parent, flags)
|
||||||
self.setWindowTitle("License")
|
self.setWindowTitle("License")
|
||||||
self.setWindowIcon(QIcon(':/icons/license.png'))
|
self.setWindowIcon(QIcon(':/icons/logo.png'))
|
||||||
self.setWindowFlags(QtCore.Qt.WindowCloseButtonHint)
|
self.setWindowFlags(QtCore.Qt.WindowCloseButtonHint)
|
||||||
self.setFixedSize(600, 400)
|
self.setFixedSize(600, 400)
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@ class MainWindow(QMainWindow):
|
|||||||
self.layer_tree.result_clicked.connect(self.result_box.on_result)
|
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_click.connect(self.double_map.zoom_to_result)
|
||||||
self.result_box.on_item_changed.connect(Project().change_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.action_manager = ActionManager(
|
||||||
self.double_map,
|
self.double_map,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
# from alg.utils import random_color
|
# from alg.utils import random_color
|
||||||
# from mul.mulgrubcut import GrabCut
|
# from mul.mulgrubcut import GrabCut
|
||||||
|
import logging
|
||||||
import multiprocessing
|
import multiprocessing
|
||||||
# from alg.grubcut import grubcut
|
# from alg.grubcut import grubcut
|
||||||
# from gui.layerselect import LayerSelect
|
# from gui.layerselect import LayerSelect
|
||||||
@ -82,24 +83,27 @@ class DoubleCanvas(QWidget):
|
|||||||
zoom_out.triggered.connect( self.set_zoom_out)
|
zoom_out.triggered.connect( self.set_zoom_out)
|
||||||
|
|
||||||
def set_pan_tool(self, s):
|
def set_pan_tool(self, s):
|
||||||
print('set pan tool')
|
# print('set pan tool')
|
||||||
if s:
|
if s:
|
||||||
self.mapcanva1.setMapTool(QgsMapToolPan(self.mapcanva1))
|
self.mapcanva1.setMapTool(QgsMapToolPan(self.mapcanva1))
|
||||||
self.mapcanva2.setMapTool(QgsMapToolPan(self.mapcanva2))
|
self.mapcanva2.setMapTool(QgsMapToolPan(self.mapcanva2))
|
||||||
|
|
||||||
def set_zoom_in(self, s):
|
def set_zoom_in(self, s):
|
||||||
print('set zoom in')
|
# print('set zoom in')
|
||||||
if s:
|
if s:
|
||||||
self.mapcanva1.setMapTool(QgsMapToolZoom(self.mapcanva1, False))
|
self.mapcanva1.setMapTool(QgsMapToolZoom(self.mapcanva1, False))
|
||||||
self.mapcanva2.setMapTool(QgsMapToolZoom(self.mapcanva2, False))
|
self.mapcanva2.setMapTool(QgsMapToolZoom(self.mapcanva2, False))
|
||||||
|
|
||||||
def set_zoom_out(self, s):
|
def set_zoom_out(self, s):
|
||||||
print('set zoom out')
|
# print('set zoom out')
|
||||||
if s:
|
if s:
|
||||||
self.mapcanva1.setMapTool(QgsMapToolZoom(self.mapcanva1, True))
|
self.mapcanva1.setMapTool(QgsMapToolZoom(self.mapcanva1, True))
|
||||||
self.mapcanva2.setMapTool(QgsMapToolZoom(self.mapcanva2, True))
|
self.mapcanva2.setMapTool(QgsMapToolZoom(self.mapcanva2, True))
|
||||||
|
|
||||||
def add_layer(self, layer:str):
|
def add_layer(self, layer:str):
|
||||||
|
if not layer in Project().layers:
|
||||||
|
self.clear()
|
||||||
|
return
|
||||||
layer:PairLayer = Project().layers[layer]
|
layer:PairLayer = Project().layers[layer]
|
||||||
if not layer.enable:
|
if not layer.enable:
|
||||||
return
|
return
|
||||||
@ -210,430 +214,3 @@ class CanvasWidget(QgsMapCanvas):
|
|||||||
return self.update_coordinates_text.emit("X: {:.5f}, Y: {:.5f}".format(pt.x(), pt.y()))
|
return self.update_coordinates_text.emit("X: {:.5f}, Y: {:.5f}".format(pt.x(), pt.y()))
|
||||||
self.xyCoordinates.connect(coordinates2text)
|
self.xyCoordinates.connect(coordinates2text)
|
||||||
self.scaleChanged.connect(lambda _ : self.update_scale_text.emit("1 : {:.3f}".format(self.scale())))
|
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.QtWidgets import QTextEdit
|
||||||
from PyQt5 import QtWidgets
|
from PyQt5 import QtWidgets
|
||||||
from PyQt5.QtGui import QTextCursor
|
from PyQt5.QtGui import QTextCursor, QIcon
|
||||||
from PyQt5.QtCore import Qt
|
from PyQt5.QtCore import Qt
|
||||||
from datetime import datetime, time
|
from datetime import datetime, time
|
||||||
class MessageBox(QTextEdit):
|
class MessageBox(QTextEdit):
|
||||||
@ -24,7 +24,7 @@ class MessageBox(QTextEdit):
|
|||||||
def right_menu_show(self, position):
|
def right_menu_show(self, position):
|
||||||
rightMenu = QtWidgets.QMenu(self)
|
rightMenu = QtWidgets.QMenu(self)
|
||||||
# QAction = QtWidgets.QAction(self.menuBar1)
|
# QAction = QtWidgets.QAction(self.menuBar1)
|
||||||
action = QtWidgets.QAction('清空')
|
action = QtWidgets.QAction(QIcon(':/icons/exit.png'), '清空')
|
||||||
action.triggered.connect(self.clear)
|
action.triggered.connect(self.clear)
|
||||||
rightMenu.addAction(action)
|
rightMenu.addAction(action)
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import logging
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
from PyQt5.QtWidgets import *
|
from PyQt5.QtWidgets import *
|
||||||
@ -11,7 +12,7 @@ class PluginDialog(QDialog):
|
|||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self.setWindowTitle('Plugins')
|
self.setWindowTitle('Plugins')
|
||||||
self.setWindowIcon(QIcon(":/icons/logo.svg"))
|
self.setWindowIcon(QIcon(":/icons/logo.png"))
|
||||||
self.setMinimumWidth(900)
|
self.setMinimumWidth(900)
|
||||||
self.setMinimumHeight(600)
|
self.setMinimumHeight(600)
|
||||||
self.plugins = list(Settings.Plugin().plugins)
|
self.plugins = list(Settings.Plugin().plugins)
|
||||||
@ -57,7 +58,7 @@ class PluginDialog(QDialog):
|
|||||||
plugin_directory = QFileDialog.getExistingDirectory(self, 'Select Plugin Directory', '.')
|
plugin_directory = QFileDialog.getExistingDirectory(self, 'Select Plugin Directory', '.')
|
||||||
if plugin_directory is not None:
|
if plugin_directory is not None:
|
||||||
info = PluginLoader.load_plugin_info(plugin_directory)
|
info = PluginLoader.load_plugin_info(plugin_directory)
|
||||||
print(info)
|
logging.info(info)
|
||||||
|
|
||||||
if info is not None:
|
if info is not None:
|
||||||
try:
|
try:
|
||||||
@ -73,6 +74,7 @@ class PluginDialog(QDialog):
|
|||||||
|
|
||||||
self.plugin_table.insertRow(self.plugin_table.rowCount())
|
self.plugin_table.insertRow(self.plugin_table.rowCount())
|
||||||
name_item = QTableWidgetItem(info['name'])
|
name_item = QTableWidgetItem(info['name'])
|
||||||
|
name_item.setIcon(QIcon(':/icons/tools.png'))
|
||||||
module_item = QTableWidgetItem(info['module'])
|
module_item = QTableWidgetItem(info['module'])
|
||||||
enabled_item = QTableWidgetItem('启用')
|
enabled_item = QTableWidgetItem('启用')
|
||||||
enabled_item.setCheckState(Qt.Checked)
|
enabled_item.setCheckState(Qt.Checked)
|
||||||
@ -94,7 +96,8 @@ class PluginDialog(QDialog):
|
|||||||
try:
|
try:
|
||||||
shutil.rmtree(info['path'])
|
shutil.rmtree(info['path'])
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
# logging
|
||||||
|
logging.info(e)
|
||||||
pass
|
pass
|
||||||
# for idx in self.plugins
|
# for idx in self.plugins
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
|
|
||||||
|
import logging
|
||||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
from PyQt5.QtCore import Qt,QModelIndex, pyqtSignal
|
from PyQt5.QtCore import Qt,QModelIndex, pyqtSignal
|
||||||
from PyQt5.QtGui import QStandardItemModel, QStandardItem
|
from PyQt5.QtGui import QStandardItemModel, QStandardItem
|
||||||
@ -47,7 +48,8 @@ class ResultTable(QtWidgets.QWidget):
|
|||||||
self.tablewidget.item(row, col).setBackground(Qt.yellow)
|
self.tablewidget.item(row, col).setBackground(Qt.yellow)
|
||||||
else:
|
else:
|
||||||
self.tablewidget.item(row, col).setBackground(Qt.green)
|
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.result.update({'row':item_idx, 'value':item_status})
|
||||||
self.no_change = False
|
self.no_change = False
|
||||||
|
|
||||||
|
@ -39,12 +39,16 @@ class MulStart:
|
|||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
# Create and display the splash screen
|
# Create and display the splash screen
|
||||||
splash_pix = QPixmap(':/icons/splash.png')
|
splash_pix = QPixmap(':/icons/splash.png')
|
||||||
|
# splash_pix.scaledToWidth(800)
|
||||||
|
# splash_pix.scaledToHeight(600)
|
||||||
|
|
||||||
splash = QSplashScreen(splash_pix, Qt.WindowStaysOnTopHint)
|
splash = QSplashScreen(splash_pix, Qt.WindowStaysOnTopHint)
|
||||||
|
# splash
|
||||||
|
# splash.setFixedSize(800, 600)
|
||||||
progressBar = QProgressBar(splash)
|
progressBar = QProgressBar(splash)
|
||||||
progressBar.setMaximum(10)
|
progressBar.setMaximum(10)
|
||||||
progressBar.setTextVisible(False)
|
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()
|
splash.show()
|
||||||
for i in range(1, 11):
|
for i in range(1, 11):
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import logging
|
||||||
import shutil
|
import shutil
|
||||||
from rscder.utils.setting import Settings
|
from rscder.utils.setting import Settings
|
||||||
from PyQt5.QtWidgets import QMessageBox
|
from PyQt5.QtWidgets import QMessageBox
|
||||||
@ -34,12 +35,13 @@ class PluginLoader(QObject):
|
|||||||
module = importlib.import_module(os.path.basename(path))
|
module = importlib.import_module(os.path.basename(path))
|
||||||
mes = inspect.getmembers(module)
|
mes = inspect.getmembers(module)
|
||||||
for name, obj in mes:
|
for name, obj in mes:
|
||||||
print(name, obj)
|
# logging
|
||||||
|
logging.info(name, obj)
|
||||||
if inspect.isclass(obj) and issubclass(obj, BasicPlugin):
|
if inspect.isclass(obj) and issubclass(obj, BasicPlugin):
|
||||||
info = obj.info()
|
info = obj.info()
|
||||||
break
|
break
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
logging.info(str(e))
|
||||||
QMessageBox.critical(None, 'Error', f'{path} load error: {e}')
|
QMessageBox.critical(None, 'Error', f'{path} load error: {e}')
|
||||||
finally:
|
finally:
|
||||||
sys.path.pop(0)
|
sys.path.pop(0)
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import base64
|
import base64
|
||||||
|
import logging
|
||||||
from Crypto.Cipher import AES
|
from Crypto.Cipher import AES
|
||||||
import uuid
|
import uuid
|
||||||
import hashlib
|
import hashlib
|
||||||
@ -78,7 +79,7 @@ def get_aes():
|
|||||||
|
|
||||||
class LicenseHelper(object):
|
class LicenseHelper(object):
|
||||||
def generate_license(self, end_date, mac_addr):
|
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))
|
psw = self.hash_msg('smartant' + str(mac_addr))
|
||||||
license_str = {}
|
license_str = {}
|
||||||
license_str['mac'] = mac_addr
|
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")
|
lic_date_array = datetime.datetime.strptime(lic_date, "%Y-%m-%d %H:%M:%S")
|
||||||
remain_days = lic_date_array - current_time_array
|
remain_days = lic_date_array - current_time_array
|
||||||
remain_days = remain_days.days
|
remain_days = remain_days.days
|
||||||
print('lic data:{}'.format(lic_date))
|
logging.info('lic data:{}'.format(lic_date))
|
||||||
print('remain_days: {}'.format(remain_days))
|
logging.info('remain_days: {}'.format(remain_days))
|
||||||
if remain_days < 0 or remain_days == 0:
|
if remain_days < 0 or remain_days == 0:
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
@ -138,6 +139,6 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
license_dic = LicenseHelper().read_license(license_result)
|
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