def prepareAlgorithm(self, parameters, context, feedback): #pylint: disable=unused-argument,missing-docstring self.length = self.parameterAsDouble(parameters, self.LENGTH, context) dynamic = QgsProcessingParameters.isDynamic(parameters, self.LENGTH) self.length_property = parameters[self.LENGTH] if dynamic else None return True
def prepareAlgorithm(self, parameters, context, feedback): self.m_value = self.parameterAsDouble(parameters, self.M_VALUE, context) self.dynamic_m = QgsProcessingParameters.isDynamic( parameters, self.M_VALUE) if self.dynamic_m: self.m_property = parameters[self.M_VALUE] return True
def registerDynamicParameterAsDouble(self, parameters, name, context): """ Register a dynamic parameter of type double with name `name` """ param_default = self.parameterAsDouble(parameters, name, context) dynamic = QgsProcessingParameters.isDynamic(parameters, name) param_property = parameters[name] if dynamic else None self.dynamic_parameters[name] = (param_property, param_default)
def prepareAlgorithm(self, parameters, context, feedback): self.m_value = self.parameterAsDouble(parameters, self.M_VALUE, context) self.dynamic_m = QgsProcessingParameters.isDynamic(parameters, self.M_VALUE) if self.dynamic_m: self.m_property = parameters[self.M_VALUE] return True
def processAlgorithm(self, parameters, context, feedback): source = self.parameterAsSource(parameters, self.INPUT, context) if source is None: raise QgsProcessingException( self.invalidSourceError(parameters, self.INPUT)) strategy = self.parameterAsEnum(parameters, self.STRATEGY, context) if self.MIN_DISTANCE in parameters and parameters[ self.MIN_DISTANCE] is not None: minDistance = self.parameterAsDouble(parameters, self.MIN_DISTANCE, context) else: minDistance = None expressionContext = self.createExpressionContext( parameters, context, source) dynamic_value = QgsProcessingParameters.isDynamic(parameters, "VALUE") value_property = None if self.EXPRESSION in parameters and parameters[ self.EXPRESSION] is not None: expression = QgsExpression( self.parameterAsString(parameters, self.EXPRESSION, context)) value = None if expression.hasParserError(): raise QgsProcessingException(expression.parserErrorString()) expression.prepare(expressionContext) else: expression = None if dynamic_value: value_property = parameters["VALUE"] value = self.parameterAsDouble(parameters, self.VALUE, context) fields = QgsFields() fields.append(QgsField('id', QVariant.Int, '', 10, 0)) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, fields, QgsWkbTypes.Point, source.sourceCrs(), QgsFeatureSink.RegeneratePrimaryKey) if sink is None: raise QgsProcessingException( self.invalidSinkError(parameters, self.OUTPUT)) da = QgsDistanceArea() da.setSourceCrs(source.sourceCrs(), context.transformContext()) da.setEllipsoid(context.project().ellipsoid()) total = 100.0 / source.featureCount() if source.featureCount() else 0 current_progress = 0 pointId = 0 for current, f in enumerate(source.getFeatures()): if feedback.isCanceled(): break if not f.hasGeometry(): continue current_progress = total * current feedback.setProgress(current_progress) this_value = value if value_property is not None or expression is not None: expressionContext.setFeature(f) if value_property: this_value, _ = value_property.valueAsDouble( expressionContext, value) else: this_value = expression.evaluate(expressionContext) if expression.hasEvalError(): feedback.pushInfo( self.tr('Evaluation error for feature ID {}: {}'). format(f.id(), expression.evalErrorString())) continue fGeom = f.geometry() engine = QgsGeometry.createGeometryEngine(fGeom.constGet()) engine.prepareGeometry() bbox = fGeom.boundingBox() if strategy == 0: pointCount = int(this_value) else: pointCount = int(round(this_value * da.measureArea(fGeom))) if pointCount == 0: feedback.pushInfo( "Skip feature {} as number of points for it is 0.".format( f.id())) continue index = None if minDistance: index = QgsSpatialIndex() points = dict() nPoints = 0 nIterations = 0 maxIterations = pointCount * 200 feature_total = total / pointCount if pointCount else 1 random.seed() while nIterations < maxIterations and nPoints < pointCount: if feedback.isCanceled(): break rx = bbox.xMinimum() + bbox.width() * random.random() ry = bbox.yMinimum() + bbox.height() * random.random() p = QgsPointXY(rx, ry) geom = QgsGeometry.fromPointXY(p) if engine.contains(geom.constGet()) and \ (not minDistance or vector.checkMinDistance(p, index, minDistance, points)): f = QgsFeature(nPoints) f.initAttributes(1) f.setFields(fields) f.setAttribute('id', pointId) f.setGeometry(geom) sink.addFeature(f, QgsFeatureSink.FastInsert) if minDistance: index.addFeature(f) points[nPoints] = p nPoints += 1 pointId += 1 feedback.setProgress(current_progress + int(nPoints * feature_total)) nIterations += 1 if nPoints < pointCount: feedback.pushInfo( self.tr('Could not generate requested number of random ' 'points. Maximum number of attempts exceeded.')) feedback.setProgress(100) return {self.OUTPUT: dest_id}
def processAlgorithm(self, parameters, context, feedback): #pylint: disable=unused-argument,missing-docstring layer = self.parameterAsSource(parameters, self.INPUT, context) from_node_field = self.parameterAsString(parameters, self.FROM_NODE_FIELD, context) to_node_field = self.parameterAsString(parameters, self.TO_NODE_FIELD, context) cost_default = self.parameterAsDouble(parameters, self.COST, context) dynamic = QgsProcessingParameters.isDynamic(parameters, self.COST) cost_property = parameters[self.COST] if dynamic else None (sink, dest_id) = self.parameterAsSink( parameters, self.OUTPUT, context, layer.fields(), layer.wkbType(), layer.sourceCrs()) feedback.setProgressText(self.tr('Build Upward Index ...')) # forwardtracks = { nb: list(segment, na, cost) } forwardtracks = defaultdict(list) total = 100.0 / layer.featureCount() if layer.featureCount() else 0 anodes = set() for current, feature in enumerate(layer.getFeatures()): # toi = feature.attribute('TOI') # if toi == 0: # continue context.expressionContext().setFeature(feature) a = feature.attribute(from_node_field) b = feature.attribute(to_node_field) if dynamic: value, ok = cost_property.valueAsDouble(context.expressionContext(), cost_default) cost = value if ok else cost_default else: cost = cost_default forwardtracks[b].append((feature.id(), a, cost)) anodes.add(a) feedback.setProgress(int(current * total)) feedback.setProgressText(self.tr('Walk up from Outlets to Sources ...')) # backtracks = { ba: segment, nb, cost } backtracks = dict() sources = list() stack = list(set(forwardtracks.keys()) - anodes) del anodes while stack: if feedback.isCanceled(): break nb = stack.pop() if nb in backtracks: sb, nbb, cost = backtracks[nb] else: cost = 0.0 for segment, na, step_cost in forwardtracks[nb]: new_cost = cost + step_cost if na in backtracks: sa, nba, costa = backtracks[na] if new_cost < costa: backtracks[na] = (segment, nb, new_cost) else: backtracks[na] = (segment, nb, new_cost) if na in forwardtracks: stack.append(na) else: sources.append(na) feedback.setProgressText(self.tr('Select main drain ...')) current = 0 segments = set() for source in sources: if feedback.isCanceled(): break na = source while na in backtracks: if feedback.isCanceled(): break segment, nb, cost = backtracks[na] if segment not in segments: # feature = network.getFeatures(QgsFeatureRequest(segment)).next() segments.add(segment) current = current + 1 feedback.setProgress(int(current * total)) na = nb feedback.setProgressText(self.tr('Export selected features ...')) request = QgsFeatureRequest().setFilterFids([fid for fid in segments]) total = 100.0 / len(segments) if segments else 0 for current, feature in enumerate(layer.getFeatures(request)): sink.addFeature(feature) feedback.setProgress(int(current*total)) return { self.OUTPUT: dest_id }
def processAlgorithm(self, parameters, context, feedback): source = self.parameterAsSource(parameters, self.INPUT, context) expressionContext = self.createExpressionContext( parameters, context, source) x_expression = self.parameterAsString(parameters, self.XEXPRESSION, context) x_expression = QgsExpression(x_expression) if x_expression.hasParserError(): x_expression.prepare(expressionContext) raise QgsProcessingException(x_expression.parserErrorString()) y_expression = self.parameterAsString(parameters, self.YEXPRESSION, context) y_expression = QgsExpression(y_expression) if y_expression.hasParserError(): y_expression.prepare(expressionContext) raise QgsProcessingException(y_expression.parserErrorString()) size = self.parameterAsDouble(parameters, self.SIZE, context) size_property = None if QgsProcessingParameters.isDynamic(parameters, "SIZE"): size_property = parameters["SIZE"] color = self.parameterAsColor(parameters, self.COLOR, context) color_property = None if QgsProcessingParameters.isDynamic(parameters, "COLOR"): color_property = parameters["COLOR"] facet_row = self.parameterAsString(parameters, self.FACET_ROW, context) facet_row_expression = QgsExpression(facet_row) if facet_row and facet_row_expression.hasParserError(): facet_row_expression.prepare(expressionContext) raise QgsProcessingException( facet_row_expression.parserErrorString()) facet_col = self.parameterAsString(parameters, self.FACET_COL, context) facet_col_expression = QgsExpression(facet_col) if facet_col and facet_col_expression.hasParserError(): facet_col_expression.prepare(expressionContext) raise QgsProcessingException( facet_col_expression.parserErrorString()) offline = self.parameterAsBool(parameters, self.OFFLINE, context) if offline is not True: offline = 'cdn' output_html = self.parameterAsFileOutput(parameters, self.OUTPUT_HTML_FILE, context) output_json = self.parameterAsFileOutput(parameters, self.OUTPUT_JSON_FILE, context) colnames = ['x', 'y', 'customdata'] data = [] request = QgsFeatureRequest() request.setFlags(QgsFeatureRequest.NoGeometry) for current, f in enumerate(source.getFeatures(request)): tl = [] expressionContext.setFeature(f) x_val = x_expression.evaluate(expressionContext) y_val = y_expression.evaluate(expressionContext) ids = f.id() tl.append(x_val) tl.append(y_val) tl.append(ids) if facet_row: facet_row_val = facet_row_expression.evaluate( expressionContext) tl.append(facet_row_val) if facet_col: facet_col_val = facet_col_expression.evaluate( expressionContext) tl.append(facet_col_val) if size_property: the_size, _ = size_property.valueAsDouble( expressionContext, size) tl.append(the_size) if color_property: the_color, _ = color_property.value(expressionContext, color) tl.append(the_color) data.append(tl) if facet_row: colnames.append('facet_row') if facet_col: colnames.append('facet_col') if size_property: colnames.append('size') if color_property: colnames.append('color') df = pd.DataFrame(data=data, columns=colnames) feedback.pushDebugInfo(f'{df}') fig = px.scatter(df, x='x', y='y', size='size' if size_property else None, color='color' if color_property else None, facet_row="facet_row" if facet_row else None, facet_col="facet_col" if facet_col else None) if size_property is None: fig.update_traces(marker_size=size) if color_property is None: fig.update_traces(marker_color=color.name()) fig.update_layout(showlegend=True) results = {} fig.write_html(output_html, include_plotlyjs=offline) results[self.OUTPUT_HTML_FILE] = output_html if output_json: fig.write_json(output_json, pretty=True) results[self.OUTPUT_JSON_FILE] = output_json return results