def content():
    """Helper method that returns just the content.

    This method was added so that the text could be reused in the
    dock_help module.

    .. versionadded:: 3.2.2

    :returns: A message object without brand element.
    :rtype: safe.messaging.message.Message
    """
    message = m.Message()
    paragraph = m.Paragraph(m.Image('file:///%s/img/screenshots/'
                                    'batch-calculator-screenshot.png' %
                                    resources_path()),
                            style_class='text-center')
    message.add(paragraph)
    message.add(
        m.Paragraph(
            tr('Depending on which Impact Function you have chosen you have '
               'different options available for adjusting the parameters of the '
               'question you are asking. Some Impact Functions have more '
               'configurable Options than others. To open the Impact Function '
               'Configuration Dialog you need to click on the "Options ..." '
               'button next to the selected impact function paragraph in the '
               'InaSAFE dock. You can have up to 3 tabs visible:')))

    bullets = m.BulletedList()
    bullets.add(
        m.Text(
            m.ImportantText(tr('Options')),
            tr('- Depending in the Impact function you selected, you can '
               'influence the result of your question here (the Impact Function) '
               'by setting different values to the defaults that will be loaded. '
               'The options available will depend on the Impact Function you '
               'choose (some Impact Functions do not allow users to change the '
               'default parameters).')))
    bullets.add(
        m.Text(
            m.ImportantText(tr('Post-processors')),
            tr('- Takes the results from the Impact Function and calculates '
               'derivative indicators, for example if you have an affected '
               'population total, the Gender postprocessor will calculate gender '
               'specific indicators such as additional nutritional requirements '
               'for pregnant women.')))
    bullets.add(
        m.Text(
            m.ImportantText(tr('Minimum Needs')),
            tr('- If the analysis uses population exposure, InaSAFE calculates '
               'the minimum needs of the people affected by the impact scenario. '
               'You should refer to the minimum needs tool for configuring the '
               'global defaults used in these calculations. '),
            m.Image(
                'file:///%s/img/icons/'
                'show-minimum-needs.svg' % resources_path(),
                **SMALL_ICON_STYLE),
            tr(' This panel will let you override global defaults for a specific '
               'analysis run.')))
    message.add(bullets)
    return message
Beispiel #2
0
def content():
    """Helper method that returns just the content.

    This method was added so that the text could be reused in the
    dock_help module.

    .. versionadded:: 4.1.0

    :returns: A message object without brand element.
    :rtype: safe.messaging.message.Message
    """
    message = m.Message()
    paragraph = m.Paragraph(m.Image('file:///%s/img/screenshots/'
                                    'field-mapping-tool-screenshot.png' %
                                    resources_path()),
                            style_class='text-center')
    message.add(paragraph)

    paragraph = m.Paragraph(
        tr('This tool allows you to define field mappings to use for demographic '
           'breakdowns of your analysis results. You can activate the '
           'tool on the InaSAFE toolbar:'),
        m.Image(
            'file:///%s/img/icons/'
            'show-mapping-tool.svg' % resources_path(), **SMALL_ICON_STYLE),
    )
    message.add(paragraph)
    message.add(field_mapping_help_content())
    return message
Beispiel #3
0
def show_keywords_need_review_message(sender, message=None):
    """Show a message keywords are not adequate to run an analysis.

    .. versionadded: 4.0

    :param sender: Sender of the message signal. Default to Any object.
    :type sender: object

    :param message: Additional message to display.
    :type message: str

    .. note:: The print button will be disabled if this method is called.
    """
    LOGGER.debug('Showing incorrect keywords for v4 message')
    message = generate_input_error_message(
        tr('Layer Keywords Outdated:'),
        m.Paragraph(
            tr('Please update the keywords for your layers and then '
               'try to run the analysis again. Use the keyword wizard '),
            m.Image(
                'file:///%s/img/icons/'
                'show-keyword-wizard.svg' % resources_path(),
                **SMALL_ICON_STYLE),
            tr(' icon in the toolbar to update your layer\'s keywords.'),
            message))
    send_static_message(sender, message)
Beispiel #4
0
def show_keyword_version_message(sender, keyword_version, inasafe_version):
    """Show a message indicating that the keywords version is mismatch

    .. versionadded: 3.2

    :param keyword_version: The version of the layer's keywords
    :type keyword_version: str

    :param inasafe_version: The version of the InaSAFE
    :type inasafe_version: str

    .. note:: The print button will be disabled if this method is called.
    """
    LOGGER.debug('Showing Mismatch Version Message')
    message = generate_input_error_message(
        tr('Layer Keyword\'s Version Mismatch:'),
        m.Paragraph(
            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 use the keyword wizard to update the '
               'keywords. You can open the wizard by clicking on '
               'the ').format(layer_version=keyword_version,
                              inasafe_version=inasafe_version),
            m.Image(
                'file:///%s/img/icons/'
                'show-keyword-wizard.svg' % resources_path(),
                **SMALL_ICON_STYLE), tr(' icon in the toolbar.')))
    send_static_message(sender, message)
Beispiel #5
0
def missing_keyword_message(sender, missing_keyword_exception):
    """Display an error when there is missing keyword.

    :param sender: The sender.
    :type sender: object

    :param missing_keyword_exception: A KeywordNotFoundError exception.
    :type missing_keyword_exception: KeywordNotFoundError

    """
    warning_heading = m.Heading(tr('Missing Keyword'), **WARNING_STYLE)
    warning_message = tr(
        'There is missing keyword that needed for this analysis.')
    detail_heading = m.Heading(tr('Detail'), **DETAILS_STYLE)
    suggestion_heading = m.Heading(tr('Suggestion'), **DETAILS_STYLE)
    detail = tr('The layer <b>%s</b> is missing the keyword <i>%s</i>.' %
                (missing_keyword_exception.layer_name,
                 missing_keyword_exception.keyword))
    suggestion = m.Paragraph(
        tr('Please use the keyword wizard to update the keywords. You '
           'can open the wizard by clicking on the '),
        m.Image(
            'file:///%s/img/icons/'
            'show-keyword-wizard.svg' % resources_path(), **SMALL_ICON_STYLE),
        tr(' icon in the toolbar.'))

    message = m.Message()
    message.add(warning_heading)
    message.add(warning_message)
    message.add(detail_heading)
    message.add(detail)
    message.add(suggestion_heading)
    message.add(suggestion)
    send_static_message(sender, message)
Beispiel #6
0
def content():
    """Helper method that returns just the content.

    This method was added so that the text could be reused in the
    dock_help module.

    .. versionadded:: 4.0.0

    :returns: A message object without brand element.
    :rtype: safe.messaging.message.Message
    """
    message = m.Message()
    paragraph = m.Paragraph(
        m.Image(
            'file:///%s/img/screenshots/'
            'multi-buffer-screenshot.png' % resources_path()),
        style_class='text-center'
    )
    message.add(paragraph)
    message.add(m.Paragraph(tr(
        'This tool will generate a polygon layer by multi-buffering the input '
        'layer. '
        'To use this tool effectively:'
    )))
    tips = m.BulletedList()
    tips.add(tr(
        'Load a point or line layer in QGIS. Typically, the layer will '
        'represent hazard source such as volcano and river.'
    ))
    tips.add(tr(
        'Choose where to save the output layer to.'
    ))
    tips.add(tr(
        'Create one or more entries in the classes list, and define '
        'the appropriate distances for each buffer. You should give '
        'each buffer distance a corresponding name '
        'e.g. "high", "medium", "low". Click the add (+) button to '
        'record your entries.'
    ))
    tips.add(tr(
        'To remove the classification, select the classification you want to '
        'remove, then click the remove (-) button.'
    ))
    tips.add(tr(
        'Check the "launch keywords wizard" checkbox to launch the keywords '
        'creation wizard after the buffering is complete. If you want assign '
        'keywords later, uncheck the "launch keywords wizard" checkbox.'
    ))
    tips.add(tr(
        'A new layer will be added to QGIS after the buffering is complete. '
        'The layer will contain new buffer polygon(s) and the class name will '
        'be stored as an attribute of each polygon. If you check the '
        'launch keywords wizard checkbox, the keywords creation wizard will '
        'launch right after the buffering process has completed. '
        'You can assign the keywords to the output layer.'
    ))
    message.add(tips)
    return message
def content():
    """Helper method that returns just the content.

    This method was added so that the text could be reused in the
    dock_help module.

    .. versionadded:: 3.2.3

    :returns: A message object without brand element.
    :rtype: safe.messaging.message.Message
    """
    message = m.Message()
    paragraph = m.Paragraph(m.Image('file:///%s/img/screenshots/'
                                    'petabencana-screenshot.png' %
                                    resources_path()),
                            style_class='text-center')
    message.add(paragraph)
    link = m.Link('https://petabencana.id', 'PetaBencana.id')
    body = m.Paragraph(
        tr('This tool will fetch current flood data for Jakarta from '), link)
    tips = m.BulletedList()
    tips.add(
        tr('Check the output directory is correct. Note that the saved '
           'dataset will be called jakarta_flood.shp (and associated files).'))
    tips.add(
        tr('If you wish you can specify a prefix to '
           'add in front of this default name. For example using a prefix '
           'of \'foo-\' will cause the downloaded files to be saved as e.g. '
           '\'foo-rw-jakarta-flood.shp\'. Note that the only allowed prefix '
           'characters are A-Z, a-z, 0-9 and the characters \'-\' and \'_\'. '
           'You can leave this blank if you prefer.'))
    tips.add(
        tr('If a dataset already exists in the output directory it will be '
           'overwritten if the "overwrite existing files" checkbox is ticked.')
    )
    tips.add(
        tr('If the "include date/time in output filename" option is ticked, '
           'the filename will be prefixed with a time stamp e.g. '
           '\'foo-22-Mar-2015-08-01-2015-rw-jakarta-flood.shp\' where the date '
           'timestamp is in the form DD-MMM-YYYY.'))
    tips.add(
        tr('This tool requires a working internet connection and fetching '
           'data will consume your bandwidth.'))
    tips.add(
        m.Link(production_api['help_url'],
               text=tr(
                   'Downloaded data is copyright the PetaBencana contributors'
                   ' (click for more info).')))
    message.add(body)
    message.add(tips)
    return message
Beispiel #8
0
def content():
    """Helper method that returns just the content.

    This method was added so that the text could be reused in the
    dock_help module.

    .. versionadded:: 3.2.2

    :returns: A message object without brand element.
    :rtype: safe.messaging.message.Message
    """
    message = m.Message()
    paragraph = m.Paragraph(m.Image('file:///%s/img/screenshots/'
                                    'analysis-area-screenshot.png' %
                                    resources_path()),
                            style_class='text-center')
    message.add(paragraph)

    paragraph = m.Paragraph(
        tr('This tool allows you to specify which geographical region should be '
           'used for your analysis. If you want to check what area will be '
           'included in your analysis, enable the \'Toggle scenario outlines\' '
           'tool on the InaSAFE toolbar:'),
        m.Image(
            'file:///%s/img/icons/'
            'toggle-rubber-bands.svg' % resources_path(), **SMALL_ICON_STYLE),
    )
    message.add(paragraph)
    paragraph = m.Paragraph(
        tr('Your user defined extent will be shown on the map as a rectangle. '
           'There are a number of different modes that can be used which are '
           'described below:'))
    message.add(paragraph)

    message.add(extent_mode_content())

    return message
Beispiel #9
0
def getting_started_message():
    """Generate a message for initial application state.

    :returns: Information for the user on how to get started.
    :rtype: safe.messaging.Message
    """
    message = m.Message()
    message.add(LOGO_ELEMENT)
    message.add(m.Heading(tr('Getting started'), **INFO_STYLE))
    notes = m.Paragraph(
        tr(
            'These are the minimum steps you need to follow in order '
            'to use InaSAFE:'))
    message.add(notes)
    basics_list = m.NumberedList()
    basics_list.add(m.Paragraph(
        tr('Add at least one '),
        m.ImportantText(tr('hazard'), **KEYWORD_STYLE),
        tr(' layer (e.g. earthquake MMI) to QGIS.')))
    basics_list.add(m.Paragraph(
        tr('Add at least one '),
        m.ImportantText(tr('exposure'), **KEYWORD_STYLE),
        tr(' layer (e.g. structures) to QGIS.')))
    basics_list.add(m.Paragraph(
        tr(
            'Make sure you have defined keywords for your hazard and '
            'exposure layers. You can do this using the '
            'keywords creation wizard '),
        m.Image(
            'file:///%s/img/icons/show-keyword-wizard.svg' %
            (resources_path()), **SMALL_ICON_STYLE),
        tr(' in the toolbar.')))
    basics_list.add(m.Paragraph(
        tr('Click on the '),
        m.ImportantText(tr('Run'), **KEYWORD_STYLE),
        tr(' button below.')))
    message.add(basics_list)

    message.add(m.Heading(tr('Limitations'), **WARNING_STYLE))
    caveat_list = m.NumberedList()
    for limitation in limitations():
        caveat_list.add(limitation)
    message.add(caveat_list)

    message.add(m.Heading(tr('Disclaimer'), **WARNING_STYLE))
    message.add(m.Paragraph(disclaimer()))

    return message
Beispiel #10
0
def content():
    """Helper method that returns just the content.

    This method was added so that the text could be reused in the
    dock_help module.

    .. versionadded:: 3.2.2

    :returns: A message object without brand element.
    :rtype: safe.messaging.message.Message
    """

    message = m.Message()
    paragraph = m.Paragraph(
        m.Image(
            'file:///%s/img/screenshots/'
            'shakemap-converter-screenshot.png' % resources_path()),
        style_class='text-center'
    )
    message.add(paragraph)
    body = tr(
        'This tool will convert an earthquake \'shakemap\' that is in '
        'grid xml format into a GeoTIFF file. The imported file can be used '
        'in InaSAFE as an input for impact functions that require an '
        'earthquake layer.  To use this tool effectively:')
    message.add(body)
    tips = m.BulletedList()
    tips.add(tr(
        'Select a grid.xml for the input layer.'))
    tips.add(tr(
        'Choose where to write the output layer to.'
    ))
    tips.add(tr(
        'Choose the interpolation algorithm that should be used when '
        'converting the xml grid to a raster. If unsure keep the default.'
    ))
    tips.add(tr(
        'If you want to obtain shake data you can get download it free from '
        'the USGS shakemap site: '
        'http://earthquake.usgs.gov/earthquakes/shakemap/list.php?y=2013'))

    message.add(tips)
    return message
Beispiel #11
0
def content():
    """Helper method that returns just the content.

    This method was added so that the text could be reused in the
    dock_help module.

    .. versionadded:: 3.2.2

    :returns: A message object without brand element.
    :rtype: safe.messaging.message.Message
    """
    message = m.Message()
    paragraph = m.Paragraph(
        m.Image(
            'file:///%s/img/screenshots/'
            'needs-calculator-screenshot.png' % resources_path()),
        style_class='text-center'
    )
    message.add(paragraph)
    message.add(m.Paragraph(tr(
        'This tool will calculated minimum needs for evacuated people. To '
        'use this tool effectively:'
    )))
    tips = m.BulletedList()
    tips.add(tr(
        'Load a point or polygon layer in QGIS. Typically the layer will '
        'represent administrative districts where people have gone to an '
        'evacuation center.'))
    tips.add(tr(
        'Ensure that the layer has an INTEGER attribute for the number of '
        'displaced people associated with each feature.'
    ))
    tips.add(tr(
        'Use the pick lists to select the layer and the population '
        'field and then press \'OK\'.'
    ))
    tips.add(tr(
        'A new layer will be added to QGIS after the calculation is '
        'complete. The layer will contain the minimum needs per district '
        '/ administrative boundary.'))
    message.add(tips)
    return message
Beispiel #12
0
def show_no_keywords_message(sender):
    """Show a message indicating that no keywords are defined.

    .. note:: The print button will be disabled if this method is called.
    """
    LOGGER.debug('Showing No Keywords Message')
    message = generate_input_error_message(
        tr('Layer keywords missing:'),
        m.Paragraph(
            tr('No keywords have been defined for this layer yet or there is '
               'an issue with the currently defined keywords and they need '
               'to be reviewed. If you wish to use this layer as an '
               'exposure, hazard, or aggregation layer in an analysis, '
               'please use the keyword wizard to update the keywords. You '
               'can open the wizard by clicking on the '),
            m.Image(
                'file:///%s/img/icons/'
                'show-keyword-wizard.svg' % resources_path(),
                **SMALL_ICON_STYLE), tr(' icon in the toolbar.')))
    send_static_message(sender, message)
Beispiel #13
0
def content():
    """Helper method that returns just the content.

    This method was added so that the text could be reused in the
    other contexts.

    .. versionadded:: 3.2.2

    :returns: A message object without brand element.
    :rtype: safe.messaging.message.Message
    """

    message = m.Message()
    paragraph = m.Paragraph(
        m.Image(
            'file:///%s/img/screenshots/'
            'batch-calculator-screenshot.png' % resources_path()),
        style_class='text-center'
    )
    message.add(paragraph)

    message.add(m.Paragraph(tr(
        'With this tool you can set up numerous scenarios and run them all in '
        'one go. A typical use case may be where you define a number of e.g. '
        'flood impact scenarios all using a standard data set e.g. '
        'flood.shp. As new flood data becomes available you replace flood.shp '
        'and rerun the scenarios using the batch runner. Using this approach '
        'you can quickly produce regional contingency plans as your '
        'understanding of hazards changes. When you run the batch of '
        'scenarios, pdf reports are generated automatically and all placed in '
        'a single common directory making it easy for you to browse and '
        'disseminate the reports produced.')))

    message.add(m.Paragraph(tr(
        'When the batch process completes, it will also produce a summary '
        'report like this:')))

    table = m.Table(style_class='table table-condensed table-striped')
    row = m.Row(m.Cell(tr('InaSAFE Batch Report File')), header=True)
    table.add(row)
    table.add(m.Row(m.Cell('P: gempa bumi Sumatran fault (Mw7.8)')))
    table.add(m.Row(m.Cell('P: gempa di Yogya tahun 2006')))
    table.add(m.Row(m.Cell('P: banjir jakarta 2007')))
    table.add(m.Row(m.Cell('P: Tsunami di Maumere (Mw 8.1)')))
    table.add(m.Row(m.Cell('P: gempa Mw6.5 Palu-Koro Fault')))
    table.add(m.Row(m.Cell('P: gunung merapi meletus')))
    table.add(m.Row(m.Cell('-----------------------------')))
    table.add(m.Row(m.Cell(tr('Total passed: 6'))))
    table.add(m.Row(m.Cell(tr('Total failed: 0'))))
    table.add(m.Row(m.Cell(tr('Total tasks: 6'))))

    message.add(table)

    # message.add(m.Paragraph(tr(
    #     'For advanced users there is also the ability to batch run python '
    #     'scripts using this tool, but this should be considered an '
    #     'experimental</strong> feature still at this stage.')))

    message.add(m.Paragraph(tr(
        'Before running the Batch Runner you might want to use the \'save '
        'scenario\' tool to first save some scenarios on which you '
        'can let the batch runner do its work. This tool lets you run saved '
        'scenarios in one go. It lets you select scenarios or let run all '
        'scenarios in one go.')))
    return message
Beispiel #14
0
def content():
    """Helper method that returns just the content.

    This method was added so that the text could be reused in the
    dock_help module.

    .. versionadded:: 3.2.2

    :returns: A message object without brand element.
    :rtype: safe.messaging.message.Message
    """
    message = m.Message()
    message.add(
        m.Paragraph(
            tr('The InaSAFE options dialog is used to control various aspects of '
               'the InaSAFE analysis and reporting environment. Here are brief '
               'descriptions of all the options available, grouped by the tab '
               'page on which they occur.')))

    header = m.Heading(tr('Organisation Profile tab'), **INFO_STYLE)
    message.add(header)

    paragraph = m.Paragraph(m.Image(
        'file:///%s/img/screenshots/'
        'inasafe-options-organisation-screenshot.png' % resources_path()),
                            style_class='text-center')

    message.add(paragraph)
    message.add(
        m.Paragraph(
            tr('The Organisation Profile tab provides several general settings:'
               )))
    bullets = m.BulletedList()
    bullets.add(
        m.Text(
            m.ImportantText(tr('Organisation')),
            tr(' - Use this option to specify the name of your organisation.'))
    )
    bullets.add(
        m.Text(
            m.ImportantText(tr('Contact email')),
            tr(' - Use this option to specify the contact person\'s email '
               'address to use in the generated metadata document.')))
    bullets.add(
        m.Text(
            m.ImportantText(tr('Website')),
            tr(' - Use this option to set the website address to be used in '
               'the generated metadata document.')))
    bullets.add(
        m.Text(
            m.ImportantText(tr('Use custom organisation logo')),
            tr(' - By default, InaSAFE will add the supporters logo to each '
               'map template. The supporters logo is also used at tbe bottom '
               'of the dock panel if the \'show organisation logo in dock\' '
               'option is enabled. You can use this option to replace the '
               'organisation logo with that of your own organisation. The logo '
               'will be rescaled automatically to fill the space provided.')))
    bullets.add(
        m.Text(
            m.ImportantText(tr('Currency')),
            tr(' - InaSAFE will use the selected currency for the analysis.')))
    bullets.add(
        m.Text(
            m.ImportantText(tr('Analysis license')),
            tr(' - Use this to set the usage and redistribution license for the '
               'generated impact layer.')))
    message.add(bullets)

    header = m.Heading(tr('Population Parameters tab'), **INFO_STYLE)
    message.add(header)

    paragraph = m.Paragraph(m.Image(
        'file:///%s/img/screenshots/'
        'inasafe-options-population-screenshot.png' % resources_path()),
                            style_class='text-center')
    message.add(paragraph)

    message.add(
        m.Paragraph(
            tr('In this tab you can define some parameters that will be used by '
               'InaSAFE in the analysis of exposed populations. You have the option '
               'to change the parameters for whether the exposed population is '
               'considered to be affected by each hazard type and class, and the '
               'displacement rate that will be used for affected people.')))

    bullets = m.BulletedList()
    bullets.add(
        m.Text(
            m.ImportantText(tr('Affected')),
            tr(' - When this option is checked, people exposed to the hazard '
               'class will be included in the count of affected people.')))

    bullets.add(
        m.Text(
            m.ImportantText(tr('Displacement Rate')),
            tr(' - The displacement rate is used to estimate the number of '
               'people displaced for each hazard class. People must be affected '
               'before they can be displaced. ')))
    message.add(bullets)
    message.add(
        m.Paragraph(
            tr('Please refer to the InaSAFE manual for concept definitions and '
               'more information on the source of the hazard classifications and '
               'default settings. We really encourage you to consider these '
               'parameters carefully and to choose appropriate values for your '
               'local situation based on past events and expert knowledge.')))

    header = m.Heading(tr('GIS Environment tab'), **INFO_STYLE)
    message.add(header)
    paragraph = m.Paragraph(m.Image(
        'file:///%s/img/screenshots/'
        'inasafe-options-environment-screenshot.png' % resources_path()),
                            style_class='text-center')
    message.add(paragraph)

    message.add(
        m.Paragraph(
            tr('The GIS Environment tab provides several general settings:')))

    bullets = m.BulletedList()

    bullets.add(
        m.Text(
            m.ImportantText(
                tr('Always show welcome message when opening QGIS with InaSAFE'
                   )),
            tr(' - When this option is enabled, the welcome message will be '
               'enabled when opening QGIS with InaSAFE. By default the Welcome '
               'message will be displayed.')))
    bullets.add(
        m.Text(
            m.ImportantText(tr('Show organisation logo in InaSAFE dock')),
            tr(' - When this option is enabled, a logo will be displayed at the '
               'bottom of the InaSAFE dock widget. By default the logo used '
               'is the InaSAFE supporters logo, but you can alter this by '
               'setting the \'Use custom organisation logo\' option in '
               'the template options tab (see below).')))
    bullets.add(
        m.Text(
            m.ImportantText(
                tr('Show only visible layers in the InaSAFE dock')),
            tr(' - When this option is enabled layers that are not visible '
               'in the QGIS layers panel will not be shown in the hazard, '
               'exposure and aggregation combo boxes in the dock area.')))
    bullets.add(
        m.Text(
            m.ImportantText(tr('Set QGIS layer name from title in keywords')),
            tr(' - If this option is enabled, the InaSAFE keywords title '
               'attribute will be used for the layer name in the QGIS Layers list '
               'when adding a layer.')))
    bullets.add(
        m.Text(
            m.ImportantText(
                tr('Zoom to impact layer on scenario estimate completion')),
            tr(' - When this option is enabled, the map view extents will '
               'be updated to match the extents of the generated impact layer '
               'once the analysis completes.')))
    bullets.add(
        m.Text(
            m.ImportantText(
                tr('Hide exposure on scenario estimate completion')),
            tr(' - Use this option if you prefer to not show the exposure '
               'layer as an underlay behind the generated impact layer.')))
    bullets.add(
        m.Text(
            m.ImportantText(tr('Show only impact layer on report map')),
            tr('When this option is enabled, the map report created after an '
               'analysis completes will not show any other layers in your '
               'current project except for the impact layer. ')))
    bullets.add(
        m.Text(
            m.ImportantText(
                tr('Print atlas report on atlas driven template with the '
                   'aggregation layer')),
            tr('When this option is enabled, InaSAFE will generate an atlas '
               'report based on aggregation area if the template has atlas '
               'generation flag enabled.')))
    bullets.add(
        m.Text(
            m.ImportantText(
                tr('Use selected features only with the aggregation layer')),
            tr('If enabled, running an analysis with some features of the '
               'aggregation layer selected will constrain the analysis to only '
               'those selected aggregation areas, all others will be ignored.')
        ))
    bullets.add(
        m.Text(
            m.ImportantText(tr('Location for results')),
            tr(' - By default, InaSAFE will write impact layer and intermediate '
               'outputs to the system temporary directory. On some operating '
               'systems, these temporary files will be deleted on each reboot. '
               'If you wish to, you can specify an alternative directory '
               'to use for storing these temporary files.')))
    message.add(bullets)

    header = m.Heading(tr('Earthquake tab'), **INFO_STYLE)
    message.add(header)
    paragraph = m.Paragraph(m.Image(
        'file:///%s/img/screenshots/'
        'inasafe-options-earthquake-screenshot.png' % resources_path()),
                            style_class='text-center')
    message.add(paragraph)
    paragraph = m.Paragraph(
        tr('In this tab you can select which earthquake fatality model to use '
           'when estimating earthquake impact on population. This option is '
           'global - it will affect all subsequent earthquake analyses carried '
           'out in InaSAFE.'))
    message.add(paragraph)
    paragraph = m.Paragraph(
        tr('When selecting an earthquake analysis model, its details will be '
           'shown below in the text box area.'))
    message.add(paragraph)

    header = m.Heading(tr('Template Options tab'), **INFO_STYLE)
    message.add(header)
    paragraph = m.Paragraph(m.Image('file:///%s/img/screenshots/'
                                    'inasafe-options-template-screenshot.png' %
                                    resources_path()),
                            style_class='text-center')
    message.add(paragraph)

    message.add(
        m.Paragraph(
            tr('This tab has options relating to the generation of map composer '
               'templates and how reports will be printed:'
               '.')))

    bullets = m.BulletedList()

    bullets.add(
        m.Text(
            m.ImportantText(tr('Use custom north arrow image')),
            tr(' - InaSAFE provides a basic north arrow which is placed on '
               'generated map compositions and rendered PDF reports. You can '
               'replace this north arrow with one of your own choosing using '
               'this option.')))
    bullets.add(
        m.Text(
            m.ImportantText(tr('Use custom disclaimer text')),
            tr(' - By default, InaSAFE will display a disclaimer on reports '
               'advising readers of the report to exercise caution when '
               'interpreting the outputs presented. You can override this '
               'text using this option, though we do advise that you include '
               'a similar statement of caution in your overridden text.')))
    message.add(bullets)

    header = m.Heading(tr('Demographic Defaults tab'), **INFO_STYLE)
    message.add(header)
    paragraph = m.Paragraph(m.Image(
        'file:///%s/img/screenshots/'
        'inasafe-options-demographic-screenshot.png' % resources_path()),
                            style_class='text-center')
    message.add(paragraph)
    paragraph = m.Paragraph(
        tr('In this tab you will find options for setting the default ratios '
           'for demographic groups. There is more detailed help on demographic '
           'groups within the main help page for InaSAFE in the Field Mapping '
           'Tool section. Essentially default ratios for demographic groups '
           'determine what proportion of the population are within each '
           'population group (e.g. infants versus children etc.). The options '
           'defined in this tab are used in cases where you choose to use the '
           'global default ratios while configuring the keywords for an '
           'aggregation layer as shown below.'))
    message.add(paragraph)
    paragraph = m.Paragraph(
        tr('Note that the contents of this tab may changed depending on what '
           'groups have been defined for demographic breakdowns.'))
    message.add(paragraph)
    paragraph = m.Paragraph(m.Image(
        'file:///%s/img/screenshots/'
        'field-mapping-tool-default-ratios-screenshot.png' % resources_path()),
                            style_class='text-center')
    message.add(paragraph)

    header = m.Heading(tr('Advanced tab'), **INFO_STYLE)
    message.add(header)
    paragraph = m.Paragraph(m.Image('file:///%s/img/screenshots/'
                                    'inasafe-options-advanced-screenshot.png' %
                                    resources_path()),
                            style_class='text-center')
    message.add(paragraph)

    message.add(
        m.Paragraph(
            tr('This tab contains options intended for advanced users only: '))
    )

    bullets = m.BulletedList()
    bullets.add(
        m.Text(
            m.ImportantText(tr('Keyword cache for remote databases')),
            tr(' - When InaSAFE is used with remote layers (for example a '
               'database layer or a WFS layer), it is not possible to store the '
               'keywords for the layer with the layer itself. To accommodate for '
               'these types of layers, InaSAFE writes the keywords to a small '
               'file based database (using sqlite) and then retrieves them based '
               'on unique connection details used for that layer. You can '
               'specify a custom path to be used for storing the keywords '
               'database using this option.')))
    bullets.add(
        m.Text(
            m.ImportantText(
                tr('Help to improve InaSAFE by submitting errors to a '
                   'remote server')),
            tr(' - With this option enabled, InaSAFE will post any errors that '
               'occur to an online server for analysis by our development team. '
               'This option is disabled by default as some may consider some of '
               'the data submitted (IP Address, logged in user name) to be '
               'sensitive.')))
    bullets.add(
        m.Text(
            m.ImportantText(tr('Enable developer mode')),
            tr(' - When this option is enabled, right clicking on the webview '
               'widget in the dock will allow you to debug the generated HTML. '
               'In addition, if the metadata.txt for the running InaSAFE is '
               'set to \'alpha\', an additional icon will be added to the '
               'toolbar to add test layers to the QGIS project.')))
    bullets.add(
        m.Text(
            m.ImportantText(tr('Generate reports')),
            tr(' - When this option is enabled, InaSAFE will generate reports. '
               )))
    bullets.add(
        m.Text(
            m.ImportantText(tr('Show memory profile')),
            tr(' - When this option is enabled, InaSAFE will display the memory '
               'profile when it runs. ')))

    message.add(bullets)

    return message
Beispiel #15
0
def definition_to_message(definition, heading_style=None):
    """Helper function to render a definition to a message.

    :param definition: A definition dictionary (see definitions package).
    :type definition: dict

    :param heading_style: Optional style to apply to the definition
        heading. See safe.messaging.styles
    :type heading_style: dict


    :returns: Message
    :rtype: str
    """

    if heading_style:
        header = m.Heading(definition['name'], **heading_style)
    else:
        header = m.Paragraph(m.ImportantText(definition['name']))
    message = m.Message()
    message.add(header)
    # If the definition has an icon, we put the icon and description side by
    # side in a table otherwise just show the description as a paragraph
    url = _definition_icon_url(definition)
    if url is None:
        LOGGER.info('No URL for definition icon')
        message.add(m.Paragraph(definition['description']))
        for citation in definition['citations']:
            if citation['text'] in [None, '']:
                continue
            if citation['link'] in [None, '']:
                message.add(m.Paragraph(citation['text']))
            else:
                message.add(
                    m.Paragraph(m.Link(citation['link'], citation['text'])))
    else:
        LOGGER.info('Creating mini table for definition description: ' + url)
        table = m.Table(style_class='table table-condensed')
        row = m.Row()
        row.add(m.Cell(m.Image(url, **MEDIUM_ICON_STYLE)))
        row.add(m.Cell(definition['description']))
        table.add(row)
        for citation in definition['citations']:
            if citation['text'] in [None, '']:
                continue
            row = m.Row()
            row.add(m.Cell(''))
            if citation['link'] in [None, '']:
                row.add(m.Cell(citation['text']))
            else:
                row.add(m.Cell(m.Link(citation['link'], citation['text'])))
            table.add(row)
        message.add(table)

    url = _definition_screenshot_url(definition)
    if url:
        message.add(m.Image(url))

    # types contains e.g. hazard_all
    if 'types' in definition:
        for sub_definition in definition['types']:
            message.add(
                definition_to_message(sub_definition, RED_CHAPTER_STYLE))

    #
    # Notes section if available
    #

    if 'notes' in definition:
        # Start a notes details group too since we have an exposure
        message.add(m.Heading(tr('Notes:'), **DETAILS_STYLE))
        message.add(m.Heading(tr('General notes:'), **DETAILS_SUBGROUP_STYLE))
        bullets = m.BulletedList()
        for note in definition['notes']:
            bullets.add(m.Text(note))
        message.add(bullets)

    # This only for EQ
    if 'earthquake_fatality_models' in definition:
        for model in definition['earthquake_fatality_models']:
            message.add(m.Heading(model['name'], **DETAILS_SUBGROUP_STYLE))
            bullets = m.BulletedList()
            for note in model['notes']:
                bullets.add(m.Text(note))
                message.add(bullets)

    for exposure in exposure_all:
        extra_exposure_notes = specific_notes(definition, exposure)
        if extra_exposure_notes:
            title = tr(u'Notes for exposure : {exposure_name}').format(
                exposure_name=exposure['name'])
            message.add(m.Heading(title, **DETAILS_SUBGROUP_STYLE))
            bullets = m.BulletedList()
            for note in extra_exposure_notes:
                bullets.add(m.Text(note))
            message.add(bullets)

    if 'continuous_notes' in definition:
        message.add(
            m.Heading(tr('Notes for continuous datasets:'),
                      **DETAILS_SUBGROUP_STYLE))
        bullets = m.BulletedList()
        for note in definition['continuous_notes']:
            bullets.add(m.Text(note))
        message.add(bullets)

    if 'classified_notes' in definition:
        message.add(
            m.Heading(tr('Notes for classified datasets:'),
                      **DETAILS_SUBGROUP_STYLE))
        bullets = m.BulletedList()
        for note in definition['classified_notes']:
            bullets.add(m.Text(note))
        message.add(bullets)

    if 'single_event_notes' in definition:
        message.add(m.Heading(tr('Notes for single events'), **DETAILS_STYLE))
        if len(definition['single_event_notes']) < 1:
            message.add(m.Paragraph(tr('No single event notes defined.')))
        else:
            bullets = m.BulletedList()
            for note in definition['single_event_notes']:
                bullets.add(m.Text(note))
            message.add(bullets)

    if 'multi_event_notes' in definition:
        message.add(
            m.Heading(tr('Notes for multi events / scenarios:'),
                      **DETAILS_STYLE))
        if len(definition['multi_event_notes']) < 1:
            message.add(m.Paragraph(tr('No multi-event notes defined.')))
        else:
            bullets = m.BulletedList()
            for note in definition['multi_event_notes']:
                bullets.add(m.Text(note))
            message.add(bullets)

    if 'actions' in definition:
        message.add(m.Paragraph(m.ImportantText(tr('Actions:'))))
        bullets = m.BulletedList()
        for note in definition['actions']:
            bullets.add(m.Text(note))
        message.add(bullets)

    for exposure in exposure_all:
        extra_exposure_actions = specific_actions(definition, exposure)
        if extra_exposure_actions:
            title = tr(u'Actions for exposure : {exposure_name}').format(
                exposure_name=exposure['name'])
            message.add(m.Heading(title, **DETAILS_SUBGROUP_STYLE))
            bullets = m.BulletedList()
            for note in extra_exposure_actions:
                bullets.add(m.Text(note))
            message.add(bullets)

    if 'continuous_hazard_units' in definition:
        message.add(m.Paragraph(m.ImportantText(tr('Units:'))))
        table = m.Table(style_class='table table-condensed table-striped')
        row = m.Row()
        row.add(m.Cell(tr('Name')), header_flag=True)
        row.add(m.Cell(tr('Plural')), header_flag=True)
        row.add(m.Cell(tr('Abbreviation')), header_flag=True)
        row.add(m.Cell(tr('Details')), header_flag=True)
        table.add(row)
        for unit in definition['continuous_hazard_units']:
            row = m.Row()
            row.add(m.Cell(unit['name']))
            row.add(m.Cell(unit['plural_name']))
            row.add(m.Cell(unit['abbreviation']))
            row.add(m.Cell(unit['description']))
            table.add(row)
        message.add(table)

    if 'extra_fields' and 'fields' in definition:
        message.add(m.Paragraph(m.ImportantText(tr('Fields:'))))
        table = _create_fields_table()
        all_fields = definition['fields'] + definition['extra_fields']
        for field in all_fields:
            _add_field_to_table(field, table)
        message.add(table)

    if 'classifications' in definition:
        message.add(m.Heading(tr('Hazard classifications'), **DETAILS_STYLE))
        message.add(
            m.Paragraph(definitions.hazard_classification['description']))
        for inasafe_class in definition['classifications']:
            message.add(
                definition_to_message(inasafe_class, DETAILS_SUBGROUP_STYLE))

    if 'classes' in definition:
        message.add(m.Paragraph(m.ImportantText(tr('Classes:'))))
        table = _make_defaults_table()
        for inasafe_class in definition['classes']:
            row = m.Row()
            # name() on QColor returns its hex code
            if 'color' in inasafe_class:
                colour = inasafe_class['color'].name()
                row.add(
                    m.Cell(u'', attributes='style="background: %s;"' % colour))
            else:
                row.add(m.Cell(u' '))

            row.add(m.Cell(inasafe_class['name']))
            if 'affected' in inasafe_class:
                row.add(m.Cell(tr(inasafe_class['affected'])))
            else:
                row.add(m.Cell(tr('unspecified')))

            if 'displacement_rate' in inasafe_class:
                rate = inasafe_class['displacement_rate'] * 100
                rate = u'%s%%' % rate
                row.add(m.Cell(rate))
            else:
                row.add(m.Cell(tr('unspecified')))

            if 'string_defaults' in inasafe_class:
                defaults = None
                for default in inasafe_class['string_defaults']:
                    if defaults:
                        defaults += ',%s' % default
                    else:
                        defaults = default
                row.add(m.Cell(defaults))
            else:
                row.add(m.Cell(tr('unspecified')))
            # Min may be a single value or a dict of values so we need
            # to check type and deal with it accordingly
            if 'numeric_default_min' in inasafe_class:
                if isinstance(inasafe_class['numeric_default_min'], dict):
                    bullets = m.BulletedList()
                    minima = inasafe_class['numeric_default_min']
                    for key, value in minima.iteritems():
                        bullets.add(u'%s : %s' % (key, value))
                    row.add(m.Cell(bullets))
                else:
                    row.add(m.Cell(inasafe_class['numeric_default_min']))
            else:
                row.add(m.Cell(tr('unspecified')))

            # Max may be a single value or a dict of values so we need
            # to check type and deal with it accordingly
            if 'numeric_default_max' in inasafe_class:
                if isinstance(inasafe_class['numeric_default_max'], dict):
                    bullets = m.BulletedList()
                    maxima = inasafe_class['numeric_default_max']
                    for key, value in maxima.iteritems():
                        bullets.add(u'%s : %s' % (key, value))
                    row.add(m.Cell(bullets))
                else:
                    row.add(m.Cell(inasafe_class['numeric_default_max']))
            else:
                row.add(m.Cell(tr('unspecified')))

            table.add(row)
            # Description goes in its own row with spanning
            row = m.Row()
            row.add(m.Cell(''))
            row.add(m.Cell(inasafe_class['description'], span=6))
            table.add(row)
        # For hazard classes we also add the 'not affected' class manually:
        if definition['type'] == definitions.hazard_classification_type:
            row = m.Row()
            colour = definitions.not_exposed_class['color'].name()
            row.add(m.Cell(u'', attributes='style="background: %s;"' % colour))
            description = definitions.not_exposed_class['description']
            row.add(m.Cell(description, span=5))
            table.add(row)

        message.add(table)

    if 'affected' in definition:
        if definition['affected']:
            message.add(
                m.Paragraph(
                    tr('Exposure entities in this class ARE considered affected'
                       )))
        else:
            message.add(
                m.Paragraph(
                    tr('Exposure entities in this class are NOT considered '
                       'affected')))

    if 'optional' in definition:
        if definition['optional']:
            message.add(
                m.Paragraph(
                    tr('This class is NOT required in the hazard keywords.')))
        else:
            message.add(
                m.Paragraph(
                    tr('This class IS required in the hazard keywords.')))

    return message
Beispiel #16
0
def content():
    """Helper method that returns just the content.

    This method was added so that the text could be reused in the
    dock_help module.

    .. versionadded:: 3.2.2

    :returns: A message object without brand element.
    :rtype: safe.messaging.message.Message
    """
    message = m.Message()
    paragraph = m.Paragraph(m.Image('file:///%s/img/screenshots/'
                                    'analysis-area-screenshot.png' %
                                    resources_path()),
                            style_class='text-center')
    message.add(paragraph)

    paragraph = m.Paragraph(
        tr('This tool allows you to specify which geographical region should be '
           'used for your analysis. If you want to check what area will be '
           'included in your analysis, enable the \'Toggle scenario outlines\' '
           'tool on the InaSAFE toolbar:'),
        m.Image(
            'file:///%s/img/icons/'
            'toggle-rubber-bands.svg' % resources_path(), **SMALL_ICON_STYLE),
    )
    message.add(paragraph)
    paragraph = m.Paragraph(
        tr('Your user defined extent will be shown on the map as a rectangle. '
           'There are a number of different modes that can be used which are '
           'described below:'))
    message.add(paragraph)
    header = m.Heading(tr('Use intersection of hazard and exposure layers'),
                       **INFO_STYLE)
    message.add(header)
    paragraph = m.Paragraph(
        tr('The largest area that can be analysed is the intersection of the '
           'hazard and exposure layers you have added. To choose this option, '
           'click \'Use intersection of hazard and exposure layers\'. '))
    message.add(paragraph)
    paragraph = m.Paragraph(
        tr('Sometimes it is more useful to analyse a smaller area. This could be '
           'to reduce processing time (smaller areas with process faster) or '
           'because information is only needed in a certain area (e.g. if a '
           'district only wants information for their district, not for the '
           'entire city). If you want to analyse a smaller area, there are a few '
           'different ways to do this.'))
    message.add(paragraph)
    header = m.Heading(
        tr('Use intersection of hazard, exposure and current view extent'),
        **INFO_STYLE)
    message.add(header)
    paragraph = m.Paragraph(
        tr('If you wish to conduct the analysis on the area currently shown in '
           'the window, you can set the analysis area to \'Use intersection of '
           'hazard, exposure and current view extent\'. If the extents of the '
           'datasets are smaller than the view extent, the analysis area will be '
           'reduced to the extents of the datasets.'))
    message.add(paragraph)
    header = m.Heading(
        tr('Use intersection of hazard, exposure and this bookmark'),
        **INFO_STYLE)
    message.add(header)
    paragraph = m.Paragraph(
        tr('You can also use one of your QGIS bookmarks to set the analysis '
           'area.'),
        m.ImportantText(
            tr('This option will be greyed out if you have no bookmarks.')))
    message.add(paragraph)
    paragraph = m.Paragraph(
        tr('To create a bookmark, zoom to the area you want to create a bookmark '
           'for. When you are happy with the extent, click the \'New bookmark\' '
           'button in the QGIS toolbar.'))
    message.add(paragraph)
    paragraph = m.Paragraph(
        tr('The drop down menu in the InaSAFE Analysis Area window should now be '
           'activated. When you choose a bookmark from the drop down menu it '
           'will zoom to the analysis area selected by the bookmark.'))
    message.add(paragraph)
    header = m.Heading(
        tr('Use intersection of hazard, exposure and this bounding box'),
        **INFO_STYLE)
    message.add(header)
    paragraph = m.Paragraph(
        tr('You can also choose the analysis area interactively by clicking '
           '\'Use intersection of hazard, exposure and this bounding box\'. This '
           'will allow you to click \'Drag on map\' which will temporarily hide '
           'this window and allow you to drag a rectangle on the map. After you '
           'have finished dragging the rectangle, this window will reappear with '
           'values in the North, South, East and West boxes. If the extents of '
           'the datasets are smaller than the user defined analysis area, the '
           'analysis area will be reduced to the extents of the datasets.'))
    message.add(paragraph)
    paragraph = m.Paragraph(
        tr('Alternatively, you can enter the coordinates directly into the '
           'N/S/E/W boxes once the \'Use intersection of hazard, exposure and '
           'this bounding box\' option is selected (using the same coordinate '
           'reference system, or CRS, as the map is currently set).'))
    message.add(paragraph)

    return message
Beispiel #17
0
def content():
    """Helper method that returns just the content.

    This method was added so that the text could be reused in the
    dock_help module.

    .. versionadded:: 3.2.2

    :returns: A message object without brand element.
    :rtype: safe.messaging.message.Message
    """
    message = m.Message()
    paragraph = m.Paragraph(
        tr('InaSAFE is free software that produces realistic natural hazard '
           'impact scenarios for better planning, preparedness and response '
           'activities. It provides a simple but rigourous way to combine data '
           'from scientists, local governments and communities to provide '
           'insights into the likely impacts of future disaster events.'))
    message.add(paragraph)
    paragraph = m.Paragraph(
        tr('The InaSAFE \'dock panel\' helps you to run hazard impact analysis '
           'within the QGIS environment. It helps you create your hazard impact '
           'analysis question and shows the results of this analysis. If you are '
           'a new user, you may also consider using the \'Impact Function '
           'Centric Wizard\' to run the analysis. This wizard will guide you '
           'through the process of running an InaSAFE assessment, with '
           'interactive step by step instructions. You can launch the wizard '
           'by clicking on this icon in the toolbar:'),
        m.Image('file:///%s/img/icons/'
                'show-wizard.svg' % resources_path(), **SMALL_ICON_STYLE),
    )
    message.add(paragraph)
    paragraph = m.Paragraph(
        tr('You can drag and drop the dock panel to reposition it on the screen. '
           'For example, dragging the panel towards the right margin of the QGIS '
           'application will dock it to the right side of the screen.'))
    message.add(paragraph)

    message.add(
        m.Paragraph(tr('There are three main areas to the dock panel:')))
    bullets = m.BulletedList()
    bullets.add(
        m.Text(
            # format 'the __questions__ area' for proper i18n
            tr('the %s area') %
            (m.ImportantText(tr('questions')).to_html(), )))
    bullets.add(
        m.Text(
            # format 'the __results__ area' for proper i18n
            tr('the %s area') % (m.ImportantText(tr('results')).to_html(), )))
    bullets.add(
        m.Text(
            # format 'the __buttons__ area' for proper i18n
            tr('the %s area') % (m.ImportantText(tr('buttons')).to_html(), )))
    message.add(bullets)
    message.add(
        m.Paragraph(
            tr('You can get help at any time in InaSAFE by clicking on the '
               'help buttons provided on each dock and dialog.')))

    header = m.Heading(tr('The questions area'), **INFO_STYLE)
    message.add(header)
    message.add(
        m.Paragraph(
            tr('The intention of InaSAFE is to make it easy to perform your impact '
               'analysis. We start the analysis in the questions area. This area '
               'contains three drop down menus. You create your question by using '
               'these drop down menus to select the hazard and exposure data you '
               'wish to perform the analysis on. '
               'All questions follow this form:'),
            m.EmphasizedText(
                tr('In the event of a [hazard], how many [exposure] might be '
                   '[impacted]?'))))
    message.add(
        m.Paragraph(
            tr('For example: "If there is a flood, how many buildings might be '
               'flooded?"')))
    message.add(
        m.Paragraph(
            tr('InaSAFE can be used to answer such questions for hazards such as '
               'flood, tsunami, volcanic ash fall and earthquake and exposures '
               'such as population, roads, structures, land cover etc.')))
    message.add(
        m.Paragraph(
            tr('The first step in answering these questions is to load layers that '
               'represent either hazard scenarios or exposure data into QGIS. '
               'A hazard, for example, may be represented as a raster layer in '
               'QGIS where each pixel in the raster represents the flood depth '
               'following an inundation event. An exposure layer could be '
               'represented, for example, as vector polygon data representing '
               'building outlines, or a raster outline where each pixel represents '
               'the number of people thought to be living in that cell.')))
    message.add(
        m.Paragraph(
            tr('InaSAFE will combine these two layers in a '
               'mathematical model. The results of this model will show what the '
               'effect of the hazard will be on the exposed infrastructure or '
               'people. The plugin relies on simple keyword metadata '
               'associated with each layer to determine what kind of information the '
               'layer represents. You can define these keywords by '
               'selecting a layer and then clicking the InaSAFE Keywords Wizard icon '
               'on the toolbar: '),
            m.Image(
                'file:///%s/img/icons/'
                'show-keyword-wizard.svg' % resources_path(),
                **SMALL_ICON_STYLE),
            tr('The wizard will guide you through the process of defining the '
               'keywords for that layer.')))
    message.add(
        m.Paragraph(
            tr('Aggregation is the process whereby we group the analysis results '
               'by district so that you can see how many people, roads or '
               'buildings were affected in each area. This will help you to '
               'understand where the most critical needs are.  Aggregation is '
               'optional in InaSAFE - if you do not use aggregation, the entire '
               'analysis area will be used for the data summaries. Typically '
               'aggregation layers in InaSAFE have the name of the district or '
               'reporting area as attributes. It is also possible to use extended '
               'attributes to indicate the ratio of men and women; youth, adults '
               'and elderly living in each area. Where these are provided and the '
               'exposure layer is population, InaSAFE will provide a demographic '
               'breakdown per aggregation area indicating how many men, women, etc. '
               'were probably affected in that area.')))

    header = m.Heading(tr('The results area'), **INFO_STYLE)
    message.add(header)

    message.add(
        m.Paragraph(
            tr('After running an analysis, the question area is hidden to maximise '
               'the amount of space allocated to the results area. You can '
               're-open the question area at any time by pressing the \'show '
               'question form\' button.')))

    message.add(
        m.Paragraph(
            tr('The results area is used to display various useful feedback items to '
               'the user. Once an impact scenario has been run, a summary table will '
               'be shown.')))

    message.add(
        m.Paragraph(
            tr('If you select an impact layer (i.e. a layer that was produced using '
               'an InaSAFE Impact Function), in the QGIS layers list, this summary '
               'will also be displayed in the results area. When you select a hazard '
               'or exposure layer in the QGIS layers list, the keywords for that '
               'layer will be shown in the results area, making it easy to '
               'understand what metadata exists for that layer.')))

    message.add(
        m.Paragraph(
            tr('The results area is also used to display status information. For '
               'example, during the analysis process, the status area will display '
               'notes about each step in the analysis process. The \'Run\' '
               'button will be activated when both a valid hazard and valid exposure '
               'layer have been added in QGIS.')))

    message.add(
        m.Paragraph(
            tr('Finally, the results area is also used to display any error messages '
               'so that you can see what went wrong and why. You may need to '
               'scroll down to view the message completely to see all of the error '
               'message details.')))

    message.add(
        m.Paragraph(
            tr('After running the impact scenario calculation, the question is '
               'automatically hidden to make the results area as large as possible. '
               'If you want to see what the question used in the analysis was, click '
               'on the \'Show question form\' button at the top of the results area.'
               )))

    message.add(
        m.Paragraph(
            tr('If you want to hide the question area again to have more space to '
               'display the results, click on the layer you just calculated '
               'with InaSAFE in the Layers list of QGIS to make it active.')))

    header = m.Heading(tr('The buttons area'), **INFO_STYLE)
    message.add(header)

    message.add(m.Paragraph(tr('The buttons area contains four buttons:')))
    bullets = m.BulletedList()
    bullets.add(
        m.Text(
            m.ImportantText(tr('Help')),
            tr('- click on this if you need context help, such as the document '
               'you are reading right now!')))
    bullets.add(
        m.Text(
            m.ImportantText(tr('About')),
            tr('- click on this to see short credits for the InaSAFE project.')
        ))
    bullets.add(
        m.Text(
            m.ImportantText(tr('Print')),
            tr('... - click on this if you wish to create a pdf of your '
               'impact scenario project or generate a report to open in '
               'composer for further tuning. An impact layer must be active '
               'before the \'Print\' button will be enabled.')))
    bullets.add(
        m.Text(
            m.ImportantText(tr('Run')),
            tr('- this button is enabled when the combination of hazard and '
               'exposure selected in the questions area\'s drop down menus will '
               'allow you to run a scenario.')))
    message.add(bullets)

    header = m.Heading(tr('Data conversions'), **INFO_STYLE)
    message.add(header)

    message.add(
        m.Paragraph(
            tr('When running a scenario, the data being used needs to be processed '
               'into a state where it is acceptable for use by InaSAFE. '
               'In particular it should be noted that:')))

    bullets = m.BulletedList()
    bullets.add(
        tr('Remote datasets will be copied locally before processing.'))
    bullets.add(
        m.Text(
            tr('All datasets will be clipped to the behaviours defined in the '
               'analysis extents dialog if you do not use an aggregation layer.'
               ),
            m.Image(
                'file:///%s/img/icons/'
                'set-extents-tool.svg' % resources_path(),
                **SMALL_ICON_STYLE)))
    bullets.add(
        m.Text(
            tr('You can visualise the area that will be used for the analysis '
               'by enabling the "Toggle Scenario Outlines" tool. When this tool '
               'is enabled, a line (green by default) will be drawn around the '
               'outermost boundary of the analysis area.'),
            m.Image(
                'file:///%s/img/icons/'
                'toggle-rubber-bands.svg' % resources_path(),
                **SMALL_ICON_STYLE)))
    bullets.add(
        m.Text(
            tr('When you have selected an aggregation layer the analysis area '
               'will be the outline of the aggregation layer. If you select one '
               'or more polygons in the aggregation layer (by using the QGIS '
               'feature selection tools), the analysis boundary will be reduced '
               'to just the outline of these selected polygons. If the "Toggle '
               'Scenario Outlines" tool is enabled, the preview of the effective '
               'analysis area will be updated to reflect the selected features.'
               ), ))
    bullets.add(
        tr('All clipped datasets will be converted (reprojected) to the '
           'Coordinate Reference System of the exposure layer '
           'before analysis.'))
    message.add(bullets)

    header = m.Heading(tr('Generating impact reports'), **INFO_STYLE)
    message.add(header)

    message.add(
        m.Paragraph(
            tr('When the impact analysis has completed you may want to generate a '
               'report. Usually the \'Print...\'  button will be enabled immediately '
               'after analysis. Selecting an InaSAFE impact layer in QGIS Layers '
               'panel will also enable it.')))

    # This adds the help content of the print dialog
    message.add(report())
    return message
Beispiel #18
0
def content():
    """Helper method that returns just the content.

    This method was added so that the text could be reused in the
    dock_help module.

    .. versionadded:: 3.2.2

    :returns: A message object without brand element.
    :rtype: safe.messaging.message.Message
    """
    message = m.Message()
    paragraph = m.Paragraph(m.Image('file:///%s/img/screenshots/'
                                    'minimum-needs-screenshot.png' %
                                    resources_path()),
                            style_class='text-center')
    message.add(paragraph)
    message.add(
        m.Paragraph(
            tr('During and after a disaster, providing for the basic human minimum '
               'needs of food, water, hygiene and shelter is an important element of '
               'your contingency plan. InaSAFE has a customisable minimum needs '
               'system that allows you to define country or region specific '
               'requirements for compiling a needs report where the exposure '
               'layer represents population.')))
    message.add(
        m.Paragraph(
            tr('By default InaSAFE uses minimum needs defined for Indonesia - '
               'and ships with additional profiles for the Philippines and Tanzania. '
               'You can customise these or add your own region-specific profiles too.'
               )))
    message.add(
        m.Paragraph(
            tr('Minimum needs are grouped into regional or linguistic \'profiles\'. '
               'The default profile is \'BNPB_en\' - the english profile for the '
               'national disaster agency in Indonesia. '
               'You will see that this profile defines requirements for displaced '
               'persons in terms of Rice, Drinking Water, Clean Water (for bathing '
               'etc.), Family Kits (with personal hygiene items) and provision of '
               'toilets.')))
    message.add(
        m.Paragraph(
            tr('Each item in the profile can be customised or removed. For example '
               'selecting the first item in the list and then clicking on the '
               '\'pencil\' icon will show the details of how it was defined. '
               'If you scroll up and down in the panel you will see that for each '
               'item, you can set a name, description, units (in singular, '
               'plural and abbreviated forms), specify maxima and minima for the '
               'quantity of item allowed, a default and a frequency. You would use '
               'the maxima and minima to ensure that disaster managers never '
               'allocate amounts that will not be sufficient for human livelihood, '
               'and also that will not overtax the logistics operation for those '
               'providing humanitarian relief.')))
    message.add(
        m.Paragraph(
            tr('The final item in the item configuration is the \'readable '
               'sentence\' which bears special discussion. Using a simple system of '
               'tokens you can construct a sentence that will be used in the '
               'generated needs report.')))
    message.add(m.Heading(tr('Minimum needs profiles'), **INFO_STYLE))
    message.add(
        m.Paragraph(
            tr('A profile is a collection of resources that define the minimum needs '
               'for a particular country or region. Typically a profile should be '
               'based on a regional, national or international standard. The '
               'actual definition of which resources are needed in a given '
               'profile is dependent on the local conditions and customs for the '
               'area where the contingency plan is being devised.')))
    message.add(
        m.Paragraph(
            tr('For example in the middle east, rice is a staple food whereas in '
               'South Africa, maize meal is a staple food and thus the contingency '
               'planning should take these localised needs into account.')))

    message.add(m.Heading(tr('Minimum needs resources'), **INFO_STYLE))
    message.add(
        m.Paragraph(
            tr('Each item in a minimum needs profile is a resource. Each resource '
               'is described as a simple natural language sentence e.g.:')))

    message.add(
        m.EmphasizedText(
            tr('Each person should be provided with 2.8 kilograms of Rice weekly.'
               )))
    message.add(
        m.Paragraph(
            tr('By clicking on a resource entry in the profile window, and then '
               'clicking the black pencil icon you will be able to edit the '
               'resource using the resource editor. Alternatively you can create a '
               'new resource for a profile by clicking on the black + icon in '
               'the profile manager. You can also remove any resource from a '
               'profile using the - icon in the profile manager.')))

    message.add(m.Heading(tr('Resource Editor'), **INFO_STYLE))
    message.add(
        m.Paragraph(
            tr('When switching to edit or add resource mode, the minimum needs '
               'manager will be updated to show the resource editor. Each '
               'resource is described in terms of:')))
    bullets = m.BulletedList()
    bullets.add(
        m.Text(m.ImportantText(tr('resource name')), tr(' - e.g. Rice')))
    bullets.add(
        m.Text(m.ImportantText(tr('a description of the resource')),
               tr(' - e.g. Basic food')))
    bullets.add(
        m.Text(m.ImportantText(tr('unit in which the resource is provided')),
               tr(' - e.g. kilogram')))
    bullets.add(
        m.Text(m.ImportantText(tr('pluralised form of the units')),
               tr(' - e.g. kilograms')))
    bullets.add(
        m.Text(m.ImportantText(tr('abbreviation for the unit')),
               tr(' - e.g. kg')))
    bullets.add(
        m.Text(
            m.ImportantText(tr('the default allocation for the resource')),
            tr(' - e.g. 2.8. This number can be overridden on a '
               'per-analysis basis')))
    bullets.add(
        m.Text(
            m.ImportantText(
                tr('minimum allowed which is used to prevent allocating')),
            tr(' - e.g. no drinking water to displaced persons')))
    bullets.add(
        m.ImportantText(
            tr('maximum allowed which is used to set a sensible upper '
               'limit for the resource')))
    bullets.add(
        m.ImportantText(
            tr('a readable sentence which is used to compile the '
               'sentence describing the resource in reports.')))
    message.add(bullets)

    message.add(
        m.Paragraph(
            tr('These parameters are probably all fairly self explanatory, but '
               'the readable sentence probably needs further detail. The '
               'sentence is compiled using a simple keyword token replacement '
               'system. The following tokens can be used:')))

    bullets = m.BulletedList()
    bullets.add(m.Text('{{ Default }}'))
    bullets.add(m.Text('{{ Unit }}'))
    bullets.add(m.Text('{{ Units }}'))
    bullets.add(m.Text('{{ Unit abbreviation }}'))
    bullets.add(m.Text('{{ Resource name }}'))
    bullets.add(m.Text('{{ Frequency }}'))
    bullets.add(m.Text('{{ Minimum allowed }}'))
    bullets.add(m.Text('{{ Maximum allowed }}'))
    message.add(bullets)

    message.add(
        m.Paragraph(
            tr('When the token is placed in the sentence it will be replaced with '
               'the actual value at report generation time. This contrived example '
               'shows a tokenised sentence that includes all possible keywords:'
               )))

    message.add(
        m.EmphasizedText(
            tr('A displaced person should be provided with {{ %s }} '
               '{{ %s }}/{{ %s }}/{{ %s }} of {{ %s }}. Though no less than {{ %s }} '
               'and no more than {{ %s }}. This should be provided {{ %s }}.' %
               ('Default', 'Unit', 'Units', 'Unit abbreviation',
                'Resource name', 'Minimum allowed', 'Maximum allowed',
                'Frequency'))))
    message.add(
        m.Paragraph(tr('Would generate a human readable sentence like this:')))

    message.add(
        m.ImportantText(
            tr('A displaced person should be provided with 2.8 kilogram/kilograms/kg '
               'of rice. Though no less than 0 and no more than 100. This should '
               'be provided daily.')))
    message.add(
        m.Paragraph(
            tr('Once you have populated the resource elements, click the Save '
               'resource button to return to the profile view. You will see the '
               'new resource added in the profile\'s resource list.')))

    message.add(m.Heading(tr('Managing profiles'), **INFO_STYLE))
    message.add(
        m.Paragraph(
            tr('In addition to the profiles that come as standard with InaSAFE, you '
               'can create new ones, either from scratch, or based on an existing '
               'one (which you can then modify).')))
    message.add(
        m.Paragraph(
            tr('Use the New button to create new profile. When prompted, give your '
               'profile a name e.g. \'JakartaProfile\'.')))
    message.add(
        m.Paragraph(
            tr('Note: The profile must be saved in your home directory under '
               '(QGIS profile path)/minimum_needs in order '
               'for InaSAFE to successfully '
               'detect it.')))
    message.add(
        m.Paragraph(
            tr('An alternative way to create a new profile is to use the Save as to '
               'clone an existing profile. The clone profile can then be edited '
               'according to your specific needs.')))
    message.add(m.Heading(tr('Active profile'), **INFO_STYLE))
    message.add(
        m.Paragraph(
            tr('It is important to note, that which ever profile you select in the '
               'Profile pick list, will be considered active and will be used as '
               'the basis for all minimum needs analysis. You need to restart '
               'QGIS before the changed profile become active.')))
    return message
Beispiel #19
0
def content():
    """Helper method that returns just the content.

    This method was added so that the text could be reused in the
    dock_help module.

    .. versionadded:: 3.2.2

    :returns: A message object without brand element.
    :rtype: safe.messaging.message.Message
    """
    message = m.Message()
    message.add(
        tr('The InaSAFE options dialog is used to control various aspects of '
           'the InaSAFE analysis and reporting environment. Here are brief '
           'descriptions of all the options available, grouped by the tab '
           'page on which they occur.'))

    header = m.Heading(tr('Basic options tab'), **INFO_STYLE)
    message.add(header)

    message.add(
        m.Paragraph(
            tr('The basic options tab provides several general settings:')))

    bullets = m.BulletedList()
    bullets.add(
        m.Text(
            m.ImportantText(tr('Show organisation logo in InaSAFE dock')),
            tr(' - When this option is enabled, a logo will be displayed at the '
               'bottom of the InaSAFE dock widget. By default the logo used '
               'is the InaSAFE supporters logo, but you can alter this by '
               'setting the \'Use custom organisation logo\' option in '
               'the template options tab (see below).')))
    bullets.add(
        m.Text(
            m.ImportantText(
                tr('Show only visible layers in the InaSAFE dock')),
            tr(' - When this option is enabled layers that are not visible '
               'in the QGIS layers panel will not be shown in the hazard, '
               'exposure and aggregation combo boxes in the dock area.')))
    bullets.add(
        m.Text(
            m.ImportantText(tr('Set QGIS layer name from title in keywords')),
            tr(' - If this option is enabled, the InaSAFE keywords title '
               'attribute will be used for the layer name in the QGIS Layers list '
               'when adding a layer.')))
    bullets.add(
        m.Text(
            m.ImportantText(
                tr('Zoom to impact layer on scenario estimate completion')),
            tr(' - When this option is enabled, the map view extents will '
               'be updated to match the extents of the generated impact layer '
               'once the analysis completes.')))
    bullets.add(
        m.Text(
            m.ImportantText(
                tr('Hide exposure on scenario estimate completion')),
            tr(' - Use this option if you prefer to not show the exposure '
               'layer as an underlay behind the generated impact layer.')))
    bullets.add(
        m.Text(
            m.ImportantText(
                tr('When clipping to analysis extents, also clip features')),
            tr(' - This option only applies in cases where hazard or exposure '
               'layers are vector layers. In these cases, any feature (line or '
               'polygon) that extends beyond the analysis extents will first '
               'be clipped so that it is coincident with the analysis extent. '
               'Note that enabling this option may have some unwanted side '
               'effects. For example, if you have an area attribute, that '
               'attribute may no longer match the actual clipped polygon area. '
               )))
    bullets.add(
        m.Text(
            m.ImportantText(
                tr('Show intermediate layers generated by post processing')),
            tr(' - When enabled, the working layer used for doing by-area '
               'breakdowns of impact results will be added to the current QGIS '
               'project. You can generally leave this option disabled.')))
    bullets.add(
        m.Text(
            m.ImportantText(tr('Female ratio default value')),
            tr(' - When doing an analysis that uses population as the '
               'exposure layer, various post-processors are used to produce a '
               'demographic breakdown. In the case of the gender breakdown, '
               'InaSAFE will report on how many males versus females are present '
               'in each aggregation area. If there is no female ratio attribute '
               'defined in the aggregation layer, the value in this setting will '
               'be used to determine what the ratio between males to females '
               'is.')))
    bullets.add(
        m.Text(
            m.ImportantText(tr('Location for results')),
            tr(' - By default, InaSAFE will write impact layer and intermediate '
               'outputs to the system temporary directory. On some operating '
               'systems, these temporary files will be deleted on each reboot. '
               'If you wish to, you can specify an alternative directory '
               'to use for storing these temporary files.')))
    message.add(bullets)

    header = m.Heading(tr('Template options tab'), **INFO_STYLE)
    message.add(header)

    message.add(
        m.Paragraph(
            tr('This tab has options relating to the printing of reports and the '
               'generation of map composer templates.')))

    bullets = m.BulletedList()
    bullets.add(
        m.Text(
            m.ImportantText(
                tr('Prompt me when template has missing elements')),
            tr(' - You can define your own templates in InaSAFE. In some cases '
               'critical elements on the template may be ommitted during this '
               'template definition process. Should this happen, InaSAFE can '
               'warn you when you try to use the template that it is missing '
               'vital map components.')))
    bullets.add(
        m.Text(
            m.ImportantText(tr('Use custom organisation logo')),
            tr(' - By default, InaSAFE will add the supporters logo to each '
               'map template. The supporters logo is also used at tbe bottom '
               'of the dock panel if the \'show organisation logo in dock\' '
               'option is enabled. You can use this option to replace the '
               'organisation logo with that of your own organisation. The logo '
               'will be rescaled automatically to fill the space provided.')))
    bullets.add(
        m.Text(
            m.ImportantText(tr('Use custom north arrow image')),
            tr(' - InaSAFE provides a basic north arrow which is placed on '
               'generated map compositions and rendered PDF reports. You can '
               'replace this north arrow with one of your own choosing using '
               'this option.')))
    bullets.add(
        m.Text(
            m.ImportantText(tr('Additional template directory')),
            tr(' - When generating a print report, InaSAFE will offer a number '
               'of pre-defined templates for you to use. For example there '
               'is an A4 variant, an A3 variant and so on. You can use this '
               'option to specify additional search directories to be used '
               'when presenting a list of available templates. This is useful '
               'in cases where you have created your own custom map templates '
               'and you wish to use them for report production.')))
    bullets.add(
        m.Text(
            m.ImportantText(tr('Use custom disclaimer text')),
            tr(' - By default, InaSAFE will display a disclaimer on reports '
               'advising readers of the report to exercise caution when '
               'interpreting the outputs presented. You can override this '
               'text using this option, though we do advise that you include '
               'a similar statement of caution in your overridden text.')))
    message.add(bullets)

    header = m.Heading(tr('ISO 19115 metadata tab'), **INFO_STYLE)
    message.add(header)

    message.add(
        m.Paragraph(
            tr('This tab is used to define various options related to the '
               'automated generation of ISO 19115 metadata which is associated with '
               'hazard, exposure, aggregation and impact layers.')))

    bullets = m.BulletedList()
    bullets.add(
        m.Text(
            m.ImportantText(tr('Organisation')),
            tr(' - Use this option to specify the name of your organisation.'))
    )
    bullets.add(
        m.Text(
            m.ImportantText(tr('Contact email')),
            tr(' - Use this option to specify the contact person\s email '
               'address to use in the generated metadata document.')))
    bullets.add(
        m.Text(
            m.ImportantText(tr('Website')),
            tr(' - Use this option to set the website address to be used in '
               'the generated metadata document.')))
    bullets.add(
        m.Text(
            m.ImportantText(tr('Analysis title')),
            tr(' - Use this to set the title value for the generated metadata '
               'document.')))
    bullets.add(
        m.Text(
            m.ImportantText(tr('Analysis license')),
            tr(' - Use this to set the usage and redistribution license for the '
               'generated impact layer.')))
    message.add(bullets)

    header = m.Heading(tr('Advanced tab'), **INFO_STYLE)
    message.add(header)

    message.add(
        m.Paragraph(
            tr('This tab contains options intended for advanced users only.')))

    bullets = m.BulletedList()
    bullets.add(
        m.Text(
            m.ImportantText(tr('Keyword cache for remote databases')),
            tr(' - When InaSAFE is used with remote layers (for example a '
               'database layer or a WFS layer), it is not possible to store the '
               'keywords for the layer with the layer itself. To accommodate for '
               'these types of layers, InaSAFE writes the keywords to a small '
               'file based database (using sqlite) and then retrieves them based '
               'on unique connection details used for that layer. You can '
               'specify a custom path to be used for storing the keywords '
               'database using this option.')))
    bullets.add(
        m.Text(
            m.ImportantText(
                tr('Help to improve InaSAFE by submitting errors to a '
                   'remote server')),
            tr(' - With this option enabled, InaSAFE will post any errors that '
               'occur to an online server for analysis by our development team. '
               'This option is disabled by default as some may consider some of '
               'the data submitted (IP Address, logged in user name) to be '
               'sensitive.')))
    bullets.add(
        m.Text(
            m.ImportantText(tr('Enable developer mode')),
            tr(' - When this option is enabled, right clicking on the webview '
               'widget in the dock will allow you to debug the generated HTML. '
               'In addition, if the metadata.txt for the running InaSAFE is '
               'set to \'alpha\', an additional icon will be added to the '
               'toolbar to add test layers to the QGIS project.'),
            m.Image(
                'file:///%s/img/icons/'
                'add-test-layers.svg' % resources_path(), **SMALL_ICON_STYLE)))
    bullets.add(
        m.Text(
            m.ImportantText(tr('Use QGIS zonal statistics')),
            tr(' - Some versions of QGIS shipped with a buggy zonal statistics '
               'algorithm. With this option you can elect whether to use '
               'built in zonal statistics functions from QGIS or to use '
               'an implementation of zonal statistics included with InaSAFE. '
               'At some point in the future we expect to deprecate this feature '
               'but for now we suggest to use the InaSAFE implementation.')))
    message.add(bullets)

    return message
Beispiel #20
0
def content():
    """Helper method that returns just the content.

    This method was added so that the text could be reused in the
    dock_help module.

    .. versionadded:: 3.2.2

    :returns: A message object without brand element.
    :rtype: safe.messaging.message.Message
    """
    message = m.Message()
    paragraph = m.Paragraph(tr(
        'This document describes the usage of the InaSAFE \'dock panel\''
        '- which is an interface for running risk scenarios within the QGIS '
        'environment. If you are a new user, you may also consider using the '
        '\'Impact Function Centric Wizard\' to run the analysis. You can '
        'launch the wizard by clicking on this icon in the toolbar:'),
        m.Image(
            'file:///%s/img/icons/'
            'show-wizard.svg' % resources_path(),
            **SMALL_ICON_STYLE),

    )
    message.add(paragraph)
    paragraph = m.Paragraph(tr(
        'You can drag and drop the dock panel to reposition it in the user '
        'interface. For example, dragging the panel towards the right margin '
        'of the QGIS application will dock it to the right side of the screen.'
    ))
    message.add(paragraph)

    message.add(m.Paragraph(tr(
        'There are three main areas to the dock panel:')))
    bullets = m.BulletedList()
    bullets.add(tr('the Questions area'))
    bullets.add(tr('the Results area'))
    bullets.add(tr('the Buttons area'))
    message.add(bullets)
    message.add(m.Paragraph(tr(
        'At any time you can obtain help in InaSAFE by clicking on the '
        'help buttons provided on each dock and dialog.')))

    header = m.Heading(tr('The questions area'), **INFO_STYLE)
    message.add(header)
    message.add(m.Paragraph(tr(
        'The intention of InaSAFE is to make it really simple and easy to '
        'perform your impact analysis. The question area provides a simple '
        'way for you to formulate what it is you want to find out? All '
        'questions are formulated in the form:'),
        m.EmphasizedText(tr(
            'In the event of a [hazard], how many [exposure] might be '
            'affected?'))))
    message.add(m.Paragraph(tr(
        'For example: "If there is a flood, how many buildings might be '
        'affected?"')))
    message.add(m.Paragraph(tr(
        'In order to answer such questions, the InaSAFE developers have '
        'built a number of Impact Functions that cover scenarios such as '
        'flood, tsunami, volcanic fall, earthquake and so on.')))
    message.add(m.Paragraph(tr(
        'The formulation of these questions if carried out by loading layers '
        'into QGIS that represent either hazard scenarios or exposure data.'
        'A hazard, for example, may be represented as, a raster layer in '
        'QGIS where each pixel in the raster represents the current flood '
        'depth following an inundation event. An exposure layer could be '
        'represented, for example, as vector polygon data representing '
        'building outlines, or a raster outline where each pixel represents '
        'the number of people thought to be resident in that cell.')))
    message.add(m.Paragraph(tr(
        'The impact function will combine these two input layers in a '
        'mathematical model in order to derive what the impacts of the '
        'hazard will be on the exposure infrastructure or people. By '
        'selecting a combination from the hazard and exposure combo boxes, '
        'an appropriate set of impact functions will be listed in the '
        'combo box. You may be wondering how the InaSAFE plugin determines '
        'whether a layer should be listed in the hazard or exposure combo '
        'boxes? The plugin relies on simple keyword metadata to be associated '
        'with each layer. You can define these keywords by selecting a layer '
        'and then clicking the InaSAFE Keywords Wizard icon on the toolbar: '),
        m.Image(
            'file:///%s/img/icons/'
            'show-keyword-wizard.svg' % resources_path(),
            **SMALL_ICON_STYLE),
        tr(
            'The wizard will guide you through the process of defining the '
            'keywords for that layer.')))
    message.add(m.Paragraph(tr(
        'Based on the combination of hazard and exposure layers that are '
        'selected, the Impact Function list (shown in the combo box under '
        '"Might" in the InaSAFE dock panel)  will be updated. Each impact '
        'function can only work with specific combinations of hazard and '
        'exposure types, so the options shown here will be limited '
        'accordingly. The chosen impact function can be configured (if '
        'applicable) by pressing the small ellipses (...) button next to '
        'the chosen impact function. This is explained in more detail below '
        'under the heading "Setting Analysis Parameters".')))
    message.add(m.Paragraph(tr(
        'Aggregation is the process whereby we group the results of the '
        'analysis by district so that you can see how many people, roads or '
        'buildings were affected in each area. This will help you to '
        'understand where the most critical needs are. Aggregation is '
        'optional in InaSAFE - if you do not use aggregation, the entire '
        'analysis area will be used for the data summaries. Typically '
        'aggregation layers in InaSAFE have as attributes the name of the '
        'district or reporting area. It is also possible to use extended '
        'attributes to indicate the ratio of men and women; youth, adults '
        'and elderly living in each area. Where these are provided and the '
        'exposure layer is population, InaSAFE will provide a demographic '
        'breakdown per aggregation area indicating how many men, women etc. '
        'were probably affected in that area.'
    )))

    header = m.Heading(tr('The results area'), **INFO_STYLE)
    message.add(header)

    message.add(m.Paragraph(tr(
        'After running an analysis, the question area is hidden to maximise '
        'the amount of space allocated to the results area. You can '
        're-open the question area at any time by pressing the "show question '
        'form" button.')))

    message.add(m.Paragraph(tr(
        'The Results area is used to display various useful feedback items to '
        'the user. Once an impact scenario has been run, a summary table will '
        'be shown.')))

    message.add(m.Paragraph(tr(
        'If you select an impact layer (i.e. a layer that was produced using '
        'an InaSAFE impact function), in the QGIS layers list, this summary '
        'will also be displayed in the results area. When you select a hazard '
        'or exposure layer in the QGIS layers list, the keywords for that '
        'layer will be shown in the Results area, making it easy to '
        'understand what metadata exists for that layer.')))

    message.add(m.Paragraph(tr(
        'The Results area is also used to display status information. For '
        'example, when a suitable combination of hazard, exposure and impact '
        'function are selected, the results area will be updated to indicate '
        'that you can proceed to run the impact scenario calculation. The Run '
        'Button will be activated.'
    )))

    message.add(m.Paragraph(tr(
        'Finally, the Results area is also used to display any error messages '
        'so that the user is informed as to what went wrong and why. You '
        'might want to scroll down a bit in the messaging window to view the '
        'message completely.'
    )))

    message.add(m.Paragraph(tr(
        'To have more space for the results available your Question is '
        'automatically hidden to make the results area as large as possible '
        'to display the results. If you want to have a look again what the '
        'question was that you formulated click on the Show question form '
        'button on top of the result area.'
    )))

    message.add(m.Paragraph(tr(
        'If you want to hide the question area again to have more space to '
        'display the results again, just make the Layer you just calculated '
        'with InaSAFE active again in the Layers list of QGIS.'
    )))

    header = m.Heading(tr('The Buttons Area'), **INFO_STYLE)
    message.add(header)

    message.add(m.Paragraph(tr(
        'The buttons area contains four buttons:')))
    bullets = m.BulletedList()
    bullets.add(m.Text(
        m.ImportantText(tr('Help')),
        tr(
            '- click on this if you need context help, such as the document '
            'you are reading right now!')))
    bullets.add(m.Text(
        m.ImportantText(tr('About')),
        tr(
            '- click on this to see short credits for the InaSAFE project.')))
    bullets.add(m.Text(
        m.ImportantText(tr('Help')),
        tr(
            'Print... - click on this if you wish to create a pdf of your '
            'impact scenarion project or just generate report and open it in '
            'composer for further tuning. An impact layer must be active '
            'before the Print button will be enabled.')))
    bullets.add(m.Text(
        m.ImportantText(tr('Run')),
        tr(
            '- Run - if the combination of options in the Questions area\'s '
            'combo boxes will allow you to run a scenario, this button is '
            'enabled.')))
    message.add(bullets)

    header = m.Heading(tr('Data conversions'), **INFO_STYLE)
    message.add(header)

    message.add(m.Paragraph(tr(
        'When running a scenario, the data being used needs to be processed '
        'into a state where it is acceptable for use by the impact function. '
        'In particular it should be noted that:')))

    bullets = m.BulletedList()
    bullets.add(tr(
        'Remote datasets will be copied locally before processing.'))
    bullets.add(m.Text(
        tr(
            'All datasets will be clipped to the intersection of the hazard '
            'layer, exposure layer and the current view extents unless '
            'you have specified a different clipping behaviour in the '
            'extents selector dialog.'),
        m.Image(
            'file:///%s/img/icons/'
            'set-extents-tool.svg' % resources_path(),
            **SMALL_ICON_STYLE)
    ))
    bullets.add(tr(
        'All clipped datasets will be converted (reprojected) to Geographic '
        '(EPSG:4326) coordinate reference system before analysis.'))
    message.add(bullets)

    header = m.Heading(tr('Analysis parameters'), **INFO_STYLE)
    message.add(header)
    # this adds the help content from the IF options dialog
    message.add(options())

    header = m.Heading(tr('Generating impact reports'), **INFO_STYLE)
    message.add(header)

    message.add(m.Paragraph(tr(
        'When the scenario analysis completed you may want to generate a '
        'report. Usually the "Print..."  button will be enabled immediately '
        'after analysis. Selecting an InaSAFE impact layer in QGIS Layers '
        'panel will also enable it.'
    )))

    # This adds the help content of the print dialog
    message.add(report())
    return message
Beispiel #21
0
def field_mapping_help_content():
    """Helper method that returns just the content in extent mode.

    This method was added so that the text could be reused in the
    wizard.

    :returns: A message object without brand element.
    :rtype: safe.messaging.message.Message
    """
    message = m.Message()
    paragraph = m.Paragraph(
        tr('Field mapping describes the process of matching one or more fields '
           'in an attribute table to a concept in InaSAFE. The field mappings '
           'tool InaSAFE allows you to match concepts such as "elderly", '
           '"disabled people", "pregnant" and so on to their counterpart fields '
           'in either an aggregation layer or an exposure population vector '
           'layer.'))
    message.add(paragraph)
    paragraph = m.Paragraph(
        m.ImportantText(
            'Note: It is not possible to use this tool with raster population '
            'exposure data, but ratios defined in aggregation layers will be '
            'used when raster exposure population data is used.'))
    message.add(paragraph)

    paragraph = m.Paragraph(m.Image('file:///%s/img/screenshots/'
                                    'demographic-concepts-screenshot.png' %
                                    resources_path()),
                            style_class='text-center')
    message.add(paragraph)

    paragraph = m.Paragraph(
        tr('The illustration above shows the principle behind InaSAFE\'s '
           'demographic breakdown reporting system. The idea here is to support '
           'the production of a detailed demographic breakdown when carrying out '
           'an analysis with a population exposure vector dataset. So for '
           'example instead of simply reporting on the total number of people '
           'exposed to a hazard, we want to break down the affected population '
           'into distinct demographic groups. In InaSAFE by default we consider '
           'three groups:'))
    message.add(paragraph)

    bullets = m.BulletedList()
    bullets.add(
        m.Paragraph(
            m.ImportantText(tr('Gender: ')),
            tr('The gender group reports on gender specific demographics '
               'including things like the number of women of child bearing age, '
               'number of pregnant women, number of lactating women and so on.'
               )))
    bullets.add(
        m.Paragraph(
            m.ImportantText(tr('Age: ')),
            tr('The age group reports on age specific demographics including '
               'things like the number of infants, children, young adults, '
               'adults elderly people and so on.')))
    bullets.add(
        m.Paragraph(
            m.ImportantText(tr('Vulnerable people: ')),
            tr('The vulnerable people group reports on specific demographics '
               'relating to vulnerability including things like the number of '
               'infants, elderly people, disabled people and so on.')))
    message.add(bullets)
    paragraph = m.Paragraph(
        tr('In the diagram above, you can see that we have an "age" group '
           '(column on the right) which, for purposes of illustration, has two '
           'age classes: "infant" and "child" (center column). These age classes '
           'are defined in InaSAFE metadata and there are actually five classes '
           'in a default installation. In the left hand column you can see a '
           'number of columns listed from the attribute table. In this example '
           'our population data contains columns for different age ranges ('
           '0-1, 1-2, 2-4, 4-6). The field mapping tool can be used in order '
           'to combine the data in the "0 - 1" and "1 - 2" columns into a '
           'new column called "infant". In the next section of this document we '
           'enumerate the different groups and concepts that InaSAFE supports '
           'when generating demographic breakdowns.'))
    message.add(paragraph)
    paragraph = m.Paragraph(
        tr('When the tool is used, it will write additional data to the '
           'exposure or aggregation layer keywords so that your preferred '
           'concept mappings will be used when reports are generated after the '
           'analysis is carried out. You should note the following special '
           'characteristics of the field mapping tool when used for aggregation '
           'datasets versus when used for vector population exposure datasets:'
           ))
    message.add(paragraph)
    paragraph = m.Paragraph(
        m.ImportantText(tr('Aggregation datasets: ')),
        tr('For aggregation datasets, the field mapping tool uses global '
           'defaults (see the InaSAFE Options Dialog documentation for more '
           'details) or dataset level defaults to determine which ratios '
           'should be used to calculate concept values. For example, in the '
           'age group the aggregation dataset may specify that infants '
           'should by calculated as a ratio of 0.1% of the total population. '
           'Note that for aggregation datasets you can only use ratios, '
           'not counts.'))
    message.add(paragraph)
    paragraph = m.Paragraph(
        m.ImportantText(tr('Vector population exposure datasets: ')),
        tr('For exposure datasets, ratios are not supported, only counts. '
           'The field mappings carried out here will be used to generate '
           'new columns during a pre-processing step before the actual '
           'analysis is carried out.'))
    message.add(paragraph)
    paragraph = m.Paragraph(
        tr('The interplay between default ratios, aggregation layer '
           'provided ratios and population exposure layers is illustrated '
           'in the table below.'))
    message.add(paragraph)

    table = m.Table(style_class='table table-condensed table-striped')
    row = m.Row()
    row.add(m.Cell(tr('Aggregation'), header=True))
    row.add(m.Cell(tr('Raster'), header=True))
    row.add(m.Cell(tr('Vector, no counts'), header=True))
    row.add(m.Cell(tr('Vector with counts'), header=True))
    row.add(m.Cell(tr('Notes'), header=True))
    table.add(row)
    row = m.Row([
        tr('No aggregation'),
        tr('Use global default ratio'),
        tr('Use global default ratio'),
        tr('Use count to determine ratio'),
        tr(''),
    ])
    table.add(row)
    row = m.Row([
        tr('Aggregation, ratio not set'),
        tr('Use global default ratio'),
        tr('Do nothing'),
        tr('Use count to determine ratio'),
        tr(''),
    ])
    table.add(row)
    row = m.Row([
        tr('Aggregation, ratio value set'),
        tr('Use aggregation layer ratio'),
        tr('Use aggregation layer ratio'),
        tr('Use count to determine ratio'),
        tr(''),
    ])
    table.add(row)
    row = m.Row([
        tr('Aggregation, ratio field mapping set'),
        tr('Use aggregation layer ratio'),
        tr('Use aggregation layer ratio'),
        tr('Use count to determine ratio'),
        tr(''),
    ])
    table.add(row)
    message.add(table)

    return message
Beispiel #22
0
def content():
    """Helper method that returns just the content.

    This method was added so that the text could be reused in the
    dock_help module.

    .. versionadded:: 4.0.0

    :returns: A message object without brand element.
    :rtype: safe.messaging.message.Message
    """
    # We will store a contents section at the top for easy navigation
    table_of_contents = m.Message()
    # and this will be the main message that we create
    message = m.Message()

    _create_section_header(message,
                           table_of_contents,
                           'overview',
                           tr('Overview'),
                           heading_level=1)
    ##
    # Credits and disclaimers ...
    ##
    _create_section_header(message,
                           table_of_contents,
                           'disclaimer',
                           tr('Disclaimer'),
                           heading_level=2)
    message.add(m.Paragraph(definitions.messages.disclaimer()))

    _create_section_header(message,
                           table_of_contents,
                           'limitations',
                           tr('Limitations and License'),
                           heading_level=2)
    bullets = m.BulletedList()
    for item in definitions.limitations():
        bullets.add(item)
    message.add(bullets)

    ##
    # Basic concepts ...
    ##
    ##
    # Help dialog contents ...
    ##
    _create_section_header(message,
                           table_of_contents,
                           'glossary',
                           tr('Glossary of terms'),
                           heading_level=1)

    last_group = None
    table = None
    for key, value in definitions.concepts.iteritems():
        current_group = value['group']
        if current_group != last_group:
            if last_group is not None:
                message.add(table)
            _create_section_header(message,
                                   table_of_contents,
                                   current_group.replace(' ', '-'),
                                   current_group,
                                   heading_level=2)
            table = _start_glossary_table(current_group)
            last_group = current_group
        row = m.Row()
        term = value['key'].replace('_', ' ').title()
        description = m.Message(value['description'])
        for citation in value['citations']:
            if citation['text'] in [None, '']:
                continue
            if citation['link'] in [None, '']:
                description.add(m.Paragraph(citation['text']))
            else:
                description.add(
                    m.Paragraph(m.Link(citation['link'], citation['text'])))
        row.add(m.Cell(term))
        row.add(m.Cell(description))
        url = _definition_icon_url(value)
        if url:
            row.add(m.Cell(m.Image(url, **MEDIUM_ICON_STYLE)))
        else:
            row.add(m.Cell(''))
        table.add(row)
    # ensure the last group's table is added
    message.add(table)

    ##
    # Help dialog contents ...
    ##
    _create_section_header(message,
                           table_of_contents,
                           'core-functionality',
                           tr('Core functionality and tools'),
                           heading_level=1)

    _create_section_header(message,
                           table_of_contents,
                           'dock',
                           tr('The InaSAFE Dock'),
                           heading_level=2)
    message.add(dock_help())

    _create_section_header(message,
                           table_of_contents,
                           'reports',
                           tr('InaSAFE Reports'),
                           heading_level=2)
    message.add(report_help())

    _create_section_header(
        message,
        table_of_contents,
        'extents',
        tr('Managing analysis extents with the extents selector'),
        heading_level=2)
    message.add(extent_help())

    _create_section_header(message,
                           table_of_contents,
                           'options',
                           tr('InaSAFE Options'),
                           heading_level=2)
    message.add(options_help())

    _create_section_header(message,
                           table_of_contents,
                           'batch-runner',
                           tr('The Batch Runner'),
                           heading_level=2)
    message.add(batch_help())

    _create_section_header(message,
                           table_of_contents,
                           'osm-downloader',
                           tr('The OpenStreetmap Downloader'),
                           heading_level=2)
    message.add(osm_help())

    _create_section_header(message,
                           table_of_contents,
                           'petabencana-downloader',
                           tr('The PetaBencana Downloader'),
                           heading_level=2)
    message.add(petabencana_help())

    _create_section_header(message,
                           table_of_contents,
                           'shakemap-converter',
                           tr('The Shakemap Converter'),
                           heading_level=2)
    message.add(shakemap_help())

    _create_section_header(message,
                           table_of_contents,
                           'multi-buffer-tool',
                           tr('The Multi Buffer Tool'),
                           heading_level=2)
    message.add(multi_buffer_help())

    # Field mapping tool has a few added bits to enumerate the groups
    _create_section_header(message,
                           table_of_contents,
                           'field-mapping-tool',
                           tr('The Field Mapping Tool'),
                           heading_level=2)
    message.add(field_mapping_tool_help())

    _create_section_header(message,
                           table_of_contents,
                           'exposure-groups',
                           tr('Exposure Groups'),
                           heading_level=3)
    message.add(
        m.Paragraph(
            'The following demographic groups apply only to vector population '
            'exposure layers:'))
    for group in population_field_groups:
        definition_to_message(group,
                              message,
                              table_of_contents,
                              heading_level=4)

    _create_section_header(message,
                           table_of_contents,
                           'aggregation-groups',
                           tr('Aggregation Groups'),
                           heading_level=3)
    message.add(
        m.Paragraph(
            'The following demographic groups apply only to aggregation layers:'
        ))
    for group in aggregation_field_groups:
        definition_to_message(group,
                              message,
                              table_of_contents,
                              heading_level=4)

    # End of field mapping tool help

    # Keep this last in the tool section please as it has subsections
    # and so uses the top level section style
    _create_section_header(message,
                           table_of_contents,
                           'minimum-needs',
                           tr('Minimum Needs'),
                           heading_level=2)
    _create_section_header(message,
                           table_of_contents,
                           'minimum-needs-tool',
                           tr('The minimum needs tool'),
                           heading_level=3)
    message.add(needs_help())
    _create_section_header(message,
                           table_of_contents,
                           'minimum-manager',
                           tr('The minimum needs manager'),
                           heading_level=3)
    message.add(needs_manager_help())

    ##
    #  Analysis workflow
    ##

    _create_section_header(message,
                           table_of_contents,
                           'analysis-steps',
                           tr('Analysis steps'),
                           heading_level=1)
    _create_section_header(message,
                           table_of_contents,
                           'analysis-internal-process',
                           tr('Analysis internal process'),
                           heading_level=2)
    analysis = definitions.concepts['analysis']
    message.add(analysis['description'])
    url = _definition_screenshot_url(analysis)
    if url:
        message.add(m.Paragraph(m.Image(url), style_class='text-center'))

    _create_section_header(message,
                           table_of_contents,
                           'analysis-progress-reporting',
                           tr('Progress reporting steps'),
                           heading_level=2)
    steps = definitions.analysis_steps.values()
    for step in steps:
        definition_to_message(step,
                              message,
                              table_of_contents,
                              heading_level=3)

    ##
    #  Hazard definitions
    ##

    _create_section_header(message,
                           table_of_contents,
                           'hazards',
                           tr('Hazard Concepts'),
                           heading_level=1)

    hazard_category = definitions.hazard_category
    definition_to_message(hazard_category,
                          message,
                          table_of_contents,
                          heading_level=2)

    hazards = definitions.hazards
    definition_to_message(hazards, message, table_of_contents, heading_level=2)

    ##
    #  Exposure definitions
    ##

    _create_section_header(message,
                           table_of_contents,
                           'exposures',
                           tr('Exposure Concepts'),
                           heading_level=1)
    exposures = definitions.exposures

    definition_to_message(exposures,
                          message,
                          table_of_contents,
                          heading_level=2)

    ##
    #  Defaults
    ##

    _create_section_header(message,
                           table_of_contents,
                           'defaults',
                           tr('InaSAFE Defaults'),
                           heading_level=1)
    table = m.Table(style_class='table table-condensed table-striped')
    row = m.Row()
    row.add(m.Cell(tr('Name'), header=True))
    row.add(m.Cell(tr('Default value'), header=True))
    row.add(m.Cell(tr('Default min'), header=True))
    row.add(m.Cell(tr('Default max'), header=True))
    row.add(m.Cell(tr('Description'), header=True))
    table.add(row)
    defaults = [
        definitions.youth_ratio_default_value,
        definitions.adult_ratio_default_value,
        definitions.elderly_ratio_default_value,
        definitions.female_ratio_default_value,
        definitions.feature_rate_default_value
    ]
    for default in defaults:
        row = m.Row()
        row.add(m.Cell(default['name']))
        row.add(m.Cell(default['default_value']))
        row.add(m.Cell(default['min_value']))
        row.add(m.Cell(default['max_value']))
        row.add(m.Cell(default['description']))
        table.add(row)
    message.add(table)

    ##
    #  All Fields
    ##

    _create_section_header(message,
                           table_of_contents,
                           'all-fields',
                           tr('Fields'),
                           heading_level=1)
    _create_section_header(message,
                           table_of_contents,
                           'input-fields',
                           tr('Input dataset fields'),
                           heading_level=2)
    _create_fields_section(message, table_of_contents, tr('Exposure fields'),
                           definitions.exposure_fields)
    _create_fields_section(message, table_of_contents, tr('Hazard fields'),
                           definitions.hazard_fields)
    _create_fields_section(message, table_of_contents,
                           tr('Aggregation fields'),
                           definitions.aggregation_fields)
    _create_section_header(message,
                           table_of_contents,
                           'output-fields',
                           tr('Output dataset fields'),
                           heading_level=2)
    _create_fields_section(message, table_of_contents, tr('Impact fields'),
                           definitions.impact_fields)
    _create_fields_section(message, table_of_contents,
                           tr('Aggregate hazard fields'),
                           definitions.aggregate_hazard_fields)
    _create_fields_section(message, table_of_contents,
                           tr('Aggregation summary fields'),
                           definitions.aggregation_summary_fields)
    _create_fields_section(message, table_of_contents,
                           tr('Exposure summary table fields'),
                           definitions.exposure_summary_table_fields)
    _create_fields_section(message, table_of_contents, tr('Analysis fields'),
                           definitions.analysis_fields)

    ##
    #  Geometries
    ##

    _create_section_header(message,
                           table_of_contents,
                           'geometries',
                           tr('Layer Geometry Types'),
                           heading_level=1)
    _create_section_header(message,
                           table_of_contents,
                           'vector-geometries',
                           tr('Vector'),
                           heading_level=2)
    definition_to_message(definitions.layer_geometry_point,
                          message,
                          table_of_contents,
                          heading_level=3)
    definition_to_message(definitions.layer_geometry_line,
                          message,
                          table_of_contents,
                          heading_level=3)
    definition_to_message(definitions.layer_geometry_polygon,
                          message,
                          table_of_contents,
                          heading_level=3)
    _create_section_header(message,
                           table_of_contents,
                           'raster-geometries',
                           tr('Raster'),
                           heading_level=2)
    definition_to_message(definitions.layer_geometry_raster,
                          message,
                          table_of_contents,
                          heading_level=3)

    ##
    #  Layer Modes
    ##

    _create_section_header(message,
                           table_of_contents,
                           'layer-modes',
                           tr('Layer Modes'),
                           heading_level=1)
    definition_to_message(definitions.layer_mode,
                          message,
                          table_of_contents,
                          heading_level=2)

    ##
    #  Layer Purposes
    ##

    _create_section_header(message,
                           table_of_contents,
                           'layer-purposes',
                           tr('Layer Purposes'),
                           heading_level=1)
    definition_to_message(definitions.layer_purpose_hazard,
                          message,
                          table_of_contents,
                          heading_level=2)
    definition_to_message(definitions.layer_purpose_exposure,
                          message,
                          table_of_contents,
                          heading_level=2)
    definition_to_message(definitions.layer_purpose_aggregation,
                          message,
                          table_of_contents,
                          heading_level=2)
    definition_to_message(definitions.layer_purpose_exposure_summary,
                          message,
                          table_of_contents,
                          heading_level=2)
    definition_to_message(definitions.layer_purpose_aggregate_hazard_impacted,
                          message,
                          table_of_contents,
                          heading_level=2)
    definition_to_message(definitions.layer_purpose_aggregation_summary,
                          message,
                          table_of_contents,
                          heading_level=2)
    definition_to_message(definitions.layer_purpose_exposure_summary_table,
                          message,
                          table_of_contents,
                          heading_level=2)
    definition_to_message(definitions.layer_purpose_profiling,
                          message,
                          table_of_contents,
                          heading_level=2)

    ##
    # All units
    ##

    _create_section_header(message,
                           table_of_contents,
                           'all-units',
                           tr('All Units'),
                           heading_level=1)
    table = m.Table(style_class='table table-condensed table-striped')
    row = m.Row()
    row.add(m.Cell(tr('Name'), header=True))
    row.add(m.Cell(tr('Plural'), header=True))
    row.add(m.Cell(tr('Abbreviation'), header=True))
    row.add(m.Cell(tr('Details'), header=True))
    table.add(row)
    for unit in definitions.units_all:
        row = m.Row()
        row.add(m.Cell(unit['name']))
        row.add(m.Cell(unit['plural_name']))
        row.add(m.Cell(unit['abbreviation']))
        row.add(m.Cell(unit['description']))
        table.add(row)
    message.add(table)

    ##
    #  Post processors
    ##

    _create_section_header(message,
                           table_of_contents,
                           'post-processors',
                           tr('Post Processors'),
                           heading_level=1)
    _create_section_header(message,
                           table_of_contents,
                           'post-processor-input-types',
                           tr('Post Processor Input Types'),
                           heading_level=2)
    table = _create_post_processor_subtable(post_processor_input_types)
    message.add(table)

    _create_section_header(message,
                           table_of_contents,
                           'post-processor-input-values',
                           tr('Post Processor Input Values'),
                           heading_level=2)
    table = _create_post_processor_subtable(post_processor_input_values)
    message.add(table)

    _create_section_header(message,
                           table_of_contents,
                           'post-processor-process-values',
                           tr('Post Processor Process Types'),
                           heading_level=2)
    table = _create_post_processor_subtable(
        definitions.post_processor_process_types)
    message.add(table)

    _create_section_header(message,
                           table_of_contents,
                           'post-processors',
                           tr('Post Processors'),
                           heading_level=2)
    post_processors = safe.definitions.post_processors
    table = m.Table(style_class='table table-condensed table-striped')
    row = m.Row()
    row.add(m.Cell(tr('Name'), header=True))
    row.add(m.Cell(tr('Input Fields'), header=True))
    row.add(m.Cell(tr('Output Fields'), header=True))
    table.add(row)
    for post_processor in post_processors:
        row = m.Row()
        row.add(m.Cell(post_processor['name']))
        # Input fields
        bullets = m.BulletedList()
        for key, value in post_processor['input'].iteritems():
            bullets.add(key)
        row.add(m.Cell(bullets))
        # Output fields
        bullets = m.BulletedList()
        for key, value in post_processor['output'].iteritems():
            name = value['value']['name']
            formula_type = value['type']['key']
            if formula_type == 'formula':
                formula = value['formula']
            else:
                # We use python introspection because the processor
                # uses a python function for calculations
                formula = value['function'].__name__
                formula += ' ('
                formula += value['function'].__doc__
                formula += ')'
            bullets.add('%s  %s. : %s' % (name, formula_type, formula))

        row.add(m.Cell(bullets))
        table.add(row)
        # Add the descriptions
        row = m.Row()
        row.add(m.Cell(''))
        row.add(m.Cell(post_processor['description'], span=2))
        table.add(row)
    message.add(table)

    ##
    # Developer documentation
    ##

    _create_section_header(message,
                           table_of_contents,
                           'developer-guide',
                           tr('Developer Guide'),
                           heading_level=1)
    message.add(developer_help())

    # Finally we add the table of contents at the top
    full_message = m.Message()
    # Contents is not a link so reset style
    style = SECTION_STYLE
    style['element_id'] = ''
    header = m.Heading(tr('Contents'), **style)
    full_message.add(header)
    full_message.add(table_of_contents)
    full_message.add(message)
    return full_message
Beispiel #23
0
from safe import messaging as m
from safe.messaging import styles
from safe.common.exceptions import (InsufficientOverlapError,
                                    TemplateLoadingError)
from safe.report.impact_report import ImpactReport
from safe.gui.tools.impact_report_dialog import ImpactReportDialog
from safe_extras.pydispatch import dispatcher
from safe.utilities.analysis import Analysis
from safe.utilities.extent import Extent

PROGRESS_UPDATE_STYLE = styles.PROGRESS_UPDATE_STYLE
INFO_STYLE = styles.INFO_STYLE
WARNING_STYLE = styles.WARNING_STYLE

LOGO_ELEMENT = m.Image(
    resource_url(resources_path('img', 'logos', 'inasafe-logo.png')),
    'InaSAFE Logo')
LOGGER = logging.getLogger('InaSAFE')


class AnalysisHandler(QObject):
    """Analysis handler for the dock and the wizard."""

    analysisDone = pyqtSignal(bool)

    # noinspection PyUnresolvedReferences
    def __init__(self, parent):
        """Constructor for the class.

        :param parent: Parent widget i.e. the wizard dialog.
        :type parent: QWidget
Beispiel #24
0
def content():
    """Helper method that returns just the content.

    This method was added so that the text could be reused in the
    dock_help module.

    .. versionadded:: 3.2.2

    :returns: A message object without brand element.
    :rtype: safe.messaging.message.Message
    """
    message = m.Message()
    paragraph = m.Paragraph(m.Image('file:///%s/img/screenshots/'
                                    'osm-downloader-screenshot.png' %
                                    resources_path()),
                            style_class='text-center')
    message.add(paragraph)
    body = tr('This tool will fetch building (\'structure\') or road ('
              '\'highway\') data from the OpenStreetMap project for you. '
              'The downloaded data will have InaSAFE keywords defined and a '
              'default QGIS style applied. To use this tool effectively:')
    tips = m.BulletedList()
    tips.add(
        tr('Your current extent, when opening this window, will be used to '
           'determine the area for which you want data to be retrieved. '
           'You can interactively select the area by using the '
           '\'select on map\' button - which will temporarily hide this '
           'window and allow you to drag a rectangle on the map. After you '
           'have finished dragging the rectangle, this window will '
           'reappear.'))
    tips.add(
        tr('Check the output directory is correct. Note that the saved '
           'dataset will be named after the type of data being downloaded '
           'e.g. roads.shp or buildings.shp (and associated files).'))
    tips.add(
        tr('By default simple file names will be used (e.g. roads.shp, '
           'buildings.shp). If you wish you can specify a prefix to '
           'add in front of this default name. For example using a prefix '
           'of \'padang-\' will cause the downloaded files to be saved as '
           '\'padang-roads.shp\' and \'padang-buildings.shp\'. Note that '
           'the only allowed prefix characters are A-Z, a-z, 0-9 and the '
           'characters \'-\' and \'_\'. You can leave this blank if you '
           'prefer.'))
    tips.add(
        tr('If a dataset already exists in the output directory it will be '
           'overwritten.'))
    tips.add(
        tr('This tool requires a working internet connection and fetching '
           'buildings or roads will consume your bandwidth.'))
    tips.add(
        m.Link('http://www.openstreetmap.org/copyright',
               text=tr(
                   'Downloaded data is copyright OpenStreetMap contributors '
                   '(click for more info).')))
    message.add(m.Paragraph(body))
    message.add(tips)

    message.add(
        m.Paragraph(
            # format 'When the __Political boundaries__' for proper i18n
            tr('When the %s '
               'box in the Feature types menu is ticked, the Political boundary '
               'options panel will be enabled. The panel lets you select which '
               'admin level you wish to download. The admin levels are country '
               'specific. When you select an admin level, the local name for '
               'that admin level will be shown. You can change which country '
               'is used for the admin level description using the country drop '
               'down menu. The country will be automatically set to coincide '
               'with the view extent if a matching country can be found.') %
            (m.ImportantText(tr('Political boundaries')).to_html(), )))
    message.add(
        m.Paragraph(
            m.ImportantText(tr('Note: ')),
            tr('We have only provide presets for a subset of the available '
               'countries. If you want to know what the levels are for your '
               'country, please check on the following web page: '),
            m.Link(
                'http://wiki.openstreetmap.org/wiki/Tag:boundary%3Dadministrative',
                text=tr('List of OSM Admin Boundary definitions '))))

    return message
Beispiel #25
0
def definition_to_message(definition,
                          message=None,
                          table_of_contents=None,
                          heading_level=None):
    """Helper function to render a definition to a message.

    :param definition: A definition dictionary (see definitions package).
    :type definition: dict

    :param message: The message that the definition should be appended to.
    :type message: safe_extras.parameters.message.Message

    :param table_of_contents: Table of contents that the headings should be
        included in.
    :type message: safe_extras.parameters.message.Message

    :param heading_level: Optional style to apply to the definition
        heading. See HEADING_LOOKUPS
    :type heading_level: int

    :returns: Message
    :rtype: str
    """

    if message is None:
        message = m.Message()

    if table_of_contents is None:
        table_of_contents = m.Message()

    if heading_level:
        _create_section_header(message,
                               table_of_contents,
                               definition['name'].replace(' ', '-'),
                               definition['name'],
                               heading_level=heading_level)
    else:
        header = m.Paragraph(m.ImportantText(definition['name']))
        message.add(header)

    # If the definition has an icon, we put the icon and description side by
    # side in a table otherwise just show the description as a paragraph
    url = _definition_icon_url(definition)
    if url is None:
        message.add(m.Paragraph(definition['description']))
        if 'citations' in definition:
            _citations_to_message(message, definition)
    else:
        LOGGER.info('Creating mini table for definition description: ' + url)
        table = m.Table(style_class='table table-condensed')
        row = m.Row()
        row.add(m.Cell(m.Image(url, **MEDIUM_ICON_STYLE)))
        row.add(m.Cell(definition['description']))
        table.add(row)
        for citation in definition['citations']:
            if citation['text'] in [None, '']:
                continue
            row = m.Row()
            row.add(m.Cell(''))
            if citation['link'] in [None, '']:
                row.add(m.Cell(citation['text']))
            else:
                row.add(m.Cell(m.Link(citation['link'], citation['text'])))
            table.add(row)
        message.add(table)

    url = _definition_screenshot_url(definition)
    if url:
        message.add(m.Paragraph(m.Image(url), style_class='text-center'))

    # types contains e.g. hazard_all
    if 'types' in definition:
        for sub_definition in definition['types']:
            definition_to_message(sub_definition,
                                  message,
                                  table_of_contents,
                                  heading_level=3)

    #
    # Notes section if available
    #

    if 'notes' in definition:
        # Start a notes details group too since we have an exposure
        message.add(m.Heading(tr('Notes:'), **DETAILS_STYLE))
        message.add(m.Heading(tr('General notes:'), **DETAILS_SUBGROUP_STYLE))
        bullets = m.BulletedList()
        for note in definition['notes']:
            if type(note) is dict:
                bullets = _add_dict_to_bullets(bullets, note)
            elif note:
                bullets.add(m.Text(note))
        message.add(bullets)
        if 'citations' in definition:
            _citations_to_message(message, definition)

    # This only for EQ
    if 'earthquake_fatality_models' in definition:
        current_function = current_earthquake_model_name()
        paragraph = m.Paragraph(
            'The following earthquake fatality models are available in '
            'InaSAFE. Note that you need to set one of these as the '
            'active model in InaSAFE Options. The currently active model is: ',
            m.ImportantText(current_function))
        message.add(paragraph)

        models_definition = definition['earthquake_fatality_models']
        for model in models_definition:
            message.add(m.Heading(model['name'], **DETAILS_SUBGROUP_STYLE))
            if 'description' in model:
                paragraph = m.Paragraph(model['description'])
                message.add(paragraph)
            for note in model['notes']:
                paragraph = m.Paragraph(note)
                message.add(paragraph)
            _citations_to_message(message, model)

    for exposure in exposure_all:
        extra_exposure_notes = specific_notes(definition, exposure)
        if extra_exposure_notes:
            title = tr(u'Notes for exposure : {exposure_name}').format(
                exposure_name=exposure['name'])
            message.add(m.Heading(title, **DETAILS_SUBGROUP_STYLE))
            bullets = m.BulletedList()
            for note in extra_exposure_notes:
                if type(note) is dict:
                    bullets = _add_dict_to_bullets(bullets, note)
                elif note:
                    bullets.add(m.Text(note))
            message.add(bullets)

    if 'continuous_notes' in definition:
        message.add(
            m.Heading(tr('Notes for continuous datasets:'),
                      **DETAILS_SUBGROUP_STYLE))
        bullets = m.BulletedList()
        for note in definition['continuous_notes']:
            bullets.add(m.Text(note))
        message.add(bullets)

    if 'classified_notes' in definition:
        message.add(
            m.Heading(tr('Notes for classified datasets:'),
                      **DETAILS_SUBGROUP_STYLE))
        bullets = m.BulletedList()
        for note in definition['classified_notes']:
            bullets.add(m.Text(note))
        message.add(bullets)

    if 'single_event_notes' in definition:
        message.add(m.Heading(tr('Notes for single events'), **DETAILS_STYLE))
        if len(definition['single_event_notes']) < 1:
            message.add(m.Paragraph(tr('No single event notes defined.')))
        else:
            bullets = m.BulletedList()
            for note in definition['single_event_notes']:
                bullets.add(m.Text(note))
            message.add(bullets)

    if 'multi_event_notes' in definition:
        message.add(
            m.Heading(tr('Notes for multi events / scenarios:'),
                      **DETAILS_STYLE))
        if len(definition['multi_event_notes']) < 1:
            message.add(m.Paragraph(tr('No multi-event notes defined.')))
        else:
            bullets = m.BulletedList()
            for note in definition['multi_event_notes']:
                bullets.add(m.Text(note))
            message.add(bullets)

    if 'actions' in definition:
        message.add(m.Paragraph(m.ImportantText(tr('Actions:'))))
        bullets = m.BulletedList()
        for note in definition['actions']:
            if type(note) is dict:
                bullets = _add_dict_to_bullets(bullets, note)
            elif note:
                bullets.add(m.Text(note))
        message.add(bullets)

    for exposure in exposure_all:
        extra_exposure_actions = specific_actions(definition, exposure)
        if extra_exposure_actions:
            title = tr(u'Actions for exposure : {exposure_name}').format(
                exposure_name=exposure['name'])
            message.add(m.Heading(title, **DETAILS_SUBGROUP_STYLE))
            bullets = m.BulletedList()
            for note in extra_exposure_actions:
                if type(note) is dict:
                    bullets = _add_dict_to_bullets(bullets, note)
                elif note:
                    bullets.add(m.Text(note))
            message.add(bullets)

    if 'continuous_hazard_units' in definition:
        message.add(m.Paragraph(m.ImportantText(tr('Units:'))))
        table = m.Table(style_class='table table-condensed table-striped')
        row = m.Row()
        row.add(m.Cell(tr('Name'), header=True))
        row.add(m.Cell(tr('Plural'), header=True))
        row.add(m.Cell(tr('Abbreviation'), header=True))
        row.add(m.Cell(tr('Details'), header=True))
        table.add(row)
        for unit in definition['continuous_hazard_units']:
            row = m.Row()
            row.add(m.Cell(unit['name']))
            row.add(m.Cell(unit['plural_name']))
            row.add(m.Cell(unit['abbreviation']))
            row.add(m.Cell(unit['description']))
            table.add(row)
        message.add(table)

    if 'fields' in definition:
        message.add(m.Paragraph(m.ImportantText(tr('Fields:'))))
        table = _create_fields_table()

        if 'extra_fields' in definition:
            all_fields = definition['fields'] + definition['extra_fields']
        else:
            all_fields = definition['fields']

        for field in all_fields:
            _add_field_to_table(field, table)
        message.add(table)

    if 'classifications' in definition:
        message.add(m.Heading(tr('Hazard classifications'), **DETAILS_STYLE))
        message.add(
            m.Paragraph(definitions.hazard_classification['description']))
        for inasafe_class in definition['classifications']:
            definition_to_message(inasafe_class,
                                  message,
                                  table_of_contents,
                                  heading_level=3)

    if 'classes' in definition:
        message.add(m.Paragraph(m.ImportantText(tr('Classes:'))))
        is_hazard = definition['type'] == hazard_classification_type
        if is_hazard:
            table = _make_defaults_hazard_table()
        else:
            table = _make_defaults_exposure_table()

        for inasafe_class in definition['classes']:
            row = m.Row()
            if is_hazard:
                # name() on QColor returns its hex code
                if 'color' in inasafe_class:
                    colour = inasafe_class['color'].name()
                    row.add(
                        m.Cell(u'',
                               attributes='style="background: %s;"' % colour))
                else:
                    row.add(m.Cell(u' '))

            row.add(m.Cell(inasafe_class['name']))

            if is_hazard:
                if 'affected' in inasafe_class:
                    row.add(m.Cell(tr(inasafe_class['affected'])))
                else:
                    row.add(m.Cell(tr('unspecified')))

            if is_hazard:
                if inasafe_class.get('fatality_rate') > 0:
                    # we want to show the rate as a scientific notation
                    rate = html_scientific_notation_rate(
                        inasafe_class['fatality_rate'])
                    rate = u'%s%%' % rate
                    row.add(m.Cell(rate))
                elif inasafe_class.get('fatality_rate') == 0:
                    row.add(m.Cell('0%'))
                else:
                    row.add(m.Cell(tr('unspecified')))

            if is_hazard:
                if 'displacement_rate' in inasafe_class:
                    rate = inasafe_class['displacement_rate'] * 100
                    rate = u'%.0f%%' % rate
                    row.add(m.Cell(rate))
                else:
                    row.add(m.Cell(tr('unspecified')))

            if 'string_defaults' in inasafe_class:
                defaults = None
                for default in inasafe_class['string_defaults']:
                    if defaults:
                        defaults += ',%s' % default
                    else:
                        defaults = default
                row.add(m.Cell(defaults))
            else:
                row.add(m.Cell(tr('unspecified')))

            if is_hazard:
                # Min may be a single value or a dict of values so we need
                # to check type and deal with it accordingly
                if 'numeric_default_min' in inasafe_class:
                    if isinstance(inasafe_class['numeric_default_min'], dict):
                        bullets = m.BulletedList()
                        minima = inasafe_class['numeric_default_min']
                        for key, value in minima.iteritems():
                            bullets.add(u'%s : %s' % (key, value))
                        row.add(m.Cell(bullets))
                    else:
                        row.add(m.Cell(inasafe_class['numeric_default_min']))
                else:
                    row.add(m.Cell(tr('unspecified')))

            if is_hazard:
                # Max may be a single value or a dict of values so we need
                # to check type and deal with it accordingly
                if 'numeric_default_max' in inasafe_class:
                    if isinstance(inasafe_class['numeric_default_max'], dict):
                        bullets = m.BulletedList()
                        maxima = inasafe_class['numeric_default_max']
                        for key, value in maxima.iteritems():
                            bullets.add(u'%s : %s' % (key, value))
                        row.add(m.Cell(bullets))
                    else:
                        row.add(m.Cell(inasafe_class['numeric_default_max']))
                else:
                    row.add(m.Cell(tr('unspecified')))

            table.add(row)
            # Description goes in its own row with spanning
            row = m.Row()
            row.add(m.Cell(''))
            row.add(m.Cell(inasafe_class['description'], span=7))
            table.add(row)

        # For hazard classes we also add the 'not affected' class manually:
        if definition['type'] == definitions.hazard_classification_type:
            row = m.Row()
            colour = definitions.not_exposed_class['color'].name()
            row.add(m.Cell(u'', attributes='style="background: %s;"' % colour))
            description = definitions.not_exposed_class['description']
            row.add(m.Cell(description, span=7))
            table.add(row)

        message.add(table)

    if 'affected' in definition:
        if definition['affected']:
            message.add(
                m.Paragraph(
                    tr('Exposure entities in this class ARE considered affected'
                       )))
        else:
            message.add(
                m.Paragraph(
                    tr('Exposure entities in this class are NOT considered '
                       'affected')))

    if 'optional' in definition:
        if definition['optional']:
            message.add(
                m.Paragraph(
                    tr('This class is NOT required in the hazard keywords.')))
        else:
            message.add(
                m.Paragraph(
                    tr('This class IS required in the hazard keywords.')))

    return message