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 10 commits into
base: main
Choose a base branch
from
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
22 changes: 11 additions & 11 deletions LDMP/gui/DlgCalculateOneStep.ui
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<string>SDG 15.3.1 Indicator (one-step) | Land Degradation</string>
</property>
<property name="toolTip">
<string>User notes associated with the executed task.</string>
<string/>
</property>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
Expand Down Expand Up @@ -66,9 +66,9 @@
<property name="geometry">
<rect>
<x>0</x>
<y>-427</y>
<width>653</width>
<height>890</height>
<y>0</y>
<width>787</width>
<height>1348</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_7">
Expand All @@ -90,7 +90,7 @@
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="collapsed">
<bool>true</bool>
<bool>false</bool>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
Expand Down Expand Up @@ -1091,7 +1091,7 @@
<string>Advanced configuration</string>
</property>
<property name="collapsed">
<bool>true</bool>
<bool>false</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
Expand Down Expand Up @@ -1204,11 +1204,11 @@
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:5.5pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:16px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Ubuntu'; font-size:11pt; font-weight:600;&quot;&gt;Calculate all SDG 15.3.1 sub-indicators in a single step&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Ubuntu'; font-size:11pt;&quot;&gt;This algorithm enables the simultaneous calculation of the three SDG 15.3.1 sub-indicators (Productivity, Land Cover and Soil Organic Carbon) in a single step. This is done using the remote Trends.Earth datasets described in each of the individual sub-indicator's sections.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Ubuntu'; font-size:11pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a href=&quot;https://docs.trends.earth/en/latest/for_users/features/landdegradation.html&quot;&gt;&lt;span style=&quot; font-family:'Ubuntu'; font-size:11pt; text-decoration: underline; color:#0000ff;&quot;&gt;More information&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Ubuntu Sans'; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:16px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Ubuntu'; font-weight:600;&quot;&gt;Calculate all SDG 15.3.1 sub-indicators in a single step&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Ubuntu';&quot;&gt;This algorithm enables the simultaneous calculation of the three SDG 15.3.1 sub-indicators (Productivity, Land Cover and Soil Organic Carbon) in a single step. This is done using the remote Trends.Earth datasets described in each of the individual sub-indicator's sections.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Ubuntu';&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a href=&quot;https://docs.trends.earth/en/latest/for_users/features/landdegradation.html&quot;&gt;&lt;span style=&quot; font-family:'Ubuntu'; text-decoration: underline; color:#0000ff;&quot;&gt;More information&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
Expand Down
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
13 changes: 13 additions & 0 deletions LDMP/lc_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -1235,12 +1235,25 @@ def __init__(self, parent=None):
def setup_deg_def_matrix(self, legend):
self.deg_def_matrix.setRowCount(len(legend.key))
self.deg_def_matrix.setColumnCount(len(legend.key))

self.deg_def_matrix.setHorizontalHeaderLabels(
[c.get_name_short() for c in legend.key]
)
self.deg_def_matrix.setVerticalHeaderLabels(
[c.get_name_short() for c in legend.key]
)

for index in range(len(legend.key)):
long_name = legend.key[index].get_name_long()

horizontal_header_item = self.deg_def_matrix.horizontalHeaderItem(index)
horizontal_header_item.setToolTip(
long_name
) if horizontal_header_item else None

vertical_header_item = self.deg_def_matrix.verticalHeaderItem(index)
vertical_header_item.setToolTip(long_name) if vertical_header_item else None

if len(legend.key) > 9:
self.deg_def_matrix.setHorizontalHeader(
RotatedHeaderView(QtCore.Qt.Horizontal, self.deg_def_matrix)
Expand Down
155 changes: 155 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 @@ -1997,12 +2043,15 @@ def _update_lcc_row_items(

if not update:
name_item = QtGui.QStandardItem(lcc.name_long)
name_item.setToolTip(lcc.name_long)

code_item = QtGui.QStandardItem(str(lcc.code))
parent_item = QtGui.QStandardItem(str(parent.name_long))
else:
name_idx = self.model.index(row, 0)
name_item = self.model.itemFromIndex(name_idx)
name_item.setText(lcc.name_long)
name_item.setToolTip(lcc.name_long)

code_idx = self.model.index(row, 1)
code_item = self.model.itemFromIndex(code_idx)
Expand Down Expand Up @@ -2117,6 +2166,112 @@ 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 120 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[:119] + "…" if len(class_name) >= 120 else class_name
)

if len(class_name) >= 120:
label_tooltip = self.parent.tr(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_short_name = class_name[:19] if len(class_name) > 20 else class_name
trimmed_long_name = (
class_name[:119] if len(class_name) > 120 else class_name
)

if not parent:
continue

lcc = LCClass(auto_id, trimmed_short_name, trimmed_long_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