Skip to content

Commit

Permalink
Merge branch 'main' into 149-add-styling-from-qml-file
Browse files Browse the repository at this point in the history
  • Loading branch information
koebi committed Dec 21, 2023
2 parents f34f951 + 4b05e86 commit 5cbaabd
Show file tree
Hide file tree
Showing 10 changed files with 11,188 additions and 5,549 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,13 @@ RELEASING:
## Unreleased

### Added
- Add keyboard shortcut (Ctrl+R)
- Additional parameter for the "smoothing factor" to isochrones processing algorithms ([#172](https://github.com/GIScience/orstools-qgis-plugin/issues/172))
- Mention omission of configuration options when using traveling salesman
- option to set location type for isochrones ([#191](https://github.com/GIScience/orstools-qgis-plugin/pull/191))
- Add styling of routing output in main plugin ([#149](https://github.com/GIScience/orstools-qgis-plugin/issues/149))
- make items in centroid list drag and droppable ([#144](https://github.com/GIScience/orstools-qgis-plugin/issues/144))
- Add save button for vertices ([#144](https://github.com/GIScience/orstools-qgis-plugin/issues/144))

## [1.6.0] - 2023-07-25

Expand Down
75 changes: 71 additions & 4 deletions ORStools/gui/ORStoolsDialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,18 @@
import os
import processing
import webbrowser
from qgis.core import QgsProject, QgsVectorLayer, QgsTextAnnotation, QgsMapLayerProxyModel

from qgis._core import Qgis
from qgis.core import (
QgsProject,
QgsVectorLayer,
QgsTextAnnotation,
QgsMapLayerProxyModel,
QgsFeature,
QgsPointXY,
QgsGeometry,
QgsCoordinateReferenceSystem,
)
from qgis.gui import QgsMapCanvasAnnotationItem

from PyQt5.QtCore import QSizeF, QPointF, QCoreApplication, QSettings
Expand All @@ -58,6 +69,8 @@
from .ORStoolsDialogConfig import ORStoolsDialogConfigMain
from .ORStoolsDialogUI import Ui_ORStoolsDialogBase

from . import resources_rc # noqa: F401


def on_config_click(parent):
"""Pop up provider config window. Outside of classes because it's accessed by multiple dialogs.
Expand Down Expand Up @@ -415,6 +428,7 @@ def __init__(self, iface, parent=None):
# Routing tab
self.routing_fromline_map.clicked.connect(self._on_linetool_init)
self.routing_fromline_clear.clicked.connect(self._on_clear_listwidget_click)
self.save_vertices.clicked.connect(self._save_vertices_to_layer)

# Batch
self.batch_routing_points.clicked.connect(
Expand All @@ -436,6 +450,37 @@ def __init__(self, iface, parent=None):
lambda: processing.execAlgorithmDialog(f"{PLUGIN_NAME}:matrix_from_layers")
)

# Reset index of list items every time something is moved or deleted
self.routing_fromline_list.model().rowsMoved.connect(self._reindex_list_items)
self.routing_fromline_list.model().rowsRemoved.connect(self._reindex_list_items)

def _save_vertices_to_layer(self):
"""Saves the vertices list to a temp layer"""
items = [
self.routing_fromline_list.item(x).text()
for x in range(self.routing_fromline_list.count())
]

if len(items) > 0:
point_layer = QgsVectorLayer(
"point?crs=epsg:4326&field=ID:integer", "Vertices", "memory"
)
point_layer.updateFields()
for idx, x in enumerate(items):
coords = x.split(":")[1]
x, y = (float(i) for i in coords.split(", "))
feature = QgsFeature()
feature.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(x, y)))
feature.setAttributes([idx])

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

self._iface.messageBar().pushMessage(
"Success", "Vertices saved to layer.", level=Qgis.Success
)

def _on_prov_refresh_click(self):
"""Populates provider dropdown with fresh list from config.yml"""

Expand All @@ -459,8 +504,10 @@ def _on_clear_listwidget_click(self):
self.routing_fromline_list.clear()
self._clear_annotations()

def _linetool_annotate_point(self, point, idx):
map_crs = self._iface.mapCanvas().mapSettings().destinationCrs()
def _linetool_annotate_point(self, point, idx, crs=None):
if not crs:
crs = self._iface.mapCanvas().mapSettings().destinationCrs()

annotation = QgsTextAnnotation()

c = QTextDocument()
Expand All @@ -472,7 +519,7 @@ def _linetool_annotate_point(self, point, idx):
annotation.setFrameSizeMm(QSizeF(7, 5))
annotation.setFrameOffsetFromReferencePointMm(QPointF(1.3, 1.3))
annotation.setMapPosition(point)
annotation.setMapPositionCrs(map_crs)
annotation.setMapPositionCrs(crs)

return QgsMapCanvasAnnotationItem(annotation, self._iface.mapCanvas()).annotation()

Expand Down Expand Up @@ -509,6 +556,26 @@ def _on_linetool_map_click(self, point, idx):
self.annotations.append(annotation)
self.project.annotationManager().addAnnotation(annotation)

def _reindex_list_items(self):
"""Resets the index when an item in the list is moved"""
items = [
self.routing_fromline_list.item(x).text()
for x in range(self.routing_fromline_list.count())
]
self.routing_fromline_list.clear()
self._clear_annotations()
crs = QgsCoordinateReferenceSystem(f"EPSG:{4326}")
for idx, x in enumerate(items):
coords = x.split(":")[1]
item = f"Point {idx}:{coords}"
x, y = (float(i) for i in coords.split(", "))
point = QgsPointXY(x, y)

self.routing_fromline_list.addItem(item)
annotation = self._linetool_annotate_point(point, idx, crs)
self.annotations.append(annotation)
self.project.annotationManager().addAnnotation(annotation)

def _on_linetool_map_doubleclick(self):
"""
Populate line list widget with coordinates, end line drawing and show dialog again.
Expand Down
69 changes: 43 additions & 26 deletions ORStools/gui/ORStoolsDialogUI.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
# -*- 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.14.1
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING! All changes made in this file will be lost!
# 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.


from PyQt5 import QtCore, QtGui, QtWidgets
Expand All @@ -13,7 +14,7 @@
class Ui_ORStoolsDialogBase(object):
def setupUi(self, ORStoolsDialogBase):
ORStoolsDialogBase.setObjectName("ORStoolsDialogBase")
ORStoolsDialogBase.resize(412, 868)
ORStoolsDialogBase.resize(412, 686)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
Expand Down Expand Up @@ -191,18 +192,31 @@ def setupUi(self, ORStoolsDialogBase):
self.routing_fromline_list.setMinimumSize(QtCore.QSize(0, 0))
self.routing_fromline_list.setMaximumSize(QtCore.QSize(16777215, 16777215))
self.routing_fromline_list.setFrameShadow(QtWidgets.QFrame.Sunken)
self.routing_fromline_list.setDragDropMode(QtWidgets.QAbstractItemView.InternalMove)
self.routing_fromline_list.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection)
self.routing_fromline_list.setResizeMode(QtWidgets.QListView.Fixed)
self.routing_fromline_list.setObjectName("routing_fromline_list")
self.gridLayout.addWidget(self.routing_fromline_list, 0, 2, 3, 1)
self.gridLayout.addWidget(self.routing_fromline_list, 0, 1, 4, 1)
self.save_vertices = QtWidgets.QPushButton(self.widget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.save_vertices.sizePolicy().hasHeightForWidth())
self.save_vertices.setSizePolicy(sizePolicy)
self.save_vertices.setText("")
icon4 = QtGui.QIcon()
icon4.addPixmap(QtGui.QPixmap(":/plugins/ORStools/img/save_vertices.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.save_vertices.setIcon(icon4)
self.save_vertices.setObjectName("save_vertices")
self.gridLayout.addWidget(self.save_vertices, 2, 0, 1, 1)
self.verticalLayout_7.addWidget(self.widget)
self.advances_group = gui.QgsCollapsibleGroupBox(self.qwidget)
self.advances_group = QgsCollapsibleGroupBox(self.qwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.advances_group.sizePolicy().hasHeightForWidth())
self.advances_group.setSizePolicy(sizePolicy)
self.advances_group.setMaximumSize(QtCore.QSize(16777215, 23))
self.advances_group.setMaximumSize(QtCore.QSize(16777215, 20))
self.advances_group.setCheckable(False)
self.advances_group.setChecked(False)
self.advances_group.setCollapsed(True)
Expand All @@ -211,14 +225,14 @@ def setupUi(self, ORStoolsDialogBase):
self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.advances_group)
self.verticalLayout_3.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint)
self.verticalLayout_3.setObjectName("verticalLayout_3")
self.optimization_group = gui.QgsCollapsibleGroupBox(self.advances_group)
self.optimization_group = QgsCollapsibleGroupBox(self.advances_group)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
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, 23))
self.optimization_group.setMaximumSize(QtCore.QSize(16777215, 20))
self.optimization_group.setCheckable(True)
self.optimization_group.setChecked(False)
self.optimization_group.setCollapsed(True)
Expand Down Expand Up @@ -255,7 +269,7 @@ def setupUi(self, ORStoolsDialogBase):
self.optimize_button_group.addButton(self.round_trip)
self.gridLayout_2.addWidget(self.round_trip, 2, 0, 1, 1)
self.verticalLayout_3.addWidget(self.optimization_group)
self.routing_avoid_tags_group = gui.QgsCollapsibleGroupBox(self.advances_group)
self.routing_avoid_tags_group = QgsCollapsibleGroupBox(self.advances_group)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
Expand Down Expand Up @@ -285,40 +299,40 @@ def setupUi(self, ORStoolsDialogBase):
self.routing_avoid_tracks_3.setObjectName("routing_avoid_tracks_3")
self.gridLayout_4.addWidget(self.routing_avoid_tracks_3, 2, 0, 1, 1)
self.verticalLayout_3.addWidget(self.routing_avoid_tags_group)
self.routing_avoid_countries_group = gui.QgsCollapsibleGroupBox(self.advances_group)
self.routing_avoid_countries_group = QgsCollapsibleGroupBox(self.advances_group)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.routing_avoid_countries_group.sizePolicy().hasHeightForWidth())
self.routing_avoid_countries_group.setSizePolicy(sizePolicy)
self.routing_avoid_countries_group.setMaximumSize(QtCore.QSize(16777215, 23))
self.routing_avoid_countries_group.setMaximumSize(QtCore.QSize(16777215, 20))
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")
self.countries_text = gui.QgsFilterLineEdit(self.routing_avoid_countries_group)
self.countries_text = QgsFilterLineEdit(self.routing_avoid_countries_group)
self.countries_text.setProperty("qgisRelation", "")
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 = gui.QgsCollapsibleGroupBox(self.advances_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.setMaximumSize(QtCore.QSize(16777215, 20))
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 = gui.QgsMapLayerComboBox(self.avoidpolygon_group)
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)
Expand Down Expand Up @@ -381,14 +395,14 @@ def setupUi(self, ORStoolsDialogBase):
self.verticalLayout.addItem(spacerItem)
self.tabWidget.addTab(self.batch_tab, "")
self.verticalLayout_5.addWidget(self.tabWidget)
self.ors_log_group = gui.QgsCollapsibleGroupBox(ORStoolsDialogBase)
self.ors_log_group = QgsCollapsibleGroupBox(ORStoolsDialogBase)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.ors_log_group.sizePolicy().hasHeightForWidth())
self.ors_log_group.setSizePolicy(sizePolicy)
self.ors_log_group.setMinimumSize(QtCore.QSize(0, 0))
self.ors_log_group.setMaximumSize(QtCore.QSize(16777215, 23))
self.ors_log_group.setMaximumSize(QtCore.QSize(16777215, 20))
self.ors_log_group.setFlat(True)
self.ors_log_group.setCollapsed(True)
self.ors_log_group.setSaveCollapsedState(False)
Expand Down Expand Up @@ -425,15 +439,15 @@ def setupUi(self, ORStoolsDialogBase):
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.help_button.sizePolicy().hasHeightForWidth())
self.help_button.setSizePolicy(sizePolicy)
icon4 = QtGui.QIcon()
icon4.addPixmap(QtGui.QPixmap(":/plugins/ORStools/img/icon_help.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.help_button.setIcon(icon4)
icon5 = QtGui.QIcon()
icon5.addPixmap(QtGui.QPixmap(":/plugins/ORStools/img/icon_help.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.help_button.setIcon(icon5)
self.help_button.setObjectName("help_button")
self.horizontalLayout_8.addWidget(self.help_button)
self.about_button = QtWidgets.QPushButton(self.widget_2)
icon5 = QtGui.QIcon()
icon5.addPixmap(QtGui.QPixmap(":/plugins/ORStools/img/icon_about.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.about_button.setIcon(icon5)
icon6 = QtGui.QIcon()
icon6.addPixmap(QtGui.QPixmap(":/plugins/ORStools/img/icon_about.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.about_button.setIcon(icon6)
self.about_button.setObjectName("about_button")
self.horizontalLayout_8.addWidget(self.about_button)
self.global_buttons = QtWidgets.QDialogButtonBox(self.widget_2)
Expand Down Expand Up @@ -470,6 +484,7 @@ def retranslateUi(self, ORStoolsDialogBase):
self.routing_fromline_map.setToolTip(_translate("ORStoolsDialogBase", "<html><head/><body><p>Add wayoints interactively from the map canvas.</p><p>Double-click will terminate waypoint selection.</p></body></html>"))
self.routing_fromline_clear.setToolTip(_translate("ORStoolsDialogBase", "<html><head/><body><p>If waypoints are selected in the list, only these will be deleted. Else all waypoints will be deleted.</p></body></html>"))
self.routing_fromline_list.setToolTip(_translate("ORStoolsDialogBase", "Select waypoints from the map!"))
self.save_vertices.setToolTip(_translate("ORStoolsDialogBase", "<html><head/><body><p>Save points in list to layer.</p></body></html>"))
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"))
Expand Down Expand Up @@ -515,5 +530,7 @@ def retranslateUi(self, ORStoolsDialogBase):
self.debug_text.setPlaceholderText(_translate("ORStoolsDialogBase", "Queries and errors will be printed here."))
self.help_button.setText(_translate("ORStoolsDialogBase", " Help"))
self.about_button.setText(_translate("ORStoolsDialogBase", "About"))
from qgis import gui
from . import resources_rc
from qgscollapsiblegroupbox import QgsCollapsibleGroupBox
from qgsfilterlineedit import QgsFilterLineEdit
from qgsmaplayercombobox import QgsMapLayerComboBox
# import resources_rc
Loading

0 comments on commit 5cbaabd

Please sign in to comment.