32 SetMarkerRotationVisitor(
const QString &rotationField )
33 : mRotationField( rotationField )
49 QString mRotationField;
57 SetMarkerRotationPostProcessor( std::unique_ptr< QgsFeatureRenderer > renderer,
const QString &rotationField )
58 : mRenderer( std::move( renderer ) )
59 , mRotationField( rotationField )
64 if (
QgsVectorLayer *vl = qobject_cast< QgsVectorLayer * >( layer ) )
66 SetMarkerRotationVisitor visitor( mRotationField );
67 mRenderer->accept( &visitor );
68 vl->setRenderer( mRenderer.release() );
75 std::unique_ptr<QgsFeatureRenderer> mRenderer;
76 QString mRotationField;
79 QString QgsAngleToNearestAlgorithm::name()
const
81 return QStringLiteral(
"angletonearest" );
84 QString QgsAngleToNearestAlgorithm::displayName()
const
86 return QObject::tr(
"Align points to features" );
89 QStringList QgsAngleToNearestAlgorithm::tags()
const
91 return QObject::tr(
"align,marker,stroke,fill,orient,points,lines,angles,rotation,rotate" ).split(
',' );
94 QString QgsAngleToNearestAlgorithm::group()
const
96 return QObject::tr(
"Cartography" );
99 QString QgsAngleToNearestAlgorithm::groupId()
const
101 return QStringLiteral(
"cartography" );
104 QgsAngleToNearestAlgorithm::~QgsAngleToNearestAlgorithm() =
default;
106 void QgsAngleToNearestAlgorithm::initAlgorithm(
const QVariantMap &configuration )
108 mIsInPlace = configuration.value( QStringLiteral(
"IN_PLACE" ) ).toBool();
113 QObject::tr(
"Reference layer" ) ) );
116 QObject::tr(
"Maximum distance to consider" ), QVariant(), QStringLiteral(
"INPUT" ),
true, 0 ) );
119 addParameter(
new QgsProcessingParameterString( QStringLiteral(
"FIELD_NAME" ), QObject::tr(
"Angle field name" ), QStringLiteral(
"rotation" ) ) );
121 addParameter(
new QgsProcessingParameterField( QStringLiteral(
"FIELD_NAME" ), QObject::tr(
"Angle field name" ), QStringLiteral(
"rotation" ), QStringLiteral(
"INPUT" ) ) );
123 addParameter(
new QgsProcessingParameterBoolean( QStringLiteral(
"APPLY_SYMBOLOGY" ), QObject::tr(
"Automatically apply symbology" ),
true ) );
128 QgsProcessingAlgorithm::Flags QgsAngleToNearestAlgorithm::flags()
const
135 QString QgsAngleToNearestAlgorithm::shortHelpString()
const
137 return QObject::tr(
"This algorithm calculates the rotation required to align point features with their nearest "
138 "feature from another reference layer. A new field is added to the output layer which is filled with the angle "
139 "(in degrees, clockwise) to the nearest reference feature.\n\n"
140 "Optionally, the output layer's symbology can be set to automatically use the calculated rotation "
141 "field to rotate marker symbols.\n\n"
142 "If desired, a maximum distance to use when aligning points can be set, to avoid aligning isolated points "
143 "to distant features." );
146 QString QgsAngleToNearestAlgorithm::shortDescription()
const
148 return QObject::tr(
"Rotates point features to align them to nearby features." );
151 QgsAngleToNearestAlgorithm *QgsAngleToNearestAlgorithm::createInstance()
const
153 return new QgsAngleToNearestAlgorithm();
156 bool QgsAngleToNearestAlgorithm::supportInPlaceEdit(
const QgsMapLayer *layer )
const
158 if (
const QgsVectorLayer *vl = qobject_cast< const QgsVectorLayer * >( layer ) )
169 if (
QgsVectorLayer *sourceLayer = parameterAsVectorLayer( parameters, QStringLiteral(
"INPUT" ), context ) )
171 mSourceRenderer.reset( sourceLayer->renderer()->clone() );
180 const double maxDistance = parameters.value( QStringLiteral(
"MAX_DISTANCE" ) ).isValid() ? parameterAsDouble( parameters, QStringLiteral(
"MAX_DISTANCE" ), context ) : std::numeric_limits< double >::quiet_NaN();
181 std::unique_ptr< QgsProcessingFeatureSource > input( parameterAsSource( parameters, QStringLiteral(
"INPUT" ), context ) );
185 std::unique_ptr< QgsProcessingFeatureSource > referenceSource( parameterAsSource( parameters, QStringLiteral(
"REFERENCE_LAYER" ), context ) );
186 if ( !referenceSource )
189 const QString fieldName = parameterAsString( parameters, QStringLiteral(
"FIELD_NAME" ), context );
203 std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral(
"OUTPUT" ), context, dest, outFields,
204 input->wkbType(), input->sourceCrs() ) );
205 if ( parameters.value( QStringLiteral(
"OUTPUT" ) ).isValid() && !sink )
210 double step = referenceSource->featureCount() > 0 ? 50.0 / referenceSource->featureCount() : 1;
226 step = input->featureCount() > 0 ? 50.0 / input->featureCount() : 1;
241 if ( !f.hasGeometry() )
244 attributes.append( QVariant() );
246 attributes[ fieldIndex ] = QVariant();
247 f.setAttributes( attributes );
253 const QList< QgsFeatureId > nearest = index.nearestNeighbor( f.geometry(), 1, std::isnan( maxDistance ) ? 0 : maxDistance );
254 if ( nearest.empty() )
256 feedback->
pushInfo( QObject::tr(
"No matching features found within search distance" ) );
258 attributes.append( QVariant() );
260 attributes[ fieldIndex ] = QVariant();
261 f.setAttributes( attributes );
267 if ( nearest.count() > 1 )
269 feedback->
pushInfo( QObject::tr(
"Multiple matching features found at same distance from search feature, found %1 features" ).arg( nearest.count() ) );
276 attributes.append( line->startPoint().azimuth( line->endPoint() ) );
278 attributes[ fieldIndex ] = line->startPoint().azimuth( line->endPoint() );
283 attributes.append( QVariant() );
285 attributes[ fieldIndex ] = QVariant();
287 f.setAttributes( attributes );
294 const bool applySymbology = parameterAsBool( parameters, QStringLiteral(
"APPLY_SYMBOLOGY" ), context );
295 if ( applySymbology )
301 QVariantMap inPlaceParams = parameters;
302 inPlaceParams.insert( QStringLiteral(
"INPUT" ), parameters.value( QStringLiteral(
"INPUT" ) ).value< QgsProcessingFeatureSourceDefinition >().source );
303 if (
QgsVectorLayer *sourceLayer = parameterAsVectorLayer( inPlaceParams, QStringLiteral(
"INPUT" ), context ) )
305 std::unique_ptr< QgsFeatureRenderer > sourceRenderer( sourceLayer->renderer()->clone() );
306 SetMarkerRotationPostProcessor processor( std::move( sourceRenderer ), fieldName );
307 processor.postProcessLayer( sourceLayer, context, feedback );
317 outputs.insert( QStringLiteral(
"OUTPUT" ), dest );
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
This class wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setNoAttributes()
Set that no attributes will be fetched.
@ FastInsert
Use faster inserts, at the cost of updating the passed features to reflect changes made at the provid...
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
bool isCanceled() const SIP_HOLDGIL
Tells whether the operation has been canceled already.
void setProgress(double progress)
Sets the current progress for the feedback object.
Encapsulate a field in an attribute table or data source.
Container of fields for a vector layer.
bool append(const QgsField &field, FieldOrigin origin=OriginProvider, int originIndex=-1)
Appends a field. The field must have unique name, otherwise it is rejected (returns false)
int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
A geometry is the spatial representation of a feature.
const QgsAbstractGeometry * constGet() const SIP_HOLDGIL
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
QgsGeometry shortestLine(const QgsGeometry &other) const
Returns the shortest line joining this geometry to another geometry.
Line string geometry type, with support for z-dimension and m-values.
Base class for all map layer types.
A marker symbol type, for rendering Point and MultiPoint geometries.
virtual Flags flags() const
Returns the flags indicating how and when the algorithm operates and should be exposed to users.
@ FlagSupportsInPlaceEdits
Algorithm supports in-place editing.
void setPostProcessor(QgsProcessingLayerPostProcessorInterface *processor)
Sets the layer post-processor.
Contains information about the context in which a processing algorithm is executed.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context.
bool willLoadLayerOnCompletion(const QString &layer) const
Returns true if the given layer (by ID or datasource) will be loaded into the current project upon co...
QgsProcessingContext::LayerDetails & layerToLoadOnCompletionDetails(const QString &layer)
Returns a reference to the details for a given layer which is loaded on completion of the algorithm o...
Custom exception class for processing related exceptions.
Base class for providing feedback from a processing algorithm.
virtual void pushInfo(const QString &info)
Pushes a general informational message from the algorithm.
An interface for layer post-processing handlers for execution following a processing algorithm operat...
virtual void postProcessLayer(QgsMapLayer *layer, QgsProcessingContext &context, QgsProcessingFeedback *feedback)=0
Post-processes the specified layer, following successful execution of a processing algorithm.
A boolean parameter for processing algorithms.
A double numeric parameter for distance values.
A feature sink output for processing algorithms.
An input feature source (such as vector layers) parameter for processing algorithms.
A vector layer or feature source field parameter for processing algorithms.
A string parameter for processing algorithms.
@ TypeVectorPoint
Vector point layers.
static QgsProperty fromField(const QString &fieldName, bool isActive=true)
Returns a new FieldBasedProperty created from the specified field name.
A spatial index for QgsFeature objects.
@ FlagStoreFeatureGeometries
Indicates that the spatial index should also store feature geometries. This requires more memory,...
An interface for classes which can visit style entity (e.g.
virtual bool visit(const QgsStyleEntityVisitorInterface::StyleLeaf &entity)
Called when the visitor will visit a style entity.
A symbol entity for QgsStyle databases.
Represents a vector layer which manages a vector based data sets.
Contains information relating to the style entity currently being visited.
const QgsStyleEntityInterface * entity
Reference to style entity being visited.