QGIS/src/analysis/processing/qgsalgorithmorientedminimumboundingbox.cpp
2024-05-31 08:46:33 +10:00

128 lines
4.5 KiB
C++

/***************************************************************************
qgsalgorithmorientedminimumboundingbox.cpp
---------------------
begin : April 2017
copyright : (C) 2017 by Nyall Dawson
email : nyall dot dawson at gmail dot com
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgsalgorithmorientedminimumboundingbox.h"
#include "qgsvectorlayer.h"
///@cond PRIVATE
QString QgsOrientedMinimumBoundingBoxAlgorithm::name() const
{
return QStringLiteral( "orientedminimumboundingbox" );
}
QString QgsOrientedMinimumBoundingBoxAlgorithm::displayName() const
{
return QObject::tr( "Oriented minimum bounding box" );
}
QStringList QgsOrientedMinimumBoundingBoxAlgorithm::tags() const
{
return QObject::tr( "bounding,boxes,envelope,rectangle,extent,oriented,angle" ).split( ',' );
}
QString QgsOrientedMinimumBoundingBoxAlgorithm::group() const
{
return QObject::tr( "Vector geometry" );
}
QString QgsOrientedMinimumBoundingBoxAlgorithm::groupId() const
{
return QStringLiteral( "vectorgeometry" );
}
QString QgsOrientedMinimumBoundingBoxAlgorithm::outputName() const
{
return QObject::tr( "Bounding boxes" );
}
Qgis::WkbType QgsOrientedMinimumBoundingBoxAlgorithm::outputWkbType( Qgis::WkbType ) const
{
return Qgis::WkbType::Polygon;
}
QString QgsOrientedMinimumBoundingBoxAlgorithm::shortHelpString() const
{
return QObject::tr( "This algorithm calculates the minimum area rotated rectangle which covers each feature in an input layer." ) +
QStringLiteral( "\n\n" ) +
QObject::tr( "See the 'Minimum bounding geometry' algorithm for a oriented bounding box calculation which covers the whole layer or grouped subsets of features." );
}
QgsOrientedMinimumBoundingBoxAlgorithm *QgsOrientedMinimumBoundingBoxAlgorithm::createInstance() const
{
return new QgsOrientedMinimumBoundingBoxAlgorithm();
}
bool QgsOrientedMinimumBoundingBoxAlgorithm::supportInPlaceEdit( const QgsMapLayer *l ) const
{
const QgsVectorLayer *layer = qobject_cast< const QgsVectorLayer * >( l );
if ( !layer )
return false;
if ( ! QgsProcessingFeatureBasedAlgorithm::supportInPlaceEdit( layer ) )
return false;
// Polygons only
return layer->wkbType() == Qgis::WkbType::Polygon || layer->wkbType() == Qgis::WkbType::MultiPolygon;
}
QgsFields QgsOrientedMinimumBoundingBoxAlgorithm::outputFields( const QgsFields &inputFields ) const
{
QgsFields fields = inputFields;
fields.append( QgsField( QStringLiteral( "width" ), QMetaType::Type::Double, QString(), 20, 6 ) );
fields.append( QgsField( QStringLiteral( "height" ), QMetaType::Type::Double, QString(), 20, 6 ) );
fields.append( QgsField( QStringLiteral( "angle" ), QMetaType::Type::Double, QString(), 20, 6 ) );
fields.append( QgsField( QStringLiteral( "area" ), QMetaType::Type::Double, QString(), 20, 6 ) );
fields.append( QgsField( QStringLiteral( "perimeter" ), QMetaType::Type::Double, QString(), 20, 6 ) );
return fields;
}
QgsFeatureList QgsOrientedMinimumBoundingBoxAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &, QgsProcessingFeedback * )
{
QgsFeature f = feature;
if ( f.hasGeometry() )
{
double area = 0;
double angle = 0;
double width = 0;
double height = 0;
const QgsGeometry outputGeometry = f.geometry().orientedMinimumBoundingBox( area, angle, width, height );
f.setGeometry( outputGeometry );
QgsAttributes attrs = f.attributes();
attrs << width
<< height
<< angle
<< area
<< 2 * width + 2 * height;
f.setAttributes( attrs );
}
else
{
QgsAttributes attrs = f.attributes();
attrs << QVariant()
<< QVariant()
<< QVariant()
<< QVariant()
<< QVariant();
f.setAttributes( attrs );
}
return QgsFeatureList() << f;
}
///@endcond