Copy the command displayed below and paste it into the terminal, then hit Enter and confirm installation with 'yes' when prompted
"), self.tr("pip install matplotlib"),False,False))
65 |
66 | def processAlgorithm(self, parameters, context, feedback):
67 | output_message = self.parameterAsString(parameters, self.MESSAGE1, context)
68 | feedback.pushInfo("You need to install matplotlib to enable this algorithm.")
69 |
70 | results = {}
71 | results[self.MESSAGE1] = 'Refer to the help provided in the algorithm.'
72 | return results
73 |
74 |
--------------------------------------------------------------------------------
/algs/IsoAreaAsContoursFromLayer.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | ***************************************************************************
4 | IsoAreaAsContourFromLayer.py
5 | ---------------------
6 |
7 | Partially based on QGIS3 network analysis algorithms.
8 | Copyright 2016 Alexander Bruy
9 |
10 | Date : February 2018
11 | Copyright : (C) 2018 by Clemens Raffler
12 | Email : clemens dot raffler at gmail dot com
13 | ***************************************************************************
14 | * *
15 | * This program is free software; you can redistribute it and/or modify *
16 | * it under the terms of the GNU General Public License as published by *
17 | * the Free Software Foundation; either version 2 of the License, or *
18 | * (at your option) any later version. *
19 | * *
20 | ***************************************************************************
21 | """
22 |
23 | __author__ = 'Clemens Raffler'
24 | __date__ = 'February 2018'
25 | __copyright__ = '(C) 2018, Clemens Raffler'
26 |
27 | # This will get replaced with a git SHA1 when you do a git archive
28 |
29 | __revision__ = '$Format:%H$'
30 |
31 | import os
32 | from collections import OrderedDict
33 |
34 | from qgis.PyQt.QtCore import QVariant
35 | from qgis.PyQt.QtGui import QIcon
36 |
37 | from qgis.core import (QgsWkbTypes,
38 | QgsVectorLayer,
39 | QgsFeatureSink,
40 | QgsFields,
41 | QgsField,
42 | QgsProcessing,
43 | QgsProcessingParameterEnum,
44 | QgsProcessingParameterField,
45 | QgsProcessingParameterNumber,
46 | QgsProcessingParameterRasterDestination,
47 | QgsProcessingParameterString,
48 | QgsProcessingParameterFeatureSource,
49 | QgsProcessingParameterFeatureSink,
50 | QgsProcessingParameterDefinition)
51 |
52 | from qgis.analysis import QgsVectorLayerDirector
53 |
54 | from QNEAT3.Qneat3Framework import Qneat3Network, Qneat3AnalysisPoint
55 | from QNEAT3.Qneat3Utilities import getListOfPoints, getFeaturesFromQgsIterable
56 |
57 | from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
58 |
59 | pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
60 |
61 |
62 | class IsoAreaAsContoursFromLayer(QgisAlgorithm):
63 |
64 | INPUT = 'INPUT'
65 | START_POINTS = 'START_POINTS'
66 | ID_FIELD = 'ID_FIELD'
67 | MAX_DIST = "MAX_DIST"
68 | CELL_SIZE = "CELL_SIZE"
69 | INTERVAL = "INTERVAL"
70 | STRATEGY = 'STRATEGY'
71 | ENTRY_COST_CALCULATION_METHOD = 'ENTRY_COST_CALCULATION_METHOD'
72 | DIRECTION_FIELD = 'DIRECTION_FIELD'
73 | VALUE_FORWARD = 'VALUE_FORWARD'
74 | VALUE_BACKWARD = 'VALUE_BACKWARD'
75 | VALUE_BOTH = 'VALUE_BOTH'
76 | DEFAULT_DIRECTION = 'DEFAULT_DIRECTION'
77 | SPEED_FIELD = 'SPEED_FIELD'
78 | DEFAULT_SPEED = 'DEFAULT_SPEED'
79 | TOLERANCE = 'TOLERANCE'
80 | OUTPUT_INTERPOLATION = 'OUTPUT_INTERPOLATION'
81 | OUTPUT_CONTOURS = 'OUTPUT_CONTOURS'
82 |
83 | def icon(self):
84 | return QIcon(os.path.join(pluginPath, 'QNEAT3', 'icons', 'icon_servicearea_contour_multiple.svg'))
85 |
86 | def group(self):
87 | return self.tr('Iso-Areas')
88 |
89 | def groupId(self):
90 | return 'isoareas'
91 |
92 | def name(self):
93 | return 'isoareaascontoursfromlayer'
94 |
95 | def displayName(self):
96 | return self.tr('Iso-Area as Contours (from Layer)')
97 |
98 | def shortHelpString(self):
99 | return "General: "\
100 | "This algorithm implements iso-area contours to return the isochrone areas for a maximum cost level and interval levels on a given network dataset for a layer of points. "\
101 | "It accounts for points outside of the network (eg. non-network-elements) and increments the iso-areas cost regarding to distance/default speed value. Distances are measured accounting for ellipsoids. Please, only use a projected coordinate system (eg. no WGS84) for this kind of analysis.
"\
102 | "Parameters (required): "\
103 | "Following Parameters must be set to run the algorithm:"\
104 | "
Network Layer
Startpoint Layer
Unique Point ID Field (numerical)
Maximum cost level for Iso-Area
Cost Intervals for Iso-Area Bands
Cellsize in Meters (increase default when analyzing larger networks)
Cost Strategy
"\
105 | "Parameters (optional): "\
106 | "There are also a number of optional parameters to implement direction dependent shortest paths and provide information on speeds on the networks edges."\
107 | "
Direction Field
Value for forward direction
Value for backward direction
Value for both directions
Default direction
Speed Field
Default Speed (affects entry/exit costs)
Topology tolerance
"\
108 | "Output: "\
109 | "The output of the algorithm are two layers:"\
110 | "
"\
102 | "Parameters (required): "\
103 | "Following Parameters must be set to run the algorithm:"\
104 | "
Network Layer
Startpoint
Maximum cost level for Iso-Area
Cost Intervals for Iso-Area Bands
Cellsize in Meters (increase default when analyzing larger networks)
Cost Strategy
"\
105 | "Parameters (optional): "\
106 | "There are also a number of optional parameters to implement direction dependent shortest paths and provide information on speeds on the networks edges."\
107 | "
Direction Field
Value for forward direction
Value for backward direction
Value for both directions
Default direction
Speed Field
Default Speed (affects entry/exit costs)
Topology tolerance
"\
108 | "Output: "\
109 | "The output of the algorithm are two layers:"\
110 | "
"\
95 | "Parameters (required): "\
96 | "Following Parameters must be set to run the algorithm:"\
97 | "
Network Layer
Startpoint Layer
Unique Point ID Field (numerical)
Maximum cost level for Iso-Area
Cellsize in Meters (increase default when analyzing larger networks)
Cost Strategy
"\
98 | "Parameters (optional): "\
99 | "There are also a number of optional parameters to implement direction dependent shortest paths and provide information on speeds on the networks edges."\
100 | "
Direction Field
Value for forward direction
Value for backward direction
Value for both directions
Default direction
Speed Field
Default Speed (affects entry/exit costs)
Topology tolerance
"\
101 | "Output: "\
102 | "The output of the algorithm is one layer:"\
103 | "
"\
95 | "Parameters (required): "\
96 | "Following Parameters must be set to run the algorithm:"\
97 | "
Network Layer
Startpoint
Maximum cost level for Iso-Area
Cellsize in Meters (increase default when analyzing larger networks)
Cost Strategy
"\
98 | "Parameters (optional): "\
99 | "There are also a number of optional parameters to implement direction dependent shortest paths and provide information on speeds on the networks edges."\
100 | "
Direction Field
Value for forward direction
Value for backward direction
Value for both directions
Default direction
Speed Field
Default Speed (affects entry/exit costs)
Topology tolerance
"\
101 | "Output: "\
102 | "The output of the algorithm is one layer:"\
103 | "
"\
97 | "Parameters (required): "\
98 | "Following Parameters must be set to run the algorithm:"\
99 | "
Network Layer
Startpoint Layer
Unique Point ID Field (numerical)
Maximum cost level for Iso-Area
Cost Strategy
"\
100 | "Parameters (optional): "\
101 | "There are also a number of optional parameters to implement direction dependent shortest paths and provide information on speeds on the networks edges."\
102 | "
Direction Field
Value for forward direction
Value for backward direction
Value for both directions
Default direction
Speed Field
Default Speed (affects entry/exit costs)
Topology tolerance
"\
103 | "Output: "\
104 | "The output of the algorithm is one layer:"\
105 | "
Point layer of reachable network nodes
"\
106 | "You may use the output pointcloud as input for further analyses."
107 |
108 | def msg(self, var):
109 | return "Type:"+str(type(var))+" repr: "+var.__str__()
110 |
111 | def __init__(self):
112 | super().__init__()
113 |
114 | def initAlgorithm(self, config=None):
115 | self.DIRECTIONS = OrderedDict([
116 | (self.tr('Forward direction'), QgsVectorLayerDirector.DirectionForward),
117 | (self.tr('Backward direction'), QgsVectorLayerDirector.DirectionBackward),
118 | (self.tr('Both directions'), QgsVectorLayerDirector.DirectionBoth)])
119 |
120 | self.STRATEGIES = [self.tr('Shortest Path (distance optimization)'),
121 | self.tr('Fastest Path (time optimization)')
122 | ]
123 |
124 | self.ENTRY_COST_CALCULATION_METHODS = [self.tr('Ellipsoidal'),
125 | self.tr('Planar (only use with projected CRS)')]
126 |
127 | self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT,
128 | self.tr('Network Layer'),
129 | [QgsProcessing.TypeVectorLine]))
130 | self.addParameter(QgsProcessingParameterFeatureSource(self.START_POINTS,
131 | self.tr('Startpoint Layer'),
132 | [QgsProcessing.TypeVectorPoint]))
133 | self.addParameter(QgsProcessingParameterField(self.ID_FIELD,
134 | self.tr('Unique Point ID Field'),
135 | None,
136 | self.START_POINTS,
137 | optional=False))
138 | self.addParameter(QgsProcessingParameterNumber(self.MAX_DIST,
139 | self.tr('Size of Iso-Area (Distance or Seconds depending on Strategy)'),
140 | QgsProcessingParameterNumber.Double,
141 | 2500.0, False, 0, 99999999.99))
142 | self.addParameter(QgsProcessingParameterEnum(self.STRATEGY,
143 | self.tr('Optimization criterion'),
144 | self.STRATEGIES,
145 | defaultValue=0))
146 |
147 | params = []
148 | params.append(QgsProcessingParameterEnum(self.ENTRY_COST_CALCULATION_METHOD,
149 | self.tr('Entry Cost calculation method'),
150 | self.ENTRY_COST_CALCULATION_METHODS,
151 | defaultValue=0))
152 | params.append(QgsProcessingParameterField(self.DIRECTION_FIELD,
153 | self.tr('Direction field'),
154 | None,
155 | self.INPUT,
156 | optional=True))
157 | params.append(QgsProcessingParameterString(self.VALUE_FORWARD,
158 | self.tr('Value for forward direction'),
159 | optional=True))
160 | params.append(QgsProcessingParameterString(self.VALUE_BACKWARD,
161 | self.tr('Value for backward direction'),
162 | optional=True))
163 | params.append(QgsProcessingParameterString(self.VALUE_BOTH,
164 | self.tr('Value for both directions'),
165 | optional=True))
166 | params.append(QgsProcessingParameterEnum(self.DEFAULT_DIRECTION,
167 | self.tr('Default direction'),
168 | list(self.DIRECTIONS.keys()),
169 | defaultValue=2))
170 | params.append(QgsProcessingParameterField(self.SPEED_FIELD,
171 | self.tr('Speed field'),
172 | None,
173 | self.INPUT,
174 | optional=True))
175 | params.append(QgsProcessingParameterNumber(self.DEFAULT_SPEED,
176 | self.tr('Default speed (km/h)'),
177 | QgsProcessingParameterNumber.Double,
178 | 5.0, False, 0, 99999999.99))
179 | params.append(QgsProcessingParameterNumber(self.TOLERANCE,
180 | self.tr('Topology tolerance'),
181 | QgsProcessingParameterNumber.Double,
182 | 0.0, False, 0, 99999999.99))
183 |
184 | for p in params:
185 | p.setFlags(p.flags() | QgsProcessingParameterDefinition.FlagAdvanced)
186 | self.addParameter(p)
187 |
188 | self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT,
189 | self.tr('Output Pointcloud'),
190 | QgsProcessing.TypeVectorPoint))
191 |
192 | def processAlgorithm(self, parameters, context, feedback):
193 | feedback.pushInfo(self.tr("[QNEAT3Algorithm] This is a QNEAT3 Algorithm: '{}'".format(self.displayName())))
194 | network = self.parameterAsSource(parameters, self.INPUT, context) #QgsProcessingFeatureSource
195 | startPoints = self.parameterAsSource(parameters, self.START_POINTS, context) #QgsProcessingFeatureSource
196 | id_field = self.parameterAsString(parameters, self.ID_FIELD, context) #str
197 | max_dist = self.parameterAsDouble(parameters, self.MAX_DIST, context)#float
198 | strategy = self.parameterAsEnum(parameters, self.STRATEGY, context) #int
199 |
200 | entry_cost_calc_method = self.parameterAsEnum(parameters, self.ENTRY_COST_CALCULATION_METHOD, context) #int
201 | directionFieldName = self.parameterAsString(parameters, self.DIRECTION_FIELD, context) #str (empty if no field given)
202 | forwardValue = self.parameterAsString(parameters, self.VALUE_FORWARD, context) #str
203 | backwardValue = self.parameterAsString(parameters, self.VALUE_BACKWARD, context) #str
204 | bothValue = self.parameterAsString(parameters, self.VALUE_BOTH, context) #str
205 | defaultDirection = self.parameterAsEnum(parameters, self.DEFAULT_DIRECTION, context) #int
206 | speedFieldName = self.parameterAsString(parameters, self.SPEED_FIELD, context) #str
207 | defaultSpeed = self.parameterAsDouble(parameters, self.DEFAULT_SPEED, context) #float
208 | tolerance = self.parameterAsDouble(parameters, self.TOLERANCE, context) #float
209 |
210 | analysisCrs = network.sourceCrs()
211 | input_coordinates = getListOfPoints(startPoints)
212 |
213 | feedback.pushInfo("[QNEAT3Algorithm] Building Graph...")
214 | feedback.setProgress(10)
215 | net = Qneat3Network(network, input_coordinates, strategy, directionFieldName, forwardValue, backwardValue, bothValue, defaultDirection, analysisCrs, speedFieldName, defaultSpeed, tolerance, feedback)
216 | feedback.setProgress(40)
217 |
218 | list_apoints = [Qneat3AnalysisPoint("from", feature, id_field, net, net.list_tiedPoints[i], entry_cost_calc_method, feedback) for i, feature in enumerate(getFeaturesFromQgsIterable(startPoints))]
219 |
220 | fields = QgsFields()
221 | fields.append(QgsField('vertex_id', QVariant.Int, '', 254, 0))
222 | fields.append(QgsField('cost', QVariant.Double, '', 254, 7))
223 | fields.append(QgsField('origin_point_id', getFieldDatatype(startPoints, id_field)))
224 |
225 | (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, fields, QgsWkbTypes.Point, network.sourceCrs())
226 |
227 | feedback.pushInfo("[QNEAT3Algorithm] Calculating Iso-Pointcloud...")
228 | iso_pointcloud = net.calcIsoPoints(list_apoints, max_dist)
229 | feedback.setProgress(90)
230 |
231 | sink.addFeatures(iso_pointcloud, QgsFeatureSink.FastInsert)
232 |
233 | feedback.pushInfo("[QNEAT3Algorithm] Ending Algorithm")
234 | feedback.setProgress(100)
235 |
236 | results = {}
237 | results[self.OUTPUT] = dest_id
238 | return results
239 |
240 |
--------------------------------------------------------------------------------
/algs/IsoAreaAsPointcloudFromPoint.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | ***************************************************************************
4 | IsoAreaAsPointcloudFromPoint.py
5 | ---------------------
6 |
7 | Partially based on QGIS3 network analysis algorithms.
8 | Copyright 2016 Alexander Bruy
9 |
10 | Date : February 2018
11 | Copyright : (C) 2018 by Clemens Raffler
12 | Email : clemens dot raffler at gmail dot com
13 | ***************************************************************************
14 | * *
15 | * This program is free software; you can redistribute it and/or modify *
16 | * it under the terms of the GNU General Public License as published by *
17 | * the Free Software Foundation; either version 2 of the License, or *
18 | * (at your option) any later version. *
19 | * *
20 | ***************************************************************************
21 | """
22 |
23 | __author__ = 'Clemens Raffler'
24 | __date__ = 'February 2018'
25 | __copyright__ = '(C) 2018, Clemens Raffler'
26 |
27 | # This will get replaced with a git SHA1 when you do a git archive
28 |
29 | __revision__ = '$Format:%H$'
30 |
31 | import os
32 | from collections import OrderedDict
33 |
34 | from qgis.PyQt.QtCore import QVariant
35 | from qgis.PyQt.QtGui import QIcon
36 |
37 | from qgis.core import (QgsWkbTypes,
38 | QgsFeatureSink,
39 | QgsFields,
40 | QgsField,
41 | QgsProcessing,
42 | QgsProcessingParameterEnum,
43 | QgsProcessingParameterPoint,
44 | QgsProcessingParameterField,
45 | QgsProcessingParameterNumber,
46 | QgsProcessingParameterString,
47 | QgsProcessingParameterFeatureSource,
48 | QgsProcessingParameterFeatureSink,
49 | QgsProcessingParameterDefinition)
50 |
51 | from qgis.analysis import QgsVectorLayerDirector
52 |
53 | from QNEAT3.Qneat3Framework import Qneat3Network, Qneat3AnalysisPoint
54 | from QNEAT3.Qneat3Utilities import getFeatureFromPointParameter
55 |
56 | from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
57 |
58 | pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
59 |
60 |
61 | class IsoAreaAsPointcloudFromPoint(QgisAlgorithm):
62 |
63 | INPUT = 'INPUT'
64 | START_POINT = 'START_POINT'
65 | MAX_DIST = "MAX_DIST"
66 | STRATEGY = 'STRATEGY'
67 | ENTRY_COST_CALCULATION_METHOD = 'ENTRY_COST_CALCULATION_METHOD'
68 | DIRECTION_FIELD = 'DIRECTION_FIELD'
69 | VALUE_FORWARD = 'VALUE_FORWARD'
70 | VALUE_BACKWARD = 'VALUE_BACKWARD'
71 | VALUE_BOTH = 'VALUE_BOTH'
72 | DEFAULT_DIRECTION = 'DEFAULT_DIRECTION'
73 | SPEED_FIELD = 'SPEED_FIELD'
74 | DEFAULT_SPEED = 'DEFAULT_SPEED'
75 | TOLERANCE = 'TOLERANCE'
76 | OUTPUT = 'OUTPUT'
77 |
78 | def icon(self):
79 | return QIcon(os.path.join(pluginPath, 'QNEAT3', 'icons', 'icon_servicearea_points.svg'))
80 |
81 | def group(self):
82 | return self.tr('Iso-Areas')
83 |
84 | def groupId(self):
85 | return 'isoareas'
86 |
87 | def name(self):
88 | return 'isoareaaspointcloudfrompoint'
89 |
90 | def displayName(self):
91 | return self.tr('Iso-Area as Pointcloud (from Point)')
92 |
93 | def shortHelpString(self):
94 | return "General: "\
95 | "This algorithm implements iso-pointcloud analysis to return all network nodes reachable within a maximum cost level as pointcloud on a given network dataset for a manually chosen point. "\
96 | "It accounts for points outside of the network (eg. non-network-elements) and increments the iso-areas cost regarding to distance/default speed value. Distances are measured accounting for ellipsoids. Please, only use a projected coordinate system (eg. no WGS84) for this kind of analysis.
"\
97 | "Parameters (required): "\
98 | "Following Parameters must be set to run the algorithm:"\
99 | "
Network Layer
Startpoint
Unique Point ID Field (numerical)
Maximum cost level for Iso-Area
Cost Strategy
"\
100 | "Parameters (optional): "\
101 | "There are also a number of optional parameters to implement direction dependent shortest paths and provide information on speeds on the networks edges."\
102 | "
Direction Field
Value for forward direction
Value for backward direction
Value for both directions
Default direction
Speed Field
Default Speed (affects entry/exit costs)
Topology tolerance
"\
103 | "Output: "\
104 | "The output of the algorithm is one layer:"\
105 | "
"\
96 | "Parameters (required): "\
97 | "Following Parameters must be set to run the algorithm:"\
98 | "
Network Layer
Startpoint
Maximum cost level for Iso-Area
Cost Intervals for Iso-Area Bands
Cellsize in Meters (increase default when analyzing larger networks)
Cost Strategy
"\
99 | "Parameters (optional): "\
100 | "There are also a number of optional parameters to implement direction dependent shortest paths and provide information on speeds on the networks edges."\
101 | "
Direction Field
Value for forward direction
Value for backward direction
Value for both directions
Default direction
Speed Field
Default Speed (affects entry/exit costs)
Topology tolerance
"\
102 | "Output: "\
103 | "The output of the algorithm are two layers:"\
104 | "
"\
92 | "Parameters (required): "\
93 | "Following Parameters must be set to run the algorithm:"\
94 | "
Network Layer
Point Layer
Unique Point ID Field (numerical)
Cost Strategy
"\
95 | "Parameters (optional): "\
96 | "There are also a number of optional parameters to implement direction dependent shortest paths and provide information on speeds on the networks edges."\
97 | "
Direction Field
Value for forward direction
Value for backward direction
Value for both directions
Default direction
Speed Field
Default Speed (affects entry/exit costs)
Topology tolerance
"\
98 | "Output: "\
99 | "The output of the algorithm is one file:"\
100 | "
OD-Matrix as csv-file with network based distances as attributes
"
101 |
102 | def print_typestring(self, var):
103 | return "Type:"+str(type(var))+" repr: "+var.__str__()
104 |
105 | def __init__(self):
106 | super().__init__()
107 |
108 | def initAlgorithm(self, config=None):
109 | self.DIRECTIONS = OrderedDict([
110 | (self.tr('Forward direction'), QgsVectorLayerDirector.DirectionForward),
111 | (self.tr('Backward direction'), QgsVectorLayerDirector.DirectionBackward),
112 | (self.tr('Both directions'), QgsVectorLayerDirector.DirectionBoth)])
113 |
114 | self.STRATEGIES = [self.tr('Shortest Path (distance optimization)'),
115 | self.tr('Fastest Path (time optimization)')
116 | ]
117 |
118 | self.ENTRY_COST_CALCULATION_METHODS = [self.tr('Ellipsoidal'),
119 | self.tr('Planar (only use with projected CRS)')]
120 |
121 |
122 | self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT,
123 | self.tr('Network Layer'),
124 | [QgsProcessing.TypeVectorLine]))
125 | self.addParameter(QgsProcessingParameterFeatureSource(self.POINTS,
126 | self.tr('Point Layer'),
127 | [QgsProcessing.TypeVectorPoint]))
128 | self.addParameter(QgsProcessingParameterField(self.ID_FIELD,
129 | self.tr('Unique Point ID Field'),
130 | None,
131 | self.POINTS,
132 | optional=False))
133 | self.addParameter(QgsProcessingParameterEnum(self.STRATEGY,
134 | self.tr('Optimization Criterion'),
135 | self.STRATEGIES,
136 | defaultValue=0))
137 |
138 | params = []
139 | params.append(QgsProcessingParameterEnum(self.ENTRY_COST_CALCULATION_METHOD,
140 | self.tr('Entry Cost calculation method'),
141 | self.ENTRY_COST_CALCULATION_METHODS,
142 | defaultValue=0))
143 | params.append(QgsProcessingParameterField(self.DIRECTION_FIELD,
144 | self.tr('Direction field'),
145 | None,
146 | self.INPUT,
147 | optional=True))
148 | params.append(QgsProcessingParameterString(self.VALUE_FORWARD,
149 | self.tr('Value for forward direction'),
150 | optional=True))
151 | params.append(QgsProcessingParameterString(self.VALUE_BACKWARD,
152 | self.tr('Value for backward direction'),
153 | optional=True))
154 | params.append(QgsProcessingParameterString(self.VALUE_BOTH,
155 | self.tr('Value for both directions'),
156 | optional=True))
157 | params.append(QgsProcessingParameterEnum(self.DEFAULT_DIRECTION,
158 | self.tr('Default direction'),
159 | list(self.DIRECTIONS.keys()),
160 | defaultValue=2))
161 | params.append(QgsProcessingParameterField(self.SPEED_FIELD,
162 | self.tr('Speed field'),
163 | None,
164 | self.INPUT,
165 | optional=True))
166 | params.append(QgsProcessingParameterNumber(self.DEFAULT_SPEED,
167 | self.tr('Default speed (km/h)'),
168 | QgsProcessingParameterNumber.Double,
169 | 5.0, False, 0, 99999999.99))
170 | params.append(QgsProcessingParameterNumber(self.TOLERANCE,
171 | self.tr('Topology tolerance'),
172 | QgsProcessingParameterNumber.Double,
173 | 0.0, False, 0, 99999999.99))
174 |
175 | for p in params:
176 | p.setFlags(p.flags() | QgsProcessingParameterDefinition.FlagAdvanced)
177 | self.addParameter(p)
178 |
179 | self.addParameter(QgsProcessingParameterFileDestination(self.OUTPUT, self.tr('Output OD Matrix'), self.tr('CSV files (*.csv)')),True)
180 |
181 | def processAlgorithm(self, parameters, context, feedback):
182 | feedback.pushInfo(self.tr("[QNEAT3Algorithm] This is a QNEAT3 Algorithm: '{}'".format(self.displayName())))
183 | network = self.parameterAsSource(parameters, self.INPUT, context) #QgsProcessingFeatureSource
184 | points = self.parameterAsSource(parameters, self.POINTS, context) #QgsProcessingFeatureSource
185 | id_field = self.parameterAsString(parameters, self.ID_FIELD, context) #str
186 | strategy = self.parameterAsEnum(parameters, self.STRATEGY, context) #int
187 |
188 | entry_cost_calc_method = self.parameterAsEnum(parameters, self.ENTRY_COST_CALCULATION_METHOD, context) #int
189 | directionFieldName = self.parameterAsString(parameters, self.DIRECTION_FIELD, context) #str (empty if no field given)
190 | forwardValue = self.parameterAsString(parameters, self.VALUE_FORWARD, context) #str
191 | backwardValue = self.parameterAsString(parameters, self.VALUE_BACKWARD, context) #str
192 | bothValue = self.parameterAsString(parameters, self.VALUE_BOTH, context) #str
193 | defaultDirection = self.parameterAsEnum(parameters, self.DEFAULT_DIRECTION, context) #int
194 | speedFieldName = self.parameterAsString(parameters, self.SPEED_FIELD, context) #str
195 | defaultSpeed = self.parameterAsDouble(parameters, self.DEFAULT_SPEED, context) #float
196 | tolerance = self.parameterAsDouble(parameters, self.TOLERANCE, context) #float
197 | output_path = self.parameterAsFileOutput(parameters, self.OUTPUT, context) #str (filepath)
198 | feedback.pushInfo(pluginPath)
199 |
200 | analysisCrs = network.sourceCrs()
201 |
202 | feedback.pushInfo("[QNEAT3Algorithm] Building Graph...")
203 | net = Qneat3Network(network, points, strategy, directionFieldName, forwardValue, backwardValue, bothValue, defaultDirection, analysisCrs, speedFieldName, defaultSpeed, tolerance, feedback)
204 |
205 | list_analysis_points = [Qneat3AnalysisPoint("point", feature, id_field, net, net.list_tiedPoints[i], entry_cost_calc_method, feedback) for i, feature in enumerate(getFeaturesFromQgsIterable(net.input_points))]
206 |
207 | total_workload = float(pow(len(list_analysis_points),2))
208 | feedback.pushInfo("[QNEAT3Algorithm] Expecting total workload of {} iterations".format(int(total_workload)))
209 |
210 | with open(output_path, 'w', newline='') as csvfile:
211 | csv_writer = csv.writer(csvfile, delimiter=';',
212 | quotechar='|',
213 | quoting=csv.QUOTE_MINIMAL)
214 | #write header
215 | csv_writer.writerow(["origin_id","destination_id","entry_cost", "network_cost", "exit_cost", "total_cost"])
216 |
217 | current_workstep_number = 0
218 |
219 | for start_point in list_analysis_points:
220 | #optimize in case of undirected (not necessary to call calcDijkstra as it has already been calculated - can be replaced by reading from list)
221 | dijkstra_query = net.calcDijkstra(start_point.network_vertex_id, 0)
222 | for query_point in list_analysis_points:
223 | if (current_workstep_number%1000)==0:
224 | feedback.pushInfo("[QNEAT3Algorithm] {} OD-pairs processed...".format(current_workstep_number))
225 | if query_point.point_id == start_point.point_id:
226 | csv_writer.writerow([start_point.point_id, query_point.point_id, float(0), float(0), float(0), float(0)])
227 | elif dijkstra_query[0][query_point.network_vertex_id] == -1:
228 | csv_writer.writerow([start_point.point_id, query_point.point_id, None, None, None, None])
229 | else:
230 | entry_cost = start_point.entry_cost
231 | network_cost = dijkstra_query[1][query_point.network_vertex_id]
232 | exit_cost = query_point.entry_cost
233 | total_cost = entry_cost + network_cost + exit_cost
234 | csv_writer.writerow([start_point.point_id, query_point.point_id, entry_cost, network_cost, exit_cost, total_cost])
235 | current_workstep_number=current_workstep_number+1
236 | feedback.setProgress((current_workstep_number/total_workload)*100)
237 |
238 | feedback.pushInfo("[QNEAT3Algorithm] Total number of OD-pairs processed: {}".format(current_workstep_number))
239 |
240 | feedback.pushInfo("[QNEAT3Algorithm] Ending Algorithm")
241 |
242 | results = {self.OUTPUT: output_path}
243 | return results
244 |
245 |
--------------------------------------------------------------------------------
/algs/OdMatrixFromPointsAsTable.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | ***************************************************************************
4 | OdMatrixFromPointsAsTable.py
5 | ---------------------
6 |
7 | Partially based on QGIS3 network analysis algorithms.
8 | Copyright 2016 Alexander Bruy
9 |
10 | Date : February 2018
11 | Copyright : (C) 2018 by Clemens Raffler
12 | Email : clemens dot raffler at gmail dot com
13 | ***************************************************************************
14 | * *
15 | * This program is free software; you can redistribute it and/or modify *
16 | * it under the terms of the GNU General Public License as published by *
17 | * the Free Software Foundation; either version 2 of the License, or *
18 | * (at your option) any later version. *
19 | * *
20 | ***************************************************************************
21 | """
22 |
23 | __author__ = 'Clemens Raffler'
24 | __date__ = 'February 2018'
25 | __copyright__ = '(C) 2018, Clemens Raffler'
26 |
27 | # This will get replaced with a git SHA1 when you do a git archive
28 |
29 | __revision__ = '$Format:%H$'
30 |
31 | import os
32 | from collections import OrderedDict
33 |
34 | from qgis.PyQt.QtCore import QVariant
35 | from qgis.PyQt.QtGui import QIcon
36 |
37 | from qgis.core import (QgsWkbTypes,
38 | QgsFields,
39 | QgsField,
40 | QgsFeature,
41 | QgsFeatureSink,
42 | QgsProcessing,
43 | QgsProcessingParameterEnum,
44 | QgsProcessingParameterFeatureSink,
45 | QgsProcessingParameterFeatureSource,
46 | QgsProcessingParameterField,
47 | QgsProcessingParameterNumber,
48 | QgsProcessingParameterString,
49 | QgsProcessingParameterDefinition)
50 |
51 | from qgis.analysis import (QgsVectorLayerDirector)
52 |
53 | from QNEAT3.Qneat3Framework import Qneat3Network, Qneat3AnalysisPoint
54 | from QNEAT3.Qneat3Utilities import getFeaturesFromQgsIterable, getFieldDatatype
55 |
56 | from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
57 |
58 | pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
59 |
60 |
61 | class OdMatrixFromPointsAsTable(QgisAlgorithm):
62 |
63 | INPUT = 'INPUT'
64 | POINTS = 'POINTS'
65 | ID_FIELD = 'ID_FIELD'
66 | STRATEGY = 'STRATEGY'
67 | ENTRY_COST_CALCULATION_METHOD = 'ENTRY_COST_CALCULATION_METHOD'
68 | DIRECTION_FIELD = 'DIRECTION_FIELD'
69 | VALUE_FORWARD = 'VALUE_FORWARD'
70 | VALUE_BACKWARD = 'VALUE_BACKWARD'
71 | VALUE_BOTH = 'VALUE_BOTH'
72 | DEFAULT_DIRECTION = 'DEFAULT_DIRECTION'
73 | SPEED_FIELD = 'SPEED_FIELD'
74 | DEFAULT_SPEED = 'DEFAULT_SPEED'
75 | TOLERANCE = 'TOLERANCE'
76 | OUTPUT = 'OUTPUT'
77 |
78 | def icon(self):
79 | return QIcon(os.path.join(pluginPath, 'QNEAT3', 'icons', 'icon_matrix.svg'))
80 |
81 | def group(self):
82 | return self.tr('Distance Matrices')
83 |
84 | def groupId(self):
85 | return 'networkbaseddistancematrices'
86 |
87 | def name(self):
88 | return 'OdMatrixFromPointsAsTable'
89 |
90 | def displayName(self):
91 | return self.tr('OD Matrix from Points as Table (n:n)')
92 |
93 | def shortHelpString(self):
94 | return "General: "\
95 | "This algorithm implements OD-Matrix analysis to return the matrix of origin-destination pairs as table yielding network based costs on a given network dataset between the elements of one point layer(n:n). "\
96 | "It accounts for points outside of the network (eg. non-network-elements). Distances are measured accounting for ellipsoids, entry-, exit-, network- and total costs are listed in the result attribute-table.
"\
97 | "Parameters (required): "\
98 | "Following Parameters must be set to run the algorithm:"\
99 | "
Network Layer
Point Layer
Unique Point ID Field (numerical)
Cost Strategy
"\
100 | "Parameters (optional): "\
101 | "There are also a number of optional parameters to implement direction dependent shortest paths and provide information on speeds on the networks edges."\
102 | "
Direction Field
Value for forward direction
Value for backward direction
Value for both directions
Default direction
Speed Field
Default Speed (affects entry/exit costs)
Topology tolerance
"\
103 | "Output: "\
104 | "The output of the algorithm is one table:"\
105 | "
OD-Matrix as table with network based distances as attributes
"
106 |
107 | def print_typestring(self, var):
108 | return "Type:"+str(type(var))+" repr: "+var.__str__()
109 |
110 | def __init__(self):
111 | super().__init__()
112 |
113 | def initAlgorithm(self, config=None):
114 | self.DIRECTIONS = OrderedDict([
115 | (self.tr('Forward direction'), QgsVectorLayerDirector.DirectionForward),
116 | (self.tr('Backward direction'), QgsVectorLayerDirector.DirectionBackward),
117 | (self.tr('Both directions'), QgsVectorLayerDirector.DirectionBoth)])
118 |
119 | self.STRATEGIES = [self.tr('Shortest Path (distance optimization)'),
120 | self.tr('Fastest Path (time optimization)')]
121 |
122 | self.ENTRY_COST_CALCULATION_METHODS = [self.tr('Ellipsoidal'),
123 | self.tr('Planar (only use with projected CRS)')]
124 |
125 |
126 | self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT,
127 | self.tr('Network Layer'),
128 | [QgsProcessing.TypeVectorLine]))
129 | self.addParameter(QgsProcessingParameterFeatureSource(self.POINTS,
130 | self.tr('Point Layer'),
131 | [QgsProcessing.TypeVectorPoint]))
132 | self.addParameter(QgsProcessingParameterField(self.ID_FIELD,
133 | self.tr('Unique Point ID Field'),
134 | None,
135 | self.POINTS,
136 | optional=False))
137 | self.addParameter(QgsProcessingParameterEnum(self.STRATEGY,
138 | self.tr('Optimization Criterion'),
139 | self.STRATEGIES,
140 | defaultValue=0))
141 |
142 | params = []
143 | params.append(QgsProcessingParameterEnum(self.ENTRY_COST_CALCULATION_METHOD,
144 | self.tr('Entry Cost calculation method'),
145 | self.ENTRY_COST_CALCULATION_METHODS,
146 | defaultValue=0))
147 | params.append(QgsProcessingParameterField(self.DIRECTION_FIELD,
148 | self.tr('Direction field'),
149 | None,
150 | self.INPUT,
151 | optional=True))
152 | params.append(QgsProcessingParameterString(self.VALUE_FORWARD,
153 | self.tr('Value for forward direction'),
154 | optional=True))
155 | params.append(QgsProcessingParameterString(self.VALUE_BACKWARD,
156 | self.tr('Value for backward direction'),
157 | optional=True))
158 | params.append(QgsProcessingParameterString(self.VALUE_BOTH,
159 | self.tr('Value for both directions'),
160 | optional=True))
161 | params.append(QgsProcessingParameterEnum(self.DEFAULT_DIRECTION,
162 | self.tr('Default direction'),
163 | list(self.DIRECTIONS.keys()),
164 | defaultValue=2))
165 | params.append(QgsProcessingParameterField(self.SPEED_FIELD,
166 | self.tr('Speed field'),
167 | None,
168 | self.INPUT,
169 | optional=True))
170 | params.append(QgsProcessingParameterNumber(self.DEFAULT_SPEED,
171 | self.tr('Default speed (km/h)'),
172 | QgsProcessingParameterNumber.Double,
173 | 5.0, False, 0, 99999999.99))
174 | params.append(QgsProcessingParameterNumber(self.TOLERANCE,
175 | self.tr('Topology tolerance'),
176 | QgsProcessingParameterNumber.Double,
177 | 0.0, False, 0, 99999999.99))
178 |
179 | for p in params:
180 | p.setFlags(p.flags() | QgsProcessingParameterDefinition.FlagAdvanced)
181 | self.addParameter(p)
182 |
183 | self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Output OD Matrix'), QgsProcessing.TypeVectorLine), True)
184 |
185 | def processAlgorithm(self, parameters, context, feedback):
186 | feedback.pushInfo(self.tr("[QNEAT3Algorithm] This is a QNEAT3 Algorithm: '{}'".format(self.displayName())))
187 | network = self.parameterAsSource(parameters, self.INPUT, context) #QgsProcessingFeatureSource
188 | points = self.parameterAsSource(parameters, self.POINTS, context) #QgsProcessingFeatureSource
189 | id_field = self.parameterAsString(parameters, self.ID_FIELD, context) #str
190 | strategy = self.parameterAsEnum(parameters, self.STRATEGY, context) #int
191 |
192 | entry_cost_calc_method = self.parameterAsEnum(parameters, self.ENTRY_COST_CALCULATION_METHOD, context) #int
193 | directionFieldName = self.parameterAsString(parameters, self.DIRECTION_FIELD, context) #str (empty if no field given)
194 | forwardValue = self.parameterAsString(parameters, self.VALUE_FORWARD, context) #str
195 | backwardValue = self.parameterAsString(parameters, self.VALUE_BACKWARD, context) #str
196 | bothValue = self.parameterAsString(parameters, self.VALUE_BOTH, context) #str
197 | defaultDirection = self.parameterAsEnum(parameters, self.DEFAULT_DIRECTION, context) #int
198 | speedFieldName = self.parameterAsString(parameters, self.SPEED_FIELD, context) #str
199 | defaultSpeed = self.parameterAsDouble(parameters, self.DEFAULT_SPEED, context) #float
200 | tolerance = self.parameterAsDouble(parameters, self.TOLERANCE, context) #float
201 |
202 | analysisCrs = network.sourceCrs()
203 |
204 | feedback.pushInfo("[QNEAT3Algorithm] Building Graph...")
205 | net = Qneat3Network(network, points, strategy, directionFieldName, forwardValue, backwardValue, bothValue, defaultDirection, analysisCrs, speedFieldName, defaultSpeed, tolerance, feedback)
206 |
207 | list_analysis_points = [Qneat3AnalysisPoint("point", feature, id_field, net, net.list_tiedPoints[i], entry_cost_calc_method, feedback) for i, feature in enumerate(getFeaturesFromQgsIterable(net.input_points))]
208 |
209 | feat = QgsFeature()
210 | fields = QgsFields()
211 | output_id_field_data_type = getFieldDatatype(points, id_field)
212 | fields.append(QgsField('origin_id', output_id_field_data_type, '', 254, 0))
213 | fields.append(QgsField('destination_id', output_id_field_data_type, '', 254, 0))
214 | fields.append(QgsField('entry_cost', QVariant.Double, '', 20,7))
215 | fields.append(QgsField('network_cost', QVariant.Double, '', 20, 7))
216 | fields.append(QgsField('exit_cost', QVariant.Double, '', 20,7))
217 | fields.append(QgsField('total_cost', QVariant.Double, '', 20,7))
218 | feat.setFields(fields)
219 |
220 | (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
221 | fields, QgsWkbTypes.NoGeometry, network.sourceCrs())
222 |
223 |
224 | total_workload = float(pow(len(list_analysis_points),2))
225 | feedback.pushInfo("[QNEAT3Algorithm] Expecting total workload of {} iterations".format(int(total_workload)))
226 |
227 |
228 | current_workstep_number = 0
229 |
230 | for start_point in list_analysis_points:
231 | #optimize in case of undirected (not necessary to call calcDijkstra as it has already been calculated - can be replaced by reading from list)
232 | dijkstra_query = net.calcDijkstra(start_point.network_vertex_id, 0)
233 | for query_point in list_analysis_points:
234 | if (current_workstep_number%1000)==0:
235 | feedback.pushInfo("[QNEAT3Algorithm] {} OD-pairs processed...".format(current_workstep_number))
236 | if query_point.point_id == start_point.point_id:
237 | feat['origin_id'] = start_point.point_id
238 | feat['destination_id'] = query_point.point_id
239 | feat['entry_cost'] = 0.0
240 | feat['network_cost'] = 0.0
241 | feat['exit_cost'] = 0.0
242 | feat['total_cost'] = 0.0
243 | sink.addFeature(feat, QgsFeatureSink.FastInsert)
244 | elif dijkstra_query[0][query_point.network_vertex_id] == -1:
245 | feat['origin_id'] = start_point.point_id
246 | feat['destination_id'] = query_point.point_id
247 | feat['entry_cost'] = None
248 | feat['network_cost'] = None
249 | feat['exit_cost'] = None
250 | feat['total_cost'] = None
251 | sink.addFeature(feat, QgsFeatureSink.FastInsert)
252 | else:
253 | network_cost = dijkstra_query[1][query_point.network_vertex_id]
254 | feat['origin_id'] = start_point.point_id
255 | feat['destination_id'] = query_point.point_id
256 | feat['entry_cost'] = start_point.entry_cost
257 | feat['network_cost'] = network_cost
258 | feat['exit_cost'] = query_point.entry_cost
259 | feat['total_cost'] = start_point.entry_cost + network_cost + query_point.entry_cost
260 | sink.addFeature(feat, QgsFeatureSink.FastInsert)
261 | current_workstep_number=current_workstep_number+1
262 | feedback.setProgress(current_workstep_number/total_workload)
263 |
264 | feedback.pushInfo("[QNEAT3Algorithm] Total number of OD-pairs processed: {}".format(current_workstep_number))
265 |
266 | feedback.pushInfo("[QNEAT3Algorithm] Ending Algorithm")
267 |
268 | results = {}
269 | results[self.OUTPUT] = dest_id
270 | return results
271 |
272 |
--------------------------------------------------------------------------------
/icon_qneat3.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
31 |
--------------------------------------------------------------------------------
/icons/icon_dijkstra_onetoone.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
38 |
--------------------------------------------------------------------------------
/icons/icon_matrix.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
48 |
--------------------------------------------------------------------------------
/icons/icon_servicearea_contour.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
48 |
--------------------------------------------------------------------------------
/icons/icon_servicearea_contour_multiple.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
41 |
--------------------------------------------------------------------------------
/icons/icon_servicearea_interpolation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/root676/QNEAT3/3f0e9ee21963ce1edb2fd691d6a23e53145b8e02/icons/icon_servicearea_interpolation.png
--------------------------------------------------------------------------------
/icons/icon_servicearea_interpolation_multiple.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/root676/QNEAT3/3f0e9ee21963ce1edb2fd691d6a23e53145b8e02/icons/icon_servicearea_interpolation_multiple.png
--------------------------------------------------------------------------------
/icons/icon_servicearea_points.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
159 |
--------------------------------------------------------------------------------
/icons/icon_servicearea_points_multiple.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
187 |
--------------------------------------------------------------------------------
/icons/icon_servicearea_polygon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
45 |
--------------------------------------------------------------------------------
/icons/icon_servicearea_polygon_missing_import.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
44 |
--------------------------------------------------------------------------------
/icons/icon_servicearea_polygon_multiple.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
39 |
--------------------------------------------------------------------------------
/metadata.txt:
--------------------------------------------------------------------------------
1 | # Mandatory items:
2 |
3 |
4 | [general]
5 | name=QNEAT3
6 | qgisMinimumVersion=3.00
7 | qgisMaximumVersion=3.99
8 | description=QNEAT3 - QGIS Network Analysis Toolbox 3
9 | about=The QNEAT3 (short for Qgis Network Analysis Toolbox 3) Plugin aims to provide sophisticated QGIS Processing-Toolbox algorithms in the field of network analysis. QNEAT3 is integrated in the QGIS3 Processing Framework. It offers algorithms that range from simple shortest path solving to more complex tasks like Iso-Area (aka service areas, accessibility polygons) and OD-Matrix (Origin-Destination-Matrix) computation. The usage of some Iso-Area algorithms require the installation of the matplotlib python library from OSGeo4W (see algorithm and help page for more information).
10 | version=1.0.5
11 | author=Clemens Raffler
12 | email=clemens.raffler@gmail.com
13 |
14 | # end of mandatory metadata
15 |
16 | # Optional items:
17 |
18 | # Uncomment the following line and add your changelog entries:
19 | changelog=1.0.0:
20 | - First release of QNEAT3 Plugin. Enjoy!
21 | 1.0.1:
22 | - Fix fatal QGIS crash: Network Strategy must not be added multiple times.
23 | - Minor user-feedback and icon tweaks.
24 | - Fixed deprecation warning.
25 | 1.0.2:
26 | - Fix bug #10 OD Matrix randomly dropping one record
27 | - Fix bug #8 related to QGIS bug #16858, error in the QNEAT3 provider
28 | - Experiments with QNEAT interpolation, probably a solution to fix bug #6
29 | - Minor enhancements for log messages
30 | 1.0.3:
31 | - Fix bug #22 Issue with QgsPoint() being constructed from QgsPointXY() in QGIS 3.10 is resolved temporary
32 | 1.0.4:
33 | - Fix bug #25 Wire tolerance parameter permanently to QgsGraphBuilder
34 | 1.0.5:
35 | - New Feature: allow output of route geometry from OD Matrix algorithms (thanks to @garci66)
36 | - Fix issue #26: report NULL or delete OD pairs with no routes
37 | - Fix issue #57: Current processing setup does not allow qgis_process (CLI) to access QNEAT3 (thanks to @JanCaha)
38 | - Fix issue #62: API break in wkbType() (thanks to @merkato)
39 | - Fix issue #29: fix analysis crs in contours and interpolation algorithms (thanks to @kufreu and @josephholler)
40 | - fix issue #36: OD Matrix miscalculates time cost if network CRS does not use linear units of meters (thanks to @kufreu and @josephholler)
41 | - fix issue #31: Allow for different origin and destination ID data types (thanks to @kufreu and @josephholler)
42 |
43 | # tags are comma separated with spaces allowed
44 | tags= network analysis, graph analysis, od matrix, distance matrix, od matrices, OD, isochrone areas, catchment areas, shortest path, dijkstra
45 |
46 | homepage=https://root676.github.io
47 | tracker=https://github.com/root676/QNEAT3/issues
48 | repository=https://github.com/root676/QNEAT3
49 | icon=icon_qneat3.svg
50 | # experimental flag
51 | experimental=False
52 |
53 | #set processing provider flag
54 | hasProcessingProvider=yes
55 |
56 | # deprecated flag (applies to the whole plugin, not just a single version
57 | deprecated=False
58 |
59 |
--------------------------------------------------------------------------------
/testdata/minimal_testnetwork.cpg:
--------------------------------------------------------------------------------
1 | UTF-8
--------------------------------------------------------------------------------
/testdata/minimal_testnetwork.dbf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/root676/QNEAT3/3f0e9ee21963ce1edb2fd691d6a23e53145b8e02/testdata/minimal_testnetwork.dbf
--------------------------------------------------------------------------------
/testdata/minimal_testnetwork.prj:
--------------------------------------------------------------------------------
1 | PROJCS["MGI_Austria_GK_East",GEOGCS["GCS_MGI",DATUM["D_MGI",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",16.33333333333333],PARAMETER["scale_factor",1],PARAMETER["false_easting",0],PARAMETER["false_northing",-5000000],UNIT["Meter",1]]
--------------------------------------------------------------------------------
/testdata/minimal_testnetwork.qpj:
--------------------------------------------------------------------------------
1 | PROJCS["MGI / Austria GK East",GEOGCS["MGI",DATUM["Militar_Geographische_Institute",SPHEROID["Bessel 1841",6377397.155,299.1528128,AUTHORITY["EPSG","7004"]],TOWGS84[577.326,90.129,463.919,5.137,1.474,5.297,2.4232],AUTHORITY["EPSG","6312"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4312"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",16.33333333333333],PARAMETER["scale_factor",1],PARAMETER["false_easting",0],PARAMETER["false_northing",-5000000],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","31256"]]
2 |
--------------------------------------------------------------------------------
/testdata/minimal_testnetwork.shp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/root676/QNEAT3/3f0e9ee21963ce1edb2fd691d6a23e53145b8e02/testdata/minimal_testnetwork.shp
--------------------------------------------------------------------------------
/testdata/minimal_testnetwork.shx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/root676/QNEAT3/3f0e9ee21963ce1edb2fd691d6a23e53145b8e02/testdata/minimal_testnetwork.shx
--------------------------------------------------------------------------------