@@ -63,6 +63,7 @@ void QgsNativeAlgorithms::loadAlgorithms()
6363 addAlgorithm ( new QgsDissolveAlgorithm () );
6464 addAlgorithm ( new QgsClipAlgorithm () );
6565 addAlgorithm ( new QgsTransformAlgorithm () );
66+ addAlgorithm ( new QgsSubdivideAlgorithm () );
6667}
6768
6869
@@ -594,5 +595,75 @@ QVariantMap QgsTransformAlgorithm::processAlgorithm( const QVariantMap ¶mete
594595}
595596
596597
598+ QgsSubdivideAlgorithm::QgsSubdivideAlgorithm ()
599+ {
600+ addParameter ( new QgsProcessingParameterFeatureSource ( QStringLiteral ( " INPUT" ), QObject::tr ( " Input layer" ) ) );
601+ addParameter ( new QgsProcessingParameterNumber ( QStringLiteral ( " MAX_NODES" ), QObject::tr ( " Maximum nodes in parts" ), QgsProcessingParameterNumber::Integer,
602+ 256 , false , 8 , 100000 ) );
603+
604+ addParameter ( new QgsProcessingParameterFeatureSink ( QStringLiteral ( " OUTPUT" ), QObject::tr ( " Subdivided" ) ) );
605+ addOutput ( new QgsProcessingOutputVectorLayer ( QStringLiteral ( " OUTPUT" ), QObject::tr ( " Subdivided" ) ) );
606+ }
607+
608+ QString QgsSubdivideAlgorithm::shortHelpString () const
609+ {
610+ return QObject::tr ( " Subdivides the geometry. The returned geometry will be a collection containing subdivided parts "
611+ " from the original geometry, where no part has more then the specified maximum number of nodes.\n\n "
612+ " This is useful for dividing a complex geometry into less complex parts, which are better able to be spatially "
613+ " indexed and faster to perform further operations such as intersects on. The returned geometry parts may "
614+ " not be valid and may contain self-intersections.\n\n "
615+ " Curved geometries will be segmentized before subdivision." );
616+ }
617+
618+ QVariantMap QgsSubdivideAlgorithm::processAlgorithm ( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) const
619+ {
620+ std::unique_ptr< QgsFeatureSource > source ( parameterAsSource ( parameters, QStringLiteral ( " INPUT" ), context ) );
621+ if ( !source )
622+ return QVariantMap ();
623+
624+ int maxNodes = parameterAsInt ( parameters, QStringLiteral ( " MAX_NODES" ), context );
625+ QString dest;
626+ std::unique_ptr< QgsFeatureSink > sink ( parameterAsSink ( parameters, QStringLiteral ( " OUTPUT" ), context, source->fields (),
627+ QgsWkbTypes::multiType ( source->wkbType () ), source->sourceCrs (), dest ) );
628+ if ( !sink )
629+ return QVariantMap ();
630+
631+ long count = source->featureCount ();
632+ if ( count <= 0 )
633+ return QVariantMap ();
634+
635+ QgsFeature f;
636+ QgsFeatureIterator it = source->getFeatures ();
637+
638+ double step = 100.0 / count;
639+ int current = 0 ;
640+ while ( it.nextFeature ( f ) )
641+ {
642+ if ( feedback->isCanceled () )
643+ {
644+ break ;
645+ }
646+
647+ QgsFeature out = f;
648+ if ( out.hasGeometry () )
649+ {
650+ out.setGeometry ( f.geometry ().subdivide ( maxNodes ) );
651+ if ( !out.geometry () )
652+ {
653+ QgsMessageLog::logMessage ( QObject::tr ( " Error calculating subdivision for feature %1" ).arg ( f.id () ), QObject::tr ( " Processing" ), QgsMessageLog::WARNING );
654+ }
655+ }
656+ sink->addFeature ( out );
657+
658+ feedback->setProgress ( current * step );
659+ current++;
660+ }
661+
662+ QVariantMap outputs;
663+ outputs.insert ( QStringLiteral ( " OUTPUT" ), dest );
664+ return outputs;
665+ }
666+
597667// /@endcond
598668
669+
0 commit comments