Not an ideal implementation (too much logic resides in the
gui QgsMapCanvasAnnotationItem class), but any approach
using current api will be dependant on some hacks.
Ideally we need a QgsVectorDataProvider method for finding
the closest feature(s) to a point(/line/polygon) within a
certain tolerance, with provider specific implementations
which offload this to the data store's spatial indices.
Then this handling could be bumped up to reside in
QgsAnnotation.
Previously only some annotations had (incomplete) support for
attaching to a particular vector layer and synchronising their
visibility with the layer's visibility.
This handling has all been moved up to QgsAnnotation, so that
all annotation types can be attached to layers.
This will allow selective annotation visibility based on the
visible layers of a particular canvas, eg in multi-canvas
environments.
Additionally:
- show the attached layer in the annotation properties
dialog, and allow it to be cleared to always show the
annotation
- allow attaching annotations to non-vector layers
- add unit tests for visibility
Splits the rendering component of annotations out from map
canvas item component.
A new core abstract base class QgsAnnotation handles the
management of the common properties associated with an
annotation, and handles rendering the annotation onto a
QgsRenderContext destination.
Existing annotation classes have been ported to this, and
with the exception of the form annotation moved into core.
Form annotations are dependant on editor widgets and must
remain in GUI.
A new QgsMapCanvasAnnotationItem item class implements
a QgsMapCanvasItem which draws an annotation inside the
canvas, and handles synchronising the position and size
of the canvas item with the QgsAnnotation position/size.
This allows annotations to be safely used in a multi-canvas
environment, with a single QgsAnnotation being displayed
in multiple canvases (even if the canvases have different
extent/crs/etc).
Additionally it allows annotations to be directly rendered
to a map (eg in composer) without going through the
gui based Qt graphics scene framework.
Also removes lots of duplicate code, and adds some basic
unit tests for annotations.
Allows projection of a point with inclination to return a 3d point.
Expression "project" function has been extended to support a new inclination parameter.
This introduces QgsGeometry::makeValid() which will try to make a valid
geometry out of invalid one. This is more complicated method than just
doing a buffer with zero width, but it should not loose any vertices.
Finally we should have a reliable way in QGIS to fix bad geometries!
Ported the C code from lwgeom library to QGIS.
Another bit in the project refactoring work to get rid of dependencies
on QgsProject singleton.
Reading of layer trees from XML is now split into two phases:
1. read XML and keep layer IDs
2. resolve layer IDs to QgsMapLayer instances (using QgsProject)
There are convenience methods to do both phases in one go.
Avoids confusing overload behavior when constructing QgsRasterLayers
from c++ code. This extra constructor was causing character literals
to be converted to a boolean loadDefaultStyle flag instead
of being used as the provider key. Removing the extra constructor
avoids this, and removes some duplicate code.
... rather than using QgsProject::instance() internally
These are small cleanups to dig out some instance() uses and move them one level up...
At some point we should maybe make labeling engine configuration a part of QgsMapSettings
and have default project labeling engine config accessible from QgsProject
in a way similar to e.g. snapping configuration.