Skip to content

Commit

Permalink
Mapping multiple fields in an existing feature class to DCE Layer cau…
Browse files Browse the repository at this point in the history
…ses error

#552
  • Loading branch information
KellyMWhitehead committed Jan 24, 2025
1 parent 83353a0 commit 5057991
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 56 deletions.
147 changes: 93 additions & 54 deletions src/view/frm_field_value_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,64 +6,99 @@
class FrmFieldValueMap(QtWidgets.QDialog):

# signal to send field value map to parent
field_value_map = QtCore.pyqtSignal(str, dict)
field_value_map_signal = QtCore.pyqtSignal(str, dict)

def __init__(self, parent, field: str, values: list, fields: dict):
def __init__(self, input_field: str, values: list, fields: dict, parent=None):
super().__init__(parent)
self.fields = fields # Dictionary to store field values
self.values = values # List to store input values
self.input_field = input_field # Name of the input field

self.field = field
self.values = values
self.fields = fields

super(FrmFieldValueMap, self).__init__(parent)
self.setupUi()

self.setWindowTitle('Field Value Map')
self.txtField.setText(self.field)

self.load_fields()
self.txtInputField.setText(input_field)

def load_fields(self):
# Populate the combo box with field names
self.cmbOutputField.addItems(self.fields.keys())

# add rows for each value
# Populate the table with input values
self.tblFields.setRowCount(len(self.values))

# add values to first column
for i, value in enumerate(self.values):
self.tblFields.setItem(i, 0, QtWidgets.QTableWidgetItem(str(value)))
# add drop down to each column with the values in self.fields
for j, field in enumerate(self.fields.keys()):
combo = QtWidgets.QComboBox()
combo.addItem('- NULL -', None)
for value in self.fields[field]:
# add the value and display name to the combo box
combo.addItem(str(value), value)

self.tblFields.setCellWidget(i, j + 1, combo)
combo.setCurrentIndex(0)
item = QtWidgets.QTableWidgetItem(str(value))
self.tblFields.setItem(i, 0, item)

def add_output_field(self, field) -> None:

if not field:
field = self.cmbOutputField.currentText()
if not field:
return

# Add a new column to the table
self.tblFields.setColumnCount(self.tblFields.columnCount() + 1)
self.tblFields.setHorizontalHeaderItem(self.tblFields.columnCount() - 1, QtWidgets.QTableWidgetItem(field))

# Add combo boxes to each row in the new column
for i in range(self.tblFields.rowCount()):
combo = QtWidgets.QComboBox()
combo.addItem('- NULL -', None)
for value in self.fields.get(field, []):
combo.addItem(str(value), value)
self.tblFields.setCellWidget(i, self.tblFields.columnCount() - 1, combo)
combo.setCurrentIndex(0)

self.cbo_changed(0)

def remove_output_field(self) -> None:
field = self.cmbOutputField.currentText()
headers = [self.tblFields.horizontalHeaderItem(i).text() for i in range(self.tblFields.columnCount())]
if field in headers:
idx = headers.index(field)
self.tblFields.removeColumn(idx)

self.cbo_changed(0)

def cbo_changed(self, idx: int) -> None:
field = self.cmbOutputField.currentText()
headers = [self.tblFields.horizontalHeaderItem(i).text() for i in range(self.tblFields.columnCount())]
if field in headers[1:]:
self.btnAddOutputField.setDisabled(True)
self.btnRemoveOutputField.setDisabled(False)
else:
self.btnAddOutputField.setDisabled(False)
self.btnRemoveOutputField.setDisabled(True)

def get_field_value_map(self) -> dict:

field_value_map = {}
for i, value in enumerate(self.values):
field_value_map[value] = {}
for j, field in enumerate(self.fields.keys()):
combo = self.tblFields.cellWidget(i, j + 1)
for j in range(1, self.tblFields.columnCount()):
field = self.tblFields.horizontalHeaderItem(j).text()
combo: QtWidgets.QComboBox = self.tblFields.cellWidget(i, j)
field_value_map[value][field] = combo.currentData()

return field_value_map

def load_field_value_map(self, field_value_map: dict) -> None:
# Add columns based on the field_value_map keys
for field in next(iter(field_value_map.values())).keys():
if field not in [self.tblFields.horizontalHeaderItem(i).text() for i in range(self.tblFields.columnCount())]:
self.add_output_field(field)

# Populate the combo boxes with the values from field_value_map
for i, value in enumerate(self.values):
for j, field in enumerate(self.fields.keys()):
combo: QtWidgets.QComboBox = self.tblFields.cellWidget(i, j + 1)
combo.setCurrentIndex(combo.findData(field_value_map[value][field]))
if value in field_value_map:
for j in range(1, self.tblFields.columnCount()):
field = self.tblFields.horizontalHeaderItem(j).text()
if field in field_value_map[value]:
combo: QtWidgets.QComboBox = self.tblFields.cellWidget(i, j)
combo.setCurrentIndex(combo.findData(field_value_map[value][field]))

def accept(self) -> None:

out_map = self.get_field_value_map()
# retain = self.chkRetain.isChecked()
self.field_value_map.emit(self.field, out_map)
self.field_value_map_signal.emit(self.input_field, out_map)

return super().accept()

Expand All @@ -72,39 +107,43 @@ def setupUi(self):
# set size
self.resize(800, 600)

# vertical layout
self.vLayout = QtWidgets.QVBoxLayout(self)
self.grid = QtWidgets.QGridLayout()
self.vLayout.addLayout(self.grid)

self.lblInputField = QtWidgets.QLabel('Input Field')
self.grid.addWidget(self.lblInputField, 0, 0)

# horizontal layout for field name
self.hLayout = QtWidgets.QHBoxLayout()
self.vLayout.addLayout(self.hLayout)
self.txtInputField = QtWidgets.QLineEdit()
self.txtInputField.setReadOnly(True)
self.grid.addWidget(self.txtInputField, 0, 1)

# label for field name
self.lblField = QtWidgets.QLabel('Input Field')
self.hLayout.addWidget(self.lblField)
self.lblOutputField = QtWidgets.QLabel('Output Field')
self.grid.addWidget(self.lblOutputField, 1, 0)

# text box for field name
self.txtField = QtWidgets.QLineEdit()
self.txtField.setToolTip('The field from the input file to map values for')
self.txtField.setReadOnly(True)
self.hLayout.addWidget(self.txtField)
self.cmbOutputField = QtWidgets.QComboBox()
self.grid.addWidget(self.cmbOutputField, 1, 1)

# # Retain original values as Metadata checkox
# self.chkRetain = QtWidgets.QCheckBox('Retain original values as Metadata')
# self.chkRetain.setChecked(True)
# self.vLayout.addWidget(self.chkRetain)
self.btnAddOutputField = QtWidgets.QPushButton('Add')
self.btnAddOutputField.setToolTip('Add a new output field')
self.grid.addWidget(self.btnAddOutputField, 1, 2)

self.btnRemoveOutputField = QtWidgets.QPushButton('Remove')
self.btnRemoveOutputField.setToolTip('Remove the selected output field')
self.grid.addWidget(self.btnRemoveOutputField, 1, 3)

# new table with 1 + number of fields columns
self.tblFields = QtWidgets.QTableWidget()
self.tblFields.setColumnCount(1 + len(self.fields))
self.tblFields.setHorizontalHeaderLabels(['Value'] + list(self.fields.keys()))
self.tblFields.setColumnCount(1)
self.tblFields.setHorizontalHeaderLabels(['Input Values'])
self.tblFields.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch)
self.tblFields.verticalHeader().setVisible(False)
self.tblFields.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection)
self.tblFields.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)

# add table to layout
self.vLayout.addWidget(self.tblFields)

# add standard form buttons
self.vLayout.addLayout(add_standard_form_buttons(self, 'field_value_map'))

self.btnAddOutputField.clicked.connect(self.add_output_field)
self.btnRemoveOutputField.clicked.connect(self.remove_output_field)
self.cmbOutputField.currentIndexChanged.connect(self.cbo_changed)
4 changes: 2 additions & 2 deletions src/view/frm_import_dce_layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,11 +147,11 @@ def open_value_map_dialog(self, row: int):
fields[target_field_name] = self.qris_project.lookup_values[target_field['lookup']]

# open the value map dialog
frm = FrmFieldValueMap(self, input_field, values, fields)
frm = FrmFieldValueMap(input_field, values, fields)
if input_field in [field.src_field for field in self.field_maps]:
in_field = next((field for field in self.field_maps if field.src_field == input_field), None)
frm.load_field_value_map(in_field.map)
frm.field_value_map.connect(self.on_field_value_map)
frm.field_value_map_signal.connect(self.on_field_value_map)
frm.exec_()

def on_field_value_map(self, field_name: str, field_value_map: dict):
Expand Down

0 comments on commit 5057991

Please sign in to comment.