Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for class names import #854

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions LDMP/calculate_ldn.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ def __init__(

self.radio_lpd_te.toggled.connect(self.toggle_lpd_options)
self.radio_lpd_precalculated.toggled.connect(self.toggle_lpd_options)
self.radio_fao_wocat.toggled.connect(self.toggle_lpd_options)

self.lc_define_deg_widget = lc_setup.LCDefineDegradationWidget()

Expand Down
2 changes: 1 addition & 1 deletion LDMP/calculate_prod.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def traj_indic_changed(self):
self.dataset_climate_update()

def mode_te_prod_toggled(self):
if self.mode_lpd_jrc.isChecked():
if self.mode_lpd_jrc.isChecked() or self.mode_fao_wocat.isChecked():
self.combo_lpd.setEnabled(True)
self.advance_configurations.setEnabled(False)
self.groupBox_ndvi_dataset.setEnabled(False)
Expand Down
2 changes: 2 additions & 0 deletions LDMP/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class Setting(enum.Enum):
BASE_DIR = "advanced/base_data_directory"
CUSTOM_CRS_ENABLED = "region_of_interest/custom_crs_enabled"
CUSTOM_CRS = "region_of_interest/custom_crs"
CSV_FILE_DIR = "advanced/csv_file_dir"
POLL_REMOTE = "advanced/poll_remote_server"
REMOTE_POLLING_FREQUENCY = "advanced/remote_polling_frequency_seconds"
DOWNLOAD_RESULTS = "advanced/download_remote_results_automatically"
Expand Down Expand Up @@ -122,6 +123,7 @@ class SettingsManager:
Setting.POINT_Y: 0.0,
Setting.VECTOR_FILE_PATH: "",
Setting.VECTOR_FILE_DIR: "",
Setting.CSV_FILE_DIR: "",
Setting.COUNTRY_NAME: "",
Setting.REGION_NAME: "",
Setting.CITY_NAME: "",
Expand Down
51 changes: 29 additions & 22 deletions LDMP/gui/DlgCalculateLDNSummaryTableAdmin.ui

Large diffs are not rendered by default.

85 changes: 46 additions & 39 deletions LDMP/gui/DlgCalculateProd.ui

Large diffs are not rendered by default.

15 changes: 14 additions & 1 deletion LDMP/gui/WidgetLCClassManage.ui
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>408</width>
<width>435</width>
<height>223</height>
</rect>
</property>
Expand Down Expand Up @@ -108,6 +108,19 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btn_import">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Import</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
Expand Down
147 changes: 147 additions & 0 deletions LDMP/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
***************************************************************************/
"""

import csv
import os
import typing
import zipfile
Expand Down Expand Up @@ -1631,6 +1632,51 @@ def __init__(
self.btn_restore.setIcon(restore_icon)
self.btn_restore.clicked.connect(self.dlg_land_cover_restore.exec_)

import_icon = qgis.core.QgsApplication.instance().getThemeIcon(
"mActionSharingImport.svg"
)
self.btn_import.setIcon(import_icon)
self.btn_import.clicked.connect(self.import_lclr_classes)

def import_lclr_classes(self):
data_dir = settings_manager.get_value(Setting.CSV_FILE_DIR)

if not data_dir:
data_dir = os.path.expanduser("~")

file_path = self._show_path_selector(data_dir)
if not file_path:
return

settings_manager.write_value(Setting.CSV_FILE_DIR, str(Path(file_path).parent))

class_names = []
with open(file_path, newline="", encoding="utf-8") as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
class_names.append(row["Class Name"])

dialog = LandCoverClassSelectionDialog(class_names, parent=self)

if dialog.exec_() == QtWidgets.QDialog.Accepted:
dialog.set_selected_classes()

def _show_path_selector(self, file_dir: str) -> str:
"""Show file selector dialog for selecting a csv file."""
filter_tr = self.tr("CSV")

layer_path, _ = QtWidgets.QFileDialog.getOpenFileName(
self,
self.tr("Select csv file"),
file_dir,
f"{filter_tr} (*.csv)",
options=QtWidgets.QFileDialog.DontResolveSymlinks,
)
if not layer_path:
return ""

return layer_path

def on_restore_esa(self):
# Slot raised to restore ESA land cover classes.
self.dlg_land_cover_restore.close()
Expand Down Expand Up @@ -2117,6 +2163,107 @@ def delete_class_info(self, row: int):
self.set_table_height()


class LandCoverClassSelectionDialog(QtWidgets.QDialog):
def __init__(self, class_names, parent=None):
super().__init__(parent)
self.parent = parent
self.setWindowTitle("Import Classes options")
self.layout = QtWidgets.QVBoxLayout()

top_label = QtWidgets.QLabel(
self.tr("<b>Select a parent for each of the below class names</b>")
)
self.layout.addWidget(top_label)

self.combo_boxes = {}

label_tooltip = self.parent.tr(
"The class name value that will imported,"
" should not exceed 20 characters. "
)

combo_box_tooltip = self.parent.tr(
"Select the parent for the corresponding class name."
)

for class_name in class_names:
row_layout = QtWidgets.QHBoxLayout()

trimmed_class_name = (
class_name[:19] + "…" if len(class_name) > 20 else class_name
)

label = QtWidgets.QLabel(trimmed_class_name)
label.setToolTip(label_tooltip)

combo_box = QtWidgets.QComboBox()
combo_box.setToolTip(combo_box_tooltip)

status, ref_classes = LccInfoUtils.load_settings()

for l_class in ref_classes:
combo_box.insertItem(l_class.idx, l_class.lcc.name_long, l_class.lcc)
clr = QtGui.QColor(l_class.lcc.color)

combo_box.setItemData(l_class.idx, clr, QtCore.Qt.DecorationRole)

self.combo_boxes[class_name] = combo_box

row_layout.addWidget(label)
row_layout.addWidget(combo_box)
self.layout.addLayout(row_layout)

self.accept_button = QtWidgets.QPushButton(self.tr("Accept"))
self.accept_button.clicked.connect(self.accept)
self.cancel_button = QtWidgets.QPushButton(self.tr("Cancel"))
self.cancel_button.clicked.connect(self.reject)

button_layout = QtWidgets.QHBoxLayout()
button_layout.addWidget(self.accept_button)
button_layout.addWidget(self.cancel_button)
self.layout.addLayout(button_layout)

self.setLayout(self.layout)

def set_selected_classes(self):
"""Sets the selected class names"""
codes_max = 255
code_range = set(range(1, codes_max + 1))

codes = self.parent.class_codes()

used_codes = set(codes)
code_set = code_range - used_codes

if len(code_set) == 0:
msg = self.parent.tr("Maximum number of codes reached.")
self.parent.append_msg(msg)

return
code = min(code_set)

auto_id = int(code)

for class_name, combo_box in self.combo_boxes.items():
parent = combo_box.itemData(combo_box.currentIndex())

trimmed_class_name = class_name[:19] if len(class_name) > 20 else class_name

if not parent:
continue

lcc = LCClass(auto_id, trimmed_class_name, trimmed_class_name)

lc_class_info = LCClassInfo()

lc_class_info.lcc = lcc
lc_class_info.parent = parent

self.parent.add_class_info_to_table(lc_class_info)

auto_id += 1


class LandCoverCustomClassEditor(
qgis.gui.QgsPanelWidget, Ui_WidgetLandCoverCustomClassEditor
):
Expand Down
Loading