Skip to content
59 changes: 29 additions & 30 deletions algs/IsoAreaAsContoursFromLayer.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 "<b>General:</b><br>"\
"This algorithm implements iso-area contours to return the <b>isochrone areas for a maximum cost level and interval levels </b> on a given <b>network dataset for a layer of points</b>.<br>"\
"It accounts for <b>points outside of the network</b> (eg. <i>non-network-elements</i>) and increments the iso-areas cost regarding to distance/default speed value. Distances are measured accounting for <b>ellipsoids</b>.<br>Please, <b>only use a projected coordinate system (eg. no WGS84)</b> for this kind of analysis.<br><br>"\
"<b>Parameters (required):</b><br>"\
"Following Parameters must be set to run the algorithm:"\
"<ul><li>Network Layer</li><li>Startpoint Layer</li><li>Unique Point ID Field (numerical)</li><li>Maximum cost level for Iso-Area</li><li>Cost Intervals for Iso-Area Bands</li><li>Cellsize in Meters (increase default when analyzing larger networks)</li><li>Cost Strategy</li></ul><br>"\
"<ul><li>Network Layer</li><li>Startpoint Layer</li><li>Unique Point ID Field (numerical)</li><li>Maximum cost level of Iso-Area in distance (meters) or time (seconds)</li><li>Contour Intervals in distance (meters) or time (seconds)</li><li>Cellsize in Meters (increase default when analyzing larger networks)</li><li>Path type to calculate</li></ul><br>"\
"<b>Parameters (optional):</b><br>"\
"There are also a number of <i>optional parameters</i> to implement <b>direction dependent</b> shortest paths and provide information on <b>speeds</b> on the networks edges."\
"<ul><li>Direction Field</li><li>Value for forward direction</li><li>Value for backward direction</li><li>Value for both directions</li><li>Default direction</li><li>Speed Field</li><li>Default Speed (affects entry/exit costs)</li><li>Topology tolerance</li></ul><br>"\
"<b>Output:</b><br>"\
"The output of the algorithm are two layers:"\
"<ul><li>TIN-Interpolation Distance Raster</li><li>Iso-Area Contours with cost levels as attributes</li></ul>"

def msg(self, var):
return "Type:"+str(type(var))+" repr: "+var.__str__()

Expand All @@ -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'),
Expand All @@ -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,
Expand All @@ -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))

Expand Down Expand Up @@ -191,15 +191,15 @@ 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_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
Expand All @@ -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

55 changes: 27 additions & 28 deletions algs/IsoAreaAsContoursFromPoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -88,7 +88,7 @@ def group(self):

def groupId(self):
return 'isoareas'

def name(self):
return 'isoareaascontoursfrompoint'

Expand All @@ -101,15 +101,15 @@ def shortHelpString(self):
"It accounts for <b>points outside of the network</b> (eg. <i>non-network-elements</i>) and increments the isochrone areas cost regarding to distance/default speed value. Distances are measured accounting for <b>ellipsoids</b>.<br>Please, <b>only use a projected coordinate system (eg. no WGS84)</b> for this kind of analysis.<br><br>"\
"<b>Parameters (required):</b><br>"\
"Following Parameters must be set to run the algorithm:"\
"<ul><li>Network Layer</li><li>Startpoint</li><li>Maximum cost level for Iso-Area</li><li>Cost Intervals for Iso-Area Bands</li><li>Cellsize in Meters (increase default when analyzing larger networks)</li><li>Cost Strategy</li></ul><br>"\
"<ul><li>Network Layer</li><li>Startpoint</li><li>Maximum cost level of Iso-Area in distance (meters) or time (seconds)</li><li>Contour Intervals in distance (meters) or time (seconds)</li><li>Cellsize in Meters (increase default when analyzing larger networks)</li><li>Path type to calculate</li></ul><br>"\
"<b>Parameters (optional):</b><br>"\
"There are also a number of <i>optional parameters</i> to implement <b>direction dependent</b> shortest paths and provide information on <b>speeds</b> on the networks edges."\
"<ul><li>Direction Field</li><li>Value for forward direction</li><li>Value for backward direction</li><li>Value for both directions</li><li>Default direction</li><li>Speed Field</li><li>Default Speed (affects entry/exit costs)</li><li>Topology tolerance</li></ul><br>"\
"<b>Output:</b><br>"\
"The output of the algorithm are two layers:"\
"<ul><li>TIN-Interpolation Distance Raster</li><li>Iso-Area Contours with cost levels as attributes</li></ul>"


def msg(self, var):
return "Type:"+str(type(var))+" repr: "+var.__str__()

Expand All @@ -122,20 +122,20 @@ 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'),
[QgsProcessing.TypeVectorLine]))
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,
Expand All @@ -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))

Expand Down Expand Up @@ -186,15 +186,15 @@ 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_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
Expand All @@ -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

Loading