Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Python QGIS (PyQGIS) visibility preset manipulation functions
def visibility_presets():
"""Return the names of the visibility presets in a list."""
# List order should be the same as in GUI.
project = qgis.core.QgsProject.instance()
pr_coll = project.visibilityPresetCollection()
return pr_coll.presets()
def active_visibility_preset():
"""Return the name of the active visibility preset or
None if no active visibility preset."""
# Note that this function should match all layers
# first by visibility then by stylename.
project = qgis.core.QgsProject.instance()
pr_coll = project.visibilityPresetCollection()
legend = qgis.utils.iface.legendInterface()
visible_layers_ids = {l.id() for l in legend.layers()
if legend.isLayerVisible(l)}
for preset_name in pr_coll.presets():
pr_state = pr_coll.presetState(preset_name)
pr_visible_layer_ids = set(pr_state.mVisibleLayerIDs)
if pr_visible_layer_ids != visible_layers_ids:
continue
pr_style_by_layer_id = pr_state.mPerLayerCurrentStyle
#// alternatively //
#pr_visible_layer_ids = pr_coll.presetVisibleLayers(
# preset_name)
for layer in legend.layers():
id_ = layer.id()
#// alternatively //
#lreg = qgis.core.QgsMapLayerRegistry.instance()
#maplayers = lreg.mapLayers()
#for id_, layer in maplayers.items():
stylemanager = layer.styleManager()
curr_style = stylemanager.currentStyle()
if curr_style != pr_style_by_layer_id.get(id_, u''):
break
else: # finished without break
return preset_name
def activate_visibility_preset(preset_name):
"""Activates a visibility preset by its name.
Return a boolean indicating success."""
# Note that it iterates over all layers and turn them on or
# off then activate their named stlye according to the preset.
project = qgis.core.QgsProject.instance()
pr_coll = project.visibilityPresetCollection()
if preset_name not in pr_coll.presets():
return False
pr_state = pr_coll.presetState(preset_name)
pr_visible_layer_ids = pr_state.mVisibleLayerIDs
pr_style_by_layer_id = pr_state.mPerLayerCurrentStyle
legend = qgis.utils.iface.legendInterface()
for layer in legend.layers():
id_ = layer.id()
visible = legend.isLayerVisible(layer)
pr_visible = (id_ in pr_visible_layer_ids)
# turn the unvisible off and set style while hidden
if not pr_visible and visible:
legend.setLayerVisible(layer, False)
pr_layer_style_name = pr_style_by_layer_id.get(id_, u'')
stylemanager = layer.styleManager()
curr_style = stylemanager.currentStyle()
# set style only if differs assuming some overhead in it
if pr_layer_style_name != curr_style:
stylemanager.setCurrentStyle(pr_layer_style_name)
# now after style is matched, turn off if hidden but should
# be visible
if pr_visible and not visible:
legend.setLayerVisible(layer, True)
return True
@SzieberthAdam

This comment has been minimized.

Copy link
Owner Author

commented Sep 14, 2017

Usage:

>>> visibility_presets()
[u'Test-01']
>>> activate_visibility_preset(u'Test-01')
True
>>> active_visibility_preset()
u'Test-01'

Tested on QGIS version 2.18.6.
If you know how to improve it, please share it!

Code on GIS.StackExchange (if you star my code here I would appreciate an upvote there too)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.