Skip to content

Commit

Permalink
review Nearest neighbour tool
Browse files Browse the repository at this point in the history
  • Loading branch information
alexbruy committed Oct 4, 2012
1 parent a796d98 commit ad0ff93
Showing 1 changed file with 81 additions and 49 deletions.
130 changes: 81 additions & 49 deletions python/plugins/sextante/ftools/NearestNeighbourAnalysis.py
@@ -1,70 +1,102 @@
from sextante.core.GeoAlgorithm import GeoAlgorithm
import os.path import os.path
import math

from PyQt4 import QtGui from PyQt4 import QtGui
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.core import * from qgis.core import *
from sextante.parameters.ParameterVector import ParameterVector
from sextante.core.GeoAlgorithm import GeoAlgorithm
from sextante.core.QGisLayers import QGisLayers from sextante.core.QGisLayers import QGisLayers
from sextante.ftools import ftools_utils
import math from sextante.parameters.ParameterVector import ParameterVector

from sextante.outputs.OutputHTML import OutputHTML from sextante.outputs.OutputHTML import OutputHTML
from sextante.outputs.OutputNumber import OutputNumber

from sextante.ftools import FToolsUtils as utils


class NearestNeighbourAnalysis(GeoAlgorithm): class NearestNeighbourAnalysis(GeoAlgorithm):


POINTS = "POINTS" POINTS = "POINTS"

OUTPUT = "OUTPUT" 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): def getIcon(self):
return QtGui.QIcon(os.path.dirname(__file__) + "/icons/neighbour.png") return QtGui.QIcon(os.path.dirname(__file__) + "/icons/neighbour.png")


def defineCharacteristics(self):
self.name = "Nearest neighbour analysis"
self.group = "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): def processAlgorithm(self, progress):
output = self.getOutputValue(NearestNeighbourAnalysis.OUTPUT) layer = QGisLayers.getObjectFromUri(self.getParameterValue(self.POINTS))
vlayer = QGisLayers.getObjectFromUri(self.getParameterValue(NearestNeighbourAnalysis.POINTS)) output = self.getOutputValue(self.OUTPUT)
vprovider = vlayer.dataProvider()
allAttrs = vprovider.attributeIndexes() provider = layer.dataProvider()
vprovider.select( allAttrs ) spatialIndex = utils.createSpatialIndex(provider)
provider.rewind()
provider.select()

feat = QgsFeature() feat = QgsFeature()
neighbour = QgsFeature() neighbour = QgsFeature()
sumDist = 0.00
distance = QgsDistanceArea() distance = QgsDistanceArea()
A = vlayer.extent()
A = float( A.width() * A.height() ) sumDist = 0.00
index = ftools_utils.createIndex( vprovider ) A = layer.extent()
vprovider.rewind() A = float(A.width() * A.height())
nFeat = vprovider.featureCount()
nElement = 0 current = 0
while vprovider.nextFeature( feat ): total = 100.0 / float(provider.featureCount())
neighbourID = index.nearestNeighbor( feat.geometry().asPoint(), 2 )[ 1 ]
vprovider.featureAtId( neighbourID, neighbour, True, [] ) while provider.nextFeature( feat ):
nearDist = distance.measureLine( neighbour.geometry().asPoint(), feat.geometry().asPoint() ) neighbourID = spatialIndex.nearestNeighbor(feat.geometry().asPoint(), 2)[1]
sumDist += nearDist provider.featureAtId(neighbourID, neighbour, True)
nElement += 1 sumDist += distance.measureLine(neighbour.geometry().asPoint(), feat.geometry().asPoint())
progress.setPercentage(int(nElement/nFeat * 100))
nVal = vprovider.featureCount() current += 1
do = float( sumDist) / nVal progress.setPercentage(int(current * total))
de = float( 0.5 / math.sqrt( nVal / A ) )
d = float( do / de ) count = provider.featureCount()
SE = float( 0.26136 / math.sqrt( ( nVal * nVal ) / A ) ) do = float(sumDist) / count
zscore = float( ( do - de ) / SE ) de = float(0.5 / math.sqrt(count / A))
lstStats = [] d = float(do / de)
lstStats.append("Observed mean distance:" + unicode( do ) ) SE = float(0.26136 / math.sqrt(( count ** 2) / A))
lstStats.append("Expected mean distance:" + unicode( de ) ) zscore = float((do - de) / SE)
lstStats.append("Nearest neighbour index:" + unicode( d ) )
lstStats.append("N:" + unicode( nVal ) ) data = []
lstStats.append("Z-Score:" + unicode( zscore ) ) data.append("Observed mean distance: " + unicode(do))
self.createHTML(output, lstStats) data.append("Expected mean distance: " + unicode(de))

data.append("Nearest neighbour index: " + unicode(d))

data.append("Number of points: " + unicode(count))
def createHTML(self, outputFile, lstStats): 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") f = open(outputFile, "w")
for s in lstStats: for s in algData:
f.write("<p>" + str(s) + "</p>") f.write("<p>" + str(s) + "</p>")
f.close() f.close()


def defineCharacteristics(self):
self.name = "Nearest neighbour analysis"
self.group = "Analysis tools"
self.addParameter(ParameterVector(NearestNeighbourAnalysis.POINTS, "Points", ParameterVector.VECTOR_TYPE_POINT))
self.addOutput(OutputHTML(NearestNeighbourAnalysis.OUTPUT, "Result"))

0 comments on commit ad0ff93

Please sign in to comment.