Skip to content

port Minimum bounding geometry algorithm to C++ #62594

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

alexbruy
Copy link
Contributor

Description

Port Processing Minimum bounding geometry algorithm from Python to C++.

@alexbruy alexbruy added the Processing Relating to QGIS Processing framework or individual Processing algorithms label Jul 15, 2025
@github-actions github-actions bot added this to the 3.46.0 milestone Jul 15, 2025
Copy link
Contributor

github-actions bot commented Jul 15, 2025

🍎 MacOS Qt6 builds

Download MacOS Qt6 builds of this PR for testing.
This installer is not signed, control+click > open the app to avoid the warning
(Built from commit e93e8f0)

🪟 Windows builds

Download Windows builds of this PR for testing.
Debug symbols for this build are available here.
(Built from commit e93e8f0)

🪟 Windows Qt6 builds

Download Windows Qt6 builds of this PR for testing.
(Built from commit e93e8f0)

@alexbruy alexbruy force-pushed the processing-min-bounding-geometry-cpp branch 2 times, most recently from 5a37812 to 2031a99 Compare July 16, 2025 15:18
Comment on lines 180 to 186
if ( !geometryHash.contains( fieldValue ) )
{
geometryHash.insert( fieldValue, QVector<QgsGeometry>() << f.geometry() );
}
else
{
geometryHash.insert( fieldValue, geometryHash[fieldValue] << f.geometry() );
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if ( !geometryHash.contains( fieldValue ) )
{
geometryHash.insert( fieldValue, QVector<QgsGeometry>() << f.geometry() );
}
else
{
geometryHash.insert( fieldValue, geometryHash[fieldValue] << f.geometry() );
auto geometryHashIt = geometryHash.constFind( fieldValue );
if ( geometryHashIt == geometryHash.constEnd() )
{
geometryHash.insert( fieldValue, QVector<QgsGeometry>() << f.geometry() );
}
else
{
geometryHash.insert( fieldValue, geometryHashIt.value() << f.geometry() );

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to me, that we need to use non-const find() here as we modify iterator value in the else branch.

@DelazJ
Copy link
Contributor

DelazJ commented Jul 22, 2025

If not done (afaict, not yet in the help text), should we also cover the situation where a group or layer would contain one singlepart point feature, as done in #62300?

@alexbruy alexbruy force-pushed the processing-min-bounding-geometry-cpp branch from 2031a99 to e93e8f0 Compare July 22, 2025 14:25
Comment on lines +167 to +176
auto boundsHashIt = boundsHash.constFind( fieldValue );
if ( boundsHashIt == boundsHash.constEnd() )
{
boundsHash.insert( fieldValue, f.geometry().boundingBox() );
}
else
{
QgsRectangle r = boundsHashIt.value();
r.combineExtentWith( f.geometry().boundingBox() );
boundsHash.insert( fieldValue, r );
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this work?

Suggested change
auto boundsHashIt = boundsHash.constFind( fieldValue );
if ( boundsHashIt == boundsHash.constEnd() )
{
boundsHash.insert( fieldValue, f.geometry().boundingBox() );
}
else
{
QgsRectangle r = boundsHashIt.value();
r.combineExtentWith( f.geometry().boundingBox() );
boundsHash.insert( fieldValue, r );
auto boundsHashIt = boundsHash.find( fieldValue );
if ( boundsHashIt == boundsHash.end() )
{
boundsHash.insert( fieldValue, f.geometry().boundingBox() );
}
else
{
boundsHashIt.value().combineExtentWith( f.geometry().boundingBox() );

Comment on lines +181 to +188
auto geometryHashIt = geometryHash.find( fieldValue );
if ( geometryHashIt == geometryHash.constEnd() )
{
geometryHash.insert( fieldValue, QVector<QgsGeometry>() << f.geometry() );
}
else
{
geometryHash.insert( fieldValue, geometryHashIt.value() << f.geometry() );
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
auto geometryHashIt = geometryHash.find( fieldValue );
if ( geometryHashIt == geometryHash.constEnd() )
{
geometryHash.insert( fieldValue, QVector<QgsGeometry>() << f.geometry() );
}
else
{
geometryHash.insert( fieldValue, geometryHashIt.value() << f.geometry() );
auto geometryHashIt = geometryHash.find( fieldValue );
if ( geometryHashIt == geometryHash.end() )
{
geometryHash.insert( fieldValue, QVector<QgsGeometry>() << f.geometry() );
}
else
{
geometryHashIt.value().append( f.geometry() );

QgsFeature feature = createFeature( feedback, i, geometryType, it.value(), it.key() );
if ( !sink->addFeature( feature, QgsFeatureSink::FastInsert ) )
throw QgsProcessingException( writeFeatureError( sink.get(), parameters, QStringLiteral( "OUTPUT" ) ) );
geometryHash.insert( it.key(), QVector<QgsGeometry>() );
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually this is going to cause issues -- we can't modify geometryHash while we're iterating over it. What's this used for anyway? Aren't we finished with the hash when we're creating the features?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Processing Relating to QGIS Processing framework or individual Processing algorithms
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants