コード例 #1
0
ファイル: layers.py プロジェクト: spch-GL/OpenComptage
    def load_layers(self):
        settings = Settings()

        group_comptages = QgsProject.instance().layerTreeRoot().findGroup(
            'Comptages')
        group_extra = QgsProject.instance().layerTreeRoot().findGroup('Extra')

        if group_comptages is None:
            group_comptages = QgsProject.instance().layerTreeRoot().addGroup(
                'Comptages')

        if group_extra is None and settings.value("extra_layers"):
            group_extra = group_comptages.addGroup('Extra')

        for key in LAYER_DEFINITIONS:
            layer_definition = LAYER_DEFINITIONS[key]

            if not QgsProject.instance().mapLayersByName(
                    layer_definition['display_name']):

                layer = self.load_layer(
                    'comptages',  # Schema
                    layer_definition['table'],
                    layer_definition['geometry'],
                    layer_definition['sql'],
                    layer_definition['display_name'],
                    layer_definition['id'],
                    layer_definition['epsg'],
                )

                if layer_definition['legend']:
                    group_comptages.addLayer(layer)
                elif settings.value("extra_layers"):
                    group_extra.addLayer(layer)

                self.layers[key] = layer

        self.apply_qml_styles()
        self.add_layer_actions()
        self.create_virtual_fields()
        self.create_joins()
        self.create_relations()
        iface.setActiveLayer(self.layers['section'])

        self.populate_list_of_highlighted_sections()

        self.layers['count'].featureAdded.connect(self.on_count_added)

        from qgis.core import QgsExpressionContextUtils
        QgsExpressionContextUtils.setProjectVariable(
            QgsProject.instance(), 'highlighted_installation', '')
コード例 #2
0
ファイル: comptages.py プロジェクト: sitn/OpenComptage
    def __init__(self, iface):
        QObject.__init__(self)

        self.iface = iface
        self.settings = Settings()
        self.settings_dialog = SettingsDialog()
        self.layers = Layers()
        self.chart_dock = ChartDock(self.iface, self.layers)
        self.iface.addDockWidget(Qt.BottomDockWidgetArea, self.chart_dock)
        self.filter_start_date = None
        self.filter_end_date = None
        self.filter_installation = None
        self.filter_sensor = None
        self.tm = QgsApplication.taskManager()
コード例 #3
0
ファイル: test_data_func.py プロジェクト: sitn/OpenComptage
    def setUpClass(self):
        self.settings = Settings()
        self.layers = plugins['comptages'].layers
        self.layers.load_layers()
        self.comptages = plugins['comptages']

        self.db = QSqlDatabase.addDatabase("QPSQL", "test_data_connection")
        self.db.setHostName(self.settings.value("db_host"))
        self.db.setPort(self.settings.value("db_port"))
        self.db.setDatabaseName(self.settings.value("db_name"))
        self.db.setUserName(self.settings.value("db_username"))
        self.db.setPassword(self.settings.value("db_password"))

        self.test_data_path = os.path.join(
            os.path.dirname(os.path.realpath(__file__)), 'test_data/')
コード例 #4
0
ファイル: __init__.py プロジェクト: spch-GL/OpenComptage
def prepare_django(default_db=None, **additional_settings):
    if django_settings.configured:
        return

    if not additional_settings:
        additional_settings = {}

    # If the default db doesn't arrives from the manage.py script
    # (i.e. the command is lauched from the QGIS python console), we
    # use the one in the plugin settings
    if not default_db:

        from comptages.core.settings import Settings as PluginSettings
        plugin_settings = PluginSettings()
        default_db = {
            "ENGINE": "django.contrib.gis.db.backends.postgis",
            "HOST": plugin_settings.value("db_host"),
            "PORT": plugin_settings.value("db_port"),
            "NAME": plugin_settings.value("db_name"),
            "USER": plugin_settings.value("db_username"),
            "PASSWORD": plugin_settings.value("db_password"),
        }

    # Allow to configure GDAL/GEOS/Spatialite libraries from env vars
    # see https://docs.djangoproject.com/en/3.2/ref/contrib/gis/install/geolibs/#geos-library-path
    GDAL_LIBRARY_PATH_ENV = os.getenv("GDAL_LIBRARY_PATH")
    GEOS_LIBRARY_PATH_ENV = os.getenv("GEOS_LIBRARY_PATH")
    SPATIALITE_LIBRARY_PATH_ENV = os.getenv("SPATIALITE_LIBRARY_PATH")
    if GDAL_LIBRARY_PATH_ENV:
        additional_settings["GDAL_LIBRARY_PATH"] = GDAL_LIBRARY_PATH_ENV
    if GEOS_LIBRARY_PATH_ENV:
        additional_settings["GEOS_LIBRARY_PATH"] = GEOS_LIBRARY_PATH_ENV
    if SPATIALITE_LIBRARY_PATH_ENV:
        additional_settings["SPATIALITE_LIBRARY_PATH"] = SPATIALITE_LIBRARY_PATH_ENV

    django_settings.configure(
        BASE_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), os.pardir),
        DATABASES={"default": default_db},
        INSTALLED_APPS=('comptages.datamodel.apps.ComptagesConfig',),
        USE_TZ=True,
        TIME_ZONE='Europe/Zurich',
        SECRET_KEY='09n+dhzh+02+_#$!1+8h-&(s-wbda#0*2mrv@lx*y#&fzlv&l)',
        **additional_settings
    )
    django.setup()
コード例 #5
0
    def load_layer(self,
                   schema,
                   layer_name,
                   geometry,
                   sql,
                   display_name,
                   id_col='',
                   epsg=None):

        settings = Settings()
        uri = QgsDataSourceUri()
        uri.setConnection(settings.value("db_host"),
                          str(settings.value("db_port")),
                          settings.value("db_name"),
                          settings.value("db_username"),
                          settings.value("db_password"))

        uri.setDataSource(schema, layer_name, geometry, sql, id_col)
        layer = QgsVectorLayer(uri.uri(), display_name, "postgres")
        if epsg is not None:
            crs = QgsCoordinateReferenceSystem(epsg)
            layer.setCrs(crs)

        QgsProject.instance().addMapLayer(layer, addToLegend=False)

        return layer
コード例 #6
0
ファイル: utils.py プロジェクト: spch-GL/OpenComptage
def connect_to_db():
    settings = Settings()
    db = QSqlDatabase.addDatabase("QPSQL", str(datetime.now()))
    db.setHostName(settings.value("db_host"))
    db.setPort(settings.value("db_port"))
    db.setDatabaseName(settings.value("db_name"))
    db.setUserName(settings.value("db_username"))
    db.setPassword(settings.value("db_password"))
    db.open()

    return db
コード例 #7
0
ファイル: comptages.py プロジェクト: spch-GL/OpenComptage
class Comptages(QObject):
    def __init__(self, iface):
        QObject.__init__(self)

        self.iface = iface
        self.settings = Settings()
        self.settings_dialog = SettingsDialog()
        self.layers = Layers()
        self.chart_dock = ChartDock(self.iface, self.layers)
        self.iface.addDockWidget(Qt.BottomDockWidgetArea, self.chart_dock)
        self.filter_start_date = None
        self.filter_end_date = None
        self.filter_installation = None
        self.filter_sensor = None
        self.filter_tjm = None
        self.filter_axe = None
        self.filter_sector = None
        self.tm = QgsApplication.taskManager()

    def initGui(self):
        self.connect_db_action = QAction(
            QIcon(':/plugins/Comptages/images/power.png'), 'Connection DB',
            self.iface.mainWindow())

        self.create_new_action = QAction(
            QIcon(':/plugins/Comptages/images/measure.png'),
            'Créer un nouveau comptage', None)

        self.select_edit_action = QAction(
            QIcon(':/plugins/Comptages/images/select_edit.png'),
            'Modifier comptage', None)

        self.import_files_action = QAction(
            QIcon(':/plugins/Comptages/images/import.png'), 'Importation',
            None)

        self.validate_imported_files = QAction(
            QIcon(':/plugins/Comptages/images/validate.png'), 'Validation',
            None)

        self.filter_action = QAction(
            QIcon(':/plugins/Comptages/images/filter.png'), 'Filtrer', None)

        self.yearly_report_action = QAction(
            QIcon(':/plugins/Comptages/images/filled_file.png'),
            'Rapport annuel', None)

        self.import_ics_action = QAction(
            QIcon(':/plugins/Comptages/images/calendar.png'),
            'Importer fichier ics', None)

        self.settings_action = QAction(
            QIcon(':/plugins/Comptages/images/settings.png'), 'Réglages', None)

        self.connect_db_action.triggered.connect(self.do_connect_db_action)

        self.create_new_action.triggered.connect(self.do_create_new_action)

        self.select_edit_action.triggered.connect(self.do_select_edit_action)

        self.import_files_action.triggered.connect(self.do_import_files_action)

        self.validate_imported_files.triggered.connect(
            self.do_validate_imported_files_action)

        self.filter_action.triggered.connect(self.do_filter_action)

        self.yearly_report_action.triggered.connect(
            self.do_yearly_report_action)

        self.import_ics_action.triggered.connect(self.do_import_ics_action)

        self.settings_action.triggered.connect(self.do_settings_action)

        self.create_new_action.setEnabled(False)
        self.select_edit_action.setEnabled(False)
        self.import_files_action.setEnabled(False)
        self.validate_imported_files.setEnabled(False)
        self.filter_action.setEnabled(False)
        self.yearly_report_action.setEnabled(False)
        self.import_ics_action.setEnabled(False)

        self.iface.addPluginToMenu('Comptages', self.connect_db_action)
        self.iface.addPluginToMenu('Comptages', self.create_new_action)
        self.iface.addPluginToMenu('Comptages', self.select_edit_action)
        self.iface.addPluginToMenu('Comptages', self.import_files_action)
        self.iface.addPluginToMenu('Comptages', self.validate_imported_files)
        self.iface.addPluginToMenu('Comptages', self.filter_action)
        self.iface.addPluginToMenu('Comptages', self.yearly_report_action)
        self.iface.addPluginToMenu('Comptages', self.import_ics_action)
        self.iface.addPluginToMenu('Comptages', self.settings_action)

        self.toolbar = self.iface.addToolBar('Comptages')
        self.toolbar.setObjectName('Comptages')
        self.toolbar.setToolTip('Comptages toolbar')

        self.toolbar.addAction(self.connect_db_action)
        self.toolbar.addSeparator()
        self.toolbar.addAction(self.create_new_action)
        self.toolbar.addAction(self.select_edit_action)
        self.toolbar.addAction(self.import_files_action)
        self.toolbar.addAction(self.validate_imported_files)
        self.toolbar.addAction(self.filter_action)
        self.toolbar.addAction(self.yearly_report_action)
        self.toolbar.addAction(self.import_ics_action)
        self.toolbar.addSeparator()
        self.toolbar.addAction(self.settings_action)

    def unload(self):
        self.iface.removePluginMenu('Comptages', self.connect_db_action)
        self.iface.removePluginMenu('Comptages', self.create_new_action)
        self.iface.removePluginMenu('Comptages', self.select_edit_action)
        self.iface.removePluginMenu('Comptages', self.filter_action)
        self.iface.removePluginMenu('Comptages', self.yearly_report_action)
        self.iface.removePluginMenu('Comptages', self.import_ics_action)
        self.iface.removePluginMenu('Comptages', self.settings_action)

        del self.connect_db_action
        del self.create_new_action
        del self.select_edit_action
        del self.filter_action
        del self.yearly_report_action
        del self.import_ics_action
        del self.settings_action

        del self.toolbar

    def do_connect_db_action(self):
        self.layers.load_layers()
        self.enable_actions_if_needed()

    def do_create_new_action(self):
        if self.tm.countActiveTasks() > 0:
            push_info(("Veuillez patienter jusqu'à ce que l'importation "
                       "soit terminée."))
            return
        self.layers.create_count()

    def do_select_edit_action(self):
        if self.tm.countActiveTasks() > 0:
            push_info(("Veuillez patienter jusqu'à ce que l'importation "
                       "soit terminée."))
            return
        self.layers.edit_count()

    def do_import_files_action(self):
        if self.tm.countActiveTasks() > 0:
            push_info(("Veuillez patienter jusqu'à ce que l'importation "
                       "soit terminée."))
            return
        file_dialog = QFileDialog()
        title = 'Importer'
        path = self.settings.value('data_import_directory')
        files = QFileDialog.getOpenFileNames(
            file_dialog, title, path,
            "Data file (*.A?? *.aV? *.I?? *.V?? *.txt)")[0]

        self.tm.allTasksFinished.connect(
            partial(self.all_tasks_finished, 'import'))

        tasks = []
        for file_path in files:
            tasks.append(self.import_file(file_path))

        for t in tasks:
            self.tm.addTask(t)

    def import_file(self, file_path, count_id=None):
        QgsMessageLog.logMessage(
            '{} - Prepare import file {} started'.format(
                datetime.now(), os.path.basename(file_path)), 'Comptages',
            Qgis.Info)

        # Manage binary files
        with open(file_path, 'rb') as fd:
            file_head = fd.read(24)

        if file_head == b'Golden River Traffic Ltd':  # is a binary file
            formatter = self.layers.get_formatter_name('GoldenRiver')
            file_path_formatted = "{}_for".format(file_path)
            os.system("{} {} {}".format(formatter, file_path,
                                        file_path_formatted))
            file_path = file_path_formatted

        if count_id:
            count = models.Count.objects.get(id=count_id)
        else:
            count = importer.guess_count(file_path)

        if not count:
            QgsMessageLog.logMessage(
                "Impossible de trouver le comptage associé {}".format(
                    file_path, ), 'Comptages', Qgis.Critical)
            return

        QgsMessageLog.logMessage(
            '{} - Prepare import file {}'.format(datetime.now(),
                                                 os.path.basename(file_path)),
            'Comptages', Qgis.Info)

        QgsMessageLog.logMessage(
            '{} - Import file {} started'.format(datetime.now(),
                                                 os.path.basename(file_path)),
            'Comptages', Qgis.Info)

        task = importer_task.ImporterTask(file_path, count)
        return task

    def all_tasks_finished(self, task='import'):
        # Check if actually all tasks are finished because apparently it doesn't
        # work the same on all systems
        if not self.tm.countActiveTasks() == 0:
            QgsMessageLog.logMessage(
                '{} - all_tasks_finished signal raised, but active tasks still exist, ignoring it'
                .format(datetime.now()), 'Comptages', Qgis.Warning)

            return

        self.tm.allTasksFinished.disconnect()
        push_info(('Toutes les tâches sont terminées. Consultez le journal '
                   'pour plus de détails.'))
        QgsMessageLog.logMessage('{} - All tasks ended'.format(datetime.now()),
                                 'Comptages', Qgis.Info)

        if task == 'import':
            self.chart_dock.show_next_quarantined_chart()

    def do_validate_imported_files_action(self):
        if self.tm.countActiveTasks() > 0:
            push_info(("Veuillez patienter jusqu'à ce que l'importation "
                       "soit terminée."))
            return
        self.chart_dock.show_next_quarantined_chart()

    def do_filter_action(self):
        dlg = FilterDialog(self.iface)

        # Set last values in the filter
        if self.filter_start_date:
            dlg.start_date.setDateTime(self.filter_start_date)
        else:
            dlg.start_date.setDateTime(QDateTime())
        if self.filter_end_date:
            dlg.end_date.setDateTime(self.filter_end_date)
        else:
            dlg.end_date.setDateTime(QDateTime())
        if self.filter_installation:
            dlg.installation.setCurrentIndex(self.filter_installation)
        if self.filter_sensor:
            dlg.sensor.setCurrentIndex(self.filter_sensor)
        if self.filter_tjm:
            dlg.tjm.setRange(self.filter_tjm[0], self.filter_tjm[1])
        else:
            dlg.tjm.setRange(0, 30000)
        if self.filter_axe:
            dlg.axe.setCurrentIndex(self.filter_axe)

        if self.filter_sector:
            dlg.sector.setCurrentIndex(self.filter_sector)

        if dlg.exec_():
            self.filter_start_date = dlg.start_date.dateTime()
            self.filter_end_date = dlg.end_date.dateTime()
            self.filter_installation = dlg.installation.currentIndex()
            self.filter_sensor = dlg.sensor.currentIndex()
            self.filter_tjm = [dlg.tjm.lowerValue(), dlg.tjm.upperValue()]
            self.filter_axe = dlg.axe.currentIndex()
            self.filter_sector = dlg.sector.currentIndex()

            self.layers.apply_filter(
                dlg.start_date.dateTime().toString('yyyy-MM-dd'),
                dlg.end_date.dateTime().toString('yyyy-MM-dd'),
                dlg.installation.currentIndex(),
                dlg.sensor.currentIndex(),
                [self.filter_tjm[0], self.filter_tjm[1]],
                dlg.axe.currentData(),
                dlg.sector.currentData(),
            )

            if (not dlg.start_date.dateTime()) and (not dlg.end_date.dateTime()) and (dlg.installation.currentIndex() == 0) and \
               (dlg.sensor.currentIndex() == 0) and (dlg.tjm.lowerValue() == 0) and (dlg.tjm.upperValue() == 30000) and \
               (dlg.axe.currentText() == 'Tous') and (dlg.sector.currentText() == 'Tous'):
                self.filter_action.setIcon(
                    QIcon(':/plugins/Comptages/images/filter.png'))
            else:
                self.filter_action.setIcon(
                    QIcon(':/plugins/Comptages/images/filter_active.png'))

    def do_yearly_report_action(self):
        QgsMessageLog.logMessage(
            '{} - Generate yearly report action started'.format(
                datetime.now()), 'Comptages', Qgis.Info)

        if self.tm.countActiveTasks() > 0:
            push_info(("Veuillez patienter jusqu'à ce que l'importation "
                       "soit terminée."))
            return

        layer = self.layers.layers['section']

        selected_count = layer.selectedFeatureCount()
        if selected_count == 0:
            push_info("Veuillez sélectionner un tronçon")
            return
        elif selected_count > 1:
            push_info("Veuillez ne sélectionner qu'un tronçon")
            return
        else:
            selected_feature = next(layer.getSelectedFeatures())

        section_id = selected_feature.attribute('id')

        classes = self.layers.get_classes_of_section(section_id)
        dlg = YearlyReportDialog(self.iface)
        dlg.section.insert(section_id)
        dlg.classi.addItems(classes)

        if dlg.exec_():
            year = dlg.year.value()
            clazz = dlg.classi.currentText()

            file_dialog = QFileDialog()
            title = 'Exporter un rapport'
            path = self.settings.value('report_export_directory')
            file_path = QFileDialog.getExistingDirectory(
                file_dialog, title, path)

            if not file_path:
                QgsMessageLog.logMessage(
                    '{} - Generate yearly report action ended: No file_path given'
                    .format(datetime.now()), 'Comptages', Qgis.Info)
                return
            QgsMessageLog.logMessage(
                '{} - Generate yearly report action can really begin now for count {} with file_path: {}'
                .format(datetime.now(), selected_count,
                        file_path), 'Comptages', Qgis.Info)

            if clazz.startswith("SPCH-MD"):
                yrb = YearlyReportBike(file_path, year, section_id)
                yrb.run()
            else:
                self.tm.allTasksFinished.connect(
                    partial(self.all_tasks_finished, report))

                # TODO: consider the chosed class too
                self.tm.addTask(
                    report_task.ReportTask(file_path=file_path,
                                           template="yearly",
                                           year=year,
                                           section_id=section_id))
            # TODO: check if there are comptages for this section and year

    def do_import_ics_action(self):
        IcsImporter(self.layers)

    def do_settings_action(self):
        self.settings_dialog.exec_()

    def do_export_configuration_action(self, count_id):
        config_creator = ConfigCreatorCmd(self.layers, count_id)
        config_creator.set_section_commands()

        installation_name = self.layers.get_installation_name_of_count(
            count_id)

        file_dialog = QFileDialog()
        file_dialog.setDefaultSuffix('*.CMD')
        title = 'Exporter la configuration'
        path = os.path.join(self.settings.value('config_export_directory'),
                            "{}.CMD".format(installation_name))
        file = QFileDialog.getSaveFileName(file_dialog, title, path,
                                           "Config file (*.CMD)")[0]

        if not file:
            return

        config_creator.write_file(file)
        push_info('Written config file {}'.format(file))

    def do_import_single_file_action(self, count_id):
        file_dialog = QFileDialog()
        title = 'Importation'
        path = self.settings.value('data_import_directory')
        file_path = QFileDialog.getOpenFileName(
            file_dialog, title, path,
            "Data file (*.A?? *.aV? *.I?? *.V?? *.txt)")[0]

        if not file_path:
            return

        self.tm.allTasksFinished.connect(
            partial(self.all_tasks_finished, 'import'))

        self.tm.addTask(self.import_file(file_path, count_id))

    def do_generate_report_action(self, count_id):
        QgsMessageLog.logMessage(
            '{} - Generate report action started'.format(datetime.now()),
            'Comptages', Qgis.Info)

        count = models.Count.objects.get(id=count_id)

        if self.tm.countActiveTasks() > 0:
            push_info(("Veuillez patienter jusqu'à ce que l'importation "
                       "soit terminée."))
            return

        # Show message if there are no data to process
        if not models.CountDetail.objects.filter(id_count=count).exists():
            push_info(
                "Installation {}: Il n'y a pas de données à traiter pour "
                "le comptage {}".format(count.id_installation.name, count.id))
            QgsMessageLog.logMessage(
                '{} - Generate report action ended: No data for count {}'.
                format(datetime.now(), count.id), 'Comptages', Qgis.Info)
            return

        file_dialog = QFileDialog()
        title = 'Exporter un rapport'
        path = self.settings.value('report_export_directory')
        file_path = QFileDialog.getExistingDirectory(file_dialog, title, path)

        if not file_path:
            QgsMessageLog.logMessage(
                '{} - Generate report action ended: No file_path given'.format(
                    datetime.now()), 'Comptages', Qgis.Info)
            return
        QgsMessageLog.logMessage(
            '{} - Generate report action can really begin now for count {} with file_path: {}'
            .format(datetime.now(), count.id,
                    file_path), 'Comptages', Qgis.Info)

        self.tm.allTasksFinished.connect(
            partial(self.all_tasks_finished, 'report'))
        self.tm.addTask(
            report_task.ReportTask(
                file_path=file_path,
                count=count,
            ))

    def do_export_plan_action(self, count_id):
        plan_creator = PlanCreator(self.layers)
        file_dialog = QFileDialog()
        file_dialog.setDefaultSuffix('*.PDF')
        title = 'Exporter plan de pose'
        path = os.path.join(self.settings.value('config_export_directory'),
                            "{}.pdf".format("plan_de_pose"))
        file = QFileDialog.getSaveFileName(file_dialog, title, path,
                                           "Config file (*.PDF)")[0]

        if not file:
            return

        # Highlight the current sections and installation in the layout
        previous_highlightes_sections = self.layers.highlighted_sections
        self.layers.highlighted_sections = \
            self.layers.get_section_ids_of_count(count_id)
        QgsExpressionContextUtils.setProjectVariable(
            QgsProject.instance(), 'highlighted_installation',
            self.layers.get_installation_name_of_count(count_id))

        plan_creator.export_pdf(count_id, file)

        self.layers.highlighted_sections = previous_highlightes_sections
        QgsExpressionContextUtils.setProjectVariable(
            QgsProject.instance(), 'highlighted_installation', '')
        self.layers.layers['section'].triggerRepaint()

    def do_generate_chart_action(self, count_id):
        QgsMessageLog.logMessage(
            '{} - Generate chart action started'.format(datetime.now()),
            'Comptages', Qgis.Info)

        if self.tm.countActiveTasks() > 0:
            push_info(("Veuillez patienter jusqu'à ce que l'importation "
                       "soit terminée."))
            return
        count = models.Count.objects.get(id=count_id)
        self.chart_dock.set_attributes(count)

        QgsMessageLog.logMessage(
            '{} - Generate chart action ended'.format(datetime.now()),
            'Comptages', Qgis.Info)

    def do_delete_data_action(self, count_id):
        dlg = DeleteDialog(self.iface)
        tz = pytz.timezone("Europe/Zurich")

        if dlg.exec_():
            start = tz.localize(dlg.start_date.dateTime().toPyDateTime())
            end = tz.localize(dlg.end_date.dateTime().toPyDateTime())
            definitive = dlg.definitive.isChecked()
            quarantine = dlg.quarantine.isChecked()
            count = models.Count.objects.get(id=count_id)

            msg = QMessageBox()
            msg.setIcon(QMessageBox.Warning)
            msg.setText("Effacement des données")
            # msg.setInformativeText(f"Effacement des données")
            msg.setDetailedText("Les données suivantes seront supprimées:\n"
                                f"comptage: {count_id}\n"
                                f"de: {start.strftime('%d.%m.%Y')}\n"
                                f"à: {end.strftime('%d.%m.%Y')} inclus\n"
                                f"provisoires: {quarantine}\n"
                                f"définitives: {definitive}")
            msg.setWindowTitle("Effacement des données")
            msg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
            retval = msg.exec_()
            if retval == QMessageBox.Ok:
                qs = models.CountDetail.objects.filter(
                    id_count=count,
                    timestamp__range=(start, end + timedelta(days=1)),
                )

                if not definitive:
                    qs = qs.filter(status=definitions.IMPORT_STATUS_QUARANTINE)

                if not quarantine:
                    qs = qs.filter(status=definitions.IMPORT_STATUS_DEFINITIVE)

                qs.delete()

    def enable_actions_if_needed(self):
        """Enable actions if the plugin is connected to the db
        otherwise disable them"""
        self.create_new_action.setEnabled(True)
        self.select_edit_action.setEnabled(True)
        self.import_files_action.setEnabled(True)
        self.validate_imported_files.setEnabled(True)
        self.import_ics_action.setEnabled(True)
        self.filter_action.setEnabled(True)
        self.yearly_report_action.setEnabled(True)

    def is_section_highlighted(self, section_id):
        return self.layers.is_section_highlighted(section_id)

    @qgsfunction(args="auto", group="Comptages")
    def is_highlighted(feature, parent):
        """Used by section layer to apply a style to the sections related to a
        count"""

        # Call the method of the current instance of the plugin
        return plugins['comptages'].is_section_highlighted(
            feature.attribute('id'))

    @qgsfunction(args="auto", group="Comptages")
    def check_dates(feature, parent):
        """Used by count layer to show if a count was during a special
        period"""

        return plugins['comptages'].layers.check_dates(
            feature.attribute('start_process_date'),
            feature.attribute('end_process_date'))
コード例 #8
0
class TestImportDetail(unittest.TestCase):

    @classmethod
    def setUpClass(self):
        self.settings = Settings()
        self.layers = plugins['comptages'].layers
        self.layers.load_layers()
        self.comptages = plugins['comptages']

        self.db = QSqlDatabase.addDatabase(
            "QPSQL", "test_import_detail_connection")
        self.db.setHostName(self.settings.value("db_host"))
        self.db.setPort(self.settings.value("db_port"))
        self.db.setDatabaseName(self.settings.value("db_name"))
        self.db.setUserName(self.settings.value("db_username"))
        self.db.setPassword(self.settings.value("db_password"))

        self.test_data_path = os.path.join(
            os.path.dirname(os.path.realpath(__file__)),
            'test_data/')

    def setUp(self):
        self.db.open()
        query = QSqlQuery(self.db)

        query.exec_("DELETE FROM comptages.count;")
        query.exec_("DELETE FROM comptages.count_detail;")
        self.db.close()

    def test_simple_import_detail_data_multi_lane(self):
        self.db.open()
        query = QSqlQuery(self.db)

        query.exec_("SELECT id FROM comptages.installation \
                    WHERE name = '00056520';")
        query.next()
        installation_id = query.value(0)

        query.exec_("SELECT id FROM comptages.model \
                    WHERE name = 'M660_LT';")
        query.next()
        model_id = query.value(0)

        query.exec_("SELECT id FROM comptages.lane \
                    WHERE id_installation = {} ORDER BY number;".format(
                        installation_id))
        query.next()
        lane_1_id = query.value(0)
        query.next()
        lane_2_id = query.value(0)

        query.exec_("select id from comptages.sensor_type \
                    where name = 'Tube'")
        query.next()
        sensor_type_id = query.value(0)

        query_str = (
            "INSERT INTO comptages.count(id, "
            "start_process_date, end_process_date, start_service_date, "
            "end_service_date, id_sensor_type, id_model, id_installation) "
            "VALUES (1, '2018-09-23', '2018-09-26', '2018-09-23', "
            "'2018-09-26', {}, {}, {});".format(
                sensor_type_id, model_id, installation_id))
        query.exec_(query_str)

        task = self.comptages.import_file(
            os.path.join(
                self.test_data_path,
                'simple_detail_multi_lane.V01'),
            1)

        task.waitForFinished()
        # Let the time to the db to finish the writing
        time.sleep(1)

        query.exec_(
            "SELECT numbering, timestamp, distance_front_front, \
            distance_front_back, speed, length, height, fixed, wrong_way, \
            file_name, import_status, id_lane, id_count, id_category \
            FROM comptages.count_detail \
            WHERE file_name = 'simple_detail_multi_lane.V01' ORDER BY id;")

        self.assertEqual(2, query.size())

        query.next()
        self.assertEqual(1, query.value(0))
        self.assertEqual(
            '240918 1545 49 800',
            query.value(1).toString('ddMMyy HHmm ss zzz'))
        self.assertEqual(12.3, query.value(2))
        self.assertEqual(99.9, query.value(3))
        self.assertEqual(50, query.value(4))
        self.assertEqual(428, query.value(5))
        self.assertEqual('L', query.value(6).strip())
        self.assertNotEqual(True, query.value(7))
        self.assertNotEqual(True, query.value(8))
        self.assertEqual('simple_detail_multi_lane.V01', query.value(9))
        self.assertEqual(self.layers.IMPORT_STATUS_QUARANTINE, query.value(10))
        self.assertEqual(lane_1_id, query.value(11))
        self.assertEqual(1, query.value(12))
        self.assertEqual(24, query.value(13))

        query.next()
        self.assertEqual(2, query.value(0))
        self.assertEqual(
            '240918 1545 50 900',
            query.value(1).toString('ddMMyy HHmm ss zzz'))
        self.assertEqual(3.8, query.value(2))
        self.assertEqual(1.4, query.value(3))
        self.assertEqual(51, query.value(4))
        self.assertEqual(416, query.value(5))
        self.assertEqual('VL', query.value(6).strip())
        self.assertNotEqual(True, query.value(7))
        self.assertNotEqual(True, query.value(8))
        self.assertEqual('simple_detail_multi_lane.V01', query.value(9))
        self.assertEqual(self.layers.IMPORT_STATUS_QUARANTINE, query.value(10))
        self.assertEqual(lane_2_id, query.value(11))
        self.assertEqual(1, query.value(12))
        self.assertEqual(25, query.value(13))

        self.db.close()

    def test_special_case(self):
        self.db.open()
        query = QSqlQuery(self.db)

        query.exec_("SELECT id FROM comptages.installation \
                    WHERE name = '53109999';")
        query.next()
        installation_id = query.value(0)

        query.exec_("SELECT id FROM comptages.model \
                    WHERE name = 'M660_LT';")
        query.next()
        model_id = query.value(0)

        query.exec_("SELECT id FROM comptages.lane \
                    WHERE id_installation = {} ORDER BY number;".format(
                        installation_id))

        lane_ids = []
        while query.next():
            lane_ids.append(query.value(0))

        query.exec_("select id from comptages.sensor_type \
                    where name = 'Boucle'")
        query.next()
        sensor_type_id = query.value(0)

        query_str = (
            "INSERT INTO comptages.count(id, "
            "start_process_date, end_process_date, start_service_date, "
            "end_service_date, id_sensor_type, id_model, id_installation) "
            "VALUES (1, '2017-03-17', '2017-04-04', '2017-03-17', "
            "'2017-04-04', {}, {}, {});".format(
                sensor_type_id, model_id, installation_id))
        query.exec_(query_str)

        task = self.comptages.import_file(
            os.path.join(
                self.test_data_path,
                'simple_detail_special_case.V01'),
            1)

        task.waitForFinished()
        # Let the time to the db to finish the writing
        time.sleep(1)

        query.exec_(
            "SELECT * \
            FROM comptages.count_detail WHERE file_name = \
            'simple_detail_special_case.V01';")

        self.assertEqual(12, query.size())

        query.exec_(
            "SELECT * \
            FROM comptages.count_detail WHERE file_name = \
            'simple_detail_special_case.V01' and id_lane = {};".format(
                lane_ids[0]))

        self.assertEqual(1, query.size())

        query.exec_(
            "SELECT * \
            FROM comptages.count_detail WHERE file_name = \
            'simple_detail_special_case.V01' and id_lane = {};".format(
                lane_ids[1]))

        self.assertEqual(2, query.size())

        query.exec_(
            "SELECT * \
            FROM comptages.count_detail WHERE file_name = \
            'simple_detail_special_case.V01' and id_lane = {};".format(
                lane_ids[2]))

        self.assertEqual(4, query.size())

        query.exec_(
            "SELECT * \
            FROM comptages.count_detail WHERE file_name = \
            'simple_detail_special_case.V01' and id_lane = {};".format(
                lane_ids[3]))

        self.assertEqual(5, query.size())

        self.db.close()

    def test_validate_special_case(self):
        self.db.open()
        query = QSqlQuery(self.db)

        query.exec_("SELECT id FROM comptages.installation \
                    WHERE name = '53109999';")
        query.next()
        installation_id = query.value(0)

        query.exec_("SELECT id FROM comptages.model \
                    WHERE name = 'M660_LT';")
        query.next()
        model_id = query.value(0)

        query.exec_("select id from comptages.sensor_type \
                    where name = 'Boucle'")
        query.next()
        sensor_type_id = query.value(0)

        query_str = (
            "INSERT INTO comptages.count(id, "
            "start_process_date, end_process_date, start_service_date, "
            "end_service_date, id_sensor_type, id_model, id_installation) "
            "VALUES (1, '2017-03-17', '2017-04-04', '2017-03-17', "
            "'2017-04-04', {}, {}, {});".format(
                sensor_type_id, model_id, installation_id))
        query.exec_(query_str)

        task = self.comptages.import_file(
            os.path.join(
                self.test_data_path,
                'simple_detail_special_case.V01'),
            1)

        task.waitForFinished()
        # Let the time to the db to finish the writing
        time.sleep(1)

        query.exec_(
            "SELECT * \
            FROM comptages.count_detail WHERE file_name = \
            'simple_detail_special_case.V01' and import_status = {}".format(
                self.layers.IMPORT_STATUS_QUARANTINE))

        self.assertEqual(12, query.size())

        self.layers.change_status_of_count_data(
            1, '53116845', self.layers.IMPORT_STATUS_DEFINITIVE)

        query.exec_(
            "SELECT * \
            FROM comptages.count_detail WHERE file_name = \
            'simple_detail_special_case.V01' and import_status = {}".format(
                self.layers.IMPORT_STATUS_QUARANTINE))

        self.assertEqual(11, query.size())

        self.layers.change_status_of_count_data(
            1, '53136855', self.layers.IMPORT_STATUS_DEFINITIVE)

        query.exec_(
            "SELECT * \
            FROM comptages.count_detail WHERE file_name = \
            'simple_detail_special_case.V01' and import_status = {}".format(
                self.layers.IMPORT_STATUS_QUARANTINE))

        self.assertEqual(7, query.size())

        self.layers.change_status_of_count_data(
            1, '53126850', self.layers.IMPORT_STATUS_DEFINITIVE)

        query.exec_(
            "SELECT * \
            FROM comptages.count_detail WHERE file_name = \
            'simple_detail_special_case.V01' and import_status = {}".format(
                self.layers.IMPORT_STATUS_QUARANTINE))

        self.assertEqual(5, query.size())

        self.layers.change_status_of_count_data(
            1, '53146860', self.layers.IMPORT_STATUS_DEFINITIVE)

        query.exec_(
            "SELECT * \
            FROM comptages.count_detail WHERE file_name = \
            'simple_detail_special_case.V01' and import_status = {}".format(
                self.layers.IMPORT_STATUS_QUARANTINE))

        self.assertEqual(0, query.size())

        self.db.close()

    def test_refuse_special_case(self):
        self.db.open()
        query = QSqlQuery(self.db)

        query.exec_("SELECT id FROM comptages.installation \
                    WHERE name = '53109999';")
        query.next()
        installation_id = query.value(0)

        query.exec_("SELECT id FROM comptages.model \
                    WHERE name = 'M660_LT';")
        query.next()
        model_id = query.value(0)

        query.exec_("select id from comptages.sensor_type \
                    where name = 'Boucle'")
        query.next()
        sensor_type_id = query.value(0)

        query_str = (
            "INSERT INTO comptages.count(id, "
            "start_process_date, end_process_date, start_service_date, "
            "end_service_date, id_sensor_type, id_model, id_installation) "
            "VALUES (1, '2017-03-17', '2017-04-04', '2017-03-17', "
            "'2017-04-04', {}, {}, {});".format(
                sensor_type_id, model_id, installation_id))
        query.exec_(query_str)

        task = self.comptages.import_file(
            os.path.join(
                self.test_data_path,
                'simple_detail_special_case.V01'),
            1)

        task.waitForFinished()
        # Let the time to the db to finish the writing
        time.sleep(1)

        query.exec_(
            "SELECT * \
            FROM comptages.count_detail WHERE file_name = \
            'simple_detail_special_case.V01';")

        self.assertEqual(12, query.size())

        self.layers.delete_count_data(
            1, '53116845', self.layers.IMPORT_STATUS_QUARANTINE)

        query.exec_(
            "SELECT * \
            FROM comptages.count_detail WHERE file_name = \
            'simple_detail_special_case.V01';")

        self.assertEqual(11, query.size())

        self.layers.delete_count_data(
            1, '53136855', self.layers.IMPORT_STATUS_QUARANTINE)

        query.exec_(
            "SELECT * \
            FROM comptages.count_detail WHERE file_name = \
            'simple_detail_special_case.V01';")

        self.assertEqual(7, query.size())

        self.layers.delete_count_data(
            1, '53126850', self.layers.IMPORT_STATUS_QUARANTINE)

        query.exec_(
            "SELECT * \
            FROM comptages.count_detail WHERE file_name = \
            'simple_detail_special_case.V01';")

        self.assertEqual(5, query.size())

        self.layers.delete_count_data(
            1, '53146860', self.layers.IMPORT_STATUS_QUARANTINE)

        query.exec_(
            "SELECT * \
            FROM comptages.count_detail WHERE file_name = \
            'simple_detail_special_case.V01';")

        self.assertEqual(0, query.size())

        self.db.close()
コード例 #9
0
ファイル: test_chart_data.py プロジェクト: sitn/OpenComptage
class TestChartData(unittest.TestCase):
    @classmethod
    def setUpClass(self):
        self.settings = Settings()
        self.layers = plugins['comptages'].layers
        self.layers.load_layers()
        self.comptages = plugins['comptages']

        self.db = QSqlDatabase.addDatabase("QPSQL",
                                           "test_chart_data_connection")
        self.db.setHostName(self.settings.value("db_host"))
        self.db.setPort(self.settings.value("db_port"))
        self.db.setDatabaseName(self.settings.value("db_name"))
        self.db.setUserName(self.settings.value("db_username"))
        self.db.setPassword(self.settings.value("db_password"))

        self.test_data_path = os.path.join(
            os.path.dirname(os.path.realpath(__file__)), 'test_data/')

    def setUp(self):
        self.db.open()
        query = QSqlQuery(self.db)

        query.exec_("DELETE FROM comptages.count;")
        query.exec_("DELETE FROM comptages.count_detail;")
        query.exec_("DELETE FROM comptages.count_aggregate;")
        query.exec_("DELETE FROM comptages.count_aggregate_value_cls;")
        query.exec_("DELETE FROM comptages.count_aggregate_value_cnt;")
        query.exec_("DELETE FROM comptages.count_aggregate_value_drn;")
        query.exec_("DELETE FROM comptages.count_aggregate_value_len;")
        query.exec_("DELETE FROM comptages.count_aggregate_value_spd;")
        query.exec_("DELETE FROM comptages.count_aggregate_value_sds;")
        self.db.close()

    def test_speed_chart_aggregate(self):
        self.db.open()
        query = QSqlQuery(self.db)

        query.exec_("SELECT id FROM comptages.installation \
                    WHERE name = '64080011';")
        query.next()
        installation_id = query.value(0)

        query.exec_("SELECT id FROM comptages.model \
                    WHERE name = 'M660_LT';")
        query.next()
        model_id = query.value(0)

        query.exec_("select id from comptages.sensor_type \
                    where name = 'Tube'")
        query.next()
        sensor_type_id = query.value(0)

        query_str = (
            "INSERT INTO comptages.count(id, "
            "start_process_date, end_process_date, start_service_date, "
            "end_service_date, id_sensor_type, id_model, id_installation) "
            "VALUES (1, '2018-12-18', '2018-12-20', '2018-12-18', "
            "'2018-12-20', {}, {}, {});".format(sensor_type_id, model_id,
                                                installation_id))
        query.exec_(query_str)

        task = self.comptages.import_file(
            os.path.join(self.test_data_path, 'speed_chart_aggregate.i00'), 1)

        task.waitForFinished()
        # Let the time to the db to finish the writing
        time.sleep(1)

        x, y = self.layers.get_aggregate_speed_chart_data(
            1, self.layers.IMPORT_STATUS_QUARANTINE, '64080011')

        self.assertEqual([
            '0-15 km/h', '15-30 km/h', '30-40 km/h', '40-50 km/h',
            '50-60 km/h', '60-70 km/h', '70-80 km/h', '80-90 km/h',
            '90-100 km/h', '100-110 km/h', '110-120 km/h', '120-999 km/h'
        ], x)

        self.assertEqual([10, 55, 55, 130, 140, 110, 70, 60, 50, 40, 90, 100],
                         y)

    def test_speed_chart_detail(self):
        self.db.open()
        query = QSqlQuery(self.db)

        query.exec_("SELECT id FROM comptages.installation \
                    WHERE name = '64080011';")
        query.next()
        installation_id = query.value(0)

        query.exec_("SELECT id FROM comptages.model \
                    WHERE name = 'M660_LT';")
        query.next()
        model_id = query.value(0)

        query.exec_("select id from comptages.sensor_type \
                    where name = 'Tube'")
        query.next()
        sensor_type_id = query.value(0)

        query_str = (
            "INSERT INTO comptages.count(id, "
            "start_process_date, end_process_date, start_service_date, "
            "end_service_date, id_sensor_type, id_model, id_installation) "
            "VALUES (1, '2018-12-18', '2018-12-20', '2018-12-18', "
            "'2018-12-20', {}, {}, {});".format(sensor_type_id, model_id,
                                                installation_id))
        query.exec_(query_str)

        task = self.comptages.import_file(
            os.path.join(self.test_data_path, 'speed_chart_detail.V01'), 1)

        task.waitForFinished()
        # Let the time to the db to finish the writing
        time.sleep(1)

        x, y = self.layers.get_detail_speed_chart_data(
            1, self.layers.IMPORT_STATUS_QUARANTINE, '64080011')

        self.assertEqual([
            '0-10 km/h', '10-20 km/h', '20-30 km/h', '30-40 km/h',
            '40-50 km/h', '50-60 km/h', '60-70 km/h', '70-80 km/h',
            '80-90 km/h', '90-100 km/h', '100-110 km/h', '110-120 km/h',
            '120-999 km/h'
        ], x)

        self.assertEqual([1, 0, 3, 0, 0, 4, 0, 0, 1, 0, 0, 0, 2], y)

    def test_category_chart_aggregate(self):
        self.db.open()
        query = QSqlQuery(self.db)

        query.exec_("SELECT id FROM comptages.installation \
                    WHERE name = '64080011';")
        query.next()
        installation_id = query.value(0)

        query.exec_("SELECT id FROM comptages.model \
                    WHERE name = 'M660_LT';")
        query.next()
        model_id = query.value(0)

        query.exec_("select id from comptages.sensor_type \
                    where name = 'Tube'")
        query.next()
        sensor_type_id = query.value(0)

        query_str = (
            "INSERT INTO comptages.count(id, "
            "start_process_date, end_process_date, start_service_date, "
            "end_service_date, id_sensor_type, id_model, id_installation) "
            "VALUES (1, '2018-12-18', '2018-12-20', '2018-12-18', "
            "'2018-12-20', {}, {}, {});".format(sensor_type_id, model_id,
                                                installation_id))
        query.exec_(query_str)

        task = self.comptages.import_file(
            os.path.join(self.test_data_path, 'category_chart_aggregate.i00'),
            1)

        task.waitForFinished()
        # Let the time to the db to finish the writing
        time.sleep(1)

        label, values = self.layers.get_aggregate_category_chart_data(
            1, self.layers.IMPORT_STATUS_QUARANTINE, '64080011')

        self.assertEqual(label.index('CAR (1)'), values.index(10))
        self.assertEqual(label.index('MR (2)'), values.index(20))
        self.assertEqual(label.index('PW (3)'), values.index(30))
        self.assertEqual(label.index('PW+ANH (4)'), values.index(40))
        self.assertEqual(label.index('LIE (5)'), values.index(50))
        self.assertEqual(label.index('LIE+ANH (6)'), values.index(60))
        self.assertEqual(label.index('LIE+AUFL (7)'), values.index(70))
        self.assertEqual(label.index('LW (8)'), values.index(80))
        self.assertEqual(label.index('LZ (9)'), values.index(90))
        self.assertEqual(label.index('SZ (10)'), values.index(100))

    def test_category_chart_detail(self):
        self.db.open()
        query = QSqlQuery(self.db)

        query.exec_("SELECT id FROM comptages.installation \
                    WHERE name = '64080011';")
        query.next()
        installation_id = query.value(0)

        query.exec_("SELECT id FROM comptages.model \
                    WHERE name = 'M660_LT';")
        query.next()
        model_id = query.value(0)

        query.exec_("select id from comptages.sensor_type \
                    where name = 'Tube'")
        query.next()
        sensor_type_id = query.value(0)

        query_str = (
            "INSERT INTO comptages.count(id, "
            "start_process_date, end_process_date, start_service_date, "
            "end_service_date, id_sensor_type, id_model, id_installation) "
            "VALUES (1, '2018-12-18', '2018-12-20', '2018-12-18', "
            "'2018-12-20', {}, {}, {});".format(sensor_type_id, model_id,
                                                installation_id))
        query.exec_(query_str)

        task = self.comptages.import_file(
            os.path.join(self.test_data_path, 'category_chart_detail.V01'), 1)

        task.waitForFinished()
        # Let the time to the db to finish the writing
        time.sleep(1)

        label, values = self.layers.get_detail_category_chart_data(
            1, self.layers.IMPORT_STATUS_QUARANTINE, '64080011')

        self.assertEqual(label.index('CAR (1)'), values.index(3))
        self.assertEqual(label.index('MR (2)'), values.index(2))
        self.assertEqual(label.index('PW (3)'), values.index(5))
        self.assertEqual(label.index('SZ (10)'), values.index(1))

    def test_time_chart_by_lane_aggregate(self):
        self.db.open()
        query = QSqlQuery(self.db)

        query.exec_("SELECT id FROM comptages.installation \
                    WHERE name = '64080011';")
        query.next()
        installation_id = query.value(0)

        query.exec_("SELECT id FROM comptages.model \
                    WHERE name = 'M660_LT';")
        query.next()
        model_id = query.value(0)

        query.exec_("SELECT id FROM comptages.lane \
                    WHERE id_installation = {};".format(installation_id))
        lanes_id = []

        while query.next():
            lanes_id.append(query.value(0))

        query.exec_("select id from comptages.sensor_type \
                    where name = 'Boucle'")
        query.next()
        sensor_type_id = query.value(0)

        query_str = (
            "INSERT INTO comptages.count(id, "
            "start_process_date, end_process_date, start_service_date, "
            "end_service_date, id_sensor_type, id_model, id_installation) "
            "VALUES (1, '2018-12-18', '2018-12-20', '2018-12-18', "
            "'2018-12-20', {}, {}, {});".format(sensor_type_id, model_id,
                                                installation_id))
        query.exec_(query_str)

        task = self.comptages.import_file(
            os.path.join(self.test_data_path, 'time_chart_aggregate.i00'), 1)

        task.waitForFinished()
        # Let the time to the db to finish the writing
        time.sleep(1)

        xs, ys, days = self.layers.get_aggregate_time_chart_data_by_lane(
            1, self.layers.IMPORT_STATUS_QUARANTINE, lanes_id[0], '64080011')

        self.assertTrue(2, len(days))
        self.assertEqual([
            '00h-01h', '01h-02h', '02h-03h', '03h-04h', '04h-05h', '05h-06h',
            '06h-07h', '07h-08h', '08h-09h', '09h-10h', '10h-11h', '11h-12h',
            '12h-13h', '13h-14h', '14h-15h', '15h-16h', '16h-17h', '17h-18h',
            '18h-19h', '19h-20h', '20h-21h', '21h-22h', '22h-23h', '23h-00h'
        ], xs[0])
        self.assertEqual([
            '00h-01h', '01h-02h', '02h-03h', '03h-04h', '04h-05h', '05h-06h',
            '06h-07h', '07h-08h', '08h-09h', '09h-10h', '10h-11h', '11h-12h',
            '12h-13h', '13h-14h', '14h-15h', '15h-16h', '16h-17h', '17h-18h',
            '18h-19h', '19h-20h', '20h-21h', '21h-22h', '22h-23h', '23h-00h'
        ], xs[1])
        self.assertEqual([
            None, None, None, None, None, None, None, 55, 55, 55, 55, 55, 55,
            55, 55, 55, 55, None, None, None, None, None, None, None
        ], ys[0])
        self.assertEqual([
            None, None, None, None, None, None, None, None, None, None, None,
            None, None, None, None, None, 55, None, None, None, None, None,
            None, None
        ], ys[1])

        xs, ys, days = self.layers.get_aggregate_time_chart_data_by_lane(
            1, self.layers.IMPORT_STATUS_QUARANTINE, lanes_id[1], '64080011')

        self.assertTrue(2, len(days))
        self.assertEqual([
            '00h-01h', '01h-02h', '02h-03h', '03h-04h', '04h-05h', '05h-06h',
            '06h-07h', '07h-08h', '08h-09h', '09h-10h', '10h-11h', '11h-12h',
            '12h-13h', '13h-14h', '14h-15h', '15h-16h', '16h-17h', '17h-18h',
            '18h-19h', '19h-20h', '20h-21h', '21h-22h', '22h-23h', '23h-00h'
        ], xs[0])
        self.assertEqual([
            '00h-01h', '01h-02h', '02h-03h', '03h-04h', '04h-05h', '05h-06h',
            '06h-07h', '07h-08h', '08h-09h', '09h-10h', '10h-11h', '11h-12h',
            '12h-13h', '13h-14h', '14h-15h', '15h-16h', '16h-17h', '17h-18h',
            '18h-19h', '19h-20h', '20h-21h', '21h-22h', '22h-23h', '23h-00h'
        ], xs[1])
        self.assertEqual([
            None, None, None, None, None, None, None, 10, 10, 10, 10, 10, 10,
            10, 10, 10, 10, None, None, None, None, None, None, None
        ], ys[0])
        self.assertEqual([
            None, None, None, None, None, None, None, None, None, None, None,
            None, None, None, None, None, 10, None, None, None, None, None,
            None, None
        ], ys[1])

    def test_time_chart_by_direction_aggregate(self):
        self.db.open()
        query = QSqlQuery(self.db)

        query.exec_("SELECT id FROM comptages.installation \
                    WHERE name = '00056520';")
        query.next()
        installation_id = query.value(0)

        query.exec_("SELECT id FROM comptages.model \
                    WHERE name = 'M660_LT';")
        query.next()
        model_id = query.value(0)

        query.exec_("select id from comptages.sensor_type \
                    where name = 'Tube'")
        query.next()
        sensor_type_id = query.value(0)

        query_str = (
            "INSERT INTO comptages.count(id, "
            "start_process_date, end_process_date, start_service_date, "
            "end_service_date, id_sensor_type, id_model, id_installation) "
            "VALUES (1, '2018-12-18', '2018-12-20', '2018-12-18', "
            "'2018-12-20', {}, {}, {});".format(sensor_type_id, model_id,
                                                installation_id))
        query.exec_(query_str)

        task = self.comptages.import_file(
            os.path.join(self.test_data_path,
                         'time_chart_aggregate_direction.i00'), 1)

        task.waitForFinished()
        # Let the time to the db to finish the writing
        time.sleep(1)

        xs, ys, days = self.layers.get_aggregate_time_chart_data_by_direction(
            1, self.layers.IMPORT_STATUS_QUARANTINE, 1, '00056520')

        self.assertTrue(1, len(days))
        self.assertEqual([
            '00h-01h', '01h-02h', '02h-03h', '03h-04h', '04h-05h', '05h-06h',
            '06h-07h', '07h-08h', '08h-09h', '09h-10h', '10h-11h', '11h-12h',
            '12h-13h', '13h-14h', '14h-15h', '15h-16h', '16h-17h', '17h-18h',
            '18h-19h', '19h-20h', '20h-21h', '21h-22h', '22h-23h', '23h-00h'
        ], xs[0])
        self.assertEqual([
            None, None, None, None, None, None, None, 66, 66, 66, 66, 66, None,
            None, None, None, None, None, None, None, None, None, None, None
        ], ys[0])

        xs, ys, days = self.layers.get_aggregate_time_chart_data_by_direction(
            1, self.layers.IMPORT_STATUS_QUARANTINE, 2, '00056520')

        self.assertTrue(1, len(days))
        self.assertEqual([
            '00h-01h', '01h-02h', '02h-03h', '03h-04h', '04h-05h', '05h-06h',
            '06h-07h', '07h-08h', '08h-09h', '09h-10h', '10h-11h', '11h-12h',
            '12h-13h', '13h-14h', '14h-15h', '15h-16h', '16h-17h', '17h-18h',
            '18h-19h', '19h-20h', '20h-21h', '21h-22h', '22h-23h', '23h-00h'
        ], xs[0])
        self.assertEqual([
            None, None, None, None, None, None, None, 70, 70, 70, 70, 70, None,
            None, None, None, None, None, None, None, None, None, None, None
        ], ys[0])

    def test_time_chart_by_lane_detail(self):
        self.db.open()
        query = QSqlQuery(self.db)

        query.exec_("SELECT id FROM comptages.installation \
                    WHERE name = '00056520';")
        query.next()
        installation_id = query.value(0)

        query.exec_("SELECT id FROM comptages.model \
                    WHERE name = 'M660_LT';")
        query.next()
        model_id = query.value(0)

        query.exec_("SELECT id FROM comptages.lane \
                    WHERE id_installation = {};".format(installation_id))
        lanes_id = []
        while query.next():
            lanes_id.append(query.value(0))

        query.exec_("select id from comptages.sensor_type \
                    where name = 'Boucle'")
        query.next()
        sensor_type_id = query.value(0)
        query_str = (
            "INSERT INTO comptages.count(id, "
            "start_process_date, end_process_date, start_service_date, "
            "end_service_date, id_sensor_type, id_model, id_installation) "
            "VALUES (1, '2018-09-23', '2018-09-29', '2018-09-23', "
            "'2018-09-29', {}, {}, {});".format(sensor_type_id, model_id,
                                                installation_id))
        query.exec_(query_str)

        task = self.comptages.import_file(
            os.path.join(self.test_data_path, 'time_chart_detail.V01'), 1)

        task.waitForFinished()
        # Let the time to the db to finish the writing
        time.sleep(1)

        xs, ys, days = self.layers.get_detail_time_chart_data_by_lane(
            1, self.layers.IMPORT_STATUS_QUARANTINE, lanes_id[0], '00056520')

        self.assertTrue(1, len(days))
        self.assertEqual([
            '00h-01h', '01h-02h', '02h-03h', '03h-04h', '04h-05h', '05h-06h',
            '06h-07h', '07h-08h', '08h-09h', '09h-10h', '10h-11h', '11h-12h',
            '12h-13h', '13h-14h', '14h-15h', '15h-16h', '16h-17h', '17h-18h',
            '18h-19h', '19h-20h', '20h-21h', '21h-22h', '22h-23h', '23h-00h'
        ], xs[0])
        self.assertEqual([
            None, None, None, None, None, None, None, None, None, None, None,
            1, 1, 1, None, None, 1, 1, 1, None, None, 1, None, None
        ], ys[0])

        xs, ys, days = self.layers.get_detail_time_chart_data_by_lane(
            1, self.layers.IMPORT_STATUS_QUARANTINE, lanes_id[1], '00056520')

        self.assertTrue(1, len(days))
        self.assertEqual([
            '00h-01h', '01h-02h', '02h-03h', '03h-04h', '04h-05h', '05h-06h',
            '06h-07h', '07h-08h', '08h-09h', '09h-10h', '10h-11h', '11h-12h',
            '12h-13h', '13h-14h', '14h-15h', '15h-16h', '16h-17h', '17h-18h',
            '18h-19h', '19h-20h', '20h-21h', '21h-22h', '22h-23h', '23h-00h'
        ], xs[0])
        self.assertEqual([
            None, None, None, None, None, None, None, None, None, None, None,
            None, None, None, 1, 1, None, None, None, 1, 1, None, None, None
        ], ys[0])

    def test_time_chart_by_direction_detail(self):
        self.db.open()
        query = QSqlQuery(self.db)

        query.exec_("SELECT id FROM comptages.installation \
                    WHERE name = '00056520';")
        query.next()
        installation_id = query.value(0)

        query.exec_("SELECT id FROM comptages.model \
                    WHERE name = 'M660_LT';")
        query.next()
        model_id = query.value(0)

        query.exec_("select id from comptages.sensor_type \
                    where name = 'Tube'")
        query.next()
        sensor_type_id = query.value(0)

        query_str = (
            "INSERT INTO comptages.count(id, "
            "start_process_date, end_process_date, start_service_date, "
            "end_service_date, id_sensor_type, id_model, id_installation) "
            "VALUES (1, '2018-12-18', '2018-12-20', '2018-12-18', "
            "'2018-12-20', {}, {}, {});".format(sensor_type_id, model_id,
                                                installation_id))
        query.exec_(query_str)

        task = self.comptages.import_file(
            os.path.join(self.test_data_path,
                         'time_chart_detail_direction.V01'), 1)

        task.waitForFinished()
        # Let the time to the db to finish the writing
        time.sleep(1)

        xs, ys, days = self.layers.get_detail_time_chart_data_by_direction(
            1, self.layers.IMPORT_STATUS_QUARANTINE, 1, '00056520')

        self.assertTrue(1, len(days))
        self.assertEqual([
            '00h-01h', '01h-02h', '02h-03h', '03h-04h', '04h-05h', '05h-06h',
            '06h-07h', '07h-08h', '08h-09h', '09h-10h', '10h-11h', '11h-12h',
            '12h-13h', '13h-14h', '14h-15h', '15h-16h', '16h-17h', '17h-18h',
            '18h-19h', '19h-20h', '20h-21h', '21h-22h', '22h-23h', '23h-00h'
        ], xs[0])
        self.assertEqual([
            None, None, None, None, None, None, None, None, None, None, None,
            8, None, None, None, None, None, None, None, None, None, None,
            None, None
        ], ys[0])

        xs, ys, days = self.layers.get_detail_time_chart_data_by_direction(
            1, self.layers.IMPORT_STATUS_QUARANTINE, 2, '00056520')

        self.assertTrue(1, len(days))
        self.assertEqual([
            '00h-01h', '01h-02h', '02h-03h', '03h-04h', '04h-05h', '05h-06h',
            '06h-07h', '07h-08h', '08h-09h', '09h-10h', '10h-11h', '11h-12h',
            '12h-13h', '13h-14h', '14h-15h', '15h-16h', '16h-17h', '17h-18h',
            '18h-19h', '19h-20h', '20h-21h', '21h-22h', '22h-23h', '23h-00h'
        ], xs[0])
        self.assertEqual([
            None, None, None, None, None, None, None, None, None, None, None,
            3, None, None, None, None, None, None, None, None, None, None,
            None, None
        ], ys[0])

    def test_time_chart_special_case_detail(self):
        self.db.open()
        query = QSqlQuery(self.db)

        query.exec_("SELECT id FROM comptages.installation \
                    WHERE name = '53109999';")
        query.next()
        installation_id = query.value(0)

        query.exec_("SELECT id FROM comptages.model \
                    WHERE name = 'M660_LT';")
        query.next()
        model_id = query.value(0)

        query.exec_("SELECT id FROM comptages.lane \
                    WHERE id_installation = {};".format(installation_id))
        lanes_id = []
        while query.next():
            lanes_id.append(query.value(0))

        query.exec_("select id from comptages.sensor_type \
                    where name = 'Boucle'")
        query.next()
        sensor_type_id = query.value(0)

        query_str = (
            "INSERT INTO comptages.count(id, "
            "start_process_date, end_process_date, start_service_date, "
            "end_service_date, id_sensor_type, id_model, id_installation) "
            "VALUES (1, '2017-03-17', '2017-04-04', '2017-03-17', "
            "'2017-04-04', {}, {}, {});".format(sensor_type_id, model_id,
                                                installation_id))
        query.exec_(query_str)

        task = self.comptages.import_file(
            os.path.join(self.test_data_path,
                         'simple_detail_special_case.V01'), 1)

        task.waitForFinished()
        # Let the time to the db to finish the writing
        time.sleep(1)

        xs, ys, days = self.layers.get_detail_time_chart_data_by_lane(
            1, self.layers.IMPORT_STATUS_QUARANTINE, lanes_id[0], '53116845')

        self.assertTrue(1, len(days))
        self.assertEqual([
            '00h-01h', '01h-02h', '02h-03h', '03h-04h', '04h-05h', '05h-06h',
            '06h-07h', '07h-08h', '08h-09h', '09h-10h', '10h-11h', '11h-12h',
            '12h-13h', '13h-14h', '14h-15h', '15h-16h', '16h-17h', '17h-18h',
            '18h-19h', '19h-20h', '20h-21h', '21h-22h', '22h-23h', '23h-00h'
        ], xs[0])
        self.assertEqual([
            None, None, None, None, None, None, None, None, None, None, None,
            None, None, None, None, 1, None, None, None, None, None, None,
            None, None
        ], ys[0])

        xs, ys, days = self.layers.get_detail_time_chart_data_by_lane(
            1, self.layers.IMPORT_STATUS_QUARANTINE, lanes_id[1], '53126850')

        self.assertTrue(1, len(days))
        self.assertEqual([
            '00h-01h', '01h-02h', '02h-03h', '03h-04h', '04h-05h', '05h-06h',
            '06h-07h', '07h-08h', '08h-09h', '09h-10h', '10h-11h', '11h-12h',
            '12h-13h', '13h-14h', '14h-15h', '15h-16h', '16h-17h', '17h-18h',
            '18h-19h', '19h-20h', '20h-21h', '21h-22h', '22h-23h', '23h-00h'
        ], xs[0])
        self.assertEqual([
            None, None, None, None, None, None, None, None, None, None, None,
            None, None, None, None, 2, None, None, None, None, None, None,
            None, None
        ], ys[0])

        xs, ys, days = self.layers.get_detail_time_chart_data_by_lane(
            1, self.layers.IMPORT_STATUS_QUARANTINE, lanes_id[2], '53136855')

        self.assertTrue(1, len(days))
        self.assertEqual([
            '00h-01h', '01h-02h', '02h-03h', '03h-04h', '04h-05h', '05h-06h',
            '06h-07h', '07h-08h', '08h-09h', '09h-10h', '10h-11h', '11h-12h',
            '12h-13h', '13h-14h', '14h-15h', '15h-16h', '16h-17h', '17h-18h',
            '18h-19h', '19h-20h', '20h-21h', '21h-22h', '22h-23h', '23h-00h'
        ], xs[0])
        self.assertEqual([
            None, None, None, None, None, None, None, None, None, None, None,
            None, None, None, None, 4, None, None, None, None, None, None,
            None, None
        ], ys[0])

        xs, ys, days = self.layers.get_detail_time_chart_data_by_lane(
            1, self.layers.IMPORT_STATUS_QUARANTINE, lanes_id[3], '53146860')

        self.assertTrue(1, len(days))
        self.assertEqual([
            '00h-01h', '01h-02h', '02h-03h', '03h-04h', '04h-05h', '05h-06h',
            '06h-07h', '07h-08h', '08h-09h', '09h-10h', '10h-11h', '11h-12h',
            '12h-13h', '13h-14h', '14h-15h', '15h-16h', '16h-17h', '17h-18h',
            '18h-19h', '19h-20h', '20h-21h', '21h-22h', '22h-23h', '23h-00h'
        ], xs[0])
        self.assertEqual([
            None, None, None, None, None, None, None, None, None, None, None,
            None, None, None, None, 5, None, None, None, None, None, None,
            None, None
        ], ys[0])

    def test_time_chart_special_case_aggregate(self):
        self.db.open()
        query = QSqlQuery(self.db)

        query.exec_("SELECT id FROM comptages.installation \
                    WHERE name = '53109999';")
        query.next()
        installation_id = query.value(0)

        query.exec_("SELECT id FROM comptages.model \
                    WHERE name = 'M660_LT';")
        query.next()
        model_id = query.value(0)

        query.exec_("SELECT id FROM comptages.lane \
                    WHERE id_installation = {};".format(installation_id))
        lanes_id = []
        while query.next():
            lanes_id.append(query.value(0))

        query.exec_("select id from comptages.sensor_type \
                    where name = 'Boucle'")
        query.next()
        sensor_type_id = query.value(0)

        query_str = (
            "INSERT INTO comptages.count(id, "
            "start_process_date, end_process_date, start_service_date, "
            "end_service_date, id_sensor_type, id_model, id_installation) "
            "VALUES (1, '2017-03-17', '2017-04-04', '2017-03-17', "
            "'2017-04-04', {}, {}, {});".format(sensor_type_id, model_id,
                                                installation_id))
        query.exec_(query_str)

        task = self.comptages.import_file(
            os.path.join(self.test_data_path,
                         'simple_aggregate_special_case.A01'), 1)

        task.waitForFinished()
        # Let the time to the db to finish the writing
        time.sleep(1)

        xs, ys, days = self.layers.get_aggregate_time_chart_data_by_lane(
            1, self.layers.IMPORT_STATUS_QUARANTINE, lanes_id[0], '53116845')

        self.assertTrue(1, len(days))
        self.assertEqual([
            '00h-01h', '01h-02h', '02h-03h', '03h-04h', '04h-05h', '05h-06h',
            '06h-07h', '07h-08h', '08h-09h', '09h-10h', '10h-11h', '11h-12h',
            '12h-13h', '13h-14h', '14h-15h', '15h-16h', '16h-17h', '17h-18h',
            '18h-19h', '19h-20h', '20h-21h', '21h-22h', '22h-23h', '23h-00h'
        ], xs[0])
        self.assertEqual([
            None, None, None, None, None, None, None, None, None, None, None,
            None, 65, None, None, None, None, None, None, None, None, None,
            None, None
        ], ys[0])

        xs, ys, days = self.layers.get_aggregate_time_chart_data_by_lane(
            1, self.layers.IMPORT_STATUS_QUARANTINE, lanes_id[1], '53126850')

        self.assertTrue(1, len(days))
        self.assertEqual([
            '00h-01h', '01h-02h', '02h-03h', '03h-04h', '04h-05h', '05h-06h',
            '06h-07h', '07h-08h', '08h-09h', '09h-10h', '10h-11h', '11h-12h',
            '12h-13h', '13h-14h', '14h-15h', '15h-16h', '16h-17h', '17h-18h',
            '18h-19h', '19h-20h', '20h-21h', '21h-22h', '22h-23h', '23h-00h'
        ], xs[0])
        self.assertEqual([
            None, None, None, None, None, None, None, None, None, None, None,
            None, 53, None, None, None, None, None, None, None, None, None,
            None, None
        ], ys[0])

        xs, ys, days = self.layers.get_aggregate_time_chart_data_by_lane(
            1, self.layers.IMPORT_STATUS_QUARANTINE, lanes_id[2], '53136855')

        self.assertTrue(1, len(days))
        self.assertEqual([
            '00h-01h', '01h-02h', '02h-03h', '03h-04h', '04h-05h', '05h-06h',
            '06h-07h', '07h-08h', '08h-09h', '09h-10h', '10h-11h', '11h-12h',
            '12h-13h', '13h-14h', '14h-15h', '15h-16h', '16h-17h', '17h-18h',
            '18h-19h', '19h-20h', '20h-21h', '21h-22h', '22h-23h', '23h-00h'
        ], xs[0])
        self.assertEqual([
            None, None, None, None, None, None, None, None, None, None, None,
            None, 37, None, None, None, None, None, None, None, None, None,
            None, None
        ], ys[0])

        xs, ys, days = self.layers.get_aggregate_time_chart_data_by_lane(
            1, self.layers.IMPORT_STATUS_QUARANTINE, lanes_id[3], '53146860')

        self.assertTrue(1, len(days))
        self.assertEqual([
            '00h-01h', '01h-02h', '02h-03h', '03h-04h', '04h-05h', '05h-06h',
            '06h-07h', '07h-08h', '08h-09h', '09h-10h', '10h-11h', '11h-12h',
            '12h-13h', '13h-14h', '14h-15h', '15h-16h', '16h-17h', '17h-18h',
            '18h-19h', '19h-20h', '20h-21h', '21h-22h', '22h-23h', '23h-00h'
        ], xs[0])
        self.assertEqual([
            None, None, None, None, None, None, None, None, None, None, None,
            None, 18, None, None, None, None, None, None, None, None, None,
            None, None
        ], ys[0])
コード例 #10
0
ファイル: comptages.py プロジェクト: sitn/OpenComptage
class Comptages(QObject):

    def __init__(self, iface):
        QObject.__init__(self)

        self.iface = iface
        self.settings = Settings()
        self.settings_dialog = SettingsDialog()
        self.layers = Layers()
        self.chart_dock = ChartDock(self.iface, self.layers)
        self.iface.addDockWidget(Qt.BottomDockWidgetArea, self.chart_dock)
        self.filter_start_date = None
        self.filter_end_date = None
        self.filter_installation = None
        self.filter_sensor = None
        self.tm = QgsApplication.taskManager()

    def initGui(self):
        self.connect_db_action = QAction(
            QIcon(':/plugins/Comptages/images/power.png'),
            'Connection DB',
            self.iface.mainWindow()
        )

        self.create_new_action = QAction(
            QIcon(':/plugins/Comptages/images/measure.png'),
            'Créer un nouveau comptage',
            None
        )

        self.select_edit_action = QAction(
            QIcon(':/plugins/Comptages/images/select_edit.png'),
            'Modifier comptage',
            None
        )

        self.import_files_action = QAction(
            QIcon(':/plugins/Comptages/images/import.png'),
            'Importation',
            None
        )

        self.validate_imported_files = QAction(
            QIcon(':/plugins/Comptages/images/validate.png'),
            'Validation',
            None
        )

        self.filter_action = QAction(
            QIcon(':/plugins/Comptages/images/filter.png'),
            'Filtrer',
            None
        )

        self.import_ics_action = QAction(
            QIcon(':/plugins/Comptages/images/calendar.png'),
            'Importer fichier ics',
            None
        )

        self.settings_action = QAction(
            QIcon(':/plugins/Comptages/images/settings.png'),
            'Réglages',
            None
        )

        self.connect_db_action.triggered.connect(
            self.do_connect_db_action)

        self.create_new_action.triggered.connect(
            self.do_create_new_action)

        self.select_edit_action.triggered.connect(
            self.do_select_edit_action)

        self.import_files_action.triggered.connect(
            self.do_import_files_action)

        self.validate_imported_files.triggered.connect(
            self.do_validate_imported_files_action)

        self.filter_action.triggered.connect(
            self.do_filter_action)

        self.import_ics_action.triggered.connect(
            self.do_import_ics_action)

        self.settings_action.triggered.connect(
            self.do_settings_action)

        self.create_new_action.setEnabled(False)
        self.select_edit_action.setEnabled(False)
        self.import_files_action.setEnabled(False)
        self.validate_imported_files.setEnabled(False)
        self.filter_action.setEnabled(False)
        self.import_ics_action.setEnabled(False)

        self.iface.addPluginToMenu('Comptages', self.connect_db_action)
        self.iface.addPluginToMenu('Comptages', self.create_new_action)
        self.iface.addPluginToMenu('Comptages', self.select_edit_action)
        self.iface.addPluginToMenu('Comptages', self.import_files_action)
        self.iface.addPluginToMenu('Comptages', self.validate_imported_files)
        self.iface.addPluginToMenu('Comptages', self.filter_action)
        self.iface.addPluginToMenu('Comptages', self.import_ics_action)
        self.iface.addPluginToMenu('Comptages', self.settings_action)

        self.toolbar = self.iface.addToolBar('Comptages')
        self.toolbar.setObjectName('Comptages')
        self.toolbar.setToolTip('Comptages toolbar')

        self.toolbar.addAction(self.connect_db_action)
        self.toolbar.addSeparator()
        self.toolbar.addAction(self.create_new_action)
        self.toolbar.addAction(self.select_edit_action)
        self.toolbar.addAction(self.import_files_action)
        self.toolbar.addAction(self.validate_imported_files)
        self.toolbar.addAction(self.filter_action)
        self.toolbar.addAction(self.import_ics_action)
        self.toolbar.addSeparator()
        self.toolbar.addAction(self.settings_action)

    def unload(self):
        self.iface.removePluginMenu('Comptages', self.connect_db_action)
        self.iface.removePluginMenu('Comptages', self.create_new_action)
        self.iface.removePluginMenu('Comptages', self.select_edit_action)
        self.iface.removePluginMenu('Comptages', self.filter_action)
        self.iface.removePluginMenu('Comptages', self.import_ics_action)
        self.iface.removePluginMenu('Comptages', self.settings_action)

        del self.connect_db_action
        del self.create_new_action
        del self.select_edit_action
        del self.filter_action
        del self.import_ics_action
        del self.settings_action

        del self.toolbar

    def do_connect_db_action(self):
        self.layers.load_layers()
        self.enable_actions_if_needed()

    def do_create_new_action(self):
        if self.tm.countActiveTasks() > 0:
            push_info(("Veuillez patienter jusqu'à ce que l'importation "
                       "soit terminée."))
            return
        self.layers.create_count()

    def do_select_edit_action(self):
        if self.tm.countActiveTasks() > 0:
            push_info(("Veuillez patienter jusqu'à ce que l'importation "
                       "soit terminée."))
            return
        self.layers.edit_count()

    def do_import_files_action(self):
        if self.tm.countActiveTasks() > 0:
            push_info(("Veuillez patienter jusqu'à ce que l'importation "
                       "soit terminée."))
            return
        file_dialog = QFileDialog()
        title = 'Importer'
        path = self.settings.value('data_import_directory')
        files = QFileDialog.getOpenFileNames(
            file_dialog, title, path,
            "Data file (*.A?? *.aV? *.I?? *.V?? *.txt)")[0]

        for file_path in files:
            self.import_file(file_path)

    def import_file(self, file_path, count_id=None):

        # Manage binary files
        with open(file_path, 'rb') as fd:
            file_head = fd.read(24)

        if file_head == b'Golden River Traffic Ltd':  # is a binary file
            formatter = self.layers.get_formatter_name('GoldenRiver')
            file_path_formatted = "{}_for".format(file_path)
            os.system("{} {} {}".format(
                formatter, file_path, file_path_formatted))
            file_path = file_path_formatted

        file_header = DataImporter.parse_file_header(file_path)

        if not count_id:
            count_id = self.layers.guess_count_id(
                file_header['SITE'],
                datetime.strptime(file_header['STARTREC'], "%H:%M %d/%m/%y"),
                datetime.strptime(file_header['STOPREC'], "%H:%M %d/%m/%y"))

        if not count_id:
            QgsMessageLog.logMessage(
                """Impossible de trouver le comptage associé {}:
                section: {} start: {} end: {}""".format(
                    file_path,
                    file_header['SITE'],
                    datetime.strptime(file_header['STARTREC'], "%H:%M %d/%m/%y"),
                    datetime.strptime(file_header['STOPREC'], "%H:%M %d/%m/%y")
                ),
                'Comptages', Qgis.Critical)
            return

        QgsMessageLog.logMessage(
            'Importation {}'.format(os.path.basename(file_path)),
            'Comptages', Qgis.Info)

        file_format = file_header['FORMAT']

        if file_format == 'VBV-1':
            task = DataImporterVbv1(file_path, count_id)
        elif file_format == 'INT-2':
            task = DataImporterInt2(file_path, count_id)
        elif file_format == 'MC':
            task = DataImporterMC(file_path, count_id)
        else:
            push_info('Format {} of {} not supported'.format(
                file_format,
                os.path.basename(file_path)))
            return

        self.tm.allTasksFinished.connect(self.task_finished)
        self.tm.addTask(task)
        return task

    def task_finished(self):
        self.tm.allTasksFinished.disconnect(self.task_finished)
        push_info(('Toutes les tâches sont terminées. Consultez le journal '
                   'pour plus de détails.'))
        self.chart_dock.show_next_quarantined_chart()

    def do_validate_imported_files_action(self):
        if self.tm.countActiveTasks() > 0:
            push_info(("Veuillez patienter jusqu'à ce que l'importation "
                       "soit terminée."))
            return
        self.chart_dock.show_next_quarantined_chart()

    def do_filter_action(self):
        dlg = FilterDialog(self.iface)

        # Set last values in the filter
        if self.filter_start_date:
            dlg.start_date.setDateTime(self.filter_start_date)
        else:
            dlg.start_date.setDateTime(QDateTime())
        if self.filter_end_date:
            dlg.end_date.setDateTime(self.filter_end_date)
        else:
            dlg.end_date.setDateTime(QDateTime())
        if self.filter_installation:
            dlg.installation.setCurrentIndex(self.filter_installation)
        if self.filter_sensor:
            dlg.sensor.setCurrentIndex(self.filter_sensor)

        if dlg.exec_():
            self.filter_start_date = dlg.start_date.dateTime()
            self.filter_end_date = dlg.end_date.dateTime()
            self.filter_installation = dlg.installation.currentIndex()
            self.filter_sensor = dlg.sensor.currentIndex()

            self.layers.apply_filter(
                dlg.start_date.dateTime().toString('yyyy-MM-dd'),
                dlg.end_date.dateTime().toString('yyyy-MM-dd'),
                dlg.installation.currentIndex(),
                dlg.sensor.currentIndex())

    def do_import_ics_action(self):
        IcsImporter(self.layers)

    def do_settings_action(self):
        self.settings_dialog.exec_()

    def do_export_configuration_action(self, count_id):
        config_creator = ConfigCreatorCmd(self.layers, count_id)
        config_creator.set_section_commands()

        installation_name = self.layers.get_installation_name_of_count(
            count_id)

        file_dialog = QFileDialog()
        file_dialog.setDefaultSuffix('*.CMD')
        title = 'Exporter la configuration'
        path = os.path.join(
            self.settings.value('config_export_directory'),
            "{}.CMD".format(installation_name))
        file = QFileDialog.getSaveFileName(
            file_dialog, title, path, "Config file (*.CMD)")[0]

        if not file:
            return

        config_creator.write_file(file)
        push_info('Written config file {}'.format(file))

    def do_import_single_file_action(self, count_id):
        file_dialog = QFileDialog()
        title = 'Importation'
        path = self.settings.value('data_import_directory')
        file_path = QFileDialog.getOpenFileName(
            file_dialog, title, path,
            "Data file (*.A?? *.aV? *.I?? *.V?? *.txt)")[0]

        if not file_path:
            return

        self.import_file(file_path, count_id)

    def do_generate_report_action(self, count_id):
        if self.tm.countActiveTasks() > 0:
            push_info(("Veuillez patienter jusqu'à ce que l'importation "
                       "soit terminée."))
            return

        # Show message if there are no data to process
        contains_data = self.layers.count_contains_data(count_id)
        if not contains_data :
            push_info("Installation {}: Il n'y a pas de données à traiter pour "
                "le comptage {}".format(
                self.layers.get_installation_name_of_count(count_id),count_id))
            return

        file_dialog = QFileDialog()
        title = 'Exporter un rapport'
        path = self.settings.value('report_export_directory')
        file_path = QFileDialog.getExistingDirectory(
            file_dialog, title, path)
        print(file_path)

        if not file_path:
            return

        report_creator = ReportCreator(count_id, file_path, self.layers)
        report_creator.run()
        push_info("Installation {} (count={}): Génération du rapport terminée."
         .format(self.layers.get_installation_name_of_count(count_id),count_id))

    def do_export_plan_action(self, count_id):
        plan_creator = PlanCreator(self.layers)
        file_dialog = QFileDialog()
        file_dialog.setDefaultSuffix('*.PDF')
        title = 'Exporter plan de pose'
        path = os.path.join(
            self.settings.value('config_export_directory'),
            "{}.pdf".format("plan_de_pose"))
        file = QFileDialog.getSaveFileName(
            file_dialog, title, path, "Config file (*.PDF)")[0]

        if not file:
            return

        # Highlight the current sections and installation in the layout
        previous_highlightes_sections = self.layers.highlighted_sections
        self.layers.highlighted_sections = \
            self.layers.get_section_ids_of_count(count_id)
        QgsExpressionContextUtils.setProjectVariable(
            QgsProject.instance(), 'highlighted_installation',
            self.layers.get_installation_name_of_count(count_id))

        plan_creator.export_pdf(count_id, file)

        self.layers.highlighted_sections = previous_highlightes_sections
        QgsExpressionContextUtils.setProjectVariable(
            QgsProject.instance(), 'highlighted_installation',
            '')
        self.layers.layers['section'].triggerRepaint()

    def do_generate_chart_action(self, count_id):
        if self.tm.countActiveTasks() > 0:
            push_info(("Veuillez patienter jusqu'à ce que l'importation "
                       "soit terminée."))
            return
        self.chart_dock.set_attributes(count_id)

    def enable_actions_if_needed(self):
        """Enable actions if the plugin is connected to the db
        otherwise disable them"""
        self.create_new_action.setEnabled(True)
        self.select_edit_action.setEnabled(True)
        self.import_files_action.setEnabled(True)
        self.validate_imported_files.setEnabled(True)
        self.import_ics_action.setEnabled(True)
        self.filter_action.setEnabled(True)

    def is_section_highlighted(self, section_id):
        return self.layers.is_section_highlighted(section_id)

    @qgsfunction(args="auto", group="Comptages")
    def is_highlighted(feature, parent):
        """Used by section layer to apply a style to the sections related to a
        count"""

        # Call the method of the current instance of the plugin
        return plugins['comptages'].is_section_highlighted(
            feature.attribute('id'))

    @qgsfunction(args="auto", group="Comptages")
    def check_dates(feature, parent):
        """Used by count layer to show if a count was during a special
        period"""

        return plugins['comptages'].layers.check_dates(
            feature.attribute('start_process_date'),
            feature.attribute('end_process_date')
        )
コード例 #11
0
ファイル: plan_creator.py プロジェクト: spch-GL/OpenComptage
class PlanCreator():
    def __init__(self, layers):
        self.layers = layers
        self.settings = Settings()

    def export_pdf(self, count_id, file_name):

        current_dir = os.path.dirname(os.path.abspath(__file__))
        qpt_file_path = os.path.join(
            current_dir, os.pardir, 'qml', 'plan.qpt')
        self.layout = PlanCreator.create_layout_from_template(
            qpt_file_path)

        self.set_fields(count_id)

        # self.layers.select_and_zoom_on_section_of_count(count_id)
        canvas = iface.mapCanvas()

        map_item = self.layout.itemById('map')
        map_item.setExtent(canvas.extent())

        exporter = QgsLayoutExporter(self.layout)

        exporter.exportToPdf(
            file_name, exporter.PdfExportSettings())

    def set_fields(self, count_id):
        count = self.layers.get_count(count_id)
        installation = self.layers.get_installation_of_count(count_id)
        sections = self.layers.get_sections_of_count(count_id)

        self.set_text_item('f_01', installation.attribute('name'))
        self.set_text_item('f_03', '')
        self.set_text_item('f_04', sections[0].attribute('owner'))
        self.set_text_item('f_05', sections[0].attribute('road'))
        self.set_text_item('f_06', sections[0].attribute('way'))
        self.set_text_item(
            'f_07',
            '{} + {} m'.format(
                sections[0].attribute('start_pr'),
                sections[0].attribute('start_dist')))
        self.set_text_item(
            'f_08',
            '{} + {} m'.format(
                sections[0].attribute('end_pr'),
                sections[0].attribute('end_dist')))
        self.set_text_item('f_09', sections[0].attribute('place_name'))
        self.set_text_item(
            'f_10',
            count.attribute('start_process_date').toString(
                'dd.MM.yyyy (dddd)'))
        self.set_text_item(
            'f_11',
            count.attribute('end_process_date').toString(
                'dd.MM.yyyy (dddd)'))
        self.set_text_item('f_14', '')
        self.set_text_item('f_15', '')

        # Page 2
        self.set_text_item('f_17', 'Campagne de comptage')
        self.set_text_item(
            'f_18',
            'Pose {}'.format(count.attribute('start_put_date').toString(
                'dddd dd.MM.yyyy')))
        self.set_text_item(
            'f_19',
            'Dépose {}'.format(count.attribute('end_put_date').toString(
                'dddd dd.MM.yyyy')))
        self.set_text_item('f_20', sections[0].attribute('place_name'))
        self.set_text_item('f_21', installation.attribute('name'))
        self.set_text_item('f_22', '')
        self.set_text_item('f_23', '')

        self.set_picture_item('picture_1', installation.attribute('picture'))
        current_dir = os.path.dirname(os.path.abspath(__file__))
        self.set_picture_item(
            'logo',
            os.path.join(current_dir, os.pardir, 'images', 'logo_ne.png'))

    def set_text_item(self, name, text):
        self.layout.itemById(name).setText(text)

    def set_picture_item(self, name, file_name):
        if not file_name:
            return

        picture_path = os.path.join(
            self.settings.value('picture_directory'), file_name)
        self.layout.itemById(name).setPicturePath(picture_path)

    @staticmethod
    def create_layout_from_template(template_filename):
        layout = QgsPrintLayout(QgsProject().instance())
        document = QDomDocument()
        with open(os.path.join('data', 'general',
                               template_filename)) as template_file:
            template_content = template_file.read()
        document.setContent(template_content)
        layout.loadFromTemplate(document, QgsReadWriteContext())
        return layout
コード例 #12
0
ファイル: plan_creator.py プロジェクト: spch-GL/OpenComptage
 def __init__(self, layers):
     self.layers = layers
     self.settings = Settings()
コード例 #13
0
ファイル: test_data_func.py プロジェクト: sitn/OpenComptage
class TestData(unittest.TestCase):
    @classmethod
    def setUpClass(self):
        self.settings = Settings()
        self.layers = plugins['comptages'].layers
        self.layers.load_layers()
        self.comptages = plugins['comptages']

        self.db = QSqlDatabase.addDatabase("QPSQL", "test_data_connection")
        self.db.setHostName(self.settings.value("db_host"))
        self.db.setPort(self.settings.value("db_port"))
        self.db.setDatabaseName(self.settings.value("db_name"))
        self.db.setUserName(self.settings.value("db_username"))
        self.db.setPassword(self.settings.value("db_password"))

        self.test_data_path = os.path.join(
            os.path.dirname(os.path.realpath(__file__)), 'test_data/')

    def setUp(self):
        self.db.open()
        query = QSqlQuery(self.db)

        query.exec_("DELETE FROM comptages.count;")
        query.exec_("DELETE FROM comptages.count_detail;")
        query.exec_("DELETE FROM comptages.count_aggregate;")
        query.exec_("DELETE FROM comptages.count_aggregate_value_cls;")
        query.exec_("DELETE FROM comptages.count_aggregate_value_cnt;")
        query.exec_("DELETE FROM comptages.count_aggregate_value_drn;")
        query.exec_("DELETE FROM comptages.count_aggregate_value_len;")
        query.exec_("DELETE FROM comptages.count_aggregate_value_spd;")
        query.exec_("DELETE FROM comptages.count_aggregate_value_sds;")
        self.db.close()

    def test_data_detail(self):
        self.db.open()
        query = QSqlQuery(self.db)

        query.exec_("SELECT id FROM comptages.installation \
                    WHERE name = '64080011';")
        query.next()
        installation_id = query.value(0)

        query.exec_("SELECT id FROM comptages.model \
                    WHERE name = 'M660_LT';")
        query.next()
        model_id = query.value(0)

        query.exec_("select id from comptages.sensor_type \
                    where name = 'Tube'")
        query.next()
        sensor_type_id = query.value(0)

        query.exec_("select id from comptages.class \
                    where name = 'SWISS10'")
        query.next()
        class_id = query.value(0)

        query_str = (
            "INSERT INTO comptages.count(id, "
            "start_process_date, end_process_date, start_service_date, "
            "end_service_date, id_sensor_type, id_model, id_class, "
            "id_installation) "
            "VALUES (1, '2018-12-18', '2018-12-20', '2018-12-18', "
            "'2018-12-20', {}, {}, {}, {});".format(sensor_type_id, model_id,
                                                    class_id, installation_id))
        query.exec_(query_str)

        task = self.comptages.import_file(
            os.path.join(self.test_data_path, 'data_loader_simple_detail.V01'),
            1)

        task.waitForFinished()
        # Let the time to the db to finish the writing
        time.sleep(1)

        data_loader = DataLoader(1, '64080011',
                                 self.layers.IMPORT_STATUS_QUARANTINE)

        count_data = data_loader.load()
        self.assertEqual(
            [1, 0, 3, 0, 0, 4, 0, 0, 1, 0, 0, 0, 2],
            count_data.day_data[0].hour_data[15].direction_data[0].speed_data)

        self.assertEqual([1, 1, 2, 1, 1, 1, 1, 1, 1, 1],
                         count_data.day_data[0].hour_data[15].
                         direction_data[0].category_data)

        self.assertEqual(20, count_data.day_data[0].total())
        self.assertEqual(16, count_data.day_data[0].light_vehicles())
        self.assertEqual(4, count_data.day_data[0].heavy_vehicles())
        self.assertEqual(20.0, count_data.day_data[0].percent_heavy_vehicles())

    def test_data_aggregate(self):
        self.db.open()
        query = QSqlQuery(self.db)

        query.exec_("SELECT id FROM comptages.installation \
                    WHERE name = '64080011';")
        query.next()
        installation_id = query.value(0)

        query.exec_("SELECT id FROM comptages.model \
                    WHERE name = 'M660_LT';")
        query.next()
        model_id = query.value(0)

        query.exec_("select id from comptages.sensor_type \
                    where name = 'Tube'")
        query.next()
        sensor_type_id = query.value(0)

        query.exec_("select id from comptages.class \
                    where name = 'SWISS10'")
        query.next()
        class_id = query.value(0)

        query_str = (
            "INSERT INTO comptages.count(id, "
            "start_process_date, end_process_date, start_service_date, "
            "end_service_date, id_sensor_type, id_model, id_class, "
            "id_installation) "
            "VALUES (1, '2018-12-18', '2018-12-20', '2018-12-18', "
            "'2018-12-20', {}, {}, {}, {});".format(sensor_type_id, model_id,
                                                    class_id, installation_id))
        query.exec_(query_str)

        task = self.comptages.import_file(
            os.path.join(self.test_data_path,
                         'data_loader_simple_aggregate.i00'), 1)

        task.waitForFinished()
        # Let the time to the db to finish the writing
        time.sleep(1)

        data_loader = DataLoader(1, '64080011',
                                 self.layers.IMPORT_STATUS_QUARANTINE)

        count_data = data_loader.load()

        self.assertEqual(
            [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
            count_data.day_data[1].hour_data[8].direction_data[0].speed_data)
        self.assertEqual([
            1, 2, 3, 4, 5, 6, 7, 8, 9, 10
        ], count_data.day_data[1].hour_data[8].direction_data[0].category_data)
コード例 #14
0
 def __init__(self, count_id, file_path, layers):
     self.count_id = count_id
     self.file_path = file_path
     self.settings = Settings()
     self.layers = layers