示例#1
0
文件: QgsUtils.py 项目: tlh22/QGISFMV
    def CustomMessage(title, msg, informative="", icon="Critical"):
        ''' Custom Informative Message '''
        d = QMessageBox()
        d.setTextFormat(Qt.RichText)
        d.setWindowTitle(title)
        d.setWindowIcon(QIcon(QPixmap(":/imgFMV/images/icon.png")))
        d.setText(msg)
        d.setInformativeText(informative)
        d.setIconPixmap(QgsUtils.GetIcon(icon))
        d.addButton(QMessageBox.Yes)
        d.addButton(QMessageBox.No)
        d.setDefaultButton(QMessageBox.No)

        # Trick resize QMessageBox
        horizontalSpacer = QSpacerItem(500, 0, QSizePolicy.Minimum,
                                       QSizePolicy.Expanding)
        layout = d.layout()
        layout.addItem(horizontalSpacer, layout.rowCount(), 0, 1,
                       layout.columnCount())

        ret = d.exec_()
        return ret
class OneAtlas:
    def __init__(self, iface):
        self.iface = iface
        self.menu = 'OneAtlas'
        self.toolbar = self.iface.addToolBar(self.menu)
        self.mySearch = None

        # Connect function who diable layer button
        self.iface.currentLayerChanged.connect(
            self.disableLayerBtnByLayerSelection)

    # Add action to toolbar
    def addAction(self, menu, icon, callback):
        icon = QIcon(os.path.dirname(__file__) + f'/{icon}.png')
        action = QAction(icon, menu, self.iface.mainWindow())
        action.triggered.connect(callback)
        self.toolbar.addAction(action)
        self.iface.addPluginToMenu(self.menu, action)
        return action

    # Add plugins actions
    def initGui(self):
        self.searchAction = self.addAction('Search OneAtlas', 'logo',
                                           self.showMySearch)

        self.layerAction = self.addAction('Display Imagery', 'layer',
                                          self.stream)
        self.disableLayerBtnByLayerSelection(self.iface.activeLayer())
        # self.layerAction.setEnabled(False)

    # Remove the toolbar
    def unload(self):
        for action in self.toolbar.actions():
            self.iface.removePluginMenu(self.menu, action)
        self.iface.mainWindow().removeToolBar(self.toolbar)

    # Init then show the search dialog
    def showMySearch(self):
        if self.mySearch is None:
            self.mySearch = MySearch(self.iface)
        self.mySearch.show()

    # Disable layer button is active layer isn't valid
    def disableLayerBtnByLayerSelection(self, layer):
        # Try to disconnect last layer selection detection
        # TODO this is really dirty...
        try:
            self.activeLayer.selectionChanged.disconnect(
                self.disableLayerBtnByFeatureSelection)
        except:
            pass
        # Disable layer button
        self.layerAction.setEnabled(False)
        # Check if current selected layer is a VectorLayer
        if isinstance(layer, QgsVectorLayer):
            self.activeLayer = layer
            # Connect the selection changed signal
            self.activeLayer.selectionChanged.connect(
                self.disableLayerBtnByFeatureSelection)
            self.disableLayerBtnByFeatureSelection()

    # Check if attributes 'service' exist in selected features
    def disableLayerBtnByFeatureSelection(self):
        self.layerAction.setEnabled(False)
        if self.activeLayer.selectedFeatureCount() == 1:
            self.selectedFeature = self.activeLayer.selectedFeatures()[0]
            self.layerAction.setEnabled(
                self.selectedFeature.fields().indexFromName('service') != -1)

    # Stream image
    def stream(self):
        # Avoid auth exception if you reopen the project and don't open the search
        if self.mySearch == None:
            self.mySearch = MySearch(self.iface)

        # Get selected feature of active layer
        service = self.selectedFeature['service']

        # Setup raster params
        isWcs = False
        if service == 'BaseMap':
            if self.mySearch.bmAuth is None:
                try:
                    self.mySearch.bmSetAuth()
                except:
                    return
            username = self.mySearch.bmUsernameInput.text()
            password = self.mySearch.bmPasswordInput.text()
            layers = self.mySearch.bmGetLayer(self.selectedFeature['wmts'])
            styles = 'default'
            tileMatrixSet = '4326'
            urlAttr = 'wmts'
        elif service == 'Data':
            if self.mySearch.dtHeaders is None:
                try:
                    self.mySearch.dtSetAuth()
                except:
                    return
            username = '******'
            password = self.mySearch.dtApikeyInput.text()

            # Dialog for image choice (panchro/multi & wmts/wcs)
            self.msgBox = QMessageBox()
            self.msgBox.setWindowTitle('Airbus')

            protocolGroup = QGroupBox('Protocol')
            protocolGrid = QGridLayout()
            wmtsRadio = QRadioButton('WMTS')
            wcsRadio = QRadioButton('WCS')
            protocolGrid.addWidget(wmtsRadio, 0, 0)
            protocolGrid.addWidget(wcsRadio, 0, 1)
            protocolGroup.setLayout(protocolGrid)

            styleGroup = QGroupBox('Style')
            styleGrid = QGridLayout()
            multispectralRadio = QRadioButton('multispectral')
            panchromaticRadio = QRadioButton('panchromatic')
            styleGrid.addWidget(multispectralRadio, 0, 0)
            styleGrid.addWidget(panchromaticRadio, 0, 1)
            styleGroup.setLayout(styleGrid)

            self.msgBox.layout().addWidget(protocolGroup, 0, 0)
            self.msgBox.layout().addWidget(styleGroup, 1, 0)

            wmtsRadio.setChecked(True)
            if type(self.selectedFeature['wcs_multispectral']) != str:
                protocolGroup.setEnabled(False)

            multispectralRadio.setChecked(True)

            self.msgBox.setStandardButtons(QMessageBox.Abort | QMessageBox.Ok)
            reply = self.msgBox.exec_()
            if reply == QMessageBox.Abort:
                return
            if wmtsRadio.isChecked():
                urlAttr = 'wmts_'
                layers = 'default'
                styles = 'rgb'
                tileMatrixSet = 'EPSG4326'
            else:
                urlAttr = 'wcs_'
                isWcs = True
            if multispectralRadio.isChecked():
                urlAttr += 'multispectral'
            else:
                urlAttr += 'panchromatic'
        else:
            self.error(
                f'Service "{service}" of the feature ocg_fid={self.selectedFeature.id()} isn\'t recognized\nIt should be "Basemap" or "Data"'
            )
            return

        # Add a WMTS raster layer
        # Order of url parameters are important !
        # Why layers is required, maybe is an internal id for wmts gesture ?
        # What is styles ?
        try:
            url = self.selectedFeature[urlAttr]
            name = f'{service} {self.selectedFeature["id"]}'
            if isWcs:
                rlayer = QgsRasterLayer(
                    f'dpiMode=7&identifier=default&password={password}&url={url}&username={username}',
                    name, 'wcs')
            else:
                rlayer = QgsRasterLayer(
                    f'crs=EPSG:4326&dpiMode=7&format=image/png&layers={layers}&password={password}&styles={styles}&tileMatrixSet={tileMatrixSet}&url={url}&username={username}',
                    name, 'wms')
        except Exception as e:
            self.error(f'Error in protocol connection\n\n{str(e)}')
            return
        if rlayer.isValid() == False:
            self.error(f'Raster layer is invalid\n\n{rlayer.error()}')
            return

        QgsProject.instance().addMapLayer(rlayer)

    def error(self, msg):
        QMessageBox.critical(None, 'Airbus', msg)