Skip to content

Commit

Permalink
feat: option to export waypoint order when requesting TSP (#227)
Browse files Browse the repository at this point in the history
Co-authored-by: koebi <koebi@ezelo.de>
  • Loading branch information
merydian and koebi authored May 10, 2024
1 parent 2f04fa2 commit a3df611
Show file tree
Hide file tree
Showing 7 changed files with 237 additions and 108 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ RELEASING:
14. Create new release in GitHub with tag version and release title of `vX.X.X`
-->

# Unreleased
- Add option to export order of optimization route points ([#145](https://github.com/GIScience/orstools-qgis-plugin/issues/145))

## Unreleased

Expand Down
23 changes: 23 additions & 0 deletions ORStools/gui/ORStoolsDialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,29 @@ def run_gui_control(self):
)
return
response = clnt.request("/optimization", {}, post_json=params)

if self.dlg.export_jobs_order.isChecked():
items = list()
for route in response["routes"]:
for i, step in enumerate(route["steps"]):
location = step["location"]
items.append(location)

point_layer = QgsVectorLayer(
"point?crs=epsg:4326&field=ID:integer", "Steps", "memory"
)

point_layer.updateFields()
for idx, coords in enumerate(items):
x, y = coords
feature = QgsFeature()
feature.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(x, y)))
feature.setAttributes([idx])

point_layer.dataProvider().addFeature(feature)
QgsProject.instance().addMapLayer(point_layer)
self.dlg._iface.mapCanvas().refresh()

feat = directions_core.get_output_features_optimization(
response, params["vehicles"][0]["profile"]
)
Expand Down
55 changes: 30 additions & 25 deletions ORStools/gui/ORStoolsDialogUI.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'ORSToolsDialogUI.ui'
# Form implementation generated from reading ui file 'ORStoolsDialogUI.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
# Created by: PyQt5 UI code generator 5.15.10
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
Expand All @@ -14,7 +14,7 @@
class Ui_ORStoolsDialogBase(object):
def setupUi(self, ORStoolsDialogBase):
ORStoolsDialogBase.setObjectName("ORStoolsDialogBase")
ORStoolsDialogBase.resize(412, 686)
ORStoolsDialogBase.resize(412, 868)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
Expand Down Expand Up @@ -241,33 +241,36 @@ def setupUi(self, ORStoolsDialogBase):
self.gridLayout_2 = QtWidgets.QGridLayout(self.optimization_group)
self.gridLayout_2.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint)
self.gridLayout_2.setObjectName("gridLayout_2")
self.fix_both = QtWidgets.QRadioButton(self.optimization_group)
self.fix_both.setChecked(False)
self.fix_both.setObjectName("fix_both")
self.optimize_button_group = QtWidgets.QButtonGroup(ORStoolsDialogBase)
self.optimize_button_group.setObjectName("optimize_button_group")
self.optimize_button_group.addButton(self.fix_both)
self.gridLayout_2.addWidget(self.fix_both, 2, 3, 1, 1)
self.label_4 = QtWidgets.QLabel(self.optimization_group)
self.label_4.setEnabled(False)
self.label_4.setObjectName("label_4")
self.gridLayout_2.addWidget(self.label_4, 0, 0, 1, 4)
self.fix_start = QtWidgets.QRadioButton(self.optimization_group)
self.fix_start.setObjectName("fix_start")
self.optimize_button_group = QtWidgets.QButtonGroup(ORStoolsDialogBase)
self.optimize_button_group.setObjectName("optimize_button_group")
self.optimize_button_group.addButton(self.fix_start)
self.gridLayout_2.addWidget(self.fix_start, 2, 1, 1, 1)
self.label_5 = QtWidgets.QLabel(self.optimization_group)
self.label_5.setObjectName("label_5")
self.gridLayout_2.addWidget(self.label_5, 1, 0, 1, 3, QtCore.Qt.AlignHCenter)
self.fix_end = QtWidgets.QRadioButton(self.optimization_group)
self.fix_end.setObjectName("fix_end")
self.optimize_button_group.addButton(self.fix_end)
self.gridLayout_2.addWidget(self.fix_end, 2, 2, 1, 1)
self.label_5 = QtWidgets.QLabel(self.optimization_group)
self.label_5.setObjectName("label_5")
self.gridLayout_2.addWidget(self.label_5, 1, 0, 1, 3, QtCore.Qt.AlignHCenter)
self.fix_both = QtWidgets.QRadioButton(self.optimization_group)
self.fix_both.setChecked(False)
self.fix_both.setObjectName("fix_both")
self.optimize_button_group.addButton(self.fix_both)
self.gridLayout_2.addWidget(self.fix_both, 2, 3, 1, 1)
self.fix_start = QtWidgets.QRadioButton(self.optimization_group)
self.fix_start.setObjectName("fix_start")
self.optimize_button_group.addButton(self.fix_start)
self.gridLayout_2.addWidget(self.fix_start, 2, 1, 1, 1)
self.round_trip = QtWidgets.QRadioButton(self.optimization_group)
self.round_trip.setChecked(True)
self.round_trip.setObjectName("round_trip")
self.optimize_button_group.addButton(self.round_trip)
self.gridLayout_2.addWidget(self.round_trip, 2, 0, 1, 1)
self.export_jobs_order = QtWidgets.QCheckBox(self.optimization_group)
self.export_jobs_order.setObjectName("export_jobs_order")
self.gridLayout_2.addWidget(self.export_jobs_order, 3, 1, 1, 2)
self.verticalLayout_3.addWidget(self.optimization_group)
self.routing_avoid_tags_group = QgsCollapsibleGroupBox(self.advances_group)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
Expand Down Expand Up @@ -464,8 +467,8 @@ def setupUi(self, ORStoolsDialogBase):

self.retranslateUi(ORStoolsDialogBase)
self.tabWidget.setCurrentIndex(0)
self.global_buttons.accepted.connect(ORStoolsDialogBase.accept)
self.global_buttons.rejected.connect(ORStoolsDialogBase.reject)
self.global_buttons.accepted.connect(ORStoolsDialogBase.accept) # type: ignore
self.global_buttons.rejected.connect(ORStoolsDialogBase.reject) # type: ignore
QtCore.QMetaObject.connectSlotsByName(ORStoolsDialogBase)

def retranslateUi(self, ORStoolsDialogBase):
Expand All @@ -488,20 +491,22 @@ def retranslateUi(self, ORStoolsDialogBase):
self.advances_group.setTitle(_translate("ORStoolsDialogBase", "Advanced Configuration"))
self.optimization_group.setToolTip(_translate("ORStoolsDialogBase", "<html><head/><body><p>Enabling Traveling Salesman will omit all other advanced configuration and assume the preference to be <span style=\" font-weight:600;\">fastest</span>.</p></body></html>"))
self.optimization_group.setTitle(_translate("ORStoolsDialogBase", "Traveling Salesman"))
self.fix_both.setToolTip(_translate("ORStoolsDialogBase", "<html><head/><body><p>First and last waypoints are not optimized.</p></body></html>"))
self.fix_both.setText(_translate("ORStoolsDialogBase", "Fix Both"))
self.label_4.setText(_translate("ORStoolsDialogBase", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'Ubuntu\'; font-size:11pt; font-weight:400; font-style:normal;\">\n"
"<p style=\" padding: 10px; -qt-block-indent:0; text-indent:0px ; background-color:#e7f2fa; color: #999999\"><img stype=\"margin: 10px\" src=\":/plugins/ORStools/img/icon_about.png\" width=16 height=16 /> All other configuration will be omitted</p></body></html>"))
self.fix_start.setToolTip(_translate("ORStoolsDialogBase", "<html><head/><body><p>First waypoint won\'t be optimized.</p></body></html>"))
self.fix_start.setText(_translate("ORStoolsDialogBase", "Fix Start"))
self.label_5.setText(_translate("ORStoolsDialogBase", "<html><head/><body><p><span style=\" font-weight:600;\">Other Options</span></p></body></html>"))
self.fix_end.setToolTip(_translate("ORStoolsDialogBase", "<html><head/><body><p>Last waypoint won\'t be optimized.</p></body></html>"))
self.fix_end.setText(_translate("ORStoolsDialogBase", "Fix End"))
self.label_5.setText(_translate("ORStoolsDialogBase", "<html><head/><body><p><span style=\" font-weight:600;\">Other Options</span></p></body></html>"))
self.fix_both.setToolTip(_translate("ORStoolsDialogBase", "<html><head/><body><p>First and last waypoints are not optimized.</p></body></html>"))
self.fix_both.setText(_translate("ORStoolsDialogBase", "Fix Both"))
self.fix_start.setToolTip(_translate("ORStoolsDialogBase", "<html><head/><body><p>First waypoint won\'t be optimized.</p></body></html>"))
self.fix_start.setText(_translate("ORStoolsDialogBase", "Fix Start"))
self.round_trip.setToolTip(_translate("ORStoolsDialogBase", "<html><head/><body><p>Return to first waypoint after last waypoint.</p></body></html>"))
self.round_trip.setText(_translate("ORStoolsDialogBase", "Round Trip"))
self.export_jobs_order.setToolTip(_translate("ORStoolsDialogBase", "<html><body><p>Create a point layer with the order in which the waypoints are traversed.</p></body></html>"))
self.export_jobs_order.setText(_translate("ORStoolsDialogBase", "Export order of jobs"))
self.routing_avoid_tags_group.setToolTip(_translate("ORStoolsDialogBase", "Avoid certain road attributes."))
self.routing_avoid_tags_group.setTitle(_translate("ORStoolsDialogBase", "Avoid tags"))
self.routing_avoid_highways_3.setText(_translate("ORStoolsDialogBase", "highways"))
Expand Down Expand Up @@ -533,4 +538,4 @@ def retranslateUi(self, ORStoolsDialogBase):
from qgscollapsiblegroupbox import QgsCollapsibleGroupBox
from qgsfilterlineedit import QgsFilterLineEdit
from qgsmaplayercombobox import QgsMapLayerComboBox
# import resources_rc
from . import resources_rc
56 changes: 33 additions & 23 deletions ORStools/gui/ORStoolsDialogUI.ui
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,22 @@
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<item row="2" column="3">
<widget class="QRadioButton" name="fix_both">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;First and last waypoints are not optimized.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Fix Both</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">optimize_button_group</string>
</attribute>
</widget>
</item>
<item row="0" column="0" colspan="4">
<widget class="QLabel" name="label_4">
<property name="enabled">
Expand All @@ -453,17 +469,11 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QRadioButton" name="fix_start">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;First waypoint won't be optimized.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<item row="1" column="0" colspan="3" alignment="Qt::AlignHCenter">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Fix Start</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Other Options&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<attribute name="buttonGroup">
<string notr="true">optimize_button_group</string>
</attribute>
</widget>
</item>
<item row="2" column="2">
Expand All @@ -479,23 +489,13 @@ p, li { white-space: pre-wrap; }
</attribute>
</widget>
</item>
<item row="1" column="0" colspan="3" alignment="Qt::AlignHCenter">
<widget class="QLabel" name="label_5">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Other Options&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QRadioButton" name="fix_both">
<item row="2" column="1">
<widget class="QRadioButton" name="fix_start">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;First and last waypoints are not optimized.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;First waypoint won't be optimized.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Fix Both</string>
</property>
<property name="checked">
<bool>false</bool>
<string>Fix Start</string>
</property>
<attribute name="buttonGroup">
<string notr="true">optimize_button_group</string>
Expand All @@ -518,6 +518,16 @@ p, li { white-space: pre-wrap; }
</attribute>
</widget>
</item>
<item row="3" column="1" colspan="2">
<widget class="QCheckBox" name="export_jobs_order">
<property name="toolTip">
<string>&lt;html&gt;&lt;body&gt;&lt;p&gt;Create a point layer with the order in which the waypoints are traversed.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Export order of jobs</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
Expand Down
Loading

0 comments on commit a3df611

Please sign in to comment.