Skip to content

Commit

Permalink
implement avoid_polygons in GUI
Browse files Browse the repository at this point in the history
  • Loading branch information
nilsnolde committed Sep 2, 2019
1 parent 1031a31 commit 1492cf5
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 31 deletions.
8 changes: 5 additions & 3 deletions ORStools/gui/ORStoolsDialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@

from qgis.core import (QgsProject,
QgsVectorLayer,
QgsTextAnnotation)
from qgis.gui import QgsFilterLineEdit, QgsMapCanvasAnnotationItem
QgsTextAnnotation,
QgsMapLayerProxyModel)
from qgis.gui import QgsMapCanvasAnnotationItem
import processing

from . import resources_rc
Expand Down Expand Up @@ -86,7 +87,7 @@ def on_about_click(parent):
'Author: Nils Nolde<br>' \
'Email: <a href="mailto:Nils Nolde <{1}>">{1}</a><br>' \
'Web: <a href="{2}">{2}</a><br>' \
'Repo: <a href="https://github.com/nilsnolde/ORStools">github.com/nilsnolde/ORStools</a><br>' \
'Repo: <a href="https://github.com/GIScience/ORStools">github.com/GIScience/ORStools</a><br>' \
'Version: {3}'.format(DEFAULT_COLOR, __email__, __web__, __version__)

QMessageBox.information(
Expand Down Expand Up @@ -209,6 +210,7 @@ def _init_gui_control(self):
# Make sure plugin window stays open when OK is clicked by reconnecting the accepted() signal
self.dlg.global_buttons.accepted.disconnect(self.dlg.accept)
self.dlg.global_buttons.accepted.connect(self.run_gui_control)
self.dlg.avoidpolygon_dropdown.setFilters(QgsMapLayerProxyModel.PolygonLayer)

# Populate provider box on window startup, since can be changed from multiple menus/buttons
providers = configmanager.read_config()['providers']
Expand Down
37 changes: 32 additions & 5 deletions ORStools/gui/ORStoolsDialogUI.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
class Ui_ORStoolsDialogBase(object):
def setupUi(self, ORStoolsDialogBase):
ORStoolsDialogBase.setObjectName("ORStoolsDialogBase")
ORStoolsDialogBase.resize(412, 781)
ORStoolsDialogBase.resize(412, 868)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
Expand Down Expand Up @@ -200,10 +200,11 @@ def setupUi(self, ORStoolsDialogBase):
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.advances_group.sizePolicy().hasHeightForWidth())
self.advances_group.setSizePolicy(sizePolicy)
self.advances_group.setMaximumSize(QtCore.QSize(16777215, 16777215))
self.advances_group.setMaximumSize(QtCore.QSize(16777215, 23))
self.advances_group.setCheckable(False)
self.advances_group.setChecked(False)
self.advances_group.setCollapsed(False)
self.advances_group.setCollapsed(True)
self.advances_group.setSaveCollapsedState(False)
self.advances_group.setObjectName("advances_group")
self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.advances_group)
self.verticalLayout_3.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint)
Expand All @@ -215,10 +216,11 @@ def setupUi(self, ORStoolsDialogBase):
sizePolicy.setHeightForWidth(self.optimization_group.sizePolicy().hasHeightForWidth())
self.optimization_group.setSizePolicy(sizePolicy)
self.optimization_group.setMinimumSize(QtCore.QSize(0, 0))
self.optimization_group.setMaximumSize(QtCore.QSize(16777215, 115))
self.optimization_group.setMaximumSize(QtCore.QSize(16777215, 23))
self.optimization_group.setCheckable(True)
self.optimization_group.setChecked(False)
self.optimization_group.setCollapsed(False)
self.optimization_group.setCollapsed(True)
self.optimization_group.setSaveCollapsedState(False)
self.optimization_group.setObjectName("optimization_group")
self.gridLayout_2 = QtWidgets.QGridLayout(self.optimization_group)
self.gridLayout_2.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint)
Expand Down Expand Up @@ -255,6 +257,7 @@ def setupUi(self, ORStoolsDialogBase):
self.routing_avoid_tags_group.setCheckable(True)
self.routing_avoid_tags_group.setChecked(False)
self.routing_avoid_tags_group.setCollapsed(True)
self.routing_avoid_tags_group.setSaveCollapsedState(False)
self.routing_avoid_tags_group.setObjectName("routing_avoid_tags_group")
self.gridLayout_4 = QtWidgets.QGridLayout(self.routing_avoid_tags_group)
self.gridLayout_4.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint)
Expand Down Expand Up @@ -285,6 +288,7 @@ def setupUi(self, ORStoolsDialogBase):
self.routing_avoid_countries_group.setCheckable(True)
self.routing_avoid_countries_group.setChecked(False)
self.routing_avoid_countries_group.setCollapsed(True)
self.routing_avoid_countries_group.setSaveCollapsedState(False)
self.routing_avoid_countries_group.setObjectName("routing_avoid_countries_group")
self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.routing_avoid_countries_group)
self.verticalLayout_4.setObjectName("verticalLayout_4")
Expand All @@ -293,6 +297,25 @@ def setupUi(self, ORStoolsDialogBase):
self.countries_text.setObjectName("countries_text")
self.verticalLayout_4.addWidget(self.countries_text)
self.verticalLayout_3.addWidget(self.routing_avoid_countries_group)
self.avoidpolygon_group = QgsCollapsibleGroupBox(self.advances_group)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.avoidpolygon_group.sizePolicy().hasHeightForWidth())
self.avoidpolygon_group.setSizePolicy(sizePolicy)
self.avoidpolygon_group.setMaximumSize(QtCore.QSize(16777215, 23))
self.avoidpolygon_group.setCheckable(True)
self.avoidpolygon_group.setChecked(False)
self.avoidpolygon_group.setCollapsed(True)
self.avoidpolygon_group.setSaveCollapsedState(False)
self.avoidpolygon_group.setObjectName("avoidpolygon_group")
self.verticalLayout_6 = QtWidgets.QVBoxLayout(self.avoidpolygon_group)
self.verticalLayout_6.setObjectName("verticalLayout_6")
self.avoidpolygon_dropdown = QgsMapLayerComboBox(self.avoidpolygon_group)
self.avoidpolygon_dropdown.setShowCrs(False)
self.avoidpolygon_dropdown.setObjectName("avoidpolygon_dropdown")
self.verticalLayout_6.addWidget(self.avoidpolygon_dropdown)
self.verticalLayout_3.addWidget(self.avoidpolygon_group)
self.verticalLayout_7.addWidget(self.advances_group)
self.tabWidget.addTab(self.qwidget, "")
self.batch_tab = QtWidgets.QWidget()
Expand Down Expand Up @@ -465,6 +488,9 @@ def retranslateUi(self, ORStoolsDialogBase):
self.routing_avoid_countries_group.setToolTip(_translate("ORStoolsDialogBase", "<html><head/><body><p>Avoid countries based on alphnumeric ISO 3166 Alpha-2 or Alpha-3 codes.</p><p>Find a list of codes at https://github.com/GIScience/openrouteservice-docs#country-list.</p></body></html>"))
self.routing_avoid_countries_group.setTitle(_translate("ORStoolsDialogBase", "Avoid countries"))
self.countries_text.setToolTip(_translate("ORStoolsDialogBase", "<html><head/><body><p>Avoid countries based on ISO 3166 Alpha-2 or Alpha-3 codes.</p></body></html>"))
self.avoidpolygon_group.setToolTip(_translate("ORStoolsDialogBase", "<html><head/><body><p>Avoid areas by specifying a (Multi-)Polygon layer. </p><p><br/></p><p><span style=\" font-weight:600;\">Note</span>, only the first feature of the layer will be respected.</p></body></html>"))
self.avoidpolygon_group.setTitle(_translate("ORStoolsDialogBase", "Avoid polygon(s)"))
self.avoidpolygon_dropdown.setToolTip(_translate("ORStoolsDialogBase", "<html><head/><body><p>Avoid areas by specifying a (Multi-)Polygon layer. </p><p><br/></p><p><span style=\" font-weight:600;\">Note</span>, only the first feature of the layer will be respected.</p></body></html>"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.qwidget), _translate("ORStoolsDialogBase", "Advanced Directions"))
self.groupBox.setTitle(_translate("ORStoolsDialogBase", "Directions"))
self.batch_routing_line.setText(_translate("ORStoolsDialogBase", "Polylines Layer"))
Expand All @@ -483,4 +509,5 @@ def retranslateUi(self, ORStoolsDialogBase):

from qgscollapsiblegroupbox import QgsCollapsibleGroupBox
from qgsfilterlineedit import QgsFilterLineEdit
from qgsmaplayercombobox import QgsMapLayerComboBox
from . import resources_rc
69 changes: 66 additions & 3 deletions ORStools/gui/ORStoolsDialogUI.ui
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>412</width>
<height>781</height>
<height>868</height>
</rect>
</property>
<property name="sizePolicy">
Expand Down Expand Up @@ -352,7 +352,7 @@
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
<height>23</height>
</size>
</property>
<property name="title">
Expand All @@ -365,6 +365,9 @@
<bool>false</bool>
</property>
<property name="collapsed">
<bool>true</bool>
</property>
<property name="saveCollapsedState">
<bool>false</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
Expand All @@ -388,7 +391,7 @@
<property name="maximumSize">
<size>
<width>16777215</width>
<height>115</height>
<height>23</height>
</size>
</property>
<property name="toolTip">
Expand All @@ -404,6 +407,9 @@
<bool>false</bool>
</property>
<property name="collapsed">
<bool>true</bool>
</property>
<property name="saveCollapsedState">
<bool>false</bool>
</property>
<layout class="QGridLayout" name="gridLayout_2" columnstretch="0,0,0,0">
Expand Down Expand Up @@ -499,6 +505,9 @@ p, li { white-space: pre-wrap; }
<property name="collapsed">
<bool>true</bool>
</property>
<property name="saveCollapsedState">
<bool>false</bool>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
Expand Down Expand Up @@ -570,6 +579,9 @@ p, li { white-space: pre-wrap; }
<property name="collapsed">
<bool>true</bool>
</property>
<property name="saveCollapsedState">
<bool>false</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QgsFilterLineEdit" name="countries_text">
Expand All @@ -584,6 +596,52 @@ p, li { white-space: pre-wrap; }
</layout>
</widget>
</item>
<item>
<widget class="QgsCollapsibleGroupBox" name="avoidpolygon_group">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>23</height>
</size>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Avoid areas by specifying a (Multi-)Polygon layer. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Note&lt;/span&gt;, only the first feature of the layer will be respected.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="title">
<string>Avoid polygon(s)</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<property name="collapsed">
<bool>true</bool>
</property>
<property name="saveCollapsedState">
<bool>false</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QgsMapLayerComboBox" name="avoidpolygon_dropdown">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Avoid areas by specifying a (Multi-)Polygon layer. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Note&lt;/span&gt;, only the first feature of the layer will be respected.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="showCrs">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
Expand Down Expand Up @@ -840,6 +898,11 @@ p, li { white-space: pre-wrap; }
<extends>QLineEdit</extends>
<header>qgsfilterlineedit.h</header>
</customwidget>
<customwidget>
<class>QgsMapLayerComboBox</class>
<extends>QComboBox</extends>
<header>qgsmaplayercombobox.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="resources.qrc"/>
Expand Down
57 changes: 39 additions & 18 deletions ORStools/gui/directions_gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

from PyQt5.QtWidgets import QCheckBox

from ORStools.utils import convert
from ORStools.utils import transform


class Directions:
Expand All @@ -45,6 +45,23 @@ def __init__(self, dlg):

self.options = dict()

def get_request_line_feature(self):
"""
Extracts all coordinates for the list in GUI.
:returns: coordinate list of line
:rtype: list
"""
coordinates = []
layers_list = self.dlg.routing_fromline_list
for idx in range(layers_list.count()):
item = layers_list.item(idx).text()
param, coords = item.split(":")

coordinates.append([float(coord) for coord in coords.split(', ')])

return [[round(x, 6), round(y, 6)] for x, y in coordinates]

def get_parameters(self):
"""
Builds parameters across directions functionalities.
Expand Down Expand Up @@ -73,6 +90,7 @@ def get_parameters(self):
avoid_boxes = self.dlg.routing_avoid_tags_group.findChildren(QCheckBox)
if any(box.isChecked() for box in avoid_boxes):
self.options['avoid_features'] = self._get_avoid_options(avoid_boxes)

if self.dlg.routing_avoid_countries_group.isChecked():
countries_text = self.dlg.countries_text.value()
if countries_text:
Expand All @@ -81,28 +99,19 @@ def get_parameters(self):
countries = [int(x) for x in countries]
self.options['avoid_countries'] = countries

if self.dlg.avoidpolygon_group.isChecked():
layer = self.dlg.avoidpolygon_dropdown.currentLayer()
if layer:
transformer = transform.transformToWGS(layer.sourceCrs())
geom = layer.getGeometry(0)
geom.transform(transformer)
self.options['avoid_polygons'] = json.loads(geom.asJson())

if self.options:
params['options'] = self.options

return params

def get_request_line_feature(self):
"""
Extracts all coordinates for the list in GUI.
:returns: coordinate list of line
:rtype: list
"""
coordinates = []
layers_list = self.dlg.routing_fromline_list
for idx in range(layers_list.count()):
item = layers_list.item(idx).text()
param, coords = item.split(":")

coordinates.append([float(coord) for coord in coords.split(', ')])

return [[round(x, 6), round(y, 6)] for x, y in coordinates]

def _get_avoid_options(self, avoid_boxes):
"""
Extracts checked boxes in Advanced avoid parameters.
Expand All @@ -120,6 +129,18 @@ def _get_avoid_options(self, avoid_boxes):

return avoid_features

def _get_avoid_polygons(self, layer):
"""
Extract polygon geometries from the selected polygon layer.
:param layer: The polygon layer
:type layer: QgsMapLayer
:returns: GeoJSON object
:rtype: dict
"""

return json.loads(geom.asJson())

def _get_optimize_parameters(self):
"""Return parameters for optimization waypoint"""
coordinates = self.get_request_line_feature()
Expand Down
5 changes: 3 additions & 2 deletions ORStools/metadata.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ name=ORS Tools
qgisMinimumVersion=3.0
description=openrouteservice routing, isochrones and matrix calculations for QGIS

version=1.1.1
version=1.2.0
author=GIS • OPS UG & HeiGIT gGmbH
email=nils@gis-ops.com

about=ORS Tools provides access to most of the functions of openrouteservice.org, based on OpenStreetMap. The tool set includes routing, isochrones and matrix calculations, either interactive in the map canvas or from point files within the processing framework. Extensive attributes are set for output files, incl. duration, length and start/end locations.

changelog=2019/08/19 v1.1.1 Update metadata, bcs repository moved to GIScience
changelog=2019/08/19 v1.2.0 Implement avoid_polygons parameter (#79)
2019/08/19 v1.1.1 Update metadata, bcs repository moved to GIScience
2019/08/19 v1.1.0 Implement Traveling Salesman (#109), proper support for > 2 waypoints (batch & interactive), enable elevation (#83), ORS API v2 (#99), add avoid_countries (#78)
2019/05/21 v1.0.7 Improve first user experience with warning messages (#106)
2019/05/02 v1.0.6 Make quota info optional (#106)
Expand Down

0 comments on commit 1492cf5

Please sign in to comment.