def test_get_version(self): """Test for get_version.""" version_tuple = ('2', '2', '0', 'alpha', '0') version = get_version(version_tuple) if 'win32' in sys.platform or 'darwin' in sys.platform: expected_version = '2.2.0.dev-master' message = 'It should be %s but got %s' % ( expected_version, version) self.assertEqual(expected_version, version, message) else: expected_version = '2.2.0.dev-ABCDEFG' message = 'It should be %s but got %s' % ( expected_version[:9], version[:9]) self.assertEqual(expected_version[:9], version[:9], message) message = 'Expected version that has length %d, got %d' % ( len(expected_version), len(version)) self.assertEqual(len(expected_version), len(version), message) # Version tuple doesn't have length == 5 version_tuple = ('2', '2', '0', 'alpha') self.assertRaises(RuntimeError, get_version, version_tuple) # Version tuple item 4th is not alpha, beta, rc, final version_tuple = ('2', '2', '0', 'avocado', '0') self.assertRaises(RuntimeError, get_version, version_tuple) # Final version version_tuple = ('2', '2', '0', 'final', '0') version = get_version(version_tuple) self.assertEqual(version, '2.2.0', 'The version should be 2.2.0')
def test_get_version(self): """Test for get_version.""" version_tuple = ('2', '2', '0', 'alpha', '0') version = get_version(version_tuple) if 'win32' in sys.platform or 'darwin' in sys.platform: expected_version = '2.2.0.dev-master' message = 'It should be %s but got %s' % (expected_version, version) self.assertEqual(expected_version, version, message) else: expected_version = '2.2.0.dev-ABCDEFG' message = 'It should be %s but got %s' % (expected_version[:9], version[:9]) self.assertEqual(expected_version[:9], version[:9], message) message = 'Expected version that has length %d, got %d' % ( len(expected_version), len(version)) self.assertEqual(len(expected_version), len(version), message) # Version tuple doesn't have length == 5 version_tuple = ('2', '2', '0', 'alpha') self.assertRaises(RuntimeError, get_version, version_tuple) # Version tuple item 4th is not alpha, beta, rc, final version_tuple = ('2', '2', '0', 'avocado', '0') self.assertRaises(RuntimeError, get_version, version_tuple) # Final version version_tuple = ('2', '2', '0', 'final', '0') version = get_version(version_tuple) self.assertEqual(version, '2.2.0', 'The version should be 2.2.0')
def __init__(self, parent=None): """Constructor for the dialog. Show the grid converter dialog. :param parent: parent - widget to use as parent. :type parent: QWidget """ QDialog.__init__(self, parent) self.parent = parent self.setupUi(self) self.setWindowTitle( self.tr('InaSAFE %s Shakemap Converter' % get_version())) self.warning_text = set() self.on_input_path_textChanged() self.on_output_path_textChanged() self.update_warning() # Event register # noinspection PyUnresolvedReferences self.use_output_default.toggled.connect( self.get_output_from_input) # noinspection PyUnresolvedReferences self.input_path.textChanged.connect(self.on_input_path_textChanged) # noinspection PyUnresolvedReferences self.output_path.textChanged.connect(self.on_output_path_textChanged) # Set up things for context help help_button = self.button_box.button(QDialogButtonBox.Help) help_button.clicked.connect(ShakemapConverterDialog.show_help) self.show_info()
def load_template(self): """Load the template to composition.""" # Get information for substitutions # date, time and plugin version date_time = self._keyword_io.read_keywords(self.layer, "time_stamp") if date_time is None: date = "" time = "" else: tokens = date_time.split("_") date = tokens[0] time = tokens[1] long_version = get_version() tokens = long_version.split(".") version = "%s.%s.%s" % (tokens[0], tokens[1], tokens[2]) # Get title of the layer title = self.map_title if not title: title = "" # Prepare the substitution map substitution_map = { "impact-title": title, "date": date, "time": time, "safe-version": version, "disclaimer": self.disclaimer, } # Load template self._template_composition.substitution = substitution_map try: self._template_composition.load_template() except TemplateLoadingError: raise
def __init__(self, parent=None): """Constructor for the minimum needs dialog. :param parent: Parent widget of this dialog. :type parent: QWidget """ QtGui.QDialog.__init__(self, parent) self.setupUi(self) self.setWindowTitle( self.tr('InaSAFE %s Minimum Needs Calculator' % get_version())) self.polygon_layers_to_combo() # Set up things for context help self.help_button = self.button_box.button(QtGui.QDialogButtonBox.Help) # Allow toggling the help button self.help_button.setCheckable(True) self.help_button.toggled.connect(self.help_toggled) self.main_stacked_widget.setCurrentIndex(1) # Fix for issue 1699 - cancel button does nothing cancel_button = self.button_box.button(QtGui.QDialogButtonBox.Cancel) cancel_button.clicked.connect(self.reject) # Fix ends ok_button = self.button_box.button(QtGui.QDialogButtonBox.Ok) ok_button.clicked.connect(self.accept)
def __init__(self, parent=None): """Constructor for the minimum needs dialog. :param parent: Parent widget of this dialog. :type parent: QWidget """ QtGui.QDialog.__init__(self, parent) self.setupUi(self) self.setWindowTitle(self.tr( 'InaSAFE %s Minimum Needs Calculator' % get_version())) self.polygon_layers_to_combo() # Set up things for context help self.help_button = self.button_box.button(QtGui.QDialogButtonBox.Help) # Allow toggling the help button self.help_button.setCheckable(True) self.help_button.toggled.connect(self.help_toggled) self.main_stacked_widget.setCurrentIndex(1) # Fix for issue 1699 - cancel button does nothing cancel_button = self.button_box.button(QtGui.QDialogButtonBox.Cancel) cancel_button.clicked.connect(self.reject) # Fix ends ok_button = self.button_box.button(QtGui.QDialogButtonBox.Ok) ok_button.clicked.connect(self.accept)
def download(feature_type, output_base_path, extent, progress_dialog=None): """Download shapefiles from Kartoza server. .. versionadded:: 3.2 :param feature_type: What kind of features should be downloaded. Currently 'buildings', 'building-points' or 'roads' are supported. :type feature_type: str :param output_base_path: The base path of the shape file. :type output_base_path: str :param extent: A list in the form [xmin, ymin, xmax, ymax] where all coordinates provided are in Geographic / EPSG:4326. :type extent: list :param progress_dialog: A progress dialog. :type progress_dialog: QProgressDialog :raises: ImportDialogError, CanceledImportDialogError """ # preparing necessary data min_longitude = extent[0] min_latitude = extent[1] max_longitude = extent[2] max_latitude = extent[3] box = ( '{min_longitude},{min_latitude},{max_longitude},' '{max_latitude}').format( min_longitude=min_longitude, min_latitude=min_latitude, max_longitude=max_longitude, max_latitude=max_latitude ) url = ( '{url_osm_prefix}' '{feature_type}' '{url_osm_suffix}?' 'bbox={box}&' 'qgis_version={qgis}&' 'lang={lang}&' 'inasafe_version={inasafe_version}'.format( url_osm_prefix=URL_OSM_PREFIX, feature_type=feature_type, url_osm_suffix=URL_OSM_SUFFIX, box=box, qgis=qgis_version(), lang=locale(), inasafe_version=get_version())) path = tempfile.mktemp('.shp.zip') # download and extract it fetch_zip(url, path, feature_type, progress_dialog) extract_zip(path, output_base_path) if progress_dialog: progress_dialog.done(QDialog.Accepted)
def __init__(self, parent=None): """Constructor for the dialog. Show the grid converter dialog. :param parent: parent - widget to use as parent. :type parent: QWidget """ QDialog.__init__(self, parent) self.parent = parent self.setupUi(self) self.setWindowTitle( self.tr('InaSAFE %s Shakemap Converter' % get_version())) self.warning_text = set() self.on_input_path_textChanged() self.on_output_path_textChanged() self.update_warning() # Event register # noinspection PyUnresolvedReferences self.use_output_default.toggled.connect( self.get_output_from_input) # noinspection PyUnresolvedReferences self.input_path.textChanged.connect(self.on_input_path_textChanged) # noinspection PyUnresolvedReferences self.output_path.textChanged.connect(self.on_output_path_textChanged) # Set up things for context help self.help_button = self.button_box.button(QtGui.QDialogButtonBox.Help) # Allow toggling the help button self.help_button.setCheckable(True) self.help_button.toggled.connect(self.help_toggled) self.main_stacked_widget.setCurrentIndex(1)
def set_if_provenance(self): """Set IF provenance step for the IF.""" data = { 'start_time': self._start_time , 'finish_time': datetime.now(), 'hazard_layer': self.hazard.keywords['title'], 'exposure_layer': self.exposure.keywords['title'], 'impact_function_id': self.metadata().as_dict()['id'], 'impact_function_version': '1.0', # TODO: Add IF version. 'host_name': self.host_name, 'user': self.user, 'qgis_version': QGis.QGIS_VERSION, 'gdal_version': gdal.__version__, 'qt_version': QT_VERSION_STR, 'pyqt_version': PYQT_VERSION_STR, 'os': platform.version(), 'inasafe_version': get_version(), # Temporary. # TODO: Update it later. 'exposure_pixel_size': '', 'hazard_pixel_size': '', 'impact_pixel_size': '', 'analysis_extent': '', 'parameter': '' } self.provenance.append_if_provenance_step( 'IF Provenance', 'Impact function\'s provenance.', timestamp=None, data=data )
def __init__(self, parent=None): """Constructor for the dialog. Show the grid converter dialog. :param parent: parent - widget to use as parent. :type parent: QWidget """ QDialog.__init__(self, parent) self.parent = parent self.setupUi(self) self.setWindowTitle( self.tr('InaSAFE %s Shakemap Converter' % get_version())) self.warning_text = set() self.on_input_path_textChanged() self.on_output_path_textChanged() self.update_warning() # Event register # noinspection PyUnresolvedReferences self.use_output_default.toggled.connect(self.get_output_from_input) # noinspection PyUnresolvedReferences self.input_path.textChanged.connect(self.on_input_path_textChanged) # noinspection PyUnresolvedReferences self.output_path.textChanged.connect(self.on_output_path_textChanged) # Set up things for context help self.help_button = self.button_box.button(QtGui.QDialogButtonBox.Help) # Allow toggling the help button self.help_button.setCheckable(True) self.help_button.toggled.connect(self.help_toggled) self.main_stacked_widget.setCurrentIndex(1)
def request(self, request_url): """Mock handler for an http request. :param request_url: Url being requested. """ url = str(request_url.url().toString()) reply = MockQNetworkReply() if url == 'http://hot-export.geofabrik.de/newjob': reply.content = read_all('test-importdlg-newjob.html') elif url == 'http://hot-export.geofabrik.de/wizard_area': reply.content = read_all('test-importdlg-wizardarea.html') elif url == 'http://hot-export.geofabrik.de/tagupload': reply.content = read_all('test-importdlg-job.html') reply._url = 'http://hot-export.geofabrik.de/jobs/1990' elif url == 'http://hot-export.geofabrik.de/jobs/1990': reply.content = read_all('test-importdlg-job.html') elif url == ('http://osm.inasafe.org/buildings-shp?' 'bbox=20.389938354492188,-34.10782492987083' ',20.712661743164062,' '-34.008273470938335&qgis_version=%s' '&inasafe_version=%s' '&lang=en' % (qgis_version(), get_version())): reply.content = read_all("test-importdlg-extractzip.zip") return reply
def load_template(self): """Load the template to composition.""" # Get information for substitutions # date, time and plugin version date_time = self._keyword_io.read_keywords(self.layer, 'time_stamp') if date_time is None: date = '' time = '' else: tokens = date_time.split('_') date = tokens[0] time = tokens[1] long_version = get_version() tokens = long_version.split('.') version = '%s.%s.%s' % (tokens[0], tokens[1], tokens[2]) # Get title of the layer title = self.map_title if not title: title = '' # Prepare the substitution map substitution_map = { 'impact-title': title, 'date': date, 'time': time, 'safe-version': version, 'disclaimer': self.disclaimer } # Load template self._template_composition.substitution = substitution_map try: self._template_composition.load_template() except TemplateLoadingError: raise
def set_if_provenance(self): """Set IF provenance step for the IF.""" data = { 'start_time': self._start_time, 'finish_time': datetime.now(), 'hazard_layer': self.hazard.keywords['title'], 'exposure_layer': self.exposure.keywords['title'], 'impact_function_id': self.metadata().as_dict()['id'], 'impact_function_version': '1.0', # TODO: Add IF version. 'host_name': self.host_name, 'user': self.user, 'qgis_version': QGis.QGIS_VERSION, 'gdal_version': gdal.__version__, 'qt_version': QT_VERSION_STR, 'pyqt_version': PYQT_VERSION_STR, 'os': platform.version(), 'inasafe_version': get_version(), # Temporary. # TODO: Update it later. 'exposure_pixel_size': '', 'hazard_pixel_size': '', 'impact_pixel_size': '', 'analysis_extent': '', 'parameter': '' } self.provenance.append_if_provenance_step( 'IF Provenance', 'Impact function\'s provenance.', timestamp=None, data=data)
def __init__(self, parent=None): """Constructor for the dialog. :param parent: Parent widget of this dialog :type parent: QWidget """ QtGui.QDialog.__init__(self, parent) self.setupUi(self) self.setWindowTitle(self.tr('About InaSAFE %s' % get_version())) self.parent = parent # Set Limitations Text limitations_text = '' for index, limitation in enumerate(limitations()): limitations_text += '%s. %s \n' % (index + 1, limitation) self.limitations_text.setFontPointSize(11) self.limitations_text.setText(limitations_text) # Set Disclaimer Text self.disclaimer_text.setFontPointSize(11) self.disclaimer_text.setText(disclaimer()) # Set Attributions text image_credits_text = '' for index, limitation in enumerate(self.attributions()): image_credits_text += '%s. %s \n' % (index + 1, limitation) self.image_credits_text.setFontPointSize(11) self.image_credits_text.setText(image_credits_text) supporters_path = resources_path('img', 'logos', 'supporters.png') pixmap = QtGui.QPixmap(supporters_path) self.supporters_label.setPixmap(pixmap)
def __init__(self, parent=None): """Constructor for the dialog. Show the grid converter dialog. :param parent: parent - widget to use as parent. :type parent: QWidget """ QDialog.__init__(self, parent) self.parent = parent self.setupUi(self) self.setWindowTitle( self.tr('InaSAFE %s Shakemap Converter' % get_version())) self.warning_text = set() self.on_input_path_textChanged() self.on_output_path_textChanged() self.update_warning() # Event register # noinspection PyUnresolvedReferences self.use_output_default.toggled.connect( self.get_output_from_input) # noinspection PyUnresolvedReferences self.input_path.textChanged.connect(self.on_input_path_textChanged) # noinspection PyUnresolvedReferences self.output_path.textChanged.connect(self.on_output_path_textChanged) # Set up things for context help help_button = self.button_box.button(QDialogButtonBox.Help) help_button.clicked.connect(ShakemapImporterDialog.show_help) self.show_info()
def test_provenance_without_aggregation(self): """Test provenance of impact function without aggregation.""" hazard_layer = load_test_vector_layer( 'gisv4', 'hazard', 'classified_vector.geojson') exposure_layer = load_test_vector_layer( 'gisv4', 'exposure', 'building-points.geojson') hazard = definition(hazard_layer.keywords['hazard']) exposure = definition(exposure_layer.keywords['exposure']) hazard_category = definition(hazard_layer.keywords['hazard_category']) expected_provenance = { 'gdal_version': gdal.__version__, 'host_name': gethostname(), 'map_title': get_map_title(hazard, exposure, hazard_category), 'map_legend_title': exposure['layer_legend_title'], 'inasafe_version': get_version(), 'pyqt_version': PYQT_VERSION_STR, 'qgis_version': QGis.QGIS_VERSION, 'qt_version': QT_VERSION_STR, 'user': getpass.getuser(), 'os': readable_os_version(), 'aggregation_layer': None, 'aggregation_layer_id': None, 'exposure_layer': exposure_layer.source(), 'exposure_layer_id': exposure_layer.id(), 'hazard_layer': hazard_layer.source(), 'hazard_layer_id': hazard_layer.id(), 'analysis_question': get_analysis_question(hazard, exposure), 'aggregation_keywords': None, 'exposure_keywords': deepcopy(exposure_layer.keywords), 'hazard_keywords': deepcopy(hazard_layer.keywords), } # Set up impact function impact_function = ImpactFunction() impact_function.exposure = exposure_layer impact_function.hazard = hazard_layer status, message = impact_function.prepare() self.assertEqual(PREPARE_SUCCESS, status, message) status, message = impact_function.run() self.assertEqual(ANALYSIS_SUCCESS, status, message) self.maxDiff = None expected_provenance.update({ 'action_checklist': impact_function.action_checklist(), 'analysis_extent': impact_function.analysis_extent.exportToWkt(), 'impact_function_name': impact_function.name, 'impact_function_title': impact_function.title, 'notes': impact_function.notes(), 'requested_extent': impact_function.requested_extent, 'data_store_uri': impact_function.datastore.uri_path, 'start_datetime': impact_function.start_datetime, 'end_datetime': impact_function.end_datetime, 'duration': impact_function.duration }) self.assertDictEqual(expected_provenance, impact_function.provenance)
def event_dict(self): tz = pytz.timezone('Asia/Jakarta') timestamp = self.time.astimezone(tz=tz) time_format = '%-d-%b-%Y %H:%M:%S' timestamp_string = timestamp.strftime(time_format) point = QgsPoint(self.longitude, self.latitude) coordinates = point.toDegreesMinutesSeconds(2) tokens = coordinates.split(',') longitude_string = tokens[0] latitude_string = tokens[1] elapsed_time = datetime.datetime.utcnow().replace( tzinfo=pytz.utc) - self.time elapsed_hour = elapsed_time.seconds / 3600 elapsed_minute = (elapsed_time.seconds / 60) % 60 event = { 'report-title': self.tr('Volcanic Ash Impact'), 'report-timestamp': self.tr('Volcano: %s, Alert Level: %s %s') % (self.volcano_name, self.alert_level, timestamp_string), 'report-province': self.tr('Province: %s') % (self.region, ), 'report-location': self.tr('Longitude %s Latitude %s;' ' Eruption Column Height (a.s.l) - %d m') % (longitude_string, latitude_string, self.erupction_height), 'report-elapsed': self.tr('Elapsed time since event %s hour(s) and %s minute(s)') % (elapsed_hour, elapsed_minute), 'header-impact-table': self.tr('Potential impact at each fallout level'), 'header-nearby-table': self.tr('Nearby places'), 'header-landcover-table': self.tr('Land Cover Impact'), 'content-disclaimer': self.tr( 'The impact estimation is automatically generated and only ' 'takes into account the population, cities and land cover ' 'affected by different levels of volcanic ash fallout at ' 'surface level. The estimate is based on volcanic ash ' 'fallout data from Badan Geologi, population count data ' 'derived by DMInnovation from worldpop.org.uk, place ' 'information from geonames.org, land cover classification ' 'data provided by Indonesian Geospatial Portal at ' 'http://portal.ina-sdi.or.id and software developed by BNPB. ' 'Limitation in the estimates of surface fallout, population ' 'and place names datasets may result in significant ' 'misrepresentation of the on-the-surface situation in the ' 'figures shown here. Consequently decisions should not be ' 'made soley on the information presented here and should ' 'always be verified by ground truthing and other reliable ' 'information sources.'), 'content-notes': self.tr('This report was created using InaSAFE version %s. Visit ' 'http://inasafe.org for more information. ') % get_version() } return event
def download(feature_type, output_base_path, extent, progress_dialog=None): """Download shapefiles from Kartoza server. .. versionadded:: 3.2 :param feature_type: What kind of features should be downloaded. Currently 'buildings', 'building-points' or 'roads' are supported. :type feature_type: str :param output_base_path: The base path of the shape file. :type output_base_path: str :param extent: A list in the form [xmin, ymin, xmax, ymax] where all coordinates provided are in Geographic / EPSG:4326. :type extent: list :param progress_dialog: A progress dialog. :type progress_dialog: QProgressDialog :raises: ImportDialogError, CanceledImportDialogError """ # preparing necessary data min_longitude = extent[0] min_latitude = extent[1] max_longitude = extent[2] max_latitude = extent[3] box = ( '{min_longitude},{min_latitude},{max_longitude},' '{max_latitude}').format( min_longitude=min_longitude, min_latitude=min_latitude, max_longitude=max_longitude, max_latitude=max_latitude ) url = URL_OSM_PREFIX + feature_type + URL_OSM_SUFFIX url = '{url}?bbox={box}&qgis_version={qgis}'.format( url=url, box=box, qgis=qgis_version()) url += '&inasafe_version=%s' % get_version() if 'LANG' in os.environ: # Get the language only : eg 'en_US' -> 'en' env_lang = os.environ['LANG'].split('_')[0] url += '&lang=%s' % env_lang path = tempfile.mktemp('.shp.zip') # download and extract it fetch_zip(url, path, feature_type, progress_dialog) extract_zip(path, output_base_path) if progress_dialog: progress_dialog.done(QDialog.Accepted)
def __init__(self, parent=None): """Constructor for the minimum needs dialog. :param parent: Parent widget of this dialog. :type parent: QWidget """ QtWidgets.QDialog.__init__(self, parent) self.setupUi(self) self.setWindowTitle(self.tr( 'InaSAFE %s Minimum Needs Calculator' % get_version())) icon = resources_path('img', 'icons', 'show-minimum-needs.svg') self.setWindowIcon(QtGui.QIcon(icon)) self.result_layer = None self.button_box.button(QtWidgets.QDialogButtonBox.Ok).setEnabled(False) # get qgis map layer combobox object self.layer.setFilters(QgsMapLayerProxyModel.VectorLayer) # get field that represent displaced count(population) self.displaced.setFilters(QgsFieldProxyModel.Numeric) # get field that represent aggregation name self.aggregation_name.setFilters(QgsFieldProxyModel.String) # set field to the current selected layer self.displaced.setLayer(self.layer.currentLayer()) self.aggregation_name.setLayer(self.layer.currentLayer()) self.aggregation_id.setLayer(self.layer.currentLayer()) # link map layer and field combobox self.layer.layerChanged.connect(self.displaced.setLayer) self.layer.layerChanged.connect(self.aggregation_name.setLayer) self.layer.layerChanged.connect(self.aggregation_id.setLayer) # enable/disable ok button self.update_button_status() self.displaced.fieldChanged.connect(self.update_button_status) # Set up things for context help self.help_button = self.button_box.button( QtWidgets.QDialogButtonBox.Help) # Allow toggling the help button self.help_button.setCheckable(True) self.help_button.toggled.connect(self.help_toggled) self.main_stacked_widget.setCurrentIndex(1) # Fix for issue 1699 - cancel button does nothing cancel_button = self.button_box.button( QtWidgets.QDialogButtonBox.Cancel) cancel_button.clicked.connect(self.reject) # Fix ends ok_button = self.button_box.button(QtWidgets.QDialogButtonBox.Ok) ok_button.clicked.connect(self.accept)
def load_template(self): """Load the template to composition.""" # Get information for substitutions # date, time and plugin version date_time = self._keyword_io.read_keywords(self.layer, 'time_stamp') if date_time is None: date = '' time = '' else: tokens = date_time.split('_') date = tokens[0] time = tokens[1] long_version = get_version() tokens = long_version.split('.') version = '%s.%s.%s' % (tokens[0], tokens[1], tokens[2]) # Get title of the layer title = self.map_title if not title: title = '' # Prepare the substitution map substitution_map = { 'impact-title': title, 'date': date, 'time': time, 'safe-version': version, # deprecated 'disclaimer': self.disclaimer, # These added in 3.2 'version-title': tr('Version'), 'inasafe-version': version, 'disclaimer-title': tr('Disclaimer'), 'date-title': tr('Date'), 'time-title': tr('Time'), 'caution-title': tr('Note'), 'caution-text': tr( 'This assessment is a guide - we strongly recommend that you ' 'ground truth the results shown here before deploying ' 'resources and / or personnel.'), 'version-text': tr( 'Assessment carried out using InaSAFE release %s.' % version), 'legend-title': tr('Legend'), 'information-title': tr('Analysis information'), 'supporters-title': tr('Report produced by') } # Load template self._template_composition.substitution = substitution_map try: self._template_composition.load_template() except TemplateLoadingError: raise
def heading(): """Helper method that returns just the header. This method was added so that the text could be reused in the other contexts. .. versionadded:: 4.0.0 :returns: A heading object. :rtype: safe.messaging.heading.Heading """ message = m.Heading( '{} {}'.format(tr('InaSAFE help'), get_version()), **TITLE_STYLE) return message
def main(): """Main function here.""" try: shell_arguments = docopt(USAGE) except DocoptExit as exc: print exc.message return try: args = CommandLineArguments(shell_arguments) LOGGER.debug(shell_arguments) # Version if args.version is True: print 'QGIS VERSION: %s' % str(qgis_version()).replace('0', '.') print 'InaSAFE VERSION: %s' % get_version() # User is only interested in doing a download elif args.download and not args.hazard_path: print "Downloading..." download_exposure(args) # Interested in running a scenario elif args.hazard_path and args.exposure_path and args.output_dir: if not args.hazard_layer: return if not args.exposure_layer: return # if using aggregation make sure it's valid if args.aggregation_path and not args.exposure_layer: return status, msg, impact_function = run_impact_function(args) if status != ANALYSIS_SUCCESS: print 'Failed running impact function...' print msg else: print 'Running impact function is succesfull...' print 'Building reports...' status, msg = build_report(args, impact_function) if status != ImpactReport.REPORT_GENERATION_SUCCESS: print 'Failed building reports...' print msg else: print "Argument combination not recognised" except Exception as excp: print excp.message print excp.__doc__
def event_dict(self): tz = pytz.timezone("Asia/Jakarta") timestamp = self.time.astimezone(tz=tz) time_format = "%-d-%b-%Y %H:%M:%S" timestamp_string = timestamp.strftime(time_format) point = QgsPoint(self.longitude, self.latitude) coordinates = point.toDegreesMinutesSeconds(2) tokens = coordinates.split(",") longitude_string = tokens[0] latitude_string = tokens[1] elapsed_time = datetime.datetime.utcnow().replace(tzinfo=pytz.utc) - self.time elapsed_hour = elapsed_time.seconds / 3600 elapsed_minute = (elapsed_time.seconds / 60) % 60 event = { "report-title": self.tr("Volcanic Ash Impact"), "report-timestamp": self.tr("Volcano: %s, Alert Level: %s %s") % (self.volcano_name, self.alert_level, timestamp_string), "report-province": self.tr("Province: %s") % (self.region,), "report-location": self.tr("Longitude %s Latitude %s;" " Eruption Column Height (a.s.l) - %d m") % (longitude_string, latitude_string, self.erupction_height), "report-elapsed": self.tr("Elapsed time since event %s hour(s) and %s minute(s)") % (elapsed_hour, elapsed_minute), "header-impact-table": self.tr("Potential impact at each fallout level"), "header-nearby-table": self.tr("Nearby places"), "header-landcover-table": self.tr("Land Cover Impact"), "content-disclaimer": self.tr( "The impact estimation is automatically generated and only " "takes into account the population, cities and land cover " "affected by different levels of volcanic ash fallout at " "surface level. The estimate is based on volcanic ash " "fallout data from Badan Geologi, population count data " "derived by DMInnovation from worldpop.org.uk, place " "information from geonames.org, land cover classification " "data provided by Indonesian Geospatial Portal at " "http://portal.ina-sdi.or.id and software developed by BNPB. " "Limitation in the estimates of surface fallout, population " "and place names datasets may result in significant " "misrepresentation of the on-the-surface situation in the " "figures shown here. Consequently decisions should not be " "made soley on the information presented here and should " "always be verified by ground truthing and other reliable " "information sources." ), "content-notes": self.tr( "This report was created using InaSAFE version %s. Visit " "http://inasafe.org for more information. " ) % get_version(), } return event
def __init__(self, parent=None): """Constructor for the minimum needs dialog. :param parent: Parent widget of this dialog. :type parent: QWidget """ QtGui.QDialog.__init__(self, parent) self.setupUi(self) self.setWindowTitle( self.tr('InaSAFE %s Minimum Needs Tool' % get_version())) self.polygon_layers_to_combo() self.show_info() help_button = self.button_box.button(QtGui.QDialogButtonBox.Help) help_button.clicked.connect(self.show_help)
def __init__(self, iface, dock=None, parent=None): """Constructor for the dialog. :param iface: A Quantum GIS QGisAppInterface instance. :type iface: QGisAppInterface :param parent: Parent widget of this dialog :type parent: QWidget :param dock: Optional dock widget instance that we can notify of changes to the keywords. :type dock: Dock """ QtGui.QDialog.__init__(self, parent) self.setupUi(self) self.setWindowTitle(self.tr('InaSAFE %s Options' % get_version())) # Save reference to the QGIS interface and parent self.iface = iface self.parent = parent self.dock = dock self.keyword_io = KeywordIO() self.defaults = get_defaults() # Set up things for context help self.help_button = self.button_box.button(QtGui.QDialogButtonBox.Help) # Allow toggling the help button self.help_button.setCheckable(True) self.help_button.toggled.connect(self.help_toggled) self.main_stacked_widget.setCurrentIndex(1) self.grpNotImplemented.hide() self.adjustSize() self.restore_state() # hack prevent showing use thread visible and set it false see #557 self.cbxUseThread.setChecked(True) self.cbxUseThread.setVisible(False) # Set up listener for various UI self.custom_org_logo_checkbox.toggled.connect( self.set_organisation_logo) self.custom_north_arrow_checkbox.toggled.connect(self.set_north_arrow) self.custom_UseUserDirectory_checkbox.toggled.connect( self.set_user_dir) self.custom_templates_dir_checkbox.toggled.connect( self.set_templates_dir) self.custom_org_disclaimer_checkbox.toggled.connect( self.set_org_disclaimer)
def show_welcome_dialog(self): """Setup for showing welcome message dialog. This method will setup several things: - Only show welcome, organisation profile, and population parameter tab. Currently, they are the first 3 tabs. - Set the title - Move the check box for always showing welcome message. """ self.welcome_layout.addWidget(self.welcome_message_check_box) while self.tabWidget.count() > 3: self.tabWidget.removeTab(self.tabWidget.count() - 1) self.setWindowTitle(self.tr('Welcome to InaSAFE %s' % get_version())) # Hide the export import button self.export_button.hide() self.import_button.hide()
def __init__(self, parent=None): """Constructor for the minimum needs dialog. :param parent: Parent widget of this dialog. :type parent: QWidget """ QtGui.QDialog.__init__(self, parent) self.setupUi(self) self.setWindowTitle(self.tr( 'InaSAFE %s Minimum Needs Tool' % get_version())) self.polygon_layers_to_combo() self.show_info() help_button = self.button_box.button(QtGui.QDialogButtonBox.Help) help_button.clicked.connect(self.show_help) # Fix for issue 1699 - cancel button does nothing cancel_button = self.button_box.button(QtGui.QDialogButtonBox.Cancel) cancel_button.clicked.connect(self.reject)
def __init__(self, parent=None): """Constructor for the dialog. :param parent: Parent widget of this dialog :type parent: QWidget """ QtGui.QDialog.__init__(self, parent) self.setupUi(self) self.setWindowTitle(self.tr('InaSAFE %s Help' % get_version())) self.parent = parent header = html_header() footer = html_footer() string = header message = dock_help() string += message.to_html() string += footer self.help_web_view.setHtml(string)
def test_multi_exposure(self): """Test we can run a multi exposure analysis.""" hazard_layer = load_test_vector_layer('gisv4', 'hazard', 'classified_vector.geojson') building_layer = load_test_vector_layer('gisv4', 'exposure', 'building-points.geojson') population_layer = load_test_vector_layer('gisv4', 'exposure', 'population.geojson') roads_layer = load_test_vector_layer('gisv4', 'exposure', 'roads.geojson') aggregation_layer = load_test_vector_layer('gisv4', 'aggregation', 'small_grid.geojson') impact_function = MultiExposureImpactFunction() impact_function.hazard = hazard_layer impact_function.exposures = [ building_layer, population_layer, roads_layer ] impact_function.aggregation = aggregation_layer code, message = impact_function.prepare() self.assertEqual(code, PREPARE_SUCCESS, message) code, message, exposure = impact_function.run() self.assertEqual(code, ANALYSIS_SUCCESS, message) # Test provenance hazard = definition(hazard_layer.keywords['hazard']) # exposure = definition(exposure_layer.keywords['exposure']) hazard_category = definition(hazard_layer.keywords['hazard_category']) expected_provenance = { provenance_gdal_version['provenance_key']: gdal.__version__, provenance_host_name['provenance_key']: gethostname(), provenance_user['provenance_key']: getpass.getuser(), provenance_os['provenance_key']: readable_os_version(), provenance_pyqt_version['provenance_key']: PYQT_VERSION_STR, provenance_qgis_version['provenance_key']: qgis_version(), provenance_qt_version['provenance_key']: QT_VERSION_STR, provenance_inasafe_version['provenance_key']: get_version(), provenance_aggregation_layer['provenance_key']: aggregation_layer.source(), provenance_aggregation_layer_id['provenance_key']: aggregation_layer.id(), # provenance_exposure_layer['provenance_key']: # exposure_layer.source(), # provenance_exposure_layer_id['provenance_key']: # exposure_layer.id(), provenance_hazard_layer['provenance_key']: hazard_layer.source(), provenance_hazard_layer_id['provenance_key']: hazard_layer.id(), provenance_aggregation_keywords['provenance_key']: deepcopy(aggregation_layer.keywords), # provenance_exposure_keywords['provenance_key']: # deepcopy(exposure_layer.keywords), provenance_hazard_keywords['provenance_key']: deepcopy(hazard_layer.keywords), } self.maxDiff = None expected_provenance.update({ provenance_analysis_extent['provenance_key']: impact_function.analysis_extent.asWkt(), provenance_impact_function_name['provenance_key']: impact_function.name, # provenance_requested_extent['provenance_key']: impact_function. # requested_extent, provenance_data_store_uri['provenance_key']: impact_function.datastore.uri_path, provenance_start_datetime['provenance_key']: impact_function.start_datetime, provenance_end_datetime['provenance_key']: impact_function.end_datetime, provenance_duration['provenance_key']: impact_function.duration }) self.assertDictContainsSubset(expected_provenance, impact_function.provenance) output_layer_provenance_keys = [ provenance_layer_aggregation_summary['provenance_key'], provenance_layer_analysis_impacted['provenance_key'], ] for key in output_layer_provenance_keys: self.assertIn(key, list(impact_function.provenance.keys())) # Test serialization/deserialization output_metadata = impact_function.aggregation_summary.keywords new_impact_function = MultiExposureImpactFunction. \ load_from_output_metadata(output_metadata) self.assertEqualImpactFunction(impact_function, new_impact_function) # Check the analysis layer id equal with the actual layer old_analysis_layer_id = impact_function.provenance[ provenance_layer_analysis_impacted['provenance_key']] new_analysis_layer_id = new_impact_function.provenance[ provenance_layer_analysis_impacted['provenance_key']] self.assertEqual(old_analysis_layer_id, new_analysis_layer_id)
def test_provenance_without_aggregation(self): """Test provenance of impact function without aggregation.""" hazard_layer = load_test_vector_layer('gisv4', 'hazard', 'classified_vector.geojson') exposure_layer = load_test_vector_layer('gisv4', 'exposure', 'building-points.geojson') hazard = definition(hazard_layer.keywords['hazard']) exposure = definition(exposure_layer.keywords['exposure']) hazard_category = definition(hazard_layer.keywords['hazard_category']) expected_provenance = { provenance_gdal_version['provenance_key']: gdal.__version__, provenance_host_name['provenance_key']: gethostname(), provenance_map_title['provenance_key']: get_map_title(hazard, exposure, hazard_category), provenance_map_legend_title['provenance_key']: exposure['layer_legend_title'], provenance_user['provenance_key']: getpass.getuser(), provenance_os['provenance_key']: readable_os_version(), provenance_pyqt_version['provenance_key']: PYQT_VERSION_STR, provenance_qgis_version['provenance_key']: QGis.QGIS_VERSION, provenance_qt_version['provenance_key']: QT_VERSION_STR, provenance_inasafe_version['provenance_key']: get_version(), provenance_aggregation_layer['provenance_key']: None, provenance_aggregation_layer_id['provenance_key']: None, provenance_exposure_layer['provenance_key']: exposure_layer.source(), provenance_exposure_layer_id['provenance_key']: exposure_layer.id(), provenance_hazard_layer['provenance_key']: hazard_layer.source(), provenance_hazard_layer_id['provenance_key']: hazard_layer.id(), provenance_analysis_question['provenance_key']: get_analysis_question(hazard, exposure), provenance_aggregation_keywords['provenance_key']: None, provenance_exposure_keywords['provenance_key']: deepcopy(exposure_layer.keywords), provenance_hazard_keywords['provenance_key']: deepcopy(hazard_layer.keywords), } # Set up impact function impact_function = ImpactFunction() impact_function.exposure = exposure_layer impact_function.hazard = hazard_layer status, message = impact_function.prepare() self.assertEqual(PREPARE_SUCCESS, status, message) status, message = impact_function.run() self.assertEqual(ANALYSIS_SUCCESS, status, message) self.maxDiff = None expected_provenance.update({ provenance_action_checklist['provenance_key']: impact_function.action_checklist(), provenance_analysis_extent['provenance_key']: impact_function.analysis_extent.exportToWkt(), provenance_impact_function_name['provenance_key']: impact_function.name, provenance_impact_function_title['provenance_key']: impact_function.title, provenance_notes['provenance_key']: impact_function.notes(), provenance_requested_extent['provenance_key']: impact_function.requested_extent, provenance_data_store_uri['provenance_key']: impact_function.datastore.uri_path, provenance_start_datetime['provenance_key']: impact_function.start_datetime, provenance_end_datetime['provenance_key']: impact_function.end_datetime, provenance_duration['provenance_key']: impact_function.duration }) self.assertDictContainsSubset(expected_provenance, impact_function.provenance) output_layer_provenance_keys = [ provenance_layer_exposure_summary['provenance_key'], provenance_layer_aggregate_hazard_impacted['provenance_key'], provenance_layer_aggregation_summary['provenance_key'], provenance_layer_analysis_impacted['provenance_key'], provenance_layer_exposure_summary_table['provenance_key'] ] for key in output_layer_provenance_keys: self.assertIn(key, impact_function.provenance.keys())
def layer_description_html(layer, keywords=None): """Form a html description of a given layer based on the layer parameters and keywords if provided :param layer: The layer to get the description :type layer: QgsMapLayer :param keywords: The layer keywords :type keywords: None, dict :returns: The html description in tabular format, ready to use in a label or tool tip. :rtype: str """ if keywords and 'keyword_version' in keywords: keyword_version = str(keywords['keyword_version']) else: keyword_version = None if (keywords and keyword_version and is_keyword_version_supported(keyword_version)): # The layer has valid keywords purpose = keywords.get('layer_purpose') if purpose == layer_purpose_hazard['key']: subcategory = '<tr><td><b>%s</b>: </td><td>%s</td></tr>' % ( tr('Hazard'), keywords.get(purpose)) unit = keywords.get('continuous_hazard_unit') elif purpose == layer_purpose_exposure['key']: subcategory = '<tr><td><b>%s</b>: </td><td>%s</td></tr>' % ( tr('Exposure'), keywords.get(purpose)) unit = keywords.get('exposure_unit') else: subcategory = '' unit = None if keywords.get('layer_mode') == layer_mode_classified['key']: unit = tr('classified data') if unit: unit = '<tr><td><b>%s</b>: </td><td>%s</td></tr>' % (tr('Unit'), unit) description = """ <table border="0" width="100%%"> <tr><td><b>%s</b>: </td><td>%s</td></tr> <tr><td><b>%s</b>: </td><td>%s</td></tr> %s %s <tr><td><b>%s</b>: </td><td>%s</td></tr> </table> """ % (tr('Title'), keywords.get('title'), tr('Purpose'), keywords.get('layer_purpose'), subcategory, unit, tr('Source'), keywords.get('source')) elif keywords: # The layer has keywords, but the version is wrong layer_version = keyword_version or tr('No Version') description = tr( 'Your layer\'s keyword\'s version ({layer_version}) does not ' 'match with your InaSAFE version ({inasafe_version}). If you wish ' 'to use it as an exposure, hazard, or aggregation layer in an ' 'analysis, please update the keywords. Click Next if you want to ' 'assign keywords now.').format(layer_version=layer_version, inasafe_version=get_version()) else: # The layer is keywordless if is_point_layer(layer): geom_type = layer_geometry_point['key'] elif is_polygon_layer(layer): geom_type = layer_geometry_polygon['key'] else: geom_type = layer_geometry_line['key'] # hide password in the layer source source = layer.publicSource() description = """ %s<br/><br/> <b>%s</b>: %s<br/> <b>%s</b>: %s<br/><br/> %s """ % (tr('This layer has no valid keywords assigned'), tr('SOURCE'), source, tr('TYPE'), is_raster_layer(layer) and 'raster' or 'vector (%s)' % geom_type, tr('In the next step you will be able' + ' to assign keywords to this layer.')) return description
def __init__(self, parent=None, iface=None, dock_widget=None): """Constructor for the dialog. Show the grid converter dialog. :param parent: parent - widget to use as parent. :type parent: QWidget :param iface: QGIS QgisAppInterface instance. :type iface: QgisAppInterface :param dock_widget: Dock widget instance. :type dock_widget: Dock """ QDialog.__init__(self, parent) self.parent = parent self.iface = iface self.dock_widget = dock_widget self.setupUi(self) self.setWindowTitle(tr('InaSAFE %s Shakemap Converter' % get_version())) icon = resources_path('img', 'icons', 'show-converter-tool.svg') self.setWindowIcon(QtGui.QIcon(icon)) self.warning_text = set() self.on_input_path_textChanged() self.on_output_path_textChanged() self.update_warning() self.output_layer = None # Event register # noinspection PyUnresolvedReferences self.use_output_default.toggled.connect(self.get_output_from_input) # noinspection PyUnresolvedReferences self.input_path.textChanged.connect(self.on_input_path_textChanged) # noinspection PyUnresolvedReferences self.output_path.textChanged.connect(self.on_output_path_textChanged) self.load_result.clicked.connect(self.load_result_toggled) # Set up things for context help self.help_button = self.button_box.button(QDialogButtonBox.Help) # Allow toggling the help button self.help_button.setCheckable(True) self.help_button.toggled.connect(self.help_toggled) self.main_stacked_widget.setCurrentIndex(1) self.check_box_custom_shakemap_id.toggled.connect( self.line_edit_shakemap_id.setEnabled) # Set value for EQ source type combo box self.combo_box_source_type.addItem(tr('N/A'), '') for source_type in extra_keyword_earthquake_source['options']: self.combo_box_source_type.addItem(source_type['name'], source_type['key']) self.combo_box_source_type.setCurrentIndex(0) self.update_warning() if not setting('developer_mode', expected_type=bool): self.smoothing_group_box.hide() self.use_ascii_mode.setToolTip( tr('This algorithm will convert the grid xml to a ascii raster file. ' 'If the cell width and height is different, it will use the width ' '(length cell in x axis).')) if not HAS_SCIPY: if self.scipy_smoothing.isChecked: self.none_smoothing.setChecked(True) self.scipy_smoothing.setToolTip( tr('You can not use select this option since you do not have ' 'scipy installed in you system.')) self.scipy_smoothing.setEnabled(False) else: self.scipy_smoothing.setEnabled(True) self.scipy_smoothing.setToolTip('')
def __init__(self, parent, iface, dock=None, layer=None): """Constructor for the dialog. .. note:: In QtDesigner the advanced editor's predefined keywords list should be shown in english always, so when adding entries to cboKeyword, be sure to choose :safe_qgis:`Properties<<` and untick the :safe_qgis:`translatable` property. :param parent: Parent widget of this dialog. :type parent: QWidget :param iface: Quantum GIS QGisAppInterface instance. :type iface: QGisAppInterface :param dock: Dock widget instance that we can notify of changes to the keywords. Optional. :type dock: Dock """ QtGui.QDialog.__init__(self, parent) self.setupUi(self) self.setWindowTitle( self.tr('InaSAFE %s Keywords Editor' % get_version())) # Save reference to the QGIS interface and parent self.iface = iface self.parent = parent self.dock = dock self.defaults = None # string constants self.global_default_string = definitions.global_default_attribute[ 'name'] self.do_not_use_string = definitions.do_not_use_attribute['name'] self.global_default_data = definitions.global_default_attribute['id'] self.do_not_use_data = definitions.do_not_use_attribute['id'] if layer is None: self.layer = self.iface.activeLayer() else: self.layer = layer self.keyword_io = KeywordIO() # note the keys should remain untranslated as we need to write # english to the keywords file. The keys will be written as user data # in the combo entries. # .. seealso:: http://www.voidspace.org.uk/python/odict.html self.standard_exposure_list = OrderedDict([ ('population', self.tr('population')), ('structure', self.tr('structure')), ('road', self.tr('road')), ('Not Set', self.tr('Not Set')) ]) self.standard_hazard_list = OrderedDict([ ('earthquake [MMI]', self.tr('earthquake [MMI]')), ('tsunami [m]', self.tr('tsunami [m]')), ('tsunami [wet/dry]', self.tr('tsunami [wet/dry]')), ('tsunami [feet]', self.tr('tsunami [feet]')), ('flood [m]', self.tr('flood [m]')), ('flood [wet/dry]', self.tr('flood [wet/dry]')), ('flood [feet]', self.tr('flood [feet]')), ('tephra [kg2/m2]', self.tr('tephra [kg2/m2]')), ('volcano', self.tr('volcano')), ('generic [categorised]', self.tr('generic [categorised]')), ('Not Set', self.tr('Not Set')) ]) # noinspection PyUnresolvedReferences self.lstKeywords.itemClicked.connect(self.edit_key_value_pair) # Set up help dialog showing logic. help_button = self.buttonBox.button(QtGui.QDialogButtonBox.Help) help_button.clicked.connect(self.show_help) if self.layer is not None and is_polygon_layer(self.layer): # set some initial ui state: self.defaults = get_defaults() self.radPredefined.setChecked(True) self.dsbFemaleRatioDefault.blockSignals(True) self.dsbFemaleRatioDefault.setValue(self.defaults['FEMALE_RATIO']) self.dsbFemaleRatioDefault.blockSignals(False) self.dsbYouthRatioDefault.blockSignals(True) self.dsbYouthRatioDefault.setValue(self.defaults['YOUTH_RATIO']) self.dsbYouthRatioDefault.blockSignals(False) self.dsbAdultRatioDefault.blockSignals(True) self.dsbAdultRatioDefault.setValue(self.defaults['ADULT_RATIO']) self.dsbAdultRatioDefault.blockSignals(False) self.dsbElderlyRatioDefault.blockSignals(True) self.dsbElderlyRatioDefault.setValue( self.defaults['ELDERLY_RATIO']) self.dsbElderlyRatioDefault.blockSignals(False) else: self.radPostprocessing.hide() self.tab_widget.removeTab(1) if self.layer: self.load_state_from_keywords() # add a reload from keywords button reload_button = self.buttonBox.addButton( self.tr('Reload'), QtGui.QDialogButtonBox.ActionRole) reload_button.clicked.connect(self.load_state_from_keywords) self.resize_dialog() self.tab_widget.setCurrentIndex(0) # TODO No we should not have test related stuff in prod code. TS self.test = False
def __init__(self, iface, parent=None, qsetting=''): """Constructor for the dialog. :param iface: A Quantum GIS QGisAppInterface instance. :type iface: QGisAppInterface :param parent: Parent widget of this dialog :type parent: QWidget :param qsetting: String to specify the QSettings. By default, use empty string. :type qsetting: str """ QDialog.__init__(self, parent) self.setupUi(self) self.setWindowTitle(self.tr('InaSAFE %s Options' % get_version())) # Save reference to the QGIS interface and parent self.iface = iface self.parent = parent if qsetting: self.settings = QSettings(qsetting) else: self.settings = QSettings() # InaSAFE default values self.default_value_parameters = [] self.default_value_parameter_containers = [] # Flag for restore default values self.is_restore_default = False # List of setting key and control self.boolean_settings = { 'visibleLayersOnlyFlag': self.cbxVisibleLayersOnly, 'set_layer_from_title_flag': self.cbxSetLayerNameFromTitle, 'setZoomToImpactFlag': self.cbxZoomToImpact, 'set_show_only_impact_on_report': self.cbx_show_only_impact, 'setHideExposureFlag': self.cbxHideExposure, 'useSelectedFeaturesOnly': self.cbxUseSelectedFeaturesOnly, 'useSentry': self.cbxUseSentry, 'template_warning_verbose': self.template_warning_checkbox, 'showOrganisationLogoInDockFlag': self.organisation_on_dock_checkbox, 'developer_mode': self.cbxDevMode, 'generate_report': self.checkbox_generate_reports, 'memory_profile': self.check_box_memory } self.text_settings = { 'keywordCachePath': self.leKeywordCachePath, 'ISO19115_ORGANIZATION': self.iso19115_organization_le, 'ISO19115_URL': self.iso19115_url_le, 'ISO19115_EMAIL': self.iso19115_email_le, 'ISO19115_LICENSE': self.iso19115_license_le, } # Set up things for context help self.help_button = self.button_box.button(QDialogButtonBox.Help) # Allow toggling the help button self.help_button.setCheckable(True) self.help_button.toggled.connect(self.help_toggled) self.main_stacked_widget.setCurrentIndex(1) # Always set first tab to be open, 0-th index self.tabWidget.setCurrentIndex(0) # Hide not implemented group self.grpNotImplemented.hide() self.adjustSize() # Demographic tab self.scroll_area = QScrollArea() self.scroll_area.setWidgetResizable(True) self.widget_container = QWidget() self.scroll_area.setWidget(self.widget_container) self.container_layout = QVBoxLayout() self.widget_container.setLayout(self.container_layout) self.default_values_layout.addWidget(self.scroll_area) self.restore_state() # Hide checkbox if not developers if not self.cbxDevMode.isChecked(): self.checkbox_generate_reports.hide() # Set up listener for various UI self.custom_org_logo_checkbox.toggled.connect( self.set_organisation_logo) self.custom_north_arrow_checkbox.toggled.connect(self.set_north_arrow) self.custom_UseUserDirectory_checkbox.toggled.connect( self.set_user_dir) self.custom_templates_dir_checkbox.toggled.connect( self.set_templates_dir) self.custom_org_disclaimer_checkbox.toggled.connect( self.set_org_disclaimer) # Set up listener for restore defaults button self.restore_defaults = self.button_box_restore_defaults.button( QDialogButtonBox.RestoreDefaults) self.restore_defaults.setCheckable(True) self.restore_defaults.clicked.connect( self.restore_defaults_ratio) # TODO: Hide this until behaviour is defined # hide template warning toggle self.template_warning_checkbox.hide() # hide custom template dir toggle self.custom_templates_dir_checkbox.hide() self.splitter_custom_report.hide()
def qgis_composer_extractor(impact_report, component_metadata): """Extract composer context. This method extract necessary context for a given impact report and component metadata and save the context so it can be used in composer rendering phase :param impact_report: the impact report that acts as a proxy to fetch all the data that extractor needed :type impact_report: safe.report.impact_report.ImpactReport :param component_metadata: the component metadata. Used to obtain information about the component we want to render :type component_metadata: safe.report.report_metadata. ReportComponentsMetadata :return: context for rendering phase :rtype: dict .. versionadded:: 4.0 """ # QGIS Composer needed certain context to generate the output # - Map Settings # - Substitution maps # - Element settings, such as icon for picture file or image source # Generate map settings qgis_context = impact_report.qgis_composition_context inasafe_context = impact_report.inasafe_context provenance = impact_report.impact_function.provenance extra_args = component_metadata.extra_args context = QGISComposerContext() # Set default image elements to replace image_elements = [{ 'id': 'safe-logo', 'path': inasafe_context.inasafe_logo }, { 'id': 'black-inasafe-logo', 'path': inasafe_context.black_inasafe_logo }, { 'id': 'white-inasafe-logo', 'path': inasafe_context.white_inasafe_logo }, { 'id': 'north-arrow', 'path': inasafe_context.north_arrow }, { 'id': 'organisation-logo', 'path': inasafe_context.organisation_logo }, { 'id': 'supporters_logo', 'path': inasafe_context.supporters_logo }] context.image_elements = image_elements # Set default HTML Frame elements to replace html_frame_elements = [{ 'id': 'impact-report', 'mode': 'text', # another mode is url 'text': '', # TODO: get impact summary table }] context.html_frame_elements = html_frame_elements # Set default map to resize # check show only impact show_only_impact = setting('set_show_only_impact_on_report', False, bool) layers = [impact_report.impact_function.impact] layer_registry = QgsMapLayerRegistry.instance() if not show_only_impact: hazard_layer = layer_registry.mapLayers().get( provenance['hazard_layer_id'], None) aggregation_layer_id = provenance['aggregation_layer_id'] if aggregation_layer_id: aggregation_layer = layer_registry.mapLayers().get( aggregation_layer_id, None) layers.insert(0, aggregation_layer) layers.append(hazard_layer) # check hide exposure settings hide_exposure_flag = setting('setHideExposureFlag', False, bool) if not hide_exposure_flag: # place exposure at the bottom exposure_layer = layer_registry.mapLayers().get( provenance['exposure_layer_id']) layers.append(exposure_layer) # default extent is analysis extent if not qgis_context.extent: qgis_context.extent = impact_report.impact_function.analysis_extent map_elements = [{ 'id': 'impact-map', 'extent': qgis_context.extent, 'grid_split_count': 5, 'layers': layers, }] context.map_elements = map_elements # calculate map_legends layers = [impact_report.impact] + impact_report.extra_layers symbol_count = 0 for l in layers: layer = l """:type: qgis.core.QgsMapLayer""" try: symbol_count += len(layer.legendSymbologyItems()) continue except Exception: # pylint: disable=broad-except pass try: symbol_count += len(layer.rendererV2().legendSymbolItemsV2()) continue except Exception: # pylint: disable=broad-except pass symbol_count += 1 legend_title = provenance['map_legend_title'] or '' map_legends = [{ 'id': 'impact-legend', 'title': legend_title, 'layers': layers, 'symbol_count': symbol_count, # 'column_count': 2, # the number of column in legend display }] context.map_legends = map_legends # process substitution map date_time = provenance['datetime'] """:type: datetime.datetime""" date_format = resolve_from_dictionary(extra_args, 'date-format') time_format = resolve_from_dictionary(extra_args, 'time-format') if isinstance(date_time, datetime.datetime): date = date_time.strftime(date_format) time = date_time.strftime(time_format) else: date = '' time = '' long_version = get_version() tokens = long_version.split('.') version = '%s.%s.%s' % (tokens[0], tokens[1], tokens[2]) # Get title of the layer title = provenance['map_title'] # Set source unknown_source_text = resolve_from_dictionary( extra_args, ['defaults', 'unknown_source']) aggregation_not_used = resolve_from_dictionary( extra_args, ['defaults', 'aggregation_not_used']) hazard_source = (provenance['hazard_keywords'].get('source') or unknown_source_text) exposure_source = (provenance['exposure_keywords'].get('source') or unknown_source_text) if provenance['aggregation_layer']: aggregation_source = (provenance['aggregation_keywords'].get('source') or unknown_source_text) else: aggregation_source = aggregation_not_used spatial_reference_format = resolve_from_dictionary( extra_args, 'spatial-reference-format') reference_name = spatial_reference_format.format( crs=impact_report.impact_function.impact.crs().authid()) analysis_layer = impact_report.analysis analysis_name = value_from_field_name(analysis_name_field['field_name'], analysis_layer) # Prepare the substitution map version_title = resolve_from_dictionary(extra_args, 'version-title') disclaimer_title = resolve_from_dictionary(extra_args, 'disclaimer-title') date_title = resolve_from_dictionary(extra_args, 'date-title') time_title = resolve_from_dictionary(extra_args, 'time-title') caution_title = resolve_from_dictionary(extra_args, 'caution-title') caution_text = resolve_from_dictionary(extra_args, 'caution-text') version_text = resolve_from_dictionary(extra_args, 'version-text') legend_section_title = resolve_from_dictionary(extra_args, 'legend-title') information_title = resolve_from_dictionary(extra_args, 'information-title') supporters_title = resolve_from_dictionary(extra_args, 'supporters-title') source_title = resolve_from_dictionary(extra_args, 'source-title') analysis_title = resolve_from_dictionary(extra_args, 'analysis-title') reference_title = resolve_from_dictionary(extra_args, 'spatial-reference-title') substitution_map = { 'impact-title': title, 'date': date, 'time': time, 'safe-version': version, # deprecated 'disclaimer': inasafe_context.disclaimer, # These added in 3.2 'version-title': version_title, 'inasafe-version': version, 'disclaimer-title': disclaimer_title, 'date-title': date_title, 'time-title': time_title, 'caution-title': caution_title, 'caution-text': caution_text, 'version-text': version_text.format(version=version), 'legend-title': legend_section_title, 'information-title': information_title, 'supporters-title': supporters_title, 'source-title': source_title, 'analysis-title': analysis_title, 'analysis-name': analysis_name, 'reference-title': reference_title, 'reference-name': reference_name, 'hazard-source': hazard_source, 'exposure-source': exposure_source, 'aggregation-source': aggregation_source, } context.substitution_map = substitution_map return context
def qgis_composer_extractor(impact_report, component_metadata): """Extract composer context. This method extract necessary context for a given impact report and component metadata and save the context so it can be used in composer rendering phase :param impact_report: the impact report that acts as a proxy to fetch all the data that extractor needed :type impact_report: safe.report.impact_report.ImpactReport :param component_metadata: the component metadata. Used to obtain information about the component we want to render :type component_metadata: safe.report.report_metadata. ReportComponentsMetadata :return: context for rendering phase :rtype: dict .. versionadded:: 4.0 """ # QGIS Composer needed certain context to generate the output # - Map Settings # - Substitution maps # - Element settings, such as icon for picture file or image source # Generate map settings qgis_context = impact_report.qgis_composition_context inasafe_context = impact_report.inasafe_context provenance = impact_report.impact_function.provenance extra_args = component_metadata.extra_args context = QGISComposerContext() # Set default image elements to replace image_elements = [{ 'id': 'safe-logo', 'path': inasafe_context.inasafe_logo }, { 'id': 'black-inasafe-logo', 'path': inasafe_context.black_inasafe_logo }, { 'id': 'white-inasafe-logo', 'path': inasafe_context.white_inasafe_logo }, { 'id': 'north-arrow', 'path': inasafe_context.north_arrow }, { 'id': 'organisation-logo', 'path': inasafe_context.organisation_logo }, { 'id': 'supporters_logo', 'path': inasafe_context.supporters_logo }] context.image_elements = image_elements # Set default HTML Frame elements to replace html_frame_elements = [{ 'id': 'impact-report', 'mode': 'text', # another mode is url 'text': '', # TODO: get impact summary table }] context.html_frame_elements = html_frame_elements """Define the layers for the impact map.""" project = QgsProject.instance() layers = [] exposure_summary_layers = [] if impact_report.multi_exposure_impact_function: for impact_function in ( impact_report.multi_exposure_impact_function.impact_functions): impact_layer = impact_function.exposure_summary or ( impact_function.aggregate_hazard_impacted) exposure_summary_layers.append(impact_layer) # use custom ordered layer if any if impact_report.ordered_layers: for layer in impact_report.ordered_layers: layers.append(layer) # We are keeping this if we want to enable below behaviour again. # Currently realtime might have layer order without impact layer in it. # # make sure at least there is an impact layer # if impact_report.multi_exposure_impact_function: # additional_layers = [] # for exposure summary layers # impact_layer_found = False # impact_functions = ( # impact_report.multi_exposure_impact_function.impact_functions) # # check for impact layer occurrences # for analysis in impact_functions: # impact_layer = analysis.exposure_summary or ( # analysis.aggregate_hazard_impacted) # for index, layer in enumerate(layers): # if impact_layer.source() == layer.source(): # add_impact_layers_to_canvas(analysis) # layers[index] = impact_layer # impact_layer_found = True # if not impact_layer_found: # for analysis in impact_functions: # add_impact_layers_to_canvas(analysis) # impact_layer = analysis.exposure_summary or ( # analysis.aggregate_hazard_impacted) # layer_uri = full_layer_uri(impact_layer) # layer = load_layer_from_registry(layer_uri) # additional_layers.append(layer) # layers = additional_layers + layers # else: # impact_layer = ( # impact_report.impact_function.exposure_summary or ( # impact_report.impact_function.aggregate_hazard_impacted)) # if impact_layer not in layers: # layers.insert(0, impact_layer) # use default layer order if no custom ordered layer found else: if not impact_report.multi_exposure_impact_function: # single IF layers = [impact_report.impact] + impact_report.extra_layers else: # multi-exposure IF layers = [] + impact_report.extra_layers add_supplementary_layers = ( not impact_report.multi_exposure_impact_function or not (impact_report.multi_exposure_impact_function. output_layers_ordered)) if add_supplementary_layers: # Check show only impact. show_only_impact = setting('set_show_only_impact_on_report', expected_type=bool) if not show_only_impact: hazard_layer = project.mapLayers().get( provenance['hazard_layer_id'], None) aggregation_layer_id = provenance['aggregation_layer_id'] if aggregation_layer_id: aggregation_layer = project.mapLayers().get( aggregation_layer_id, None) layers.append(aggregation_layer) layers.append(hazard_layer) # check hide exposure settings hide_exposure_flag = setting('setHideExposureFlag', expected_type=bool) if not hide_exposure_flag: exposure_layers_id = [] if provenance.get( provenance_exposure_layer_id['provenance_key']): exposure_layers_id.append( provenance.get( provenance_exposure_layer_id['provenance_key'])) elif provenance.get( provenance_multi_exposure_layers_id['provenance_key']): exposure_layers_id = provenance.get( provenance_multi_exposure_layers_id['provenance_key']) # place exposure at the bottom for layer_id in exposure_layers_id: exposure_layer = project.mapLayers().get(layer_id) layers.append(exposure_layer) # default extent is analysis extent if not qgis_context.extent: qgis_context.extent = impact_report.impact_function.analysis_extent map_elements = [{ 'id': 'impact-map', 'extent': qgis_context.extent, 'grid_split_count': 5, 'layers': layers, }] context.map_elements = map_elements # calculate map_legends, only show the legend for impact layer if impact_report.legend_layers: # use requested legend if any layers = impact_report.legend_layers elif impact_report.multi_exposure_impact_function: # multi-exposure IF layers = exposure_summary_layers else: # single IF layers = [impact_report.impact] symbol_count = 0 for l in layers: layer = l """:type: qgis.core.QgsMapLayer""" try: symbol_count += len(layer.legendSymbologyItems()) continue except Exception: # pylint: disable=broad-except pass try: symbol_count += len(layer.renderer().legendSymbolItems()) continue except Exception: # pylint: disable=broad-except pass symbol_count += 1 legend_title = provenance.get('map_legend_title') or '' map_legends = [{ 'id': 'impact-legend', 'title': legend_title, 'layers': layers, 'symbol_count': symbol_count, # 'column_count': 2, # the number of column in legend display }] context.map_legends = map_legends # process substitution map start_datetime = provenance['start_datetime'] """:type: datetime.datetime""" date_format = resolve_from_dictionary(extra_args, 'date-format') time_format = resolve_from_dictionary(extra_args, 'time-format') if isinstance(start_datetime, datetime.datetime): date = start_datetime.strftime(date_format) time = start_datetime.strftime(time_format) else: date = '' time = '' long_version = get_version() tokens = long_version.split('.') version = '%s.%s.%s' % (tokens[0], tokens[1], tokens[2]) # Get title of the layer title = provenance.get('map_title') or '' # Set source unknown_source_text = resolve_from_dictionary( extra_args, ['defaults', 'unknown_source']) aggregation_not_used = resolve_from_dictionary( extra_args, ['defaults', 'aggregation_not_used']) hazard_source = (provenance.get('hazard_keywords', {}).get('source') or unknown_source_text) exposure_source = (provenance.get('exposure_keywords', {}).get('source') or unknown_source_text) if provenance['aggregation_layer']: aggregation_source = (provenance['aggregation_keywords'].get('source') or unknown_source_text) else: aggregation_source = aggregation_not_used spatial_reference_format = resolve_from_dictionary( extra_args, 'spatial-reference-format') reference_name = spatial_reference_format.format( crs=impact_report.impact_function.crs.authid()) analysis_layer = impact_report.analysis analysis_name = value_from_field_name(analysis_name_field['field_name'], analysis_layer) # Prepare the substitution map version_title = resolve_from_dictionary(extra_args, 'version-title') disclaimer_title = resolve_from_dictionary(extra_args, 'disclaimer-title') date_title = resolve_from_dictionary(extra_args, 'date-title') time_title = resolve_from_dictionary(extra_args, 'time-title') caution_title = resolve_from_dictionary(extra_args, 'caution-title') caution_text = resolve_from_dictionary(extra_args, 'caution-text') version_text = resolve_from_dictionary(extra_args, 'version-text') legend_section_title = resolve_from_dictionary(extra_args, 'legend-title') information_title = resolve_from_dictionary(extra_args, 'information-title') supporters_title = resolve_from_dictionary(extra_args, 'supporters-title') source_title = resolve_from_dictionary(extra_args, 'source-title') analysis_title = resolve_from_dictionary(extra_args, 'analysis-title') reference_title = resolve_from_dictionary(extra_args, 'spatial-reference-title') substitution_map = { 'impact-title': title, 'date': date, 'time': time, 'safe-version': version, # deprecated 'disclaimer': inasafe_context.disclaimer, # These added in 3.2 'version-title': version_title, 'inasafe-version': version, 'disclaimer-title': disclaimer_title, 'date-title': date_title, 'time-title': time_title, 'caution-title': caution_title, 'caution-text': caution_text, 'version-text': version_text.format(version=version), 'legend-title': legend_section_title, 'information-title': information_title, 'supporters-title': supporters_title, 'source-title': source_title, 'analysis-title': analysis_title, 'analysis-name': analysis_name, 'reference-title': reference_title, 'reference-name': reference_name, 'hazard-source': hazard_source, 'exposure-source': exposure_source, 'aggregation-source': aggregation_source, } context.substitution_map = substitution_map return context
def impact_attribution(keywords, inasafe_flag=False): """Make a little table for attribution of data sources used in impact. :param keywords: A keywords dict for an impact layer. :type keywords: dict :param inasafe_flag: bool - whether to show a little InaSAFE promotional text in the attribution output. Defaults to False. :returns: An html snippet containing attribution information for the impact layer. If no keywords are present or no appropriate keywords are present, None is returned. :rtype: safe.messaging.Message """ if keywords is None: return None join_words = ' - %s ' % tr('sourced from') analysis_details = tr('Analysis details') hazard_details = tr('Hazard details') hazard_title_keywords = 'hazard_title' hazard_source_keywords = 'hazard_source' exposure_details = tr('Exposure details') exposure_title_keywords = 'exposure_title' exposure_source_keyword = 'exposure_source' if hazard_title_keywords in keywords: hazard_title = tr(keywords[hazard_title_keywords]) else: hazard_title = tr('Hazard layer') if hazard_source_keywords in keywords: hazard_source = tr(keywords[hazard_source_keywords]) else: hazard_source = tr('an unknown source') if exposure_title_keywords in keywords: exposure_title = keywords[exposure_title_keywords] else: exposure_title = tr('Exposure layer') if exposure_source_keyword in keywords: exposure_source = keywords[exposure_source_keyword] else: exposure_source = tr('an unknown source') report = m.Message() report.add(m.Heading(analysis_details, **INFO_STYLE)) report.add(hazard_details) report.add(m.Paragraph(hazard_title, join_words, hazard_source)) report.add(exposure_details) report.add(m.Paragraph(exposure_title, join_words, exposure_source)) if inasafe_flag: report.add(m.Heading(tr('Software notes'), **INFO_STYLE)) # noinspection PyUnresolvedReferences inasafe_phrase = tr( 'This report was created using InaSAFE version %s. Visit ' 'http://inasafe.org to get your free copy of this software! %s' ) % (get_version(), disclaimer()) report.add(m.Paragraph(m.Text(inasafe_phrase))) return report
def impact_attribution(keywords, inasafe_flag=False): """Make a little table for attribution of data sources used in impact. :param keywords: A keywords dict for an impact layer. :type keywords: dict :param inasafe_flag: bool - whether to show a little InaSAFE promotional text in the attribution output. Defaults to False. :returns: An html snippet containing attribution information for the impact layer. If no keywords are present or no appropriate keywords are present, None is returned. :rtype: safe.messaging.Message """ if keywords is None: return None join_words = ' - %s ' % tr('sourced from') analysis_details = tr('Analysis details') hazard_details = tr('Hazard details') hazard_title_keywords = 'hazard_title' hazard_source_keywords = 'hazard_source' exposure_details = tr('Exposure details') exposure_title_keywords = 'exposure_title' exposure_source_keyword = 'exposure_source' if hazard_title_keywords in keywords: hazard_title = tr(keywords[hazard_title_keywords]) else: hazard_title = tr('Hazard layer') if hazard_source_keywords in keywords: hazard_source = tr(keywords[hazard_source_keywords]) else: hazard_source = tr('an unknown source') if exposure_title_keywords in keywords: exposure_title = keywords[exposure_title_keywords] else: exposure_title = tr('Exposure layer') if exposure_source_keyword in keywords: exposure_source = keywords[exposure_source_keyword] else: exposure_source = tr('an unknown source') report = m.Message() report.add(m.Heading(analysis_details, **INFO_STYLE)) report.add(hazard_details) report.add(m.Paragraph( hazard_title, join_words, hazard_source)) report.add(exposure_details) report.add(m.Paragraph( exposure_title, join_words, exposure_source)) if inasafe_flag: report.add(m.Heading(tr('Software notes'), **INFO_STYLE)) # noinspection PyUnresolvedReferences inasafe_phrase = tr( 'This report was created using InaSAFE version %s. Visit ' 'http://inasafe.org to get your free copy of this software! %s' ) % (get_version(), disclaimer()) report.add(m.Paragraph(m.Text(inasafe_phrase))) return report
def _show_system_info(self): print "safe version %s" % get_version() super(SafeTester, self)._show_system_info()
def qgis_composer_extractor(impact_report, component_metadata): """Extract composer context. This method extract necessary context for a given impact report and component metadata and save the context so it can be used in composer rendering phase :param impact_report: the impact report that acts as a proxy to fetch all the data that extractor needed :type impact_report: safe.report.impact_report.ImpactReport :param component_metadata: the component metadata. Used to obtain information about the component we want to render :type component_metadata: safe.report.report_metadata. ReportComponentsMetadata :return: context for rendering phase :rtype: dict .. versionadded:: 4.0 """ # QGIS Composer needed certain context to generate the output # - Map Settings # - Substitution maps # - Element settings, such as icon for picture file or image source # Generate map settings qgis_context = impact_report.qgis_composition_context inasafe_context = impact_report.inasafe_context provenance = impact_report.impact_function.provenance extra_args = component_metadata.extra_args context = QGISComposerContext() # Set default image elements to replace image_elements = [ { 'id': 'safe-logo', 'path': inasafe_context.inasafe_logo }, { 'id': 'black-inasafe-logo', 'path': inasafe_context.black_inasafe_logo }, { 'id': 'white-inasafe-logo', 'path': inasafe_context.white_inasafe_logo }, { 'id': 'north-arrow', 'path': inasafe_context.north_arrow }, { 'id': 'organisation-logo', 'path': inasafe_context.organisation_logo }, { 'id': 'supporters_logo', 'path': inasafe_context.supporters_logo } ] context.image_elements = image_elements # Set default HTML Frame elements to replace html_frame_elements = [ { 'id': 'impact-report', 'mode': 'text', # another mode is url 'text': '', # TODO: get impact summary table } ] context.html_frame_elements = html_frame_elements # Set default map to resize # check show only impact show_only_impact = setting('set_show_only_impact_on_report', False, bool) layers = [impact_report.impact] + impact_report.extra_layers layer_registry = QgsMapLayerRegistry.instance() if not show_only_impact: hazard_layer = layer_registry.mapLayers().get( provenance['hazard_layer_id'], None) aggregation_layer_id = provenance['aggregation_layer_id'] if aggregation_layer_id: aggregation_layer = layer_registry.mapLayers().get( aggregation_layer_id, None) layers.insert(0, aggregation_layer) layers.append(hazard_layer) # check hide exposure settings hide_exposure_flag = setting('setHideExposureFlag', False, bool) if not hide_exposure_flag: # place exposure at the bottom exposure_layer = layer_registry.mapLayers().get( provenance['exposure_layer_id']) layers.append(exposure_layer) # default extent is analysis extent if not qgis_context.extent: qgis_context.extent = impact_report.impact_function.analysis_extent map_elements = [ { 'id': 'impact-map', 'extent': qgis_context.extent, 'grid_split_count': 5, 'layers': layers, } ] context.map_elements = map_elements # calculate map_legends, only show the legend for impact layer layers = [impact_report.impact] symbol_count = 0 for l in layers: layer = l """:type: qgis.core.QgsMapLayer""" try: symbol_count += len(layer.legendSymbologyItems()) continue except Exception: # pylint: disable=broad-except pass try: symbol_count += len(layer.rendererV2().legendSymbolItemsV2()) continue except Exception: # pylint: disable=broad-except pass symbol_count += 1 legend_title = provenance['map_legend_title'] or '' map_legends = [ { 'id': 'impact-legend', 'title': legend_title, 'layers': layers, 'symbol_count': symbol_count, # 'column_count': 2, # the number of column in legend display } ] context.map_legends = map_legends # process substitution map start_datetime = provenance['start_datetime'] """:type: datetime.datetime""" date_format = resolve_from_dictionary(extra_args, 'date-format') time_format = resolve_from_dictionary(extra_args, 'time-format') if isinstance(start_datetime, datetime.datetime): date = start_datetime.strftime(date_format) time = start_datetime.strftime(time_format) else: date = '' time = '' long_version = get_version() tokens = long_version.split('.') version = '%s.%s.%s' % (tokens[0], tokens[1], tokens[2]) # Get title of the layer title = provenance['map_title'] # Set source unknown_source_text = resolve_from_dictionary( extra_args, ['defaults', 'unknown_source']) aggregation_not_used = resolve_from_dictionary( extra_args, ['defaults', 'aggregation_not_used']) hazard_source = ( provenance['hazard_keywords'].get('source') or unknown_source_text) exposure_source = ( provenance['exposure_keywords'].get('source') or unknown_source_text) if provenance['aggregation_layer']: aggregation_source = ( provenance['aggregation_keywords'].get('source') or unknown_source_text) else: aggregation_source = aggregation_not_used spatial_reference_format = resolve_from_dictionary( extra_args, 'spatial-reference-format') reference_name = spatial_reference_format.format( crs=impact_report.impact_function.impact.crs().authid()) analysis_layer = impact_report.analysis analysis_name = value_from_field_name( analysis_name_field['field_name'], analysis_layer) # Prepare the substitution map version_title = resolve_from_dictionary(extra_args, 'version-title') disclaimer_title = resolve_from_dictionary(extra_args, 'disclaimer-title') date_title = resolve_from_dictionary(extra_args, 'date-title') time_title = resolve_from_dictionary(extra_args, 'time-title') caution_title = resolve_from_dictionary(extra_args, 'caution-title') caution_text = resolve_from_dictionary(extra_args, 'caution-text') version_text = resolve_from_dictionary(extra_args, 'version-text') legend_section_title = resolve_from_dictionary( extra_args, 'legend-title') information_title = resolve_from_dictionary( extra_args, 'information-title') supporters_title = resolve_from_dictionary( extra_args, 'supporters-title') source_title = resolve_from_dictionary(extra_args, 'source-title') analysis_title = resolve_from_dictionary(extra_args, 'analysis-title') reference_title = resolve_from_dictionary( extra_args, 'spatial-reference-title') substitution_map = { 'impact-title': title, 'date': date, 'time': time, 'safe-version': version, # deprecated 'disclaimer': inasafe_context.disclaimer, # These added in 3.2 'version-title': version_title, 'inasafe-version': version, 'disclaimer-title': disclaimer_title, 'date-title': date_title, 'time-title': time_title, 'caution-title': caution_title, 'caution-text': caution_text, 'version-text': version_text.format(version=version), 'legend-title': legend_section_title, 'information-title': information_title, 'supporters-title': supporters_title, 'source-title': source_title, 'analysis-title': analysis_title, 'analysis-name': analysis_name, 'reference-title': reference_title, 'reference-name': reference_name, 'hazard-source': hazard_source, 'exposure-source': exposure_source, 'aggregation-source': aggregation_source, } context.substitution_map = substitution_map return context
def test_event_info_dict(self): """Test we can get a dictionary of location info nicely.""" working_dir = shakemap_extract_dir() shake_event = ShakeEvent(working_dir=working_dir, event_id=SHAKE_ID, data_is_local_flag=True) result = shake_event.event_dict() software_tag = ( "This report was created using InaSAFE version %s. " "Visit http://inasafe.org for more information." % get_version() ) # noinspection PyUnresolvedReferences expected_dict = { "place-name": u"n/a", "depth-name": u"Depth", "fatalities-name": u"Estimated fatalities", "fatalities-count": u"0", # 44 only after render "elapsed-time": u"", # empty as it will change "legend-name": u"Population count per grid cell", "fatalities-range": "0 - 100", "longitude-name": u"Longitude", "located-label": u"Located", "distance-unit": u"km", "bearing-compass": u"n/a", "elapsed-time-name": u"Elapsed time since event", "exposure-table-name": u"Estimated number of people " u"affected by each MMI level", "longitude-value": u"140\xb037\u203212.00\u2033E", "city-table-name": u"Nearby Places", "bearing-text": u"bearing", "limitations": ( u"This impact estimation is automatically generated and only " u"takes into account the population and cities affected by " u"different levels of ground shaking. The estimate is based " u"on ground shaking data from BMKG, population count data " u"derived by AIFDR from worldpop.org.uk, place information " u"from geonames.org and software developed by BNPB. " u"Limitations in the estimates of ground shaking, population " u"and place names datasets may result in significant " u"misrepresentation of the on-the-ground situation in the " u"figures shown here. Consequently decisions should not be " u"made solely on the information presented here and should " u"always be verified by ground truthing and other reliable " u"information sources. The fatality calculation assumes that " u"no fatalities occur for shake levels below MMI 4. Fatality " u"counts of less than 50 are disregarded." ), "depth-unit": u"km", "latitude-name": u"Latitude", "mmi": "3.6", "map-name": u"Estimated Earthquake Impact", "date": "5-11-2013", "bearing-degrees": "0.00\xb0", "formatted-date-time": "05-Nov-13 06:08:09 LMT", "distance": "0.00", "direction-relation": u"of", "software-tag": software_tag, "credits": ( u"Supported by the Australia-Indonesia Facility for Disaster " u"Reduction, Geoscience Australia and the World Bank-GFDRR." ), "latitude-value": u"2\xb025\u203248.00\u2033S", "time": "6:8:9", "depth-value": "10.0", } result["elapsed-time"] = u"" message = "Got:\n%s\nExpected:\n%s\n" % (result, expected_dict) self.max_diff = None difference = DictDiffer(result, expected_dict) print difference.all() self.assertDictEqual(expected_dict, result, message)
def test_event_info_dict(self): """Test we can get a dictionary of location info nicely.""" working_dir = shakemap_extract_dir() shake_event = ShakeEvent( working_dir=working_dir, event_id=SHAKE_ID, data_is_local_flag=True) result = shake_event.event_dict() software_tag = ('This report was created using InaSAFE version %s. ' 'Visit http://inasafe.org for more information.' % get_version()) # noinspection PyUnresolvedReferences expected_dict = { 'place-name': u'Jayapura', 'shake-grid-location': u'Papua', 'depth-name': u'Depth', 'fatalities-name': u'Estimated fatalities', 'fatalities-count': u'0', # 44 only after render 'elapsed-time': u'', # empty as it will change 'legend-name': u'Population count per grid cell', 'fatalities-range': '0 - 100', 'longitude-name': u'Longitude', 'located-label': u'Located', 'distance-unit': u'km', 'bearing-compass': u'NW', 'elapsed-time-name': u'Elapsed time since event', 'exposure-table-name': u'Estimated number of people ' u'affected by each MMI level', 'longitude-value': u'140\xb037\u203212.00\u2033E', 'city-table-name': u'Nearby Places', 'bearing-text': u'bearing', 'limitations': ( u'This impact estimation is automatically generated and only ' u'takes into account the population and cities affected by ' u'different levels of ground shaking. The estimate is based ' u'on ground shaking data from BMKG, population count data ' u'derived by Australian Government from worldpop.org.uk, ' u'place information from geonames.org and software developed ' u'by BNPB. Limitations in the estimates of ground shaking, ' u'population and place names datasets may result in ' u'significant misrepresentation of the on-the-ground ' u'situation in the figures shown here. Consequently ' u'decisions should not be made solely on the information ' u'presented here and should always be verified by ground ' u'truthing and other reliable information sources. The ' u'fatality calculation assumes that no fatalities occur ' u'for shake levels below MMI 4. Fatality counts of less than ' u'50 are disregarded.'), 'depth-unit': u'km', 'latitude-name': u'Latitude', 'mmi': '3.6', 'map-name': u'Estimated Earthquake Impact', 'date': '5-11-2013', 'bearing-degrees': '-37.75\xb0', 'formatted-date-time': '05-Nov-13 06:08:09 +0707', 'distance': '0.02', 'direction-relation': u'of', 'software-tag': software_tag, 'credits': ( u'Supported by the Australian Government, Geoscience ' u'Australia and the World Bank-GFDRR.'), 'latitude-value': u'2\xb025\u203248.00\u2033S', 'time': '6:8:9', 'depth-value': '10.0'} result['elapsed-time'] = u'' message = 'Got:\n%s\nExpected:\n%s\n' % (result, expected_dict) self.max_diff = None difference = DictDiffer(result, expected_dict) LOGGER.debug(difference.all()) self.assertDictEqual(expected_dict, result, message)
def __init__(self, iface, parent=None, qsetting=''): """Constructor for the dialog. :param iface: A Quantum GIS QgisAppInterface instance. :type iface: QgisAppInterface :param parent: Parent widget of this dialog :type parent: QWidget :param qsetting: String to specify the QSettings. By default, use empty string. :type qsetting: str """ QDialog.__init__(self, parent) self.setupUi(self) icon = resources_path('img', 'icons', 'configure-inasafe.svg') self.setWindowIcon(QIcon(icon)) self.setWindowTitle(self.tr('InaSAFE %s Options' % get_version())) # Save reference to the QGIS interface and parent self.iface = iface self.parent = parent if qsetting: self.settings = QSettings(qsetting) else: self.settings = QSettings() # InaSAFE default values self.default_value_parameters = [] self.default_value_parameter_containers = [] # Flag for restore default values self.is_restore_default = False # List of setting key and control self.boolean_settings = { 'visibleLayersOnlyFlag': self.cbxVisibleLayersOnly, 'set_layer_from_title_flag': self.cbxSetLayerNameFromTitle, 'setZoomToImpactFlag': self.cbxZoomToImpact, 'set_show_only_impact_on_report': self.cbx_show_only_impact, 'print_atlas_report': self.cbx_print_atlas_report, 'setHideExposureFlag': self.cbxHideExposure, 'useSelectedFeaturesOnly': self.cbxUseSelectedFeaturesOnly, 'useSentry': self.cbxUseSentry, 'template_warning_verbose': self.template_warning_checkbox, 'showOrganisationLogoInDockFlag': self.organisation_on_dock_checkbox, 'developer_mode': self.cbxDevMode, 'generate_report': self.checkbox_generate_reports, 'memory_profile': self.check_box_memory, 'always_show_welcome_message': self.welcome_message_check_box } self.text_settings = { 'keywordCachePath': self.leKeywordCachePath, 'ISO19115_ORGANIZATION': self.organisation_line_edit, 'ISO19115_URL': self.website_line_edit, 'ISO19115_EMAIL': self.email_line_edit, 'ISO19115_LICENSE': self.license_line_edit, } # Export and Import button # Export button self.export_button = QPushButton(tr('Export')) # noinspection PyUnresolvedReferences self.export_button.clicked.connect(self.export_setting) self.button_box.addButton(self.export_button, QDialogButtonBox.ActionRole) # Import button self.import_button = QPushButton(tr('Import')) # noinspection PyUnresolvedReferences self.import_button.clicked.connect(self.import_setting) self.button_box.addButton(self.import_button, QDialogButtonBox.ActionRole) # Set up things for context help self.help_button = self.button_box.button(QDialogButtonBox.Help) # Allow toggling the help button self.help_button.setCheckable(True) self.help_button.toggled.connect(self.help_toggled) self.main_stacked_widget.setCurrentIndex(1) # Always set first tab to be open, 0-th index self.tabWidget.setCurrentIndex(0) # Hide not implemented group self.grpNotImplemented.hide() self.adjustSize() # Population parameter Tab # Label self.preference_label = QLabel() self.preference_label.setText( tr('Please set parameters for each hazard class below. Affected ' 'status and displacement rates selected on this tab are only ' 'applied to exposed populations. ')) self.preference_layout.addWidget(self.preference_label) # Profile preference widget self.profile_widget = ProfileWidget() self.preference_layout.addWidget(self.profile_widget) # Demographic tab self.demographic_label = QLabel() self.demographic_label.setText( tr('Please set the global default demographic ratio below.')) self.default_values_layout.addWidget(self.demographic_label) self.scroll_area = QScrollArea() self.scroll_area.setWidgetResizable(True) self.widget_container = QWidget() self.scroll_area.setWidget(self.widget_container) self.container_layout = QVBoxLayout() self.widget_container.setLayout(self.container_layout) self.default_values_layout.addWidget(self.scroll_area) # Restore state from setting self.restore_state() # Hide checkbox if not developers if not self.cbxDevMode.isChecked(): self.checkbox_generate_reports.hide() # Connections # Check boxes self.custom_north_arrow_checkbox.toggled.connect(self.set_north_arrow) self.custom_UseUserDirectory_checkbox.toggled.connect( self.set_user_dir) self.custom_templates_dir_checkbox.toggled.connect( self.set_templates_dir) self.custom_org_disclaimer_checkbox.toggled.connect( self.set_org_disclaimer) self.custom_organisation_logo_check_box.toggled.connect( self.toggle_logo_path) # Buttons self.toolKeywordCachePath.clicked.connect(self.open_keyword_cache_path) self.toolUserDirectoryPath.clicked.connect( self.open_user_directory_path) self.toolNorthArrowPath.clicked.connect(self.open_north_arrow_path) self.open_organisation_logo_path_button.clicked.connect( self.open_organisation_logo_path) self.toolReportTemplatePath.clicked.connect( self.open_report_template_path) # Others self.organisation_logo_path_line_edit.textChanged.connect( self.update_logo_preview) self.earthquake_function.currentIndexChanged.connect( self.update_earthquake_info) # Set up listener for restore defaults button self.demographic_restore_defaults = self.button_box_restore_defaults.\ button(QDialogButtonBox.RestoreDefaults) self.demographic_restore_defaults.setText( self.demographic_restore_defaults.text().capitalize()) self.demographic_restore_defaults.setCheckable(True) self.demographic_restore_defaults.clicked.connect( self.restore_defaults_ratio) # Restore button in population parameter tab self.parameter_population_restore_button = \ self.button_box_restore_preference.button( QDialogButtonBox.RestoreDefaults) self.parameter_population_restore_button.setText( self.parameter_population_restore_button.text().capitalize()) self.parameter_population_restore_button.clicked.connect( partial(self.restore_population_parameters, global_default=True)) # TODO: Hide this until behaviour is defined # hide template warning toggle self.template_warning_checkbox.hide() # hide custom template dir toggle self.custom_templates_dir_checkbox.hide() self.splitter_custom_report.hide() # Welcome message self.set_welcome_message()
def __init__(self, parent, iface, dock=None, layer=None): """Constructor for the dialog. .. note:: In QtDesigner the advanced editor's predefined keywords list should be shown in english always, so when adding entries to cboKeyword, be sure to choose :safe_qgis:`Properties<<` and untick the :safe_qgis:`translatable` property. :param parent: Parent widget of this dialog. :type parent: QWidget :param iface: Quantum GIS QGisAppInterface instance. :type iface: QGisAppInterface :param dock: Dock widget instance that we can notify of changes to the keywords. Optional. :type dock: Dock """ QtGui.QDialog.__init__(self, parent) self.setupUi(self) self.setWindowTitle(self.tr( 'InaSAFE %s Keywords Editor' % get_version())) # Save reference to the QGIS interface and parent self.iface = iface self.parent = parent self.dock = dock self.defaults = None # string constants self.global_default_string = metadata.global_default_attribute['name'] self.do_not_use_string = metadata.do_not_use_attribute['name'] self.global_default_data = metadata.global_default_attribute['id'] self.do_not_use_data = metadata.do_not_use_attribute['id'] if layer is None: self.layer = self.iface.activeLayer() else: self.layer = layer self.keyword_io = KeywordIO() # note the keys should remain untranslated as we need to write # english to the keywords file. The keys will be written as user data # in the combo entries. # .. seealso:: http://www.voidspace.org.uk/python/odict.html self.standard_exposure_list = OrderedDict( [('population', self.tr('population')), ('structure', self.tr('structure')), ('road', self.tr('road')), ('Not Set', self.tr('Not Set'))]) self.standard_hazard_list = OrderedDict( [('earthquake [MMI]', self.tr('earthquake [MMI]')), ('tsunami [m]', self.tr('tsunami [m]')), ('tsunami [wet/dry]', self.tr('tsunami [wet/dry]')), ('tsunami [feet]', self.tr('tsunami [feet]')), ('flood [m]', self.tr('flood [m]')), ('flood [wet/dry]', self.tr('flood [wet/dry]')), ('flood [feet]', self.tr('flood [feet]')), ('tephra [kg2/m2]', self.tr('tephra [kg2/m2]')), ('volcano', self.tr('volcano')), ('generic [categorised]', self.tr('generic [categorised]')), ('Not Set', self.tr('Not Set'))]) # noinspection PyUnresolvedReferences self.lstKeywords.itemClicked.connect(self.edit_key_value_pair) # Set up help dialog showing logic. help_button = self.buttonBox.button(QtGui.QDialogButtonBox.Help) help_button.clicked.connect(self.show_help) if self.layer is not None and is_polygon_layer(self.layer): # set some initial ui state: self.defaults = get_defaults() self.radPredefined.setChecked(True) self.dsbFemaleRatioDefault.blockSignals(True) self.dsbFemaleRatioDefault.setValue(self.defaults['FEMALE_RATIO']) self.dsbFemaleRatioDefault.blockSignals(False) self.dsbYouthRatioDefault.blockSignals(True) self.dsbYouthRatioDefault.setValue(self.defaults['YOUTH_RATIO']) self.dsbYouthRatioDefault.blockSignals(False) self.dsbAdultRatioDefault.blockSignals(True) self.dsbAdultRatioDefault.setValue(self.defaults['ADULT_RATIO']) self.dsbAdultRatioDefault.blockSignals(False) self.dsbElderlyRatioDefault.blockSignals(True) self.dsbElderlyRatioDefault.setValue( self.defaults['ELDERLY_RATIO']) self.dsbElderlyRatioDefault.blockSignals(False) else: self.radPostprocessing.hide() self.tab_widget.removeTab(1) if self.layer: self.load_state_from_keywords() # add a reload from keywords button reload_button = self.buttonBox.addButton( self.tr('Reload'), QtGui.QDialogButtonBox.ActionRole) reload_button.clicked.connect(self.load_state_from_keywords) self.resize_dialog() self.tab_widget.setCurrentIndex(0) # TODO No we should not have test related stuff in prod code. TS self.test = False
from safe.common.version import get_version __version__ = (1, 0, 0, 'final', 0) __full_version__ = get_version(__version__)
def __init__(self, iface, parent=None, qsetting=''): """Constructor for the dialog. :param iface: A Quantum GIS QGisAppInterface instance. :type iface: QGisAppInterface :param parent: Parent widget of this dialog :type parent: QWidget :param qsetting: String to specify the QSettings. By default, use empty string. :type qsetting: str """ QDialog.__init__(self, parent) self.setupUi(self) self.setWindowTitle(self.tr('InaSAFE %s Options' % get_version())) # Save reference to the QGIS interface and parent self.iface = iface self.parent = parent if qsetting: self.settings = QSettings(qsetting) else: self.settings = QSettings() # InaSAFE default values self.default_value_parameters = [] self.default_value_parameter_containers = [] # Flag for restore default values self.is_restore_default = False # List of setting key and control self.boolean_settings = { 'visibleLayersOnlyFlag': self.cbxVisibleLayersOnly, 'set_layer_from_title_flag': self.cbxSetLayerNameFromTitle, 'setZoomToImpactFlag': self.cbxZoomToImpact, 'set_show_only_impact_on_report': self.cbx_show_only_impact, 'print_atlas_report': self.cbx_print_atlas_report, 'setHideExposureFlag': self.cbxHideExposure, 'useSelectedFeaturesOnly': self.cbxUseSelectedFeaturesOnly, 'useSentry': self.cbxUseSentry, 'template_warning_verbose': self.template_warning_checkbox, 'showOrganisationLogoInDockFlag': self.organisation_on_dock_checkbox, 'developer_mode': self.cbxDevMode, 'generate_report': self.checkbox_generate_reports, 'memory_profile': self.check_box_memory } self.text_settings = { 'keywordCachePath': self.leKeywordCachePath, 'ISO19115_ORGANIZATION': self.iso19115_organization_le, 'ISO19115_URL': self.iso19115_url_le, 'ISO19115_EMAIL': self.iso19115_email_le, 'ISO19115_LICENSE': self.iso19115_license_le, } # Set up things for context help self.help_button = self.button_box.button(QDialogButtonBox.Help) # Allow toggling the help button self.help_button.setCheckable(True) self.help_button.toggled.connect(self.help_toggled) self.main_stacked_widget.setCurrentIndex(1) # Always set first tab to be open, 0-th index self.tabWidget.setCurrentIndex(0) # Hide not implemented group self.grpNotImplemented.hide() self.adjustSize() # Demographic tab self.scroll_area = QScrollArea() self.scroll_area.setWidgetResizable(True) self.widget_container = QWidget() self.scroll_area.setWidget(self.widget_container) self.container_layout = QVBoxLayout() self.widget_container.setLayout(self.container_layout) self.default_values_layout.addWidget(self.scroll_area) self.restore_state() # Hide checkbox if not developers if not self.cbxDevMode.isChecked(): self.checkbox_generate_reports.hide() # Set up listener for various UI self.custom_org_logo_checkbox.toggled.connect( self.set_organisation_logo) self.custom_north_arrow_checkbox.toggled.connect(self.set_north_arrow) self.custom_UseUserDirectory_checkbox.toggled.connect( self.set_user_dir) self.custom_templates_dir_checkbox.toggled.connect( self.set_templates_dir) self.custom_org_disclaimer_checkbox.toggled.connect( self.set_org_disclaimer) # Set up listener for restore defaults button self.restore_defaults = self.button_box_restore_defaults.button( QDialogButtonBox.RestoreDefaults) self.restore_defaults.setCheckable(True) self.restore_defaults.clicked.connect(self.restore_defaults_ratio) # TODO: Hide this until behaviour is defined # hide template warning toggle self.template_warning_checkbox.hide() # hide custom template dir toggle self.custom_templates_dir_checkbox.hide() self.splitter_custom_report.hide()
def __init__(self, iface, parent=None, qsetting=''): """Constructor for the dialog. :param iface: A Quantum GIS QgisAppInterface instance. :type iface: QgisAppInterface :param parent: Parent widget of this dialog :type parent: QWidget :param qsetting: String to specify the QSettings. By default, use empty string. :type qsetting: str """ QDialog.__init__(self, parent) self.setupUi(self) icon = resources_path('img', 'icons', 'configure-inasafe.svg') self.setWindowIcon(QIcon(icon)) self.setWindowTitle(self.tr('InaSAFE %s Options' % get_version())) # Save reference to the QGIS interface and parent self.iface = iface self.parent = parent if qsetting: self.settings = QSettings(qsetting) else: self.settings = QSettings() # InaSAFE default values self.default_value_parameters = [] self.default_value_parameter_containers = [] # Flag for restore default values self.is_restore_default = False # List of setting key and control self.boolean_settings = { 'visibleLayersOnlyFlag': self.cbxVisibleLayersOnly, 'set_layer_from_title_flag': self.cbxSetLayerNameFromTitle, 'setZoomToImpactFlag': self.cbxZoomToImpact, 'set_show_only_impact_on_report': self.cbx_show_only_impact, 'print_atlas_report': self.cbx_print_atlas_report, 'setHideExposureFlag': self.cbxHideExposure, 'useSelectedFeaturesOnly': self.cbxUseSelectedFeaturesOnly, 'useSentry': self.cbxUseSentry, 'template_warning_verbose': self.template_warning_checkbox, 'showOrganisationLogoInDockFlag': self.organisation_on_dock_checkbox, 'developer_mode': self.cbxDevMode, 'generate_report': self.checkbox_generate_reports, 'memory_profile': self.check_box_memory, 'always_show_welcome_message': self.welcome_message_check_box } self.text_settings = { 'keywordCachePath': self.leKeywordCachePath, 'ISO19115_ORGANIZATION': self.organisation_line_edit, 'ISO19115_URL': self.website_line_edit, 'ISO19115_EMAIL': self.email_line_edit, 'ISO19115_LICENSE': self.license_line_edit, } # Export and Import button # Export button self.export_button = QPushButton(tr('Export')) # noinspection PyUnresolvedReferences self.export_button.clicked.connect(self.export_setting) self.button_box.addButton( self.export_button, QDialogButtonBox.ActionRole) # Import button self.import_button = QPushButton(tr('Import')) # noinspection PyUnresolvedReferences self.import_button.clicked.connect(self.import_setting) self.button_box.addButton( self.import_button, QDialogButtonBox.ActionRole) # Set up things for context help self.help_button = self.button_box.button(QDialogButtonBox.Help) # Allow toggling the help button self.help_button.setCheckable(True) self.help_button.toggled.connect(self.help_toggled) self.main_stacked_widget.setCurrentIndex(1) # Always set first tab to be open, 0-th index self.tabWidget.setCurrentIndex(0) # Hide not implemented group self.grpNotImplemented.hide() self.adjustSize() # Population parameter Tab # Label self.preference_label = QLabel() self.preference_label.setText(tr( 'Please set parameters for each hazard class below. Affected ' 'status and displacement rates selected on this tab are only ' 'applied to exposed populations. ' )) self.preference_layout.addWidget(self.preference_label) # Profile preference widget self.profile_widget = ProfileWidget() self.preference_layout.addWidget(self.profile_widget) # Demographic tab self.demographic_label = QLabel() self.demographic_label.setText(tr( 'Please set the global default demographic ratio below.')) self.default_values_layout.addWidget(self.demographic_label) self.scroll_area = QScrollArea() self.scroll_area.setWidgetResizable(True) self.widget_container = QWidget() self.scroll_area.setWidget(self.widget_container) self.container_layout = QVBoxLayout() self.widget_container.setLayout(self.container_layout) self.default_values_layout.addWidget(self.scroll_area) # Restore state from setting self.restore_state() # Hide checkbox if not developers if not self.cbxDevMode.isChecked(): self.checkbox_generate_reports.hide() # Connections # Check boxes self.custom_north_arrow_checkbox.toggled.connect(self.set_north_arrow) self.custom_UseUserDirectory_checkbox.toggled.connect( self.set_user_dir) self.custom_templates_dir_checkbox.toggled.connect( self.set_templates_dir) self.custom_org_disclaimer_checkbox.toggled.connect( self.set_org_disclaimer) self.custom_organisation_logo_check_box.toggled.connect( self.toggle_logo_path) # Buttons self.toolKeywordCachePath.clicked.connect(self.open_keyword_cache_path) self.toolUserDirectoryPath.clicked.connect( self.open_user_directory_path) self.toolNorthArrowPath.clicked.connect(self.open_north_arrow_path) self.open_organisation_logo_path_button.clicked.connect( self.open_organisation_logo_path) self.toolReportTemplatePath.clicked.connect( self.open_report_template_path) # Others self.organisation_logo_path_line_edit.textChanged.connect( self.update_logo_preview) self.earthquake_function.currentIndexChanged.connect( self.update_earthquake_info) # Set up listener for restore defaults button self.demographic_restore_defaults = self.button_box_restore_defaults.\ button(QDialogButtonBox.RestoreDefaults) self.demographic_restore_defaults.setText( self.demographic_restore_defaults.text().capitalize()) self.demographic_restore_defaults.setCheckable(True) self.demographic_restore_defaults.clicked.connect( self.restore_defaults_ratio) # Restore button in population parameter tab self.parameter_population_restore_button = \ self.button_box_restore_preference.button( QDialogButtonBox.RestoreDefaults) self.parameter_population_restore_button.setText( self.parameter_population_restore_button.text().capitalize()) self.parameter_population_restore_button.clicked.connect( partial(self.restore_population_parameters, global_default=True)) # TODO: Hide this until behaviour is defined # hide template warning toggle self.template_warning_checkbox.hide() # hide custom template dir toggle self.custom_templates_dir_checkbox.hide() self.splitter_custom_report.hide() # Welcome message self.set_welcome_message()
def layer_description_html(layer, keywords=None): """Form a html description of a given layer based on the layer parameters and keywords if provided :param layer: The layer to get the description :type layer: QgsMapLayer :param keywords: The layer keywords :type keywords: None, dict :returns: The html description in tabular format, ready to use in a label or tool tip. :rtype: str """ if keywords and 'keyword_version' in keywords: keyword_version = str(keywords['keyword_version']) else: keyword_version = None if (keywords and keyword_version and is_keyword_version_supported(keyword_version)): # The layer has valid keywords purpose = keywords.get('layer_purpose') if purpose == layer_purpose_hazard['key']: subcategory = '<tr><td><b>%s</b>: </td><td>%s</td></tr>' % ( tr('Hazard'), keywords.get(purpose)) unit = keywords.get('continuous_hazard_unit') elif purpose == layer_purpose_exposure['key']: subcategory = '<tr><td><b>%s</b>: </td><td>%s</td></tr>' % ( tr('Exposure'), keywords.get(purpose)) unit = keywords.get('exposure_unit') else: subcategory = '' unit = None if keywords.get('layer_mode') == layer_mode_classified['key']: unit = tr('classified data') if unit: unit = '<tr><td><b>%s</b>: </td><td>%s</td></tr>' % ( tr('Unit'), unit) desc = """ <table border="0" width="100%%"> <tr><td><b>%s</b>: </td><td>%s</td></tr> <tr><td><b>%s</b>: </td><td>%s</td></tr> %s %s <tr><td><b>%s</b>: </td><td>%s</td></tr> </table> """ % (tr('Title'), keywords.get('title'), tr('Purpose'), keywords.get('layer_purpose'), subcategory, unit, tr('Source'), keywords.get('source')) elif keywords: # The layer has keywords, but the version is wrong layer_version = keyword_version or tr('No Version') desc = tr( 'Your layer\'s keyword\'s version ({layer_version}) does not ' 'match with your InaSAFE version ({inasafe_version}). If you wish ' 'to use it as an exposure, hazard, or aggregation layer in an ' 'analysis, please update the keywords. Click Next if you want to ' 'assign keywords now.').format( layer_version=layer_version, inasafe_version=get_version()) else: # The layer is keywordless if is_point_layer(layer): geom_type = 'point' elif is_polygon_layer(layer): geom_type = 'polygon' else: geom_type = 'line' # hide password in the layer source source = layer.publicSource() desc = """ %s<br/><br/> <b>%s</b>: %s<br/> <b>%s</b>: %s<br/><br/> %s """ % (tr('This layer has no valid keywords assigned'), tr('SOURCE'), source, tr('TYPE'), is_raster_layer(layer) and 'raster' or 'vector (%s)' % geom_type, tr('In the next step you will be able' + ' to assign keywords to this layer.')) return desc