Пример #1
0
    def create_count(self):

        layer = self.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())

            lanes = self.get_lanes_of_section(selected_feature.attribute('id'))
            installation = self.get_installation_of_lane(
                next(lanes).attribute('id'))

            # Save the id of the installation related to the selected section
            # so we can use in the count form to automatically select the
            # installation in the combobox
            QgsExpressionContextUtils.setProjectVariable(
                QgsProject.instance(), 'selected_installation',
                installation.attribute('id'))
            self.layers['count'].startEditing()
            iface.setActiveLayer(self.layers['count'])
            iface.actionAddFeature().trigger()
Пример #2
0
    def delete_count_data(self, count_id, section_id, status):
        self.init_db_connection()
        query = QSqlQuery(self.db)

        query_strs = []

        query_strs.append("delete from comptages.count_aggregate as cou "
                          "using comptages.lane as lan "
                          "where cou.id_lane = lan.id "
                          "and cou.id_count = {} "
                          "and cou.import_status = {} "
                          "and lan.id_section = '{}' ".format(
                              count_id, status, section_id))

        query_strs.append("delete from comptages.count_detail as cou "
                          "using comptages.lane as lan "
                          "where cou.id_lane = lan.id "
                          "and cou.id_count = {} "
                          "and cou.import_status = {} "
                          "and lan.id_section = '{}' ".format(
                              count_id, status, section_id))

        for _ in query_strs:
            query.exec_(_)

        push_info("Les données ont été supprimées")
Пример #3
0
    def set_attributes(self, count):
        try:
            self.tabWidget.currentChanged.disconnect(self.current_tab_changed)
        except Exception:
            pass

        self.count = count

        self.setWindowTitle("Comptage: {}, installation: {}".format(
            count.id, count.id_installation.name))

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

        self.show()

        self.tabWidget.clear()
        self.tabWidget.currentChanged.connect(self.current_tab_changed)

        # We do by section and not by count because of special cases.
        sections = models.Section.objects.filter(
            lane__id_installation__count=count).distinct()
        for section in sections:
            tab = ChartTab()
            self.tabWidget.addTab(tab, section.id)
            self._populate_tab(tab, section, count)
Пример #4
0
    def import_file(self, file_path):
        ics = open(file_path, 'rb')
        cal = icalendar.Calendar.from_ical(ics.read())
        ics.close()

        for event in cal.walk('vevent'):

            if 'DTSTART' not in event and 'DTEND' not in event:
                continue

            summary = ''
            if 'SUMMARY' in event:
                summary = str(event['SUMMARY'])

            location = ''
            if 'LOCATION' in event:
                location = str(event['LOCATION'])

            self.layers.write_special_period(event['DTSTART'].dt,
                                             event['DTEND'].dt, summary,
                                             location, '')

            # str(event['PRIORITY'])
            # event['CATEGORIES'].cats

        push_info('Importation terminée')
        QgsMessageLog.logMessage('Import ics finished', 'Comptages', Qgis.Info)
Пример #5
0
    def change_status_of_count_data(self, count_id, section_id, new_status):
        self.init_db_connection()
        query = QSqlQuery(self.db)

        query_strs = []

        query_strs.append(
            "update comptages.count_aggregate as cou set import_status = {} "
            "from comptages.lane as lan "
            "where cou.id_lane = lan.id "
            "and id_count = {} "
            "and lan.id_section = '{}'".format(new_status, count_id,
                                               section_id))

        query_strs.append(
            "update comptages.count_detail as cou set import_status = {} "
            "from comptages.lane as lan "
            "where cou.id_lane = lan.id "
            "and id_count = {} "
            "and lan.id_section = '{}'".format(new_status, count_id,
                                               section_id))

        for _ in query_strs:
            query.exec_(_)

        push_info("Les données ont été importées")
Пример #6
0
    def show_next_quarantined_chart(self):
        quarantined_counts = self.layers.get_quarantined_counts()
        if not quarantined_counts:
            self.hide()
            push_info("Il n'y a pas de données à montrer")
            return

        self.set_attributes(quarantined_counts[0], True)
        self.show()
Пример #7
0
    def open_count_attribute_table_and_filter(self, count_ids):
        """Open the attribute table of count filtered on the passed ids"""
        if not count_ids:
            push_info("No counts found for this section")
            return

        iface.showAttributeTable(
            self.layers['count'],
            '"id" in ({})'.format(", ".join(map(str, count_ids))))
Пример #8
0
    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
Пример #9
0
    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)
Пример #10
0
    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)
Пример #11
0
    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()
Пример #12
0
    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,
            ))
Пример #13
0
    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))
Пример #14
0
    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
        file_dialog = QFileDialog()
        file_dialog.setDefaultSuffix('*.xlsx')
        title = 'Exporter un rapport'
        path = os.path.join(
            self.settings.value('report_export_directory'),
            "{}.xlsx".format("report"))
        file_path = QFileDialog.getSaveFileName(
            file_dialog, title, path, "Rapport (*.XLSX)")[0]

        if not file_path:
            return

        report_creator = ReportCreator(count_id, file_path, self.layers)
        report_creator.run()
        push_info(("Exportation rappport terminée."))
Пример #15
0
    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)
Пример #16
0
    def edit_count(self):
        """Open attribute table of count filtered with only the
        features related to the selected section"""

        layer = self.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())
            counts = self.get_counts_of_section(
                selected_feature.attribute('id'))
            ids = []
            for c in counts:
                ids.append(c.attribute('id'))
            self.open_count_attribute_table_and_filter(ids)
Пример #17
0
    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))
Пример #18
0
    def show_next_quarantined_chart(self):
        QgsMessageLog.logMessage(
            '{} - Generate validation chart started'.format(datetime.now()),
            'Comptages', Qgis.Info)

        quarantined_counts = models.Count.objects.filter(
            countdetail__import_status=definitions.IMPORT_STATUS_QUARANTINE
        ).distinct()
        if not quarantined_counts.exists():
            self.hide()
            push_info("Il n'y a pas de données à valider")
            QgsMessageLog.logMessage(
                '{} - Generate validation chart ended : No data to validate'.
                format(datetime.now()), 'Comptages', Qgis.Info)
            return

        self.set_attributes(quarantined_counts[0])
        self.show()

        QgsMessageLog.logMessage(
            '{} - Generate validation chart ended'.format(datetime.now()),
            'Comptages', Qgis.Info)
Пример #19
0
    def set_attributes(self, count_id, approval_process=False):
        try:
            self.tabWidget.currentChanged.disconnect(self.current_tab_changed)
        except Exception:
            pass

        self.count_id = count_id

        self.setWindowTitle("Comptage: {}, installation: {}".format(
            count_id, self.layers.get_installation_name_of_count(count_id)))

        contains_data = self.layers.count_contains_data(count_id)

        # Show message if there are no data to show
        if not contains_data and not approval_process:
            self.hide()
            push_info("Il n'y a pas de données à montrer")
            return

        self.show()

        # Show message if data for this count already exists in the db
        if contains_data and approval_process:
            push_warning(('La base de données contient déjà des données '
                          'pour ce comptage.'))

        self.tabWidget.clear()
        self.tabWidget.currentChanged.connect(self.current_tab_changed)
        status = self.layers.IMPORT_STATUS_DEFINITIVE
        if approval_process:
            status = self.layers.IMPORT_STATUS_QUARANTINE

        section_ids = self.layers.get_sections_with_data_of_count(
            count_id, status)

        for section_id in section_ids:
            tab = ChartTab(section_id)
            self.tabWidget.addTab(tab, section_id)
            self.populate_tab(tab, count_id, section_id, approval_process)
Пример #20
0
    def import_file(self, file_path, count_id=None):
        file_header = DataImporter.parse_file_header(file_path)
        print(file_header)
        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é {}'.format(
                    file_path),
                '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
Пример #21
0
    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))
Пример #22
0
 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()
Пример #23
0
 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()
Пример #24
0
 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()
Пример #25
0
 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)