diff --git a/algs/IsoAreaAsContoursFromLayer.py b/algs/IsoAreaAsContoursFromLayer.py index bbd301c..c4e94ec 100644 --- a/algs/IsoAreaAsContoursFromLayer.py +++ b/algs/IsoAreaAsContoursFromLayer.py @@ -3,10 +3,10 @@ *************************************************************************** IsoAreaAsContourFromLayer.py --------------------- - - Partially based on QGIS3 network analysis algorithms. - Copyright 2016 Alexander Bruy - + + Partially based on QGIS3 network analysis algorithms. + Copyright 2016 Alexander Bruy + Date : February 2018 Copyright : (C) 2018 by Clemens Raffler Email : clemens dot raffler at gmail dot com @@ -88,27 +88,27 @@ def group(self): def groupId(self): return 'isoareas' - + def name(self): return 'isoareaascontoursfromlayer' def displayName(self): return self.tr('Iso-Area as Contours (from Layer)') - + def shortHelpString(self): return "General:
"\ "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.
"\ "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.

"\ "Parameters (required):
"\ "Following Parameters must be set to run the algorithm:"\ - "
"\ + "
"\ "Parameters (optional):
"\ "There are also a number of optional parameters to implement direction dependent shortest paths and provide information on speeds on the networks edges."\ "
"\ "Output:
"\ "The output of the algorithm are two layers:"\ "" - + def msg(self, var): return "Type:"+str(type(var))+" repr: "+var.__str__() @@ -121,12 +121,12 @@ def initAlgorithm(self, config=None): (self.tr('Backward direction'), QgsVectorLayerDirector.DirectionBackward), (self.tr('Both directions'), QgsVectorLayerDirector.DirectionBoth)]) - self.STRATEGIES = [self.tr('Shortest Path (distance optimization)'), - self.tr('Fastest Path (time optimization)') + self.STRATEGIES = [self.tr('Shortest distance'), + self.tr('Fastest time') ] self.ENTRY_COST_CALCULATION_METHODS = [self.tr('Planar (only use with projected CRS)')] - + self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT, self.tr('Network Layer'), @@ -140,7 +140,7 @@ def initAlgorithm(self, config=None): self.START_POINTS, optional=False)) self.addParameter(QgsProcessingParameterNumber(self.MAX_DIST, - self.tr('Size of Iso-Area (distance or time value)'), + self.tr('Maximum cost level of Iso-Area'), QgsProcessingParameterNumber.Double, 2500.0, False, 0, 99999999.99)) self.addParameter(QgsProcessingParameterNumber(self.INTERVAL, @@ -152,7 +152,7 @@ def initAlgorithm(self, config=None): QgsProcessingParameterNumber.Integer, 10, False, 1, 99999999)) self.addParameter(QgsProcessingParameterEnum(self.STRATEGY, - self.tr('Optimization Criterion'), + self.tr('Path type to calculate'), self.STRATEGIES, defaultValue=0)) @@ -191,7 +191,7 @@ def initAlgorithm(self, config=None): params.append(QgsProcessingParameterNumber(self.TOLERANCE, self.tr('Topology tolerance'), QgsProcessingParameterNumber.Double, - 0.0, False, 0, 99999999.99)) + 0.00001, False, 0, 99999999.99)) for p in params: p.setFlags(p.flags() | QgsProcessingParameterDefinition.FlagAdvanced) @@ -199,7 +199,7 @@ def initAlgorithm(self, config=None): self.addParameter(QgsProcessingParameterRasterDestination(self.OUTPUT_INTERPOLATION, self.tr('Output Interpolation'))) self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT_CONTOURS, self.tr('Output Contours'), QgsProcessing.TypeVectorLine)) - + def processAlgorithm(self, parameters, context, feedback): feedback.pushInfo(self.tr("[QNEAT3Algorithm] This is a QNEAT3 Algorithm: '{}'".format(self.displayName()))) network = self.parameterAsSource(parameters, self.INPUT, context) #QgsProcessingFeatureSource @@ -221,47 +221,46 @@ def processAlgorithm(self, parameters, context, feedback): tolerance = self.parameterAsDouble(parameters, self.TOLERANCE, context) #float output_path = self.parameterAsOutputLayer(parameters, self.OUTPUT_INTERPOLATION, context) #string - analysisCrs = context.project().crs() - input_coordinates = getListOfPoints(startPoints) - + analysisCrs = network.sourceCrs() + input_coordinates = getListOfPoints(startPoints) + feedback.pushInfo("[QNEAT3Algorithm] Building Graph...") feedback.setProgress(10) net = Qneat3Network(network, input_coordinates, strategy, directionFieldName, forwardValue, backwardValue, bothValue, defaultDirection, analysisCrs, speedFieldName, defaultSpeed, tolerance, feedback) feedback.setProgress(40) - + list_apoints = [Qneat3AnalysisPoint("from", feature, id_field, net, net.list_tiedPoints[i], entry_cost_calc_method, feedback) for i, feature in enumerate(getFeaturesFromQgsIterable(startPoints))] - + feedback.pushInfo("[QNEAT3Algorithm] Calculating Iso-Pointcloud...") iso_pointcloud = net.calcIsoPoints(list_apoints, max_dist+(max_dist*0.1)) feedback.setProgress(50) - + uri = "Point?crs={}&field=vertex_id:int(254)&field=cost:double(254,7)&field=origin_point_id:string(254)&index=yes".format(analysisCrs.authid()) - + iso_pointcloud_layer = QgsVectorLayer(uri, "iso_pointcloud_layer", "memory") iso_pointcloud_provider = iso_pointcloud_layer.dataProvider() iso_pointcloud_provider.addFeatures(iso_pointcloud, QgsFeatureSink.FastInsert) - + feedback.pushInfo("[QNEAT3Algorithm] Calculating Iso-Interpolation-Raster using QGIS TIN-Interpolator...") net.calcIsoTinInterpolation(iso_pointcloud_layer, cell_size, output_path) feedback.setProgress(70) - + fields = QgsFields() fields.append(QgsField('id', QVariant.Int, '', 254, 0)) fields.append(QgsField('cost_level', QVariant.Double, '', 20, 7)) - + (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT_CONTOURS, context, fields, QgsWkbTypes.LineString, network.sourceCrs()) - + feedback.pushInfo("[QNEAT3Algorithm] Calculating Iso-Contours using numpy and matplotlib...") contour_featurelist = net.calcIsoContours(max_dist, interval, output_path) feedback.setProgress(90) - + sink.addFeatures(contour_featurelist, QgsFeatureSink.FastInsert) - + feedback.pushInfo("[QNEAT3Algorithm] Ending Algorithm") feedback.setProgress(100) - + results = {} results[self.OUTPUT_INTERPOLATION] = output_path results[self.OUTPUT_CONTOURS] = dest_id return results - diff --git a/algs/IsoAreaAsContoursFromPoint.py b/algs/IsoAreaAsContoursFromPoint.py index 62dba7a..1620582 100644 --- a/algs/IsoAreaAsContoursFromPoint.py +++ b/algs/IsoAreaAsContoursFromPoint.py @@ -3,10 +3,10 @@ *************************************************************************** IsoAreaAsContourFromPoint.py --------------------- - - Partially based on QGIS3 network analysis algorithms. - Copyright 2016 Alexander Bruy - + + Partially based on QGIS3 network analysis algorithms. + Copyright 2016 Alexander Bruy + Date : February 2018 Copyright : (C) 2018 by Clemens Raffler Email : clemens dot raffler at gmail dot com @@ -88,7 +88,7 @@ def group(self): def groupId(self): return 'isoareas' - + def name(self): return 'isoareaascontoursfrompoint' @@ -101,15 +101,15 @@ def shortHelpString(self): "It accounts for points outside of the network (eg. non-network-elements) and increments the isochrone 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.

"\ "Parameters (required):
"\ "Following Parameters must be set to run the algorithm:"\ - "
"\ + "
"\ "Parameters (optional):
"\ "There are also a number of optional parameters to implement direction dependent shortest paths and provide information on speeds on the networks edges."\ "
"\ "Output:
"\ "The output of the algorithm are two layers:"\ "" - - + + def msg(self, var): return "Type:"+str(type(var))+" repr: "+var.__str__() @@ -122,12 +122,12 @@ def initAlgorithm(self, config=None): (self.tr('Backward direction'), QgsVectorLayerDirector.DirectionBackward), (self.tr('Both directions'), QgsVectorLayerDirector.DirectionBoth)]) - self.STRATEGIES = [self.tr('Shortest Path (distance optimization)'), - self.tr('Fastest Path (time optimization)') + self.STRATEGIES = [self.tr('Shortest distance'), + self.tr('Fastest time') ] self.ENTRY_COST_CALCULATION_METHODS = [self.tr('Planar (only use with projected CRS)')] - + self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT, self.tr('Network Layer'), @@ -135,7 +135,7 @@ def initAlgorithm(self, config=None): self.addParameter(QgsProcessingParameterPoint(self.START_POINT, self.tr('Start point'))) self.addParameter(QgsProcessingParameterNumber(self.MAX_DIST, - self.tr('Size of Iso-Area (distance or time value)'), + self.tr('Maximum cost level of Iso-Area'), QgsProcessingParameterNumber.Double, 2500.0, False, 0, 99999999.99)) self.addParameter(QgsProcessingParameterNumber(self.INTERVAL, @@ -147,7 +147,7 @@ def initAlgorithm(self, config=None): QgsProcessingParameterNumber.Integer, 10, False, 1, 99999999)) self.addParameter(QgsProcessingParameterEnum(self.STRATEGY, - self.tr('Optimization Criterion'), + self.tr('Path type to calculate'), self.STRATEGIES, defaultValue=0)) @@ -186,7 +186,7 @@ def initAlgorithm(self, config=None): params.append(QgsProcessingParameterNumber(self.TOLERANCE, self.tr('Topology tolerance'), QgsProcessingParameterNumber.Double, - 0.0, False, 0, 99999999.99)) + 0.00001, False, 0, 99999999.99)) for p in params: p.setFlags(p.flags() | QgsProcessingParameterDefinition.FlagAdvanced) @@ -194,7 +194,7 @@ def initAlgorithm(self, config=None): self.addParameter(QgsProcessingParameterRasterDestination(self.OUTPUT_INTERPOLATION, self.tr('Output Interpolation'))) self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT_CONTOURS, self.tr('Output Contours'), QgsProcessing.TypeVectorLine)) - + def processAlgorithm(self, parameters, context, feedback): feedback.pushInfo(self.tr("[QNEAT3Algorithm] This is a QNEAT3 Algorithm: '{}'".format(self.displayName()))) network = self.parameterAsSource(parameters, self.INPUT, context) #QgsProcessingFeatureSource @@ -218,44 +218,43 @@ def processAlgorithm(self, parameters, context, feedback): analysisCrs = network.sourceCrs() input_coordinates = [startPoint] input_point = getFeatureFromPointParameter(startPoint) - + feedback.pushInfo("[QNEAT3Algorithm] Building Graph...") - feedback.setProgress(10) + feedback.setProgress(10) net = Qneat3Network(network, input_coordinates, strategy, directionFieldName, forwardValue, backwardValue, bothValue, defaultDirection, analysisCrs, speedFieldName, defaultSpeed, tolerance, feedback) feedback.setProgress(40) - + analysis_point = Qneat3AnalysisPoint("point", input_point, "point_id", net, net.list_tiedPoints[0], entry_cost_calc_method, feedback) - + feedback.pushInfo("[QNEAT3Algorithm] Calculating Iso-Pointcloud...") iso_pointcloud = net.calcIsoPoints([analysis_point], (max_dist+(max_dist*0.1))) feedback.setProgress(50) - + uri = "Point?crs={}&field=vertex_id:int(254)&field=cost:double(254,7)&field=origin_point_id:string(254)&index=yes".format(analysisCrs.authid()) - + iso_pointcloud_layer = QgsVectorLayer(uri, "iso_pointcloud_layer", "memory") iso_pointcloud_provider = iso_pointcloud_layer.dataProvider() iso_pointcloud_provider.addFeatures(iso_pointcloud, QgsFeatureSink.FastInsert) - + feedback.pushInfo("[QNEAT3Algorithm] Calculating Iso-Interpolation-Raster using QGIS TIN-Interpolator...") net.calcIsoTinInterpolation(iso_pointcloud_layer, cell_size, output_path) feedback.setProgress(70) - + fields = QgsFields() fields.append(QgsField('id', QVariant.Int, '', 254, 0)) fields.append(QgsField('cost_level', QVariant.Double, '', 20, 7)) - + (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT_CONTOURS, context, fields, QgsWkbTypes.LineString, network.sourceCrs()) - + feedback.pushInfo("[QNEAT3Algorithm] Calculating Iso-Contours using numpy and matplotlib...") contour_featurelist = net.calcIsoContours(max_dist, interval, output_path) feedback.setProgress(90) - + sink.addFeatures(contour_featurelist, QgsFeatureSink.FastInsert) feedback.pushInfo("[QNEAT3Algorithm] Ending Algorithm") feedback.setProgress(100) - + results = {} results[self.OUTPUT_INTERPOLATION] = output_path results[self.OUTPUT_CONTOURS] = dest_id return results - diff --git a/algs/IsoAreaAsInterpolationFromLayer.py b/algs/IsoAreaAsInterpolationFromLayer.py index 9603886..f352af6 100644 --- a/algs/IsoAreaAsInterpolationFromLayer.py +++ b/algs/IsoAreaAsInterpolationFromLayer.py @@ -3,10 +3,10 @@ *************************************************************************** IsoAreaAsInterpolationFromLayer.py --------------------- - - Partially based on QGIS3 network analysis algorithms. - Copyright 2016 Alexander Bruy - + + Partially based on QGIS3 network analysis algorithms. + Copyright 2016 Alexander Bruy + Date : March 2018 Copyright : (C) 2018 by Clemens Raffler Email : clemens dot raffler at gmail dot com @@ -81,28 +81,28 @@ def group(self): def groupId(self): return 'isoareas' - + def name(self): return 'isoareaasinterpolationfromlayer' def displayName(self): return self.tr('Iso-Area as Interpolation (from Layer)') - + def shortHelpString(self): return "General:
"\ "This algorithm implements iso-area analysis to return the network-distance interpolation for a maximum cost level on a given network dataset for a layer of points.
"\ "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.

"\ "Parameters (required):
"\ "Following Parameters must be set to run the algorithm:"\ - "
"\ + "
"\ "Parameters (optional):
"\ "There are also a number of optional parameters to implement direction dependent shortest paths and provide information on speeds on the networks edges."\ "
"\ "Output:
"\ "The output of the algorithm is one layer:"\ "" - - + + def msg(self, var): return "Type:"+str(type(var))+" repr: "+var.__str__() @@ -115,12 +115,12 @@ def initAlgorithm(self, config=None): (self.tr('Backward direction'), QgsVectorLayerDirector.DirectionBackward), (self.tr('Both directions'), QgsVectorLayerDirector.DirectionBoth)]) - self.STRATEGIES = [self.tr('Shortest Path (distance optimization)'), - self.tr('Fastest Path (time optimization)') + self.STRATEGIES = [self.tr('Shortest distance'), + self.tr('Fastest time') ] self.ENTRY_COST_CALCULATION_METHODS = [self.tr('Planar (only use with projected CRS)')] - + self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT, self.tr('Network Layer'), @@ -134,7 +134,7 @@ def initAlgorithm(self, config=None): self.START_POINTS, optional=False)) self.addParameter(QgsProcessingParameterNumber(self.MAX_DIST, - self.tr('Size of Iso-Area (distance or time value)'), + self.tr('Maximum cost level of Iso-Area'), QgsProcessingParameterNumber.Double, 2500.0, False, 0, 99999999.99)) self.addParameter(QgsProcessingParameterNumber(self.CELL_SIZE, @@ -142,7 +142,7 @@ def initAlgorithm(self, config=None): QgsProcessingParameterNumber.Integer, 10, False, 1, 99999999)) self.addParameter(QgsProcessingParameterEnum(self.STRATEGY, - self.tr('Optimization Criterion'), + self.tr('Path type to calculate'), self.STRATEGIES, defaultValue=0)) @@ -181,12 +181,12 @@ def initAlgorithm(self, config=None): params.append(QgsProcessingParameterNumber(self.TOLERANCE, self.tr('Topology tolerance'), QgsProcessingParameterNumber.Double, - 0.0, False, 0, 99999999.99)) + 0.00001, False, 0, 99999999.99)) for p in params: p.setFlags(p.flags() | QgsProcessingParameterDefinition.FlagAdvanced) self.addParameter(p) - + self.addParameter(QgsProcessingParameterRasterDestination(self.OUTPUT, self.tr('Output Interpolation'))) def processAlgorithm(self, parameters, context, feedback): @@ -209,34 +209,33 @@ def processAlgorithm(self, parameters, context, feedback): tolerance = self.parameterAsDouble(parameters, self.TOLERANCE, context) #float output_path = self.parameterAsOutputLayer(parameters, self.OUTPUT, context) - analysisCrs = context.project().crs() + analysisCrs = network.sourceCrs() input_coordinates = getListOfPoints(startPoints) - + feedback.pushInfo("[QNEAT3Algorithm] Building Graph...") - feedback.setProgress(10) + feedback.setProgress(10) net = Qneat3Network(network, input_coordinates, strategy, directionFieldName, forwardValue, backwardValue, bothValue, defaultDirection, analysisCrs, speedFieldName, defaultSpeed, tolerance, feedback) feedback.setProgress(40) - + list_apoints = [Qneat3AnalysisPoint("from", feature, id_field, net, net.list_tiedPoints[i], entry_cost_calc_method, feedback) for i, feature in enumerate(getFeaturesFromQgsIterable(startPoints))] - + feedback.pushInfo("[QNEAT3Algorithm] Calculating Iso-Pointcloud...") iso_pointcloud = net.calcIsoPoints(list_apoints, max_dist) feedback.setProgress(70) - + uri = "Point?crs={}&field=vertex_id:int(254)&field=cost:double(254,7)&field=origin_point_id:string(254)&index=yes".format(analysisCrs.authid()) - + iso_pointcloud_layer = QgsVectorLayer(uri, "iso_pointcloud_layer", "memory") iso_pointcloud_provider = iso_pointcloud_layer.dataProvider() iso_pointcloud_provider.addFeatures(iso_pointcloud, QgsFeatureSink.FastInsert) - + feedback.pushInfo("[QNEAT3Algorithm] Calculating Iso-Interpolation-Raster using QGIS TIN-Interpolator...") net.calcIsoTinInterpolation(iso_pointcloud_layer, cell_size, output_path) feedback.setProgress(99) - + feedback.pushInfo("[QNEAT3Algorithm] Ending Algorithm") - feedback.setProgress(100) - + feedback.setProgress(100) + results = {} results[self.OUTPUT] = output_path return results - diff --git a/algs/IsoAreaAsInterpolationFromPoint.py b/algs/IsoAreaAsInterpolationFromPoint.py index 7c90578..4a872e8 100644 --- a/algs/IsoAreaAsInterpolationFromPoint.py +++ b/algs/IsoAreaAsInterpolationFromPoint.py @@ -3,10 +3,10 @@ *************************************************************************** IsoAreaAsInterpolationPoint.py --------------------- - - Partially based on QGIS3 network analysis algorithms. - Copyright 2016 Alexander Bruy - + + Partially based on QGIS3 network analysis algorithms. + Copyright 2016 Alexander Bruy + Date : March 2018 Copyright : (C) 2018 by Clemens Raffler Email : clemens dot raffler at gmail dot com @@ -81,7 +81,7 @@ def group(self): def groupId(self): return 'isoareas' - + def name(self): return 'isoareaasinterpolationfrompoint' @@ -94,14 +94,14 @@ def shortHelpString(self): "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.

"\ "Parameters (required):
"\ "Following Parameters must be set to run the algorithm:"\ - "
"\ + "
"\ "Parameters (optional):
"\ "There are also a number of optional parameters to implement direction dependent shortest paths and provide information on speeds on the networks edges."\ "
"\ "Output:
"\ "The output of the algorithm is one layer:"\ "" - + def msg(self, var): return "Type:"+str(type(var))+" repr: "+var.__str__() @@ -114,12 +114,12 @@ def initAlgorithm(self, config=None): (self.tr('Backward direction'), QgsVectorLayerDirector.DirectionBackward), (self.tr('Both directions'), QgsVectorLayerDirector.DirectionBoth)]) - self.STRATEGIES = [self.tr('Shortest Path (distance optimization)'), - self.tr('Fastest Path (time optimization)') + self.STRATEGIES = [self.tr('Shortest distance'), + self.tr('Fastest time') ] self.ENTRY_COST_CALCULATION_METHODS = [self.tr('Planar (only use with projected CRS)')] - + self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT, self.tr('Network Layer'), @@ -127,7 +127,7 @@ def initAlgorithm(self, config=None): self.addParameter(QgsProcessingParameterPoint(self.START_POINT, self.tr('Start point'))) self.addParameter(QgsProcessingParameterNumber(self.MAX_DIST, - self.tr('Size of Iso-Area (distance or time value)'), + self.tr('Maximum cost level of Iso-Area'), QgsProcessingParameterNumber.Double, 2500.0, False, 0, 99999999.99)) self.addParameter(QgsProcessingParameterNumber(self.CELL_SIZE, @@ -135,7 +135,7 @@ def initAlgorithm(self, config=None): QgsProcessingParameterNumber.Integer, 10, False, 1, 99999999)) self.addParameter(QgsProcessingParameterEnum(self.STRATEGY, - self.tr('Optimization Criterion'), + self.tr('Path type to calculate'), self.STRATEGIES, defaultValue=0)) @@ -174,12 +174,12 @@ def initAlgorithm(self, config=None): params.append(QgsProcessingParameterNumber(self.TOLERANCE, self.tr('Topology tolerance'), QgsProcessingParameterNumber.Double, - 0.0, False, 0, 99999999.99)) + 0.00001, False, 0, 99999999.99)) for p in params: p.setFlags(p.flags() | QgsProcessingParameterDefinition.FlagAdvanced) self.addParameter(p) - + self.addParameter(QgsProcessingParameterRasterDestination(self.OUTPUT, self.tr('Output Interpolation'))) def processAlgorithm(self, parameters, context, feedback): @@ -204,32 +204,31 @@ def processAlgorithm(self, parameters, context, feedback): analysisCrs = network.sourceCrs() input_coordinates = [startPoint] input_point = getFeatureFromPointParameter(startPoint) - + feedback.pushInfo("[QNEAT3Algorithm] Building Graph...") - feedback.setProgress(10) + feedback.setProgress(10) net = Qneat3Network(network, input_coordinates, strategy, directionFieldName, forwardValue, backwardValue, bothValue, defaultDirection, analysisCrs, speedFieldName, defaultSpeed, tolerance, feedback) feedback.setProgress(40) - + analysis_point = Qneat3AnalysisPoint("point", input_point, "point_id", net, net.list_tiedPoints[0], entry_cost_calc_method, feedback) - + feedback.pushInfo("[QNEAT3Algorithm] Calculating Iso-Pointcloud...") iso_pointcloud = net.calcIsoPoints([analysis_point], max_dist) feedback.setProgress(70) - + uri = "Point?crs={}&field=vertex_id:int(254)&field=cost:double(254,7)&field=origin_point_id:string(254)&index=yes".format(analysisCrs.authid()) - + iso_pointcloud_layer = QgsVectorLayer(uri, "iso_pointcloud_layer", "memory") iso_pointcloud_provider = iso_pointcloud_layer.dataProvider() iso_pointcloud_provider.addFeatures(iso_pointcloud, QgsFeatureSink.FastInsert) - + feedback.pushInfo("[QNEAT3Algorithm] Calculating Iso-Interpolation-Raster using QGIS TIN-Interpolator...") net.calcIsoTinInterpolation(iso_pointcloud_layer, cell_size, output_path) feedback.setProgress(99) - + feedback.pushInfo("[QNEAT3Algorithm] Ending Algorithm") - feedback.setProgress(100) - + feedback.setProgress(100) + results = {} results[self.OUTPUT] = output_path return results - diff --git a/algs/IsoAreaAsPointcloudFromLayer.py b/algs/IsoAreaAsPointcloudFromLayer.py index 1e273ff..819e70d 100644 --- a/algs/IsoAreaAsPointcloudFromLayer.py +++ b/algs/IsoAreaAsPointcloudFromLayer.py @@ -3,10 +3,10 @@ *************************************************************************** IsoAreaAsPointcloudFromLayer.py --------------------- - - Partially based on QGIS3 network analysis algorithms. - Copyright 2016 Alexander Bruy - + + Partially based on QGIS3 network analysis algorithms. + Copyright 2016 Alexander Bruy + Date : February 2018 Copyright : (C) 2018 by Clemens Raffler Email : clemens dot raffler at gmail dot com @@ -83,7 +83,7 @@ def group(self): def groupId(self): return 'isoareas' - + def name(self): return 'isoareaaspointcloudfromlayer' @@ -96,7 +96,7 @@ def shortHelpString(self): "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.

"\ "Parameters (required):
"\ "Following Parameters must be set to run the algorithm:"\ - "
"\ + "
"\ "Parameters (optional):
"\ "There are also a number of optional parameters to implement direction dependent shortest paths and provide information on speeds on the networks edges."\ "
"\ @@ -104,7 +104,7 @@ def shortHelpString(self): "The output of the algorithm is one layer:"\ "
"\ "You may use the output pointcloud as input for further analyses." - + def msg(self, var): return "Type:"+str(type(var))+" repr: "+var.__str__() @@ -117,13 +117,13 @@ def initAlgorithm(self, config=None): (self.tr('Backward direction'), QgsVectorLayerDirector.DirectionBackward), (self.tr('Both directions'), QgsVectorLayerDirector.DirectionBoth)]) - self.STRATEGIES = [self.tr('Shortest Path (distance optimization)'), - self.tr('Fastest Path (time optimization)') + self.STRATEGIES = [self.tr('Shortest distance'), + self.tr('Fastest time') ] self.ENTRY_COST_CALCULATION_METHODS = [self.tr('Ellipsoidal'), self.tr('Planar (only use with projected CRS)')] - + self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT, self.tr('Network Layer'), [QgsProcessing.TypeVectorLine])) @@ -140,7 +140,7 @@ def initAlgorithm(self, config=None): QgsProcessingParameterNumber.Double, 2500.0, False, 0, 99999999.99)) self.addParameter(QgsProcessingParameterEnum(self.STRATEGY, - self.tr('Optimization criterion'), + self.tr('Path type to calculate'), self.STRATEGIES, defaultValue=0)) @@ -179,12 +179,12 @@ def initAlgorithm(self, config=None): params.append(QgsProcessingParameterNumber(self.TOLERANCE, self.tr('Topology tolerance'), QgsProcessingParameterNumber.Double, - 0.0, False, 0, 99999999.99)) + 0.00001, False, 0, 99999999.99)) for p in params: p.setFlags(p.flags() | QgsProcessingParameterDefinition.FlagAdvanced) self.addParameter(p) - + self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Output Pointcloud'), QgsProcessing.TypeVectorPoint)) @@ -209,31 +209,30 @@ def processAlgorithm(self, parameters, context, feedback): analysisCrs = network.sourceCrs() input_coordinates = getListOfPoints(startPoints) - + feedback.pushInfo("[QNEAT3Algorithm] Building Graph...") - feedback.setProgress(10) + feedback.setProgress(10) net = Qneat3Network(network, input_coordinates, strategy, directionFieldName, forwardValue, backwardValue, bothValue, defaultDirection, analysisCrs, speedFieldName, defaultSpeed, tolerance, feedback) feedback.setProgress(40) - + list_apoints = [Qneat3AnalysisPoint("from", feature, id_field, net, net.list_tiedPoints[i], entry_cost_calc_method, feedback) for i, feature in enumerate(getFeaturesFromQgsIterable(startPoints))] - + fields = QgsFields() fields.append(QgsField('vertex_id', QVariant.Int, '', 254, 0)) fields.append(QgsField('cost', QVariant.Double, '', 254, 7)) fields.append(QgsField('origin_point_id', getFieldDatatype(startPoints, id_field))) - + (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, fields, QgsWkbTypes.Point, network.sourceCrs()) - + feedback.pushInfo("[QNEAT3Algorithm] Calculating Iso-Pointcloud...") iso_pointcloud = net.calcIsoPoints(list_apoints, max_dist) feedback.setProgress(90) - + sink.addFeatures(iso_pointcloud, QgsFeatureSink.FastInsert) - + feedback.pushInfo("[QNEAT3Algorithm] Ending Algorithm") - feedback.setProgress(100) - + feedback.setProgress(100) + results = {} results[self.OUTPUT] = dest_id return results - diff --git a/algs/IsoAreaAsPointcloudFromPoint.py b/algs/IsoAreaAsPointcloudFromPoint.py index 95e9583..b1c4322 100644 --- a/algs/IsoAreaAsPointcloudFromPoint.py +++ b/algs/IsoAreaAsPointcloudFromPoint.py @@ -3,10 +3,10 @@ *************************************************************************** IsoAreaAsPointcloudFromPoint.py --------------------- - - Partially based on QGIS3 network analysis algorithms. - Copyright 2016 Alexander Bruy - + + Partially based on QGIS3 network analysis algorithms. + Copyright 2016 Alexander Bruy + Date : February 2018 Copyright : (C) 2018 by Clemens Raffler Email : clemens dot raffler at gmail dot com @@ -83,20 +83,20 @@ def group(self): def groupId(self): return 'isoareas' - + def name(self): return 'isoareaaspointcloudfrompoint' def displayName(self): return self.tr('Iso-Area as Pointcloud (from Point)') - + def shortHelpString(self): return "General:
"\ "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.
"\ "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.

"\ "Parameters (required):
"\ "Following Parameters must be set to run the algorithm:"\ - "
"\ + "
"\ "Parameters (optional):
"\ "There are also a number of optional parameters to implement direction dependent shortest paths and provide information on speeds on the networks edges."\ "
"\ @@ -104,7 +104,7 @@ def shortHelpString(self): "The output of the algorithm is one layer:"\ "
"\ "You may use the output pointcloud as input for further analyses." - + def msg(self, var): return "Type:"+str(type(var))+" repr: "+var.__str__() @@ -117,8 +117,8 @@ def initAlgorithm(self, config=None): (self.tr('Backward direction'), QgsVectorLayerDirector.DirectionBackward), (self.tr('Both directions'), QgsVectorLayerDirector.DirectionBoth)]) - self.STRATEGIES = [self.tr('Shortest Path (distance optimization)'), - self.tr('Fastest Path (time optimization)') + self.STRATEGIES = [self.tr('Shortest distance'), + self.tr('Fastest time') ] self.ENTRY_COST_CALCULATION_METHODS = [self.tr('Ellipsoidal'), @@ -134,7 +134,7 @@ def initAlgorithm(self, config=None): QgsProcessingParameterNumber.Double, 2500.0, False, 0, 99999999.99)) self.addParameter(QgsProcessingParameterEnum(self.STRATEGY, - self.tr('Optimization Criterion'), + self.tr('Path type to calculate'), self.STRATEGIES, defaultValue=0)) @@ -173,12 +173,12 @@ def initAlgorithm(self, config=None): params.append(QgsProcessingParameterNumber(self.TOLERANCE, self.tr('Topology tolerance'), QgsProcessingParameterNumber.Double, - 0.0, False, 0, 99999999.99)) + 0.00001, False, 0, 99999999.99)) for p in params: p.setFlags(p.flags() | QgsProcessingParameterDefinition.FlagAdvanced) self.addParameter(p) - + self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Output Pointcloud'), QgsProcessing.TypeVectorPoint)) @@ -203,31 +203,30 @@ def processAlgorithm(self, parameters, context, feedback): analysisCrs = network.sourceCrs() input_coordinates = [startPoint] input_point = getFeatureFromPointParameter(startPoint) - + feedback.pushInfo("[QNEAT3Algorithm] Building Graph...") - feedback.setProgress(10) + feedback.setProgress(10) net = Qneat3Network(network, input_coordinates, strategy, directionFieldName, forwardValue, backwardValue, bothValue, defaultDirection, analysisCrs, speedFieldName, defaultSpeed, tolerance, feedback) feedback.setProgress(40) analysis_point = Qneat3AnalysisPoint("point", input_point, "point_id", net, net.list_tiedPoints[0], entry_cost_calc_method, feedback) - + fields = QgsFields() fields.append(QgsField('vertex_id', QVariant.Int, '', 254, 0)) fields.append(QgsField('cost', QVariant.Double, '', 254, 7)) fields.append(QgsField('origin_point_id',QVariant.String, '', 254, 7)) - + (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, fields, QgsWkbTypes.Point, network.sourceCrs()) - + feedback.pushInfo("[QNEAT3Algorithm] Calculating Iso-Pointcloud...") iso_pointcloud = net.calcIsoPoints([analysis_point], max_dist) feedback.setProgress(90) - + sink.addFeatures(iso_pointcloud, QgsFeatureSink.FastInsert) - + feedback.pushInfo("[QNEAT3Algorithm] Ending Algorithm") - feedback.setProgress(100) - + feedback.setProgress(100) + results = {} results[self.OUTPUT] = dest_id return results - diff --git a/algs/IsoAreaAsPolygonsFromLayer.py b/algs/IsoAreaAsPolygonsFromLayer.py index 75b0107..a1328b2 100644 --- a/algs/IsoAreaAsPolygonsFromLayer.py +++ b/algs/IsoAreaAsPolygonsFromLayer.py @@ -3,10 +3,10 @@ *************************************************************************** IsoAreaAsPolygonFromLayer.py --------------------- - - Partially based on QGIS3 network analysis algorithms. - Copyright 2016 Alexander Bruy - + + Partially based on QGIS3 network analysis algorithms. + Copyright 2016 Alexander Bruy + Date : April 2018 Copyright : (C) 2018 by Clemens Raffler Email : clemens dot raffler at gmail dot com @@ -88,27 +88,27 @@ def group(self): def groupId(self): return 'isoareas' - + def name(self): return 'isoareaaspolygonsfromlayer' def displayName(self): return self.tr('Iso-Area as Polygons (from Layer)') - + def shortHelpString(self): return "General:
"\ "This algorithm implements iso-area analysis to return the iso-area polygons for a maximum cost level and interval levels on a given network dataset for a layer of points.
"\ "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.

"\ "Parameters (required):
"\ "Following Parameters must be set to run the algorithm:"\ - "
"\ + "
"\ "Parameters (optional):
"\ "There are also a number of optional parameters to implement direction dependent shortest paths and provide information on speeds on the networks edges."\ "
"\ "Output:
"\ "The output of the algorithm are two layers:"\ - "" - + "" + def msg(self, var): return "Type:"+str(type(var))+" repr: "+var.__str__() @@ -121,12 +121,12 @@ def initAlgorithm(self, config=None): (self.tr('Backward direction'), QgsVectorLayerDirector.DirectionBackward), (self.tr('Both directions'), QgsVectorLayerDirector.DirectionBoth)]) - self.STRATEGIES = [self.tr('Shortest Path (distance optimization)'), - self.tr('Fastest Path (time optimization)') + self.STRATEGIES = [self.tr('Shortest distance'), + self.tr('Fastest time') ] self.ENTRY_COST_CALCULATION_METHODS = [self.tr('Planar (only use with projected CRS)')] - + self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT, self.tr('Vector layer representing network'), @@ -140,7 +140,7 @@ def initAlgorithm(self, config=None): self.START_POINTS, optional=False)) self.addParameter(QgsProcessingParameterNumber(self.MAX_DIST, - self.tr('Size of Iso-Area (distance or time value)'), + self.tr('Maximum cost level of Iso-Area'), QgsProcessingParameterNumber.Double, 2500.0, False, 0, 99999999.99)) self.addParameter(QgsProcessingParameterNumber(self.INTERVAL, @@ -191,7 +191,7 @@ def initAlgorithm(self, config=None): params.append(QgsProcessingParameterNumber(self.TOLERANCE, self.tr('Topology tolerance'), QgsProcessingParameterNumber.Double, - 0.0, False, 0, 99999999.99)) + 0.00001, False, 0, 99999999.99)) for p in params: p.setFlags(p.flags() | QgsProcessingParameterDefinition.FlagAdvanced) @@ -199,7 +199,7 @@ def initAlgorithm(self, config=None): self.addParameter(QgsProcessingParameterRasterDestination(self.OUTPUT_INTERPOLATION, self.tr('Output Interpolation'))) self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT_POLYGONS, self.tr('Output Polygon'), QgsProcessing.TypeVectorPolygon)) - + def processAlgorithm(self, parameters, context, feedback): feedback.pushInfo(self.tr("[QNEAT3Algorithm] This is a QNEAT3 Algorithm: '{}'".format(self.displayName()))) network = self.parameterAsSource(parameters, self.INPUT, context) #QgsProcessingFeatureSource @@ -223,45 +223,43 @@ def processAlgorithm(self, parameters, context, feedback): analysisCrs = network.sourceCrs() input_coordinates = getListOfPoints(startPoints) - + feedback.pushInfo("[QNEAT3Algorithm] Building Graph...") feedback.setProgress(10) net = Qneat3Network(network, input_coordinates, strategy, directionFieldName, forwardValue, backwardValue, bothValue, defaultDirection, analysisCrs, speedFieldName, defaultSpeed, tolerance, feedback) feedback.setProgress(40) - + list_apoints = [Qneat3AnalysisPoint("from", feature, id_field, net, net.list_tiedPoints[i], entry_cost_calc_method, feedback) for i, feature in enumerate(getFeaturesFromQgsIterable(startPoints))] - + feedback.pushInfo("[QNEAT3Algorithm] Calculating Iso-Pointcloud...") iso_pointcloud = net.calcIsoPoints(list_apoints, max_dist+(max_dist*0.1)) feedback.setProgress(50) - + uri = "Point?crs={}&field=vertex_id:int(254)&field=cost:double(254,7)&field=origin_point_id:string(254)&index=yes".format(analysisCrs.authid()) - + iso_pointcloud_layer = QgsVectorLayer(uri, "iso_pointcloud_layer", "memory") iso_pointcloud_provider = iso_pointcloud_layer.dataProvider() iso_pointcloud_provider.addFeatures(iso_pointcloud, QgsFeatureSink.FastInsert) - + feedback.pushInfo("[QNEAT3Algorithm] Calculating Iso-Interpolation-Raster using QGIS TIN-Interpolator...") net.calcIsoTinInterpolation(iso_pointcloud_layer, cell_size, output_path) feedback.setProgress(70) - + fields = QgsFields() fields.append(QgsField('id', QVariant.Int, '', 254, 0)) fields.append(QgsField('cost_level', QVariant.Double, '', 20, 7)) - - (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT_POLYGONS, context, fields, QgsWkbTypes.Polygon, network.sourceCrs()) - + + (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT_POLYGONS, context, fields, QgsWkbTypes.Polygon, network.sourceCrs()) + feedback.pushInfo("[QNEAT3Algorithm] Calculating Iso-Polygons using numpy and matplotlib...") polygon_featurelist = net.calcIsoPolygons(max_dist, interval, output_path) feedback.setProgress(90) - + sink.addFeatures(polygon_featurelist, QgsFeatureSink.FastInsert) feedback.pushInfo("[QNEAT3Algorithm] Ending Algorithm") feedback.setProgress(100) - + results = {} results[self.OUTPUT_INTERPOLATION] = output_path results[self.OUTPUT_POLYGONS] = dest_id return results - - diff --git a/algs/IsoAreaAsPolygonsFromPoint.py b/algs/IsoAreaAsPolygonsFromPoint.py index 80a6d06..0e96396 100644 --- a/algs/IsoAreaAsPolygonsFromPoint.py +++ b/algs/IsoAreaAsPolygonsFromPoint.py @@ -3,10 +3,10 @@ *************************************************************************** IsoAreaAsPolygonFromPoint.py --------------------- - - Partially based on QGIS3 network analysis algorithms. - Copyright 2016 Alexander Bruy - + + Partially based on QGIS3 network analysis algorithms. + Copyright 2016 Alexander Bruy + Date : April 2018 Copyright : (C) 2018 by Clemens Raffler Email : clemens dot raffler at gmail dot com @@ -88,27 +88,27 @@ def group(self): def groupId(self): return 'isoareas' - + def shortHelpString(self): return "General:
"\ "This algorithm implements iso-area analysis to return the iso-area polygons for a maximum cost level and interval levels on a given network dataset for a manually chosen point.
"\ "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.

"\ "Parameters (required):
"\ "Following Parameters must be set to run the algorithm:"\ - "
"\ + "
"\ "Parameters (optional):
"\ "There are also a number of optional parameters to implement direction dependent shortest paths and provide information on speeds on the networks edges."\ "
"\ "Output:
"\ "The output of the algorithm are two layers:"\ - "" - + "" + def name(self): return 'isoareaaspolygonsfrompoint' def displayName(self): return self.tr('Iso-Area as Polygons (from Point)') - + def msg(self, var): return "Type:"+str(type(var))+" repr: "+var.__str__() @@ -121,12 +121,12 @@ def initAlgorithm(self, config=None): (self.tr('Backward direction'), QgsVectorLayerDirector.DirectionBackward), (self.tr('Both directions'), QgsVectorLayerDirector.DirectionBoth)]) - self.STRATEGIES = [self.tr('Shortest Path (distance optimization)'), - self.tr('Fastest Path (time optimization)') + self.STRATEGIES = [self.tr('Shortest distance'), + self.tr('Fastest time') ] self.ENTRY_COST_CALCULATION_METHODS = [self.tr('Planar (only use with projected CRS)')] - + self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT, self.tr('Network Layer'), @@ -134,7 +134,7 @@ def initAlgorithm(self, config=None): self.addParameter(QgsProcessingParameterPoint(self.START_POINT, self.tr('Start Point'))) self.addParameter(QgsProcessingParameterNumber(self.MAX_DIST, - self.tr('Size of Iso-Area (distance or time value)'), + self.tr('Maximum cost level of Iso-Area'), QgsProcessingParameterNumber.Double, 2500.0, False, 0, 99999999.99)) self.addParameter(QgsProcessingParameterNumber(self.INTERVAL, @@ -146,7 +146,7 @@ def initAlgorithm(self, config=None): QgsProcessingParameterNumber.Integer, 10, False, 1, 99999999)) self.addParameter(QgsProcessingParameterEnum(self.STRATEGY, - self.tr('Optimization Criterion'), + self.tr('Path type to calculate'), self.STRATEGIES, defaultValue=0)) @@ -185,7 +185,7 @@ def initAlgorithm(self, config=None): params.append(QgsProcessingParameterNumber(self.TOLERANCE, self.tr('Topology tolerance'), QgsProcessingParameterNumber.Double, - 0.0, False, 0, 99999999.99)) + 0.00001, False, 0, 99999999.99)) for p in params: p.setFlags(p.flags() | QgsProcessingParameterDefinition.FlagAdvanced) @@ -193,7 +193,7 @@ def initAlgorithm(self, config=None): self.addParameter(QgsProcessingParameterRasterDestination(self.OUTPUT_INTERPOLATION, self.tr('Output Interpolation'))) self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT_POLYGONS, self.tr('Output Polygon'), QgsProcessing.TypeVectorPolygon)) - + def processAlgorithm(self, parameters, context, feedback): feedback.pushInfo(self.tr("[QNEAT3Algorithm] This is a QNEAT3 Algorithm: '{}'".format(self.displayName()))) network = self.parameterAsSource(parameters, self.INPUT, context) #QgsProcessingFeatureSource @@ -217,45 +217,43 @@ def processAlgorithm(self, parameters, context, feedback): analysisCrs = network.sourceCrs() input_coordinates = [startPoint] input_point = getFeatureFromPointParameter(startPoint) - + feedback.pushInfo("[QNEAT3Algorithm] Building Graph...") feedback.setProgress(10) net = Qneat3Network(network, input_coordinates, strategy, directionFieldName, forwardValue, backwardValue, bothValue, defaultDirection, analysisCrs, speedFieldName, defaultSpeed, tolerance, feedback) feedback.setProgress(40) - + analysis_point = Qneat3AnalysisPoint("point", input_point, "point_id", net, net.list_tiedPoints[0], entry_cost_calc_method, feedback) - + feedback.pushInfo("[QNEAT3Algorithm] Calculating Iso-Pointcloud...") iso_pointcloud = net.calcIsoPoints([analysis_point], max_dist+(max_dist*0.1)) feedback.setProgress(50) - + uri = "Point?crs={}&field=vertex_id:int(254)&field=cost:double(254,7)&field=origin_point_id:string(254)&index=yes".format(analysisCrs.authid()) - + iso_pointcloud_layer = QgsVectorLayer(uri, "iso_pointcloud_layer", "memory") iso_pointcloud_provider = iso_pointcloud_layer.dataProvider() iso_pointcloud_provider.addFeatures(iso_pointcloud, QgsFeatureSink.FastInsert) - + feedback.pushInfo("[QNEAT3Algorithm] Calculating Iso-Interpolation-Raster using QGIS TIN-Interpolator...") net.calcIsoTinInterpolation(iso_pointcloud_layer, cell_size, output_path) feedback.setProgress(70) - + fields = QgsFields() fields.append(QgsField('id', QVariant.Int, '', 254, 0)) fields.append(QgsField('cost_level', QVariant.Double, '', 20, 7)) - - (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT_POLYGONS, context, fields, QgsWkbTypes.Polygon, network.sourceCrs()) - + + (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT_POLYGONS, context, fields, QgsWkbTypes.Polygon, network.sourceCrs()) + feedback.pushInfo("[QNEAT3Algorithm] Calculating Iso-Polygons using numpy and matplotlib...") polygon_featurelist = net.calcIsoPolygons(max_dist, interval, output_path) feedback.setProgress(90) - + sink.addFeatures(polygon_featurelist, QgsFeatureSink.FastInsert) feedback.pushInfo("[QNEAT3Algorithm] Ending Algorithm") feedback.setProgress(100) - + results = {} results[self.OUTPUT_INTERPOLATION] = output_path results[self.OUTPUT_POLYGONS] = dest_id return results - - diff --git a/algs/IsoAreaAsQneatInterpolationFromPoint.py b/algs/IsoAreaAsQneatInterpolationFromPoint.py index 4663d47..9318695 100644 --- a/algs/IsoAreaAsQneatInterpolationFromPoint.py +++ b/algs/IsoAreaAsQneatInterpolationFromPoint.py @@ -3,10 +3,10 @@ *************************************************************************** IsoAreaAsQneatInterpolationPoint.py --------------------- - - Partially based on QGIS3 network analysis algorithms. - Copyright 2016 Alexander Bruy - + + Partially based on QGIS3 network analysis algorithms. + Copyright 2016 Alexander Bruy + Date : July 2018 Copyright : (C) 2018 by Clemens Raffler Email : clemens dot raffler at gmail dot com @@ -91,7 +91,7 @@ def group(self): def groupId(self): return 'isoareas' - + def name(self): return 'isoareaasqneatinterpolationfrompoint' @@ -104,14 +104,14 @@ def shortHelpString(self): "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.

"\ "Parameters (required):
"\ "Following Parameters must be set to run the algorithm:"\ - "
"\ + "
"\ "Parameters (optional):
"\ "There are also a number of optional parameters to implement direction dependent shortest paths and provide information on speeds on the networks edges."\ "
"\ "Output:
"\ "The output of the algorithm is one layer:"\ "" - + def msg(self, var): return "Type:"+str(type(var))+" repr: "+var.__str__() @@ -124,16 +124,16 @@ def initAlgorithm(self, config=None): (self.tr('Backward direction'), QgsVectorLayerDirector.DirectionBackward), (self.tr('Both directions'), QgsVectorLayerDirector.DirectionBoth)]) - self.STRATEGIES = [self.tr('Shortest Path (distance optimization)'), - self.tr('Fastest Path (time optimization)') + self.STRATEGIES = [self.tr('Shortest distance'), + self.tr('Fastest time') ] - + self.METHODS = [self.tr('QGIS TIN-Interpolation (faster but not exact)'), self.tr('QNEAT-Interpolation (slower but more exact') ] self.ENTRY_COST_CALCULATION_METHODS = [self.tr('Planar (only use with projected CRS)')] - + self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT, self.tr('Network Layer'), @@ -141,7 +141,7 @@ def initAlgorithm(self, config=None): self.addParameter(QgsProcessingParameterPoint(self.START_POINT, self.tr('Start point'))) self.addParameter(QgsProcessingParameterNumber(self.MAX_DIST, - self.tr('Size of Iso-Area (distance or time value)'), + self.tr('Maximum cost level of Iso-Area'), QgsProcessingParameterNumber.Double, 2500.0, False, 0, 99999999.99)) self.addParameter(QgsProcessingParameterNumber(self.CELL_SIZE, @@ -149,7 +149,7 @@ def initAlgorithm(self, config=None): QgsProcessingParameterNumber.Integer, 10, False, 1, 99999999)) self.addParameter(QgsProcessingParameterEnum(self.STRATEGY, - self.tr('Optimization Criterion'), + self.tr('Path type to calculate'), self.STRATEGIES, defaultValue=0)) self.addParameter(QgsProcessingParameterEnum(self.METHOD, @@ -192,12 +192,12 @@ def initAlgorithm(self, config=None): params.append(QgsProcessingParameterNumber(self.TOLERANCE, self.tr('Topology tolerance'), QgsProcessingParameterNumber.Double, - 0.0, False, 0, 99999999.99)) + 0.00001, False, 0, 99999999.99)) for p in params: p.setFlags(p.flags() | QgsProcessingParameterDefinition.FlagAdvanced) self.addParameter(p) - + self.addParameter(QgsProcessingParameterRasterDestination(self.OUTPUT, self.tr('Output Interpolation'))) def processAlgorithm(self, parameters, context, feedback): @@ -223,24 +223,24 @@ def processAlgorithm(self, parameters, context, feedback): analysisCrs = network.sourceCrs() input_coordinates = [startPoint] input_point = getFeatureFromPointParameter(startPoint) - + feedback.pushInfo("[QNEAT3Algorithm] Building Graph...") - feedback.setProgress(10) + feedback.setProgress(10) net = Qneat3Network(network, input_coordinates, strategy, directionFieldName, forwardValue, backwardValue, bothValue, defaultDirection, analysisCrs, speedFieldName, defaultSpeed, tolerance, feedback) feedback.setProgress(40) - + analysis_point = Qneat3AnalysisPoint("point", input_point, "point_id", net, net.list_tiedPoints[0], entry_cost_calc_method, feedback) - + feedback.pushInfo("[QNEAT3Algorithm] Calculating Iso-Pointcloud...") iso_pointcloud = net.calcIsoPoints([analysis_point], max_dist) feedback.setProgress(70) - + uri = "Point?crs={}&field=vertex_id:int(254)&field=cost:double(254,7)&field=origin_point_id:string(254)&index=yes".format(analysisCrs.authid()) - + iso_pointcloud_layer = QgsVectorLayer(uri, "iso_pointcloud_layer", "memory") iso_pointcloud_provider = iso_pointcloud_layer.dataProvider() iso_pointcloud_provider.addFeatures(iso_pointcloud, QgsFeatureSink.FastInsert) - + feedback.pushInfo("[QNEAT3Algorithm] Calculating Iso-Interpolation-Raster using QGIS TIN-Interpolator...") if interpolation_method == 0: feedback.pushInfo("[QNEAT3Algorithm] Calculating Iso-Interpolation-Raster using QGIS TIN-Interpolator...") @@ -252,84 +252,84 @@ def processAlgorithm(self, parameters, context, feedback): #prepare numpy coordinate grids NoData_value = -9999 raster_rectangle = iso_pointcloud_layer.extent() - + #implement spatial index for lines (closest line, etc...) spt_idx = QgsSpatialIndex(iso_pointcloud_layer.getFeatures(QgsFeatureRequest()), feedback) - + #top left point xmin = raster_rectangle.xMinimum() ymin = raster_rectangle.yMinimum() xmax = raster_rectangle.xMaximum() ymax = raster_rectangle.yMaximum() - + cols = int((xmax - xmin) / cell_size) rows = int((ymax - ymin) / cell_size) - + output_interpolation_raster = gdal.GetDriverByName('GTiff').Create(output_path, cols, rows, 1, gdal.GDT_Float64 ) output_interpolation_raster.SetGeoTransform((xmin, cell_size, 0, ymax, 0, -cell_size)) - + band = output_interpolation_raster.GetRasterBand(1) band.SetNoDataValue(NoData_value) - + #initialize zero array with 2 dimensions (according to rows and cols) raster_routingcost_data = zeros(shape=(rows, cols)) - + #compute raster cell MIDpoints x_pos = linspace(xmin+(cell_size/2), xmax -(cell_size/2), raster_routingcost_data.shape[1]) y_pos = linspace(ymax-(cell_size/2), ymin + (cell_size/2), raster_routingcost_data.shape[0]) - x_grid, y_grid = meshgrid(x_pos, y_pos) - + x_grid, y_grid = meshgrid(x_pos, y_pos) + feedback.pushInfo('[QNEAT3Network][calcQneatInterpolation] Beginning with interpolation') total_work = rows * cols counter = 0 - + feedback.pushInfo('[QNEAT3Network][calcQneatInterpolation] Total workload: {} cells'.format(total_work)) feedback.setProgress(0) for i in range(rows): for j in range(cols): current_pixel_midpoint = QgsPointXY(x_grid[i,j],y_grid[i,j]) - + nearest_vertex_fid = spt_idx.nearestNeighbor(current_pixel_midpoint, 1)[0] - + nearest_feature = iso_pointcloud_layer.getFeature(nearest_vertex_fid) - + nearest_vertex = net.network.vertex(nearest_feature['vertex_id']) - - #yields a list of all incoming and outgoing edges - edges = nearest_vertex.incomingEdges() + nearest_vertex.outgoingEdges() - + + #yields a list of all incoming and outgoing edges + edges = nearest_vertex.incomingEdges() + nearest_vertex.outgoingEdges() + vertex_found = False nearest_counter = 2 while vertex_found == False: #find the second nearest vertex (eg, the vertex with least cost of all edges incoming to the first nearest vertex) - second_nearest_feature_fid = spt_idx.nearestNeighbor(current_pixel_midpoint, nearest_counter)[nearest_counter-1] + second_nearest_feature_fid = spt_idx.nearestNeighbor(current_pixel_midpoint, nearest_counter)[nearest_counter-1] second_nearest_feature = iso_pointcloud_layer.getFeature(second_nearest_feature_fid) second_nearest_vertex_id = second_nearest_feature['vertex_id'] - + for edge_id in edges: from_vertex_id = net.network.edge(edge_id).fromVertex() to_vertex_id = net.network.edge(edge_id).toVertex() - - if second_nearest_vertex_id == from_vertex_id: + + if second_nearest_vertex_id == from_vertex_id: vertex_found = True vertex_type = "from_vertex" from_point = second_nearest_feature.geometry().asPoint() from_vertex_cost = second_nearest_feature['cost'] - + if second_nearest_vertex_id == to_vertex_id: vertex_found = True vertex_type = "to_vertex" to_point = second_nearest_feature.geometry().asPoint() to_vertex_cost = second_nearest_feature['cost'] - - + + nearest_counter = nearest_counter + 1 """ if nearest_counter == 5: vertex_found = True vertex_type = "end_vertex" """ - + if vertex_type == "from_vertex": nearest_edge_geometry = QgsGeometry().fromPolylineXY([from_point, nearest_vertex.point()]) res = nearest_edge_geometry.closestSegmentWithContext(current_pixel_midpoint) @@ -354,34 +354,34 @@ def processAlgorithm(self, parameters, context, feedback): raster_routingcost_data[i,j] = pixel_cost else: pixel_cost = -99999#nearest_feature['cost'] + (nearest_vertex.point().distance(current_pixel_midpoint)) - - + + """ nearest_feature_pointxy = nearest_feature.geometry().asPoint() nearest_feature_cost = nearest_feature['cost'] - + dist_to_vertex = current_pixel_midpoint.distance(nearest_feature_pointxy) #implement time cost pixel_cost = dist_to_vertex + nearest_feature_cost - + raster_data[i,j] = pixel_cost """ counter = counter+1 if counter%1000 == 0: feedback.pushInfo("[QNEAT3Network][calcQneatInterpolation] Interpolated {} cells...".format(counter)) feedback.setProgress((counter/total_work)*100) - - + + band.WriteArray(raster_routingcost_data) outRasterSRS = osr.SpatialReference() outRasterSRS.ImportFromWkt(net.AnalysisCrs.toWkt()) output_interpolation_raster.SetProjection(outRasterSRS.ExportToWkt()) band.FlushCache() - + feedback.pushInfo("[QNEAT3Algorithm] Ending Algorithm") - feedback.setProgress(100) - + feedback.setProgress(100) + results = {} results[self.OUTPUT] = output_path - return results \ No newline at end of file + return results diff --git a/algs/OdMatrixFromLayersAsLines.py b/algs/OdMatrixFromLayersAsLines.py index 1d82d3d..01d4ad1 100644 --- a/algs/OdMatrixFromLayersAsLines.py +++ b/algs/OdMatrixFromLayersAsLines.py @@ -3,10 +3,10 @@ *************************************************************************** OdMatrixFromLayersAsLines.py --------------------- - - Partially based on QGIS3 network analysis algorithms. - Copyright 2016 Alexander Bruy - + + Partially based on QGIS3 network analysis algorithms. + Copyright 2016 Alexander Bruy + Date : February 2018 Copyright : (C) 2018 by Clemens Raffler Email : clemens dot raffler at gmail dot com @@ -65,7 +65,7 @@ class OdMatrixFromLayersAsLines(QgisAlgorithm): FROM_POINT_LAYER = 'FROM_POINT_LAYER' FROM_ID_FIELD = 'FROM_ID_FIELD' TO_POINT_LAYER = 'TO_POINT_LAYER' - TO_ID_FIELD = 'TO_ID_FIELD' + TO_ID_FIELD = 'TO_ID_FIELD' STRATEGY = 'STRATEGY' ENTRY_COST_CALCULATION_METHOD = 'ENTRY_COST_CALCULATION_METHOD' DIRECTION_FIELD = 'DIRECTION_FIELD' @@ -86,28 +86,28 @@ def group(self): def groupId(self): return 'networkbaseddistancematrices' - + def name(self): return 'OdMatrixFromLayersAsLines' def displayName(self): return self.tr('OD Matrix from Layers as Lines (m:n)') - + def shortHelpString(self): return "General:
"\ - "This algorithm implements OD-Matrix analysis to return the matrix of origin-destination pairs as lines yielding network based costs on a given network dataset between two layer of points (m:n).
"\ + "This algorithm implements OD Matrix analysis to return the matrix of origin-destination pairs as lines yielding network based costs on a given network dataset between two layer of points (m:n).
"\ "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.

"\ "Parameters (required):
"\ "Following Parameters must be set to run the algorithm:"\ - "
"\ + "
"\ "Parameters (optional):
"\ "There are also a number of optional parameters to implement direction dependent shortest paths and provide information on speeds on the networks edges."\ "
"\ "Output:
"\ "The output of the algorithm is one layer:"\ - "" - - + "" + + def print_typestring(self, var): return "Type:"+str(type(var))+" repr: "+var.__str__() @@ -120,39 +120,39 @@ def initAlgorithm(self, config=None): (self.tr('Backward direction'), QgsVectorLayerDirector.DirectionBackward), (self.tr('Both directions'), QgsVectorLayerDirector.DirectionBoth)]) - self.STRATEGIES = [self.tr('Shortest Path (distance optimization)'), - self.tr('Fastest Path (time optimization)') + self.STRATEGIES = [self.tr('Shortest distance'), + self.tr('Fastest time') ] self.ENTRY_COST_CALCULATION_METHODS = [self.tr('Ellipsoidal'), self.tr('Planar (only use with projected CRS)')] - + self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT, - self.tr('Network Layer'), + self.tr('Network layer'), [QgsProcessing.TypeVectorLine])) - + self.addParameter(QgsProcessingParameterFeatureSource(self.FROM_POINT_LAYER, - self.tr('From-Point Layer'), + self.tr('Input point layer (origin points)'), [QgsProcessing.TypeVectorPoint])) - + self.addParameter(QgsProcessingParameterField(self.FROM_ID_FIELD, - self.tr('Unique Point ID Field'), + self.tr('Input unique ID field'), None, self.FROM_POINT_LAYER, optional=False)) - + self.addParameter(QgsProcessingParameterFeatureSource(self.TO_POINT_LAYER, - self.tr('To-Point Layer'), + self.tr('Target point layer (destination points)'), [QgsProcessing.TypeVectorPoint])) - + self.addParameter(QgsProcessingParameterField(self.TO_ID_FIELD, - self.tr('Unique Point ID Field'), + self.tr('Target unique ID field'), None, self.TO_POINT_LAYER, optional=False)) - + self.addParameter(QgsProcessingParameterEnum(self.STRATEGY, - self.tr('Optimization Criterion'), + self.tr('Path type to calculate'), self.STRATEGIES, defaultValue=0)) @@ -191,7 +191,7 @@ def initAlgorithm(self, config=None): params.append(QgsProcessingParameterNumber(self.TOLERANCE, self.tr('Topology tolerance'), QgsProcessingParameterNumber.Double, - 0.0, False, 0, 99999999.99)) + 0.00001, False, 0, 99999999.99)) for p in params: p.setFlags(p.flags() | QgsProcessingParameterDefinition.FlagAdvanced) @@ -217,9 +217,9 @@ def processAlgorithm(self, parameters, context, feedback): speedFieldName = self.parameterAsString(parameters, self.SPEED_FIELD, context) #str defaultSpeed = self.parameterAsDouble(parameters, self.DEFAULT_SPEED, context) #float tolerance = self.parameterAsDouble(parameters, self.TOLERANCE, context) #float - + analysisCrs = network.sourceCrs() - + #Points of both layers have to be merged into one layer --> then tied to the Qneat3Network #get point list of from layer from_coord_list = getListOfPoints(from_points) @@ -227,34 +227,35 @@ def processAlgorithm(self, parameters, context, feedback): to_coord_list = getListOfPoints(to_points) merged_coords = from_coord_list + to_coord_list - + feedback.pushInfo("[QNEAT3Algorithm] Building Graph...") net = Qneat3Network(network, merged_coords, strategy, directionFieldName, forwardValue, backwardValue, bothValue, defaultDirection, analysisCrs, speedFieldName, defaultSpeed, tolerance, feedback) - + #read the merged point-list seperately for the two layers --> index at the first element of the second layer begins at len(firstLayer) and gets added the index of the current point of layer b. list_from_apoints = [Qneat3AnalysisPoint("from", feature, from_id_field, net, net.list_tiedPoints[i], entry_cost_calc_method, feedback) for i, feature in enumerate(getFeaturesFromQgsIterable(from_points))] list_to_apoints = [Qneat3AnalysisPoint("to", feature, to_id_field, net, net.list_tiedPoints[from_coord_list_length+i], entry_cost_calc_method, feedback) for i, feature in enumerate(getFeaturesFromQgsIterable(to_points))] - + feat = QgsFeature() fields = QgsFields() - output_id_field_data_type = getFieldDatatype(from_points, from_id_field) - fields.append(QgsField('origin_id', output_id_field_data_type, '', 254, 0)) - fields.append(QgsField('destination_id', output_id_field_data_type, '', 254, 0)) + orig_id_field_data_type = getFieldDatatype(from_points, from_id_field) + dest_id_field_data_type = getFieldDatatype(to_points, to_id_field) + fields.append(QgsField('InputID', orig_id_field_data_type, '', 254, 0)) + fields.append(QgsField('TargetID', dest_id_field_data_type, '', 254, 0)) fields.append(QgsField('entry_cost', QVariant.Double, '', 20,7)) fields.append(QgsField('network_cost', QVariant.Double, '', 20, 7)) fields.append(QgsField('exit_cost', QVariant.Double, '', 20,7)) fields.append(QgsField('total_cost', QVariant.Double, '', 20,7)) feat.setFields(fields) - + (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, fields, QgsWkbTypes.LineString, network.sourceCrs()) - + total_workload = float(len(from_coord_list)*len(to_coord_list)) feedback.pushInfo("[QNEAT3Algorithm] Expecting total workload of {} iterations".format(int(total_workload))) - - + + current_workstep_number = 0 - + for start_point in list_from_apoints: #optimize in case of undirected (not necessary to call calcDijkstra as it has already been calculated - can be replaced by reading from list) dijkstra_query = net.calcDijkstra(start_point.network_vertex_id, 0) @@ -262,8 +263,8 @@ def processAlgorithm(self, parameters, context, feedback): if (current_workstep_number%1000)==0: feedback.pushInfo("[QNEAT3Algorithm] {} OD-pairs processed...".format(current_workstep_number)) if dijkstra_query[0][query_point.network_vertex_id] == -1: - feat['origin_id'] = start_point.point_id - feat['destination_id'] = query_point.point_id + feat['InputID'] = start_point.point_id + feat['TargetID'] = query_point.point_id #do not populate cost field so that it defaults to null sink.addFeature(feat, QgsFeatureSink.FastInsert) else: @@ -271,23 +272,22 @@ def processAlgorithm(self, parameters, context, feedback): network_cost = dijkstra_query[1][query_point.network_vertex_id] exit_cost = query_point.entry_cost total_cost = network_cost + entry_cost + exit_cost - + feat.setGeometry(QgsGeometry.fromPolylineXY([start_point.point_geom, query_point.point_geom])) - feat['origin_id'] = start_point.point_id - feat['destination_id'] = query_point.point_id + feat['InputID'] = start_point.point_id + feat['TargetID'] = query_point.point_id feat['entry_cost'] = entry_cost feat['network_cost'] = network_cost feat['exit_cost'] = exit_cost feat['total_cost'] = total_cost - sink.addFeature(feat, QgsFeatureSink.FastInsert) + sink.addFeature(feat, QgsFeatureSink.FastInsert) current_workstep_number=current_workstep_number+1 feedback.setProgress((current_workstep_number/total_workload)*100) - + feedback.pushInfo("[QNEAT3Algorithm] Total number of OD-pairs processed: {}".format(current_workstep_number)) - + feedback.pushInfo("[QNEAT3Algorithm] Ending Algorithm") results = {} results[self.OUTPUT] = dest_id return results - diff --git a/algs/OdMatrixFromLayersAsTable.py b/algs/OdMatrixFromLayersAsTable.py index 0ed6b5f..9b15437 100644 --- a/algs/OdMatrixFromLayersAsTable.py +++ b/algs/OdMatrixFromLayersAsTable.py @@ -3,10 +3,10 @@ *************************************************************************** OdMatrixFromLayersAsTable.py --------------------- - - Partially based on QGIS3 network analysis algorithms. - Copyright 2016 Alexander Bruy - + + Partially based on QGIS3 network analysis algorithms. + Copyright 2016 Alexander Bruy + Date : February 2018 Copyright : (C) 2018 by Clemens Raffler Email : clemens dot raffler at gmail dot com @@ -64,7 +64,7 @@ class OdMatrixFromLayersAsTable(QgisAlgorithm): FROM_POINT_LAYER = 'FROM_POINT_LAYER' FROM_ID_FIELD = 'FROM_ID_FIELD' TO_POINT_LAYER = 'TO_POINT_LAYER' - TO_ID_FIELD = 'TO_ID_FIELD' + TO_ID_FIELD = 'TO_ID_FIELD' STRATEGY = 'STRATEGY' ENTRY_COST_CALCULATION_METHOD = 'ENTRY_COST_CALCULATION_METHOD' DIRECTION_FIELD = 'DIRECTION_FIELD' @@ -85,7 +85,7 @@ def group(self): def groupId(self): return 'networkbaseddistancematrices' - + def name(self): return 'OdMatrixFromLayersAsTable' @@ -98,14 +98,14 @@ def shortHelpString(self): "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.

"\ "Parameters (required):
"\ "Following Parameters must be set to run the algorithm:"\ - "
"\ + "
"\ "Parameters (optional):
"\ "There are also a number of optional parameters to implement direction dependent shortest paths and provide information on speeds on the networks edges."\ "
"\ "Output:
"\ "The output of the algorithm is one table:"\ - "" - + "" + def print_typestring(self, var): return "Type:"+str(type(var))+" repr: "+var.__str__() @@ -118,38 +118,38 @@ def initAlgorithm(self, config=None): (self.tr('Backward direction'), QgsVectorLayerDirector.DirectionBackward), (self.tr('Both directions'), QgsVectorLayerDirector.DirectionBoth)]) - self.STRATEGIES = [self.tr('Shortest Path (distance optimization)'), - self.tr('Fastest Path (time optimization)')] - + self.STRATEGIES = [self.tr('Shortest distance'), + self.tr('Fastest time')] + self.ENTRY_COST_CALCULATION_METHODS = [self.tr('Ellipsoidal'), self.tr('Planar (only use with projected CRS)')] self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT, self.tr('Network layer'), [QgsProcessing.TypeVectorLine])) - + self.addParameter(QgsProcessingParameterFeatureSource(self.FROM_POINT_LAYER, - self.tr('From-Point Layer'), + self.tr('Input point layer (origin points)'), [QgsProcessing.TypeVectorPoint])) - + self.addParameter(QgsProcessingParameterField(self.FROM_ID_FIELD, - self.tr('Unique Point ID Field'), + self.tr('Input unique ID field'), None, self.FROM_POINT_LAYER, optional=False)) - + self.addParameter(QgsProcessingParameterFeatureSource(self.TO_POINT_LAYER, - self.tr('To-Point Layer'), + self.tr('Target point layer (destination points)'), [QgsProcessing.TypeVectorPoint])) - + self.addParameter(QgsProcessingParameterField(self.TO_ID_FIELD, - self.tr('Unique Point ID Field'), + self.tr('Target unique ID field'), None, self.TO_POINT_LAYER, optional=False)) - + self.addParameter(QgsProcessingParameterEnum(self.STRATEGY, - self.tr('Optimization Criterion'), + self.tr('Path type to calculate'), self.STRATEGIES, defaultValue=0)) @@ -188,7 +188,7 @@ def initAlgorithm(self, config=None): params.append(QgsProcessingParameterNumber(self.TOLERANCE, self.tr('Topology tolerance'), QgsProcessingParameterNumber.Double, - 0.0, False, 0, 99999999.99)) + 0.00001, False, 0, 99999999.99)) for p in params: p.setFlags(p.flags() | QgsProcessingParameterDefinition.FlagAdvanced) @@ -204,7 +204,7 @@ def processAlgorithm(self, parameters, context, feedback): to_points = self.parameterAsSource(parameters, self.TO_POINT_LAYER, context) to_id_field = self.parameterAsString(parameters, self.TO_ID_FIELD, context) strategy = self.parameterAsEnum(parameters, self.STRATEGY, context) #int - + entry_cost_calc_method = self.parameterAsEnum(parameters, self.ENTRY_COST_CALCULATION_METHOD, context) #int directionFieldName = self.parameterAsString(parameters, self.DIRECTION_FIELD, context) #str (empty if no field given) forwardValue = self.parameterAsString(parameters, self.VALUE_FORWARD, context) #str @@ -214,9 +214,9 @@ def processAlgorithm(self, parameters, context, feedback): speedFieldName = self.parameterAsString(parameters, self.SPEED_FIELD, context) #str defaultSpeed = self.parameterAsDouble(parameters, self.DEFAULT_SPEED, context) #float tolerance = self.parameterAsDouble(parameters, self.TOLERANCE, context) #float - + analysisCrs = network.sourceCrs() - + #Points of both layers have to be merged into one layer --> then tied to the Qneat3Network #get point list of from layer from_coord_list = getListOfPoints(from_points) @@ -224,35 +224,36 @@ def processAlgorithm(self, parameters, context, feedback): to_coord_list = getListOfPoints(to_points) merged_coords = from_coord_list + to_coord_list - + feedback.pushInfo("[QNEAT3Algorithm] Building Graph...") net = Qneat3Network(network, merged_coords, strategy, directionFieldName, forwardValue, backwardValue, bothValue, defaultDirection, analysisCrs, speedFieldName, defaultSpeed, tolerance, feedback) - + #read the merged point-list seperately for the two layers --> index at the first element of the second layer begins at len(firstLayer) and gets added the index of the current point of layer b. list_from_apoints = [Qneat3AnalysisPoint("from", feature, from_id_field, net, net.list_tiedPoints[i], entry_cost_calc_method, feedback) for i, feature in enumerate(getFeaturesFromQgsIterable(from_points))] list_to_apoints = [Qneat3AnalysisPoint("to", feature, to_id_field, net, net.list_tiedPoints[from_coord_list_length+i], entry_cost_calc_method, feedback) for i, feature in enumerate(getFeaturesFromQgsIterable(to_points))] - + feat = QgsFeature() fields = QgsFields() - output_id_field_data_type = getFieldDatatype(from_points, from_id_field) - fields.append(QgsField('origin_id', output_id_field_data_type, '', 254, 0)) - fields.append(QgsField('destination_id', output_id_field_data_type, '', 254, 0)) + orig_id_field_data_type = getFieldDatatype(from_points, from_id_field) + dest_id_field_data_type = getFieldDatatype(to_points, to_id_field) + fields.append(QgsField('InputID', orig_id_field_data_type, '', 254, 0)) + fields.append(QgsField('TargetID', dest_id_field_data_type, '', 254, 0)) fields.append(QgsField('entry_cost', QVariant.Double, '', 20,7)) fields.append(QgsField('network_cost', QVariant.Double, '', 20, 7)) fields.append(QgsField('exit_cost', QVariant.Double, '', 20,7)) fields.append(QgsField('total_cost', QVariant.Double, '', 20,7)) feat.setFields(fields) - + (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, fields, QgsWkbTypes.NoGeometry, network.sourceCrs()) - + total_workload = float(len(from_coord_list)*len(to_coord_list)) feedback.pushInfo("[QNEAT3Algorithm] Expecting total workload of {} iterations".format(int(total_workload))) - - + + current_workstep_number = 0 - + for start_point in list_from_apoints: #optimize in case of undirected (not necessary to call calcDijkstra as it has already been calculated - can be replaced by reading from list) dijkstra_query = net.calcDijkstra(start_point.network_vertex_id, 0) @@ -260,27 +261,26 @@ def processAlgorithm(self, parameters, context, feedback): if (current_workstep_number%1000)==0: feedback.pushInfo("[QNEAT3Algorithm] {} OD-pairs processed...".format(current_workstep_number)) if dijkstra_query[0][query_point.network_vertex_id] == -1: - feat['origin_id'] = start_point.point_id - feat['destination_id'] = query_point.point_id + feat['InputID'] = start_point.point_id + feat['TargetID'] = query_point.point_id #do not populate cost field so that it defaults to null sink.addFeature(feat, QgsFeatureSink.FastInsert) else: network_cost = dijkstra_query[1][query_point.network_vertex_id] - feat['origin_id'] = start_point.point_id - feat['destination_id'] = query_point.point_id + feat['InputID'] = start_point.point_id + feat['TargetID'] = query_point.point_id feat['entry_cost'] = start_point.entry_cost feat['network_cost'] = network_cost feat['exit_cost'] = query_point.entry_cost feat['total_cost'] = network_cost + start_point.entry_cost + query_point.entry_cost - sink.addFeature(feat, QgsFeatureSink.FastInsert) + sink.addFeature(feat, QgsFeatureSink.FastInsert) current_workstep_number=current_workstep_number+1 feedback.setProgress((current_workstep_number/total_workload)*100) - + feedback.pushInfo("[QNEAT3Algorithm] Total number of OD-pairs processed: {}".format(current_workstep_number)) - + feedback.pushInfo("[QNEAT3Algorithm] Ending Algorithm") results = {} results[self.OUTPUT] = dest_id return results - diff --git a/algs/OdMatrixFromPointsAsCsv.py b/algs/OdMatrixFromPointsAsCsv.py index e4439ba..038ee6c 100644 --- a/algs/OdMatrixFromPointsAsCsv.py +++ b/algs/OdMatrixFromPointsAsCsv.py @@ -3,10 +3,10 @@ *************************************************************************** OdMatrixFromPointsAsCsv.py --------------------- - - Partially based on QGIS3 network analysis algorithms. - Copyright 2016 Alexander Bruy - + + Partially based on QGIS3 network analysis algorithms. + Copyright 2016 Alexander Bruy + Date : February 2018 Copyright : (C) 2018 by Clemens Raffler Email : clemens dot raffler at gmail dot com @@ -57,7 +57,7 @@ class OdMatrixFromPointsAsCsv(QgisAlgorithm): INPUT = 'INPUT' POINTS = 'POINTS' - ID_FIELD = 'ID_FIELD' + ID_FIELD = 'ID_FIELD' STRATEGY = 'STRATEGY' ENTRY_COST_CALCULATION_METHOD = 'ENTRY_COST_CALCULATION_METHOD' DIRECTION_FIELD = 'DIRECTION_FIELD' @@ -78,27 +78,27 @@ def group(self): def groupId(self): return 'networkbaseddistancematrices' - + def name(self): return 'OdMatrixFromPointsAsCsv' def displayName(self): - return self.tr('OD-Matrix from Points as CSV (n:n)') - + return self.tr('OD Matrix from Points as CSV (n:n)') + def shortHelpString(self): return "General:
"\ - "This algorithm implements OD-Matrix analysis to return the matrix of origin-destination pairs as csv-file yielding network based costs on a given network dataset between the elements of one point layer(n:n).
"\ + "This algorithm implements OD Matrix analysis to return the matrix of origin-destination pairs as csv-file yielding network based costs on a given network dataset between the elements of one point layer(n:n).
"\ "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.

"\ "Parameters (required):
"\ "Following Parameters must be set to run the algorithm:"\ - "
"\ + "
"\ "Parameters (optional):
"\ "There are also a number of optional parameters to implement direction dependent shortest paths and provide information on speeds on the networks edges."\ "
"\ "Output:
"\ "The output of the algorithm is one file:"\ - "" - + "" + def print_typestring(self, var): return "Type:"+str(type(var))+" repr: "+var.__str__() @@ -111,27 +111,27 @@ def initAlgorithm(self, config=None): (self.tr('Backward direction'), QgsVectorLayerDirector.DirectionBackward), (self.tr('Both directions'), QgsVectorLayerDirector.DirectionBoth)]) - self.STRATEGIES = [self.tr('Shortest Path (distance optimization)'), - self.tr('Fastest Path (time optimization)') + self.STRATEGIES = [self.tr('Shortest distance'), + self.tr('Fastest time') ] self.ENTRY_COST_CALCULATION_METHODS = [self.tr('Ellipsoidal'), self.tr('Planar (only use with projected CRS)')] - + self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT, - self.tr('Network Layer'), + self.tr('Network layer'), [QgsProcessing.TypeVectorLine])) self.addParameter(QgsProcessingParameterFeatureSource(self.POINTS, - self.tr('Point Layer'), + self.tr('Input point layer (origin points)'), [QgsProcessing.TypeVectorPoint])) self.addParameter(QgsProcessingParameterField(self.ID_FIELD, - self.tr('Unique Point ID Field'), + self.tr('Input unique ID field'), None, self.POINTS, optional=False)) self.addParameter(QgsProcessingParameterEnum(self.STRATEGY, - self.tr('Optimization Criterion'), + self.tr('Path type to calculate'), self.STRATEGIES, defaultValue=0)) @@ -170,7 +170,7 @@ def initAlgorithm(self, config=None): params.append(QgsProcessingParameterNumber(self.TOLERANCE, self.tr('Topology tolerance'), QgsProcessingParameterNumber.Double, - 0.0, False, 0, 99999999.99)) + 0.00001, False, 0, 99999999.99)) for p in params: p.setFlags(p.flags() | QgsProcessingParameterDefinition.FlagAdvanced) @@ -185,7 +185,7 @@ def processAlgorithm(self, parameters, context, feedback): id_field = self.parameterAsString(parameters, self.ID_FIELD, context) #str strategy = self.parameterAsEnum(parameters, self.STRATEGY, context) #int - entry_cost_calc_method = self.parameterAsEnum(parameters, self.ENTRY_COST_CALCULATION_METHOD, context) #int + entry_cost_calc_method = self.parameterAsEnum(parameters, self.ENTRY_COST_CALCULATION_METHOD, context) #int directionFieldName = self.parameterAsString(parameters, self.DIRECTION_FIELD, context) #str (empty if no field given) forwardValue = self.parameterAsString(parameters, self.VALUE_FORWARD, context) #str backwardValue = self.parameterAsString(parameters, self.VALUE_BACKWARD, context) #str @@ -196,26 +196,26 @@ def processAlgorithm(self, parameters, context, feedback): tolerance = self.parameterAsDouble(parameters, self.TOLERANCE, context) #float output_path = self.parameterAsFileOutput(parameters, self.OUTPUT, context) #str (filepath) feedback.pushInfo(pluginPath) - + analysisCrs = network.sourceCrs() - + feedback.pushInfo("[QNEAT3Algorithm] Building Graph...") net = Qneat3Network(network, points, strategy, directionFieldName, forwardValue, backwardValue, bothValue, defaultDirection, analysisCrs, speedFieldName, defaultSpeed, tolerance, feedback) - + 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))] - + total_workload = float(pow(len(list_analysis_points),2)) feedback.pushInfo("[QNEAT3Algorithm] Expecting total workload of {} iterations".format(int(total_workload))) - + with open(output_path, 'w', newline='') as csvfile: csv_writer = csv.writer(csvfile, delimiter=';', - quotechar='|', + quotechar='|', quoting=csv.QUOTE_MINIMAL) #write header - csv_writer.writerow(["origin_id","destination_id","entry_cost", "network_cost", "exit_cost", "total_cost"]) - + csv_writer.writerow(["InputID","TargetID","entry_cost", "network_cost", "exit_cost", "total_cost"]) + current_workstep_number = 0 - + for start_point in list_analysis_points: #optimize in case of undirected (not necessary to call calcDijkstra as it has already been calculated - can be replaced by reading from list) dijkstra_query = net.calcDijkstra(start_point.network_vertex_id, 0) @@ -234,11 +234,10 @@ def processAlgorithm(self, parameters, context, feedback): csv_writer.writerow([start_point.point_id, query_point.point_id, entry_cost, network_cost, exit_cost, total_cost]) current_workstep_number=current_workstep_number+1 feedback.setProgress((current_workstep_number/total_workload)*100) - + feedback.pushInfo("[QNEAT3Algorithm] Total number of OD-pairs processed: {}".format(current_workstep_number)) - + feedback.pushInfo("[QNEAT3Algorithm] Ending Algorithm") results = {self.OUTPUT: output_path} return results - diff --git a/algs/OdMatrixFromPointsAsLines.py b/algs/OdMatrixFromPointsAsLines.py index ae72a99..8c1767f 100644 --- a/algs/OdMatrixFromPointsAsLines.py +++ b/algs/OdMatrixFromPointsAsLines.py @@ -3,10 +3,10 @@ *************************************************************************** OdMatrixFromPointsAsLines.py --------------------- - - Partially based on QGIS3 network analysis algorithms. - Copyright 2016 Alexander Bruy - + + Partially based on QGIS3 network analysis algorithms. + Copyright 2016 Alexander Bruy + Date : February 2018 Copyright : (C) 2018 by Clemens Raffler Email : clemens dot raffler at gmail dot com @@ -63,7 +63,7 @@ class OdMatrixFromPointsAsLines(QgisAlgorithm): INPUT = 'INPUT' POINTS = 'POINTS' - ID_FIELD = 'ID_FIELD' + ID_FIELD = 'ID_FIELD' STRATEGY = 'STRATEGY' ENTRY_COST_CALCULATION_METHOD = 'ENTRY_COST_CALCULATION_METHOD' DIRECTION_FIELD = 'DIRECTION_FIELD' @@ -84,27 +84,27 @@ def group(self): def groupId(self): return 'networkbaseddistancematrices' - + def name(self): return 'OdMatrixFromPointsAsLines' def displayName(self): - return self.tr('OD-Matrix from Points as Lines (n:n)') + return self.tr('OD Matrix from Points as Lines (n:n)') def shortHelpString(self): return "General:
"\ - "This algorithm implements OD-Matrix analysis to return the matrix of origin-destination pairs as lines yielding network based costs on a given network dataset between the elements of one point layer(n:n).
"\ + "This algorithm implements OD Matrix analysis to return the matrix of origin-destination pairs as lines yielding network based costs on a given network dataset between the elements of one point layer(n:n).
"\ "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.

"\ "Parameters (required):
"\ "Following Parameters must be set to run the algorithm:"\ - "
"\ + "
"\ "Parameters (optional):
"\ "There are also a number of optional parameters to implement direction dependent shortest paths and provide information on speeds on the networks edges."\ "
"\ "Output:
"\ "The output of the algorithm is one layer:"\ - "" - + "" + def print_typestring(self, var): return "Type:"+str(type(var))+" repr: "+var.__str__() @@ -118,8 +118,8 @@ def initAlgorithm(self, config=None): (self.tr('Backward direction'), QgsVectorLayerDirector.DirectionBackward), (self.tr('Both directions'), QgsVectorLayerDirector.DirectionBoth)]) - self.STRATEGIES = [self.tr('Shortest Path (distance optimization)'), - self.tr('Fastest Path (time optimization)')] + self.STRATEGIES = [self.tr('Shortest distance'), + self.tr('Fastest time')] self.ENTRY_COST_CALCULATION_METHODS = [self.tr('Ellipsoidal'), self.tr('Planar (only use with projected CRS)')] @@ -128,15 +128,15 @@ def initAlgorithm(self, config=None): self.tr('Network Layer'), [QgsProcessing.TypeVectorLine])) self.addParameter(QgsProcessingParameterFeatureSource(self.POINTS, - self.tr('Point Layer'), + self.tr('Input point layer (origin points)'), [QgsProcessing.TypeVectorPoint])) self.addParameter(QgsProcessingParameterField(self.ID_FIELD, - self.tr('Unique Point ID Field'), + self.tr('Unique point ID field'), None, self.POINTS, optional=False)) self.addParameter(QgsProcessingParameterEnum(self.STRATEGY, - self.tr('Optimization Criterion'), + self.tr('Path type to calculate'), self.STRATEGIES, defaultValue=0)) @@ -175,7 +175,7 @@ def initAlgorithm(self, config=None): params.append(QgsProcessingParameterNumber(self.TOLERANCE, self.tr('Topology tolerance'), QgsProcessingParameterNumber.Double, - 0.0, False, 0, 99999999.99)) + 0.00001, False, 0, 99999999.99)) for p in params: p.setFlags(p.flags() | QgsProcessingParameterDefinition.FlagAdvanced) @@ -200,35 +200,35 @@ def processAlgorithm(self, parameters, context, feedback): speedFieldName = self.parameterAsString(parameters, self.SPEED_FIELD, context) #str defaultSpeed = self.parameterAsDouble(parameters, self.DEFAULT_SPEED, context) #float tolerance = self.parameterAsDouble(parameters, self.TOLERANCE, context) #float - + analysisCrs = network.sourceCrs() - + feedback.pushInfo("[QNEAT3Algorithm] Building Graph...") net = Qneat3Network(network, points, strategy, directionFieldName, forwardValue, backwardValue, bothValue, defaultDirection, analysisCrs, speedFieldName, defaultSpeed, tolerance, feedback) - + 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))] - + feat = QgsFeature() fields = QgsFields() output_id_field_data_type = getFieldDatatype(points, id_field) - fields.append(QgsField('origin_id', output_id_field_data_type, '', 254, 0)) - fields.append(QgsField('destination_id', output_id_field_data_type, '', 254, 0)) + fields.append(QgsField('InputID', output_id_field_data_type, '', 254, 0)) + fields.append(QgsField('TargetID', output_id_field_data_type, '', 254, 0)) fields.append(QgsField('entry_cost', QVariant.Double, '', 20,7)) fields.append(QgsField('network_cost', QVariant.Double, '', 20, 7)) fields.append(QgsField('exit_cost', QVariant.Double, '', 20,7)) fields.append(QgsField('total_cost', QVariant.Double, '', 20,7)) feat.setFields(fields) - + (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, fields, QgsWkbTypes.LineString, network.sourceCrs()) - + total_workload = float(pow(len(list_analysis_points),2)) feedback.pushInfo("[QNEAT3Algorithm] Expecting total workload of {} iterations".format(int(total_workload))) - - + + current_workstep_number = 0 - + for start_point in list_analysis_points: #optimize in case of undirected (not necessary to call calcDijkstra as it has already been calculated - can be replaced by reading from list) dijkstra_query = net.calcDijkstra(start_point.network_vertex_id, 0) @@ -236,35 +236,34 @@ def processAlgorithm(self, parameters, context, feedback): if (current_workstep_number%1000)==0: feedback.pushInfo("[QNEAT3Algorithm] {} OD-pairs processed...".format(current_workstep_number)) if query_point.point_id == start_point.point_id: - feat['origin_id'] = start_point.point_id - feat['destination_id'] = query_point.point_id + feat['InputID'] = start_point.point_id + feat['TargetID'] = query_point.point_id feat['entry_cost'] = 0.0 feat['network_cost'] = 0.0 feat['exit_cost'] = 0.0 feat['total_cost'] = 0.0 sink.addFeature(feat, QgsFeatureSink.FastInsert) elif dijkstra_query[0][query_point.network_vertex_id] == -1: - feat['origin_id'] = start_point.point_id - feat['destination_id'] = query_point.point_id + feat['InputID'] = start_point.point_id + feat['TargetID'] = query_point.point_id #do not populate cost field so that it defaults to null sink.addFeature(feat, QgsFeatureSink.FastInsert) else: network_cost = dijkstra_query[1][query_point.network_vertex_id] feat.setGeometry(QgsGeometry.fromPolylineXY([start_point.point_geom, query_point.point_geom])) - feat['origin_id'] = start_point.point_id - feat['destination_id'] = query_point.point_id + feat['InputID'] = start_point.point_id + feat['TargetID'] = query_point.point_id feat['entry_cost'] = start_point.entry_cost feat['network_cost'] = network_cost feat['exit_cost'] = query_point.entry_cost feat['total_cost'] = network_cost + start_point.entry_cost + query_point.entry_cost - sink.addFeature(feat, QgsFeatureSink.FastInsert) + sink.addFeature(feat, QgsFeatureSink.FastInsert) current_workstep_number=current_workstep_number+1 feedback.setProgress((current_workstep_number/total_workload)*100) - + feedback.pushInfo("[QNEAT3Algorithm] Total number of OD-pairs processed: {}".format(current_workstep_number)) - + feedback.pushInfo("[QNEAT3Algorithm] Ending Algorithm") results = {} results[self.OUTPUT] = dest_id return results - diff --git a/algs/OdMatrixFromPointsAsTable.py b/algs/OdMatrixFromPointsAsTable.py index 0c3a315..7d20b35 100644 --- a/algs/OdMatrixFromPointsAsTable.py +++ b/algs/OdMatrixFromPointsAsTable.py @@ -3,10 +3,10 @@ *************************************************************************** OdMatrixFromPointsAsTable.py --------------------- - - Partially based on QGIS3 network analysis algorithms. - Copyright 2016 Alexander Bruy - + + Partially based on QGIS3 network analysis algorithms. + Copyright 2016 Alexander Bruy + Date : February 2018 Copyright : (C) 2018 by Clemens Raffler Email : clemens dot raffler at gmail dot com @@ -62,7 +62,7 @@ class OdMatrixFromPointsAsTable(QgisAlgorithm): INPUT = 'INPUT' POINTS = 'POINTS' - ID_FIELD = 'ID_FIELD' + ID_FIELD = 'ID_FIELD' STRATEGY = 'STRATEGY' ENTRY_COST_CALCULATION_METHOD = 'ENTRY_COST_CALCULATION_METHOD' DIRECTION_FIELD = 'DIRECTION_FIELD' @@ -83,7 +83,7 @@ def group(self): def groupId(self): return 'networkbaseddistancematrices' - + def name(self): return 'OdMatrixFromPointsAsTable' @@ -92,18 +92,18 @@ def displayName(self): def shortHelpString(self): return "General:
"\ - "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).
"\ + "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).
"\ "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.

"\ "Parameters (required):
"\ "Following Parameters must be set to run the algorithm:"\ - "
"\ + "
"\ "Parameters (optional):
"\ "There are also a number of optional parameters to implement direction dependent shortest paths and provide information on speeds on the networks edges."\ "
"\ "Output:
"\ "The output of the algorithm is one table:"\ - "" - + "" + def print_typestring(self, var): return "Type:"+str(type(var))+" repr: "+var.__str__() @@ -116,26 +116,26 @@ def initAlgorithm(self, config=None): (self.tr('Backward direction'), QgsVectorLayerDirector.DirectionBackward), (self.tr('Both directions'), QgsVectorLayerDirector.DirectionBoth)]) - self.STRATEGIES = [self.tr('Shortest Path (distance optimization)'), - self.tr('Fastest Path (time optimization)')] + self.STRATEGIES = [self.tr('Shortest distance'), + self.tr('Fastest time')] self.ENTRY_COST_CALCULATION_METHODS = [self.tr('Ellipsoidal'), self.tr('Planar (only use with projected CRS)')] self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT, - self.tr('Network Layer'), + self.tr('Network layer'), [QgsProcessing.TypeVectorLine])) self.addParameter(QgsProcessingParameterFeatureSource(self.POINTS, - self.tr('Point Layer'), + self.tr('Input point layer (origin points)'), [QgsProcessing.TypeVectorPoint])) self.addParameter(QgsProcessingParameterField(self.ID_FIELD, - self.tr('Unique Point ID Field'), + self.tr('Input unique ID field'), None, self.POINTS, optional=False)) self.addParameter(QgsProcessingParameterEnum(self.STRATEGY, - self.tr('Optimization Criterion'), + self.tr('Path type to calculate'), self.STRATEGIES, defaultValue=0)) @@ -174,7 +174,7 @@ def initAlgorithm(self, config=None): params.append(QgsProcessingParameterNumber(self.TOLERANCE, self.tr('Topology tolerance'), QgsProcessingParameterNumber.Double, - 0.0, False, 0, 99999999.99)) + 0.00001, False, 0, 99999999.99)) for p in params: p.setFlags(p.flags() | QgsProcessingParameterDefinition.FlagAdvanced) @@ -188,7 +188,7 @@ def processAlgorithm(self, parameters, context, feedback): points = self.parameterAsSource(parameters, self.POINTS, context) #QgsProcessingFeatureSource id_field = self.parameterAsString(parameters, self.ID_FIELD, context) #str strategy = self.parameterAsEnum(parameters, self.STRATEGY, context) #int - + entry_cost_calc_method = self.parameterAsEnum(parameters, self.ENTRY_COST_CALCULATION_METHOD, context) #int directionFieldName = self.parameterAsString(parameters, self.DIRECTION_FIELD, context) #str (empty if no field given) forwardValue = self.parameterAsString(parameters, self.VALUE_FORWARD, context) #str @@ -198,35 +198,35 @@ def processAlgorithm(self, parameters, context, feedback): speedFieldName = self.parameterAsString(parameters, self.SPEED_FIELD, context) #str defaultSpeed = self.parameterAsDouble(parameters, self.DEFAULT_SPEED, context) #float tolerance = self.parameterAsDouble(parameters, self.TOLERANCE, context) #float - + analysisCrs = network.sourceCrs() - + feedback.pushInfo("[QNEAT3Algorithm] Building Graph...") net = Qneat3Network(network, points, strategy, directionFieldName, forwardValue, backwardValue, bothValue, defaultDirection, analysisCrs, speedFieldName, defaultSpeed, tolerance, feedback) - + 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))] - + feat = QgsFeature() fields = QgsFields() output_id_field_data_type = getFieldDatatype(points, id_field) - fields.append(QgsField('origin_id', output_id_field_data_type, '', 254, 0)) - fields.append(QgsField('destination_id', output_id_field_data_type, '', 254, 0)) + fields.append(QgsField('InputID', output_id_field_data_type, '', 254, 0)) + fields.append(QgsField('TargetID', output_id_field_data_type, '', 254, 0)) fields.append(QgsField('entry_cost', QVariant.Double, '', 20,7)) fields.append(QgsField('network_cost', QVariant.Double, '', 20, 7)) fields.append(QgsField('exit_cost', QVariant.Double, '', 20,7)) fields.append(QgsField('total_cost', QVariant.Double, '', 20,7)) feat.setFields(fields) - + (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, fields, QgsWkbTypes.NoGeometry, network.sourceCrs()) - + total_workload = float(pow(len(list_analysis_points),2)) feedback.pushInfo("[QNEAT3Algorithm] Expecting total workload of {} iterations".format(int(total_workload))) - - + + current_workstep_number = 0 - + for start_point in list_analysis_points: #optimize in case of undirected (not necessary to call calcDijkstra as it has already been calculated - can be replaced by reading from list) dijkstra_query = net.calcDijkstra(start_point.network_vertex_id, 0) @@ -234,32 +234,31 @@ def processAlgorithm(self, parameters, context, feedback): if (current_workstep_number%1000)==0: feedback.pushInfo("[QNEAT3Algorithm] {} OD-pairs processed...".format(current_workstep_number)) if query_point.point_id == start_point.point_id: - feat['origin_id'] = start_point.point_id - feat['destination_id'] = query_point.point_id + feat['InputID'] = start_point.point_id + feat['TargetID'] = query_point.point_id feat['network_cost'] = 0.0 sink.addFeature(feat, QgsFeatureSink.FastInsert) elif dijkstra_query[0][query_point.network_vertex_id] == -1: - feat['origin_id'] = start_point.point_id - feat['destination_id'] = query_point.point_id + feat['InputID'] = start_point.point_id + feat['TargetID'] = query_point.point_id #do not populate cost field so that it defaults to null sink.addFeature(feat, QgsFeatureSink.FastInsert) else: network_cost = dijkstra_query[1][query_point.network_vertex_id] - feat['origin_id'] = start_point.point_id - feat['destination_id'] = query_point.point_id + feat['InputID'] = start_point.point_id + feat['TargetID'] = query_point.point_id feat['entry_cost'] = start_point.entry_cost feat['network_cost'] = network_cost feat['exit_cost'] = query_point.entry_cost feat['total_cost'] = start_point.entry_cost + network_cost + query_point.entry_cost - sink.addFeature(feat, QgsFeatureSink.FastInsert) + sink.addFeature(feat, QgsFeatureSink.FastInsert) current_workstep_number=current_workstep_number+1 feedback.setProgress(current_workstep_number/total_workload) - + feedback.pushInfo("[QNEAT3Algorithm] Total number of OD-pairs processed: {}".format(current_workstep_number)) - + feedback.pushInfo("[QNEAT3Algorithm] Ending Algorithm") results = {} results[self.OUTPUT] = dest_id return results - diff --git a/algs/ShortestPathBetweenPoints.py b/algs/ShortestPathBetweenPoints.py index 89e3e6f..afda8a3 100644 --- a/algs/ShortestPathBetweenPoints.py +++ b/algs/ShortestPathBetweenPoints.py @@ -3,10 +3,10 @@ *************************************************************************** ShortestPathPointToPoint.py --------------------- - - Partially based on QGIS3 network analysis algorithms. - Copyright 2016 Alexander Bruy - + + Partially based on QGIS3 network analysis algorithms. + Copyright 2016 Alexander Bruy + Date : February 2018 Copyright : (C) 2018 by Clemens Raffler Email : clemens dot raffler at gmail dot com @@ -86,13 +86,13 @@ def group(self): def groupId(self): return 'networkanalysis' - + def name(self): return 'shortestpathpointtopoint' def displayName(self): return self.tr('Shortest path (point to point)') - + def shortHelpString(self): return "General:
"\ "This algorithm implements the Dijkstra-Search to return the shortest path between two points on a given network dataset.
"\ @@ -100,14 +100,14 @@ def shortHelpString(self): "separate entry- and exit-costs. Distances are measured accounting for ellipsoids.

"\ "Parameters (required):
"\ "Following Parameters must be set to run the algorithm:"\ - "
"\ + "
"\ "Parameters (optional):
"\ "There are also a number of optional parameters to implement direction dependent shortest paths and provide information on speeds on the networks edges."\ "
"\ "Output:
"\ "The output of the algorithm is a Layer containing a single linestring, the attributes showcase the"\ "" - + def msg(self, var): return "Type:"+str(type(var))+" repr: "+var.__str__() @@ -120,13 +120,13 @@ def initAlgorithm(self, config=None): (self.tr('Backward direction'), QgsVectorLayerDirector.DirectionBackward), (self.tr('Both directions'), QgsVectorLayerDirector.DirectionBoth)]) - self.STRATEGIES = [self.tr('Shortest Path (distance optimization)'), - self.tr('Fastest Path (time optimization)') + self.STRATEGIES = [self.tr('Shortest distance'), + self.tr('Fastest time') ] self.ENTRY_COST_CALCULATION_METHODS = [self.tr('Ellipsoidal'), self.tr('Planar (only use with projected CRS)')] - + self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT, self.tr('Network Layer'), @@ -136,7 +136,7 @@ def initAlgorithm(self, config=None): self.addParameter(QgsProcessingParameterPoint(self.END_POINT, self.tr('End point'))) self.addParameter(QgsProcessingParameterEnum(self.STRATEGY, - self.tr('Optimization Criterion'), + self.tr('Path type to calculate'), self.STRATEGIES, defaultValue=0)) @@ -175,7 +175,7 @@ def initAlgorithm(self, config=None): params.append(QgsProcessingParameterNumber(self.TOLERANCE, self.tr('Topology tolerance'), QgsProcessingParameterNumber.Double, - 0.0, False, 0, 99999999.99)) + 0.00001, False, 0, 99999999.99)) for p in params: p.setFlags(p.flags() | QgsProcessingParameterDefinition.FlagAdvanced) @@ -204,43 +204,43 @@ def processAlgorithm(self, parameters, context, feedback): tolerance = self.parameterAsDouble(parameters, self.TOLERANCE, context) #float analysisCrs = network.sourceCrs() - + input_qgspointxy_list = [startPoint,endPoint] input_points = [getFeatureFromPointParameter(startPoint),getFeatureFromPointParameter(endPoint)] - + feedback.pushInfo(self.tr('[QNEAT3Algorithm] Building Graph')) feedback.setProgress(10) net = Qneat3Network(network, input_qgspointxy_list, strategy, directionFieldName, forwardValue, backwardValue, bothValue, defaultDirection, analysisCrs, speedFieldName, defaultSpeed, tolerance, feedback) feedback.setProgress(40) - + list_analysis_points = [Qneat3AnalysisPoint("point", feature, "point_id", net, net.list_tiedPoints[i], entry_cost_calc_method, feedback) for i, feature in enumerate(input_points)] - + start_vertex_idx = list_analysis_points[0].network_vertex_id end_vertex_idx = list_analysis_points[1].network_vertex_id - + feedback.pushInfo("[QNEAT3Algorithm] Calculating shortest path...") feedback.setProgress(50) - + dijkstra_query = net.calcDijkstra(start_vertex_idx,0) - + if dijkstra_query[0][end_vertex_idx] == -1: raise QgsProcessingException(self.tr('Could not find a path from start point to end point - Check your graph or alter the input points.')) - + path_elements = [list_analysis_points[1].point_geom] #start route with the endpoint outside the network - path_elements.append(net.network.vertex(end_vertex_idx).point()) #then append the corresponding vertex of the graph - + path_elements.append(net.network.vertex(end_vertex_idx).point()) #then append the corresponding vertex of the graph + count = 1 current_vertex_idx = end_vertex_idx while current_vertex_idx != start_vertex_idx: current_vertex_idx = net.network.edge(dijkstra_query[0][current_vertex_idx]).fromVertex() path_elements.append(net.network.vertex(current_vertex_idx).point()) - - + + count = count + 1 if count%10 == 0: feedback.pushInfo("[QNEAT3Algorithm] Taversed {} Nodes...".format(count)) - - path_elements.append(list_analysis_points[0].point_geom) #end path with startpoint outside the network + + path_elements.append(list_analysis_points[0].point_geom) #end path with startpoint outside the network feedback.pushInfo("[QNEAT3Algorithm] Total number of Nodes traversed: {}".format(count+1)) path_elements.reverse() #reverse path elements because it was built from end to start @@ -248,39 +248,34 @@ def processAlgorithm(self, parameters, context, feedback): end_exit_cost = list_analysis_points[1].entry_cost cost_on_graph = dijkstra_query[1][end_vertex_idx] total_cost = start_entry_cost + cost_on_graph + end_exit_cost - + feedback.pushInfo("[QNEAT3Algorithm] Writing path-feature...") feedback.setProgress(80) feat = QgsFeature() - + fields = QgsFields() - fields.append(QgsField('start_id', QVariant.String, '', 254, 0)) - fields.append(QgsField('start_coordinates', QVariant.String, '', 254, 0)) + fields.append(QgsField('start', QVariant.String, '', 254, 0)) fields.append(QgsField('start_entry_cost', QVariant.Double, '', 20, 7)) - fields.append(QgsField('end_id', QVariant.String, '', 254, 0)) - fields.append(QgsField('end_coordinates', QVariant.String, '', 254, 0)) + fields.append(QgsField('end', QVariant.String, '', 254, 0)) fields.append(QgsField('end_exit_cost', QVariant.Double, '', 20, 7)) fields.append(QgsField('cost_on_graph', QVariant.Double, '', 20, 7)) fields.append(QgsField('total_cost', QVariant.Double, '', 20, 7)) feat.setFields(fields) - + (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, fields, QgsWkbTypes.LineString, network.sourceCrs()) - - feat['start_id'] = "A" - feat['start_coordinates'] = startPoint.toString() + + feat['start'] = startPoint.toString() feat['start_entry_cost'] = start_entry_cost - feat['end_id'] = "B" - feat['end_coordinates'] = endPoint.toString() + feat['end'] = endPoint.toString() feat['end_exit_cost'] = end_exit_cost feat['cost_on_graph'] = cost_on_graph - feat['total_cost'] = total_cost + feat['total_cost'] = total_cost geom = QgsGeometry.fromPolylineXY(path_elements) feat.setGeometry(geom) - + sink.addFeature(feat, QgsFeatureSink.FastInsert) - feedback.pushInfo("[QNEAT3Algorithm] Ending Algorithm") + feedback.pushInfo("[QNEAT3Algorithm] Ending Algorithm") feedback.setProgress(100) results = {} results[self.OUTPUT] = dest_id return results -