-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathkGraph.py
140 lines (122 loc) · 4.15 KB
/
kGraph.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#k-Nearest Neighbor Graph algorithm for Qgis
#author: Roman Kuchukov, rk.arch@yandex.ru
#to run -- 1. save empty layer (lines) to outLayerPath, 2. select input point layer, 3. run script and view notes
#output file paths
outLayerPath = u'E:/QGIS/myData/kGraph.shp'
outLayerName = 'kGraph'
outTxtPath = u'E:/QGIS/myData/kGraphLog.txt'
#list of log strings
listLog = []
#active layer
layer = iface.activeLayer()
#output layer with graph
vectorLyr = QgsVectorLayer(outLayerPath, outLayerName , "ogr")
#add field "fieldNm" to input layer
def addField (layer, fieldNm):
from PyQt4.QtCore import QVariant #to add top-Field
vpr = layer.dataProvider()
vpr.addAttributes([QgsField(fieldNm, QVariant.Int)])
layer.updateFields()
print ("DONE: added text field", fieldNm)
#add Qgis ID to input layer
def AddID(layer, fieldNm):
print('Layer loaded: ', layer.isValid(), "adding Qgis ID")
layer.startEditing()
addField(layer, fieldNm)
for feature in layer.getFeatures():
feature[fieldNm] = feature.id()
layer.updateFeature(feature)
layer.commitChanges()
print "Qgis id added"
#request by ID
def iterID(fid):
ptsCoord = []
request = QgsFeatureRequest().setFilterFids(fid)
iter = layer.getFeatures(request)
for i in iter:
#print i.id()
#print i.geometry().asPoint()
ptsCoord.append(i.geometry().asPoint())
return ptsCoord
#draw line
def drawLine(points):
vpr = vectorLyr.dataProvider()
line = QgsGeometry.fromPolyline(points)
f = QgsFeature()
f.setGeometry(line)
vpr.addFeatures([f])
vectorLyr.updateExtents()
return f
#create Spatial Index
def SIndex():
fts = layer.getFeatures()
first = fts.next()
index = QgsSpatialIndex()
for f in fts:
index.insertFeature(f)
print "Spatial Index created"
return index
#select nearest neibhors
def Nhood(index, idInput, k):
layer.setSelectedFeatures([]) #deselect
points = []
pointInput = iterID([idInput])
hood = index.nearestNeighbor(pointInput[0], k+1)
#print("hood ", hood)
print "%i, hood k=%i, " % (idInput, k), ". ".join( str(e) for e in hood) #without [ ]
for h in hood:
layer.select(h)
points = iterID([idInput, h])
iface.mapCanvas().zoomToSelected()
return hood
#draw hub
def HUBhood(index, idInput, k):
points = []
pointInput = iterID([idInput])
hood = index.nearestNeighbor(pointInput[0], k+1)
print idInput
txtIO = str("%i, %i, " % (idInput, k),) + str(". ".join( str(e) for e in hood[1:])) #without self element
AddTxt(listLog, txtIO)
for h in hood:
#layer.select(h)
points = iterID([idInput, h])
drawLine(points)
#iface.mapCanvas().zoomToSelected()
return hood[1:]
#main function
def kGraph(index, layer, k):
listLog = []
fts = layer.getFeatures()
print "computing Qid:"
for f in fts:
#print f.id()
HUBhood(indx, f.id(), k)
print "kGraph - DONE"
#text functions
def AddTxt(string, txtIO):
string.append(txtIO)
def log():
for i in listLog:
print i
def saveLog():
count = 0
output_file = open(outTxtPath, 'w')
line = "#, Qid, k-Neighbors, hood\n"
unicode_line = line.encode('utf-8')
output_file.write(unicode_line)
for i in listLog:
line = "%i, %s\n" %(count, i)
unicode_line = line.encode('utf-8')
output_file.write(unicode_line)
count = count +1
output_file.close()
print "log saved to %s" %outTxtPath
#RUN script
print "# RUNNING k-Nearest Points Graph algorithm #\n# SELECT input point layer #\n***"
indx = SIndex() # create Spatial Index
print "result file path", outLayerPath
print '1. To add Qgis ID on input layer type:\n\tAddID(layer, "Qid") # "Qid" - name of field - example'
print '2. To view nearest points, type:\n\tNhood(indx, 1, 4) # 1- Qid, 4 - links - example'
print '3. To add hub lines - manualliy, type:\n\tHUBhood(indx, 1, 4) # 1- Qid, 4 - links - example'
print '4. To start building graph(s) - automatically, SELECT INPUT layer, type:\n\tkGraph(indx, layer, 4) # 4 - links - example\n*** '
print '5. To view log type: log() ; to save log type: saveLog()'