Ejemplo n.º 1
0
 def pkWidget(self):
     """
     Instanciates a push button with no border using a key as an icon to be
     used on rows associated with primary key attributes.
     """
     pb = QPushButton()
     pb.setIcon(QIcon(':/plugins/DsgTools/icons/key.png'))
     pb.setFlat(True)
     pb.blockSignals(True)
     pb.setObjectName("pkWidget")
     pb.setText("")
     return pb
Ejemplo n.º 2
0
 def attributeNameWidget(self, fieldName, isNotNull):
     """
     Retrieves a widget to be used into field table to expose field's name.
     :param fieldName: (str) fieldName to be exhibited.
     :param isNotNull: (bool) whether field is a mandatory attribute.
     :return: (QPushButton) a button ready to be setup to GUI.
     """
     pb = QPushButton()
     pb.setText(fieldName)
     pb.setFlat(True)
     pb.setEnabled(False)
     if isNotNull:
         pb.setStyleSheet(
             "*{ color:rgb(150, 10, 25); "\
             "background-color:rgba(255, 88, 116, 1.00); }"
         )
         pb.setToolTip(self.tr("Field cannot be empty"))
     else:
         pb.setStyleSheet("color: black;")
     return pb
Ejemplo n.º 3
0
    def draw(self, element: Union[Param, Seperator, Title, QLayoutItem]):
        '''
        add an element (parameter or style element) to the dialog and draw it

        Parameters
        ----------
        element : object
            parameter or style element to draw
        '''
        self.inputs = []
        # put param objects into grid, else added to the base layout
        if isinstance(element, Param):
            if not self._grid:
                self._grid = QGridLayout()
                self.layout.addLayout(self._grid)
            element.draw(self._grid, edit=True)
            if element.help_text:
                help_button = QPushButton('?')
                help_button.setMaximumWidth(20)
                help_button.setToolTip('Hilfe')
                help_button.setCursor(QCursor(Qt.PointingHandCursor))
                help_button.setFlat(True)
                font = help_button.font()
                font.setUnderline(True)
                font.setBold(True)
                help_button.setFont(font)
                help_button.clicked.connect(
                    lambda: self.show_help(element.help_text, expand=True))
                element.row.addWidget(help_button)
            if element.input:
                element.input.focus.connect(
                    lambda: self.show_help(element.help_text))
                self.inputs.append(element.input)
        else:
            self._grid = None
            if isinstance(element, QLayoutItem):
                self.layout.addItem(element)
            else:
                element.draw(self.layout)
        self.adjustSize()
    def initGui(self):
        # Add GUI elements
        self.splash_screen = ui.SplashScreen(self)
        self.config_dialog = ui.ConfigDialog()

        self.toolbar = self.iface.addToolBar("Travel Time Platform Toolbar")

        # Logo
        button = QPushButton(resources.logo, "")
        button.setIconSize(QSize(112, 30))
        button.setFlat(True)
        button.pressed.connect(self.show_splash)
        self.toolbar.addWidget(button)
        self.toolbar.addSeparator()

        # Show toolbox action
        self.action_show_toolbox = QAction(resources.icon, tr("Show the toolbox"), self.iface.mainWindow())
        self.action_show_toolbox.triggered.connect(self.show_toolbox)
        self.toolbar.addAction(self.action_show_toolbox)
        self.iface.addPluginToMenu(u"&Travel Time Platform", self.action_show_toolbox)
        self.toolbar.addSeparator()

        # Show help actions
        self.action_show_help = QAction(resources.icon_help, tr("Help"), self.iface.mainWindow())
        self.action_show_help.triggered.connect(self.show_splash)
        self.toolbar.addAction(self.action_show_help)
        self.iface.addPluginToMenu(u"&Travel Time Platform", self.action_show_help)

        # Show config actions
        self.action_show_config = QAction(resources.icon_config, tr("Configure Travel Time Platform plugin"), self.iface.mainWindow())
        self.action_show_config.triggered.connect(self.show_config)
        self.toolbar.addAction(self.action_show_config)
        self.iface.addPluginToMenu(u"&Travel Time Platform", self.action_show_config)

        # Add the provider to the registry
        QgsApplication.processingRegistry().addProvider(self.provider)

        # Show splash screen
        if not QSettings().value('travel_time_platform/spashscreen_dontshowagain', False, type=bool):
            self.show_splash()
Ejemplo n.º 5
0
class PlanetOrderReviewWidget(QWidget):

    selectedImagesChanged = pyqtSignal()

    def __init__(self, item_type, bundle_type, images, add_clip,
                 add_harmonize):
        super().__init__()

        self.item_type = item_type
        self.bundle_type = bundle_type
        self.images = images
        self.add_clip = add_clip
        self.add_harmonize = add_harmonize

        layout = QVBoxLayout()
        layout.setMargin(0)
        item_types_names = PlanetClient.getInstance().item_types_names()
        labelName = IconLabel(
            f"<b>{item_types_names[self.item_type]} - {bundle_type}</b>",
            SATELLITE_ICON,
        )
        labelNumItems = IconLabel(f"{len(images)} items", NITEMS_ICON)
        gridlayout = QGridLayout()
        gridlayout.setMargin(0)
        gridlayout.addWidget(labelNumItems, 0, 0)
        self.btnDetails = QPushButton()
        self.btnDetails.setFlat(True)
        self.btnDetails.setIcon(EXPAND_MORE_ICON)
        self.btnDetails.clicked.connect(self._btnDetailsClicked)
        gridlayout.addWidget(self.btnDetails, 0, 2)
        gridlayout.addWidget(labelName, 1, 0, 1, 3)
        layout.addLayout(gridlayout)
        self.widgetDetails = QWidget()
        layout.addWidget(self.widgetDetails)
        line = QFrame()
        line.setFrameShape(QFrame.HLine)
        line.setFrameShadow(QFrame.Sunken)
        layout.addWidget(line)

        self.setLayout(layout)

        self.widgetDetails.hide()
        self.updateGeometry()

        self.populate_details()

    def populate_details(self):
        self.imgWidgets = []
        layout = QGridLayout()
        layout.setMargin(0)
        layout.setVerticalSpacing(15)
        layout.setColumnStretch(0, 1)
        layout.setColumnStretch(2, 1)
        self.chkClip = None
        self.chkHarmonize = None
        if self.add_clip:
            layout.addWidget(QLabel("<b>Clipping</b>"), 0, 1, Qt.AlignCenter)
            layout.addWidget(
                QLabel("Only get items delivered within your AOI"), 1, 1,
                Qt.AlignCenter)
            self.chkClip = QCheckBox("Clip items to AOI")
            enabled = QSettings().value(
                f"{SETTINGS_NAMESPACE}/{ENABLE_CLIP_SETTING}", False)
            self.chkClip.setChecked(str(enabled).lower() == str(True).lower())
            self.chkClip.stateChanged.connect(self.checkStateChanged)
            layout.addWidget(self.chkClip, 2, 1, Qt.AlignCenter)
        if self.add_harmonize:
            layout.addWidget(QLabel("<b>Harmonization</b>"), 3, 1,
                             Qt.AlignCenter)
            layout.addWidget(
                QLabel(
                    "Radiometrically harmonize imagery captured by one satellite "
                    "instrument type to imagery capture by another"),
                4,
                1,
                Qt.AlignCenter,
            )
            self.chkHarmonize = QCheckBox("Harmonize")
            enabled = QSettings().value(
                f"{SETTINGS_NAMESPACE}/{ENABLE_HARMONIZATION_SETTING}", False)
            self.chkHarmonize.setChecked(
                str(enabled).lower() == str(True).lower())
            self.chkHarmonize.stateChanged.connect(self.checkStateChanged)
            layout.addWidget(self.chkHarmonize, 5, 1, Qt.AlignCenter)
        layout.addWidget(QLabel("<b>Review Items</b>"), 6, 1, Qt.AlignCenter)
        layout.addWidget(
            QLabel(
                "We recommend deselecting items that appear to have no pixels"
            ),
            7,
            1,
            Qt.AlignCenter,
        )

        sublayout = QGridLayout()
        sublayout.setMargin(0)
        for i, img in enumerate(self.images):
            w = ImageReviewWidget(img)
            w.selectedChanged.connect(self.selectedImagesChanged.emit)
            row = i // 4
            col = i % 4 + 1
            sublayout.addWidget(w, row, col)
            self.imgWidgets.append(w)
        layout.addLayout(sublayout, 8, 1, Qt.AlignCenter)

        self.widgetDetails.setLayout(layout)

    def checkStateChanged(self):
        self.selectedImagesChanged.emit()

    def selected_images(self):
        return [w.image for w in self.imgWidgets if w.selected()]

    def clipping(self):
        if self.chkClip is None:
            return False
        else:
            return self.chkClip.isChecked()

    def harmonize(self):
        if self.chkHarmonize is None:
            return False
        else:
            return self.chkHarmonize.isChecked()

    def _btnDetailsClicked(self):
        if self.widgetDetails.isVisible():
            self.widgetDetails.hide()
            self.btnDetails.setIcon(EXPAND_MORE_ICON)
        else:
            self.widgetDetails.show()
            self.btnDetails.setIcon(EXPAND_LESS_ICON)
        self.updateGeometry()

    def expand(self):
        self.widgetDetails.show()
        self.btnDetails.setIcon(EXPAND_LESS_ICON)
        self.updateGeometry()
Ejemplo n.º 6
0
class PlanetOrderItemTypeWidget(QWidget):

    selectionChanged = pyqtSignal()

    def __init__(self, item_type, images):
        super().__init__()

        self.thumbnails = []

        self.item_type = item_type
        self.images = images

        layout = QGridLayout()
        layout.setMargin(0)

        self.labelThumbnail = QLabel()
        pixmap = QPixmap(PLACEHOLDER_THUMB, "SVG")
        thumb = pixmap.scaled(96, 96, Qt.KeepAspectRatio,
                              Qt.SmoothTransformation)
        self.labelThumbnail.setPixmap(thumb)
        self.labelThumbnail.setFixedSize(96, 96)
        layout.addWidget(self.labelThumbnail, 0, 0, 3, 1)

        for image in images:
            url = f"{image['_links']['thumbnail']}?api_key={PlanetClient.getInstance().api_key()}"
            download_thumbnail(url, self)

        labelName = IconLabel(
            f"<b>{PlanetClient.getInstance().item_types_names()[self.item_type]}</b>",
            SATELLITE_ICON,
        )
        labelNumItems = IconLabel(f"{len(images)} items", NITEMS_ICON)
        layout.addWidget(labelNumItems, 0, 1)
        layout.addWidget(labelName, 1, 1)

        self.btnDetails = QPushButton()
        self.btnDetails.setFlat(True)
        self.btnDetails.setIcon(EXPAND_MORE_ICON)
        self.btnDetails.clicked.connect(self._btnDetailsClicked)
        layout.addWidget(self.btnDetails, 0, 2)

        self.widgetDetails = QWidget()
        layout.addWidget(self.widgetDetails, 3, 0, 1, 3)

        line = QFrame()
        line.setFrameShape(QFrame.HLine)
        line.setFrameShadow(QFrame.Sunken)
        layout.addWidget(line, 4, 0, 1, 3)

        self.setLayout(layout)

        self.widgetDetails.hide()
        self.updateGeometry()

        self.populate_details()

    def populate_details(self):
        self.bundleWidgets = []

        client = PlanetClient.getInstance()
        permissions = [img[PERMISSIONS] for img in self.images]
        item_bundles = client.bundles_for_item_type(self.item_type,
                                                    permissions=permissions)
        default = default_bundles.get(self.item_type, "")

        def _center(obj):
            hlayout = QHBoxLayout()
            hlayout.addStretch()
            hlayout.addWidget(obj)
            hlayout.addStretch()
            return hlayout

        layout = QVBoxLayout()
        layout.setMargin(0)
        layout.setSpacing(20)

        layout.addLayout(_center(QLabel("<b>RECTIFIED ASSETS</b>")))

        gridlayout = QGridLayout()
        gridlayout.setMargin(0)

        widgets = {}
        i = 0
        for bundleid, bundle in item_bundles.items():
            if bundle["rectification"] == "orthorectified":
                name = bundle["name"]
                description = bundle["description"]
                udm = bundle.get("auxiliaryFiles",
                                 "").lower().startswith("udm2")
                assets = bundle["assets"][self.item_type]
                can_harmonize = ("ortho_analytic_4b_sr" in assets
                                 or "ortho_analytic_8b_sr" in assets)
                w = PlanetOrderBundleWidget(bundleid, name, description, udm,
                                            can_harmonize, True)
                gridlayout.addWidget(w, i // 2, i % 2)
                w.setSelected(False)
                widgets[bundleid] = w
                w.selectionChanged.connect(
                    partial(self._bundle_selection_changed, w))
                self.bundleWidgets.append(w)
                i += 1

        selected = False
        for defaultid in default:
            for bundleid, w in widgets.items():
                if defaultid == bundleid:
                    w.setSelected(True)
                    selected = True
                    break
            if selected:
                break

        layout.addLayout(gridlayout)

        self.labelUnrectified = QLabel("<b>UNRECTIFIED ASSETS</b>")
        layout.addLayout(_center(self.labelUnrectified))

        self.widgetUnrectified = QWidget()

        gridlayoutUnrect = QGridLayout()
        gridlayoutUnrect.setMargin(0)

        i = 0
        for bundleid, bundle in item_bundles.items():
            if bundle["rectification"] != "orthorectified":
                name = bundle["name"]
                description = bundle["description"]
                udm = bundle.get("auxiliaryFiles",
                                 "").lower().startswith("udm2")
                assets = bundle["assets"][self.item_type]
                can_harmonize = ("ortho_analytic_4b_sr" in assets
                                 or "ortho_analytic_8b_sr" in assets)
                w = PlanetOrderBundleWidget(bundleid, name, description, udm,
                                            can_harmonize, False)
                gridlayoutUnrect.addWidget(w, i // 2, i % 2)
                w.selectionChanged.connect(
                    partial(self._bundle_selection_changed, w))
                self.bundleWidgets.append(w)
                i += 1

        self.widgetUnrectified.setLayout(gridlayoutUnrect)
        layout.addWidget(self.widgetUnrectified)

        self.labelMore = QLabel('<a href="#">+ Show More</a>')
        self.labelMore.setOpenExternalLinks(False)
        self.labelMore.setTextInteractionFlags(Qt.LinksAccessibleByMouse)
        self.labelMore.linkActivated.connect(self._showMoreClicked)
        layout.addLayout(_center(self.labelMore))

        self.widgetUnrectified.hide()
        self.labelUnrectified.hide()
        self.widgetDetails.setLayout(layout)

    def _bundle_selection_changed(self, widget):
        for w in self.bundleWidgets:
            if widget != w:
                w.setSelected(False, False)
        self.selectionChanged.emit()

    def _showMoreClicked(self):
        visible = self.widgetUnrectified.isVisible()
        self.widgetUnrectified.setVisible(not visible)
        self.labelUnrectified.setVisible(not visible)
        if visible:
            self.labelMore.setText('<a href="#">+ Show More</a>')
        else:
            self.labelMore.setText('<a href="#">- Show Less</a>')

    def expand(self):
        self.widgetDetails.show()
        self.btnDetails.setIcon(EXPAND_LESS_ICON)
        self.updateGeometry()

    def _btnDetailsClicked(self):
        if self.widgetDetails.isVisible():
            self.widgetDetails.hide()
            self.btnDetails.setIcon(EXPAND_MORE_ICON)
        else:
            self.widgetDetails.show()
            self.btnDetails.setIcon(EXPAND_LESS_ICON)
        self.updateGeometry()

    def bundles(self):
        bundles = []
        for w in self.bundleWidgets:
            if w.selected():
                bundle = {}
                bundle["id"] = w.bundleid
                bundle["name"] = w.name
                bundle["filetype"] = w.filetype()
                bundle["udm"] = w.udm
                bundle["rectified"] = w.rectified
                bundle["canharmonize"] = w.can_harmonize
                bundles.append(bundle)
        return bundles

    def set_thumbnail(self, img):
        thumbnail = QPixmap(img)
        self.thumbnails.append(
            thumbnail.scaled(96, 96, Qt.KeepAspectRatio,
                             Qt.SmoothTransformation))

        if len(self.images) == len(self.thumbnails):
            bboxes = [img[GEOMETRY] for img in self.images]
            pixmap = createCompoundThumbnail(bboxes, self.thumbnails)
            thumb = pixmap.scaled(128, 128, Qt.KeepAspectRatio,
                                  Qt.SmoothTransformation)
            self.labelThumbnail.setPixmap(thumb)
    def initGui(self):
        # Add GUI elements
        self.splash_screen = ui.SplashScreen(self)
        self.config_dialog = ui.ConfigDialog()
        self.tilesManager = tiles.TilesManager()

        self.toolbar = self.iface.addToolBar("Travel Time Platform Toolbar")

        # Logo
        button = QPushButton(resources.logo, "")
        button.setIconSize(QSize(112, 30))
        button.setFlat(True)
        button.pressed.connect(self.show_splash)
        self.toolbar.addWidget(button)
        self.toolbar.addSeparator()

        # Show toolbox action
        self.action_show_toolbox = QAction(resources.icon_general,
                                           tr("Show the toolbox"),
                                           self.iface.mainWindow())
        self.action_show_toolbox.triggered.connect(self.show_toolbox)
        self.toolbar.addAction(self.action_show_toolbox)
        self.iface.addPluginToMenu(u"&Travel Time Platform",
                                   self.action_show_toolbox)

        # Add tiles
        tiles_menu = QMenu()
        for key, tile in self.tilesManager.tiles.items():
            action = QAction(tile["resource"], tile["label"], tiles_menu)
            action.triggered.connect(
                functools.partial(self.tilesManager.add_layer, key))
            action.setEnabled(self.tilesManager.has_tiles)
            tiles_menu.addAction(action)
        if not self.tilesManager.has_tiles:
            action = QAction(tr("Request access to backgrounds"), tiles_menu)
            action.triggered.connect(
                lambda: self.tilesManager.request_access())
            tiles_menu.addAction(action)

        tiles_button = QToolButton()
        tiles_button.setToolTip(tr("Add background"))
        tiles_button.setIcon(resources.icon_tiles)
        tiles_button.setMenu(tiles_menu)
        tiles_button.setPopupMode(QToolButton.InstantPopup)

        # self.action_show_toolbox.triggered.connect(self.show_toolbox)
        self.toolbar.addWidget(tiles_button)
        # self.iface.addPluginToMenu(u"&Travel Time Platform", self.action_show_toolbox)
        self.toolbar.addSeparator()

        # Show help actions
        self.action_show_help = QAction(resources.icon_help, tr("Help"),
                                        self.iface.mainWindow())
        self.action_show_help.triggered.connect(self.show_splash)
        self.toolbar.addAction(self.action_show_help)
        self.iface.addPluginToMenu(u"&Travel Time Platform",
                                   self.action_show_help)

        # Show config actions
        self.action_show_config = QAction(
            resources.icon_config,
            tr("Configure Travel Time Platform plugin"),
            self.iface.mainWindow(),
        )
        self.action_show_config.triggered.connect(self.show_config)
        self.toolbar.addAction(self.action_show_config)
        self.iface.addPluginToMenu(u"&Travel Time Platform",
                                   self.action_show_config)

        # Add the provider to the registry
        QgsApplication.processingRegistry().addProvider(self.provider)

        # Show splash screen
        if not QSettings().value(
                "travel_time_platform/spashscreen_dontshowagain", False,
                type=bool):
            self.show_splash()
    def initGui(self):
        # Add GUI elements
        self.splash_screen = ui.SplashScreen(self)
        self.config_dialog = ui.ConfigDialog()
        self.help_dialog = ui.HelpWidget(self)
        self.tilesManager = tiles.TilesManager(self)

        self.toolbar = self.iface.addToolBar("TravelTime platform Toolbar")

        # Logo
        button = QPushButton(resources.logo, "")
        button.setIconSize(QSize(112, 30))
        button.setFlat(True)
        button.pressed.connect(self.show_splash)
        self.toolbar.addWidget(button)

        self.toolbar.addSeparator()

        # Show toolbox action
        self.action_show_toolbox = QAction(resources.icon_toolbox,
                                           tr("Show the toolbox"),
                                           self.iface.mainWindow())
        self.action_show_toolbox.triggered.connect(self.show_toolbox)
        self.toolbar.addAction(self.action_show_toolbox)
        self.iface.addPluginToMenu(u"&TravelTime platform",
                                   self.action_show_toolbox)

        self.toolbar.addSeparator()

        # Express timemap action
        self.express_time_map_action = express.ExpressTimeMapAction(self)
        self.toolbar.addAction(self.express_time_map_action)

        # Express timefilter action
        self.express_time_filter_action = express.ExpressTimeFilterAction(self)
        self.toolbar.addAction(self.express_time_filter_action)

        # Express route action
        self.express_route_action = express.ExpressRouteAction(self)
        self.toolbar.addAction(self.express_route_action)

        self.toolbar.addSeparator()

        # Show tiles action
        self.action_show_tiles = QAction(resources.icon_tiles,
                                         tr("Add a background layer"),
                                         self.iface.mainWindow())
        self.action_show_tiles.triggered.connect(self.show_tiles)
        self.toolbar.addAction(self.action_show_tiles)
        self.iface.addPluginToMenu(u"&TravelTime platform",
                                   self.action_show_tiles)

        # Show help actions
        self.action_show_help = QAction(resources.icon_help, tr("Help"),
                                        self.iface.mainWindow())
        self.action_show_help.triggered.connect(self.show_help)
        self.toolbar.addAction(self.action_show_help)
        self.iface.addPluginToMenu(u"&TravelTime platform",
                                   self.action_show_help)

        # Show config actions
        self.action_show_config = QAction(
            resources.icon_config,
            tr("Configure TravelTime platform plugin"),
            self.iface.mainWindow(),
        )
        self.action_show_config.triggered.connect(self.show_config)
        self.toolbar.addAction(self.action_show_config)
        self.iface.addPluginToMenu(u"&TravelTime platform",
                                   self.action_show_config)

        # Add the provider to the registry
        QgsApplication.processingRegistry().addProvider(self.provider)

        # Show splash screen
        if not QSettings().value(
                "traveltime_platform/spashscreen_dontshowagain", False,
                type=bool):
            self.show_splash()
class LayerTreeImageLegendWidget(QWidget):
    """
    Layer tree widget for displaying image legend in a raster layer
    """
    def __init__(self, layer):
        super().__init__()
        self.layer = layer
        # Is legend a png file?
        self.my_img = os.path.splitext(layer.source())[0] + '.legend.png'
        if not os.path.exists(self.my_img):
            # No, is it a jpg?
            self.my_img = os.path.splitext(layer.source())[0] + '.legend.jpg'
            if not os.path.exists(self.my_img):
                # No: is this raster using a common legend?
                pwd = os.getcwd()
                compath = os.path.split(layer.source())[0]
                os.chdir(compath)
                englob = glob.glob("*.legendcommon.*")
                if len(englob) > 0:
                    # Yes
                    self.my_img = os.path.join(compath, self.getMy_Img())
                else:
                    # No: abort
                    os.chdir(pwd)
                    return
                #
                os.chdir(pwd)

        im = Image.open(self.my_img)
        w, h = im.size

        self.setAutoFillBackground(False)
        self.my_pix = QPixmap(self.my_img)
        self.imgleg = QPushButton()
        self.imgleg.setIcon(QIcon(self.my_pix))
        self.imgleg.setCheckable(False)
        self.imgleg.setFlat(True)
        if w >= h:
            self.imgleg.setIconSize(QSize(200, int(200 * h / w)))
        else:
            self.imgleg.setIconSize(QSize(int(200 * w / h), 200))
        self.imgleg.setSizePolicy(QSizePolicy.MinimumExpanding,
                                  QSizePolicy.MinimumExpanding)

        layout = QHBoxLayout()
        spacer = QSpacerItem(1, 0, QSizePolicy.MinimumExpanding,
                             QSizePolicy.Minimum)
        layout.addWidget(self.imgleg)
        layout.addItem(spacer)
        self.setLayout(layout)

        if self.layer.type() == QgsMapLayer.RasterLayer:
            self.imgleg.released.connect(self.showLegend)

    def showLegend(self):
        """
        Triggered when the image legend button is released after click/press.
        """
        webbrowser.open('file:///' + self.my_img)

    def getMy_Img(self):
        """
        Find and return the common legend file.
           Can only be 1 common legend per folder.
        """
        qq = map(glob.glob, ["*.legendcommon.png", "*.legendcommon.jpg"])
        s = ''
        for q in qq:
            try:
                # qq is made of two lists, one should be empty the other one should only
                #  have one element: the common legend
                # If empty list then assignment will cause an error, so at the end only
                #  one element is stored in s
                s = q[0]
            except:
                pass
        return s
Ejemplo n.º 10
0
class FinderBox(QComboBox):

    running = False
    to_finish = 0

    search_started = pyqtSignal()
    search_finished = pyqtSignal()

    def __init__(self, finders, iface, parent=None):
        self.iface = iface
        self.mapCanvas = iface.mapCanvas()
        self.marker = None
        self.rubber = QgsRubberBand(self.mapCanvas)
        self.rubber.setColor(QColor(255, 255, 50, 200))
        self.rubber.setIcon(self.rubber.ICON_CIRCLE)
        self.rubber.setIconSize(15)
        self.rubber.setWidth(4)
        self.rubber.setBrushStyle(Qt.NoBrush)

        QComboBox.__init__(self, parent)
        self.setEditable(True)
        self.setInsertPolicy(QComboBox.InsertAtTop)
        self.setMinimumHeight(27)
        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)

        self.insertSeparator(0)
        self.lineEdit().returnPressed.connect(self.search)

        self.result_view = QTreeView()
        self.result_view.setHeaderHidden(True)
        self.result_view.setMinimumHeight(300)
        self.result_view.activated.connect(self.itemActivated)
        self.result_view.pressed.connect(self.itemPressed)
        self.setView(self.result_view)

        self.result_model = ResultModel(self)
        self.setModel(self.result_model)

        self.finders = finders
        for finder in list(self.finders.values()):
            finder.result_found.connect(self.result_found)
            finder.limit_reached.connect(self.limit_reached)
            finder.finished.connect(self.finished)

        self.clearButton = QPushButton(self)
        self.clearButton.setIcon(
            QIcon(":/plugins/quickfinder/icons/draft.svg"))
        self.clearButton.setText('')
        self.clearButton.setFlat(True)
        self.clearButton.setCursor(QCursor(Qt.ArrowCursor))
        self.clearButton.setStyleSheet('border: 0px; padding: 0px;')
        self.clearButton.clicked.connect(self.clear)

        layout = QHBoxLayout(self)
        self.setLayout(layout)
        layout.addStretch()
        layout.addWidget(self.clearButton)
        layout.addSpacing(20)

        button_size = self.clearButton.sizeHint()
        # frameWidth = self.lineEdit().style().pixelMetric(QtGui.QStyle.PM_DefaultFrameWidth)
        padding = button_size.width()  # + frameWidth + 1
        self.lineEdit().setStyleSheet('QLineEdit {padding-right: %dpx; }' %
                                      padding)

    def __del__(self):
        if self.rubber:
            self.iface.mapCanvas().scene().removeItem(self.rubber)
            del self.rubber

    #clear marker that the lonlat seted
    def clearMarker(self):
        self.mapCanvas.scene().removeItem(self.marker)
        self.marker = None

    def clearSelection(self):
        self.result_model.setSelected(None, self.result_view.palette())
        self.rubber.reset()
        #self.clearMarker()

    def clear(self):
        self.clearSelection()
        self.result_model.clearResults()
        self.lineEdit().setText('')

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Escape:
            self.clearSelection()
            self.clearMarker()
        QComboBox.keyPressEvent(self, event)

    def lnglatFinder(self, to_find):
        import re
        m = re.match(r'(?P<lon>-?\d*(.\d+))\s+(?P<lat>-?\d*(.\d+))', to_find)
        if not m:
            return False
        x = float(m.group('lon'))
        y = float(m.group('lat'))
        return self.zoomLnglat(x, y)

    def zoomLnglat(self, lng, lat):
        x, y = lng, lat

        canvas = self.mapCanvas
        currExt = canvas.extent()
        canvasCenter = currExt.center()
        dx = float(x) - canvasCenter.x()
        dy = float(y) - canvasCenter.y()

        xMin = currExt.xMinimum() + dx
        xMax = currExt.xMaximum() + dx
        yMin = currExt.yMinimum() + dy
        yMax = currExt.yMaximum() + dy

        rect = QgsRectangle(xMin, yMin, xMax, yMax)
        canvas.setExtent(rect)
        pt = QgsPointXY(float(x), float(y))
        self.marker = QgsVertexMarker(canvas)
        self.marker.setCenter(pt)
        self.marker.setIconSize(18)
        self.marker.setPenWidth(2)
        self.marker.setIconType(QgsVertexMarker.ICON_CROSS)
        canvas.refresh()
        return True

#    def geocodeFinder(self, to_finder):
#        print(to_finder[:2])
#        if not to_finder[:2] == 'b:':
#            return False
#
#        address = to_finder[2:]
#        url = MySettings().value("baiduUrl")
#        url = url + parse.quote(address)
#
#        response = request.urlopen(url)
#        content = response.read()
#        data = json.loads(content)
#        print(data)
#        lng, lat = (data['result']['location']['lng'], data['result']['location']['lat'])
#        from .cood_trans import bd09_to_wgs84
#        lng, lat = bd09_to_wgs84(lng, lat)
#        print(f'{lng}-{lat}')
#        return self.zoomLnglat(lng, lat)

    def search(self):
        #  self.geocode()
        if self.running:
            return

        to_find = self.lineEdit().text()
        if not to_find or to_find == '':
            return
#        if not (self.lnglatFinder(to_find) or self.geocodeFinder(to_find)):
        if not self.lnglatFinder(to_find):
            self.showPopup()

        self.running = True
        self.search_started.emit()

        self.clearSelection()
        self.result_model.clearResults()
        self.result_model.truncateHistory(MySettings().value("historyLength"))
        self.result_model.setLoading(True)

        QCoreApplication.processEvents(QEventLoop.ExcludeUserInputEvents)

        self.finders_to_start = []
        for finder in list(self.finders.values()):
            if finder.activated():
                self.finders_to_start.append(finder)

        bbox = self.mapCanvas.fullExtent()

        while len(self.finders_to_start) > 0:
            finder = self.finders_to_start[0]
            self.finders_to_start.remove(finder)
            self.result_model.addResult(finder.name)
            finder.start(to_find, bbox=bbox)

        # For case there is no finder activated
        self.finished(None)

    def stop(self):
        self.finders_to_start = []
        for finder in list(self.finders.values()):
            if finder.is_running():
                finder.stop()
        self.finished(None)

    def result_found(self, finder, layername, value, geometry, srid):
        self.result_model.addResult(finder.name, layername, value, geometry,
                                    srid)
        self.result_view.expandAll()

    def limit_reached(self, finder, layername):
        self.result_model.addEllipsys(finder.name, layername)

    def finished(self, finder):
        if len(self.finders_to_start) > 0:
            return
        for finder in list(self.finders.values()):
            if finder.is_running():
                return

        self.running = False
        self.search_finished.emit()

        self.result_model.setLoading(False)

        QCoreApplication.processEvents(QEventLoop.ExcludeUserInputEvents)

    def itemActivated(self, index):
        item = self.result_model.itemFromIndex(index)
        self.showItem(item)

    def itemPressed(self, index):
        item = self.result_model.itemFromIndex(index)
        if QApplication.mouseButtons() == Qt.LeftButton:
            self.showItem(item)

    def showItem(self, item):
        if isinstance(item, ResultItem):
            self.result_model.setSelected(item, self.result_view.palette())
            geometry = self.transform_geom(item)
            self.rubber.reset(geometry.type())
            self.rubber.setToGeometry(geometry, None)
            self.zoom_to_rubberband()
            return

        if isinstance(item, GroupItem):
            child = item.child(0)
            if isinstance(child, ResultItem):
                self.result_model.setSelected(item, self.result_view.palette())
                self.rubber.reset(child.geometry.type())
                for i in range(0, item.rowCount()):
                    geometry = self.transform_geom(item.child(i))
                    self.rubber.addGeometry(geometry, None)
                self.zoom_to_rubberband()
            return

        if item.__class__.__name__ == 'QStandardItem':
            self.clearSelection()

    def transform_geom(self, item):
        src_crs = QgsCoordinateReferenceSystem()
        src_crs.createFromSrid(item.srid)
        dest_crs = self.mapCanvas.mapSettings().destinationCrs()
        geom = QgsGeometry(item.geometry)
        geom.transform(
            QgsCoordinateTransform(src_crs, dest_crs, QgsProject.instance()))
        return geom

    def zoom_to_rubberband(self):
        geom = self.rubber.asGeometry()
        if geom:
            rect = geom.boundingBox()
            rect.scale(1.5)
            self.mapCanvas.setExtent(rect)
            self.mapCanvas.refresh()
Ejemplo n.º 11
0
class PlanetOrderReviewWidget(QWidget):

    selectedImagesChanged = pyqtSignal()

    def __init__(self, item_type, bundle_type, images, add_clip):
        super().__init__()

        self.item_type = item_type
        self.bundle_type = bundle_type
        self.images = images
        self.add_clip = add_clip

        layout = QVBoxLayout()
        layout.setMargin(0)
        labelName = IconLabel(
            f"<b>{ITEM_TYPE_SPECS[self.item_type]['name']} - {bundle_type}</b>",
            SATELLITE_ICON)
        labelNumItems = IconLabel(f"{len(images)} items", NITEMS_ICON)
        gridlayout = QGridLayout()
        gridlayout.setMargin(0)
        gridlayout.addWidget(labelNumItems, 0, 0)
        self.btnDetails = QPushButton()
        self.btnDetails.setFlat(True)
        self.btnDetails.setIcon(EXPAND_MORE_ICON)
        self.btnDetails.clicked.connect(self._btnDetailsClicked)
        gridlayout.addWidget(self.btnDetails, 0, 2)
        gridlayout.addWidget(labelName, 1, 0, 1, 3)
        layout.addLayout(gridlayout)
        self.widgetDetails = QWidget()
        layout.addWidget(self.widgetDetails)
        line = QFrame()
        line.setFrameShape(QFrame.HLine)
        line.setFrameShadow(QFrame.Sunken)
        layout.addWidget(line)

        self.setLayout(layout)

        self.widgetDetails.hide()
        self.updateGeometry()

        self.populate_details()

    def populate_details(self):
        self.imgWidgets = []
        layout = QGridLayout()
        layout.setMargin(0)
        layout.setVerticalSpacing(15)
        layout.setColumnStretch(0, 1)
        layout.setColumnStretch(2, 1)
        self.chkClip = None
        if self.add_clip:
            layout.addWidget(QLabel("<b>Clipping</b>"), 0, 1, Qt.AlignCenter)
            layout.addWidget(
                QLabel("Only get items delivered within your AOI"), 1, 1,
                Qt.AlignCenter)
            self.chkClip = QCheckBox("Clip items to AOI")
            self.chkClip.stateChanged.connect(self.checkStateChanged)
            layout.addWidget(self.chkClip, 2, 1, Qt.AlignCenter)
        layout.addWidget(QLabel("<b>Review Items</b>"), 3, 1, Qt.AlignCenter)
        layout.addWidget(
            QLabel(
                "We recommend deselecting items that appear to have no pixels"
            ), 4, 1, Qt.AlignCenter)

        sublayout = QGridLayout()
        sublayout.setMargin(0)
        for i, img in enumerate(self.images):
            w = ImageReviewWidget(img)
            w.selectedChanged.connect(self.selectedImagesChanged.emit)
            row = i // 4
            col = i % 4 + 1
            sublayout.addWidget(w, row, col)
            self.imgWidgets.append(w)
        layout.addLayout(sublayout, 5, 1, Qt.AlignCenter)

        self.widgetDetails.setLayout(layout)

    def checkStateChanged(self):
        self.selectedImagesChanged.emit()

    def selected_images(self):
        return [w.image for w in self.imgWidgets if w.selected()]

    def clipping(self):
        if self.chkClip is None:
            return False
        else:
            return self.chkClip.isChecked()

    def _btnDetailsClicked(self):
        if self.widgetDetails.isVisible():
            self.widgetDetails.hide()
            self.btnDetails.setIcon(EXPAND_MORE_ICON)
        else:
            self.widgetDetails.show()
            self.btnDetails.setIcon(EXPAND_LESS_ICON)
        self.updateGeometry()

    def expand(self):
        self.widgetDetails.show()
        self.btnDetails.setIcon(EXPAND_LESS_ICON)
        self.updateGeometry()