AequilibraE / qaequilibrae

Free QGIS add-on for transportation modeling
https://www.aequilibrae.com/qgis/latest/
Other
75 stars 24 forks source link

BUG: Fix use of backgroundcolor in stacked bandwidths #297

Closed m-richards closed 7 months ago

m-richards commented 7 months ago

In the stacked bandwidths dialogue: image the up and down buttons don't seem to work on newer versions of QGIS: image

I'm seeing this on QGIS 3.34 (and I think 3.28 as well). I assume this is to do with the version of Qt (QGIS 3.34 comes with Qt 5.15.3) but I can't seem to find a corresponding changelog where backgroundColor was removed (apparently in the cpp it's just obsolete but not removed: https://doc.qt.io/qt-5/qtablewidgetitem-obsolete.html ?). I'm not sure of backwards compatibility requirements / what promises the qaequilbrae plugin makes, but background seems to exist back to Qt 4.2 (https://doc.qt.io/qt-5/qtablewidgetitem.html#background).

(I've also set the default layer in the stacked bandwidths dialogue to be the selected layer, but can revert that if it's not desired)

pedrocamargo commented 7 months ago

Excellent contribution, @m-richards . Thank you!

m-richards commented 7 months ago

Separately I was wondering if there's any appetite to add some functionality to make it easier to inspect which colours correspond to which fields after creating stacked bandwidths. I've been doing this a few times recently and have found myself taking screenshots of the creation dialogue as reference when using the layer. Some thoughts I had on this were to either

If there's interest I'd be happy to contribute a PR along one of these lines (or other suggestions), but appreciate this isn't exactly core functionality for the plugin, so perhaps it's overkill.

pedrocamargo commented 7 months ago

That would be excellent to have indeed.

I have recently added this (idea No. 1) to Polaris, so I do have some code I could port to QAequilibraE if you'd like.

Maintaining states in QAequilibraE is something I have long wanted to do, and my plan was to add a yaml/json to the temp folder in order to do that. I currently do something in those lines in QPolaris, but that's just for the opening of projects...

pedrocamargo commented 7 months ago

The QPolaris code borrowed a lot from QAequilibraE, so the code below should be helpful

color legend (in that case it is not for stacked, but rather for a color ramp)

    legend_steps = 5
    color_layer = QgsVectorLayer("LineString?crs=4326", f"{self.color_results.metric_name} (Color)", "memory")
    symbol = QgsSymbol.defaultSymbol(color_layer.geometryType())
    symbol.setWidth(2)
    renderer = QgsRuleBasedRenderer(symbol)

    ref_style = QgsStyle().defaultStyle()
    color_ramp = ref_style.colorRamp(self.color_ramp)
    max_legend = self.maxcolor / self.dsp_color_thresh.value()
    for interval in range(legend_steps + 1):
        val = interval / legend_steps
        rule = renderer.rootRule().children()[0].clone()
        label = f"{(val * max_legend):,.2f}" if max_legend < 100 else f"{int(val * max_legend):,}"
        rule.setLabel(label)
        rule.symbol().setColor(color_ramp.color(val))
        renderer.rootRule().appendChild(rule)

Thickness legend

    legend_steps = 5
    width_layer = QgsVectorLayer("LineString?crs=4326", f"{self.results.metric_name} (Width)", "memory")
    symbol = QgsSymbol.defaultSymbol(width_layer.geometryType())
    symbol.setWidth(0.001)
    symbol.setColor(QColor("#000000"))

    renderer = QgsRuleBasedRenderer(symbol)
    max_legend = self.maxwidth / self.dsp_thick.value()
    for interval in range(legend_steps + 1):
        val = interval / legend_steps
        rule = renderer.rootRule().children()[0].clone()
        label = f"{(val * max_legend):,.2f}" if max_legend < 100 else f"{int(val * max_legend):,}"
        rule.setLabel(label)
        rule.symbol().setWidth(val * self.__map_width)
        renderer.rootRule().appendChild(rule)

    # remove first child
    renderer.rootRule().removeChildAt(0)
    width_layer.setRenderer(renderer)
    QgsProject.instance().addMapLayer(width_layer)
    width_layer.triggerRepaint()
m-richards commented 7 months ago

That would be excellent to have indeed.

I have recently added this (idea No. 1) to Polaris, so I do have some code I could port to QAequilibraE if you'd like.

Maintaining states in QAequilibraE is something I have long wanted to do, and my plan was to add a yaml/json to the temp folder in order to do that. I currently do something in those lines in QPolaris, but that's just for the opening of projects...

Thanks for the starting point snippet - I'll go with 1 for now then - it's the simplest starting point and it's not incompatible with persisting state later either.