Skip to content

Commit 49c8d44

Browse files
authored
Merge pull request #74 from AasheeshT/Functionality
withPoint Family
2 parents 2ff38e9 + 785258c commit 49c8d44

File tree

3 files changed

+334
-5
lines changed

3 files changed

+334
-5
lines changed

pgRoutingLayer.py

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ class PgRoutingLayer(object):
4343

4444
SUPPORTED_FUNCTIONS = [
4545
'tsp_euclid',
46+
'with_Points',
47+
'with_PointsCost',
4648
'dijkstra',
4749
'trsp_vertex',
4850
'astar',
@@ -80,12 +82,14 @@ class PgRoutingLayer(object):
8082
'labelTargetPos', 'lineEditTargetPos',
8183
'labelDistance', 'lineEditDistance',
8284
'labelAlpha', 'lineEditAlpha',
83-
'labelPaths', 'lineEditPaths',
85+
'labelPaths', 'lineEditPaths','label_pointsTable','lineEditPointsTable',
8486
'checkBoxDirected',
8587
'checkBoxHasReverseCost',
8688
'checkBoxHeapPaths',
87-
'checkBoxUseBBOX',
89+
'checkBoxUseBBOX', 'checkBoxDetails',
8890
'labelTurnRestrictSql', 'plainTextEditTurnRestrictSql',
91+
'labelPid', 'lineEditPid', 'labelEdge_id', 'lineEditEdge_id',
92+
'labelFraction', 'lineEditFraction', 'labelSide', 'lineEditSide','labelDrivingSide','checkBoxLeft','checkBoxRight'
8993
]
9094
FIND_RADIUS = 10
9195
FRACTION_DECIMAL_PLACES = 2
@@ -930,6 +934,22 @@ def getArguments(self, controls):
930934

931935
if 'lineEditTarget' in controls:
932936
args['target'] = self.dock.lineEditTarget.text()
937+
938+
if 'lineEditPointsTable' in controls:
939+
args['points_table'] = self.dock.lineEditPointsTable.text()
940+
941+
if 'lineEditPid' in controls:
942+
args['pid'] = self.dock.lineEditPid.text()
943+
944+
if 'lineEditEdge_id' in controls:
945+
args['edge_id'] = self.dock.lineEditEdge_id.text()
946+
947+
if 'lineEditFraction' in controls:
948+
args['fraction'] = self.dock.lineEditFraction.text()
949+
950+
if 'lineEditSide' in controls:
951+
args['side'] = self.dock.lineEditSide.text()
952+
933953

934954
if 'lineEditCost' in controls:
935955
args['cost'] = self.dock.lineEditCost.text()
@@ -991,16 +1011,27 @@ def getArguments(self, controls):
9911011
if 'checkBoxDirected' in controls:
9921012
args['directed'] = str(self.dock.checkBoxDirected.isChecked()).lower()
9931013

1014+
if 'checkBoxDetails' in controls:
1015+
args['details'] = str(self.dock.checkBoxDirected.isChecked()).lower()
1016+
1017+
1018+
1019+
9941020
if 'checkBoxHeapPaths' in controls:
9951021
args['heap_paths'] = str(self.dock.checkBoxHeapPaths.isChecked()).lower()
9961022

9971023
if 'checkBoxUseBBOX' in controls:
9981024
args['use_bbox'] = str(self.dock.checkBoxUseBBOX.isChecked()).lower()
9991025
else:
10001026
args['use_bbox'] = 'false'
1001-
1002-
1003-
1027+
1028+
if 'labelDrivingSide' in controls:
1029+
args['driving_side'] = str('b')
1030+
if (self.dock.checkBoxLeft.isChecked() == True and self.dock.checkBoxRight.isChecked() == False):
1031+
args['driving_side'] = str('l')
1032+
elif (self.dock.checkBoxLeft.isChecked() == False and self.dock.checkBoxRight.isChecked() == True):
1033+
args['driving_side'] = str('r')
1034+
10041035
if 'checkBoxHasReverseCost' in controls:
10051036
args['has_reverse_cost'] = str(self.dock.checkBoxHasReverseCost.isChecked()).lower()
10061037
if args['has_reverse_cost'] == 'false':
@@ -1242,6 +1273,7 @@ def loadSettings(self):
12421273
self.dock.comboBoxFunction.setCurrentIndex(idx)
12431274

12441275
self.dock.lineEditTable.setText(Utils.getStringValue(settings, '/pgRoutingLayer/sql/edge_table', 'roads'))
1276+
self.dock.lineEditPointsTable.setText(Utils.getStringValue(settings, '/pgRoutingLayer/sql/pointsOfInterest', 'pointsOfInterest'))
12451277
self.dock.lineEditGeometry.setText(Utils.getStringValue(settings, '/pgRoutingLayer/sql/geometry', 'the_geom'))
12461278
self.dock.lineEditId.setText(Utils.getStringValue(settings, '/pgRoutingLayer/sql/id', 'id'))
12471279
self.dock.lineEditSource.setText(Utils.getStringValue(settings, '/pgRoutingLayer/sql/source', 'source'))
@@ -1281,6 +1313,7 @@ def saveSettings(self):
12811313
settings.setValue('/pgRoutingLayer/Function', self.dock.comboBoxFunction.currentText())
12821314

12831315
settings.setValue('/pgRoutingLayer/sql/edge_table', self.dock.lineEditTable.text())
1316+
settings.setValue('/pgRoutingLayer/sql/pointsOfInterest', self.dock.lineEditPointsTable.text())
12841317
settings.setValue('/pgRoutingLayer/sql/geometry', self.dock.lineEditGeometry.text())
12851318

12861319
settings.setValue('/pgRoutingLayer/sql/id', self.dock.lineEditId.text())

with_Points.py

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
from __future__ import absolute_import
2+
from builtins import str
3+
from qgis.PyQt.QtCore import QSizeF, QPointF
4+
from qgis.PyQt.QtGui import QColor, QTextDocument
5+
from qgis.core import QgsGeometry, Qgis, QgsTextAnnotation, QgsWkbTypes, QgsAnnotation
6+
from qgis.gui import QgsRubberBand
7+
import psycopg2
8+
from pgRoutingLayer import pgRoutingLayer_utils as Utils
9+
from .FunctionBase import FunctionBase
10+
11+
class Function(FunctionBase):
12+
13+
@classmethod
14+
def getName(self):
15+
''' returns Function name. '''
16+
return 'with_Points'
17+
18+
@classmethod
19+
def getControlNames(self, version):
20+
''' returns control names. '''
21+
self.version = version
22+
if self.version < 2.1:
23+
# version 2.0 has only one to one
24+
return self.commonControls + self.commonBoxes + [
25+
'labelSourceId', 'lineEditSourceId', 'buttonSelectSourceId',
26+
'labelTargetId','labelSide','lineEditSide','lineEditEdge_id','labelFraction','lineEditFraction', 'lineEditPointsTable', 'lineEditTargetId','labelPid','lineEditPid','labelEdge_id', 'buttonSelectTargetId',
27+
'labelEdge_id','labelSide'
28+
29+
]
30+
else:
31+
return self.commonControls + self.commonBoxes + [
32+
'labelSourceIds', 'lineEditSourceIds', 'buttonSelectSourceIds',
33+
'labelTargetIds', 'lineEditPointsTable', 'label_pointsTable', 'lineEditTargetIds', 'buttonSelectTargetIds',
34+
'labelSide','lineEditSide','lineEditEdge_id','labelEdge_id','labelFraction','lineEditFraction','labelPid','lineEditPid',
35+
'labelDrivingSide','checkBoxLeft','checkBoxRight','checkBoxDetails'
36+
]
37+
38+
39+
@classmethod
40+
def isSupportedVersion(self, version):
41+
''' Checks supported version '''
42+
# valid starting pgr v2.1
43+
return version >= 2.1
44+
45+
46+
@classmethod
47+
def canExportQuery(self):
48+
return False
49+
50+
@classmethod
51+
def canExportMerged(self):
52+
return False
53+
54+
55+
56+
def prepare(self, canvasItemList):
57+
resultNodesTextAnnotations = canvasItemList['annotations']
58+
for anno in resultNodesTextAnnotations:
59+
anno.setVisible(False)
60+
canvasItemList['annotations'] = []
61+
62+
63+
def getQuery(self, args):
64+
''' returns the sql query in required signature format of pgr_withPoints '''
65+
args['where_clause'] = self.whereClause(args['edge_table'], args['geometry'], args['BBOX'])
66+
args['where_clause_with'] = self.whereClause(args['points_table'], args['geometry'], args['BBOX'])
67+
return """
68+
SELECT seq, path_seq AS path_seq,
69+
start_vid AS _start_vid , end_vid AS _end_vid, node, cost AS _cost, lead(agg_cost) over() AS agg_cost
70+
FROM pgr_withPoints('
71+
SELECT %(id)s AS id,
72+
%(source)s AS source,
73+
%(target)s AS target,
74+
%(cost)s AS cost
75+
%(reverse_cost)s
76+
FROM %(edge_table)s
77+
%(where_clause)s
78+
',
79+
'SELECT %(pid)s AS pid,
80+
%(edge_id)s AS edge_id,
81+
%(fraction)s AS fraction,
82+
%(side)s AS side
83+
FROM %(points_table)s
84+
%(where_clause_with)s',
85+
array[%(source_ids)s]::BIGINT[], array[%(target_ids)s]::BIGINT[], %(directed)s, '%(driving_side)s', %(details)s)
86+
""" % args
87+
88+
def getExportQuery(self, args):
89+
return self.getJoinResultWithEdgeTable(args)
90+
91+
92+
def getExportMergeQuery(self, args):
93+
if self.version < 2.1:
94+
return self.getExportOneSourceOneTargetMergeQuery(args)
95+
else:
96+
return self.getExportManySourceManyTargetMergeQuery(args)
97+
98+
99+
100+
def draw(self, rows, con, args, geomType, canvasItemList, mapCanvas):
101+
''' draw the result '''
102+
if self.version < 2.1:
103+
self.drawOnePath(rows, con, args, geomType, canvasItemList, mapCanvas)
104+
else:
105+
self.drawManyPaths(rows, con, args, geomType, canvasItemList, mapCanvas)
106+
107+
108+
109+
def __init__(self, ui):
110+
FunctionBase.__init__(self, ui)

with_PointsCost.py

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
from __future__ import absolute_import
2+
from builtins import str
3+
from qgis.PyQt.QtCore import QSizeF, QPointF
4+
from qgis.PyQt.QtGui import QColor, QTextDocument
5+
from qgis.core import QgsGeometry, Qgis, QgsTextAnnotation, QgsWkbTypes, QgsAnnotation
6+
from qgis.gui import QgsRubberBand
7+
import psycopg2
8+
from pgRoutingLayer import pgRoutingLayer_utils as Utils
9+
from .FunctionBase import FunctionBase
10+
11+
class Function(FunctionBase):
12+
13+
@classmethod
14+
def getName(self):
15+
''' returns Function name. '''
16+
return 'with_PointsCost'
17+
18+
@classmethod
19+
def getControlNames(self, version):
20+
''' returns control names. '''
21+
self.version = version
22+
if self.version < 2.1:
23+
# version 2.0 has only one to one
24+
return self.commonControls + self.commonBoxes + [
25+
'labelSourceId', 'lineEditSourceId', 'buttonSelectSourceId',
26+
'labelTargetId','labelSide','lineEditSide','lineEditEdge_id','labelFraction','lineEditFraction', 'lineEditPointsTable', 'lineEditTargetId','labelPid','lineEditPid','labelEdge_id', 'buttonSelectTargetId',
27+
'labelEdge_id','labelSide'
28+
29+
]
30+
else:
31+
return self.commonControls + self.commonBoxes + [
32+
'labelSourceIds', 'lineEditSourceIds', 'buttonSelectSourceIds',
33+
'labelTargetIds', 'lineEditPointsTable', 'label_pointsTable', 'lineEditTargetIds', 'buttonSelectTargetIds',
34+
'labelSide','lineEditSide','lineEditEdge_id','labelEdge_id','labelFraction','lineEditFraction','labelPid','lineEditPid',
35+
'labelDrivingSide','checkBoxLeft','checkBoxRight'
36+
]
37+
38+
39+
@classmethod
40+
def isSupportedVersion(self, version):
41+
''' Checks supported version '''
42+
# valid starting pgr v2.1
43+
return version >= 2.1
44+
45+
46+
@classmethod
47+
def canExportQuery(self):
48+
return False
49+
50+
@classmethod
51+
def canExportMerged(self):
52+
return False
53+
54+
55+
56+
def prepare(self, canvasItemList):
57+
resultNodesTextAnnotations = canvasItemList['annotations']
58+
for anno in resultNodesTextAnnotations:
59+
anno.setVisible(False)
60+
canvasItemList['annotations'] = []
61+
62+
63+
def getQuery(self, args):
64+
''' returns the sql query in required signature format of pgr_withPointsCost '''
65+
args['where_clause'] = self.whereClause(args['edge_table'], args['geometry'], args['BBOX'])
66+
args['where_clause_with'] = self.whereClause(args['points_table'], args['geometry'], args['BBOX'])
67+
return """
68+
SELECT start_vid AS start_vid , end_vid AS end_vid, cost AS cost
69+
FROM pgr_withPointsCost('
70+
SELECT %(id)s AS id,
71+
%(source)s AS source,
72+
%(target)s AS target,
73+
%(cost)s AS cost
74+
%(reverse_cost)s
75+
FROM %(edge_table)s
76+
%(where_clause)s
77+
',
78+
'SELECT %(pid)s AS pid,
79+
%(edge_id)s AS edge_id,
80+
%(fraction)s AS fraction,
81+
%(side)s AS side
82+
FROM %(points_table)s
83+
%(where_clause_with)s',
84+
array[%(source_ids)s]::BIGINT[], array[%(target_ids)s]::BIGINT[], %(directed)s, '%(driving_side)s')
85+
""" % args
86+
87+
def getExportQuery(self, args):
88+
args['result_query'] = self.getQuery(args)
89+
args['vertex_table'] = """
90+
%(edge_table)s_vertices_pgr
91+
""" % args
92+
93+
return """
94+
WITH
95+
result AS ( %(result_query)s )
96+
SELECT result.*, ST_MakeLine(a.the_geom, b.the_geom) AS path_geom
97+
98+
FROM result
99+
JOIN %(vertex_table)s AS a ON (start_vid = a.id)
100+
JOIN %(vertex_table)s AS b ON (end_vid = b.id)
101+
""" % args
102+
103+
104+
105+
106+
def draw(self, rows, con, args, geomType, canvasItemList, mapCanvas):
107+
''' draw the result '''
108+
resultPathsRubberBands = canvasItemList['paths']
109+
rubberBand = None
110+
cur_path_id = -1
111+
for row in rows:
112+
cur2 = con.cursor()
113+
args['result_path_id'] = row[0]
114+
args['result_source_id'] = row[1]
115+
args['result_target_id'] = row[2]
116+
args['result_cost'] = row[3]
117+
if args['result_path_id'] != cur_path_id:
118+
cur_path_id = args['result_path_id']
119+
if rubberBand:
120+
resultPathsRubberBands.append(rubberBand)
121+
rubberBand = None
122+
123+
rubberBand = QgsRubberBand(mapCanvas, Utils.getRubberBandType(False))
124+
rubberBand.setColor(QColor(255, 0, 0, 128))
125+
rubberBand.setWidth(4)
126+
if args['result_cost'] != -1:
127+
query2 = """
128+
SELECT ST_AsText( ST_MakeLine(
129+
(SELECT the_geom FROM %(edge_table)s_vertices_pgr WHERE id = %(result_source_id)d),
130+
(SELECT the_geom FROM %(edge_table)s_vertices_pgr WHERE id = %(result_target_id)d)
131+
))
132+
""" % args
133+
##Utils.logMessage(query2)
134+
cur2.execute(query2)
135+
row2 = cur2.fetchone()
136+
##Utils.logMessage(str(row2[0]))
137+
assert row2, "Invalid result geometry. (path_id:%(result_path_id)d, saource_id:%(result_source_id)d, target_id:%(result_target_id)d)" % args
138+
139+
geom = QgsGeometry().fromWkt(str(row2[0]))
140+
if geom.wkbType() == QgsWkbTypes.MultiLineString:
141+
for line in geom.asMultiPolyline():
142+
for pt in line:
143+
rubberBand.addPoint(pt)
144+
elif geom.wkbType() == QgsWkbTypes.LineString:
145+
for pt in geom.asPolyline():
146+
rubberBand.addPoint(pt)
147+
148+
if rubberBand:
149+
resultPathsRubberBands.append(rubberBand)
150+
rubberBand = None
151+
resultNodesTextAnnotations = canvasItemList['annotations']
152+
Utils.setStartPoint(geomType, args)
153+
Utils.setEndPoint(geomType, args)
154+
for row in rows:
155+
cur2 = con.cursor()
156+
args['result_seq'] = row[0]
157+
args['result_source_id'] = row[1]
158+
args['result_target_id'] = row[2]
159+
args['result_cost'] = row[3]
160+
query2 = """
161+
SELECT ST_AsText(%(transform_s)s%(startpoint)s%(transform_e)s) FROM %(edge_table)s
162+
WHERE %(source)s = %(result_target_id)d
163+
UNION
164+
SELECT ST_AsText(%(transform_s)s%(endpoint)s%(transform_e)s) FROM %(edge_table)s
165+
WHERE %(target)s = %(result_target_id)d
166+
""" % args
167+
cur2.execute(query2)
168+
row2 = cur2.fetchone()
169+
assert row2, "Invalid result geometry. (target_id:%(result_target_id)d)" % args
170+
171+
geom = QgsGeometry().fromWkt(str(row2[0]))
172+
pt = geom.asPoint()
173+
textDocument = QTextDocument("%(result_target_id)d:%(result_cost)f" % args)
174+
textAnnotation = QgsTextAnnotation()
175+
textAnnotation.setMapPosition(geom.asPoint())
176+
textAnnotation.setFrameSize(QSizeF(textDocument.idealWidth(), 20))
177+
textAnnotation.setFrameOffsetFromReferencePoint(QPointF(20, -40))
178+
textAnnotation.setDocument(textDocument)
179+
180+
QgsMapCanvasAnnotationItem(textAnnotation, mapCanvas)
181+
resultNodesTextAnnotations.append(textAnnotation)
182+
183+
184+
185+
def __init__(self, ui):
186+
FunctionBase.__init__(self, ui)

0 commit comments

Comments
 (0)