Skip to content

Commit

Permalink
Remove XML replacement and use the native API setDataSource
Browse files Browse the repository at this point in the history
  • Loading branch information
Gustry committed Aug 28, 2024
1 parent 5265ba9 commit 7648dd1
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 45 deletions.
77 changes: 35 additions & 42 deletions dynamic_layers/core/layer_datasource_modifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,8 @@
QgsProcessingException,
QgsProcessingFeedback,
QgsProject,
QgsReadWriteContext,
QgsVectorLayer,
)
from qgis.PyQt.QtXml import QDomDocument

from dynamic_layers.definitions import CustomProperty
from dynamic_layers.tools import log_message, string_substitution, tr
Expand Down Expand Up @@ -76,28 +74,20 @@ def set_data_source(self, new_source_uri: str):
"""
Method to apply a new datasource to a vector Layer
"""
# TODO :: Change to QgsMapLayer::setDataSource
context = QgsReadWriteContext()
new_ds, new_uri = self.split_source(new_source_uri)
new_datasource_type = new_ds or self.layer.dataProvider().name()

# read layer definition
xml_document = QDomDocument("style")
# XMLMapLayers = QDomElement()
xml_map_layers = xml_document.createElement("maplayers")
# XMLMapLayer = QDomElement()
xml_map_layer = xml_document.createElement("maplayer")
self.layer.writeLayerXml(xml_map_layer, xml_document, context)

# apply layer definition
xml_map_layer.firstChildElement("datasource").firstChild().setNodeValue(new_uri)
xml_map_layer.firstChildElement("provider").firstChild().setNodeValue(new_datasource_type)
xml_map_layers.appendChild(xml_map_layer)
xml_document.appendChild(xml_map_layers)
self.layer.readLayerXml(xml_map_layer, context)
self.layer.setDataSource(new_source_uri, self.layer.name(), self.layer.dataProvider().name())

if not self.layer.isValid():
log_message(
tr(
"Error, layer '{name}' is not valid, error : {error}"
).format(self.layer.name(), self.layer.error()),
Qgis.Critical,
self.feedback,
)
return

# Update layer extent
self.layer.updateExtents()
self.layer.updateExtents(True)

# Update graduated symbol renderer
if self.layer.renderer() and self.layer.renderer().type() == 'graduatedSymbol':
Expand All @@ -107,6 +97,7 @@ def set_data_source(self, new_source_uri: str):

# Reload layer
self.layer.reload()
# self.layer.triggerRepaint()

@staticmethod
def split_source(source: str) -> typing.Tuple[str, str]:
Expand Down Expand Up @@ -192,23 +183,25 @@ def set_dynamic_layer_properties(self, search_and_replace_dictionary: dict = Non
)
self.layer.setAbstract(abstract)

# Set fields aliases
if self.layer.type() == QgsMapLayer.VectorLayer:
for fid, field in enumerate(self.layer.fields()):
alias = self.layer.attributeAlias(fid)
if not alias:
continue

log_message(
tr("Compute new value for layer {} field alias {}").format(self.layer.name(), alias),
Qgis.Info,
self.feedback,
)
new_alias = string_substitution(
input_string=alias,
variables=search_and_replace_dictionary,
project=self.project,
layer=self.layer,
feature=self.feature,
)
self.layer.setFieldAlias(fid, new_alias)
return

# # Set fields aliases
# if self.layer.type() == QgsMapLayer.VectorLayer:
# for fid, field in enumerate(self.layer.fields()):
# alias = self.layer.attributeAlias(fid)
# if not alias:
# continue
#
# log_message(
# tr("Compute new value for layer {} field alias {}").format(self.layer.name(), alias),
# Qgis.Info,
# self.feedback,
# )
# new_alias = string_substitution(
# input_string=alias,
# variables=search_and_replace_dictionary,
# project=self.project,
# layer=self.layer,
# feature=self.feature,
# )
# self.layer.setFieldAlias(fid, new_alias)
24 changes: 21 additions & 3 deletions dynamic_layers/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ def string_substitution(
feedback: QgsProcessingFeedback = None,
) -> str:
""" String substitution. """
if not input_string:
msg = tr("No expression to evaluate, returning empty string")
log_message(msg, Qgis.Info, feedback)
return ""

msg = tr(
"Evaluation of the expression '{expression}' \n"
"with variables :\n").format(expression=input_string)
Expand Down Expand Up @@ -73,7 +78,9 @@ def string_substitution(

expression = QgsExpression(input_string)
if expression.hasEvalError() or expression.hasParserError():
raise QgsProcessingException(tr("Invalid QGIS expression : {}").format(input_string))
msg = tr("Invalid QGIS expression : {}").format(input_string)
log_message(msg, Qgis.Critical, feedback)
raise QgsProcessingException(msg)

output = expression.evaluate(context)
msg = tr("Output is {}").format(output)
Expand All @@ -84,9 +91,10 @@ def string_substitution(

def log_message(msg: str, level: Qgis.MessageLevel = Qgis.Info, feedback: QgsProcessingFeedback = None):
""" Log a message, either in the log panel, or in the Processing UI panel. """
# noinspection PyTypeChecker
QgsMessageLog.logMessage(msg, PLUGIN_MESSAGE, level)

if not feedback:
# noinspection PyTypeChecker
QgsMessageLog.logMessage(msg, PLUGIN_MESSAGE, level)
return

if level == Qgis.Warning:
Expand All @@ -101,6 +109,16 @@ def log_message(msg: str, level: Qgis.MessageLevel = Qgis.Info, feedback: QgsPro
feedback.pushDebugInfo(msg)


def format_expression(input_text: str, is_expression: bool = True) -> str:
""" Format the text if it's an expression. """
if not is_expression:
return input_text

# Escaping ' to \'
input_text = input_text.replace("'", "\\'")
input_text = f"'{input_text}'"
return input_text


def plugin_path(*args) -> Path:
"""Return the path to the plugin root folder."""
Expand Down

0 comments on commit 7648dd1

Please sign in to comment.