21 #include <QTextStream>
25 QString QgsNearestNeighbourAnalysisAlgorithm::name()
const
27 return QStringLiteral(
"nearestneighbouranalysis" );
30 QString QgsNearestNeighbourAnalysisAlgorithm::displayName()
const
32 return QObject::tr(
"Nearest neighbour analysis" );
35 QStringList QgsNearestNeighbourAnalysisAlgorithm::tags()
const
37 return QObject::tr(
"point,node,vertex,nearest,neighbour,distance" ).split(
',' );
40 QString QgsNearestNeighbourAnalysisAlgorithm::group()
const
42 return QObject::tr(
"Vector analysis" );
45 QString QgsNearestNeighbourAnalysisAlgorithm::groupId()
const
47 return QStringLiteral(
"vectoranalysis" );
50 QString QgsNearestNeighbourAnalysisAlgorithm::shortHelpString()
const
52 return QObject::tr(
"This algorithm performs nearest neighbor analysis for a point layer.\n\n"
53 "The output describes how the data are distributed (clustered, randomly or distributed).\n\n"
54 "Output is generated as an HTML file with the computed statistical values." );
57 QString QgsNearestNeighbourAnalysisAlgorithm::svgIconPath()
const
62 QIcon QgsNearestNeighbourAnalysisAlgorithm::icon()
const
67 QgsNearestNeighbourAnalysisAlgorithm *QgsNearestNeighbourAnalysisAlgorithm::createInstance()
const
69 return new QgsNearestNeighbourAnalysisAlgorithm();
72 void QgsNearestNeighbourAnalysisAlgorithm::initAlgorithm(
const QVariantMap & )
76 QObject::tr(
"HTML files (*.html *.HTML)" ), QVariant(),
true ) );
86 std::unique_ptr< QgsProcessingFeatureSource > source( parameterAsSource( parameters, QStringLiteral(
"INPUT" ), context ) );
90 const QString outputFile = parameterAsFileOutput( parameters, QStringLiteral(
"OUTPUT_HTML_FILE" ), context );
97 const double step = source->featureCount() ? 100.0 / source->featureCount() : 1;
102 double sumDist = 0.0;
103 const double area = source->sourceExtent().width() * source->sourceExtent().height();
121 const long long count = source->featureCount() > 0 ? source->featureCount() : 1;
122 const double observedDistance = sumDist / count;
123 const double expectedDistance = 0.5 / std::sqrt( count / area );
124 const double nnIndex = observedDistance / expectedDistance;
125 const double se = 0.26136 / std::sqrt( std::pow( count, 2 ) / area );
126 const double zScore = ( observedDistance - expectedDistance ) / se;
129 outputs.insert( QStringLiteral(
"OBSERVED_MD" ), observedDistance );
130 outputs.insert( QStringLiteral(
"EXPECTED_MD" ), expectedDistance );
131 outputs.insert( QStringLiteral(
"NN_INDEX" ), nnIndex );
132 outputs.insert( QStringLiteral(
"POINT_COUNT" ), count );
133 outputs.insert( QStringLiteral(
"Z_SCORE" ), zScore );
135 if ( !outputFile.isEmpty() )
137 QFile file( outputFile );
138 if ( file.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
140 QTextStream out( &file );
141 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
142 out.setCodec(
"UTF-8" );
144 out << QStringLiteral(
"<html><head><meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\"/></head><body>\n" );
145 out << QObject::tr(
"<p>Observed mean distance: %1</p>\n" ).arg( observedDistance, 0,
'f', 11 );
146 out << QObject::tr(
"<p>Expected mean distance: %1</p>\n" ).arg( expectedDistance, 0,
'f', 11 );
147 out << QObject::tr(
"<p>Nearest neighbour index: %1</p>\n" ).arg( nnIndex, 0,
'f', 11 );
148 out << QObject::tr(
"<p>Number of points: %1</p>\n" ).arg( count );
149 out << QObject::tr(
"<p>Z-Score: %1</p>\n" ).arg( zScore, 0,
'f', 11 );
150 out << QStringLiteral(
"</body></html>" );
152 outputs.insert( QStringLiteral(
"OUTPUT_HTML_FILE" ), outputFile );