def testFilter(self):
        """ test calculating aggregate with filter """

        layer = QgsVectorLayer("Point?field=fldint:integer", "layer", "memory")
        pr = layer.dataProvider()

        int_values = [4, 2, 3, 2, 5, None, 8]

        features = []
        for v in int_values:
            f = QgsFeature()
            f.setFields(layer.fields())
            f.setAttributes([v])
            features.append(f)
        assert pr.addFeatures(features)

        agg = QgsAggregateCalculator(layer)

        filter_string = "fldint > 2"
        agg.setFilter(filter_string)
        self.assertEqual(agg.filter(), filter_string)

        val, ok = agg.calculate(QgsAggregateCalculator.Sum, 'fldint')
        self.assertTrue(ok)
        self.assertEqual(val, 20)

        # remove filter and retest
        agg.setFilter(None)
        val, ok = agg.calculate(QgsAggregateCalculator.Sum, 'fldint')
        self.assertTrue(ok)
        self.assertEqual(val, 24)
    def testFilter(self):
        """ test calculating aggregate with filter """

        layer = QgsVectorLayer("Point?field=fldint:integer", "layer", "memory")
        pr = layer.dataProvider()

        int_values = [4, 2, 3, 2, 5, None, 8]

        features = []
        for v in int_values:
            f = QgsFeature()
            f.setFields(layer.fields())
            f.setAttributes([v])
            features.append(f)
        assert pr.addFeatures(features)

        agg = QgsAggregateCalculator(layer)

        filter_string = "fldint > 2"
        agg.setFilter(filter_string)
        self.assertEqual(agg.filter(), filter_string)

        val, ok = agg.calculate(QgsAggregateCalculator.Sum, 'fldint')
        self.assertTrue(ok)
        self.assertEqual(val, 20)

        # remove filter and retest
        agg.setFilter(None)
        val, ok = agg.calculate(QgsAggregateCalculator.Sum, 'fldint')
        self.assertTrue(ok)
        self.assertEqual(val, 24)
    def end_edit_group(self):
        if not self.pending_affected_districts:
            super().end_edit_group()
            return

        # step 1: get all electorate features corresponding to affected electorates
        electorate_features = {f[self.electorate_layer_field]: f for f in
                               self.get_affected_districts([self.electorate_layer_field])}

        # and update the electorate boundaries based on these changes.
        # Ideally we'd redissolve the whole boundary from meshblocks, but that's too
        # slow. So instead we adjust piece-by-piece by adding or chomping away
        # the affected meshblocks only.
        new_geometries = {}
        new_attributes = {}
        for district in self.pending_affected_districts.keys():  # pylint: disable=consider-iterating-dictionary
            district_geometry = electorate_features[district].geometry()
            # add new bits
            district_geometry = self.grow_district_with_added_meshblocks(district, district_geometry)
            # minus lost bits
            district_geometry = self.shrink_district_by_removed_meshblocks(district, district_geometry)

            new_geometries[electorate_features[district].id()] = district_geometry

            calc = QgsAggregateCalculator(self.target_layer)
            calc.setFilter(QgsExpression.createFieldEqualityExpression(self.target_field, district))
            estimated_pop, ok = calc.calculate(QgsAggregateCalculator.Sum,  # pylint: disable=unused-variable
                                               self.offline_pop_field)

            new_attributes[electorate_features[district].id()] = {self.estimated_pop_idx: estimated_pop,
                                                                  self.stats_nz_pop_field_index: NULL,
                                                                  self.stats_nz_var_20_field_index: NULL,
                                                                  self.stats_nz_var_23_field_index: NULL,
                                                                  self.invalid_field_index: NULL,
                                                                  self.invalid_reason_field_index: NULL}
        self.electorate_changes_queue.push_changes(new_attributes, new_geometries)

        self.user_log_layer.dataProvider().addFeatures(self.pending_log_entries)

        self.electorate_changes_queue.blocked = True
        super().end_edit_group()
        self.electorate_changes_queue.blocked = False

        self.pending_affected_districts = {}
        self.pending_log_entries = []
        self.redistrict_occured.emit()
Example #4
0
    def paint(self, painter, option, widget):  # pylint: disable=missing-docstring, unused-argument, too-many-locals
        if self.image is not None:
            painter.drawImage(0, 0, self.image)
            return

        image_size = self.canvas.mapSettings().outputSize()
        self.image = QImage(image_size.width(), image_size.height(),
                            QImage.Format_ARGB32)
        self.image.fill(0)
        image_painter = QPainter(self.image)
        render_context = QgsRenderContext.fromQPainter(image_painter)

        image_painter.setRenderHint(QPainter.Antialiasing, True)

        rect = self.canvas.mapSettings().visibleExtent()
        request = QgsFeatureRequest()
        request.setFilterRect(rect)
        request.setFilterExpression(
            QgsExpression.createFieldEqualityExpression('type', self.task))

        for f in self.electorate_layer.getFeatures(request):
            #    pole, dist = f.geometry().clipped(rect).poleOfInaccessibility(rect.width() / 30)
            pixel = self.toCanvasCoordinates(
                f.geometry().clipped(rect).centroid().asPoint())

            calc = QgsAggregateCalculator(self.meshblock_layer)
            calc.setFilter('staged_electorate={}'.format(f['electorate_id']))
            estimated_pop, ok = calc.calculate(QgsAggregateCalculator.Sum,
                                               'offline_pop_{}'.format(
                                                   self.task.lower()))  # pylint: disable=unused-variable

            text_string = [
                '{}'.format(f['name']), '{}'.format(int(estimated_pop))
            ]
            QgsTextRenderer().drawText(QPointF(pixel.x(), pixel.y()), 0,
                                       QgsTextRenderer.AlignCenter,
                                       text_string, render_context,
                                       self.text_format)

        image_painter.end()

        painter.drawImage(0, 0, self.image)