Skip to content

Commit ad0ff93

Browse files
committedOct 4, 2012
review Nearest neighbour tool
1 parent a796d98 commit ad0ff93

File tree

1 file changed

+81
-49
lines changed

1 file changed

+81
-49
lines changed
 

‎python/plugins/sextante/ftools/NearestNeighbourAnalysis.py

Lines changed: 81 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,102 @@
1-
from sextante.core.GeoAlgorithm import GeoAlgorithm
21
import os.path
2+
import math
3+
34
from PyQt4 import QtGui
4-
from PyQt4.QtCore import *
5-
from PyQt4.QtGui import *
5+
66
from qgis.core import *
7-
from sextante.parameters.ParameterVector import ParameterVector
7+
8+
from sextante.core.GeoAlgorithm import GeoAlgorithm
89
from sextante.core.QGisLayers import QGisLayers
9-
from sextante.ftools import ftools_utils
10-
import math
10+
11+
from sextante.parameters.ParameterVector import ParameterVector
12+
1113
from sextante.outputs.OutputHTML import OutputHTML
14+
from sextante.outputs.OutputNumber import OutputNumber
15+
16+
from sextante.ftools import FToolsUtils as utils
1217

1318
class NearestNeighbourAnalysis(GeoAlgorithm):
1419

1520
POINTS = "POINTS"
21+
1622
OUTPUT = "OUTPUT"
1723

24+
OBSERVED_MD = "OBSERVED_MD"
25+
EXPECTED_MD = "EXPECTED_MD"
26+
NN_INDEX = "NN_INDEX"
27+
POINT_COUNT = "POINT_COUNT"
28+
Z_SCORE = "Z_SCORE"
29+
1830
def getIcon(self):
1931
return QtGui.QIcon(os.path.dirname(__file__) + "/icons/neighbour.png")
2032

33+
def defineCharacteristics(self):
34+
self.name = "Nearest neighbour analysis"
35+
self.group = "Analysis tools"
36+
37+
self.addParameter(ParameterVector(self.POINTS, "Points", ParameterVector.VECTOR_TYPE_POINT))
38+
39+
self.addOutput(OutputHTML(self.OUTPUT, "Result"))
40+
41+
self.addOutput(OutputNumber(self.OBSERVED_MD, "Observed mean distance"))
42+
self.addOutput(OutputNumber(self.EXPECTED_MD, "Expected mean distance"))
43+
self.addOutput(OutputNumber(self.NN_INDEX, "Nearest neighbour index"))
44+
self.addOutput(OutputNumber(self.POINT_COUNT, "Number of points"))
45+
self.addOutput(OutputNumber(self.Z_SCORE, "Z-Score"))
46+
47+
2148
def processAlgorithm(self, progress):
22-
output = self.getOutputValue(NearestNeighbourAnalysis.OUTPUT)
23-
vlayer = QGisLayers.getObjectFromUri(self.getParameterValue(NearestNeighbourAnalysis.POINTS))
24-
vprovider = vlayer.dataProvider()
25-
allAttrs = vprovider.attributeIndexes()
26-
vprovider.select( allAttrs )
49+
layer = QGisLayers.getObjectFromUri(self.getParameterValue(self.POINTS))
50+
output = self.getOutputValue(self.OUTPUT)
51+
52+
provider = layer.dataProvider()
53+
spatialIndex = utils.createSpatialIndex(provider)
54+
provider.rewind()
55+
provider.select()
56+
2757
feat = QgsFeature()
2858
neighbour = QgsFeature()
29-
sumDist = 0.00
3059
distance = QgsDistanceArea()
31-
A = vlayer.extent()
32-
A = float( A.width() * A.height() )
33-
index = ftools_utils.createIndex( vprovider )
34-
vprovider.rewind()
35-
nFeat = vprovider.featureCount()
36-
nElement = 0
37-
while vprovider.nextFeature( feat ):
38-
neighbourID = index.nearestNeighbor( feat.geometry().asPoint(), 2 )[ 1 ]
39-
vprovider.featureAtId( neighbourID, neighbour, True, [] )
40-
nearDist = distance.measureLine( neighbour.geometry().asPoint(), feat.geometry().asPoint() )
41-
sumDist += nearDist
42-
nElement += 1
43-
progress.setPercentage(int(nElement/nFeat * 100))
44-
nVal = vprovider.featureCount()
45-
do = float( sumDist) / nVal
46-
de = float( 0.5 / math.sqrt( nVal / A ) )
47-
d = float( do / de )
48-
SE = float( 0.26136 / math.sqrt( ( nVal * nVal ) / A ) )
49-
zscore = float( ( do - de ) / SE )
50-
lstStats = []
51-
lstStats.append("Observed mean distance:" + unicode( do ) )
52-
lstStats.append("Expected mean distance:" + unicode( de ) )
53-
lstStats.append("Nearest neighbour index:" + unicode( d ) )
54-
lstStats.append("N:" + unicode( nVal ) )
55-
lstStats.append("Z-Score:" + unicode( zscore ) )
56-
self.createHTML(output, lstStats)
57-
58-
59-
def createHTML(self, outputFile, lstStats):
60+
61+
sumDist = 0.00
62+
A = layer.extent()
63+
A = float(A.width() * A.height())
64+
65+
current = 0
66+
total = 100.0 / float(provider.featureCount())
67+
68+
while provider.nextFeature( feat ):
69+
neighbourID = spatialIndex.nearestNeighbor(feat.geometry().asPoint(), 2)[1]
70+
provider.featureAtId(neighbourID, neighbour, True)
71+
sumDist += distance.measureLine(neighbour.geometry().asPoint(), feat.geometry().asPoint())
72+
73+
current += 1
74+
progress.setPercentage(int(current * total))
75+
76+
count = provider.featureCount()
77+
do = float(sumDist) / count
78+
de = float(0.5 / math.sqrt(count / A))
79+
d = float(do / de)
80+
SE = float(0.26136 / math.sqrt(( count ** 2) / A))
81+
zscore = float((do - de) / SE)
82+
83+
data = []
84+
data.append("Observed mean distance: " + unicode(do))
85+
data.append("Expected mean distance: " + unicode(de))
86+
data.append("Nearest neighbour index: " + unicode(d))
87+
data.append("Number of points: " + unicode(count))
88+
data.append("Z-Score: " + unicode(zscore))
89+
90+
self.createHTML(output, data)
91+
92+
self.setOutputValue(self.OBSERVED_MD, float( data[ 0 ].split( ": " )[ 1 ] ) )
93+
self.setOutputValue(self.EXPECTED_MD, float( data[ 1 ].split( ": " )[ 1 ] ) )
94+
self.setOutputValue(self.NN_INDEX, float( data[ 2 ].split( ": " )[ 1 ] ) )
95+
self.setOutputValue(self.POINT_COUNT, float( data[ 3 ].split( ": " )[ 1 ] ) )
96+
self.setOutputValue(self.Z_SCORE, float( data[ 4 ].split( ": " )[ 1 ] ) )
97+
98+
def createHTML(self, outputFile, algData):
6099
f = open(outputFile, "w")
61-
for s in lstStats:
100+
for s in algData:
62101
f.write("<p>" + str(s) + "</p>")
63102
f.close()
64-
65-
66-
def defineCharacteristics(self):
67-
self.name = "Nearest neighbour analysis"
68-
self.group = "Analysis tools"
69-
self.addParameter(ParameterVector(NearestNeighbourAnalysis.POINTS, "Points", ParameterVector.VECTOR_TYPE_POINT))
70-
self.addOutput(OutputHTML(NearestNeighbourAnalysis.OUTPUT, "Result"))

0 commit comments

Comments
 (0)
Please sign in to comment.