# -*- coding: utf-8 -*- """ *************************************************************************** NearestNeighbourAnalysis.py --------------------- Date : August 2012 Copyright : (C) 2012 by Victor Olaya Email : volayaf 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. * * * *************************************************************************** """ __author__ = 'Victor Olaya' __date__ = 'August 2012' __copyright__ = '(C) 2012, Victor Olaya' # This will get replaced with a git SHA1 when you do a git archive __revision__ = '$Format:%H$' import math from qgis.core import * from processing.core.GeoAlgorithm import GeoAlgorithm from processing.parameters.ParameterVector import ParameterVector from processing.outputs.OutputHTML import OutputHTML from processing.outputs.OutputNumber import OutputNumber from processing.tools import dataobjects, vector class NearestNeighbourAnalysis(GeoAlgorithm): POINTS = 'POINTS' OUTPUT = 'OUTPUT' OBSERVED_MD = 'OBSERVED_MD' EXPECTED_MD = 'EXPECTED_MD' NN_INDEX = 'NN_INDEX' POINT_COUNT = 'POINT_COUNT' Z_SCORE = 'Z_SCORE' # ========================================================================= # def getIcon(self): # return QIcon(os.path.dirname(__file__) + "/icons/neighbour.png") # ========================================================================= def defineCharacteristics(self): self.name = 'Nearest neighbour analysis' self.group = 'Vector analysis tools' self.addParameter(ParameterVector(self.POINTS, 'Points', [ParameterVector.VECTOR_TYPE_POINT])) self.addOutput(OutputHTML(self.OUTPUT, 'Result')) self.addOutput(OutputNumber(self.OBSERVED_MD, 'Observed mean distance' )) self.addOutput(OutputNumber(self.EXPECTED_MD, 'Expected mean distance' )) self.addOutput(OutputNumber(self.NN_INDEX, 'Nearest neighbour index')) self.addOutput(OutputNumber(self.POINT_COUNT, 'Number of points')) self.addOutput(OutputNumber(self.Z_SCORE, 'Z-Score')) def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri( self.getParameterValue(self.POINTS)) output = self.getOutputValue(self.OUTPUT) spatialIndex = vector.spatialindex(layer) neighbour = QgsFeature() distance = QgsDistanceArea() sumDist = 0.00 A = layer.extent() A = float(A.width() * A.height()) current = 0 features = vector.features(layer) count = len(features) total = 100.0 / float(len(features)) for feat in features: neighbourID = spatialIndex.nearestNeighbor( feat.geometry().asPoint(), 2)[1] request = QgsFeatureRequest().setFilterFid(neighbourID) neighbour = layer.getFeatures(request).next() sumDist += distance.measureLine(neighbour.geometry().asPoint(), feat.geometry().asPoint()) current += 1 progress.setPercentage(int(current * total)) do = float(sumDist) / count de = float(0.5 / math.sqrt(count / A)) d = float(do / de) SE = float(0.26136 / math.sqrt(count ** 2 / A)) zscore = float((do - de) / SE) data = [] data.append('Observed mean distance: ' + unicode(do)) data.append('Expected mean distance: ' + unicode(de)) data.append('Nearest neighbour index: ' + unicode(d)) data.append('Number of points: ' + unicode(count)) data.append('Z-Score: ' + unicode(zscore)) self.createHTML(output, data) self.setOutputValue(self.OBSERVED_MD, float(data[0].split(': ')[1])) self.setOutputValue(self.EXPECTED_MD, float(data[1].split(': ')[1])) self.setOutputValue(self.NN_INDEX, float(data[2].split(': ')[1])) self.setOutputValue(self.POINT_COUNT, float(data[3].split(': ')[1])) self.setOutputValue(self.Z_SCORE, float(data[4].split(': ')[1])) def createHTML(self, outputFile, algData): f = open(outputFile, 'w') for s in algData: f.write('

' + str(s) + '

') f.close()