Преглед изворни кода

code structure: add gui and core submodules

feature/processing_qgs2
noerw пре 1 година
родитељ
комит
07079ec2c8

+ 4
- 6
Makefile Прегледај датотеку

@@ -37,21 +37,19 @@ LOCALES =
PLUGINNAME = OSMtools

PY_FILES = \
auxiliary.py dialog.py geocode.py matrix.py resources.py \
client.py directions.py __init__.py osm_tools.py resources_rc.py \
convert.py exceptions.py isochrones.py pointtool.py \
osmtools_processing
__init__.py osm_tools.py \
core gui osmtools_processing

# translation
SOURCES = $(PY_FILES)

UI_FILES = *.ui
UI_FILES = gui/*.ui

EXTRAS = metadata.txt *.png config.yml

EXTRA_DIRS =

COMPILED_RESOURCE_FILES = resources.py resources_rc.py
COMPILED_RESOURCE_FILES = gui/resources.py gui/resources_rc.py

PEP8EXCLUDE=pydev,resources.py,conf.py,third_party,ui


+ 1
- 0
__init__.py Прегледај датотеку

@@ -35,6 +35,7 @@ def classFactory(iface): # pylint: disable=invalid-name
from .osm_tools import OSMtools
return OSMtools(iface)

# TODO: test if this actually works on QGIS Server?
# noinspection PyDocstring,PyPep8Naming
def serverClassFactory(serverIface):
from osmtools_processing.provider import OSMtoolsAlgoProvider

+ 0
- 0
core/__init__.py Прегледај датотеку


auxiliary.py → core/auxiliary.py Прегледај датотеку

@@ -21,10 +21,10 @@ script_dir = os.path.dirname(os.path.abspath(__file__))
def checkCRS(layer, messageBar):
"""
Check if layer CRS is EPSG:4326.
:param layer: Layer to be inspected.
:type layer: QgsMapLayer
:param messageBar: QGIS interface message bar.
:type messageBar: QgsMessageBar
"""
@@ -34,7 +34,7 @@ def checkCRS(layer, messageBar):
messageBar.pushInfo('CRS conflict',
'The input layer CRS is {}, the output layer '
'CRS will be EPSG:4326'.format(layer_crs))
return layer
def transformToWGS(old_layer, old_crs):
@@ -48,29 +48,29 @@ def transformToWGS(old_layer, old_crs):
g.transform(xform)
f.setGeometry(g)
feats.append(f)
new_layer.dataProvider().addFeatures(feats)
attrs = old_layer.dataProvider().fields().toList()
new_layer.dataProvider().addAttributes(attrs)
new_layer.updateFields()
new_layer.updateFields()
return new_layer
def readConfig():
with open(os.path.join(script_dir, "config.yml")) as f:
with open(os.path.join(script_dir, '../config.yml')) as f:
doc = yaml.safe_load(f)
return doc
def writeConfig(key, value):
doc = readConfig()
doc[key] = value
with open(os.path.join(script_dir, "config.yml"), 'w') as f:
with open(os.path.join(script_dir, '../config.yml'), 'w') as f:
yaml.safe_dump(doc, f)
def pushProgressBar(iface):
progressMessageBar = iface.messageBar().createMessage("Requesting analysis from ORS...")
progress = QProgressBar(progressMessageBar)
@@ -78,5 +78,5 @@ def pushProgressBar(iface):
progress.setAlignment(Qt.AlignLeft|Qt.AlignVCenter)
progressMessageBar.layout().addWidget(progress)
iface.messageBar().pushWidget(progressMessageBar, level=iface.messageBar().INFO)
return progress, progressMessageBar
return progress, progressMessageBar

client.py → core/client.py Прегледај датотеку

@@ -15,7 +15,7 @@ import collections
from urllib.parse import urlencode

import OSMtools
from OSMtools import exceptions, auxiliary
from OSMtools.core import exceptions, auxiliary

_USER_AGENT = "ORSClientQGIS/%s".format(OSMtools.__version__)
_RETRIABLE_STATUSES = [503]

convert.py → core/convert.py Прегледај датотеку


exceptions.py → core/exceptions.py Прегледај датотеку


geocode.py → core/geocode.py Прегледај датотеку

@@ -6,20 +6,20 @@ Created on Sun Feb 18 00:49:36 2018
@author: nilsnolde
"""

from OSMtools import convert
from OSMtools.core import convert

def reverse_geocode(client, point_in):
params = dict()
point_in_list = convert._comma_list([point_in.x(), point_in.y()])
params['location'] = point_in_list
try:
response = client.request('/geocoding', params)['features'][0]
except:
raise #ValueError("Your input coordinates are invalid for geocoding.")
response_dict = dict()
x, y = response['geometry'].get('coordinates',None)
response_dict['Lon'] = x
response_dict['Lat'] = y
@@ -29,5 +29,5 @@ def reverse_geocode(client, point_in):
response_dict['POSTALCODE'] = response['properties'].get('postal_code', None)
response_dict['STREET'] = response['properties'].get('street', None)
response_dict['NUMBER'] = response['properties'].get('house_number', None)
return response_dict
return response_dict

+ 0
- 0
gui/__init__.py Прегледај датотеку


dialog.py → gui/dialog.py Прегледај датотеку

@@ -31,14 +31,15 @@ from PyQt4.QtGui import (QPixmap,
QApplication,
QComboBox,
QPushButton,)
from qgis.core import (QgsProject,
QgsLayerTreeLayer,
from qgis.core import (QgsProject,
QgsLayerTreeLayer,
QgsMapLayer,
QGis,
QgsMapLayerRegistry
)

from OSMtools import pointtool, geocode, auxiliary, client
from OSMtools.gui import pointtool
from OSMtools.core import auxiliary, client, geocode

FORM_CLASS, _ = loadUiType(os.path.join(
os.path.dirname(__file__), 'osm_tools_dialog_base.ui'))
@@ -60,7 +61,7 @@ preferences = ['fastest', 'shortest']
units = ['time', 'distance']

# For matrix API only
metrics =['duration', 'distance', 'distance|duration']
metrics =['duration', 'distance', 'distance|duration']

class OSMtoolsDialog(QDialog, FORM_CLASS):
def __init__(self, iface):
@@ -74,11 +75,11 @@ class OSMtoolsDialog(QDialog, FORM_CLASS):
self.setupUi(self)
self.iface = iface
self.script_dir = os.path.dirname(os.path.abspath(__file__))
self.mapInstance = QgsMapLayerRegistry.instance()
# Programmtically invoke ORS logo
header_pic = QPixmap(os.path.join(self.script_dir, "openrouteservice.png"))
header_pic = QPixmap(os.path.join(self.script_dir, "../openrouteservice.png"))
self.pixmap = header_pic.scaled(150, 50,
aspectRatioMode=Qt.KeepAspectRatio,
transformMode=Qt.SmoothTransformation
@@ -86,41 +87,41 @@ class OSMtoolsDialog(QDialog, FORM_CLASS):
self.header_pic.setPixmap(self.pixmap)
self.header_text.setAlignment(Qt.AlignHCenter)
self.header_subpic.setAlignment(Qt.AlignHCenter)
# Set fonts for few widgets, which dialog.ui somehow messes up
self.tabWidget.setFont(QFont("Sans Serif", 10))
# self.groupBox_2.setFont(QFont("Sans Serif", 9))
# Read API key file
self.api_key_dlg.setText(auxiliary.readConfig()['api_key'])
self.api_key = self.api_key_dlg.text()
self.project = QgsProject.instance()
self.route_mode_combo.addItems(profiles)
self.access_mode_combo.addItems(profiles)
self.matrix_mode_combo.addItems(profiles)
# self.matrix_metric_combo.addItems(metrics)
self.route_pref_combo.addItems(preferences)
self.access_unit_combo.addItems(units)
#### Set up signals/slots ####
# API key text line
self.api_key_dlg.textChanged.connect(self._keyWriter)
# Matrix tab
self.matrix_start_combo.currentIndexChanged.connect(self._layerSeletedChanged)
self.matrix_end_combo.currentIndexChanged.connect(self._layerSeletedChanged)
self.matrix_start_refresh.clicked.connect(self._layerTreeChanged)
self.matrix_end_refresh.clicked.connect(self._layerTreeChanged)
# Isochrone tab
self.access_map_button.clicked.connect(self._initMapTool)
self.access_unit_combo.currentIndexChanged.connect(self._unitChanged)
self.access_layer_check.stateChanged.connect(self._accessLayerChanged)
self.access_layer_refresh.clicked.connect(self._layerTreeChanged)
self.access_layer_refresh.clicked.connect(self._layerTreeChanged)
# Routing tab
self.start_map_button.clicked.connect(self._initMapTool)
self.via_map_button.clicked.connect(self._initMapTool)
@@ -129,39 +130,39 @@ class OSMtoolsDialog(QDialog, FORM_CLASS):
self.end_buttongroup.buttonReleased[int].connect(self._mappingMethodChanged)
self.via_clear_button.clicked.connect(self._clearVia)
self.mapInstance.layerWasAdded.connect(self._layerTreeChanged)
self.mapInstance.layersRemoved.connect(self._layerTreeChanged)
self.start_layer_refresh.clicked.connect(self._layerTreeChanged)
self.end_layer_refresh.clicked.connect(self._layerTreeChanged)
self.mapInstance.layersRemoved.connect(self._layerTreeChanged)
self.start_layer_refresh.clicked.connect(self._layerTreeChanged)
self.end_layer_refresh.clicked.connect(self._layerTreeChanged)
self.start_layer_combo.currentIndexChanged[int].connect(self._layerSeletedChanged)
self.end_layer_combo.currentIndexChanged[int].connect(self._layerSeletedChanged)

def _accessLayerChanged(self):
for child in self.sender().parentWidget().children():
for child in self.sender().parentWidget().children():
if not child.objectName() == self.sender().objectName():
child.setEnabled(self.sender().isChecked())
def _layerTreeChanged(self):
"""
Re-populate layers for dropdowns dynamically when layers were
Re-populate layers for dropdowns dynamically when layers were
added/removed.
"""
# First get all point layers in map canvas
layer_names = []
root = self.project.layerTreeRoot()
for child in root.children():
if isinstance(child, QgsLayerTreeLayer):
layer = child.layer()
# Handle weird project startup behaviour of QGIS (apparently
# Handle weird project startup behaviour of QGIS (apparently
# doesn't find layers on project startup and throws AttributeError)
try:
if layer.type() == QgsMapLayer.VectorLayer and layer.wkbType() == QGis.WKBPoint:
layer_names.append(layer.name())
except AttributeError:
continue
comboboxes = [self.start_layer_combo,
self.end_layer_combo,
self.access_layer_combo,
@@ -175,67 +176,67 @@ class OSMtoolsDialog(QDialog, FORM_CLASS):
box.addItem(layer)
new_text_id = box.findText(old_text)
box.setCurrentIndex(new_text_id)
def _mappingMethodChanged(self, index):
""" Generic method to enable/disable all comboboxes and buttons in the
children of the parent widget of the calling radio button.
children of the parent widget of the calling radio button.
:param index: Index of the calling radio button within the QButtonGroup.
:type index: int
"""
parent_widget = self.sender().button(index).parentWidget()
parent_widget_name = parent_widget.objectName()
grandparent_widget = parent_widget.parentWidget()
for parent in grandparent_widget.children():
if parent.objectName() == parent_widget_name:
for child in parent.findChildren((QComboBox, QPushButton)):
child.setEnabled(True)
else:
else:
for child in parent.findChildren((QComboBox, QPushButton)):
child.setEnabled(False)
condition = self.end_layer_radio.isChecked() and self.start_layer_radio.isChecked()
self.row_by_row.setEnabled(condition)
self.many_by_many.setEnabled(condition)
def _layerSeletedChanged(self, index):
"""
Populates dropdowns with QgsProject layers.
:param index: Index of previously selected layer in dropdown. -1 if no
layer was selected.
:type index: int
"""
if index != -1:
sending_widget = self.sender()
sending_widget_name = sending_widget.objectName()
parent_widget = self.sender().parentWidget()
layer_selected = [lyr for lyr in self.mapInstance.mapLayers().values() if lyr.name() == sending_widget.currentText()][0]
for widget in parent_widget.findChildren(QComboBox):
if widget.objectName() != sending_widget_name:
if widget.objectName() != sending_widget_name:
widget.clear()
widget.addItems([field.name() for field in layer_selected.fields()])
def _clearVia(self):
"""
Clears the 'via' coordinates label.
"""
self.via_label.setText("Long,Lat")
def _keyWriter(self):
"""
Writes key to text file when api key text field changes.
"""
auxiliary.writeConfig('api_key',
self.api_key_dlg.text())
def _unitChanged(self):
"""
Connector to change unit label text when changing unit
@@ -250,42 +251,42 @@ class OSMtoolsDialog(QDialog, FORM_CLASS):
"""
Initialize the mapTool to select coordinates in map canvas.
"""
self.setWindowState(Qt.WindowMinimized)
sending_button = self.sender().objectName()
self.mapTool = pointtool.PointTool(self.iface.mapCanvas(), sending_button)
self.iface.mapCanvas().setMapTool(self.mapTool)
self.mapTool.canvasClicked.connect(self._writeCoordinateLabel)
# Write map coordinates to text fields
def _writeCoordinateLabel(self, point, button):
"""
Writes the selected coordinates from map canvas to its accompanying label.
:param point: Point selected with mapTool.
:type point: QgsPointXY
:param button: Button name which intialized mapTool.
:param button: str
"""
x, y = point
if button == self.start_map_button.objectName():
self.start_map_label.setText("{0:.5f},{1:.5f}".format(x, y))
if button == self.end_map_button.objectName():
self.end_map_label.setText("{0:.5f},{1:.5f}".format(x, y))
if button == self.via_map_button.objectName():
self.via_label.setText("{0:.5f},{1:.5f}".format(x, y))
if button == self.access_map_button.objectName():
clt = client.Client(self.iface)
loc_dict = geocode.reverse_geocode(clt,
point)
out_str = u"{0:.6f}\n{1:.6f}\n{2}\n{3}\n{4}".format(loc_dict.get('Lon', ""),
loc_dict.get('Lat', ""),
loc_dict.get('CITY', "NA"),
@@ -293,9 +294,8 @@ class OSMtoolsDialog(QDialog, FORM_CLASS):
loc_dict.get('COUNTRY', "NA")
)
self.access_map_label.setText(out_str)
# Restore normal behavior
self.showNormal()
QApplication.restoreOverrideCursor()
self.mapTool.canvasClicked.disconnect()

directions.py → gui/directions.py Прегледај датотеку

@@ -16,14 +16,14 @@ from PyQt4.QtGui import (QComboBox,
from PyQt4.QtCore import QVariant

from qgis.core import (QgsVectorLayer,
QgsField,
QgsField,
QgsPoint,
QgsGeometry,
QgsFeature,
QgsMapLayerRegistry
)

from OSMtools import convert, geocode, auxiliary
from OSMtools.core import convert, geocode, auxiliary

class directions:
"""
@@ -33,35 +33,35 @@ class directions:
"""
:param dlg: Main OSMtools dialog window.
:type dlg: QDialog
:param client: Client to ORS API.
:type client: OSMtools.client.Client()
:param iface: A QGIS interface instance.
:type iface: QgisInterface
"""
self.dlg = dlg
self.client = client
self.iface = iface
self.url = '/directions'
self.url = '/directions'
self.radio_buttons = (self.dlg.start_layer_radio,
self.dlg.end_layer_radio)
# API parameters
self.route_mode = self.dlg.route_mode_combo.currentText()
self.route_pref = self.dlg.route_pref_combo.currentText()
avoid_boxes = self.dlg.avoid_frame.findChildren(QCheckBox)
self.params = {'profile': self.route_mode,
'preference': self.route_pref,
'geometry': 'true',
'geometry_format': 'geojson',
'instructions': 'false'
}
# Check if avoid features is checked
self.avoid_dict = dict()
if any(box.isChecked() for box in avoid_boxes):
@@ -71,44 +71,44 @@ class directions:
avoid_features.append((box.text()))
avoid_features = convert._pipe_list(avoid_features)
self.avoid_dict = dict()
self.avoid_dict['avoid_features'] = avoid_features
if self.avoid_dict:
self.params['options'] = str(self.avoid_dict)
def directions_calc(self):
"""
Main method to perform the actual request
"""
# create route_dict, {'radio_button_name': {'geometries': list of coords,
# 'values': list of values}}
route_dict = self._selectInput()
# generate lists with locations and values
# generate lists with locations and values
(start_layer_name,
end_layer_name) = [x.objectName() for x in self.radio_buttons]
locations_list = list(product(route_dict[start_layer_name]['geometries'],
route_dict[end_layer_name]['geometries']))
values_list = list(product(route_dict[start_layer_name]['values'],
route_dict[end_layer_name]['values']))
# If row-by-row in two-layer mode, then only zip the locations
if all([button.isChecked() for button in self.radio_buttons]) and self.dlg.row_by_row.isChecked():
locations_list = list(zip(route_dict[start_layer_name]['geometries'],
route_dict[end_layer_name]['geometries']))
values_list = list(zip(route_dict[start_layer_name]['values'],
route_dict[end_layer_name]['values']))
route_via = None
if self.dlg.via_label.text() != 'Long,Lat':
route_via = [float(x) for x in self.dlg.via_label.text().split(",")]
message_bar, progress_widget = auxiliary.pushProgressBar(self.iface)
responses = []
delete_values = []
for i, coords_tuple in enumerate(locations_list):
@@ -120,39 +120,39 @@ class directions:
# add via coords
coords_tuple = list(coords_tuple)
coords_tuple.insert(1, route_via)
# Update progress bar
percent = (i/float(len(locations_list))) * 100
message_bar.setValue(percent)
# Make the request
self.params['coordinates'] = convert._build_coords(coords_tuple)
responses.append(self.client.request(self.url, self.params))
# Delete entries in values_list where coords where the same
values_list = [value for idx, value in enumerate(values_list) if idx not in delete_values]
# Only proceed when there actual responses
if responses:
if responses:
layer_out = self._addLine(responses, values_list)
layer_out.updateExtents()
QgsMapLayerRegistry.instance().addMapLayer(layer_out)
self.iface.messageBar().popWidget(progress_widget)
def _addLine(self, responses, values_list):
"""
:param responses: Collection of HTTP responses.
:type responses: list
:param values_list: List of feature ID's.
:type values_list: list
:rtype: QgsMapLayer
"""
# Create memory routing layer with fields
layer_out = QgsVectorLayer("LineString?crs=EPSG:4326", "Route_ORS", "memory")
layer_out_prov = layer_out.dataProvider()
@@ -163,10 +163,10 @@ class directions:
layer_out_prov.addAttributes([QgsField("AVOID_TYPE", QVariant.String)])
layer_out_prov.addAttributes([QgsField("FROM_ID", QVariant.String)])
layer_out_prov.addAttributes([QgsField("TO_ID", QVariant.String)])
layer_out.updateFields()
for i, response in enumerate(responses):
resp_minified = response['routes'][0]
feat = QgsFeature()
@@ -184,13 +184,13 @@ class directions:
values_list[i][1]
])
layer_out.dataProvider().addFeatures([feat])
return layer_out
def _selectInput(self):
"""
Selects start and end features and returns them as a dict.
:rtype: dict, {'radio_button_name': {'geometries': list of coords,
'values': list of values}, 'other_radio_button':...}
"""
@@ -199,45 +199,45 @@ class directions:
if radio_button.isChecked():
# Find layer combo box
all_combos = radio_button.parent().findChildren(QComboBox)
layer_combo = [combo for combo in all_combos if combo.objectName().endswith('layer_combo')][0]
# Get selected layer
layer_combo = [combo for combo in all_combos if combo.objectName().endswith('layer_combo')][0]
# Get selected layer
layer_name = layer_combo.currentText()
layer = [layer for layer in self.iface.mapCanvas().layers() if layer.name() == layer_name][0]
# Check CRS and transform if necessary
auxiliary.checkCRS(layer,
self.iface.messageBar())
# If features are selected, calculate with those
if layer.selectedFeatureCount() == 0:
feats = layer.getFeatures()
else:
feats = layer.selectedFeatures()
# Get features
point_geom = [feat.geometry().asPoint() for feat in feats]
# Find field combo box
field_combo = [combo for combo in all_combos if combo.objectName().endswith('layer_id')][0]
field_combo = [combo for combo in all_combos if combo.objectName().endswith('layer_id')][0]
field_id = layer.fields().indexFromName(field_combo.currentText())
field_values = [feat[field_id] for feat in feats]
else:
parent_widget = radio_button.parentWidget()
parent_widget_name = parent_widget.objectName()
grandparent_widget = parent_widget.parentWidget()
parent_widget_label = [child for child in grandparent_widget.children() if child.objectName() != parent_widget_name][1]
point_label = parent_widget_label.findChild(QLabel)
point_coords = [float(x) for x in point_label.text().split(",")]
point_geom = [QgsPoint(*point_coords)]
response_dict = geocode.reverse_geocode(self.client, *point_geom)
field_values = [response_dict.get('CITY', point_label.text())]
# Get all id attributes from field
route_dict[radio_button.objectName()] = {'geometries': point_geom,
'values': field_values}
return route_dict
return route_dict

isochrones.py → gui/isochrones.py Прегледај датотеку

@@ -19,10 +19,10 @@ from qgis.core import (QgsPoint,
QgsRendererCategoryV2,
QgsCategorizedSymbolRendererV2)

from OSMtools import (geocode,
convert,
auxiliary
)
from OSMtools.core import (geocode,
convert,
auxiliary
)

class isochrones:
"""

matrix.py → gui/matrix.py Прегледај датотеку

@@ -19,7 +19,7 @@ from qgis.core import (QgsVectorLayer,
QgsMapLayerRegistry
)

from OSMtools import auxiliary
from OSMtools.core import auxiliary


class matrix:
@@ -30,10 +30,10 @@ class matrix:
"""
:param dlg: Main OSMtools dialog window.
:type dlg: QDialog
:param client: Client to ORS API.
:type client: OSMtools.client.Client()
:param iface: A QGIS interface instance.
:type iface: QgisInterface
"""
@@ -41,42 +41,42 @@ class matrix:
self.client = client
self.iface = iface
self.plugin_dir = os.path.dirname(__file__)
self.url = '/matrix'
self.url = '/matrix'
self.combo_boxes = (self.dlg.matrix_start_combo, self.dlg.matrix_end_combo)
# API parameters
self.matrix_mode = self.dlg.matrix_mode_combo.currentText()
# self.matrix_metrics = self.dlg.matrix_metric_combo.currentText()
self.params = {'profile': self.dlg.matrix_mode_combo.currentText(),
'metrics': 'distance|duration'
}
def matrix_calc(self):
"""
Main method to perform the actual request
"""
# create route_dict, {'combobox_name': {'geometries': list of coords,
# 'values': list of values}}
route_dict = self._selectInput()
start_box_name = self.combo_boxes[0].objectName()
end_box_name = self.combo_boxes[1].objectName()
# generate lists with locations and values
# generate lists with locations and values
locations_list = route_dict[start_box_name]['geometries'] + \
route_dict[end_box_name]['geometries']
values_list = route_dict[start_box_name]['values'] + \
route_dict[end_box_name]['values']
ids = list(range(len(locations_list)))
destinations_amount = len(route_dict[end_box_name]['geometries'])
sources = ids[:destinations_amount]
destinations = ids[destinations_amount:]
destinations = ids[destinations_amount:]
values_list = list(product(values_list[:destinations_amount],
values_list[destinations_amount:]))

@@ -85,35 +85,35 @@ class matrix:
self.params['sources'] = sources
self.params['destinations'] = destinations
response = self.client.request(self.url, {}, post_json=self.params)
durations = [item for sublist in response['durations'] for item in sublist]
distances = [item for sublist in response['distances'] for item in sublist]
layer_out = QgsVectorLayer('None', "Matrix_ORS", "memory")
layer_out_prov = layer_out.dataProvider()
layer_out_prov.addAttributes([QgsField("FROM_ID", QVariant.String)])
layer_out_prov.addAttributes([QgsField("TO_ID", QVariant.String)])
layer_out_prov.addAttributes([QgsField("DURATION_HOURS", QVariant.String)])
layer_out_prov.addAttributes([QgsField("DISTANCE_KM", QVariant.String)])
for row in range(len(values_list)):
for row in range(len(values_list)):
feat = QgsFeature()
feat.setAttributes([values_list[row][0],
values_list[row][1],
durations[row]/3600,
distances[row]/1000])
layer_out_prov.addFeatures([feat])
layer_out.updateFields()
QgsMapLayerRegistry.instance().addMapLayer(layer_out)
def _selectInput(self):
"""
Selects start and end features and returns them as a dict.
ues_list)):
ues_list)):
# feat = QgsFeature()
# feat.setAttributes([values_list[row][0],
# values_list[row][1],
@@ -124,34 +124,33 @@ class matrix:
'values': list of values}, 'other_radio_button':...}
"""
route_dict = dict()
for combo in self.combo_boxes:
# Get selected layer
for combo in self.combo_boxes:
# Get selected layer
layer_name = combo.currentText()
layer = [layer for layer in QgsMapLayerRegistry.instance().mapLayers().values() if layer.name() == layer_name][0]
# Check CRS and transform if necessary
auxiliary.checkCRS(layer,
self.iface.messageBar())
# If features are selected, calculate with those
if layer.selectedFeatureCount() == 0:
feats = layer.getFeatures()
else:
feats = layer.selectedFeatures()
# Get features
point_geom = [list(feat.geometry().asPoint()) for feat in feats]
# Find field combo box
all_combos = combo.parent().findChildren(QComboBox)
field_combo = [box for box in all_combos if box.objectName().endswith('_id')][0]
field_combo = [box for box in all_combos if box.objectName().endswith('_id')][0]
field_id = layer.fields().indexFromName(field_combo.currentText())
field_values = [feat[field_id] for feat in feats]
# Get all id attributes from field
route_dict[combo.objectName()] = {'geometries': point_geom,
'values': field_values}
return route_dict


osm_tools_dialog_base.ui → gui/osm_tools_dialog_base.ui Прегледај датотеку


pointtool.py → gui/pointtool.py Прегледај датотеку

@@ -19,39 +19,39 @@ def resolve(name, basepath=None):
if not basepath:
basepath = os.path.dirname(os.path.realpath(__file__))
return os.path.join(basepath, name)
class PointTool(QgsMapTool):
class PointTool(QgsMapTool):
def __init__(self, canvas, button):
QgsMapTool.__init__(self, canvas)
self.canvas = canvas
self.canvas = canvas
self.button = button
self.imgdir = resolve('icon_locate.png')
self.imgdir = resolve('../icon_locate.png')
self.cursor = QCursor(QPixmap(self.imgdir).scaledToWidth(24), 12, 12)
#QApplication.setOverrideCursor(QCursor(QPixmap('/icon_locate.png')))
#QApplication.setOverrideCursor(QCursor(QPixmap('../icon_locate.png')))
canvasClicked = pyqtSignal(['QgsPoint', 'QString', 'Qt::MouseButton'])
def canvasReleaseEvent(self, event):
#Get the click and emit a transformed point
# mapSettings() was only introduced in QGIS 2.4, keep compatibility
try:
crsSrc = self.canvas.mapSettings().destinationCrs()
except:
crsSrc = self.canvas.mapRenderer().destinationCrs()
crsWGS = QgsCoordinateReferenceSystem(4326)
point_oldcrs = self.toMapCoordinates(event.pos())
xform = QgsCoordinateTransform(crsSrc, crsWGS)
point_newcrs = xform.transform(point_oldcrs)
QApplication.restoreOverrideCursor()
self.canvasClicked.emit(point_newcrs, self.button, event.button())
def activate(self):
QApplication.setOverrideCursor(self.cursor)
@@ -62,4 +62,4 @@ class PointTool(QgsMapTool):
return False
def isEditTool(self):
return True
return True

resources.py → gui/resources.py Прегледај датотеку


resources.qrc → gui/resources.qrc Прегледај датотеку


resources_rc.py → gui/resources_rc.py Прегледај датотеку


+ 3
- 2
osm_tools.py Прегледај датотеку

@@ -33,8 +33,9 @@ from PyQt4.Qt import PYQT_VERSION_STR
from PyQt4.QtGui import QIcon, QAction, QApplication
from processing.core.Processing import Processing

from OSMtools.dialog import OSMtoolsDialog
from OSMtools import isochrones, client, directions, exceptions, matrix
from OSMtools.core import client, exceptions
from OSMtools.gui import isochrones, directions, matrix
from OSMtools.gui.dialog import OSMtoolsDialog
from OSMtools.osmtools_processing.provider import OSMtoolsAlgoProvider

import logging

+ 2
- 2
osmtools_processing/isochrones.py Прегледај датотеку

@@ -38,8 +38,8 @@ from processing.core.parameters import ParameterVector, ParameterString, Paramet
from processing.core.outputs import OutputVector
from processing.tools.dataobjects import getObjectFromUri

from OSMtools.exceptions import InvalidParameterException
from OSMtools.convert import _comma_list
from OSMtools.core.exceptions import InvalidParameterException
from OSMtools.core.convert import _comma_list

class IsochronesGeoAlg(GeoAlgorithm):
"""

Loading…
Откажи
Сачувај