def __init__(self, main):
        super().__init__(self._icon, self._name)
        self.setCheckable(True)

        self.main = main

        # Build the widget
        self.widget = QWidget()
        uic.loadUi(
            os.path.join(os.path.dirname(__file__), "ui", self._widget_ui),
            self.widget)
        self.widget.dateTimeEdit.setDateTime(QDateTime.currentDateTime())

        self.widgetAction = QWidgetAction(self)
        self.widgetAction.setDefaultWidget(self.widget)

        self.menu = QMenu()
        self.menu.addAction(self.widgetAction)
        self.setMenu(self.menu)

        # Build the tool
        self.tool = QgsMapToolEmitPoint(self.main.iface.mapCanvas())
        self.tool.activated.connect(lambda: self.setChecked(True))
        self.tool.deactivated.connect(lambda: self.setChecked(False))
        self.tool.canvasClicked.connect(self.tool_clicked)

        # Connect the action
        self.triggered.connect(self.start_tool)
Пример #2
0
    def createActions(self):
        self.nameLabel = QLabel(self.mobile.name)
        self.nameLabel.setMinimumSize(80, 23)
        self.nameLabelAction = QWidgetAction(self)
        self.nameLabelAction.setDefaultWidget(self.nameLabel)
        self.addAction(self.nameLabelAction)

        self.enableAction = QAction("Enable Display", self)
        self.enableAction.setCheckable(True)
        self.enableAction.setChecked(True)
        icon = QIcon(':/plugins/PosiView/ledgrey.png')
        icon.addFile(':/plugins/PosiView/ledgreen.png', QSize(), QIcon.Normal, QIcon.On)
        self.enableAction.setIcon(icon)
        self.addAction(self.enableAction)
        self.enableAction.triggered.connect(self.onEnableClicked)
        self.enableAction.triggered.connect(self.mobile.setEnabled)

        self.addSeparator()
        self.posLabel = QLabel("--:--:-- 0.000000 0.000000")
        self.posLabel.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
        widths = (180, 196, 204, 180, 184, 200, 208, 184)
        self.posLabel.setMinimumSize(widths[self.format], 23)
        self.posLabel.setStyleSheet('background: red; font-size: 8pt; color: white;')
        self.posLabelAction = QWidgetAction(self)
        self.posLabelAction.setDefaultWidget(self.posLabel)
        self.addAction(self.posLabelAction)
        self.centerAction = QAction(QIcon(':/plugins/PosiView/center.png'), "Center &Map", self)
        self.addAction(self.centerAction)
        self.deleteTrackAction = QAction(QIcon(':/plugins/PosiView/deletetrack.png'), 'Delete &Track', self)
        self.addAction(self.deleteTrackAction)
        self.deleteTrackAction.triggered.connect(self.mobile.deleteTrack)
        self.centerAction.triggered.connect(self.mobile.centerOnMap)
Пример #3
0
class ExpressTimeFilterAction(QAction):
    def __init__(self, main):
        super().__init__(resources.icon_time_filter_express, tr("Quick time filter"))
        self.setCheckable(True)
        self.setEnabled(False)

        self.main = main

        self.widget = ExpressTimeFilterWidget()

        self.widgetAction = QWidgetAction(self)
        self.widgetAction.setDefaultWidget(self.widget)

        self.menu = QMenu()
        # self.menu.aboutToShow.connect(self.start_tool)
        self.menu.addAction(self.widgetAction)
        self.setMenu(self.menu)

        self.main.iface.currentLayerChanged.connect(self.current_layer_changed)

        self.triggered.connect(self.start_tool)

    def current_layer_changed(self, layer):
        self.setEnabled(
            layer is not None
            and layer.type() == QgsMapLayer.LayerType.VectorLayer
            and layer.geometryType() == QgsWkbTypes.PointGeometry
        )

    def start_tool(self):
        self.tool = ExpressTimeFilterTool(self, self.main.iface.mapCanvas())
        self.main.iface.mapCanvas().setMapTool(self.tool)
Пример #4
0
    def __init__(self, main):
        super().__init__(resources.icon_routes_express, tr("Quick route"))
        self.setCheckable(True)

        self.main = main

        self.widget = ExpressRouteWidget()

        self.widgetAction = QWidgetAction(self)
        self.widgetAction.setDefaultWidget(self.widget)

        self.menu = QMenu()
        # self.menu.aboutToShow.connect(self.start_tool)
        self.menu.addAction(self.widgetAction)
        self.setMenu(self.menu)

        self.triggered.connect(self.start_tool)
Пример #5
0
def add_menu_section_action(text, menu, tag='b', pad=0.5):
    """Because QMenu.addSection() fails to render with some UI styles, and
    QWidgetAction defaults to no padding.
    :param text: Text for action's title
    :type text: str
    :param menu: QMenu to add section action
    :type menu: QMenu
    :param tag: Simple HTML tag (sans < or >) to style the text, e.g. b, i, u
    :type tag: str
    :param pad: Value for QLabel qss em and ex padding
    :type pad: float
    """
    lbl = QLabel(f'<{tag}>{text}</{tag}>', menu)
    lbl.setStyleSheet(
        f'QLabel {{ padding-left: {pad}em; padding-right: {pad}em; '
        f'padding-top: {pad}ex; padding-bottom: {pad}ex;}}')
    wa = QWidgetAction(menu)
    wa.setDefaultWidget(lbl)
    menu.addAction(wa)
    return wa
Пример #6
0
    def __init__(self, main):
        super().__init__(resources.icon_time_filter_express, tr("Quick time filter"))
        self.setCheckable(True)
        self.setEnabled(False)

        self.main = main

        self.widget = ExpressTimeFilterWidget()

        self.widgetAction = QWidgetAction(self)
        self.widgetAction.setDefaultWidget(self.widget)

        self.menu = QMenu()
        # self.menu.aboutToShow.connect(self.start_tool)
        self.menu.addAction(self.widgetAction)
        self.setMenu(self.menu)

        self.main.iface.currentLayerChanged.connect(self.current_layer_changed)

        self.triggered.connect(self.start_tool)
Пример #7
0
class ExpressTimeMapAction(QAction):
    def __init__(self, main):
        super().__init__(resources.icon_time_map_express, tr("Quick time map"))
        self.setCheckable(True)

        self.main = main

        self.widget = ExpressTimeMapWidget()

        self.widgetAction = QWidgetAction(self)
        self.widgetAction.setDefaultWidget(self.widget)

        self.menu = QMenu()
        # self.menu.aboutToShow.connect(self.start_tool)
        self.menu.addAction(self.widgetAction)
        self.setMenu(self.menu)

        self.triggered.connect(self.start_tool)

    def start_tool(self):
        self.tool = ExpressTimeMapTool(self, self.main.iface.mapCanvas())
        self.main.iface.mapCanvas().setMapTool(self.tool)
Пример #8
0
 def filterMenu(self, table, pos):
     index = table.columnAt(pos.x())
     menu = QMenu()
     filter_operation = QComboBox()
     if table.types[index] in [10]:
         filter_operation.addItems([self.tr('Contains'),self.tr('Equals')])
     else:
         filter_operation.addItems(['=','>','<'])
     filter_operation.setCurrentIndex(table.filter_op[index])
     action_filter_operation = QWidgetAction(self)
     action_filter_operation.setDefaultWidget(filter_operation)
     if table.types[index] in [14]:
         if not isinstance(table.filters[index], QDate):
             filter_value = QDateEdit()
         else:
             filter_value = QDateEdit(table.filters[index])
     elif table.types[index] in [15]:
         if not isinstance(table.filters[index], QTime):
             filter_value = QTimeEdit()
         else:
             filter_value = QTimeEdit(table.filters[index])
     elif table.types[index] in [16]:
         if not isinstance(table.filters[index], QDateTime):
             filter_value = QDateTimeEdit()
         else:
             filter_value = QDateTimeEdit(table.filters[index])
     else:
         filter_value = QLineEdit(table.filters[index])
     action_filter_value = QWidgetAction(self)
     action_filter_value.setDefaultWidget(filter_value)
     menu.addAction(action_filter_operation)
     menu.addAction(action_filter_value)
     action_filter_apply = QAction(self.tr('Apply'), self)
     action_filter_apply.triggered.connect(partial(self.applyFilter, table, index, filter_value, filter_operation))
     action_filter_cancel = QAction(self.tr('Cancel'), self)
     action_filter_cancel.triggered.connect(partial(self.applyFilter, table, index, None, filter_operation))
     menu.addAction(action_filter_apply)
     menu.addAction(action_filter_cancel)
     menu.exec_(QtGui.QCursor.pos())
class ExpressActionBase(QAction):
    _icon = None  # to be defined by subclasses
    _name = None  # to be defined by subclasses
    _widget_ui = None  # to be defined by subclasses
    _algorithm = None  # to be defined by subclasses

    def __init__(self, main):
        super().__init__(self._icon, self._name)
        self.setCheckable(True)

        self.main = main

        # Build the widget
        self.widget = QWidget()
        uic.loadUi(
            os.path.join(os.path.dirname(__file__), "ui", self._widget_ui),
            self.widget)
        self.widget.dateTimeEdit.setDateTime(QDateTime.currentDateTime())

        self.widgetAction = QWidgetAction(self)
        self.widgetAction.setDefaultWidget(self.widget)

        self.menu = QMenu()
        self.menu.addAction(self.widgetAction)
        self.setMenu(self.menu)

        # Build the tool
        self.tool = QgsMapToolEmitPoint(self.main.iface.mapCanvas())
        self.tool.activated.connect(lambda: self.setChecked(True))
        self.tool.deactivated.connect(lambda: self.setChecked(False))
        self.tool.canvasClicked.connect(self.tool_clicked)

        # Connect the action
        self.triggered.connect(self.start_tool)

    def start_tool(self):
        self.main.iface.mapCanvas().setMapTool(self.tool)

    def make_params(self, point):

        DEPARR = ("DEPARTURE" if self.widget.deparrComboBox.currentIndex() == 0
                  else "ARRIVAL")

        input_layer = pointToLayer(point)
        time = self.widget.dateTimeEdit.dateTime().toUTC().toString(Qt.ISODate)

        transpt_type = self.widget.transptTypeComboBox.currentText()

        params = {
            "INPUT_" + DEPARR + "_SEARCHES": input_layer,
            "INPUT_" + DEPARR + "_TIME": "'" + time + "'",
            "INPUT_" + DEPARR + "_TRNSPT_TYPE": "'" + transpt_type + "'",
            "OUTPUT": "memory:",
        }

        if hasattr(self.widget, "travelTimeSpinBox"):
            travel_time = self.widget.travelTimeSpinBox.value() * 60
            params.update({"INPUT_" + DEPARR + "_TRAVEL_TIME": travel_time})

        return params

    def tool_clicked(self, point):
        params = self.make_params(point)

        class Feedback(QgsProcessingFeedback):
            def __init__(self):
                super().__init__()
                self.fatal_errors = []

            def reportError(self, error, fatalError=False):
                log(error)
                if fatalError:
                    self.fatal_errors.append(error)

        feedback = Feedback()
        try:
            # TODO : use QgsProcessingAlgRunnerTask to do this as a bg task
            processing.runAndLoadResults(self._algorithm,
                                         params,
                                         feedback=feedback)
        except QgsProcessingException as e:
            print(e)
            self.main.iface.messageBar().pushMessage(
                "Error",
                ", ".join(feedback.fatal_errors),
                level=Qgis.Critical,
                duration=0,
            )
Пример #10
0
class TrackingDisplay(QToolBar):
    '''
        Display the position of a mobile and add action for centering
        the map on the vehicle and erasing the track
    '''

    def __init__(self, mobile, parent=None):
        super(TrackingDisplay, self).__init__(parent)
        self.setMovable(True)
        self.setFloatable(True)
        self.mobile = mobile
        self.timedOut = True
        self.lastFix = 0.0
        s = QSettings()
        self.defFormat = s.value('PosiView/Misc/DefaultFormat', defaultValue=0, type=int)
        self.format = self.defFormat & 3
        self.withSuff = QgsCoordinateFormatter.FlagDegreesUseStringSuffix if bool(self.defFormat & 4) else QgsCoordinateFormatter.FormatFlag(0)
        self.createActions()
        self.mobile.newPosition.connect(self.onNewPosition)
        self.mobile.timeout.connect(self.onTimeout)

    def createActions(self):
        self.nameLabel = QLabel(self.mobile.name)
        self.nameLabel.setMinimumSize(80, 23)
        self.nameLabelAction = QWidgetAction(self)
        self.nameLabelAction.setDefaultWidget(self.nameLabel)
        self.addAction(self.nameLabelAction)

        self.enableAction = QAction("Enable Display", self)
        self.enableAction.setCheckable(True)
        self.enableAction.setChecked(True)
        icon = QIcon(':/plugins/PosiView/ledgrey.png')
        icon.addFile(':/plugins/PosiView/ledgreen.png', QSize(), QIcon.Normal, QIcon.On)
        self.enableAction.setIcon(icon)
        self.addAction(self.enableAction)
        self.enableAction.triggered.connect(self.onEnableClicked)
        self.enableAction.triggered.connect(self.mobile.setEnabled)

        self.addSeparator()
        self.posLabel = QLabel("--:--:-- 0.000000 0.000000")
        self.posLabel.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
        widths = (180, 196, 204, 180, 184, 200, 208, 184)
        self.posLabel.setMinimumSize(widths[self.format], 23)
        self.posLabel.setStyleSheet('background: red; font-size: 8pt; color: white;')
        self.posLabelAction = QWidgetAction(self)
        self.posLabelAction.setDefaultWidget(self.posLabel)
        self.addAction(self.posLabelAction)
        self.centerAction = QAction(QIcon(':/plugins/PosiView/center.png'), "Center &Map", self)
        self.addAction(self.centerAction)
        self.deleteTrackAction = QAction(QIcon(':/plugins/PosiView/deletetrack.png'), 'Delete &Track', self)
        self.addAction(self.deleteTrackAction)
        self.deleteTrackAction.triggered.connect(self.mobile.deleteTrack)
        self.centerAction.triggered.connect(self.mobile.centerOnMap)

    @pyqtSlot(float, QgsPointXY, float, float)
    def onNewPosition(self, fix, pos, depth, altitude):
        s = str()
        if fix > 0:
            s = strftime('%H:%M:%S   ', gmtime(fix))
        else:
            s = '--:--:-- '
        if self.format == 0:
            s += "{:f}  {:f}".format(pos.y(), pos.x())
        elif self.format == 1:
            s += ', '.join(QgsCoordinateFormatter.format(pos,
                                                         QgsCoordinateFormatter.FormatDegreesMinutes,
                                                         4,
                                                         self.withSuff
                                                         ).rsplit(',')[::-1])
        else:
            s += ', '.join(QgsCoordinateFormatter.format(pos,
                                                         QgsCoordinateFormatter.FormatDegreesMinutesSeconds,
                                                         2,
                                                         self.withSuff
                                                         ).rsplit(',')[::-1])
        if depth > -9999:
            s += "\nd = {:.1f}".format(depth)
        if altitude > -9999:
            if depth > -9999:
                s += "   alt = {:.1f}".format(altitude)
            else:
                s += "\nalt = {:.1f}".format(altitude)
        self.posLabel.setText(s)
        if self.timedOut:
            if fix > self.lastFix:
                self.posLabel.setStyleSheet('background: lime; font-size: 8pt; color: black;')
                self.timedOut = False
        self.lastFix = fix

    @pyqtSlot()
    def onTimeout(self):
        if not self.timedOut:
            self.timedOut = True
            self.posLabel.setStyleSheet('background: red; font-size: 8pt; color: white;')

    @pyqtSlot(bool)
    def onEnableClicked(self, enable):
        self.timedOut = True
        if enable:
            self.posLabel.setStyleSheet('background: red; font-size: 8pt; color: white;')
        else:
            self.posLabel.setStyleSheet('background: white; font-size: 8pt; color: black;')

    def releaseMobile(self):
        self.mobile = None
Пример #11
0
class TrackingDisplay(QToolBar):
    '''
        Display the position of a mobile and add action for centering
        the map on the vehicle and erasing the track
    '''
    def __init__(self, mobile, parent=None):
        super(TrackingDisplay, self).__init__(parent)
        self.setMovable(True)
        self.setFloatable(True)
        self.mobile = mobile
        self.timedOut = True
        self.lastFix = 0.0
        s = QSettings()
        self.defFormat = s.value('PosiView/Misc/DefaultFormat',
                                 defaultValue=0,
                                 type=int)
        self.format = self.defFormat & 3
        self.withSuff = cf.FlagDegreesUseStringSuffix if bool(
            self.defFormat & 4) else cf.FormatFlag(0)
        try:
            self.sep = cf.separator() + ' '
        except AttributeError:
            self.sep = ', '
        self.createActions()
        self.mobile.newPosition.connect(self.onNewPosition)
        self.mobile.timeout.connect(self.onTimeout)
        self.posText = '0.000000, 0.000000'

    def createActions(self):
        self.nameLabel = QLabel(self.mobile.name)
        self.nameLabel.setMinimumSize(80, 23)
        self.nameLabelAction = QWidgetAction(self)
        self.nameLabelAction.setDefaultWidget(self.nameLabel)
        self.addAction(self.nameLabelAction)

        self.enableAction = QAction("Enable Display", self)
        self.enableAction.setCheckable(True)
        self.enableAction.setChecked(True)
        icon = QIcon(':/plugins/PosiView/ledgrey.png')
        icon.addFile(':/plugins/PosiView/ledgreen.png', QSize(), QIcon.Normal,
                     QIcon.On)
        self.enableAction.setIcon(icon)
        self.addAction(self.enableAction)
        self.enableAction.triggered.connect(self.onEnableClicked)
        self.enableAction.triggered.connect(self.mobile.setEnabled)

        self.addSeparator()
        self.posLabel = QLabel("--:--:-- 0.000000, 0.000000")
        self.posLabel.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
        widths = (180, 196, 204, 180, 184, 200, 208, 184)
        self.posLabel.setMinimumSize(widths[self.format], 23)
        self.posLabel.setStyleSheet(
            'background: red; font-size: 8pt; color: white;')
        self.posLabelAction = QWidgetAction(self)
        self.posLabelAction.setDefaultWidget(self.posLabel)
        self.addAction(self.posLabelAction)
        self.centerAction = QAction(QIcon(':/plugins/PosiView/center.png'),
                                    "Center &Map", self)
        self.addAction(self.centerAction)
        self.deleteTrackAction = QAction(
            QIcon(':/plugins/PosiView/deletetrack.png'), 'Delete &Track', self)
        self.addAction(self.deleteTrackAction)
        self.deleteTrackAction.triggered.connect(self.mobile.deleteTrack)
        self.centerAction.triggered.connect(self.mobile.centerOnMap)

    @pyqtSlot(float, QgsPointXY, float, float)
    def onNewPosition(self, fix, pos, depth, altitude):
        s = str()
        if fix > 0:
            s = strftime('%H:%M:%S   ', gmtime(fix))
        else:
            s = '--:--:-- '

        if self.format == 1:
            f, pr = cf.FormatDegreesMinutes, 4
        elif self.format == 2:
            f, pr = cf.FormatDegreesMinutesSeconds, 2
        else:
            f, pr = cf.FormatDecimalDegrees, 6
        self.posText = self.sep.join(
            (cf.formatY(pos.y(), f, pr, self.withSuff),
             cf.formatX(pos.x(), f, pr, self.withSuff)))
        s += self.posText
        if depth > -9999:
            s += "\nd = {:.1f}".format(depth)
        if altitude > -9999:
            if depth > -9999:
                s += "   alt = {:.1f}".format(altitude)
            else:
                s += "\nalt = {:.1f}".format(altitude)
        self.posLabel.setText(s)
        if self.timedOut:
            if fix > self.lastFix:
                self.posLabel.setStyleSheet(
                    'background: lime; font-size: 8pt; color: black;')
                self.timedOut = False
        self.lastFix = fix

    @pyqtSlot()
    def onTimeout(self):
        if not self.timedOut:
            self.timedOut = True
            self.posLabel.setStyleSheet(
                'background: red; font-size: 8pt; color: white;')

    @pyqtSlot(bool)
    def onEnableClicked(self, enable):
        self.timedOut = True
        if enable:
            self.posLabel.setStyleSheet(
                'background: red; font-size: 8pt; color: white;')
        else:
            self.posLabel.setStyleSheet(
                'background: white; font-size: 8pt; color: black;')

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            if event.modifiers() == Qt.ControlModifier:
                QGuiApplication.clipboard().setText(self.posText)
            else:
                drag = QDrag(self)
                mimeData = QMimeData()
                mimeData.setText(self.posText)
                drag.setMimeData(mimeData)
                drag.exec_()

    def releaseMobile(self):
        self.mobile = None