Bug report #20871

Style "Meters at scale" hogs CPU

Added by Daniel Krüger almost 2 years ago. Updated over 1 year ago.

Status:Open
Priority:Normal
Assignee:-
Category:Symbology
Affected QGIS version:3.4.2 Regression?:No
Operating System:Linux/Xubuntu 18.04.1 Easy fix?:No
Pull Request or Patch supplied:No Resolution:
Crashes QGIS or corrupts data:No Copied to github as #:28690

Description

After selecting "Meters at scale" option in a style QGIS becomes unresponsive for couple of seconds to several minutes. This involves at least the following situations:
  • Opening the project takes several minutes
  • Opening the layer settings which contains the "Meters at scale" option
  • Clicking on an item in the symbol tree
  • Changing an option of an item in the symbol tree

I attached gdb to a running QGIS process and pressed CTRL-C when clicking on symbol tab sheet in layer settings and the dialog got unresponsive for a minute or so. Maybe this helps a little bit.

Thread 1 "qgis.bin" received signal SIGINT, Interrupt.
0x00007fc790791fac in __sin_local (x=2.3596955266584345e-07) at ../sysdeps/ieee754/dbl-64/s_sin.c:473
473    ../sysdeps/ieee754/dbl-64/s_sin.c: Datei oder Verzeichnis nicht gefunden.
(gdb) bac
#0  0x00007fc790791fac in __sin_local (x=2.3596955266584345e-07) at ../sysdeps/ieee754/dbl-64/s_sin.c:473
#1  0x00007fc790791fac in __sincos (x=2.3596955266584345e-07, sinx=0x7ffc5e7817b8, cosx=0x7ffc5e7817b0) at ../sysdeps/ieee754/dbl-64/s_sincos.c:75
#2  0x00007fc79ba94d61 in QgsDistanceArea::computeSpheroidProject(QgsPointXY const&, double, double) const () at /usr/lib/libqgis_core.so.3.4.2
#3  0x00007fc79ba9527a in QgsDistanceArea::measureLineProjected(QgsPointXY const&, double, double, QgsPointXY*) const () at /usr/lib/libqgis_core.so.3.4.2
#4  0x00007fc79bc4459c in QgsRenderContext::convertMetersToMapUnits(double) const () at /usr/lib/libqgis_core.so.3.4.2
#5  0x00007fc79bc44715 in QgsRenderContext::convertToPainterUnits(double, QgsUnitTypes::RenderUnit, QgsMapUnitScale const&) const () at /usr/lib/libqgis_core.so.3.4.2
#6  0x00007fc79b8395fd in QgsMarkerSymbolLayer::markerOffset(QgsSymbolRenderContext&, double, double, QgsUnitTypes::RenderUnit, QgsUnitTypes::RenderUnit, double&, double&, QgsMapUnitScale const&, QgsMapUnitScale const&) const () at /usr/lib/libqgis_core.so.3.4.2
#7  0x00007fc79b8397af in QgsMarkerSymbolLayer::markerOffset(QgsSymbolRenderContext&, double, double, double&, double&) const () at /usr/lib/libqgis_core.so.3.4.2
#8  0x00007fc79b7f5c16 in QgsSimpleMarkerSymbolLayerBase::calculateOffsetAndRotation(QgsSymbolRenderContext&, double, bool&, QPointF&, double&) const () at /usr/lib/libqgis_core.so.3.4.2
#9  0x00007fc79b7f9646 in QgsSimpleMarkerSymbolLayerBase::renderPoint(QPointF, QgsSymbolRenderContext&) () at /usr/lib/libqgis_core.so.3.4.2
#10 0x00007fc79b7f9bfd in QgsSimpleMarkerSymbolLayer::renderPoint(QPointF, QgsSymbolRenderContext&) () at /usr/lib/libqgis_core.so.3.4.2
#11 0x00007fc79b864b31 in QgsMarkerSymbol::renderPointUsingLayer(QgsMarkerSymbolLayer*, QPointF, QgsSymbolRenderContext&) () at /usr/lib/libqgis_core.so.3.4.2
#12 0x00007fc79b86bb1d in QgsMarkerSymbol::renderPoint(QPointF, QgsFeature const*, QgsRenderContext&, int, bool) () at /usr/lib/libqgis_core.so.3.4.2
#13 0x00007fc79b7e9a5d in QgsMarkerLineSymbolLayer::renderPolylineInterval(QPolygonF const&, QgsSymbolRenderContext&) () at /usr/lib/libqgis_core.so.3.4.2
#14 0x00007fc79b7ead88 in QgsMarkerLineSymbolLayer::renderPolyline(QPolygonF const&, QgsSymbolRenderContext&) () at /usr/lib/libqgis_core.so.3.4.2
#15 0x00007fc79b839c0e in QgsLineSymbolLayer::drawPreviewIcon(QgsSymbolRenderContext&, QSize) () at /usr/lib/libqgis_core.so.3.4.2
#16 0x00007fc79b85ff0c in QgsSymbolLayerUtils::symbolLayerPreviewPicture(QgsSymbolLayer*, QgsUnitTypes::RenderUnit, QSize, QgsMapUnitScale const&) () at /usr/lib/libqgis_core.so.3.4.2
#17 0x00007fc7973e9788 in QgsLayerPropertiesWidget::emitSignalChanged() () at /usr/lib/libqgis_gui.so.3.4.2
#18 0x00007fc799f1e6cf in QMetaObject::activate(QObject*, int, int, void**) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#19 0x00007fc79ad5ebe2 in QAbstractButton::toggled(bool) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#20 0x00007fc79ad5f001 in  () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#21 0x00007fc79ad60606 in QAbstractButton::setChecked(bool) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#22 0x00007fc7973e7400 in QgsLayerPropertiesWidget::QgsLayerPropertiesWidget(QgsSymbolLayer*, QgsSymbol const*, QgsVectorLayer*, QWidget*) () at /usr/lib/libqgis_gui.so.3.4.2
#23 0x00007fc797474255 in QgsSymbolSelectorWidget::layerChanged() () at /usr/lib/libqgis_gui.so.3.4.2
#24 0x00007fc799f1e6cf in QMetaObject::activate(QObject*, int, int, void**) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#25 0x00007fc799e9b67a in QItemSelectionModel::currentChanged(QModelIndex const&, QModelIndex const&) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#26 0x00007fc799e9b96e in QItemSelectionModel::setCurrentIndex(QModelIndex const&, QFlags<QItemSelectionModel::SelectionFlag>) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#27 0x00007fc79aebba4c in QAbstractItemView::mousePressEvent(QMouseEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#28 0x00007fc79af29a7b in QTreeView::mousePressEvent(QMouseEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#29 0x00007fc79acac98f in QWidget::event(QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#30 0x00007fc79ad4d4be in QFrame::event(QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#31 0x00007fc79aec0b3b in QAbstractItemView::viewportEvent(QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5

Bug report #18399 seems to be the same. However I cannot reopen it.

Böschung_3m.qml - Style with "meters at scale" which causes 100% CPU load (11.5 KB) Daniel Krüger, 2018-12-22 10:02 PM

uncertain borders.qgz (7.12 KB) Johannes Kroeger, 2019-02-21 08:40 PM

History

#1 Updated by Daniel Krüger over 1 year ago

I made some further debugging with Callgrind and added some qDebug() output to QgsMarkerLineSymbolLayer::renderPolylineInterval().

It seems that QgsSymbolLayerUtils::symbolLayerPreviewPicture() needs a large processing time for generating the icon. That's because it uses some default QgsRenderContext with default ellipsoid. So it draws millions of markers (repeated every 3 meters at scale) on the icon.

Where is the right place to fix this scaling issue?

If someone is interested I can provide a small test project. It takes a couple of minutes for opening the project.

#2 Updated by Johannes Kroeger over 1 year ago

I just ran into this option behaving weirdly and hogging CPU as well. In my case it is NOT hogging CPU when the canvas is EPSG:4326 but it is if the canvas is for example EPSG:3857 or EPSG:25832 (UTM32N).

Here is an example project, set the OTF projection to trigger the CPU hogging. You might need to pan around a bit to make it happen. Data is https://www.naturalearthdata.com/http//www.naturalearthdata.com/download/10m/cultural/ne_10m_admin_0_countries.zip

Also available in: Atom PDF