25 QString QgsRandomPointsExtentAlgorithm::name()
const
27 return QStringLiteral(
"randompointsinextent" );
30 QString QgsRandomPointsExtentAlgorithm::displayName()
const
32 return QObject::tr(
"Random points in extent" );
35 QStringList QgsRandomPointsExtentAlgorithm::tags()
const
37 return QObject::tr(
"random,points,extent,create" ).split(
',' );
40 QString QgsRandomPointsExtentAlgorithm::group()
const
42 return QObject::tr(
"Vector creation" );
45 QString QgsRandomPointsExtentAlgorithm::groupId()
const
47 return QStringLiteral(
"vectorcreation" );
50 void QgsRandomPointsExtentAlgorithm::initAlgorithm(
const QVariantMap & )
55 addParameter(
new QgsProcessingParameterDistance( QStringLiteral(
"MIN_DISTANCE" ), QObject::tr(
"Minimum distance between points" ), 0, QStringLiteral(
"TARGET_CRS" ),
true, 0 ) );
56 addParameter(
new QgsProcessingParameterCrs( QStringLiteral(
"TARGET_CRS" ), QObject::tr(
"Target CRS" ), QStringLiteral(
"ProjectCrs" ),
false ) );
58 std::unique_ptr< QgsProcessingParameterNumber > maxAttempts_param = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral(
"MAX_ATTEMPTS" ), QObject::tr(
"Maximum number of search attempts given the minimum distance" ),
QgsProcessingParameterNumber::Integer, 200,
true, 1 );
60 addParameter( maxAttempts_param.release() );
65 QString QgsRandomPointsExtentAlgorithm::shortHelpString()
const
67 return QObject::tr(
"This algorithm creates a new point layer with a given "
68 "number of random points, all of them within a given extent. "
69 "A distance factor can be specified, to avoid points being "
70 "too close to each other. If the minimum distance between points "
71 "makes it impossible to create new points, either "
72 "distance can be decreased or the maximum number of attempts may be "
77 QgsRandomPointsExtentAlgorithm *QgsRandomPointsExtentAlgorithm::createInstance()
const
79 return new QgsRandomPointsExtentAlgorithm();
84 mCrs = parameterAsCrs( parameters, QStringLiteral(
"TARGET_CRS" ), context );
85 mExtent = parameterAsExtent( parameters, QStringLiteral(
"EXTENT" ), context, mCrs );
86 mNumPoints = parameterAsInt( parameters, QStringLiteral(
"POINTS_NUMBER" ), context );
87 mDistance = parameterAsDouble( parameters, QStringLiteral(
"MIN_DISTANCE" ), context );
88 mMaxAttempts = parameterAsInt( parameters, QStringLiteral(
"MAX_ATTEMPTS" ), context );
97 fields.
append(
QgsField( QStringLiteral(
"id" ), QVariant::LongLong ) );
100 std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral(
"OUTPUT" ), context, dest, fields,
QgsWkbTypes::Point, mCrs ) );
105 std::random_device random_device;
106 const std::mt19937 mersenne_twister( random_device() );
108 std::uniform_real_distribution<double> x_distribution( mExtent.xMinimum(), mExtent.xMaximum() );
109 std::uniform_real_distribution<double> y_distribution( mExtent.yMinimum(), mExtent.yMaximum() );
111 if ( mDistance == 0 )
114 while ( i < mNumPoints )
119 const double rx = x_distribution( random_device );
120 const double ry = y_distribution( random_device );
129 feedback->
setProgress(
static_cast<int>(
static_cast<double>( i ) /
static_cast<double>( mNumPoints ) * 100 ) );
135 int distCheckIterations = 0;
138 while ( i < mNumPoints )
143 const double rx = x_distribution( random_device );
144 const double ry = y_distribution( random_device );
148 if ( neighbors.empty() )
158 distCheckIterations = 0;
159 feedback->
setProgress(
static_cast<int>(
static_cast<double>( i ) /
static_cast<double>( mNumPoints ) * 100 ) );
163 if ( distCheckIterations == mMaxAttempts )
165 throw QgsProcessingException( QObject::tr(
"%1 of %2 points have been successfully created, but no more random points could be found "
166 "due to the given minimum distance between points. Either choose a larger extent, "
167 "lower the minimum distance between points or try increasing the number "
168 "of attempts for searching new points." ).arg( i ).arg( mNumPoints ) );
172 distCheckIterations++;
181 outputs.insert( QStringLiteral(
"OUTPUT" ), dest );