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()
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")
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)
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)
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")
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()
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))))
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 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 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 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_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_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_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."))
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 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)
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 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)
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)
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
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))
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_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 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_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)