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
Esempio n. 2
0
 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)
Esempio n. 4
0
 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}
Esempio n. 6
0
    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
        }
Esempio n. 7
0
    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