コード例 #1
0
ファイル: composer_data_source.py プロジェクト: ollawone/stdm
 def __init__(self,
              dataSourceName="",
              category="",
              referenced_table_name=''):
     self._dataSourceName = dataSourceName
     self._dataSourceCategory = category
     self.referenced_table_name = referenced_table_name
     self._dataFieldmappings = ReverseDict()
     self._spatialFieldsConfig = None
コード例 #2
0
ファイル: utils.py プロジェクト: ollawone/stdm
def pg_layerNamesIDMapping():
    '''
    Returns a dictionary containing the original table names and corresponding layer IDs in the
    QGIS legend for only those layers from a postgres database.
    '''
    mapping = ReverseDict()
    layers = QgsProject.instance().mapLayers()

    for name, layer in layers.items():
        if hasattr(layer, 'dataProvider'):
            if layer.dataProvider().name() == 'postgres':
                layerConnStr = layer.dataProvider().dataSourceUri()
                dataSourceURI = QgsDataSourceUri(layerConnStr)
                mapping[dataSourceURI.table()] = layer.id()

    return mapping
コード例 #3
0
ファイル: validators.py プロジェクト: cb-flts/stdm
def lookup_values(lookup_entity):
    """
    Fetches the lookup values and stores them in a reversible collection
    i.e. you can get the lookup values from the primary keys or the primary
    keys from the lookup values.
    :param lookup_entity: Entity for the lookup values
    :type lookup_entity: ValueList
    :return: A bi-directional collection.
    :rtype: ReverseDict
    """
    lookup_items = ReverseDict()

    # Add all lookup values in the value list table
    vl_cls = entity_model(lookup_entity)
    if not vl_cls is None:
        vl_obj = vl_cls()
        res = vl_obj.queryObject().all()
        for r in res:
            pk_id = r.id
            lk_value = r.value
            lookup_items[pk_id] = lk_value

    return lookup_items
コード例 #4
0
ファイル: composer_data_source.py プロジェクト: ollawone/stdm
 def clear(self):
     """
     Clears the data source name and removes all data field mappings.
     """
     self._dataSourceName = ""
     self._dataFieldmappings = ReverseDict()
コード例 #5
0
ファイル: composer_data_source.py プロジェクト: ollawone/stdm
class ComposerDataSource:
    """
    Container for data source settings.
    """
    def __init__(self,
                 dataSourceName="",
                 category="",
                 referenced_table_name=''):
        self._dataSourceName = dataSourceName
        self._dataSourceCategory = category
        self.referenced_table_name = referenced_table_name
        self._dataFieldmappings = ReverseDict()
        self._spatialFieldsConfig = None

    def setName(self, dataSourceName):
        """
        Sets the data source name.
        """
        self._dataSourceName = dataSourceName

    def name(self):
        """
        Returns the data source name.
        """
        return self._dataSourceName

    def category(self):
        """
        Returns the category of the data source.
        """
        return self._dataSourceCategory

    def setCategory(self, category):
        """
        Set the category of the data source.
        """
        self._dataSourceCategory = category

    def setSpatialFieldsConfig(self, spFieldsConfig):
        """
        Set the spatial fields configuration object
        """
        self._spatialFieldsConfig = spFieldsConfig

    def addDataFieldMapping(self, dataField, composerItemId):
        """
        Add the name of the data field.
        """
        self._dataFieldmappings[dataField] = composerItemId

    def dataFieldMappings(self):
        """
        Returns the collection of data field mappings.
        """
        return self._dataFieldmappings

    def clear(self):
        """
        Clears the data source name and removes all data field mappings.
        """
        self._dataSourceName = ""
        self._dataFieldmappings = ReverseDict()

    def dataFieldName(self, composerItemId):
        """
        Returns the data field name corresponding to the composer item id.
        """
        if composerItemId in self._dataFieldmappings.reverse:
            return self._dataFieldmappings.reverse[composerItemId]
        else:
            return None

    def composerItemId(self, dataField):
        """
        Returns the composer item unique identifier corresponding to the given
        field.
        """
        if dataField in self._dataFieldmappings:
            return self._dataFieldmappings[dataField]
        else:
            return None

    def sqlSelectStatement(self):
        """
        Returns a sql select statement based on the data source and fields specified,as
        well as the spatial fields.
        """
        dataFields = list(self._dataFieldmappings.keys())

        #Get spatial fields and embed into the dataFields list
        if self._spatialFieldsConfig != None:
            spatialFieldsCollection = list(
                self._spatialFieldsConfig.spatialFieldsMapping().values())

            for spfEntry in spatialFieldsCollection:
                spFields = [spm.spatialField() for spm in spfEntry]

                labelFields = [spm.labelField() for spm in spfEntry]

                dataFields.extend(spFields)
                dataFields.extend(labelFields)

        if len(dataFields) == 0:
            return ""

        #Ensure you only have unique fields
        dataFieldsSet = set(dataFields)

        dtFieldsStr = ",".join(dataFieldsSet)

        return "SELECT {0} FROM {1}".format(dtFieldsStr, self._dataSourceName)

    @staticmethod
    def create(domDocument):
        """
        Create an instance of the ComposerDataSource object from a DOM document.
        Returns None if the domDocument is invalid.
        """
        dataSourceElem = domDocument.documentElement().firstChildElement(
            "DataSource")

        if dataSourceElem is None:
            return None

        dataSourceName = dataSourceElem.attribute("name")
        dataSourceCategory = dataSourceElem.attribute("category")
        referenced_table_name = dataSourceElem.attribute('referencedTable', '')
        composerDS = ComposerDataSource(dataSourceName, dataSourceCategory,
                                        referenced_table_name)

        #Get data fields
        dataFieldList = dataSourceElem.elementsByTagName("DataField")
        numItems = dataFieldList.length()

        for i in range(numItems):
            dataFieldElement = dataFieldList.item(i).toElement()
            dataFieldName = dataFieldElement.attribute("name")
            composerItemId = dataFieldElement.attribute("itemid")

            composerDS.addDataFieldMapping(dataFieldName, composerItemId)

        return composerDS

    @staticmethod
    def domElement(composerWrapper, domDocument):
        """
        Helper method that creates a data source DOM element from a composer wrapper instance.
        """
        from stdm.ui.composer import ComposerFieldSelector

        dataSourceElement = domDocument.createElement("DataSource")
        dataSourceElement.setAttribute("name",
                                       composerWrapper.selectedDataSource())
        dataSourceElement.setAttribute(
            "category", composerWrapper.selectedDataSourceCategory())
        dataSourceElement.setAttribute(
            "referencedTable", composerWrapper.selected_referenced_table())

        #Get the configured field names
        for uuid, fieldWidget in composerWrapper.widgetMappings().items():
            """
            Assert whether the item exists in the composition since the 'itemRemoved' signal cannot be used to 
            delete items from the collection as it only returns a QObject instead of a QgsComposerItem subclass.
            """
            composerItem = composerWrapper.composition().getComposerItemByUuid(
                uuid)

            if composerItem != None:
                if isinstance(fieldWidget, ComposerFieldSelector):
                    fieldName = fieldWidget.fieldName()

                    fieldElement = domDocument.createElement("DataField")
                    fieldElement.setAttribute("itemid", uuid)
                    fieldElement.setAttribute("name", fieldName)

                    dataSourceElement.appendChild(fieldElement)

        return dataSourceElement
コード例 #6
0
class ComposerDataSource:
    """
    Container for data source settings.
    """
    def __init__(self,
                 dataSourceName="",
                 category: str = "",
                 referenced_table_name: str = ''):
        self._dataSourceName = dataSourceName
        self._dataSourceCategory = category
        self.referenced_table_name = referenced_table_name
        self._dataFieldmappings = ReverseDict()
        self._spatialFieldsConfig = None

    def setName(self, dataSourceName):
        """
        Sets the data source name.
        """
        self._dataSourceName = dataSourceName

    def name(self):
        """
        Returns the data source name.
        """
        return self._dataSourceName

    def category(self) -> str:
        """
        Returns the category of the data source.
        """
        return self._dataSourceCategory

    def setCategory(self, category: str):
        """
        Set the category of the data source.
        """
        self._dataSourceCategory = category

    def setSpatialFieldsConfig(self, spFieldsConfig):
        """
        Set the spatial fields configuration object
        """
        self._spatialFieldsConfig = spFieldsConfig

    def addDataFieldMapping(self, dataField, composerItemId):
        """
        Add the name of the data field.
        """
        self._dataFieldmappings[dataField] = composerItemId

    def dataFieldMappings(self):
        """
        Returns the collection of data field mappings.
        """
        return self._dataFieldmappings

    def clear(self):
        """
        Clears the data source name and removes all data field mappings.
        """
        self._dataSourceName = ""
        self._dataFieldmappings = ReverseDict()

    def dataFieldName(self, composerItemId):
        """
        Returns the data field name corresponding to the composer item id.
        """
        if composerItemId in self._dataFieldmappings.reverse:
            return self._dataFieldmappings.reverse[composerItemId]
        else:
            return None

    def composerItemId(self, dataField):
        """
        Returns the composer item unique identifier corresponding to the given
        field.
        """
        if dataField in self._dataFieldmappings:
            return self._dataFieldmappings[dataField]
        else:
            return None

    def sqlSelectStatement(self):
        """
        Returns a sql select statement based on the data source and fields specified,as
        well as the spatial fields.
        """
        dataFields = list(self._dataFieldmappings.keys())

        # Get spatial fields and embed into the dataFields list
        if self._spatialFieldsConfig is not None:
            spatialFieldsCollection = list(
                self._spatialFieldsConfig.spatialFieldsMapping().values())

            for spfEntry in spatialFieldsCollection:
                spFields = [spm.spatialField() for spm in spfEntry]

                labelFields = [spm.labelField() for spm in spfEntry]

                dataFields.extend(spFields)
                dataFields.extend(labelFields)

        if len(dataFields) == 0:
            return ""

        # Ensure you only have unique fields
        dataFieldsSet = set(dataFields)

        dtFieldsStr = ",".join(dataFieldsSet)

        return "SELECT {0} FROM {1}".format(dtFieldsStr, self._dataSourceName)

    @staticmethod
    def from_layout(layout: QgsLayout) -> 'ComposerDataSource':
        """
        Creates a ComposerDataSource using properties from the specified layout
        """
        data_source_name = LayoutUtils.get_stdm_data_source_for_layout(layout)
        data_source_category = LayoutUtils.get_stdm_data_category_for_layout(
            layout)
        referenced_table_name = LayoutUtils.get_stdm_referenced_table_for_layout(
            layout)

        return ComposerDataSource(data_source_name, data_source_category,
                                  referenced_table_name)

    @staticmethod
    def create(document: QDomDocument):
        """
        Create an instance of the ComposerDataSource object from a DOM document.
        Returns None if the domDocument is invalid.
        """
        custom_properties = QgsObjectCustomProperties()
        custom_properties.readXml(document.documentElement())

        data_source_name = custom_properties.value(
            LayoutUtils.DATA_SOURCE_PROPERTY)
        data_category = custom_properties.value(
            LayoutUtils.DATA_CATEGORY_PROPERTY)
        referenced_table_name = custom_properties.value(
            LayoutUtils.REFERENCED_TABLE_PROPERTY)

        if not data_source_name:
            return None

        data_source = ComposerDataSource(data_source_name, data_category,
                                         referenced_table_name)
        return data_source

    @staticmethod
    def from_template_file(
            template_file: str) -> 'Optional[ComposerDataSource]':
        """
        Creates a ComposerDataSource object from the specified template file. If
        the file cannot be opened due to file permissions or if it does not exist
        then the function will return None.
        :param template_file: Absolute template file path.
        :type template_file: str
        :return: Composer data source object.
        :rtype: ComposerDataSource
        """
        t_file = QFile(template_file)

        # Check if the file exists
        if not t_file.exists():
            return None

        # Check if the file can be opened
        if not t_file.open(QIODevice.ReadOnly):
            return None

        template_doc = QDomDocument()

        # Populate dom document
        if template_doc.setContent(t_file):
            return ComposerDataSource.create(template_doc)

        return None