def data(self, index, role=QtCore.Qt.DisplayRole): if role != QtCore.Qt.DisplayRole: return QVariant() if not index.isValid(): return QVariant() if index.column() == self.data_dict['Pressure']: return QVariant(str(self.prj.cur.proc.pressure[index.row()])) elif index.column() == self.data_dict['Depth']: return QVariant(str(self.prj.cur.proc.depth[index.row()])) elif index.column() == self.data_dict['Speed']: return QVariant(str(self.prj.cur.proc.speed[index.row()])) elif index.column() == self.data_dict['Temp']: return QVariant(str(self.prj.cur.proc.temp[index.row()])) elif index.column() == self.data_dict['Cond']: return QVariant(str(self.prj.cur.proc.conductivity[index.row()])) elif index.column() == self.data_dict['Sal']: return QVariant(str(self.prj.cur.proc.sal[index.row()])) elif index.column() == self.data_dict['Source']: return QVariant( "%.0f [%s]" % (self.prj.cur.proc.source[index.row()], Dicts.first_match(Dicts.sources, self.prj.cur.proc.source[index.row()]))) elif index.column() == self.data_dict['Flag']: return QVariant( "%.0f [%s]" % (self.prj.cur.proc.flag[index.row()], Dicts.first_match(Dicts.flags, self.prj.cur.proc.flag[index.row()]))) else: return QVariant()
def debug_info(self): msg = "Sensor: %s\n" % Dicts.first_match(Dicts.sensor_types, self.sensor_type) msg += "Probe: %s\n" % Dicts.first_match(Dicts.probe_types, self.probe_type) msg += "Location: %s, %s\n" % (self.latitude, self.longitude) msg += "Time: %s\n" % self.utc_time if self.original_path: msg += "Basename: %s\n" % os.path.basename(self.original_path) msg += "Survey: %s, Vessel: %s\n" % (self.survey, self.vessel) msg += "S/N: %s\n" % self.sn msg += "Last proc. time: %s\n" % self.proc_time msg += "Last proc. info: %s\n" % self.proc_info return msg
def on_save_db(self, auto_save=False): if auto_save: logger.debug('auto-save data to db') else: logger.debug('user wants to save data to db') self.main_win.switch_to_editor_tab() # since auto-save the same checks and questions have been asked! valid = self._run_safety_checks_on_output() if not valid: return if self.lib.cur.meta.sensor_type in [ Dicts.sensor_types['Synthetic'], ]: msg = "Do you really want to store a profile based \non synthetic %s data?\n" \ % Dicts.first_match(Dicts.probe_types, self.lib.cur.meta.probe_type) # noinspection PyCallByClass ret = QtWidgets.QMessageBox.warning( self, "Synthetic source warning", msg, QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No) if ret == QtWidgets.QMessageBox.No: return if self.lib.cur.meta.probe_type in [ Dicts.probe_types['ASVP'], Dicts.probe_types['CARIS'], Dicts.probe_types['ELAC'], Dicts.probe_types['HYPACK'] ]: msg = "Do you really want to store a profile based \non pre-processed %s data?\n\n" \ "This operation may OVERWRITE existing raw data \nin the database!" \ % Dicts.first_match(Dicts.probe_types, self.lib.cur.meta.probe_type) # noinspection PyCallByClass ret = QtWidgets.QMessageBox.warning( self, "Pre-processed source warning", msg, QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No) if ret == QtWidgets.QMessageBox.No: return if not self.lib.store_data(): msg = "Unable to save to db!" # noinspection PyCallByClass QtWidgets.QMessageBox.warning(self, "Database warning", msg, QtWidgets.QMessageBox.Ok) return self.main_win.data_stored()
def on_transmit_data(self): logger.debug('user wants to transmit the data') self.main_win.switch_to_editor_tab() valid = self._run_safety_checks_on_output() if not valid: return if self.lib.cur.meta.sensor_type in [ Dicts.sensor_types['Synthetic'], ]: msg = "Do you really want to transmit a profile\nbased on synthetic %s data?" \ % Dicts.first_match(Dicts.probe_types, self.lib.cur.meta.probe_type) # noinspection PyCallByClass ret = QtWidgets.QMessageBox.warning( self, "Synthetic source warning", msg, QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No) if ret == QtWidgets.QMessageBox.No: return if self.lib.cur.meta.probe_type in [ Dicts.probe_types['ASVP'], Dicts.probe_types['CARIS'], Dicts.probe_types['ELAC'], Dicts.probe_types['HYPACK'] ]: msg = "Do you really want to transmit a profile\nbased on pre-processed %s data?" \ % Dicts.first_match(Dicts.probe_types, self.lib.cur.meta.probe_type) # noinspection PyCallByClass ret = QtWidgets.QMessageBox.warning( self, "Pre-processed source warning", msg, QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No) if ret == QtWidgets.QMessageBox.No: return if not self.lib.transmit_ssp(): msg = "Possible issue in profile transmission." # noinspection PyCallByClass QtWidgets.QMessageBox.warning(self, "Profile transmission", msg, QtWidgets.QMessageBox.Ok) self.on_save_db(auto_save=True) self.dataplots.update_data()
def on_export_single_profile(self): logger.debug('user wants to export a single profile') self.main_win.switch_to_editor_tab() valid = self._run_safety_checks_on_output() if not valid: return if self.lib.cur.meta.sensor_type in [ Dicts.sensor_types['Synthetic'], ]: msg = "Do you really want to export a profile\nbased on synthetic %s data?" \ % Dicts.first_match(Dicts.probe_types, self.lib.cur.meta.probe_type) # noinspection PyCallByClass ret = QtWidgets.QMessageBox.warning( self, "Synthetic source warning", msg, QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No) if ret == QtWidgets.QMessageBox.No: return if self.lib.cur.meta.probe_type in [ Dicts.probe_types['ASVP'], Dicts.probe_types['CARIS'], Dicts.probe_types['ELAC'], Dicts.probe_types['HYPACK'] ]: msg = "Do you really want to export a profile\nbased on pre-processed %s data?" \ % Dicts.first_match(Dicts.probe_types, self.lib.cur.meta.probe_type) # noinspection PyCallByClass ret = QtWidgets.QMessageBox.warning( self, "Pre-processed source warning", msg, QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No) if ret == QtWidgets.QMessageBox.No: return dlg = ExportSingleProfileDialog(lib=self.lib, main_win=self.main_win, parent=self) result = dlg.exec_() if result == QtWidgets.QDialog.Accepted: self.on_save_db(auto_save=True) self.dataplots.update_data()
def _write_header(self): """Write header: 5 rows -> title, date, time, probe, comments""" # logger.debug('generating header') header = str() # row #0: title if self._project: header += "%s\n" % self._project elif self.ssp.cur.meta.survey: header += "%s\n" % self.ssp.cur.meta.survey else: header += "Generated using HydrOffice %s v.%s\n" % (ssp_name, ssp_version) # row #1: date if self.ssp.cur.meta.utc_time: header += "%s\n" % self.ssp.cur.meta.utc_time.strftime( "%d/%m/%Y").lstrip("0").replace("/0", "/") else: header += "0\n" # row #2: time if self.ssp.cur.meta.utc_time: header += "%s\n" % self.ssp.cur.meta.utc_time.strftime( "%H:%M:%S").lstrip("0").replace(":0", ":") else: header += "0\n" # row #3: probe if self.ssp.cur.meta.probe_type: header += "Probe: %s\n" % Dicts.first_match( Dicts.probe_types, self.ssp.cur.meta.probe_type) else: header += "0\n" # row #4: comments if self.ssp.cur.meta.original_path: header += "Source: %s\n" % self.ssp.cur.meta.original_path else: header += "0\n" self.fod.io.write(header)
def probe(self): return Dicts.first_match(Dicts.probe_types, self.probe_type)
def sensor(self): return Dicts.first_match(Dicts.sensor_types, self.sensor_type)
def update_table(self): class NumberWidgetItem(QtWidgets.QTableWidgetItem): def __lt__(self, other): # noinspection PyBroadException try: return float(self.text()) < float(other.text()) except Exception: return True class LocationWidgetItem(QtWidgets.QTableWidgetItem): def __lt__(self, other): self_lon = self.text()[1:].split(';')[0] other_lon = other.text()[1:].split(';')[0] self_lat = self.text()[:-1].split(';')[-1] other_lat = other.text()[:-1].split(';')[-1] logger.debug("%s %s < %s %s" % (self_lon, self_lat, other_lon, other_lat)) # noinspection PyBroadException try: if self_lon == other_lon: return float(self_lat) < float(other_lat) return float(self_lon) < float(other_lon) except Exception: return True # set the top label self.active_label.setText("<b>Current project: %s</b>" % self.lib.current_project) lst = self.lib.db_list_profiles() # prepare the table self.ssp_list.setSortingEnabled(False) self.ssp_list.clear() self.ssp_list.setColumnCount(24) self.ssp_list.setHorizontalHeaderLabels(['id', 'time', 'location', 'sensor', 'probe', 'ss@min depth', 'min depth', 'max depth', 'max depth[no ext]', 'original path', 'institution', 'survey', 'vessel', 'sn', 'processing time', 'processing info', 'surveylines', 'comments', 'pressure uom', 'depth uom', 'speed uom', 'temperature uom', 'conductivity uom', 'salinity uom', ]) # populate the table self.ssp_list.setRowCount(len(lst)) for i, ssp_ in enumerate(lst): processed = True tokens = ssp_[11].split(";") # Re-arrange index to match the new items and labels ssp = ssp_[0:5] + ssp_[20:24] + ssp_[5:20] if Dicts.proc_user_infos['PLOTTED'] not in tokens: processed = False for j, field in enumerate(ssp): if j == 3: label = '%s' % Dicts.first_match(Dicts.sensor_types, int(field)) # logger.debug('%s' % Dicts.first_match(Dicts.sensor_types, int(field))) elif j == 4: label = '%s' % Dicts.first_match(Dicts.probe_types, int(field)) # logger.debug('%s' % Dicts.first_match(Dicts.probe_types, int(field))) else: label = field if j in [0, 5, 6, 7, 8, ]: item = NumberWidgetItem("%s" % label) elif j in [2, ]: item = LocationWidgetItem("%s" % label) else: item = QtWidgets.QTableWidgetItem("%s" % label) if (j == 3) and (int(field) == Dicts.sensor_types['Future']): item.setForeground(QtGui.QColor(200, 100, 100)) elif (j == 4) and (int(field) == Dicts.sensor_types['Future']): item.setForeground(QtGui.QColor(200, 100, 100)) if not processed: item.setBackground(QtGui.QColor(200, 100, 100, 50)) item.setTextAlignment(QtCore.Qt.AlignVCenter | QtCore.Qt.AlignHCenter) item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.ssp_list.setItem(i, j, item) self.ssp_list.setSortingEnabled(True) self.ssp_list.resizeColumnsToContents()
def export_profiles_metadata(self, project_name, output_folder, ogr_format=GdalAux.ogr_formats['ESRI Shapefile'], filter_fields=None): self.filter_fields = filter_fields if self.filter_fields is None: self.filter_fields = ExportDbFields() GdalAux() output = os.path.join(self.export_folder(output_folder=output_folder), project_name) # create the data source try: ds = GdalAux.create_ogr_data_source(ogr_format=ogr_format, output_path=output) lyr = self._create_ogr_lyr_and_fields(ds) except RuntimeError as e: logger.error("%s" % e) return rows = self.db.list_profiles() if rows is None: raise RuntimeError("Unable to retrieve profiles. Empty database?") if len(rows) == 0: raise RuntimeError("Unable to retrieve profiles. Empty database?") for row in rows: ft = ogr.Feature(lyr.GetLayerDefn()) if self.filter_fields.fields['pk']: ft.SetField('pk', int(row[0])) if self.filter_fields.fields['datetime']: ft.SetField('datetime', row[1].isoformat()) if self.filter_fields.fields['sensor']: ft.SetField('sensor', Dicts.first_match(Dicts.sensor_types, row[3])) if self.filter_fields.fields['probe']: ft.SetField('probe', Dicts.first_match(Dicts.probe_types, row[4])) if self.filter_fields.fields['path']: ft.SetField('path', row[5]) if self.filter_fields.fields['agency']: if row[6]: ft.SetField('agency', row[6]) if self.filter_fields.fields['survey']: if row[7]: ft.SetField('survey', row[7]) if self.filter_fields.fields['vessel']: if row[8]: ft.SetField('vessel', row[8]) if self.filter_fields.fields['sn']: if row[9]: ft.SetField('sn', row[9]) if self.filter_fields.fields['proc_time']: ft.SetField('proc_time', row[10].isoformat()) if self.filter_fields.fields['proc_info']: ft.SetField('proc_info', row[11]) if self.filter_fields.fields['surveyline']: if row[12]: ft.SetField('surveyline', row[12]) if self.filter_fields.fields['comments']: if row[13]: ft.SetField('comments', row[13]) if self.filter_fields.fields['press_uom']: if row[14]: ft.SetField('press_uom', row[14]) if self.filter_fields.fields['depth_uom']: if row[15]: ft.SetField('depth_uom', row[15]) if self.filter_fields.fields['ss_uom']: if row[16]: ft.SetField('ss_uom', row[16]) if self.filter_fields.fields['temp_uom']: if row[17]: ft.SetField('temp_uom', row[17]) if self.filter_fields.fields['cond_uom']: if row[18]: ft.SetField('cond_uom', row[18]) if self.filter_fields.fields['sal_uom']: if row[19]: ft.SetField('sal_uom', row[19]) if self.filter_fields.fields['ss_at_mind']: if row[20]: ft.SetField('ss_at_mind', row[20]) if self.filter_fields.fields['min_depth']: if row[21]: ft.SetField('min_depth', row[21]) if self.filter_fields.fields['max_depth']: if row[22]: ft.SetField('max_depth', row[22]) if self.filter_fields.fields['max_raw_d']: if row[23]: ft.SetField('max_raw_d', row[23]) pt = ogr.Geometry(ogr.wkbPoint) lat = row[2].y lon = row[2].x if lon > 180.0: # Go back to negative longitude lon -= 360.0 pt.SetPoint_2D(0, lon, lat) if self.filter_fields.fields['POINT_X']: ft.SetField('POINT_X', lon) if self.filter_fields.fields['POINT_Y']: ft.SetField('POINT_Y', lat) try: ft.SetGeometry(pt) except Exception as e: RuntimeError("%s > pt: %s, %s" % (e, lon, lat)) if lyr.CreateFeature(ft) != 0: raise RuntimeError("Unable to create feature") ft.Destroy() ds = None return True