class ImageItemWidget(QFrame):

    checked_state_changed = pyqtSignal()

    def __init__(self, image, sort_criteria):
        QFrame.__init__(self)
        self.image = image
        self.properties = image['properties']

        datetime = iso8601.parse_date(self.properties[sort_criteria])
        self.time = datetime.strftime('%H:%M:%S')
        self.date = datetime.strftime('%b %d, %Y')

        text = f"""{self.date}<span style="color: rgb(100,100,100);"> {self.time} UTC</span><br>
                        <b>{DAILY_ITEM_TYPES_DICT[self.properties['item_type']]}</b><br>
                    """
        url = f"{image['_links']['thumbnail']}?api_key={PlanetClient.getInstance().api_key()}"

        self.checkBox = QCheckBox("")
        self.checkBox.setChecked(True)
        self.checkBox.stateChanged.connect(self.checked_state_changed.emit)
        self.nameLabel = QLabel(text)
        self.iconLabel = QLabel()

        layout = QHBoxLayout()
        layout.setMargin(0)
        layout.addWidget(self.checkBox)
        pixmap = QPixmap(PLACEHOLDER_THUMB, 'SVG')
        thumb = pixmap.scaled(48, 48, Qt.KeepAspectRatio,
                            Qt.SmoothTransformation)
        self.iconLabel.setPixmap(thumb)
        self.iconLabel.setFixedSize(48, 48)
        self.nam = QNetworkAccessManager()
        self.nam.finished.connect(self.iconDownloaded)
        self.nam.get(QNetworkRequest(QUrl(url)))
        layout.addWidget(self.iconLabel)
        layout.addWidget(self.nameLabel)
        layout.addStretch()
        self.setLayout(layout)

    def iconDownloaded(self, reply):
        img = QImage()
        img.loadFromData(reply.readAll())
        pixmap = QPixmap(img)
        thumb = pixmap.scaled(48, 48, Qt.KeepAspectRatio,
                            Qt.SmoothTransformation)
        self.iconLabel.setPixmap(thumb)

    def set_selected(self, checked):
        self.checkBox.setChecked(checked)

    def is_selected(self):
        return self.checkBox.isChecked()
Esempio n. 2
0
class ImageReviewWidget(QFrame):

    selectedChanged = pyqtSignal()

    def __init__(self, image):
        super().__init__()

        self.image = image
        self.checkBox = QCheckBox()
        self.checkBox.setChecked(True)
        self.checkBox.stateChanged.connect(self.checkStateChanged)
        hlayout = QHBoxLayout()
        hlayout.setMargin(0)
        hlayout.addStretch()
        hlayout.addWidget(self.checkBox)
        vlayout = QVBoxLayout()
        vlayout.setMargin(0)
        vlayout.addLayout(hlayout)
        self.label = QLabel()
        pixmap = QPixmap(PLACEHOLDER_THUMB, "SVG")
        thumb = pixmap.scaled(96, 96, Qt.KeepAspectRatio,
                              Qt.SmoothTransformation)
        self.label.setPixmap(thumb)
        self.label.setFixedSize(96, 96)

        url = f"{image['_links']['thumbnail']}?api_key={PlanetClient.getInstance().api_key()}"
        download_thumbnail(url, self)
        vlayout.addWidget(self.label)
        self.setLayout(vlayout)

        self.setFrameStyle(QFrame.Panel | QFrame.Raised)

    def checkStateChanged(self):
        self.selectedChanged.emit()
        self.label.setEnabled(self.checkBox.isChecked())

    def selected(self):
        return self.checkBox.isChecked()

    def set_thumbnail(self, img):
        self.thumbnail = QPixmap(img)
        thumb = self.thumbnail.scaled(96, 96, Qt.KeepAspectRatio,
                                      Qt.SmoothTransformation)
        self.label.setPixmap(thumb)
class ItemWidgetBase(QFrame):

    checkedStateChanged = pyqtSignal()
    thumbnailChanged = pyqtSignal()

    def __init__(self, item):
        QFrame.__init__(self)
        self.item = item
        self.is_updating_checkbox = False
        self.setMouseTracking(True)
        self.setStyleSheet("ItemWidgetBase{border: 2px solid transparent;}")

    def _setup_ui(self, text, thumbnailurl):

        self.lockLabel = QLabel()
        iconSize = QSize(16, 16)
        self.lockLabel.setPixmap(LOCK_ICON.pixmap(iconSize))
        self.checkBox = QCheckBox("")
        self.checkBox.clicked.connect(self.check_box_state_changed)
        self.nameLabel = QLabel(text)
        self.iconLabel = QLabel()
        self.labelZoomTo = QLabel()
        self.labelZoomTo.setPixmap(ZOOMTO_ICON.pixmap(QSize(18, 18)))
        self.labelZoomTo.setToolTip("Zoom to extent")
        self.labelZoomTo.mousePressEvent = self.zoom_to_extent
        self.labelAddPreview = QLabel()
        self.labelAddPreview.setPixmap(ADD_PREVIEW_ICON.pixmap(QSize(18, 18)))
        self.labelAddPreview.setToolTip("Add preview layer to map")
        self.labelAddPreview.mousePressEvent = self._add_preview_clicked

        layout = QHBoxLayout()
        layout.setMargin(0)
        layout.addWidget(self.checkBox)
        layout.addWidget(self.lockLabel)
        pixmap = QPixmap(PLACEHOLDER_THUMB, "SVG")
        self.thumbnail = None
        thumb = pixmap.scaled(48, 48, Qt.KeepAspectRatio,
                              Qt.SmoothTransformation)
        self.iconLabel.setPixmap(thumb)
        self.iconLabel.setFixedSize(48, 48)
        layout.addWidget(self.iconLabel)
        if thumbnailurl is not None:
            download_thumbnail(thumbnailurl, self)
        layout.addWidget(self.nameLabel)
        layout.addStretch()
        layout.addWidget(self.labelZoomTo)
        layout.addWidget(self.labelAddPreview)
        layout.addSpacing(10)
        self.setLayout(layout)

        self.footprint = QgsRubberBand(iface.mapCanvas(),
                                       QgsWkbTypes.PolygonGeometry)
        self.footprint.setStrokeColor(PLANET_COLOR)
        self.footprint.setWidth(2)

    def set_thumbnail(self, img):
        self.thumbnail = QPixmap(img)
        thumb = self.thumbnail.scaled(48, 48, Qt.KeepAspectRatio,
                                      Qt.SmoothTransformation)
        self.iconLabel.setPixmap(thumb)
        self.thumbnailChanged.emit()

    def is_selected(self):
        return self.checkBox.checkState() == Qt.Checked

    def _geom_bbox_in_project_crs(self):
        transform = QgsCoordinateTransform(
            QgsCoordinateReferenceSystem("EPSG:4326"),
            QgsProject.instance().crs(),
            QgsProject.instance(),
        )
        return transform.transformBoundingBox(self.geom.boundingBox())

    def _geom_in_project_crs(self):
        transform = QgsCoordinateTransform(
            QgsCoordinateReferenceSystem("EPSG:4326"),
            QgsProject.instance().crs(),
            QgsProject.instance(),
        )
        geom = QgsGeometry(self.geom)
        geom.transform(transform)
        return geom

    def show_footprint(self):
        self.footprint.setToGeometry(self._geom_in_project_crs())

    def hide_footprint(self):
        self.footprint.reset(QgsWkbTypes.PolygonGeometry)

    def enterEvent(self, event):
        self.setStyleSheet(
            "ItemWidgetBase{border: 2px solid rgb(0, 157, 165);}")
        self.show_footprint()

    def leaveEvent(self, event):
        self.setStyleSheet("ItemWidgetBase{border: 2px solid transparent;}")
        self.hide_footprint()

    def zoom_to_extent(self, evt):
        rect = QgsRectangle(self._geom_bbox_in_project_crs())
        rect.scale(1.05)
        iface.mapCanvas().setExtent(rect)
        iface.mapCanvas().refresh()

    def _add_preview_clicked(self, evt):
        self.add_preview()

    @waitcursor
    def add_preview(self):
        send_analytics_for_preview(self.item.images())
        create_preview_group(self.name(), self.item.images())

    def check_box_state_changed(self):
        self.update_children_items()
        self.update_parent_item()
        self.checkedStateChanged.emit()

    def update_parent_item(self):
        parent = self.item.parent()
        if parent is not None:
            w = parent.treeWidget().itemWidget(parent, 0)
            w.update_checkbox()

    def update_children_items(self):
        total = self.item.childCount()
        if self.checkBox.isTristate():
            self.checkBox.setTristate(False)
            self.checkBox.setChecked(False)
        for i in range(total):
            w = self.item.treeWidget().itemWidget(self.item.child(i), 0)
            w.set_checked(self.checkBox.isChecked())

    def update_checkbox(self):
        selected = 0
        total = self.item.childCount()
        for i in range(total):
            w = self.item.treeWidget().itemWidget(self.item.child(i), 0)
            if w.is_selected():
                selected += 1
        if selected == total:
            self.checkBox.setTristate(False)
            self.checkBox.setCheckState(Qt.Checked)
        elif selected == 0:
            self.checkBox.setTristate(False)
            self.checkBox.setCheckState(Qt.Unchecked)
        else:
            self.checkBox.setTristate(True)
            self.checkBox.setCheckState(Qt.PartiallyChecked)

    def set_checked(self, checked):
        self.checkBox.setChecked(checked)
        self.update_children_items()

    def update_thumbnail(self):
        thumbnails = self.scene_thumbnails()
        if thumbnails and None not in thumbnails:
            bboxes = [img[GEOMETRY] for img in self.item.images()]
            pixmap = createCompoundThumbnail(bboxes, thumbnails)
            thumb = pixmap.scaled(48, 48, Qt.KeepAspectRatio,
                                  Qt.SmoothTransformation)
            self.iconLabel.setPixmap(thumb)
            self.thumbnailChanged.emit()

    def scene_thumbnails(self):
        thumbnails = []
        try:
            for i in range(self.item.childCount()):
                w = self.item.treeWidget().itemWidget(self.item.child(i), 0)
                thumbnails.extend(w.scene_thumbnails())
        except RuntimeError:
            # item might not exist anymore. In this case, we just return
            # an empty list
            pass
        return thumbnails
Esempio n. 4
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)