def finish_feature_creation(self, layerId, features):
        if len(features) != 1:
            return SpacialSourceFinishFeatureCreationArgs(added_features_amount=len(features))

        fid = features[0].id()

        # editing layer Name?
        if not self.__editing_layer.getFeature(fid).isValid():
            # self.logger.warning(__name__, "Feature not found in layer {}...".format(self.__editing_layer_name))
            # TODO send this info to controller
            return SpacialSourceFinishFeatureCreationArgs(SpacialSourceFinishFeatureCreationArgs(is_valid=False))

        # feature_rrr_id: generic name used for represent id for right, restriction
        # feature_rrr_id = self._layers[self.EDITING_LAYER_NAME].getFeature(fid)[self.names.T_ID_F]
        feature_tid = self.__editing_layer.getFeature(fid)[self.__db.names.T_ID_F]

        administrative_source_ids = LADMData.get_list_of_features_ids(self.__layers[self.names.LC_ADMINISTRATIVE_SOURCE_T], self.names.T_ID_F)

        # Fill rrrfuente table
        new_features = []
        attr_fk = None

        if self.__editing_layer_name == self.names.LC_RIGHT_T:
            attr_fk = self.names.COL_RRR_SOURCE_T_LC_RIGHT_F
        elif self.__editing_layer_name == self.names.LC_RESTRICTION_T:
            attr_fk = self.names.COL_RRR_SOURCE_T_LC_RESTRICTION_F

        new_features = LADMData.save_relations(self.__layers[self.names.COL_RRR_SOURCE_T],
                                               self.names.COL_RRR_SOURCE_T_SOURCE_F,
                                               administrative_source_ids, attr_fk, feature_tid)
        return SpacialSourceFinishFeatureCreationArgs(True, feature_tid, 1, None)
예제 #2
0
    def finish_feature_creation(self, layerId, features):
        if len(features) != 1:
            # TODO send this info to controller
            # message = QCoreApplication.translate("WizardTranslations", "'{}' tool has been closed. We should have got only one {} by we have {}").format(self.WIZARD_TOOL_NAME, self.WIZARD_FEATURE_NAME, len(features))
            # self.logger.warning(__name__, "We should have got only one {}, but we have {}".format(self.WIZARD_FEATURE_NAME, len(features)))
            return SpacialSourceFinishFeatureCreationArgs(
                added_features_amount=len(features))

        feature = features[0]

        if not feature.isValid():
            # TODO send this info to controller
            # self.logger.warning(__name__, "Feature not found in layer Spatial Source...")
            return SpacialSourceFinishFeatureCreationArgs(is_valid=False)

        feature_tid = feature[self.names.T_ID_F]

        feature_ids = LADMData.get_list_of_features_ids(
            self.__layers[self.names.LC_PLOT_T], self.names.T_ID_F)
        new_features = LADMData.save_relations(
            self.__layers[self.names.COL_UE_SOURCE_T],
            self.names.COL_UE_SOURCE_T_LC_PLOT_F, feature_ids,
            self.names.COL_UE_SOURCE_T_SOURCE_F, feature_tid)
        # all_new_features.extend(new_features)
        feature_ids = LADMData.get_list_of_features_ids(
            self.__layers[self.names.LC_BOUNDARY_T], self.names.T_ID_F)

        new_features = LADMData.save_relations(
            self.__layers[self.names.COL_CCL_SOURCE_T],
            self.names.COL_CCL_SOURCE_T_BOUNDARY_F, feature_ids,
            self.names.COL_CCL_SOURCE_T_SOURCE_F, feature_tid)

        feature_ids = LADMData.get_list_of_features_ids(
            self.__layers[self.names.LC_BOUNDARY_POINT_T], self.names.T_ID_F)
        new_features = LADMData.save_relations(
            self.__layers[self.names.COL_POINT_SOURCE_T],
            self.names.COL_POINT_SOURCE_T_LC_BOUNDARY_POINT_F, feature_ids,
            self.names.COL_POINT_SOURCE_T_SOURCE_F, feature_tid)

        feature_ids = LADMData.get_list_of_features_ids(
            self.__layers[self.names.LC_SURVEY_POINT_T], self.names.T_ID_F)
        new_features = LADMData.save_relations(
            self.__layers[self.names.COL_POINT_SOURCE_T],
            self.names.COL_POINT_SOURCE_T_LC_SURVEY_POINT_F, feature_ids,
            self.names.COL_POINT_SOURCE_T_SOURCE_F, feature_tid)

        feature_ids = LADMData.get_list_of_features_ids(
            self.__layers[self.names.LC_CONTROL_POINT_T], self.names.T_ID_F)

        new_features = LADMData.save_relations(
            self.__layers[self.names.COL_POINT_SOURCE_T],
            self.names.COL_POINT_SOURCE_T_LC_CONTROL_POINT_F, feature_ids,
            self.names.COL_POINT_SOURCE_T_SOURCE_F, feature_tid)

        return SpacialSourceFinishFeatureCreationArgs(True, feature_tid, 1,
                                                      None)
예제 #3
0
    def setUp(self):
        restore_schema(SCHEMA_LADM_COL_EMPTY, True)
        self.db_pg = get_pg_conn(SCHEMA_LADM_COL_EMPTY)

        self.names = self.db_pg.names
        self.ladm_data = LADMData()
        self.geometry = GeometryUtils()

        res, code, msg = self.db_pg.test_connection()
        self.assertTrue(res, msg)
        self.assertIsNotNone(self.names.LC_BOUNDARY_POINT_T, 'Names is None')
    def _validate(self, db, db_qr, layer_dict, tolerance, **kwargs):
        self.progress_changed.emit(5)
        ladm_queries = self._get_ladm_queries(db.engine)

        pre_res, pre_obj = self._check_prerrequisite_layers(layer_dict)
        if not pre_res:
            return pre_obj

        error_state = None

        # Check boundary point with duplicate records
        table = db.names.LC_BOUNDARY_POINT_T
        fields = [
            db.names.LC_BOUNDARY_POINT_T_AGREEMENT_F,
            db.names.LC_BOUNDARY_POINT_T_PHOTO_IDENTIFICATION_F,
            db.names.LC_BOUNDARY_POINT_T_VERTICAL_ACCURACY_F,
            db.names.LC_BOUNDARY_POINT_T_HORIZONTAL_ACCURACY_F,
            db.names.COL_POINT_T_INTERPOLATION_POSITION_F,
            db.names.COL_POINT_T_PRODUCTION_METHOD_F,
            db.names.LC_BOUNDARY_POINT_T_POINT_TYPE_F,
            db.names.COL_POINT_T_ORIGINAL_LOCATION_F
        ]

        res, records = ladm_queries.get_duplicate_records_in_table(
            db, table, fields)
        count = len(records)

        self.progress_changed.emit(50)

        if res:
            error_state = LADMData().get_domain_code_from_value(
                db_qr, db_qr.names.ERR_ERROR_STATE_D,
                LADMNames.ERR_ERROR_STATE_D_ERROR_V)
            errors = {'geometries': list(), 'data': list()}
            for record in records:
                error_data = [  # [obj_uuids, rel_obj_uuids, values, details, state]
                    record['duplicate_uuids'].split(','), None, None,
                    'Punto Lindero repetido {} veces'.format(
                        record['duplicate_total']), error_state
                ]
                errors['data'].append(error_data)

            self._save_errors(db_qr, self._ERROR_01, errors)

        self.progress_changed.emit(85)

        if count > 0:
            res_type = EnumQualityRuleResult.ERRORS
            msg = QCoreApplication.translate(
                "QualityRules",
                "{} boundary points with repeated records.").format(count)
        else:
            res_type = EnumQualityRuleResult.SUCCESS
            msg = QCoreApplication.translate(
                "QualityRules", "No duplicate boundary points were found.")

        self.progress_changed.emit(100)

        return QualityRuleExecutionResult(res_type, msg, count)
예제 #5
0
    def _validate(self, db, db_qr, layer_dict, tolerance, **kwargs):
        self.progress_changed.emit(5)
        ladm_queries = self._get_ladm_queries(db.engine)

        pre_res, pre_obj = self._check_prerrequisite_layers(layer_dict)
        if not pre_res:
            return pre_obj

        error_state = None

        # Check administrative source with duplicate records
        table = db.names.LC_ADMINISTRATIVE_SOURCE_T
        fields = [
            db.names.LC_ADMINISTRATIVE_SOURCE_T_EMITTING_ENTITY_F,
            db.names.COL_ADMINISTRATIVE_SOURCE_T_SOURCE_NUMBER_F,
            db.names.COL_ADMINISTRATIVE_SOURCE_T_OBSERVATION_F,
            db.names.LC_ADMINISTRATIVE_SOURCE_T_TYPE_F,
            db.names.COL_SOURCE_T_DATE_DOCUMENT_F,
            db.names.COL_SOURCE_T_AVAILABILITY_STATUS_F,
            db.names.COL_SOURCE_T_MAIN_TYPE_F
        ]

        res, records = ladm_queries.get_duplicate_records_in_table(
            db, table, fields)
        count = len(records)

        self.progress_changed.emit(50)

        if res:
            error_state = LADMData().get_domain_code_from_value(
                db_qr, db_qr.names.ERR_ERROR_STATE_D,
                LADMNames.ERR_ERROR_STATE_D_ERROR_V)
            errors = {'geometries': list(), 'data': list()}
            for record in records:
                error_data = [  # [obj_uuids, rel_obj_uuids, values, details, state]
                    record['duplicate_uuids'].split(','), None, None,
                    'Fuente administrativa repetida {} veces'.format(
                        record['duplicate_total']), error_state
                ]
                errors['data'].append(error_data)

            self._save_errors(db_qr, self._ERROR_01, errors)

        self.progress_changed.emit(85)

        if count > 0:
            res_type = EnumQualityRuleResult.ERRORS
            msg = QCoreApplication.translate(
                "QualityRules", "{} administrative sources "
                "with duplicate records were found.").format(count)
        else:
            res_type = EnumQualityRuleResult.SUCCESS
            msg = QCoreApplication.translate(
                "QualityRules",
                "No duplicate administrative sources were found.")

        self.progress_changed.emit(100)

        return QualityRuleExecutionResult(res_type, msg, count)
    def setUpClass(cls):
        import_qgis_model_baker()
        cls.db_gpkg = get_copy_gpkg_conn('test_ladm_survey_model_gpkg')
        res, code, msg = cls.db_gpkg.test_connection()
        cls.assertTrue(res, msg)

        cls.app = AppInterface()
        cls.ladm_data = LADMData()
예제 #7
0
    def __get_error_state_value(self, state_t_id):
        if state_t_id not in self.__error_state_dict:
            db = self.__qr_engine.get_db_quality()
            self.__error_state_dict[state_t_id] = LADMData(
            ).get_domain_value_from_code(db, db.names.ERR_ERROR_STATE_D,
                                         state_t_id)

        return self.__error_state_dict.get(state_t_id, "")
    def get_dict_automatic_values(db, layer_name, models):
        names = db.names
        ladm_data = LADMData()

        dict_automatic_values = dict()

        for model_key in models:
            if model_key == LADMNames.SURVEY_MODEL_KEY:
                if layer_name == names.LC_BOUNDARY_T:
                    dict_automatic_values = {
                        names.LC_BOUNDARY_T_LENGTH_F: "$length"
                    }
                elif layer_name == names.LC_PARTY_T:
                    dict_automatic_values = {
                        names.LC_PARTY_T_TYPE_F:
                        "{}".format(
                            ladm_data.get_domain_code_from_value(
                                db, names.LC_PARTY_TYPE_D, LADMNames.
                                LC_PARTY_TYPE_D_ILICODE_F_NATURAL_PARTY_V))
                    }
                elif layer_name == names.LC_PARCEL_T:
                    dict_automatic_values = {
                        # names.LC_PARCEL_T_DEPARTMENT_F: 'substr("{}", 0, 2)'.format(names.LC_PARCEL_T_PARCEL_NUMBER_F),
                        # names.LC_PARCEL_T_MUNICIPALITY_F: 'substr("{}", 3, 3)'.format(names.LC_PARCEL_T_PARCEL_NUMBER_F)
                    }
                elif layer_name == names.LC_ADMINISTRATIVE_SOURCE_T:
                    dict_automatic_values = {
                        names.COL_SOURCE_T_MAIN_TYPE_F:
                        "{}".format(
                            ladm_data.get_domain_code_from_value(
                                db, names.CI_CODE_PRESENTATION_FORM_D,
                                LADMNames.
                                CI_CODE_PRESENTATION_FORM_D_DOCUMENT_V))
                    }
            elif model_key == LADMNames.FIELD_DATA_CAPTURE_MODEL_KEY:
                if layer_name == names.FDC_USER_T:
                    dict_automatic_values = {
                        names.FDC_USER_T_DOCUMENT_TYPE_F:
                        "{}".format(
                            ladm_data.get_domain_code_from_value(
                                db, names.FDC_PARTY_DOCUMENT_TYPE_D, LADMNames.
                                FDC_PARTY_DOCUMENT_TYPE_D_ILICODE_F_CC_V))
                    }

        return dict_automatic_values
    def setUpClass(cls):
        print("INFO: Restoring databases to be used")
        restore_schema('test_change_detections')
        cls.db_pg = get_pg_conn('test_change_detections')
        res, code, msg = cls.db_pg.test_connection()
        cls.assertTrue(res, msg)

        cls.app = AppInterface()
        cls.ladm_data = LADMData()
    def _validate(self, db, db_qr, layer_dict, tolerance, **kwargs):
        self.progress_changed.emit(5)
        ladm_queries = self._get_ladm_queries(db.engine)

        pre_res, pre_obj = self._check_prerrequisite_layers(layer_dict)
        if not pre_res:
            return pre_obj

        error_state = None

        # Check building with duplicate records
        table = db.names.LC_BUILDING_T
        fields = [
            db.names.LC_BUILDING_T_BUILDING_VALUATION_F,
            db.names.LC_BUILDING_T_BUILDING_AREA_F,
            db.names.COL_SPATIAL_UNIT_T_DIMENSION_F,
            db.names.COL_SPATIAL_UNIT_T_LABEL_F,
            db.names.COL_SPATIAL_UNIT_T_SURFACE_RELATION_F,
            db.names.COL_SPATIAL_UNIT_T_GEOMETRY_F
        ]

        res, records = ladm_queries.get_duplicate_records_in_table(
            db, table, fields)
        count = len(records)

        self.progress_changed.emit(50)

        if res:
            error_state = LADMData().get_domain_code_from_value(
                db_qr, db_qr.names.ERR_ERROR_STATE_D,
                LADMNames.ERR_ERROR_STATE_D_ERROR_V)
            errors = {'geometries': list(), 'data': list()}
            for record in records:
                error_data = [  # [obj_uuids, rel_obj_uuids, values, details, state]
                    record['duplicate_uuids'].split(','), None, None,
                    'Construcción repetida {} veces'.format(
                        record['duplicate_total']), error_state
                ]
                errors['data'].append(error_data)

            self._save_errors(db_qr, self._ERROR_01, errors)

        self.progress_changed.emit(85)

        if count > 0:
            res_type = EnumQualityRuleResult.ERRORS
            msg = QCoreApplication.translate(
                "QualityRules",
                "{} buildings with repeated records.").format(count)
        else:
            res_type = EnumQualityRuleResult.SUCCESS
            msg = QCoreApplication.translate(
                "QualityRules", "No duplicate buildings were found.")

        self.progress_changed.emit(100)

        return QualityRuleExecutionResult(res_type, msg, count)
    def _validate(self, db, db_qr, layer_dict, tolerance, **kwargs):
        self.progress_changed.emit(5)
        ladm_queries = self._get_ladm_queries(db.engine)

        pre_res, pre_obj = self._check_prerrequisite_layers(layer_dict)
        if not pre_res:
            return pre_obj

        error_state = None

        table = db.names.LC_RIGHT_T
        fields = [
            db.names.LC_RIGHT_T_TYPE_F, db.names.COL_RRR_T_DESCRIPTION_F,
            db.names.COL_RRR_PARTY_T_LC_GROUP_PARTY_F,
            db.names.COL_RRR_PARTY_T_LC_PARTY_F,
            db.names.COL_BAUNIT_RRR_T_UNIT_F
        ]

        res, records = ladm_queries.get_duplicate_records_in_table(
            db, table, fields)
        count = len(records)

        self.progress_changed.emit(50)

        if res:
            error_state = LADMData().get_domain_code_from_value(
                db_qr, db_qr.names.ERR_ERROR_STATE_D,
                LADMNames.ERR_ERROR_STATE_D_ERROR_V)
            errors = {'geometries': list(), 'data': list()}
            for record in records:
                error_data = [  # [obj_uuids, rel_obj_uuids, values, details, state]
                    record['duplicate_uuids'].split(','), None, None,
                    'Derecho repetido {} veces'.format(
                        record['duplicate_total']), error_state
                ]
                errors['data'].append(error_data)

            self._save_errors(db_qr, self._ERROR_01, errors)

        self.progress_changed.emit(85)

        if count > 0:
            res_type = EnumQualityRuleResult.ERRORS
            msg = QCoreApplication.translate(
                "QualityRules", "{} right "
                "with duplicate records were found.").format(count)
        else:
            res_type = EnumQualityRuleResult.SUCCESS
            msg = QCoreApplication.translate("QualityRules",
                                             "No duplicate right were found.")

        self.progress_changed.emit(100)

        return QualityRuleExecutionResult(res_type, msg, count)
예제 #12
0
    def _validate(self, db, db_qr, layer_dict, tolerance, **kwargs):
        self.progress_changed.emit(5)

        point_layer = self._get_layer(layer_dict)
        pre_res, res_obj = self._check_prerrequisite_layer(
            QCoreApplication.translate("QualityRules", "Boundary point"),
            point_layer)
        if not pre_res:
            return res_obj

        overlapping = GeometryUtils.get_overlapping_points(point_layer)
        flat_overlapping = [fid for items in overlapping
                            for fid in items]  # Build a flat list of ids

        self.progress_changed.emit(70)

        dict_uuids = {
            f.id(): f[db.names.T_ILI_TID_F]
            for f in point_layer.getFeatures(flat_overlapping)
        }
        error_state = LADMData().get_domain_code_from_value(
            db_qr, db_qr.names.ERR_ERROR_STATE_D,
            LADMNames.ERR_ERROR_STATE_D_ERROR_V)

        errors = {'geometries': list(), 'data': list()}
        for items in overlapping:
            # We need a feature geometry, pick the first id to get it
            feature = point_layer.getFeature(items[0])
            errors['geometries'].append(feature.geometry())

            error_data = [  # [obj_uuids, rel_obj_uuids, values, details, state]
                [str(dict_uuids.get(i)) for i in items], None,
                json.dumps({"conteo": len(items)}), None, error_state
            ]
            errors['data'].append(error_data)

        self._save_errors(db_qr, self._ERROR_01, errors)

        self.progress_changed.emit(100)

        if len(flat_overlapping) > 0:
            return QualityRuleExecutionResult(
                EnumQualityRuleResult.ERRORS,
                QCoreApplication.translate(
                    "QualityRules",
                    "{} overlapping boundary points were found!").format(
                        len(flat_overlapping)), len(errors['data']))
        else:
            return QualityRuleExecutionResult(
                EnumQualityRuleResult.SUCCESS,
                QCoreApplication.translate(
                    "QualityRules",
                    "There are no overlapping boundary points."))
예제 #13
0
    def __get_error_state_t_id(self, state_value):
        # Use __error_state_dict to read cached values, but this time we have the value,
        # not the key, so check in dict values and if not found, go for its t_id
        if state_value not in self.__error_state_dict.values():
            db = self.__qr_engine.get_db_quality()
            t_id = LADMData().get_domain_code_from_value(
                db, db.names.ERR_ERROR_STATE_D, state_value)
            self.__error_state_dict[t_id] = state_value

        # Get key by value in a dict:
        return next((k for k in self.__error_state_dict
                     if self.__error_state_dict[k] == state_value), None)
예제 #14
0
    def setUpClass(cls):
        # DB with single child model
        cls.db_gpkg = get_copy_gpkg_conn('test_ladm_survey_model_gpkg')
        res, code, msg = cls.db_gpkg.test_connection()
        cls.assertTrue(res, msg)

        # DB with multiple child models and domains
        cls.db_multi_gpkg = get_copy_gpkg_conn('test_ladm_multiple_child_domains_gpkg')
        res, code, msg = cls.db_multi_gpkg.test_connection()
        cls.assertTrue(res, msg)

        cls.app = AppInterface()
        cls.ladm_data = LADMData()
예제 #15
0
    def load_error_results_data(self):
        """
        Go to table and bring data to the dict.
        We should keep this dict updated with changes from the user.
        From time to time we reflect this dict changes in the original data source.
        """
        db = self.__qr_engine.get_db_quality()
        names = db.names

        layers = {names.ERR_QUALITY_ERROR_T: None, names.ERR_RULE_TYPE_T: None}
        self.app.core.get_layers(db, layers, load=False)
        if not layers:
            self.logger.critical(
                __name__,
                "Quality error layers ('{}') not found!".format(",".join(
                    list(layers.keys()))))
            return

        # First go for the selected quality error's t_id
        features = LADMData.get_features_from_t_ids(
            layers[names.ERR_RULE_TYPE_T], names.ERR_RULE_TYPE_T_CODE_F,
            [self.__selected_qr.id()])
        t_id = features[0][names.T_ID_F] if features else None
        if not t_id:
            self.logger.critical(
                __name__, "Quality error rule ('{}') not found!".format(
                    self.__selected_qr.id()))
            return

        # Now go for all features that match the selected quality rule
        features = LADMData.get_features_from_t_ids(
            layers[names.ERR_QUALITY_ERROR_T],
            names.ERR_QUALITY_ERROR_T_RULE_TYPE_F, [t_id])

        self.__error_results_data[self.__selected_qr.id()] = {
            feature[names.T_ID_F]: feature
            for feature in features
        }
    def _validate(self, db, db_qr, layer_dict, tolerance, **kwargs):
        self.progress_changed.emit(5)

        right_of_way_layer = self._get_layer(layer_dict)
        pre_res, res_obj = self._check_prerrequisite_layer(
            QCoreApplication.translate("QualityRules", "Right of way"),
            right_of_way_layer)
        if not pre_res:
            return res_obj

        self.progress_changed.emit(10)
        multi_parts, right_of_way_ids = GeometryUtils.get_multipart_geoms(
            right_of_way_layer)
        self.progress_changed.emit(70)

        error_state = LADMData().get_domain_code_from_value(
            db_qr, db_qr.names.ERR_ERROR_STATE_D,
            LADMNames.ERR_ERROR_STATE_D_ERROR_V)

        errors = {'geometries': list(), 'data': list()}
        if multi_parts:
            for right_of_way_geom, right_of_way_id in zip(
                    multi_parts, right_of_way_ids):
                errors['geometries'].append(right_of_way_geom)
                error_data = [  # [obj_uuids, rel_obj_uuids, values, details, state]
                    [
                        right_of_way_layer.getFeature(right_of_way_id)[
                            db.names.T_ILI_TID_F]
                    ], None, None, self._errors[self._ERROR_01], error_state
                ]
                errors['data'].append(error_data)

            self._save_errors(db_qr, self._ERROR_01, errors)
            self.progress_changed.emit(90)

        count = len(errors['data'])

        if count > 0:
            res_type = EnumQualityRuleResult.ERRORS
            msg = QCoreApplication.translate(
                "QualityRules", "{} rights of way with "
                "multipart geometry were found.").format(count)
        else:
            res_type = EnumQualityRuleResult.SUCCESS
            msg = QCoreApplication.translate(
                "QualityRules", "All rights of way have simple geometry!!")

        self.progress_changed.emit(100)

        return QualityRuleExecutionResult(res_type, msg, count)
def get_field_values_by_key_values(layer, field, field_values, expected_field):
    """
    Returns the fields associated with a field based on another field.
    Same order coming in field_values must be preserved in the returned array.

    :param layer: QgsMapLayer
    :param field: Field name, it must be a unique field in the table
    :param field_values: List of values to use for filtering the layer by field name
    :param expected_field: name of the field from which the values are expected
    :return: List of values associated with the expected field. Order is preserved
    """
    features = LADMData.get_features_from_t_ids(
        layer, field, field_values, only_attributes=[expected_field])

    return [f[expected_field] for f in features]
예제 #18
0
    def _validate(self, db, db_qr, layer_dict, tolerance, **kwargs):
        self.progress_changed.emit(5)
        ladm_queries = self._get_ladm_queries(db.engine)

        pre_res, pre_obj = self._check_prerrequisite_layers(layer_dict)
        if not pre_res:
            return pre_obj

        error_state = None

        # Check parcel with incorrect department code
        res, records = ladm_queries.get_parcels_with_invalid_department_code(
            db)
        count = len(records)

        self.progress_changed.emit(50)

        if res:
            error_state = LADMData().get_domain_code_from_value(
                db_qr, db_qr.names.ERR_ERROR_STATE_D,
                LADMNames.ERR_ERROR_STATE_D_ERROR_V)
            errors = {'geometries': list(), 'data': list()}
            for record in records:
                error_data = [  # [obj_uuids, rel_obj_uuids, values, details, state]
                    [record[db.names.T_ILI_TID_F]], None, None,
                    'El código de departamento de la tabla predio debe tener dos caracteres numéricos',
                    error_state
                ]
                errors['data'].append(error_data)

            self._save_errors(db_qr, self._ERROR_01, errors)

        self.progress_changed.emit(85)

        if count > 0:
            res_type = EnumQualityRuleResult.ERRORS
            msg = QCoreApplication.translate(
                "QualityRules",
                "{} parcels with invalid department code were found.").format(
                    count)
        else:
            res_type = EnumQualityRuleResult.SUCCESS
            msg = QCoreApplication.translate(
                "QualityRules", "All parcels have valid department code.")

        self.progress_changed.emit(100)

        return QualityRuleExecutionResult(res_type, msg, count)
    def _validate(self, db, db_qr, layer_dict, tolerance, **kwargs):
        self.progress_changed.emit(5)

        building_layer = self._get_layer(layer_dict)
        pre_res, res_obj = self._check_prerrequisite_layer(QCoreApplication.translate("QualityRules", "Building"),
                                                           building_layer)
        if not pre_res:
            return res_obj

        overlapping = GeometryUtils.get_overlapping_polygons(self, building_layer)
        flat_overlapping = [fid for items in overlapping for fid in items]  # Build a flat list of ids
        flat_overlapping = list(set(flat_overlapping))  # unique values

        self.progress_changed.emit(70)

        dict_uuids = {f.id(): f[db.names.T_ILI_TID_F] for f in building_layer.getFeatures(flat_overlapping)}
        error_state = LADMData().get_domain_code_from_value(db_qr, db_qr.names.ERR_ERROR_STATE_D,
                                                            LADMNames.ERR_ERROR_STATE_D_ERROR_V)

        errors = {'geometries': list(), 'data': list()}
        for items in overlapping:
            polygon_id_field = items[0]
            overlapping_id_field = items[1]
            polygon_intersection = GeometryUtils.get_intersection_polygons(building_layer, polygon_id_field, overlapping_id_field)

            if polygon_intersection is not None:
                errors['geometries'].append(polygon_intersection)

                error_data = [  # [obj_uuids, rel_obj_uuids, values, details, state]
                    [dict_uuids.get(polygon_id_field)],
                    [dict_uuids.get(overlapping_id_field)],
                    None,
                    self._errors[self._ERROR_01],
                    error_state]
                errors['data'].append(error_data)

        self._save_errors(db_qr, self._ERROR_01, errors)

        if len(flat_overlapping) > 0:
            res_type = EnumQualityRuleResult.ERRORS
            msg = QCoreApplication.translate("QualityRules", "{} overlapping buildings were found!").format(len(flat_overlapping))
        else:
            res_type = EnumQualityRuleResult.SUCCESS
            msg = QCoreApplication.translate("QualityRules", "There are no overlapping buildings!")

        self.progress_changed.emit(100)

        return QualityRuleExecutionResult(res_type, msg, len(flat_overlapping))
예제 #20
0
    def error_type_code_and_display(self, feature):
        db = self.__qr_engine.get_db_quality()
        names = db.names
        layer = self.app.core.get_layer(db, names.ERR_ERROR_TYPE_T, load=False)
        features = LADMData.get_features_from_t_ids(
            layer, names.T_ID_F,
            [feature[db.names.ERR_QUALITY_ERROR_T_ERROR_TYPE_F]])  # tid

        return features[0][
            names.
            ERR_ERROR_TYPE_T_CODE_F] if features else QCoreApplication.translate(
                "QualityRules", "No error type found!"
            ), features[0][
                names.
                ERR_ERROR_TYPE_T_DESCRIPTION_F] if features else QCoreApplication.translate(
                    "QualityRules", "No error description found!")
예제 #21
0
    def get_dict_automatic_values(db, layer_name, models):
        names = db.names
        ladm_data = LADMData()

        dict_automatic_values = dict()

        for model_key in models:
            if model_key == LADMNames.SURVEY_MODEL_KEY:
                if layer_name == names.LC_BOUNDARY_T:
                    dict_automatic_values = {names.LC_BOUNDARY_T_LENGTH_F: "$length"}
                elif layer_name == names.LC_PARTY_T:
                    dict_automatic_values = {
                        names.COL_PARTY_T_NAME_F: """
                            CASE
                                WHEN {party_type} = get_domain_code_from_value('{domain_party_type}', '{LC_PARTY_TYPE_D_ILICODE_F_NATURAL_PARTY_V}', True, False)  THEN
                                    concat({surname_1}, ' ', {surname_2}, ' ', {first_name_1}, ' ', {first_name_2})
                                WHEN {party_type} = get_domain_code_from_value('{domain_party_type}', '{LC_PARTY_TYPE_D_ILICODE_F_NOT_NATURAL_PARTY_V}', True, False) THEN
                                    {business_name}
                            END
                        """.format(party_type=names.LC_PARTY_T_TYPE_F,
                                   domain_party_type=names.LC_PARTY_TYPE_D,
                                   surname_1=names.LC_PARTY_T_SURNAME_1_F,
                                   surname_2=names.LC_PARTY_T_SURNAME_2_F,
                                   first_name_1=names.LC_PARTY_T_FIRST_NAME_1_F,
                                   first_name_2=names.LC_PARTY_T_FIRST_NAME_2_F,
                                   business_name=names.LC_PARTY_T_BUSINESS_NAME_F,
                                   LC_PARTY_TYPE_D_ILICODE_F_NOT_NATURAL_PARTY_V=LADMNames.LC_PARTY_TYPE_D_ILICODE_F_NOT_NATURAL_PARTY_V,
                                   LC_PARTY_TYPE_D_ILICODE_F_NATURAL_PARTY_V=LADMNames.LC_PARTY_TYPE_D_ILICODE_F_NATURAL_PARTY_V),
                        names.LC_PARTY_T_TYPE_F: "{}".format(ladm_data.get_domain_code_from_value(db,
                                                                                                  names.LC_PARTY_TYPE_D,
                                                                                                  LADMNames.LC_PARTY_TYPE_D_ILICODE_F_NATURAL_PARTY_V)),
                        names.LC_PARTY_T_ETHNIC_GROUP_F: "{}".format(ladm_data.get_domain_code_from_value(db,
                                                                                                          names.LC_ETHNIC_GROUP_TYPE_D,
                                                                                                          LADMNames.LC_PARTY_ETHNIC_GROUP_TYPE_D_NONE_V))
                    }
                elif layer_name == names.LC_PARCEL_T:
                    dict_automatic_values = {
                        names.LC_PARCEL_T_DEPARTMENT_F: 'substr("{}", 0, 2)'.format(names.LC_PARCEL_T_PARCEL_NUMBER_F),
                        names.LC_PARCEL_T_MUNICIPALITY_F: 'substr("{}", 3, 3)'.format(names.LC_PARCEL_T_PARCEL_NUMBER_F)
                    }
                elif layer_name == names.LC_ADMINISTRATIVE_SOURCE_T:
                    dict_automatic_values = {
                        names.COL_SOURCE_T_MAIN_TYPE_F: "{}".format(ladm_data.get_domain_code_from_value(db,
                                                                                                         names.CI_CODE_PRESENTATION_FORM_D,
                                                                                                         LADMNames.CI_CODE_PRESENTATION_FORM_D_DOCUMENT_V))
                    }
            elif model_key == LADMNames.FIELD_DATA_CAPTURE_MODEL_KEY:
                if layer_name == names.FDC_USER_T:
                    dict_automatic_values = {names.FDC_USER_T_DOCUMENT_TYPE_F: "{}".format(
                        ladm_data.get_domain_code_from_value(db,
                                                             names.FDC_PARTY_DOCUMENT_TYPE_D,
                                                             LADMNames.FDC_PARTY_DOCUMENT_TYPE_D_ILICODE_F_CC_V))}

        return dict_automatic_values
예제 #22
0
    def set_fixed_error(self, error_t_id, fixed):
        # Save to the intermediate dict of data and to the underlying data source whether an error is fixed or not
        db = self.__qr_engine.get_db_quality()
        idx_state = self.__get_error_layer().fields().indexOf(
            db.names.ERR_QUALITY_ERROR_T_ERROR_STATE_F)

        value = LADMNames.ERR_ERROR_STATE_D_FIXED_V if fixed else LADMNames.ERR_ERROR_STATE_D_ERROR_V
        fixed_or_error_t_id = self.__get_error_state_t_id(value)

        if fixed_or_error_t_id is None:
            self.logger.critical(
                __name__,
                "The error state t_id couldn't be found for value '{}'!".
                format(value))
            return

        # Save to dict
        self.get_error_results_data()[error_t_id].setAttribute(
            idx_state, fixed_or_error_t_id)

        fids = LADMData.get_fids_from_key_values(self.__get_error_layer(),
                                                 db.names.T_ID_F, [error_t_id])

        # Save to underlying data source
        if fids:
            res = self.__get_error_layer().dataProvider(
            ).changeAttributeValues(
                {fids[0]: {
                     idx_state: fixed_or_error_t_id
                 }})

            if not res:
                self.logger.critical(__name__,
                                     "Error modifying the error state value!")
        else:
            self.logger.critical(
                __name__, "Error with t_id '' not found!".format(error_t_id))
    def save_errors(db_qr,
                    rule_code,
                    error_code,
                    error_data,
                    target_layer,
                    ili_name=None):
        """
        Save error data in the quality error model by error_code, which means that you should call this function once
        per error type. Accepts both, spatial and non-spatial errors.

        :param db_qr: DB Connector
        :param rule_code: Rule code as specified in the external catalogs.
        :param error_code: Error code as specified in the external catalogs.
        :param error_data: Dict of lists:
                               {'geometries': [geometries], 'data': [obj_uuids, rel_obj_uuids, values, details, state]}
                               Note: this dict will always have 2 elements.
                               Note 2: For geometry errors, this dict will always have the same number of elements in
                                       each of the two lists (and the element order matters!).
                               Note 3: For geometryless errors, the 'geometries' value won't be even read.
        :param target_layer: Value of EnumQualityRuleType.
        :param ili_name: Interlis name of the class where the object uuids can be found.
        :return: Tuple (res: boolean, msg: string)
        """
        if not hasattr(db_qr.names, "T_ID_F"):
            db_qr.test_connection()

        names = db_qr.names
        layers = {
            names.ERR_QUALITY_ERROR_T: None,
            names.ERR_RULE_TYPE_T: None,
            names.ERR_ERROR_TYPE_T: None
        }

        if target_layer == EnumQualityRuleType.POINT:
            layers[names.ERR_POINT_T] = None
        elif target_layer == EnumQualityRuleType.LINE:
            layers[names.ERR_LINE_T] = None
        elif target_layer == EnumQualityRuleType.POLYGON:
            layers[names.ERR_POLYGON_T] = None

        app.core.get_layers(db_qr, layers, load=True)

        if not layers:
            return False, "At least one layer was not found in the quality error db!"

        # We do now a soon check of rule code and error code to stop if cannot be found
        fids = LADMData.get_fids_from_key_values(layers[names.ERR_RULE_TYPE_T],
                                                 names.ERR_RULE_TYPE_T_CODE_F,
                                                 [rule_code])
        if not fids:
            return False, "There was a problem saving quality error data. The rule '{}' cannot be found in the database. Is that rule in any registered catalog?".format(
                rule_code)
        rule_code_id = fids[0]

        fids = LADMData.get_fids_from_key_values(
            layers[names.ERR_ERROR_TYPE_T], names.ERR_ERROR_TYPE_T_CODE_F,
            [error_code])
        if not fids:
            return False, "There was a problem saving quality error data. The error '{}' cannot be found in the database. Is that error in any registered catalog?".format(
                error_code)
        error_code_id = fids[0]

        qr_error_layer = layers[names.ERR_QUALITY_ERROR_T]

        # First we deal with geometries
        geom_layer = None
        idx_geometry_fk = None
        geom_t_ids = list()  # To store fks (geom t_id)
        if target_layer == EnumQualityRuleType.POINT:
            geom_layer = layers[names.ERR_POINT_T]
            idx_geometry_fk = qr_error_layer.fields().indexOf(
                names.ERR_QUALITY_ERROR_T_POINT_F)
        elif target_layer == EnumQualityRuleType.LINE:
            geom_layer = layers[names.ERR_LINE_T]
            idx_geometry_fk = qr_error_layer.fields().indexOf(
                names.ERR_QUALITY_ERROR_T_LINE_F)
        elif target_layer == EnumQualityRuleType.POLYGON:
            geom_layer = layers[names.ERR_POLYGON_T]
            idx_geometry_fk = qr_error_layer.fields().indexOf(
                names.ERR_QUALITY_ERROR_T_POLYGON_F)

        if geom_layer:
            idx_t_ili_tid_geom = geom_layer.fields().indexOf(names.T_ILI_TID_F)
            geometries = error_data['geometries']

            features = list()
            for geometry in geometries:
                new_feature = QgsVectorLayerUtils().createFeature(
                    geom_layer, geometry,
                    {idx_t_ili_tid_geom: str(uuid.uuid4())})
                features.append(new_feature)

            res_geom, out_features = geom_layer.dataProvider().addFeatures(
                features)
            if res_geom:
                geom_t_ids = [
                    out_feature[names.T_ID_F] for out_feature in out_features
                ]
            else:
                return False, "There was a problem saving error geometries for error code '{}'!".format(
                    error_code)

        # Now we deal with the alphanumeric data
        idx_t_ili_tid = qr_error_layer.fields().indexOf(names.T_ILI_TID_F)
        idx_rule_type = qr_error_layer.fields().indexOf(
            names.ERR_QUALITY_ERROR_T_RULE_TYPE_F)
        idx_error_type = qr_error_layer.fields().indexOf(
            names.ERR_QUALITY_ERROR_T_ERROR_TYPE_F)
        idx_object_ids = qr_error_layer.fields().indexOf(
            names.ERR_QUALITY_ERROR_T_OBJECT_IDS_F)
        idx_rel_object_ids = qr_error_layer.fields().indexOf(
            names.ERR_QUALITY_ERROR_T_RELATED_OBJECT_IDS_F)
        idx_values = qr_error_layer.fields().indexOf(
            names.ERR_QUALITY_ERROR_T_VALUES_F)
        idx_ili_name = qr_error_layer.fields().indexOf(
            names.ERR_QUALITY_ERROR_T_ILI_NAME_F)
        idx_details = qr_error_layer.fields().indexOf(
            names.ERR_QUALITY_ERROR_T_DETAILS_F)
        idx_error_state = qr_error_layer.fields().indexOf(
            names.ERR_QUALITY_ERROR_T_ERROR_STATE_F)

        features = list()
        for i, data in enumerate(error_data['data']):
            attr_map = {
                idx_t_ili_tid: str(uuid.uuid4()),
                idx_rule_type: rule_code_id,
                idx_error_type: error_code_id,
                idx_object_ids: data[0],
                idx_rel_object_ids: data[1],
                idx_values: data[2],
                idx_details: data[3],
                idx_ili_name: ili_name,
                idx_error_state: data[4]
            }
            if geom_layer:
                attr_map[idx_geometry_fk] = geom_t_ids[
                    i]  # We take advantage of the preserved order here

            features.append(QgsVectorLayerUtils().createFeature(
                qr_error_layer, attributes=attr_map))

        res_data, out_features = qr_error_layer.dataProvider().addFeatures(
            features)
        if not res_data:
            return False, "There was a problem saving error alphanumeric data for error code '{}'! Details from the provider: {}".format(
                error_code,
                qr_error_layer.dataProvider().lastError())

        return True, "Success!"
예제 #24
0
class TestCopy(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        print("\nINFO: Setting up copy CSV points to DB validation...")
        print("INFO: Restoring databases to be used")
        import_asistente_ladm_col()
        cls.app = AppInterface()
        cls.app.core.initialize_ctm12()  # We need to initialize CTM12

    def setUp(self):
        restore_schema(SCHEMA_LADM_COL_EMPTY, True)
        self.db_pg = get_pg_conn(SCHEMA_LADM_COL_EMPTY)

        self.names = self.db_pg.names
        self.ladm_data = LADMData()
        self.geometry = GeometryUtils()

        res, code, msg = self.db_pg.test_connection()
        self.assertTrue(res, msg)
        self.assertIsNotNone(self.names.LC_BOUNDARY_POINT_T, 'Names is None')

    def test_copy_csv_to_db(self):
        print("\nINFO: Validating copy CSV points to DB...")
        clean_table(SCHEMA_LADM_COL_EMPTY, self.names.LC_BOUNDARY_POINT_T)
        layer = self.app.core.get_layer(self.db_pg,
                                        self.names.LC_BOUNDARY_POINT_T, True)
        self.app.core.disable_automatic_fields(layer)

        csv_path = get_test_path('csv/puntos_fixed_ladm_v1_1.csv')
        txt_delimiter = ';'
        cbo_longitude = 'x'
        cbo_latitude = 'y'
        csv_layer = self.app.core.csv_to_layer(csv_path,
                                               txt_delimiter,
                                               cbo_longitude,
                                               cbo_latitude,
                                               "EPSG:9377",
                                               reproject=False)

        self.upload_points_from_csv(csv_layer, SCHEMA_LADM_COL_EMPTY)

        self.validate_points_in_db(SCHEMA_LADM_COL_EMPTY)
        test_layer = self.app.core.get_layer(self.db_pg,
                                             self.names.LC_BOUNDARY_POINT_T,
                                             load=True)
        delete_features(test_layer)
        self.assertEqual(test_layer.featureCount(), 0)

    def boundary_point_layer_resolve_domains_for_test(self, csv_layer):
        data_provider = csv_layer.dataProvider()
        data_provider.addAttributes([
            QgsField('acuerdo', QVariant.Int),
            QgsField('puntotipo', QVariant.Int),
            QgsField('metodoproduccion', QVariant.Int)
        ])
        csv_layer.updateFields()

        idx_agreement_field = data_provider.fieldNameIndex('acuerdo')
        idx_point_type_field = data_provider.fieldNameIndex('puntotipo')
        idx_production_method_field = data_provider.fieldNameIndex(
            'metodoproduccion')

        with edit(csv_layer):
            for feature in csv_layer.getFeatures():
                feature.setAttribute(
                    idx_agreement_field,
                    self.ladm_data.get_domain_code_from_value(
                        self.db_pg, self.names.LC_AGREEMENT_TYPE_D,
                        feature['_acuerdo']))
                feature.setAttribute(
                    idx_point_type_field,
                    self.ladm_data.get_domain_code_from_value(
                        self.db_pg, self.names.COL_POINT_TYPE_D,
                        feature['_puntotipo']))
                feature.setAttribute(
                    idx_production_method_field,
                    self.ladm_data.get_domain_code_from_value(
                        self.db_pg, self.names.COL_PRODUCTION_METHOD_TYPE_D,
                        feature['_metodoproduccion']))
                csv_layer.updateFeature(feature)

    def upload_points_from_csv(self, csv_layer, schema):
        print("Copying CSV data with no elevation...")
        self.boundary_point_layer_resolve_domains_for_test(csv_layer)
        test_layer = self.app.core.get_layer(self.db_pg,
                                             self.names.LC_BOUNDARY_POINT_T,
                                             load=True)
        run_etl_model(self.names, csv_layer, test_layer,
                      self.names.LC_BOUNDARY_POINT_T)
        self.assertEqual(test_layer.featureCount(), 51)
        self.validate_number_of_boundary_points_in_db(schema, 51)

    def test_upload_points_from_csv_crs_wgs84(self):
        print("\nINFO: Copying CSV data with EPSG:4326...")
        layer = self.app.core.get_layer(self.db_pg,
                                        self.names.LC_BOUNDARY_POINT_T, True)
        self.app.core.disable_automatic_fields(layer)

        csv_path = get_test_path('csv/puntos_crs_4326_wgs84_ladm_v1_1.csv')
        txt_delimiter = ';'
        cbo_longitude = 'x'
        cbo_latitude = 'y'
        crs = 'EPSG:4326'
        csv_layer = self.app.core.csv_to_layer(csv_path,
                                               txt_delimiter,
                                               cbo_longitude,
                                               cbo_latitude,
                                               crs,
                                               reproject=False)
        csv_layer = reproject_to_ctm12(csv_layer)

        self.upload_points_from_csv_crs_wgs84(csv_layer, SCHEMA_LADM_COL_EMPTY)
        self.validate_points_in_db_from_wgs84(SCHEMA_LADM_COL_EMPTY)

        test_layer = self.app.core.get_layer(self.db_pg,
                                             self.names.LC_BOUNDARY_POINT_T,
                                             load=True)
        delete_features(test_layer)
        self.assertEqual(test_layer.featureCount(), 0)

    def upload_points_from_csv_crs_wgs84(self, csv_layer, schema):
        print("Copying CSV data in WGS84...")
        self.boundary_point_layer_resolve_domains_for_test(csv_layer)
        test_layer = self.app.core.get_layer(self.db_pg,
                                             self.names.LC_BOUNDARY_POINT_T,
                                             load=True)
        run_etl_model(self.names, csv_layer, test_layer,
                      self.names.LC_BOUNDARY_POINT_T)
        self.validate_number_of_boundary_points_in_db(schema, 3)

    def validate_points_in_db_from_wgs84(self, schema):
        print('\nINFO: Validating points in db from wgs84')
        cur = self.db_pg.conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
        cur.execute(
            """SELECT st_x(geometria), st_y(geometria) FROM {}.{};""".format(
                schema, self.names.LC_BOUNDARY_POINT_T))
        results = cur.fetchall()
        self.assertEqual(len(results), 3)
        self.assertEqual(
            [round(result, 3) for result in results[0]],
            [round(item_test, 3) for item_test in [4843984.711, 2143385.632]])
        self.assertEqual(
            [round(result, 3) for result in results[1]],
            [round(item_test, 3) for item_test in [4843918.478, 2143442.584]])
        self.assertEqual(
            [round(result, 3) for result in results[2]],
            [round(item_test, 3) for item_test in [4843979.173, 2143379.773]])

    def test_copy_csv_with_z_to_db(self):
        print("\nINFO: Validating copy CSV points with Z to DB...")
        clean_table(SCHEMA_LADM_COL_EMPTY, self.names.LC_BOUNDARY_POINT_T)
        layer = self.app.core.get_layer(self.db_pg,
                                        self.names.LC_BOUNDARY_POINT_T, True)
        self.app.core.disable_automatic_fields(layer)

        csv_path = get_test_path('csv/puntos_fixed_ladm_v1_1.csv')
        txt_delimiter = ';'
        cbo_longitude = 'x'
        cbo_latitude = 'y'
        elevation = 'z'
        csv_layer = self.app.core.csv_to_layer(csv_path,
                                               txt_delimiter,
                                               cbo_longitude,
                                               cbo_latitude,
                                               "EPSG:9377",
                                               elevation,
                                               reproject=False)

        self.upload_points_from_csv_with_elevation(csv_layer,
                                                   SCHEMA_LADM_COL_EMPTY)
        self.validate_points_in_db(SCHEMA_LADM_COL_EMPTY, with_z=True)

        test_layer = self.app.core.get_layer(self.db_pg,
                                             self.names.LC_BOUNDARY_POINT_T,
                                             load=True)
        delete_features(test_layer)
        self.assertEqual(test_layer.featureCount(), 0)

    def upload_points_from_csv_with_elevation(self, csv_layer, schema):
        print("\nINFO: Copying CSV data with elevation...")
        self.boundary_point_layer_resolve_domains_for_test(csv_layer)
        test_layer = self.app.core.get_layer(self.db_pg,
                                             self.names.LC_BOUNDARY_POINT_T,
                                             load=True)
        run_etl_model(self.names, csv_layer, test_layer,
                      self.names.LC_BOUNDARY_POINT_T)
        self.assertEqual(test_layer.featureCount(), 51)
        self.validate_number_of_boundary_points_in_db(schema, 51)

    def validate_points_in_db(self, schema, with_z=False):
        cur = self.db_pg.conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
        print(
            '\nValidating points {}(both spatial and alphanumeric attributes)'.
            format('with Z ' if with_z else ''))
        cur.execute("""SELECT * FROM {}.{};""".format(
            schema, self.names.LC_BOUNDARY_POINT_T))
        results = cur.fetchall()
        colnames = {
            desc[0]: cur.description.index(desc)
            for desc in cur.description
        }

        self.assertEqual(len(results), 51)

        for row in results:
            if row[colnames['id_punto_lindero']] == '50':
                break

        self.assertEqual(row[colnames['id_punto_lindero']], '50')
        self.assertEqual(row[colnames['puntotipo']], 17)
        self.assertEqual(row[colnames['acuerdo']], 596)
        self.assertEqual(row[colnames['fotoidentificacion']], None)
        self.assertEqual(row[colnames['exactitud_horizontal']], 1.000)
        self.assertEqual(row[colnames['exactitud_vertical']], None)
        self.assertEqual(row[colnames['posicion_interpolacion']], None)
        self.assertEqual(row[colnames['metodoproduccion']], 1)
        self.assertEqual(row[colnames['espacio_de_nombres']],
                         'LC_PUNTOLINDERO')
        self.assertIsNotNone(row[colnames['local_id']])
        self.assertIsNone(row[colnames['ue_lc_servidumbretransito']])
        self.assertIsNone(row[colnames['ue_lc_construccion']])
        self.assertIsNone(row[colnames['ue_lc_terreno']])
        self.assertIsNone(row[colnames['ue_lc_unidadconstruccion']])
        self.assertIsNone(row[colnames['fin_vida_util_version']])

        geom = '01010000A0A1240000EC51B836A57A5241CDCCCC7C8D5A40410000000000000000'
        if with_z:
            geom = '01010000A0A1240000EC51B836A57A5241CDCCCC7C8D5A404123DBF97EEA2E9640'

        self.assertEqual(row[colnames['geometria']], geom)

    def test_copy_csv_overlapping_to_db(self):
        print('\nINFO: Validating copy csv overlapping to db')
        clean_table(SCHEMA_LADM_COL_EMPTY, self.names.LC_BOUNDARY_POINT_T)
        csv_path = get_test_path('csv/puntos_overlapping_ladm_v1_1.csv')
        txt_delimiter = ';'
        cbo_longitude = 'x'
        cbo_latitude = 'y'
        csv_layer = self.app.core.csv_to_layer(csv_path,
                                               txt_delimiter,
                                               cbo_longitude,
                                               cbo_latitude,
                                               "EPSG:9377",
                                               reproject=False)

        self.upload_points_from_csv_overlapping(csv_layer,
                                                SCHEMA_LADM_COL_EMPTY)
        self.validate_number_of_boundary_points_in_db(SCHEMA_LADM_COL_EMPTY, 0)

        test_layer = self.app.core.get_layer(self.db_pg,
                                             self.names.LC_BOUNDARY_POINT_T,
                                             load=True)
        delete_features(test_layer)
        self.assertEqual(test_layer.featureCount(), 0)

    def upload_points_from_csv_overlapping(self, csv_layer, schema):
        print('Uploading points from csv overlapping...')
        overlapping = self.geometry.get_overlapping_points(csv_layer)

        if not overlapping:
            self.boundary_point_layer_resolve_domains_for_test(csv_layer)
            test_layer = self.app.core.get_layer(
                self.db_pg, self.names.LC_BOUNDARY_POINT_T, load=True)
            run_etl_model(self.names, csv_layer, test_layer,
                          self.names.LC_BOUNDARY_POINT_T)

        self.validate_number_of_boundary_points_in_db(schema, 0)

    def validate_number_of_boundary_points_in_db(self, schema, num=0):
        print(
            '\nINFO: Validating number of boundary points in schema {}'.format(
                schema))
        cur = self.db_pg.conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
        cur.execute("""SELECT count(t_id) FROM {}.{};""".format(
            schema, self.names.LC_BOUNDARY_POINT_T))
        result = cur.fetchone()
        self.assertEqual(result[0], num)

    def tearDown(self):
        print("INFO: Closing open connections to databases")
        self.db_pg.conn.close()

    @classmethod
    def tearDownClass(cls):
        pass
예제 #25
0
class QGISLADMQuery:
    def __init__(self):
        self.app = AppInterface()
        self.ladm_data = LADMData()

    def get_igac_property_record_card_info(self, db, **kwargs):
        return self._execute_ladm_query(
            db, EnumLADMQueryType.IGAC_PROPERTY_RECORD_CARD_INFO, kwargs)

    def get_igac_economic_info(self, db, **kwargs):
        return self._execute_ladm_query(db,
                                        EnumLADMQueryType.IGAC_ECONOMIC_INFO,
                                        kwargs)

    def get_igac_physical_info(self, db, **kwargs):
        return self._execute_ladm_query(db,
                                        EnumLADMQueryType.IGAC_PHYSICAL_INFO,
                                        kwargs)

    def get_igac_legal_info(self, db, **kwargs):
        return self._execute_ladm_query(db, EnumLADMQueryType.IGAC_LEGAL_INFO,
                                        kwargs)

    def get_igac_basic_info(self, db, **kwargs):
        return self._execute_ladm_query(db, EnumLADMQueryType.IGAC_BASIC_INFO,
                                        kwargs)

    def _execute_ladm_query(self, db, query_type, kwargs):
        params = QGISLADMQuery._get_parameters(kwargs)
        filter_field_values = self._get_plot_ids_from_params(db, params)

        response = dict()
        query = dict()

        ladm_units = db.get_ladm_units()
        if EnumLADMQueryType.IGAC_BASIC_INFO == query_type:
            query = get_igac_basic_query(db.names, ladm_units)
        elif EnumLADMQueryType.IGAC_PHYSICAL_INFO == query_type:
            query = get_igac_physical_query(db.names, ladm_units)
        elif EnumLADMQueryType.IGAC_LEGAL_INFO == query_type:
            query = get_igac_legal_query(db.names, ladm_units)
        elif EnumLADMQueryType.IGAC_ECONOMIC_INFO == query_type:
            query = get_igac_economic_query(db.names, ladm_units)
        elif EnumLADMQueryType.IGAC_PROPERTY_RECORD_CARD_INFO == query_type:
            query = get_igac_property_record_card_query(db.names, ladm_units)

        self._execute_query(db, response, query[QueryNames.LEVEL_TABLE],
                            filter_field_values)
        return response

    def _get_plot_ids_from_params(self, db, params):
        """
        Get plot ids depending on a defined filter in params
            SEARCH_KEY_PARCEL_FMI: Get plots id associated with parcel filter by parcel FMI
            SEARCH_KEY_PARCEL_NUMBER: Get plots id associated with parcel filter by parcel number
            SEARCH_KEY_PREVIOUS_PARCEL_NUMBER: Get plots id associated with parcel filter by previous parcel number
        """
        plot_ids = list()

        if params[QueryNames.SEARCH_KEY_PLOT_T_IDS] != 'NULL':
            plot_ids = params[QueryNames.SEARCH_KEY_PLOT_T_IDS]

        if params[QueryNames.SEARCH_KEY_PARCEL_FMI] != 'NULL' or params[
                QueryNames.SEARCH_KEY_PARCEL_NUMBER] != 'NULL' or params[
                    QueryNames.SEARCH_KEY_PREVIOUS_PARCEL_NUMBER] != 'NULL':
            layers = {
                db.names.LC_PARCEL_T: None,
                db.names.COL_UE_BAUNIT_T: None
            }
            self.app.core.get_layers(db, layers, False)

            if layers:
                parcel_layer = layers[db.names.LC_PARCEL_T]
                ue_baunit_layer = layers[db.names.COL_UE_BAUNIT_T]

                if params[QueryNames.SEARCH_KEY_PARCEL_FMI] != 'NULL':
                    expr = QgsExpression("{} like '{}'".format(
                        db.names.LC_PARCEL_T_FMI_F,
                        params[QueryNames.SEARCH_KEY_PARCEL_FMI]))
                    plot_ids.extend(
                        self._filter_plots_ids_from_expresion(
                            db, parcel_layer, ue_baunit_layer, expr))

                if params[QueryNames.SEARCH_KEY_PARCEL_NUMBER] != 'NULL':
                    expr = QgsExpression("{} like '{}'".format(
                        db.names.LC_PARCEL_T_PARCEL_NUMBER_F,
                        params[QueryNames.SEARCH_KEY_PARCEL_NUMBER]))
                    plot_ids.extend(
                        self._filter_plots_ids_from_expresion(
                            db, parcel_layer, ue_baunit_layer, expr))

                if params[QueryNames.
                          SEARCH_KEY_PREVIOUS_PARCEL_NUMBER] != 'NULL':
                    expr = QgsExpression("{} like '{}'".format(
                        db.names.LC_PARCEL_T_PREVIOUS_PARCEL_NUMBER_F,
                        params[QueryNames.SEARCH_KEY_PREVIOUS_PARCEL_NUMBER]))
                    plot_ids.extend(
                        self._filter_plots_ids_from_expresion(
                            db, parcel_layer, ue_baunit_layer, expr))

        return plot_ids

    @staticmethod
    def _filter_plots_ids_from_expresion(db, parcel_layer, ue_baunit_layer,
                                         expression_select_parcels):
        """
        Get plots ids depending of a defined filter expression
        """
        # Only required field in parcel layer
        fields_idx = list()
        for field in [
                db.names.T_ID_F, db.names.LC_PARCEL_T_FMI_F,
                db.names.LC_PARCEL_T_PARCEL_NUMBER_F,
                db.names.LC_PARCEL_T_PREVIOUS_PARCEL_NUMBER_F
        ]:
            fields_idx.append(parcel_layer.fields().indexFromName(field))

        request = QgsFeatureRequest(expression_select_parcels)
        request.setFlags(QgsFeatureRequest.NoGeometry)
        request.setSubsetOfAttributes(fields_idx)  # Note: this adds a new flag
        parcels = parcel_layer.getFeatures(request)
        parcel_ids = [
            select_parcel[db.names.T_ID_F] for select_parcel in parcels
        ]

        # Only required field in ue baunit layer
        field_idx = parcel_layer.fields().indexFromName(
            db.names.COL_UE_BAUNIT_T_LC_PLOT_F)
        expression_select_plots = QgsExpression(
            '{} in ({}) AND {} IS NOT NULL'.format(
                db.names.COL_UE_BAUNIT_T_PARCEL_F,
                ','.join([str(parcel_id) for parcel_id in parcel_ids]),
                db.names.COL_UE_BAUNIT_T_LC_PLOT_F))
        request = QgsFeatureRequest(expression_select_plots)
        request.setFlags(QgsFeatureRequest.NoGeometry)
        request.setSubsetOfAttributes([field_idx
                                       ])  # Note: this adds a new flag
        plots = ue_baunit_layer.getFeatures(request)

        return [plot[db.names.COL_UE_BAUNIT_T_LC_PLOT_F]
                for plot in plots]  # Plot ids

    def _execute_query(self, db, response, level_dict, filter_field_values):
        """
        Recursive function that allows solving the queries defined using the LADM Query Objects.
        Recursion ends when the last nesting level is reached.
        :param db: database connection instance
        :param response: object that is recursively built with the response.
        :param level_dict: nesting level dictionary to solve
        :param filter_field_values: list of filter field values
        :return dictionary with the query result
        """
        table_name = level_dict[QueryNames.LEVEL_TABLE_NAME]
        level_alias = level_dict[QueryNames.LEVEL_TABLE_ALIAS]
        layer = self.app.core.get_layer(db, table_name, False)
        filter_sub_level = level_dict[QueryNames.FILTER_SUB_LEVEL]
        t_id_features = self._get_features_ids_sub_level(
            db, filter_sub_level, filter_field_values)

        response[level_alias] = list()
        dict_fields_and_alias = dict()
        for required_table_field in level_dict[QueryNames.TABLE_FIELDS]:
            if isinstance(required_table_field, OwnField):
                dict_fields_and_alias[
                    required_table_field.
                    field_name] = required_table_field.field_alias

        field_names = list(dict_fields_and_alias.keys())
        features = self._get_features(layer, db.names.T_ID_F, field_names,
                                      t_id_features)

        for feature in features:
            node_response = dict()
            node_response[QueryNames.ID_FEATURE_RESPONSE] = feature[
                db.names.T_ID_F]

            node_fields_response = dict()
            for field in level_dict[QueryNames.TABLE_FIELDS]:
                if isinstance(field, DomainOwnField):
                    domain_table = field.domain_table
                    domain_code = feature[field.field_name]
                    domain_value = self.ladm_data.get_domain_value_from_code(
                        db, domain_table, domain_code, False)
                    node_fields_response[field.field_alias] = domain_value
                elif isinstance(field, OwnField):
                    node_fields_response[field.field_alias] = feature[
                        field.field_name] if feature[
                            field.field_name] != NULL else None
                elif isinstance(field, EvalExpressionOwnField):
                    node_fields_response[
                        field.field_alias] = self._get_eval_expr_value(
                            layer, feature, field.expression)
                elif isinstance(field, AbsRelatedFields):
                    if isinstance(field, RelatedRemoteFieldObject):
                        node_fields_response[
                            field.
                            field_alias] = self._get_relate_remote_field_object(
                                db, field, [feature[db.names.T_ID_F]])
                    elif isinstance(field, RelatedRemoteFieldValue):
                        node_fields_response[
                            field.
                            field_alias] = self._get_relate_remote_field_value(
                                db, field, [feature[db.names.T_ID_F]])
                    elif isinstance(field, RelatedOwnFieldObject):
                        node_fields_response[
                            field.
                            field_alias] = self._get_relate_own_field_object(
                                db, field, [feature[db.names.T_ID_F]])
                    elif isinstance(field, RelatedOwnFieldValue):
                        node_fields_response[
                            field.
                            field_alias] = self._get_relate_own_field_value(
                                db, field, [feature[db.names.T_ID_F]])

            for dict_key in level_dict:
                if dict_key.endswith(QueryNames.LEVEL_TABLE):
                    self._execute_query(db, node_fields_response,
                                        level_dict[dict_key],
                                        [feature[db.names.T_ID_F]])

            node_response[
                QueryNames.ATTRIBUTES_RESPONSE] = node_fields_response
            response[level_alias].append(node_response)

    def _get_relate_remote_field_object(self, db, field, filter_field_values):
        t_id_features = self._get_relate_own_field_object(
            db, field.filter_sub_level, filter_field_values)
        return self._get_relate_own_field_value(db, field, t_id_features)

    def _get_relate_remote_field_value(self, db, field, filter_field_values):
        t_id_features = self._get_features_ids_sub_level(
            db, field.filter_sub_level, filter_field_values)
        return self._get_relate_own_field_value(db, field, t_id_features)

    def _get_relate_own_field_object(self, db, field, filter_field_values):
        """
        Get relate own field object

        :param db: database connection instance
        :param field: AbsRelatedFields
        :param filter_field_values: list of field values used to apply the filter
        return list of dict with required fields
        """
        referenced_layer = self.app.core.get_layer(db, field.referenced_layer,
                                                   False)
        dict_fields_and_alias = self._get_dict_fields_and_alias(
            field.required_fields_referenced_layer)
        field_names = list(dict_fields_and_alias.keys())
        field_names.append(db.names.T_ID_F)

        features = self._get_features(referenced_layer, field.referenced_field,
                                      field_names, filter_field_values)

        list_result = list()
        for feature in features:
            dict_referenced_field = dict()
            dict_referenced_field[QueryNames.ID_FEATURE_RESPONSE] = feature[
                db.names.T_ID_F]
            dict_attributes = dict()
            for field_relation in field.required_fields_referenced_layer:
                if isinstance(field_relation, DomainOwnField):
                    domain_table = field_relation.domain_table
                    domain_code = feature[field_relation.field_name]
                    domain_value = self.ladm_data.get_domain_value_from_code(
                        db, domain_table, domain_code, False)
                    dict_attributes[field_relation.field_alias] = domain_value
                elif isinstance(field_relation, OwnField):
                    dict_attributes[field_relation.field_alias] = feature[
                        field_relation.field_name] if feature[
                            field_relation.field_name] != NULL else None
                elif isinstance(field_relation, EvalExpressionOwnField):
                    dict_attributes[field_relation.
                                    field_alias] = self._get_eval_expr_value(
                                        referenced_layer, feature,
                                        field_relation.expression)

            dict_referenced_field[
                QueryNames.ATTRIBUTES_RESPONSE] = dict_attributes
            list_result.append(dict_referenced_field)

        return list_result

    def _get_relate_own_field_value(self, db, field, filter_field_values):
        """
        Get relate own field value.

        :param db: database connection instance
        :param field: AbsRelatedFields
        :param filter_field_values: list of field values used to apply the filter
        :return required field value
        """
        referenced_layer = self.app.core.get_layer(db, field.referenced_layer,
                                                   False)
        required_field_referenced_layer = field.required_field_referenced_layer
        dict_fields_and_alias = self._get_dict_fields_and_alias(
            [required_field_referenced_layer])
        field_names = list(dict_fields_and_alias.keys())
        field_names.append(db.names.T_ID_F)

        features = self._get_features(referenced_layer, field.referenced_field,
                                      field_names, filter_field_values)

        field_value = None
        for feature in features:
            if isinstance(required_field_referenced_layer, DomainOwnField):
                domain_table = required_field_referenced_layer.domain_table
                domain_code = feature[
                    required_field_referenced_layer.field_name]
                domain_value = self.ladm_data.get_domain_value_from_code(
                    db, domain_table, domain_code, False)
                field_value = domain_value
            elif isinstance(required_field_referenced_layer, OwnField):
                field_value = feature[
                    required_field_referenced_layer.
                    field_name] if feature[required_field_referenced_layer.
                                           field_name] != NULL else None
            elif isinstance(required_field_referenced_layer,
                            EvalExpressionOwnField):
                field_value = self._get_eval_expr_value(
                    referenced_layer, feature,
                    required_field_referenced_layer.expression)

        return field_value

    def _get_features_ids_by_filter(self, db, filter_sub_level,
                                    filter_field_values):
        """
        Get feature ids using filter.

        :param db: database connection instance
        :param filter_sub_level: LADM Query filter
        :param filter_field_values: it is a list with only one item

        return list feature ids filters
        """
        referenced_layer = filter_sub_level.referenced_layer
        required_field_referenced_layer = filter_sub_level.required_field_referenced_layer
        sub_level_layer = self.app.core.get_layer(db, referenced_layer, False)

        if isinstance(filter_sub_level, FilterSubLevel):
            referenced_field = filter_sub_level.referenced_field
            expression = QgsExpression("{} in ({}) and {} is not null".format(
                referenced_field, ', '.join(
                    str(filter_field_value)
                    for filter_field_value in filter_field_values),
                required_field_referenced_layer))
            request = QgsFeatureRequest(expression)
            field_idx = sub_level_layer.fields().indexFromName(
                required_field_referenced_layer)
            request.setFlags(QgsFeatureRequest.NoGeometry)
            request.setSubsetOfAttributes([field_idx
                                           ])  # Note: this adds a new flag
            feature_ids = [
                feature[required_field_referenced_layer]
                for feature in sub_level_layer.getFeatures(request)
            ]
            return feature_ids

        elif isinstance(filter_sub_level, SpatialFilterSubLevel):
            referencing_layer = filter_sub_level.referencing_layer
            spatial_operation = filter_sub_level.spatial_operation
            level_layer = self.app.core.get_layer(db, referencing_layer, False)
            filter_level_layer = processing.run(
                "native:extractbyattribute", {
                    'INPUT': level_layer,
                    'FIELD': db.names.T_ID_F,
                    'OPERATOR': 0,
                    'VALUE': filter_field_values[0],
                    'OUTPUT': 'memory:'
                })['OUTPUT']

            parameters = {
                'INPUT': sub_level_layer,
                'INTERSECT': filter_level_layer,
                'OUTPUT': 'memory:'
            }
            if spatial_operation == EnumSpatialOperationType.INTERSECTS:
                parameters['PREDICATE'] = [0]  # Intersects
            elif spatial_operation == EnumSpatialOperationType.OVERLAPS:
                parameters['PREDICATE'] = [5]  # Overlaps
            elif spatial_operation == EnumSpatialOperationType.CONTAINS:
                parameters['PREDICATE'] = [1]  # Contains

            filter_sub_level_layer = processing.run("native:extractbylocation",
                                                    parameters)['OUTPUT']

            feature_ids = [
                feature[required_field_referenced_layer]
                for feature in filter_sub_level_layer.getFeatures()
            ]
            return feature_ids

    def _get_features_ids_sub_level(self, db, filter_sub_level,
                                    filter_field_values):
        """
        Get feature t_id values associated to sub level filter.
        This method is recursive and its recursion ends when all the filters it has nested are resolved.

        :param db: database connection instance
        :param filter_sub_level: custom LADM Query Filter
        :param filter_field_values: list of field values to be filtered
        return list of t_ids
        """
        t_id_features = list()
        for filter_field_value in filter_field_values:
            t_id_features.extend(
                self._get_features_ids_by_filter(db, filter_sub_level,
                                                 [filter_field_value]))

        sub_filter_sub_level = filter_sub_level.filter_sub_level  # Recursivity to get features t_ids associate to the first filter
        if sub_filter_sub_level:
            return self._get_features_ids_sub_level(db, sub_filter_sub_level,
                                                    t_id_features)
        else:
            return t_id_features

    @staticmethod
    def _get_eval_expr_value(layer, feature, expression):
        eval_feature = layer.getFeature(
            feature.id()
        )  # this is necessary because the feature is filtered and may not have all the necessary fields
        context = QgsExpressionContext()
        scope = QgsExpressionContextScope()
        scope.setFeature(eval_feature)
        context.appendScope(scope)
        expression.prepare(context)

        return expression.evaluate(context)

    @staticmethod
    def _get_dict_fields_and_alias(table_fields):
        dict_fields_and_alias = dict()
        for required_table_field in table_fields:
            if isinstance(required_table_field, OwnField):
                dict_fields_and_alias[
                    required_table_field.
                    field_name] = required_table_field.field_alias
        return dict_fields_and_alias

    @staticmethod
    def _get_features(layer, referenced_field, field_names, t_id_features):
        if not t_id_features:
            return list()

        fields_idx = [
            layer.fields().indexFromName(field) for field in field_names
        ]

        expression = QgsExpression('{} in ({})'.format(
            referenced_field,
            ', '.join(str(t_id_feature) for t_id_feature in t_id_features)))
        request = QgsFeatureRequest(expression)
        request.setFlags(QgsFeatureRequest.NoGeometry)
        request.setSubsetOfAttributes(fields_idx)  # Note: this adds a new flag

        features = [feature for feature in layer.getFeatures(request)]
        return features

    @staticmethod
    def _get_parameters(kwargs):
        params = {
            QueryNames.SEARCH_KEY_PLOT_T_IDS: 'NULL',
            QueryNames.SEARCH_KEY_PARCEL_FMI: 'NULL',
            QueryNames.SEARCH_KEY_PARCEL_NUMBER: 'NULL',
            QueryNames.SEARCH_KEY_PREVIOUS_PARCEL_NUMBER: 'NULL'
        }

        params.update(kwargs)
        return params

    @staticmethod
    def get_duplicate_records_in_table(db, table_name, fields_to_check):
        raise NotImplementedError

    @staticmethod
    def get_group_party_fractions_that_do_not_make_one(db):
        raise NotImplementedError

    @staticmethod
    def get_invalid_col_party_type_natural(db):
        raise NotImplementedError

    @staticmethod
    def get_invalid_col_party_type_no_natural(db):
        raise NotImplementedError

    @staticmethod
    def get_parcels_with_invalid_department_code(db):
        raise NotImplementedError

    @staticmethod
    def get_parcels_with_invalid_municipality_code(db):
        raise NotImplementedError

    @staticmethod
    def get_parcels_with_invalid_parcel_number(db):
        raise NotImplementedError

    @staticmethod
    def get_parcels_with_invalid_parcel_type_and_22_position_number(db):
        raise NotImplementedError

    @staticmethod
    def get_parcels_with_invalid_previous_parcel_number(db):
        raise NotImplementedError

    @staticmethod
    def get_parcels_with_no_right(db):
        raise NotImplementedError

    @staticmethod
    def get_parcels_with_repeated_domain_right(db):
        raise NotImplementedError

    @staticmethod
    def get_uebaunit_parcel(db):
        raise NotImplementedError
예제 #26
0
    def finish_feature_creation(self, layerId, features):
        if len(features) != 1:
            # TODO send this info to controller
            # message = QCoreApplication.translate("WizardTranslations", "'{}' tool has been closed. We should have got only one {} by we have {}").format(self.WIZARD_TOOL_NAME, self.WIZARD_FEATURE_NAME, len(features))
            # self.logger.warning(__name__, "We should have got only one {}, but we have {}".format(self.WIZARD_FEATURE_NAME, len(features)))
            return ParcelFinishFeatureCreationArgs(
                added_features_amount=len(features))

        if not self.is_each_layer_valid():
            return ParcelFinishFeatureCreationArgs(valid_constraints=False)

        feature = features[0]

        if not feature.isValid():
            # TODO send this info to controller
            # self.logger.warning(__name__, "Feature not found in layer Spatial Source...")
            return ParcelFinishFeatureCreationArgs(is_valid=False)

        # TODO What is the difference?
        # feature_tid = feature[self.__db.names.T_ID_F]
        feature_tid = self.__editing_layer.getFeature(
            feature.id())[self.__db.names.T_ID_F]

        plot_ids = list()
        building_ids = list()
        building_unit_ids = list()

        # Apply restriction to the selection

        # add plot associated
        if self.__db.names.LC_PLOT_T in self.__constraint_types_of_parcels[
                self.parcel_type_ili_code]:
            add_features = self.__constraint_types_of_parcels[
                self.parcel_type_ili_code][
                    self.__db.names.LC_PLOT_T] is not None
        else:
            add_features = True

        if add_features:
            plot_ids = LADMData.get_list_of_features_ids(
                self.__layers[self.__db.names.LC_PLOT_T],
                self.__db.names.T_ID_F)

        new_features = LADMData.save_relations(
            self.__layers[self.__db.names.COL_UE_BAUNIT_T],
            self.__db.names.COL_UE_BAUNIT_T_LC_PLOT_F, plot_ids,
            self.__db.names.COL_UE_BAUNIT_T_PARCEL_F, feature_tid)

        # add building associated
        if self.__db.names.LC_BUILDING_T in self.__constraint_types_of_parcels[
                self.parcel_type_ili_code]:
            add_features = self.__constraint_types_of_parcels[
                self.parcel_type_ili_code][
                    self.__db.names.LC_BUILDING_T] is not None
        else:
            add_features = True

        if add_features:
            building_ids = LADMData.get_list_of_features_ids(
                self.__layers[self.__db.names.LC_BUILDING_T],
                self.__db.names.T_ID_F)

        new_features = LADMData.save_relations(
            self.__layers[self.__db.names.COL_UE_BAUNIT_T],
            self.__db.names.COL_UE_BAUNIT_T_LC_BUILDING_F, building_ids,
            self.__db.names.COL_UE_BAUNIT_T_PARCEL_F, feature_tid)

        # add building unit associated
        if self.__db.names.LC_BUILDING_UNIT_T in self.__constraint_types_of_parcels[
                self.parcel_type_ili_code]:
            add_features = self.__constraint_types_of_parcels[
                self.parcel_type_ili_code][
                    self.__db.names.LC_BUILDING_UNIT_T] is not None
        else:
            add_features = True

        if add_features:
            building_unit_ids = LADMData.get_list_of_features_ids(
                self.__layers[self.__db.names.LC_BUILDING_UNIT_T],
                self.__db.names.T_ID_F)

        new_features = LADMData.save_relations(
            self.__layers[self.__db.names.COL_UE_BAUNIT_T],
            self.__db.names.COL_UE_BAUNIT_T_LC_BUILDING_UNIT_F,
            building_unit_ids, self.__db.names.COL_UE_BAUNIT_T_PARCEL_F,
            feature_tid)

        return ParcelFinishFeatureCreationArgs(True, feature_tid, 1, None)
    def _validate(self, db, db_qr, layer_dict, tolerance, **kwargs):
        self.progress_changed.emit(5)
        ladm_queries = self._get_ladm_queries(db.engine)

        pre_res, pre_obj = self._check_prerrequisite_layers(layer_dict)
        if not pre_res:
            return pre_obj

        error_state = None

        res, records = ladm_queries.get_invalid_col_party_type_natural(db)
        self.progress_changed.emit(40)

        if res:
            error_state = LADMData().get_domain_code_from_value(
                db_qr, db_qr.names.ERR_ERROR_STATE_D,
                LADMNames.ERR_ERROR_STATE_D_ERROR_V)

            errors_rules = {
                self._ERROR_01: {
                    'geometries': list(),
                    'data': list()
                },
                self._ERROR_02: {
                    'geometries': list(),
                    'data': list()
                },
                self._ERROR_03: {
                    'geometries': list(),
                    'data': list()
                },
                self._ERROR_04: {
                    'geometries': list(),
                    'data': list()
                },
                self._ERROR_05: {
                    'geometries': list(),
                    'data': list()
                },
                self._ERROR_06: {
                    'geometries': list(),
                    'data': list()
                },
                self._ERROR_07: {
                    'geometries': list(),
                    'data': list()
                },
                self._ERROR_08: {
                    'geometries': list(),
                    'data': list()
                },
                self._ERROR_09: {
                    'geometries': list(),
                    'data': list()
                },
                self._ERROR_10: {
                    'geometries': list(),
                    'data': list()
                },
                self._ERROR_11: {
                    'geometries': list(),
                    'data': list()
                },
                self._ERROR_12: {
                    'geometries': list(),
                    'data': list()
                },
                self._ERROR_13: {
                    'geometries': list(),
                    'data': list()
                }
            }

            progress = 40
            record_count = 0

            for record in records:
                record_count += 1
                if record[db.names.LC_PARTY_T_BUSINESS_NAME_F] > 0:
                    error_data = [  # [obj_uuids, rel_obj_uuids, values, details, state]
                        [record[db.names.T_ILI_TID_F]], None, None,
                        self._errors[self._ERROR_01], error_state
                    ]
                    errors_rules[self._ERROR_01]['data'].append(error_data)

                if record[db.names.LC_PARTY_T_SURNAME_1_F] > 0:
                    error_data = [  # [obj_uuids, rel_obj_uuids, values, details, state]
                        [record[db.names.T_ILI_TID_F]], None, None,
                        self._errors[self._ERROR_02], error_state
                    ]
                    errors_rules[self._ERROR_02]['data'].append(error_data)

                if record[db.names.LC_PARTY_T_FIRST_NAME_1_F] > 0:
                    error_data = [  # [obj_uuids, rel_obj_uuids, values, details, state]
                        [record[db.names.T_ILI_TID_F]], None, None,
                        self._errors[self._ERROR_03], error_state
                    ]
                    errors_rules[self._ERROR_03]['data'].append(error_data)

                if record[db.names.LC_PARTY_T_DOCUMENT_TYPE_F] > 0:
                    error_data = [  # [obj_uuids, rel_obj_uuids, values, details, state]
                        [record[db.names.T_ILI_TID_F]], None, None,
                        self._errors[self._ERROR_04], error_state
                    ]
                    errors_rules[self._ERROR_04]['data'].append(error_data)

                if record[db.names.LC_PARTY_T_GENRE_F] > 0:
                    error_data = [  # [obj_uuids, rel_obj_uuids, values, details, state]
                        [record[db.names.T_ILI_TID_F]], None, None,
                        self._errors[self._ERROR_05], error_state
                    ]
                    errors_rules[self._ERROR_05]['data'].append(error_data)

                if record[db.names.LC_PARTY_T_SURNAME_1_F + '_' +
                          SPECIAL_CHARACTERS] > 0:
                    error_data = [  # [obj_uuids, rel_obj_uuids, values, details, state]
                        [record[db.names.T_ILI_TID_F]], None, None,
                        self._errors[self._ERROR_06], error_state
                    ]
                    errors_rules[self._ERROR_06]['data'].append(error_data)

                if record[db.names.LC_PARTY_T_SURNAME_1_F + '_' + DIGITS] > 0:
                    error_data = [  # [obj_uuids, rel_obj_uuids, values, details, state]
                        [record[db.names.T_ILI_TID_F]], None, None,
                        self._errors[self._ERROR_07], error_state
                    ]
                    errors_rules[self._ERROR_07]['data'].append(error_data)

                if record[db.names.LC_PARTY_T_FIRST_NAME_1_F + '_' +
                          SPECIAL_CHARACTERS] > 0:
                    error_data = [  # [obj_uuids, rel_obj_uuids, values, details, state]
                        [record[db.names.T_ILI_TID_F]], None, None,
                        self._errors[self._ERROR_08], error_state
                    ]
                    errors_rules[self._ERROR_08]['data'].append(error_data)

                if record[db.names.LC_PARTY_T_FIRST_NAME_1_F + '_' +
                          DIGITS] > 0:
                    error_data = [  # [obj_uuids, rel_obj_uuids, values, details, state]
                        [record[db.names.T_ILI_TID_F]], None, None,
                        self._errors[self._ERROR_09], error_state
                    ]
                    errors_rules[self._ERROR_09]['data'].append(error_data)

                if record[db.names.LC_PARTY_T_SURNAME_2_F + '_' +
                          SPECIAL_CHARACTERS] > 0:
                    error_data = [  # [obj_uuids, rel_obj_uuids, values, details, state]
                        [record[db.names.T_ILI_TID_F]], None, None,
                        self._errors[self._ERROR_10], error_state
                    ]
                    errors_rules[self._ERROR_10]['data'].append(error_data)

                if record[db.names.LC_PARTY_T_SURNAME_2_F + '_' + DIGITS] > 0:
                    error_data = [  # [obj_uuids, rel_obj_uuids, values, details, state]
                        [record[db.names.T_ILI_TID_F]], None, None,
                        self._errors[self._ERROR_11], error_state
                    ]
                    errors_rules[self._ERROR_11]['data'].append(error_data)

                if record[db.names.LC_PARTY_T_FIRST_NAME_2_F + '_' +
                          SPECIAL_CHARACTERS] > 0:
                    error_data = [  # [obj_uuids, rel_obj_uuids, values, details, state]
                        [record[db.names.T_ILI_TID_F]], None, None,
                        self._errors[self._ERROR_12], error_state
                    ]
                    errors_rules[self._ERROR_12]['data'].append(error_data)

                if record[db.names.LC_PARTY_T_FIRST_NAME_2_F + '_' +
                          DIGITS] > 0:
                    error_data = [  # [obj_uuids, rel_obj_uuids, values, details, state]
                        [record[db.names.T_ILI_TID_F]], None, None,
                        self._errors[self._ERROR_13], error_state
                    ]
                    errors_rules[self._ERROR_13]['data'].append(error_data)

                delta_progress = record_count * 50 / len(records)
                self.progress_changed.emit(progress + delta_progress)

            count = 0
            for error_key, errors_rule in errors_rules.items():
                if errors_rule:
                    self._save_errors(db_qr, error_key, errors_rule)
                    count += len(errors_rule['data'])

            self.progress_changed.emit(90)

        if count > 0:
            res_type = EnumQualityRuleResult.ERRORS
            msg = QCoreApplication.translate(
                "QualityRules",
                "{} natural parties with inconsistent were found.").format(
                    count)
        else:
            res_type = EnumQualityRuleResult.SUCCESS
            msg = QCoreApplication.translate(
                "QualityRules", "All natural parties have valid data.")

        self.progress_changed.emit(100)

        return QualityRuleExecutionResult(res_type, msg, count)
예제 #28
0
    def _validate(self, db, db_qr, layer_dict, tolerance, **kwargs):
        self.progress_changed.emit(5)
        pre_res, pre_obj = self._check_prerrequisite_layers(layer_dict)
        if not pre_res:
            return pre_obj

        boundary_point_layer = self._get_layer(layer_dict,
                                               db.names.LC_BOUNDARY_POINT_T)
        boundary_layer = self._get_layer(layer_dict, db.names.LC_BOUNDARY_T)
        point_bfs_layer = self._get_layer(layer_dict, db.names.POINT_BFS_T)
        id_field = db.names.T_ID_F

        dict_uuid_boundary = {
            f[id_field]: f[db.names.T_ILI_TID_F]
            for f in boundary_layer.getFeatures()
        }
        dict_uuid_boundary_point = {
            f[id_field]: f[db.names.T_ILI_TID_F]
            for f in boundary_point_layer.getFeatures()
        }

        # create dict with layer data
        id_field_idx = boundary_point_layer.fields().indexFromName(id_field)
        request = QgsFeatureRequest().setSubsetOfAttributes([id_field_idx])
        dict_boundary_point = {
            feature[id_field]: feature
            for feature in boundary_point_layer.getFeatures(request)
        }

        result = GeometryUtils.get_boundary_points_not_covered_by_boundary_nodes(
            db, boundary_point_layer, boundary_layer, point_bfs_layer,
            id_field)

        boundary_point_without_boundary_node = result[0]
        no_register_point_bfs = result[1]
        duplicate_in_point_bfs = result[2]

        self.progress_changed.emit(70)

        error_state = LADMData().get_domain_code_from_value(
            db_qr, db_qr.names.ERR_ERROR_STATE_D,
            LADMNames.ERR_ERROR_STATE_D_ERROR_V)

        errors_e01 = {'geometries': list(), 'data': list()}
        errors_e02 = {'geometries': list(), 'data': list()}
        errors_e03 = {'geometries': list(), 'data': list()}

        # boundary point without boundary node
        if boundary_point_without_boundary_node:
            for item in boundary_point_without_boundary_node:
                boundary_point_id = item  # boundary_point_id
                errors_e01['geometries'].append(
                    dict_boundary_point[boundary_point_id].geometry())
                error_data = [  # [obj_uuids, rel_obj_uuids, values, details, state]
                    [dict_uuid_boundary_point.get(boundary_point_id)], None,
                    None, self._errors[self._ERROR_01], error_state
                ]
                errors_e01['data'].append(error_data)
            self._save_errors(db_qr, self._ERROR_01, errors_e01)

        # No registered in point_bfs
        if no_register_point_bfs:
            for error_no_register in set(no_register_point_bfs):
                boundary_point_id = error_no_register[0]  # boundary_point_id
                boundary_id = error_no_register[1]  # boundary_id

                errors_e02['geometries'].append(
                    dict_boundary_point[boundary_point_id].geometry())
                error_data = [  # [obj_uuids, rel_obj_uuids, values, details, state]
                    [dict_uuid_boundary_point.get(boundary_point_id)],
                    [dict_uuid_boundary.get(boundary_id)], None,
                    self._errors[self._ERROR_02], error_state
                ]
                errors_e02['data'].append(error_data)
            self._save_errors(db_qr, self._ERROR_02, errors_e02)

        # Duplicate in point_bfs
        if duplicate_in_point_bfs:
            for error_duplicate in set(duplicate_in_point_bfs):
                boundary_point_id = error_duplicate[0]  # boundary_point_id
                boundary_id = error_duplicate[1]  # boundary_id

                errors_e03['geometries'].append(
                    dict_boundary_point[boundary_point_id].geometry())
                error_data = [  # [obj_uuids, rel_obj_uuids, values, details, state]
                    [dict_uuid_boundary_point.get(boundary_point_id)],
                    [dict_uuid_boundary.get(boundary_id)], None,
                    self._errors[self._ERROR_03], error_state
                ]
                errors_e03['data'].append(error_data)
            self._save_errors(db_qr, self._ERROR_03, errors_e03)

        self.progress_changed.emit(100)

        count = len(errors_e01['data']) + len(errors_e02['data']) + len(
            errors_e03['data'])

        if count > 0:
            res_type = EnumQualityRuleResult.ERRORS
            msg = QCoreApplication.translate(
                "QualityRules",
                "{} boundary points not covered by boundary nodes were found."
            ).format(count)
        else:
            res_type = EnumQualityRuleResult.SUCCESS
            msg = QCoreApplication.translate(
                "QualityRules",
                "All boundary points are covered by boundary nodes!")

        self.progress_changed.emit(100)

        return QualityRuleExecutionResult(res_type, msg, count)
예제 #29
0
    def _validate(self, db, db_qr, layer_dict, tolerance, **kwargs):
        self.progress_changed.emit(5)
        ladm_queries = self._get_ladm_queries(db.engine)

        pre_res, pre_obj = self._check_prerrequisite_layers(layer_dict)
        if not pre_res:
            return pre_obj

        error_state = None

        # First error type: parcel with no rights
        res, records = ladm_queries.get_parcels_with_no_right(db)
        count_e01_records = len(records)

        self.progress_changed.emit(40)

        if res:
            error_state = LADMData().get_domain_code_from_value(db_qr, db_qr.names.ERR_ERROR_STATE_D,
                                                                LADMNames.ERR_ERROR_STATE_D_ERROR_V)
            errors = {'geometries': list(), 'data': list()}
            for record in records:
                error_data = [  # [obj_uuids, rel_obj_uuids, values, details, state]
                    [record[db.names.T_ILI_TID_F]],
                    None,
                    None,
                    None,
                    error_state]
                errors['data'].append(error_data)

            self._save_errors(db_qr, self._ERROR_01, errors)

            self.progress_changed.emit(50)

        # Second error type: parcel with more than one domain right
        res, records = ladm_queries.get_parcels_with_repeated_domain_right(db)
        count_e02_records = len(records)

        self.progress_changed.emit(85)

        if res:
            # Reuse it if present, otherwise get it
            error_state = error_state if error_state is not None else LADMData().get_domain_code_from_value(db_qr,
                                                                                                            db_qr.names.ERR_ERROR_STATE_D,
                                                                                                            LADMNames.ERR_ERROR_STATE_D_ERROR_V)
            errors = {'geometries': list(), 'data': list()}
            for record in records:
                related_objects = record['dominios'].split(";")
                error_data = [  # [obj_uuids, rel_obj_uuids, values, details, state]
                    [record[db.names.T_ILI_TID_F]],
                    related_objects,
                    len(related_objects),
                    None,
                    error_state]
                errors['data'].append(error_data)

            self._save_errors(db_qr, self._ERROR_02, errors)

            self.progress_changed.emit(95)

        count = count_e01_records + count_e02_records
        if count > 0:
            res_type = EnumQualityRuleResult.ERRORS
            msg = QCoreApplication.translate("QualityRules", "{} parcels with inconsistent rights were found.").format(
                count)
        else:
            res_type = EnumQualityRuleResult.SUCCESS
            msg = QCoreApplication.translate("QualityRules", "All parcels have valid right relationships.")

        self.progress_changed.emit(100)

        return QualityRuleExecutionResult(res_type, msg, count)
예제 #30
0
 def __init__(self):
     self.app = AppInterface()
     self.ladm_data = LADMData()