Ticket #18523: all.do_not_apply.patch

File all.do_not_apply.patch, 328.8 KB (added by taylor.smock, 6 years ago)

All of the modifications in my josm/core directory

  • .classpath

     
    3333                        <attribute name="test" value="true"/>
    3434                </attributes>
    3535        </classpathentry>
     36        <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/5">
     37                <attributes>
     38                        <attribute name="test" value="true"/>
     39                </attributes>
     40        </classpathentry>
    3641        <classpathentry kind="lib" path="test/lib/jfcunit.jar">
    3742                <attributes>
    3843                        <attribute name="test" value="true"/>
  • .settings/org.eclipse.jdt.core.prefs

     
    2424org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
    2525org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
    2626org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
     27org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
    2728org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
    2829org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
    2930org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
     
    8081org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
    8182org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
    8283org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
     84org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
    8385org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
    8486org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
    8587org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
     
    112114org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
    113115org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
    114116org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
     117org.eclipse.jdt.core.compiler.release=enabled
    115118org.eclipse.jdt.core.compiler.source=1.8
     119org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns=false
     120org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647
    116121org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
     122org.eclipse.jdt.core.formatter.align_variable_declarations_on_columns=false
     123org.eclipse.jdt.core.formatter.align_with_spaces=false
     124org.eclipse.jdt.core.formatter.alignment_for_additive_operator=16
    117125org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
    118126org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
    119127org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
     
    121129org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
    122130org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
    123131org.eclipse.jdt.core.formatter.alignment_for_assignment=0
    124 org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
     132org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator=16
    125133org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
     134org.eclipse.jdt.core.formatter.alignment_for_compact_loops=16
    126135org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
    127 org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
     136org.eclipse.jdt.core.formatter.alignment_for_conditional_expression_chain=0
     137org.eclipse.jdt.core.formatter.alignment_for_enum_constants=16
    128138org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
     139org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0
     140org.eclipse.jdt.core.formatter.alignment_for_logical_operator=16
    129141org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
     142org.eclipse.jdt.core.formatter.alignment_for_module_statements=16
    130143org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
     144org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
     145org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
    131146org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
    132147org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
     148org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
    133149org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
    134150org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
     151org.eclipse.jdt.core.formatter.alignment_for_shift_operator=0
     152org.eclipse.jdt.core.formatter.alignment_for_string_concatenation=16
    135153org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
    136154org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
    137155org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
    138156org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
    139157org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
     158org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0
     159org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0
    140160org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
    141161org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
    142162org.eclipse.jdt.core.formatter.blank_lines_after_package=1
     
    161181org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
    162182org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
    163183org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
     184org.eclipse.jdt.core.formatter.comment.align_tags_descriptions_grouped=true
     185org.eclipse.jdt.core.formatter.comment.align_tags_names_descriptions=false
    164186org.eclipse.jdt.core.formatter.comment.clear_blank_lines=false
    165187org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
    166188org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
    167 org.eclipse.jdt.core.formatter.comment.format_block_comments=false
     189org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position=true
     190org.eclipse.jdt.core.formatter.comment.format_block_comments=true
    168191org.eclipse.jdt.core.formatter.comment.format_comments=true
    169192org.eclipse.jdt.core.formatter.comment.format_header=false
    170 org.eclipse.jdt.core.formatter.comment.format_html=false
    171 org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=false
    172 org.eclipse.jdt.core.formatter.comment.format_line_comments=false
    173 org.eclipse.jdt.core.formatter.comment.format_source_code=false
    174 org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
     193org.eclipse.jdt.core.formatter.comment.format_html=true
     194org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
     195org.eclipse.jdt.core.formatter.comment.format_line_comments=true
     196org.eclipse.jdt.core.formatter.comment.format_source_code=true
     197org.eclipse.jdt.core.formatter.comment.indent_parameter_description=false
    175198org.eclipse.jdt.core.formatter.comment.indent_root_tags=false
    176 org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=do not insert
     199org.eclipse.jdt.core.formatter.comment.indent_tag_description=false
     200org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
    177201org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert
    178 org.eclipse.jdt.core.formatter.comment.line_length=100
     202org.eclipse.jdt.core.formatter.comment.line_length=80
    179203org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
    180204org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
    181205org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
     
    185209org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
    186210org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
    187211org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
    188 org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
     212org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=false
    189213org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
    190214org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
    191215org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
     
    196220org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
    197221org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
    198222org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
    199 org.eclipse.jdt.core.formatter.indentation.size=4
     223org.eclipse.jdt.core.formatter.indentation.size=8
     224org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert
    200225org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
    201226org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
    202227org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
     
    219244org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=do not insert
    220245org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
    221246org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=do not insert
     247org.eclipse.jdt.core.formatter.insert_space_after_additive_operator=insert
    222248org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
    223249org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
    224250org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
    225251org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
    226 org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
    227 org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
     252org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator=insert
     253org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=do not insert
    228254org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
    229255org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
    230256org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
     
    254280org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
    255281org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
    256282org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert
     283org.eclipse.jdt.core.formatter.insert_space_after_logical_operator=insert
     284org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator=insert
    257285org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
    258286org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
    259287org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
     
    278306org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
    279307org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
    280308org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
     309org.eclipse.jdt.core.formatter.insert_space_after_relational_operator=insert
    281310org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
    282311org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
     312org.eclipse.jdt.core.formatter.insert_space_after_shift_operator=insert
     313org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation=insert
    283314org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
     315org.eclipse.jdt.core.formatter.insert_space_before_additive_operator=insert
    284316org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
    285317org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
    286318org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
    287 org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
     319org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator=insert
    288320org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
    289321org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
    290322org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
     
    332364org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
    333365org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
    334366org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert
     367org.eclipse.jdt.core.formatter.insert_space_before_logical_operator=insert
     368org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator=insert
    335369org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
    336370org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
    337371org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
     
    368402org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
    369403org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
    370404org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
     405org.eclipse.jdt.core.formatter.insert_space_before_relational_operator=insert
    371406org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
    372407org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
    373408org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
     409org.eclipse.jdt.core.formatter.insert_space_before_shift_operator=insert
     410org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation=insert
    374411org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
    375412org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
    376413org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
     
    382419org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
    383420org.eclipse.jdt.core.formatter.join_lines_in_comments=true
    384421org.eclipse.jdt.core.formatter.join_wrapped_lines=true
     422org.eclipse.jdt.core.formatter.keep_annotation_declaration_on_one_line=one_line_never
     423org.eclipse.jdt.core.formatter.keep_anonymous_type_declaration_on_one_line=one_line_never
     424org.eclipse.jdt.core.formatter.keep_code_block_on_one_line=one_line_never
    385425org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
    386426org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
     427org.eclipse.jdt.core.formatter.keep_enum_constant_declaration_on_one_line=one_line_never
     428org.eclipse.jdt.core.formatter.keep_enum_declaration_on_one_line=one_line_never
     429org.eclipse.jdt.core.formatter.keep_if_then_body_block_on_one_line=one_line_never
    387430org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
     431org.eclipse.jdt.core.formatter.keep_lambda_body_block_on_one_line=one_line_never
     432org.eclipse.jdt.core.formatter.keep_loop_body_block_on_one_line=one_line_never
     433org.eclipse.jdt.core.formatter.keep_method_body_on_one_line=one_line_never
     434org.eclipse.jdt.core.formatter.keep_simple_do_while_body_on_same_line=false
     435org.eclipse.jdt.core.formatter.keep_simple_for_body_on_same_line=false
     436org.eclipse.jdt.core.formatter.keep_simple_getter_setter_on_one_line=false
     437org.eclipse.jdt.core.formatter.keep_simple_while_body_on_same_line=false
    388438org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
     439org.eclipse.jdt.core.formatter.keep_type_declaration_on_one_line=one_line_never
    389440org.eclipse.jdt.core.formatter.lineSplit=120
    390441org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
    391442org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
    392443org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
    393444org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
     445org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines
     446org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines
     447org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines
     448org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines
     449org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines
     450org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines
     451org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines
     452org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines
     453org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines
     454org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines
    394455org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
    395456org.eclipse.jdt.core.formatter.tabulation.char=space
    396457org.eclipse.jdt.core.formatter.tabulation.size=4
    397 org.eclipse.jdt.core.formatter.use_on_off_tags=true
     458org.eclipse.jdt.core.formatter.use_on_off_tags=false
    398459org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
    399 org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
     460org.eclipse.jdt.core.formatter.wrap_before_additive_operator=true
     461org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false
     462org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator=true
     463org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true
     464org.eclipse.jdt.core.formatter.wrap_before_logical_operator=true
     465org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator=true
    400466org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
     467org.eclipse.jdt.core.formatter.wrap_before_relational_operator=true
     468org.eclipse.jdt.core.formatter.wrap_before_shift_operator=true
     469org.eclipse.jdt.core.formatter.wrap_before_string_concatenation=true
    401470org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
     471org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter
  • .settings/org.eclipse.jdt.ui.prefs

     
     1cleanup.add_default_serial_version_id=true
     2cleanup.add_generated_serial_version_id=false
     3cleanup.add_missing_annotations=true
     4cleanup.add_missing_deprecated_annotations=true
     5cleanup.add_missing_methods=false
     6cleanup.add_missing_nls_tags=false
     7cleanup.add_missing_override_annotations=true
     8cleanup.add_missing_override_annotations_interface_methods=true
     9cleanup.add_serial_version_id=false
     10cleanup.always_use_blocks=true
     11cleanup.always_use_parentheses_in_expressions=false
     12cleanup.always_use_this_for_non_static_field_access=false
     13cleanup.always_use_this_for_non_static_method_access=false
     14cleanup.convert_functional_interfaces=false
     15cleanup.convert_to_enhanced_for_loop=false
     16cleanup.correct_indentation=true
     17cleanup.format_source_code=true
     18cleanup.format_source_code_changes_only=false
     19cleanup.insert_inferred_type_arguments=false
     20cleanup.make_local_variable_final=true
     21cleanup.make_parameters_final=false
     22cleanup.make_private_fields_final=true
     23cleanup.make_type_abstract_if_missing_method=false
     24cleanup.make_variable_declarations_final=false
     25cleanup.never_use_blocks=false
     26cleanup.never_use_parentheses_in_expressions=true
     27cleanup.organize_imports=true
     28cleanup.qualify_static_field_accesses_with_declaring_class=false
     29cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
     30cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
     31cleanup.qualify_static_member_accesses_with_declaring_class=true
     32cleanup.qualify_static_method_accesses_with_declaring_class=false
     33cleanup.remove_private_constructors=true
     34cleanup.remove_redundant_modifiers=true
     35cleanup.remove_redundant_semicolons=true
     36cleanup.remove_redundant_type_arguments=false
     37cleanup.remove_trailing_whitespaces=true
     38cleanup.remove_trailing_whitespaces_all=true
     39cleanup.remove_trailing_whitespaces_ignore_empty=false
     40cleanup.remove_unnecessary_casts=true
     41cleanup.remove_unnecessary_nls_tags=true
     42cleanup.remove_unused_imports=true
     43cleanup.remove_unused_local_variables=false
     44cleanup.remove_unused_private_fields=true
     45cleanup.remove_unused_private_members=false
     46cleanup.remove_unused_private_methods=true
     47cleanup.remove_unused_private_types=true
     48cleanup.sort_members=false
     49cleanup.sort_members_all=false
     50cleanup.use_anonymous_class_creation=false
     51cleanup.use_autoboxing=false
     52cleanup.use_blocks=false
     53cleanup.use_blocks_only_for_return_and_throw=false
     54cleanup.use_lambda=true
     55cleanup.use_parentheses_in_expressions=false
     56cleanup.use_this_for_non_static_field_access=false
     57cleanup.use_this_for_non_static_field_access_only_if_necessary=true
     58cleanup.use_this_for_non_static_method_access=false
     59cleanup.use_this_for_non_static_method_access_only_if_necessary=true
     60cleanup.use_unboxing=false
     61cleanup_profile=_JOSM
    162cleanup_settings_version=2
    263eclipse.preferences.version=1
    364editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
    4 formatter_profile=_josm
    5 formatter_settings_version=12
     65formatter_profile=_JOSM
     66formatter_settings_version=16
    667org.eclipse.jdt.ui.javadoc=false
    7 org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><templates><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\r\n * @return the ${bare_field_name}\r\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\r\n * @param ${param} the ${bare_field_name} to set\r\n */</template><template autoinsert\="true" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\r\n * ${tags}\r\n */</template><template autoinsert\="false" context\="filecomment_context" deleted\="false" description\="Comment for created Java files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.filecomment" name\="filecomment">// License\: GPL. \r\n</template><template autoinsert\="true" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\r\n * @author ${user}\r\n *\r\n * ${tags}\r\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for fields" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\r\n * \r\n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\r\n * ${tags}\r\n */</template><template autoinsert\="true" context\="overridecomment_context" deleted\="false" description\="Comment for overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.overridecomment" name\="overridecomment">/* (non-Javadoc)\r\n * ${see_to_overridden}\r\n */</template><template autoinsert\="true" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\r\n * ${tags}\r\n * ${see_to_target}\r\n */</template><template autoinsert\="false" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.newtype" name\="newtype">// License\: GPL. For details, see LICENSE file.\r\n${package_declaration}\r\n\r\n${typecomment}\r\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.classbody" name\="classbody">\r\n</template><template autoinsert\="true" context\="interfacebody_context" deleted\="false" description\="Code in new interface type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.interfacebody" name\="interfacebody">\r\n</template><template autoinsert\="true" context\="enumbody_context" deleted\="false" description\="Code in new enum type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.enumbody" name\="enumbody">\r\n</template><template autoinsert\="true" context\="annotationbody_context" deleted\="false" description\="Code in new annotation type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.annotationbody" name\="annotationbody">\r\n</template><template autoinsert\="true" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\r\n${exception_var}.printStackTrace();</template><template autoinsert\="true" context\="methodbody_context" deleted\="false" description\="Code in created method stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodbody" name\="methodbody">// ${todo} Auto-generated method stub\r\n${body_statement}</template><template autoinsert\="true" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\r\n// ${todo} Auto-generated constructor stub</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter function" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\r\n * @return the ${bare_field_name}\r\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter function" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\r\n * @param ${param} the ${bare_field_name} to set\r\n */</template><template autoinsert\="true" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\r\n * ${tags}\r\n */</template><template autoinsert\="true" context\="filecomment_context" deleted\="false" description\="Comment for created JavaScript files" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.filecomment" name\="filecomment">/**\r\n * \r\n */</template><template autoinsert\="true" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\r\n * @author ${user}\r\n *\r\n * ${tags}\r\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for vars" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\r\n * \r\n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding function" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\r\n * ${tags}\r\n */</template><template autoinsert\="true" context\="overridecomment_context" deleted\="false" description\="Comment for overriding functions" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.overridecomment" name\="overridecomment">/* (non-Jsdoc)\r\n * ${see_to_overridden}\r\n */</template><template autoinsert\="true" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate functions" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\r\n * ${tags}\r\n * ${see_to_target}\r\n */</template><template autoinsert\="true" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.newtype" name\="newtype">${filecomment}\r\n${package_declaration}\r\n\r\n${typecomment}\r\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.classbody" name\="classbody">\r\n</template><template autoinsert\="true" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\r\n${exception_var}.printStackTrace();</template><template autoinsert\="true" context\="methodbody_context" deleted\="false" description\="Code in created function stubs" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.methodbody" name\="methodbody">// ${todo} Auto-generated function stub\r\n${body_statement}</template><template autoinsert\="true" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\r\n// ${todo} Auto-generated constructor stub</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template></templates>
     68org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><templates><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\n * @return the ${bare_field_name}\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\n * @param ${param} the ${bare_field_name} to set\n */</template><template autoinsert\="true" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\n * ${tags}\n */</template><template autoinsert\="false" context\="filecomment_context" deleted\="false" description\="Comment for created Java files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.filecomment" name\="filecomment">// License\: GPL. \n</template><template autoinsert\="true" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\n * @author ${user}\n *\n * ${tags}\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for fields" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\n * \n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\n * ${tags}\n */</template><template autoinsert\="true" context\="overridecomment_context" deleted\="false" description\="Comment for overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.overridecomment" name\="overridecomment">/* (non-Javadoc)\n * ${see_to_overridden}\n */</template><template autoinsert\="true" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\n * ${tags}\n * ${see_to_target}\n */</template><template autoinsert\="false" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.newtype" name\="newtype">// License\: GPL. For details, see LICENSE file.\n${package_declaration}\n\n${typecomment}\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.classbody" name\="classbody">\n</template><template autoinsert\="true" context\="interfacebody_context" deleted\="false" description\="Code in new interface type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.interfacebody" name\="interfacebody">\n</template><template autoinsert\="true" context\="enumbody_context" deleted\="false" description\="Code in new enum type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.enumbody" name\="enumbody">\n</template><template autoinsert\="true" context\="annotationbody_context" deleted\="false" description\="Code in new annotation type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.annotationbody" name\="annotationbody">\n</template><template autoinsert\="true" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\n${exception_var}.printStackTrace();</template><template autoinsert\="true" context\="methodbody_context" deleted\="false" description\="Code in created method stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodbody" name\="methodbody">// ${todo} Auto-generated method stub\n${body_statement}</template><template autoinsert\="true" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\n// ${todo} Auto-generated constructor stub</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter function" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\n * @return the ${bare_field_name}\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter function" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\n * @param ${param} the ${bare_field_name} to set\n */</template><template autoinsert\="true" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\n * ${tags}\n */</template><template autoinsert\="true" context\="filecomment_context" deleted\="false" description\="Comment for created JavaScript files" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.filecomment" name\="filecomment">/**\n * \n */</template><template autoinsert\="true" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\n * @author ${user}\n *\n * ${tags}\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for vars" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\n * \n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding function" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\n * ${tags}\n */</template><template autoinsert\="true" context\="overridecomment_context" deleted\="false" description\="Comment for overriding functions" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.overridecomment" name\="overridecomment">/* (non-Jsdoc)\n * ${see_to_overridden}\n */</template><template autoinsert\="true" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate functions" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\n * ${tags}\n * ${see_to_target}\n */</template><template autoinsert\="true" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.newtype" name\="newtype">${filecomment}\n${package_declaration}\n\n${typecomment}\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.classbody" name\="classbody">\n</template><template autoinsert\="true" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\n${exception_var}.printStackTrace();</template><template autoinsert\="true" context\="methodbody_context" deleted\="false" description\="Code in created function stubs" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.methodbody" name\="methodbody">// ${todo} Auto-generated function stub\n${body_statement}</template><template autoinsert\="true" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\n// ${todo} Auto-generated constructor stub</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template></templates>
    869sp_cleanup.add_default_serial_version_id=true
    970sp_cleanup.add_generated_serial_version_id=false
    1071sp_cleanup.add_missing_annotations=true
     
    2182sp_cleanup.convert_functional_interfaces=false
    2283sp_cleanup.convert_to_enhanced_for_loop=false
    2384sp_cleanup.correct_indentation=false
    24 sp_cleanup.format_source_code=false
     85sp_cleanup.format_source_code=true
    2586sp_cleanup.format_source_code_changes_only=true
    2687sp_cleanup.insert_inferred_type_arguments=false
    2788sp_cleanup.make_local_variable_final=false
     
    39100sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
    40101sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
    41102sp_cleanup.remove_private_constructors=true
     103sp_cleanup.remove_redundant_modifiers=false
     104sp_cleanup.remove_redundant_semicolons=false
    42105sp_cleanup.remove_redundant_type_arguments=false
    43106sp_cleanup.remove_trailing_whitespaces=true
    44107sp_cleanup.remove_trailing_whitespaces_all=true
  • .settings/org.sonarlint.eclipse.core.prefs

     
    11autoEnabled=true
    22eclipse.preferences.version=1
    33extraProperties=
    4 moduleKey=josm
    54serverId=josm
  • build.xml

     
    503503        <attribute name="excludes" default="${default-junit@{testITsuffix}-excludes}"/>
    504504        <sequential>
    505505            <echo message="Running @{testfamily}@{testITsuffix} tests with JUnit"/>
    506             <jacoco:coverage destfile="${test.dir}/jacoco@{testITsuffix}.exec" enabled="@{coverage}" includes="${jacoco.includes}"
    507                 inclbootstrapclasses="${jacoco.inclbootstrapclasses}" inclnolocationclasses="${jacoco.inclnolocationclasses}">
    508                 <junit printsummary="${junit.printsummary}" fork="true" forkmode="once" failureproperty="test.@{testfamily}@{testITsuffix}.failed">
    509                     <jvmarg value="-Dfile.encoding=UTF-8"/>
    510                     <jvmarg value="-javaagent:${test.dir}/lib/jmockit.jar"/>
    511                     <jvmarg value="--add-modules" if:set="isJava9" unless:set="isJava11" />
    512                     <jvmarg value="java.activation,java.se.ee" if:set="isJava9" unless:set="isJava11" />
    513                     <jvmarg value="--add-exports" if:set="isJava9" unless:set="noJavaFX" />
    514                     <jvmarg value="javafx.graphics/com.sun.javafx.application=ALL-UNNAMED" if:set="isJava9" unless:set="noJavaFX" />
    515                     <jvmarg value="--add-exports" if:set="isJava9" unless:set="isJava11" />
    516                     <jvmarg value="jdk.deploy/com.sun.deploy.config=ALL-UNNAMED" if:set="isJava9" unless:set="isJava11" />
    517                     <jvmarg value="--add-opens" if:set="isJava9" />
    518                     <jvmarg value="java.base/java.io=ALL-UNNAMED" if:set="isJava9" />
    519                     <jvmarg value="--add-opens" if:set="isJava9" />
    520                     <jvmarg value="java.base/java.lang=ALL-UNNAMED" if:set="isJava9" />
    521                     <jvmarg value="--add-opens" if:set="isJava9" />
    522                     <jvmarg value="java.base/java.nio=ALL-UNNAMED" if:set="isJava9" />
    523                     <jvmarg value="--add-opens" if:set="isJava9" />
    524                     <jvmarg value="java.base/java.text=ALL-UNNAMED" if:set="isJava9" />
    525                     <jvmarg value="--add-opens" if:set="isJava9" />
    526                     <jvmarg value="java.base/java.util=ALL-UNNAMED" if:set="isJava9" />
    527                     <jvmarg value="--add-opens" if:set="isJava9" />
    528                     <jvmarg value="java.base/jdk.internal.loader=ALL-UNNAMED" if:set="isJava9" />
    529                     <jvmarg value="--add-opens" if:set="isJava9" />
    530                     <jvmarg value="java.desktop/java.awt=ALL-UNNAMED" if:set="isJava9" />
    531                     <sysproperty key="josm.home" value="${test.dir}/config/@{testfamily}-josm.home"/>
    532                     <sysproperty key="josm.test.data" value="${test.dir}/data"/>
    533                     <sysproperty key="java.awt.headless" value="${test.headless}"/>
    534                     <sysproperty key="glass.platform" value="Monocle"/>
    535                     <sysproperty key="monocle.platform" value="Headless"/>
    536                     <sysproperty key="prism.order" value="sw"/>
    537                     <sysproperty key="suppressPermanentFailure" value="${suppressPermanentFailure}"/>
    538                     <classpath>
    539                         <path refid="test.classpath"/>
    540                         <pathelement path="${test.dir}/build/unit"/>
    541                         <pathelement path="${test.dir}/build/@{testfamily}"/>
    542                         <pathelement path="${test.dir}/config"/>
    543                     </classpath>
    544                     <formatter type="plain"/>
    545                     <formatter type="xml"/>
    546                     <batchtest fork="yes" todir="${test.dir}/report">
    547                         <fileset dir="${test.dir}/build/@{testfamily}" includes="@{includes}" excludes="@{excludes}"/>
    548                     </batchtest>
    549                 </junit>
    550             </jacoco:coverage>
     506            <jacoco:agent destfile="${test.dir}/jacoco@{testITsuffix}.exec" enabled="@{coverage}" includes="${jacoco.includes}" dumponexit="true"
     507                    inclbootstrapclasses="${jacoco.inclbootstrapclasses}" inclnolocationclasses="${jacoco.inclnolocationclasses}" property="jacocoagent@{testfamily}@{testITsuffix}" />
     508            <junitlauncher printsummary="${junit.printsummary}" failureproperty="test.@{testfamily}@{testITsuffix}.failed">
     509                <classpath>
     510                    <path refid="test.classpath"/>
     511                    <pathelement path="${test.dir}/build/unit"/> <!-- required for functional/etc to have JOSMTestRules -->
     512                    <pathelement path="${test.dir}/build/@{testfamily}"/>
     513                </classpath>
     514                <testclasses outputDir="${test.dir}/report">
     515                    <fileset dir="${test.dir}/build/@{testfamily}" includes="@{includes}" excludes="@{excludes}"/>
     516                        <fork>
     517                            <jvmarg value="${jacocoagent@{testfamily}@{testITsuffix}}" if:set="jacocoagent@{testfamily}@{testITsuffix}" />
     518                            <jvmarg value="-Dfile.encoding=UTF-8"/>
     519                            <jvmarg value="-javaagent:${test.dir}/lib/jmockit.jar"/>
     520                            <jvmarg value="--add-modules" if:set="isJava9" unless:set="isJava11" />
     521                            <jvmarg value="java.activation,java.se.ee" if:set="isJava9" unless:set="isJava11" />
     522                            <jvmarg value="--add-exports" if:set="isJava9" unless:set="noJavaFX" />
     523                            <jvmarg value="javafx.graphics/com.sun.javafx.application=ALL-UNNAMED" if:set="isJava9" unless:set="noJavaFX" />
     524                            <jvmarg value="--add-exports" if:set="isJava9" unless:set="isJava11" />
     525                            <jvmarg value="jdk.deploy/com.sun.deploy.config=ALL-UNNAMED" if:set="isJava9" unless:set="isJava11" />
     526                            <jvmarg value="--add-opens" if:set="isJava9" />
     527                            <jvmarg value="java.base/java.io=ALL-UNNAMED" if:set="isJava9" />
     528                            <jvmarg value="--add-opens" if:set="isJava9" />
     529                            <jvmarg value="java.base/java.lang=ALL-UNNAMED" if:set="isJava9" />
     530                            <jvmarg value="--add-opens" if:set="isJava9" />
     531                            <jvmarg value="java.base/java.nio=ALL-UNNAMED" if:set="isJava9" />
     532                            <jvmarg value="--add-opens" if:set="isJava9" />
     533                            <jvmarg value="java.base/java.text=ALL-UNNAMED" if:set="isJava9" />
     534                            <jvmarg value="--add-opens" if:set="isJava9" />
     535                            <jvmarg value="java.base/java.util=ALL-UNNAMED" if:set="isJava9" />
     536                            <jvmarg value="--add-opens" if:set="isJava9" />
     537                            <jvmarg value="java.base/jdk.internal.loader=ALL-UNNAMED" if:set="isJava9" />
     538                            <jvmarg value="--add-opens" if:set="isJava9" />
     539                            <jvmarg value="java.desktop/java.awt=ALL-UNNAMED" if:set="isJava9" />
     540                            <sysproperty key="josm.home" value="${test.dir}/config/@{testfamily}-josm.home"/>
     541                            <sysproperty key="josm.test.data" value="${test.dir}/data"/>
     542                            <sysproperty key="java.awt.headless" value="${test.headless}"/>
     543                            <sysproperty key="glass.platform" value="Monocle"/>
     544                            <sysproperty key="monocle.platform" value="Headless"/>
     545                            <sysproperty key="prism.order" value="sw"/>
     546                            <sysproperty key="suppressPermanentFailure" value="${suppressPermanentFailure}"/>
     547                        </fork>
     548                    <listener type="legacy-plain" />
     549                    <listener type="legacy-xml" />
     550                </testclasses>
     551            </junitlauncher>
    551552        </sequential>
    552553    </macrodef>
    553554    <target name="test" depends="test-compile" unless="test.notRequired"
     
    658659
    659660        # Keep serialization code
    660661        -keepclassmembers class * implements java.io.Serializable {
    661             static final long serialVersionUID; 
     662            static final long serialVersionUID;
    662663            private static final java.io.ObjectStreamField[] serialPersistentFields;
    663664            private void writeObject(java.io.ObjectOutputStream);
    664665            private void readObject(java.io.ObjectInputStream);
    665             java.lang.Object writeReplace(); 
     666            java.lang.Object writeReplace();
    666667            java.lang.Object readResolve();
    667668        }
    668669
  • data/validator/potentially_fixed.mapcss

     
     1/* Check for fixme's that have tag-value pairs */
     2*[fixme][count(split(" ", tag("fixme"))) == 1][tag(tag("fixme")) != "none"]:modified {
     3  throwWarning: tr("fixme is a tag which exists on the object, is the fixme fixed?");
     4  assertNoMatch: "way fixme=name";
     5  assertMatch: "way name=TODO fixme=name";
     6  assertNoMatch: "way name=TODO fixme=\"name me\"";
     7  assertNoMatch: "way name=TODO";
     8}
     9*[fixme][count(split(" ", tag("fixme"))) == 1][tag(tag("fixme")) != "none"]!:modified {
     10  throwOther: tr("fixme is a tag which exists on the object, is the fixme fixed?");
     11  assertNoMatch: "way fixme=name";
     12  assertMatch: "way name=TODO fixme=name";
     13  assertNoMatch: "way name=TODO fixme=\"name me\"";
     14  assertNoMatch: "way name=TODO";
     15}
     16
  • eclipse/JOSM

     
    1 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    2 <launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
    3 <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
    4 <listEntry value="/JOSM/src/org/openstreetmap/josm/gui/MainApplication.java"/>
    5 </listAttribute>
    6 <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
    7 <listEntry value="1"/>
    8 </listAttribute>
    9 <stringAttribute key="org.eclipse.debug.core.source_locator_id" value="org.eclipse.jdt.launching.sourceLocator.JavaSourceLookupDirector"/>
    10 <stringAttribute key="org.eclipse.debug.core.source_locator_memento" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;sourceLookupDirector&gt;&#13;&#10;&lt;sourceContainers duplicates=&quot;false&quot;&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;josm-atlas&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-DXFImport&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM/test\/lib\/equalsverifier-2.4.4.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-apache-commons&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;classpathContainer path=&amp;quot;GROOVY_SUPPORT&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.classpathContainer&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-addrinterpolation&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-alignways&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-areaselector&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-buildings_tools&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-cadastre-fr&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-GeoTools&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-GeoTools/lib\/commons-beanutils-1.7.0.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-GeoTools/lib\/commons-pool-1.5.4.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-GeoTools/lib\/vecmath-1.3.2.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-GeoTools/lib\/jsr-275-1.0-beta-2.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-GeoTools/lib\/hsqldb-2.2.8.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-GeoTools/lib\/imageio-ext-tiff-1.1.10.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-GeoTools/lib\/imageio-ext-utilities-1.1.10.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-GeoTools/lib\/jai_codec-1.1.3.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-GeoTools/lib\/jai_core-1.1.3.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-GeoTools/lib\/jai_imageio-1.1.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-GeoTools/lib\/jdom-1.1.3.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-GeoTools/lib\/jt-contour-1.3.1.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-GeoTools/lib\/jt-rangelookup-1.3.1.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-GeoTools/lib\/jt-utils-1.3.1.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-GeoTools/lib\/jt-vectorbinarize-1.3.1.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-GeoTools/lib\/jt-vectorize-1.3.1.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-GeoTools/lib\/jt-zonalstats-1.3.1.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-jts&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-jts/lib\/jts-1.13.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-canvec_helper&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-colorscheme&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-commandline&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-conflation&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-utilsplugin2&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-create_grid_of_ways&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-czechaddress&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-dataimport&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-dataimport/lib\/jsr173-1.0_api.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-dataimport/lib\/jaxb-api.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-DirectDownload&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-DirectUpload&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-download_along&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-editgpx&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-ElevationProfile&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-EPCI-fr&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-ext_tools&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-FastDraw&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-FixAddresses&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-geochat&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-globalsat&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-gpsblam&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-gpxfilter&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-graphview&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-HouseNumberTaggingTool&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-imagery_offset_db&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-Imagery-XML-Bounds&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-imageryadjust&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-imagerycache&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-imagewaypoint&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-ImportImage&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-log4j&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-log4j/lib\/log4j-1.2.17.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-importvec&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-InfoMode&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-irsrectify&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-junctionchecking&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-lakewalker&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-livegps&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-mapdust&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-Measurement&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-merge-overlap&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-michigan_left&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-mirrored_download&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-namemanager&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-NanoLog&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-native-password-manager&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-OpenData&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-OpeningHoursEditor&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-openvisible&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-osmarender&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-OsmInspectorPlugin&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-PBF&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-pdfimport&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-photo_geotaging&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-photoadjust&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-piclayer&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-plastic_laf&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-Poly&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-print&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-proj4j&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-public_transport&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-reltoolbox&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-Reverter&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-roadsigns&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-routes&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-routing&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-sds&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-SeaMapEditor&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-SimplifyArea&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-surveyor&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-tageditor&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;josm-tagging-preset-tester&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-terracer&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-tracer&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-tracer2&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-trustosm&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-turnlanes&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-turnrestrictions&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;classpathContainer path=&amp;quot;GROOVY_DSL_SUPPORT&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.classpathContainer&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-undelete&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-videomapping&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-walkingpapers&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-waydownloader&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-waypoint_search&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-wayselector&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-wikipedia&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-wms-turbo-challenge2&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;default/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.debug.core.containerType.default&quot;/&gt;&#13;&#10;&lt;/sourceContainers&gt;&#13;&#10;&lt;/sourceLookupDirector&gt;&#13;&#10;"/>
    11 <stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
    12 <stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.openstreetmap.josm.gui.MainApplication"/>
    13 <stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="--debug"/>
    14 <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="JOSM"/>
    15 <stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea -Xverify:none"/>
    16 </launchConfiguration>
     1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
     2<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
     3    <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
     4        <listEntry value="/JOSM/src/org/openstreetmap/josm/gui/MainApplication.java"/>
     5    </listAttribute>
     6    <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
     7        <listEntry value="1"/>
     8    </listAttribute>
     9    <stringAttribute key="org.eclipse.debug.core.source_locator_id" value="org.eclipse.jdt.launching.sourceLocator.JavaSourceLookupDirector"/>
     10    <stringAttribute key="org.eclipse.debug.core.source_locator_memento" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;sourceLookupDirector&gt;&#13;&#10;&lt;sourceContainers duplicates=&quot;false&quot;&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;josm-atlas&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-DXFImport&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM/test\/lib\/equalsverifier-2.4.4.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-apache-commons&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;classpathContainer path=&amp;quot;GROOVY_SUPPORT&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.classpathContainer&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-addrinterpolation&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-alignways&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-areaselector&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-buildings_tools&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-cadastre-fr&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-GeoTools&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-GeoTools/lib\/commons-beanutils-1.7.0.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-GeoTools/lib\/commons-pool-1.5.4.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-GeoTools/lib\/vecmath-1.3.2.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-GeoTools/lib\/jsr-275-1.0-beta-2.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-GeoTools/lib\/hsqldb-2.2.8.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-GeoTools/lib\/imageio-ext-tiff-1.1.10.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-GeoTools/lib\/imageio-ext-utilities-1.1.10.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-GeoTools/lib\/jai_codec-1.1.3.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-GeoTools/lib\/jai_core-1.1.3.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-GeoTools/lib\/jai_imageio-1.1.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-GeoTools/lib\/jdom-1.1.3.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-GeoTools/lib\/jt-contour-1.3.1.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-GeoTools/lib\/jt-rangelookup-1.3.1.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-GeoTools/lib\/jt-utils-1.3.1.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-GeoTools/lib\/jt-vectorbinarize-1.3.1.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-GeoTools/lib\/jt-vectorize-1.3.1.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-GeoTools/lib\/jt-zonalstats-1.3.1.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-jts&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-jts/lib\/jts-1.13.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-canvec_helper&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-colorscheme&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-commandline&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-conflation&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-utilsplugin2&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-create_grid_of_ways&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-czechaddress&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-dataimport&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-dataimport/lib\/jsr173-1.0_api.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-dataimport/lib\/jaxb-api.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-DirectDownload&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-DirectUpload&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-download_along&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-editgpx&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-ElevationProfile&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-EPCI-fr&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-ext_tools&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-FastDraw&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-FixAddresses&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-geochat&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-globalsat&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-gpsblam&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-gpxfilter&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-graphview&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-HouseNumberTaggingTool&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-imagery_offset_db&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-Imagery-XML-Bounds&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-imageryadjust&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-imagerycache&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-imagewaypoint&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-ImportImage&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-log4j&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=JOSM-log4j/lib\/log4j-1.2.17.jar&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-importvec&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-InfoMode&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-irsrectify&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-junctionchecking&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-lakewalker&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-livegps&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-mapdust&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-Measurement&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-merge-overlap&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-michigan_left&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-mirrored_download&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-namemanager&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-NanoLog&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-native-password-manager&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-OpenData&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-OpeningHoursEditor&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-openvisible&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-osmarender&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-OsmInspectorPlugin&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-PBF&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-pdfimport&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-photo_geotaging&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-photoadjust&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-piclayer&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-plastic_laf&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-Poly&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-print&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-proj4j&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-public_transport&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-reltoolbox&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-Reverter&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-roadsigns&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-routes&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-routing&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-sds&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-SeaMapEditor&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-SimplifyArea&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-surveyor&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-tageditor&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;josm-tagging-preset-tester&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-terracer&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-tracer&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-tracer2&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-trustosm&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-turnlanes&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-turnrestrictions&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;classpathContainer path=&amp;quot;GROOVY_DSL_SUPPORT&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.classpathContainer&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-undelete&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-videomapping&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-walkingpapers&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-waydownloader&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-waypoint_search&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-wayselector&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-wikipedia&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;JOSM-wms-turbo-challenge2&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;default/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.debug.core.containerType.default&quot;/&gt;&#13;&#10;&lt;/sourceContainers&gt;&#13;&#10;&lt;/sourceLookupDirector&gt;&#13;&#10;"/>
     11    <booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
     12    <stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
     13    <stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.openstreetmap.josm.gui.MainApplication"/>
     14    <stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="--debug"/>
     15    <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="JOSM"/>
     16    <stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea -Xverify:none -Xmx4096M"/>
     17</launchConfiguration>
  • josm-latest.jnlp

     
    33<jnlp spec="6.0+" codebase="https://josm.openstreetmap.de/download/" href="josm-latest.jnlp">
    44    <information>
    55        <title>JOSM (development version)</title>
    6         <vendor>OpenStreetMap</vendor> 
    7         <homepage href="https://josm.openstreetmap.de"/> 
     6        <vendor>OpenStreetMap</vendor>
     7        <homepage href="https://josm.openstreetmap.de"/>
    88        <description>Java OpenStreetMap editor</description>
    99        <description kind="one-line">JOSM</description>
    1010        <description kind="tooltip">JOSM</description>
     
    1515            <desktop/>
    1616            <menu/>
    1717        </shortcut>
     18        <association mime-type="text/xml" extensions="osm osc"/>
     19        <association mime-type="text/plain" extensions="geojson"/>
    1820    </information>
    1921    <security>
    2022        <all-permissions/>
  • josm.jnlp

     
    33<jnlp spec="6.0+" codebase="https://josm.openstreetmap.de/download/" href="josm.jnlp">
    44    <information>
    55        <title>JOSM</title>
    6         <vendor>OpenStreetMap</vendor> 
    7         <homepage href="https://josm.openstreetmap.de"/> 
     6        <vendor>OpenStreetMap</vendor>
     7        <homepage href="https://josm.openstreetmap.de"/>
    88        <description>Java OpenStreetMap editor</description>
    99        <description kind="one-line">JOSM</description>
    1010        <description kind="tooltip">JOSM</description>
    1111        <icon href="https://josm.openstreetmap.de/logo.png" width="256" height="256"/>
    12         <icon href="https://josm.openstreetmap.de/logo64.png" width="64" height="64" kind="shortcut"/> 
     12        <icon href="https://josm.openstreetmap.de/logo64.png" width="64" height="64" kind="shortcut"/>
    1313        <offline-allowed/>
    1414        <shortcut>
    1515            <desktop/>
    1616            <menu/>
    1717        </shortcut>
     18        <association mime-type="text/xml" extensions="osm osc"/>
     19        <association mime-type="text/plain" extensions="geojson"/>
    1820    </information>
    1921    <security>
    2022        <all-permissions/>
  • src/org/openstreetmap/josm/actions/ValidateAction.java

     
    114114        private boolean canceled;
    115115        private List<TestError> errors;
    116116
     117        private List<Class<? extends Test>> runTests;
     118
    117119        /**
    118120         * Constructs a new {@code ValidationTask}
    119121         * @param tests  the tests to run
     
    151153        @Override
    152154        protected void realRun() throws SAXException, IOException,
    153155        OsmTransferException {
     156            runTests = new ArrayList<>();
    154157            if (tests == null || tests.isEmpty())
    155158                return;
    156159            errors = new ArrayList<>(200);
    157160            getProgressMonitor().setTicksCount(tests.size() * validatedPrimitives.size());
    158             int testCounter = 0;
     161            runTests(tests, 0);
     162            tests = null;
     163            if (Boolean.TRUE.equals(ValidatorPrefHelper.PREF_USE_IGNORE.get())) {
     164                getProgressMonitor().setCustomText("");
     165                getProgressMonitor().subTask(tr("Updating ignored errors ..."));
     166                for (TestError error : errors) {
     167                    if (canceled) return;
     168                    error.updateIgnored();
     169                }
     170            }
     171        }
     172
     173        protected int runTests(Collection<Test> tests, int testCounter) {
     174            ArrayList<Test> remaining = new ArrayList<>();
    159175            for (Test test : tests) {
    160176                if (canceled)
    161                     return;
     177                    return testCounter;
     178                if (test.getAfterClass() != null && !runTests.contains(test.getAfterClass())) {
     179                    remaining.add(test);
     180                    continue;
     181                }
    162182                testCounter++;
    163                 getProgressMonitor().setCustomText(tr("Test {0}/{1}: Starting {2}", testCounter, tests.size(), test.getName()));
     183                getProgressMonitor().setCustomText(tr("Test {0}/{1}: Starting {2}", testCounter, this.tests.size(), test.getName()));
    164184                test.setPartialSelection(formerValidatedPrimitives != null);
     185                test.setPreviousErrors(errors);
    165186                test.startTest(getProgressMonitor().createSubTaskMonitor(validatedPrimitives.size(), false));
    166187                test.visit(validatedPrimitives);
    167188                test.endTest();
    168189                errors.addAll(test.getErrors());
    169190                test.clear();
     191                runTests.add(test.getClass());
    170192            }
    171             tests = null;
    172             if (ValidatorPrefHelper.PREF_USE_IGNORE.get()) {
    173                 getProgressMonitor().setCustomText("");
    174                 getProgressMonitor().subTask(tr("Updating ignored errors ..."));
    175                 for (TestError error : errors) {
    176                     if (canceled) return;
    177                     error.updateIgnored();
    178                 }
     193            if (!remaining.isEmpty()) {
     194                testCounter = runTests(remaining, testCounter);
    179195            }
     196            return testCounter;
    180197        }
    181198    }
    182199}
  • src/org/openstreetmap/josm/command/AddPrimitivesCommand.java

     
    1212import java.util.stream.Collectors;
    1313
    1414import javax.swing.Icon;
     15import javax.swing.SwingUtilities;
    1516
    1617import org.openstreetmap.josm.data.osm.DataSet;
    1718import org.openstreetmap.josm.data.osm.Node;
     
    112113            }
    113114        }
    114115        if (toSelect != null) {
    115             ds.setSelected(toSelect.stream().map(ds::getPrimitiveById).collect(Collectors.toList()));
     116            SwingUtilities.invokeLater(
     117                    () -> ds.setSelected(toSelect.stream().map(ds::getPrimitiveById).filter(Objects::nonNull)
     118                            .collect(Collectors.toList())));
    116119        }
    117120        return true;
    118121    }
  • src/org/openstreetmap/josm/data/gpx/GpxData.java

     
    1818import java.util.Objects;
    1919import java.util.Optional;
    2020import java.util.Set;
     21import java.util.TreeSet;
    2122import java.util.stream.Collectors;
    2223import java.util.stream.Stream;
    2324
     
    7879     */
    7980    private final ArrayList<GpxRoute> privateRoutes = new ArrayList<>();
    8081    /**
    81      * Addidionaly waypoints for this file.
     82     * Additionally waypoints for this file.
    8283     */
    8384    private final ArrayList<WayPoint> privateWaypoints = new ArrayList<>();
    8485    /**
     
    9697    private boolean suppressedInvalidate;
    9798
    9899    /**
     100     * A list of tracks with an arbitrary max area
     101     */
     102    private final Map<Double, List<GpxTrack>> maxAreaTracks = new HashMap<>();
     103
     104    /**
    99105     * Tracks. Access is discouraged, use {@link #getTracks()} to read.
    100106     * @see #getTracks()
    101107     */
     
    12781284            return true;
    12791285        }
    12801286    }
     1287
     1288    /**
     1289     * Get a list of tracks with a maximum number of points
     1290     * @param maxPoints the maximum number of points for each subtrack
     1291     * @return A list of tracks with a maximum number of points of maxPoints
     1292     */
     1293    public List<GpxTrack> getMaxAreaTracks(double maxPoints) {
     1294        if (!maxAreaTracks.containsKey(maxPoints)) {
     1295            List<GpxTrack> ttracks = new ArrayList<>();
     1296            Collection<WayPoint> tWayPoints = new TreeSet<>();
     1297
     1298            for (WayPoint point : getTrackPoints().collect(Collectors.toList())) {
     1299                tWayPoints.add(point);
     1300                if (tWayPoints.size() >= maxPoints) {
     1301                    Map<String, Object> emptyMap = Collections.emptyMap();
     1302                    Collection<Collection<WayPoint>> tCollection = new TreeSet<>();
     1303                    tCollection.add(tWayPoints);
     1304                    ttracks.add(new GpxTrack(tCollection, emptyMap));
     1305                }
     1306            }
     1307            maxAreaTracks.put(maxPoints, ttracks);
     1308        }
     1309        return maxAreaTracks.get(maxPoints);
     1310    }
    12811311}
  • src/org/openstreetmap/josm/data/imagery/ImageryInfo.java

     
    239239    private String origName;
    240240    /** (original) language of the translated name entry */
    241241    private String langName;
     242    /** preferred source tag value (for changeset source) */
     243    private String source;
    242244    /** whether this is a entry activated by default or not */
    243245    private boolean defaultEntry;
    244246    /** Whether this service requires a explicit EULA acceptance before it can be activated */
     
    363365        @StructEntry boolean transparent;
    364366        @StructEntry int minimumTileExpire;
    365367        @StructEntry String category;
     368        @StructEntry
     369        String source;
    366370
    367371        /**
    368372         * Constructs a new empty WMS {@code ImageryPreferenceEntry}.
     
    399403            icon = i.icon;
    400404            description = i.description;
    401405            category = i.category != null ? i.category.getCategoryString() : null;
     406            source = i.source;
    402407            if (i.bounds != null) {
    403408                bounds = i.bounds.encodeAsString(",");
    404409                StringBuilder shapesString = new StringBuilder();
     
    591596        transparent = e.transparent;
    592597        minimumTileExpire = e.minimumTileExpire;
    593598        category = ImageryCategory.fromString(e.category);
     599        source = e.source;
    594600    }
    595601
    596602    /**
     
    640646        this.minimumTileExpire = i.minimumTileExpire;
    641647        this.categoryOriginalString = i.categoryOriginalString;
    642648        this.category = i.category;
     649        this.source = i.source;
    643650    }
    644651
    645652    @Override
     
    695702                Objects.equals(this.customHttpHeaders, other.customHttpHeaders) &&
    696703                Objects.equals(this.transparent, other.transparent) &&
    697704                Objects.equals(this.minimumTileExpire, other.minimumTileExpire) &&
    698                 Objects.equals(this.category, other.category);
     705                Objects.equals(this.category, other.category) && Objects.equals(this.source, other.source);
    699706        // CHECKSTYLE.ON: BooleanExpressionComplexity
    700707    }
    701708
     
    991998    }
    992999
    9931000    /**
     1001     * Returns the entry preferred source tag
     1002     *
     1003     * @return The preferred source tag. May be null or an empty string.
     1004     * @since xxx
     1005     */
     1006    public String getSource() {
     1007        return source;
     1008    }
     1009
     1010    /**
     1011     * Returns the entry preferred source tag
     1012     *
     1013     * @param source The preferred source tag for the source
     1014     * @since xxx
     1015     */
     1016    public void setSource(String source) {
     1017        this.source = source;
     1018    }
     1019
     1020    /**
    9941021     * Store the id of this info to the preferences and clear it afterwards.
    9951022     */
    9961023    public void clearId() {
     
    16381665                // Retrieve english name, unfortunately not saved in preferences
    16391666                Optional<ImageryInfo> infoEn = ImageryLayerInfo.allDefaultLayers.stream().filter(x -> id.equals(x.getId())).findAny();
    16401667                if (infoEn.isPresent()) {
    1641                     return infoEn.get().getOriginalName();
     1668                    ImageryInfo info = infoEn.get();
     1669                    String sourceTag = info.getSource();
     1670                    return sourceTag == null || sourceTag.trim().isEmpty() ? info.getOriginalName() : sourceTag;
    16421671                }
    16431672            }
    16441673            return getOriginalName();
  • src/org/openstreetmap/josm/data/osm/Node.java

     
    385385
    386386    @Override
    387387    public boolean isOutsideDownloadArea() {
    388         if (isNewOrUndeleted() || getDataSet() == null)
     388        return isOutsideDownloadArea(false);
     389    }
     390
     391    /**
     392     * Tests if this primitive lies outside of the downloaded area of its
     393     * {@link DataSet}, possibly ignoring if the node is new or undeleted.
     394     *
     395     * @param ignoreNewOrUndeleted if true, don't use
     396     *                             {@link OsmPrimitive#isNewOrUndeleted} (if
     397     *                             {@code true}, {@link Node#isOutsideDownloadArea}
     398     *                             returns {@code false})
     399     * @return {@code true} if this primitive lies outside of the downloaded area
     400     * @see Node#isOutsideDownloadArea
     401     */
     402    public boolean isOutsideDownloadArea(boolean ignoreNewOrUndeleted) {
     403        if ((!ignoreNewOrUndeleted && isNewOrUndeleted()) || getDataSet() == null)
    389404            return false;
    390405        Area area = getDataSet().getDataSourceArea();
    391406        if (area == null)
  • src/org/openstreetmap/josm/data/osm/SimplePrimitiveId.java

     
    148148    private static OsmPrimitiveType getOsmPrimitiveType(char firstChar) {
    149149        return firstChar == 'n' ? OsmPrimitiveType.NODE : firstChar == 'w' ? OsmPrimitiveType.WAY : OsmPrimitiveType.RELATION;
    150150    }
     151
     152    /**
     153     * Convert a primitive to a simple id
     154     *
     155     * @param primitive The primitive to convert
     156     * @return The type (may be n, w, or r, or something else) + the id (e.g., w42)
     157     * @since xxx
     158     */
     159    public static String toSimpleId(IPrimitive primitive) {
     160        if (primitive instanceof Relation) {
     161            return "r" + primitive.getOsmId();
     162        } else if (primitive instanceof Way) {
     163            return "w" + primitive.getOsmId();
     164        } else if (primitive instanceof Node) {
     165            return "n" + primitive.getOsmId();
     166        }
     167        return primitive.getType().toString() + primitive.getOsmId();
     168    }
    151169}
  • src/org/openstreetmap/josm/data/validation/OsmValidator.java

     
    6060import org.openstreetmap.josm.data.validation.tests.PublicTransportRouteTest;
    6161import org.openstreetmap.josm.data.validation.tests.RelationChecker;
    6262import org.openstreetmap.josm.data.validation.tests.RightAngleBuildingTest;
     63import org.openstreetmap.josm.data.validation.tests.RoutingIslandsTest;
    6364import org.openstreetmap.josm.data.validation.tests.SelfIntersectingWay;
    6465import org.openstreetmap.josm.data.validation.tests.SharpAngles;
    6566import org.openstreetmap.josm.data.validation.tests.SimilarNamedWays;
     
    149150        PublicTransportRouteTest.class, // 3600 .. 3699
    150151        RightAngleBuildingTest.class, // 3700 .. 3799
    151152        SharpAngles.class, // 3800 .. 3899
     153        RoutingIslandsTest.class, // 3900 .. 3999
    152154    };
    153155
    154156    /**
  • src/org/openstreetmap/josm/data/validation/Test.java

     
    4646    /** Name of the test */
    4747    protected final String name;
    4848
     49    /** Test to run after */
     50    protected Class<? extends Test> afterTest;
     51
    4952    /** Description of the test */
    5053    protected final String description;
    5154
     
    6770    /** The list of errors */
    6871    protected List<TestError> errors = new ArrayList<>(30);
    6972
     73    /** The list of previously found errors */
     74    protected List<TestError> previousErrors;
     75
    7076    /** Whether the test is run on a partial selection data */
    7177    protected boolean partialSelection;
    7278
     
    8490     * @param description Description of the test
    8591     */
    8692    public Test(String name, String description) {
     93        this(name, description, null);
     94    }
     95
     96    /**
     97     * Constructor
     98     * @param name Name of the test
     99     * @param description Description of the test
     100     * @param afterTest Ensure the test is run after a test with this name
     101     *
     102     * @since xxx
     103     */
     104    public Test(String name, String description, Class<? extends Test> afterTest) {
    87105        this.name = name;
    88106        this.description = description;
     107        this.afterTest = afterTest;
    89108    }
    90109
    91110    /**
     
    187206    }
    188207
    189208    /**
     209     * Set the validation errors accumulated by other tests until this moment
     210     * For validation errors accumulated by this test, use {@code getErrors()}
     211     * @param errors The errors from previous tests
     212     */
     213    public void setPreviousErrors(List<TestError> errors) {
     214        previousErrors = errors;
     215    }
     216
     217    /**
    190218     * Notification of the end of the test. The tester may perform additional
    191219     * actions and destroy the used structures.
    192220     * <p>
     
    326354    }
    327355
    328356    /**
     357     * Get the class that the test must run after
     358     * @return A class that extends {@code Test}
     359     *
     360     * @since xxx
     361     */
     362    public Class<? extends Test> getAfterClass() {
     363        return afterTest;
     364    }
     365
     366    /**
    329367     * Determines if the test has been canceled.
    330368     * @return {@code true} if the test has been canceled, {@code false} otherwise
    331369     */
  • src/org/openstreetmap/josm/data/validation/tests/ConditionalKeys.java

     
    1616import org.openstreetmap.josm.data.validation.Severity;
    1717import org.openstreetmap.josm.data.validation.Test;
    1818import org.openstreetmap.josm.data.validation.TestError;
     19import org.openstreetmap.josm.tools.Access;
    1920import org.openstreetmap.josm.tools.LanguageInfo;
    2021import org.openstreetmap.josm.tools.Logging;
    2122import org.openstreetmap.josm.tools.SubclassFilteredCollection;
     
    3031    private static final Set<String> RESTRICTION_TYPES = new HashSet<>(Arrays.asList("oneway", "toll", "noexit", "maxspeed", "minspeed",
    3132            "maxstay", "maxweight", "maxaxleload", "maxheight", "maxwidth", "maxlength", "overtaking", "maxgcweight", "maxgcweightrating",
    3233            "fee", "restriction", "interval", "duration"));
    33     private static final Set<String> RESTRICTION_VALUES = new HashSet<>(Arrays.asList("yes", "official", "designated", "destination",
    34             "delivery", "customers", "permissive", "private", "agricultural", "forestry", "no"));
    35     private static final Set<String> TRANSPORT_MODES = new HashSet<>(Arrays.asList("access", "foot", "ski", "inline_skates", "ice_skates",
    36             "horse", "vehicle", "bicycle", "carriage", "trailer", "caravan", "motor_vehicle", "motorcycle", "moped", "mofa",
    37             "motorcar", "motorhome", "psv", "bus", "taxi", "tourist_bus", "goods", "hgv", "agricultural", "atv", "snowmobile",
    38             "hgv_articulated", "ski:nordic", "ski:alpine", "ski:telemark", "coach", "golf_cart"
    39             /*,"minibus","share_taxi","hov","car_sharing","emergency","hazmat","disabled"*/));
     34    private static final Set<String> RESTRICTION_VALUES = Access.getRestrictionValues();
     35    private static final Set<String> TRANSPORT_MODES = Access.getTransportModes();
    4036
    4137    private static final Pattern CONDITIONAL_PATTERN;
    4238    static {
  • src/org/openstreetmap/josm/data/validation/tests/ConnectivityRelationCheck.java

     
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.data.validation.tests;
     3
     4import static org.openstreetmap.josm.tools.I18n.tr;
     5
     6import java.util.Collections;
     7import java.util.Comparator;
     8import java.util.HashMap;
     9import java.util.Map;
     10import java.util.Map.Entry;
     11import java.util.TreeMap;
     12import java.util.regex.Pattern;
     13
     14import org.openstreetmap.josm.data.osm.Node;
     15import org.openstreetmap.josm.data.osm.OsmPrimitive;
     16import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
     17import org.openstreetmap.josm.data.osm.Relation;
     18import org.openstreetmap.josm.data.osm.RelationMember;
     19import org.openstreetmap.josm.data.osm.Way;
     20import org.openstreetmap.josm.data.validation.Severity;
     21import org.openstreetmap.josm.data.validation.Test;
     22import org.openstreetmap.josm.data.validation.TestError;
     23
     24/**
     25 * Check for inconsistencies in lane information between relation and members.
     26 */
     27public class ConnectivityRelationCheck extends Test {
     28
     29    protected static final int INCONSISTENT_LANE_COUNT = 3900;
     30
     31    protected static final int UNKNOWN_CONNECTIVITY_ROLE = INCONSISTENT_LANE_COUNT + 1;
     32
     33    protected static final int NO_CONNECTIVITY_TAG = INCONSISTENT_LANE_COUNT + 2;
     34
     35    protected static final int TOO_MANY_ROLES = INCONSISTENT_LANE_COUNT + 3;
     36
     37    private static final String CONNECTIVITY_TAG = "connectivity";
     38    private static final String VIA = "via";
     39    private static final String TO = "to";
     40    private static final String FROM = "from";
     41
     42    /**
     43    * Constructor
     44    */
     45    public ConnectivityRelationCheck() {
     46        super(tr("Connectivity Relation Check"), tr("Checks that lane count of relation matches with lanes of members"));
     47    }
     48
     49    /**
     50     * Convert the connectivity tag into a map of values
     51     *
     52     * @param relation A relation with a {@code connectivity} tag.
     53     * @return A Map in the form of {@code Map<Lane From, Map<Lane To, Optional>>}
     54     * @since xxx
     55     */
     56    public static Map<Integer, Map<Integer, Boolean>> parseConnectivityTag(Relation relation) {
     57        final String joined = relation.get(CONNECTIVITY_TAG);
     58
     59        if (joined == null) {
     60            return new TreeMap<>();
     61        }
     62
     63        final Map<Integer, Map<Integer, Boolean>> result = new HashMap<>();
     64        String[] lanes = joined.split("\\|", -1);
     65        for (int i = 0; i < lanes.length; i++) {
     66            String[] lane = lanes[i].split(":", -1);
     67            int laneNumber = Integer.parseInt(lane[0].trim());
     68            Map<Integer, Boolean> connections = new HashMap<>();
     69            String[] toLanes = Pattern.compile("\\p{Zs}*[,:;]\\p{Zs}*").split(lane[1]);
     70            for (int j = 0; j < toLanes.length; j++) {
     71                String toLane = toLanes[j].trim();
     72                if (Pattern.compile("\\([0-9]+\\)").matcher(toLane).matches()) {
     73                    toLane = toLane.replace("(", "").replace(")", "").trim();
     74                    connections.put(Integer.parseInt(toLane), true);
     75                } else {
     76                    connections.put(Integer.parseInt(toLane), false);
     77                }
     78            }
     79            result.put(laneNumber, connections);
     80        }
     81        return result;
     82    }
     83
     84    @Override
     85    public void visit(Relation r) {
     86        if (r.hasTag("type", CONNECTIVITY_TAG)) {
     87            if (!r.hasKey(CONNECTIVITY_TAG)) {
     88                errors.add(TestError.builder(this, Severity.WARNING, NO_CONNECTIVITY_TAG)
     89                        .message(tr("No connectivity tag in connectivity relation")).primitives(r).build());
     90            } else if (!r.hasIncompleteMembers()) {
     91                boolean badRole = checkForBadRole(r);
     92                if (!badRole)
     93                    checkForInconsistentLanes(r);
     94            }
     95        }
     96    }
     97
     98    private void checkForInconsistentLanes(Relation relation) {
     99        // Lane count from connectivity tag
     100        Map<Integer, Map<Integer, Boolean>> connTagLanes = parseConnectivityTag(relation);
     101        // Lane count from member tags
     102        Map<String, Integer> roleLanes = new HashMap<>();
     103
     104        for (RelationMember rM : relation.getMembers()) {
     105            // Check lanes
     106            if (rM.getType() == OsmPrimitiveType.WAY) {
     107                OsmPrimitive prim = rM.getMember();
     108                if (prim.hasKey("lanes") && !rM.getRole().equals(VIA)) {
     109                    roleLanes.put(rM.getRole(), Integer.parseInt(prim.get("lanes")));
     110                }
     111            }
     112        }
     113        boolean fromCheck = roleLanes.get(FROM) < Collections
     114                .max(connTagLanes.entrySet(), Comparator.comparingInt(Map.Entry::getKey)).getKey();
     115        boolean toCheck = false;
     116        for (Entry<Integer, Map<Integer, Boolean>> to : connTagLanes.entrySet()) {
     117            toCheck = roleLanes.get(TO) < Collections
     118                    .max(to.getValue().entrySet(), Comparator.comparingInt(Map.Entry::getKey)).getKey();
     119        }
     120        if (fromCheck || toCheck) {
     121            errors.add(TestError.builder(this, Severity.WARNING, INCONSISTENT_LANE_COUNT)
     122                    .message(tr("Inconsistent lane numbering between relation and members")).primitives(relation)
     123                    .build());
     124        }
     125    }
     126
     127    private boolean checkForBadRole(Relation relation) {
     128        // Check role names
     129        int viaWays = 0;
     130        int viaNodes = 0;
     131        int toWays = 0;
     132        int fromWays = 0;
     133        for (RelationMember relationMember : relation.getMembers()) {
     134            if (relationMember.getMember() instanceof Way) {
     135                if (relationMember.hasRole(FROM))
     136                    fromWays++;
     137                else if (relationMember.hasRole(TO))
     138                    toWays++;
     139                else if (relationMember.hasRole(VIA))
     140                    viaWays++;
     141                else {
     142                    createUnknownRole(relation, relationMember.getMember());
     143                    return true;
     144                }
     145            } else if (relationMember.getMember() instanceof Node) {
     146                if (!relationMember.hasRole(VIA)) {
     147                    createUnknownRole(relation, relationMember.getMember());
     148                    return true;
     149                }
     150                viaNodes++;
     151            }
     152        }
     153        return mixedViaNodeAndWay(relation, viaWays, viaNodes, toWays, fromWays);
     154    }
     155
     156    private boolean mixedViaNodeAndWay(Relation relation, int viaWays, int viaNodes, int toWays, int fromWays) {
     157        String message = "";
     158        if ((viaWays != 0 && viaNodes != 0) || viaNodes > 1) {
     159            message = tr("Relation contains {1} {0} roles.", VIA, viaWays + viaNodes);
     160        } else if (toWays != 1) {
     161            message = tr("Relation contains too many {0} roles", TO);
     162        } else if (fromWays != 1) {
     163            message = tr("Relation contains too many {0} roles", FROM);
     164        }
     165        if (message.isEmpty()) {
     166            return false;
     167        } else {
     168            errors.add(TestError.builder(this, Severity.WARNING, TOO_MANY_ROLES)
     169                    .message(message).primitives(relation).build());
     170            return true;
     171        }
     172    }
     173
     174    private void createUnknownRole(Relation relation, OsmPrimitive primitive) {
     175        errors.add(TestError.builder(this, Severity.WARNING, UNKNOWN_CONNECTIVITY_ROLE)
     176                .message(tr("Unkown role in connectivity relation")).primitives(relation).highlight(primitive).build());
     177    }
     178}
  • src/org/openstreetmap/josm/data/validation/tests/Highways.java

     
    3838    protected static final int SOURCE_MAXSPEED_CONTEXT_MISMATCH_VS_MAXSPEED = 2705;
    3939    protected static final int SOURCE_MAXSPEED_CONTEXT_MISMATCH_VS_HIGHWAY = 2706;
    4040    protected static final int SOURCE_WRONG_LINK = 2707;
     41    protected static final int ROUNDABOUT_CONNECTIONS_COUNT = 2708;
    4142
    4243    protected static final String SOURCE_MAXSPEED = "source:maxspeed";
    4344
     
    6869    private int pedestrianWays;
    6970    private int cyclistWays;
    7071    private int carsWays;
     72    private final Set<Node> connectionNodesComplained = new HashSet<>();
    7173
    7274    /**
    7375     * Constructs a new {@code Highways} test.
     
    7779    }
    7880
    7981    @Override
     82    public void initialize() throws Exception {
     83        super.initialize();
     84        connectionNodesComplained.clear();
     85    }
     86
     87    @Override
     88    public void endTest() {
     89        connectionNodesComplained.clear();
     90        super.endTest();
     91    }
     92
     93    @Override
    8094    public void visit(Node n) {
    8195        if (n.isUsable()) {
    8296            if (!n.hasTag("crossing", "no")
     
    96110    @Override
    97111    public void visit(Way w) {
    98112        if (w.isUsable()) {
    99             if (w.isClosed() && w.hasTag(HIGHWAY, CLASSIFIED_HIGHWAYS) && w.hasTag("junction", "circular", "roundabout")
    100                     && IN_DOWNLOADED_AREA_STRICT.test(w)) {
    101                 // TODO: find out how to handle splitted roundabouts (see #12841)
    102                 testWrongRoundabout(w);
     113            if (isRoundabout(w) && w.hasTag(HIGHWAY, CLASSIFIED_HIGHWAYS) && IN_DOWNLOADED_AREA_STRICT.test(w)) {
     114                if (w.isClosed()) {
     115                    // TODO: find out how to handle split roundabouts (see #12841)
     116                    testWrongRoundabout(w);
     117                }
     118                testRoundaboutConnections(w, connectionNodesComplained);
    103119            }
    104120            if (w.hasKey(SOURCE_MAXSPEED)) {
    105121                // Check maxspeed, including context against highway
     
    109125        }
    110126    }
    111127
     128    /**
     129     * Find nodes in roundabout with more than one connected highway
     130     * @param w
     131     * @param complained
     132     */
     133    private void testRoundaboutConnections(Way w, Set<Node> complained) {
     134        List<OsmPrimitive> primitives = new ArrayList<>();
     135        for (Node n : w.getNodes()) {
     136            if (complained.contains(n))
     137                continue;
     138            int countConnectedArcs = 0;
     139            primitives.clear();
     140            for (Way p : n.getParentWays()) {
     141                if (p == w || !p.isUsable() || isRoundabout(p) || !p.hasTag(HIGHWAY, CLASSIFIED_HIGHWAYS))
     142                    continue;
     143
     144                primitives.add(p);
     145                if (!p.isFirstLastNode(n)) {
     146                    errors.add(TestError.builder(this, Severity.WARNING, ROUNDABOUT_CONNECTIONS_COUNT)
     147                            .message(tr("Highway doesn't start or end at roundabout"))
     148                            .primitives(Arrays.asList(p,w,n))
     149                            .highlight(n)
     150                            .build());
     151                    complained.add(n);
     152                }
     153                countConnectedArcs++;
     154            }
     155            if (countConnectedArcs > 1) {
     156                primitives.add(w);
     157                primitives.add(n);
     158                errors.add(TestError.builder(this, Severity.WARNING, ROUNDABOUT_CONNECTIONS_COUNT)
     159                        .message(tr("Multiple highways connected in one node of a roundabout"))
     160                        .primitives(new ArrayList<>(primitives))
     161                        .highlight(n)
     162                        .build());
     163                complained.add(n);
     164            }
     165        }
     166    }
     167
     168    private static boolean isRoundabout(Way w) {
     169        return w.hasTag("junction", "circular", "roundabout");
     170    }
     171
    112172    private void testWrongRoundabout(Way w) {
    113173        Map<String, List<Way>> map = new HashMap<>();
    114174        // Count all highways (per type) connected to this roundabout, except correct links
     
    190250            // in roundabout designs that physically separate a specific turn from the main roundabout
    191251            // But if we have more than a single adjacent class, and one of them is a roundabout, that's an error
    192252            for (Way w : sameClass) {
    193                 if (w.hasTag("junction", "circular", "roundabout")) {
     253                if (isRoundabout(w)) {
    194254                    return false;
    195255                }
    196256            }
  • src/org/openstreetmap/josm/data/validation/tests/IntersectionIssues.java

     
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.data.validation.tests;
     3
     4import static org.openstreetmap.josm.tools.I18n.tr;
     5
     6import java.util.ArrayList;
     7import java.util.Arrays;
     8import java.util.Collection;
     9import java.util.HashMap;
     10import java.util.HashSet;
     11import java.util.List;
     12import java.util.Set;
     13
     14import org.openstreetmap.josm.data.coor.EastNorth;
     15import org.openstreetmap.josm.data.coor.LatLon;
     16import org.openstreetmap.josm.data.osm.Node;
     17import org.openstreetmap.josm.data.osm.OsmPrimitive;
     18import org.openstreetmap.josm.data.osm.Way;
     19import org.openstreetmap.josm.data.osm.WaySegment;
     20import org.openstreetmap.josm.data.validation.Severity;
     21import org.openstreetmap.josm.data.validation.Test;
     22import org.openstreetmap.josm.data.validation.TestError;
     23import org.openstreetmap.josm.gui.progress.ProgressMonitor;
     24import org.openstreetmap.josm.tools.Geometry;
     25import org.openstreetmap.josm.tools.Logging;
     26import org.openstreetmap.josm.tools.Utils;
     27
     28/**
     29 * Finds issues with highway intersections
     30 * @author Taylor Smock
     31 * @since xxx
     32 */
     33public class IntersectionIssues extends Test {
     34    private static final int INTERSECTIONISSUESCODE = 3900;
     35    /** The code for an intersection which briefly interrupts a road */
     36    public static final int SHORT_DISCONNECT = INTERSECTIONISSUESCODE + 0;
     37    /** The code for a node that is almost on a way */
     38    public static final int NEARBY_NODE = INTERSECTIONISSUESCODE + 1;
     39    /** The distance to consider for nearby nodes/short disconnects */
     40    public static final double MAX_DISTANCE = 5.0; // meters
     41    /** The distance to consider for nearby nodes with tags */
     42    public static final double MAX_DISTANCE_NODE_INFORMATION = MAX_DISTANCE / 5.0; // meters
     43    /** The maximum angle for almost overlapping ways */
     44    public static final double MAX_ANGLE = 15.0; // degrees
     45    /** The maximum distance to consider for almost overlapping ways.
     46     * Please note that lane width should be at least 2.6m (if it is a full-size lane) */
     47    public static final double MAX_DISTANCE_OVERLAPPING = 1.0; // meters
     48
     49    private HashMap<String, ArrayList<Way>> ways;
     50    ArrayList<Way> allWays;
     51
     52    /**
     53     * Construct a new {@code IntersectionIssues} object
     54     */
     55    public IntersectionIssues() {
     56        super(tr("Intersection Issues"), tr("Check for issues at intersections"), OverlappingWays.class);
     57    }
     58
     59    @Override
     60    public void startTest(ProgressMonitor monitor) {
     61        super.startTest(monitor);
     62        ways = new HashMap<>();
     63        allWays = new ArrayList<>();
     64    }
     65
     66    @Override
     67    public void endTest() {
     68        Way pWay = null;
     69        try {
     70            for (ArrayList<Way> comparison : ways.values()) {
     71                pWay = comparison.get(0);
     72                checkNearbyEnds(comparison);
     73            }
     74            for (Way way : allWays) {
     75                pWay = way;
     76                for (Way way2 : allWays) {
     77                    if (way2.equals(way)) continue;
     78                    pWay = way2;
     79                    if (way.getBBox().intersects(way2.getBBox())) {
     80                        checkNearbyNodes(way, way2);
     81                    }
     82                }
     83            }
     84        } catch (Exception e) {
     85            if (pWay != null) {
     86                Logging.debug("Way https://osm.org/way/{0} caused an error", pWay.getOsmId());
     87            }
     88            Logging.warn(e);
     89        }
     90        ways = null;
     91        allWays = null;
     92        super.endTest();
     93    }
     94
     95    @Override
     96    public void visit(Way way) {
     97        if (!way.isUsable()) return;
     98        String highway = "highway";
     99        if (way.hasKey(highway) && !way.get(highway).contains("_link") &&
     100                !way.hasTag(highway, "proposed") && !way.hasTag(highway, "services")) {
     101            for (String tag : Arrays.asList("name", "ref")) {
     102                if (way.hasKey(tag)) {
     103                    ArrayList<Way> similar = ways.get(way.get(tag)) == null ? new ArrayList<>() : ways.get(way.get(tag));
     104                    if (!similar.contains(way)) similar.add(way);
     105                    ways.put(way.get(tag), similar);
     106                }
     107            }
     108            if (!allWays.contains(way)) allWays.add(way);
     109        }
     110    }
     111
     112    /**
     113     * Check for ends that are nearby but not directly connected
     114     * @param comparison Ways to look at
     115     */
     116    public void checkNearbyEnds(List<Way> comparison) {
     117        ArrayList<Way> errored = new ArrayList<>();
     118        for (Way one : comparison) {
     119            LatLon oneLast = one.lastNode().getCoor();
     120            LatLon oneFirst = one.firstNode().getCoor();
     121            for (Way two : comparison) {
     122                if (one.equals(two) || one.isFirstLastNode(two.firstNode())
     123                        || one.isFirstLastNode(two.lastNode()) ||
     124                        (errored.contains(one) && errored.contains(two))) continue;
     125                LatLon twoLast = two.lastNode().getCoor();
     126                LatLon twoFirst = two.firstNode().getCoor();
     127                int nearCase = getNearCase(oneFirst, oneLast, twoFirst, twoLast);
     128                if (nearCase == 8 && (two.firstNode().hasTag("noexit") && two.firstNode().get("noexit").equals("yes"))) {
     129                    continue;
     130                }
     131                if (nearCase != 0 && !checkForConnection(one, two, nearCase)) {
     132                    createCheckNearbyEndsError(nearCase, errored, one, two);
     133                    return;
     134                }
     135            }
     136        }
     137    }
     138
     139    // 8421 -> twoFirst/oneFirst, twoFirst/oneLast, twoLast/oneFirst, twoLast/oneLast
     140    private boolean checkForConnection(Way one, Way two, int nearCase) {
     141        List<Node> nodes = new ArrayList<>();
     142        if ((nearCase & 1) == 1) {
     143            nodes.add(one.lastNode());
     144            nodes.add(two.lastNode());
     145        }
     146        if ((nearCase & 2) == 2) {
     147            nodes.add(one.firstNode());
     148            nodes.add(two.lastNode());
     149        }
     150        if ((nearCase & 4) == 4) {
     151            nodes.add(one.lastNode());
     152            nodes.add(two.firstNode());
     153        }
     154        if ((nearCase & 8) == 8) {
     155            nodes.add(one.firstNode());
     156            nodes.add(two.firstNode());
     157        }
     158        for (Node node : nodes) {
     159            Collection<Way> parents = node.getParentWays();
     160            parents.remove(one);
     161            parents.remove(two);
     162            for (Way way : parents) {
     163                if ((one.hasKey("name") && way.hasKey("name") && way.get("name").equals(one.get("name"))) ||
     164                        (one.hasKey("ref") && way.hasKey("ref") && way.get("ref").equals(one.get("ref")))) {
     165                    return true;
     166                }
     167            }
     168        }
     169        return false;
     170    }
     171
     172    /**
     173     * Returns true if an exception is found
     174     * @param nodes Nodes that may be parts of roundabouts or other exceptions.
     175     * @return true if an exception is found
     176     */
     177    private boolean checkForExceptions(Node... nodes) {
     178        Collection<String> exceptions = new HashSet<>();
     179        exceptions.add("junction");
     180        for (Node node : nodes) {
     181            for (Way way : Utils.filteredCollection(node.getReferrers(), Way.class)) {
     182                for (String exceptionKey : exceptions) {
     183                    if (way.hasKey(exceptionKey)) return true;
     184                }
     185            }
     186        }
     187        return false;
     188    }
     189
     190    private void createCheckNearbyEndsError(int nearCase, List<Way> errored, Way one, Way two) {
     191        if (nearCase <= 0) return;
     192        List<Way> nearby = new ArrayList<>();
     193        nearby.add(one);
     194        nearby.add(two);
     195        List<WaySegment> segments = new ArrayList<>();
     196        if ((nearCase & 1) != 0) {
     197            if (checkForExceptions(one.lastNode(), two.lastNode())) return;
     198            segments.add(new WaySegment(two, two.getNodesCount() - 2));
     199            segments.add(new WaySegment(one, one.getNodesCount() - 2));
     200        }
     201        if ((nearCase & 2) != 0) {
     202            if (checkForExceptions(two.lastNode(), one.firstNode())) return;
     203            segments.add(new WaySegment(two, two.getNodesCount() - 2));
     204            segments.add(new WaySegment(one, 0));
     205        }
     206        if ((nearCase & 4) != 0) {
     207            if (checkForExceptions(two.firstNode(), one.lastNode())) return;
     208            segments.add(new WaySegment(two, 0));
     209            segments.add(new WaySegment(one, one.getNodesCount() - 2));
     210        }
     211        if ((nearCase & 8) != 0) {
     212            if (checkForExceptions(two.firstNode(), one.firstNode())) return;
     213            segments.add(new WaySegment(two, 0));
     214            segments.add(new WaySegment(one, 0));
     215        }
     216        errored.addAll(nearby);
     217        allWays.removeAll(errored);
     218        TestError.Builder testError = TestError.builder(this, Severity.WARNING, SHORT_DISCONNECT)
     219                .primitives(nearby)
     220                .highlightWaySegments(segments)
     221                .message(tr("Disconnected road"));
     222        errors.add(testError.build());
     223    }
     224
     225    /**
     226     * Get nearby cases
     227     * @param oneFirst The {@code LatLon} of the the first node of the first way
     228     * @param oneLast The {@code LatLon} of the the last node of the first way
     229     * @param twoFirst The {@code LatLon} of the the first node of the second way
     230     * @param twoLast The {@code LatLon} of the the last node of the second way
     231     * @return A bitwise int (8421 -> twoFirst/oneFirst, twoFirst/oneLast, twoLast/oneFirst, twoLast/oneLast)
     232     *
     233     */
     234    private int getNearCase(LatLon oneFirst, LatLon oneLast, LatLon twoFirst, LatLon twoLast) {
     235        int returnInt = 0;
     236        if (twoLast.greatCircleDistance(oneLast) <= MAX_DISTANCE) {
     237            returnInt = returnInt | 1;
     238        }
     239        if (twoLast.greatCircleDistance(oneFirst) <= MAX_DISTANCE) {
     240            returnInt = returnInt | 2;
     241        }
     242        if (twoFirst.greatCircleDistance(oneLast) <= MAX_DISTANCE) {
     243            returnInt = returnInt | 4;
     244        }
     245        if (twoFirst.greatCircleDistance(oneFirst) <= MAX_DISTANCE) {
     246            returnInt = returnInt | 8;
     247        }
     248        return returnInt;
     249    }
     250
     251    /**
     252     * Check nearby nodes to an intersection of two ways
     253     * @param way1 A way to check an almost intersection with
     254     * @param way2 A way to check an almost intersection with
     255     */
     256    public void checkNearbyNodes(Way way1, Way way2) {
     257        Collection<Node> intersectingNodes = getIntersectingNode(way1, way2);
     258        if (intersectingNodes.isEmpty() ||
     259                (way1.isOneway() != 0 && way2.isOneway() != 0 &&
     260                ((way1.hasKey("name") && way1.get("name").equals(way2.get("name"))) ||
     261                 (way1.hasKey("ref") && way1.get("ref").equals(way2.get("ref")))))) return;
     262        for (Node intersectingNode : intersectingNodes) {
     263            checkNearbyNodes(way1, way2, intersectingNode);
     264            checkNearbyNodes(way2, way1, intersectingNode);
     265        }
     266    }
     267
     268    private void checkNearbyNodes(Way way1, Way way2, Node nearby) {
     269        for (Node node : way1.getNeighbours(nearby)) {
     270            if (node.equals(nearby) || way2.containsNode(node)) continue;
     271            double distance = Geometry.getDistance(way2, node);
     272            double angle = getSmallestAngle(way2, nearby, node);
     273            if (((distance < MAX_DISTANCE && !node.isTagged())
     274                    || (distance < MAX_DISTANCE_NODE_INFORMATION && node.isTagged()))
     275                    && angle < MAX_ANGLE) {
     276                List<Way> primitiveIssues = new ArrayList<>();
     277                primitiveIssues.add(way1);
     278                primitiveIssues.add(way2);
     279                if (alreadyFoundInRelevantTest(primitiveIssues)) return;
     280
     281                List<WaySegment> waysegmentsOne = buildWaySegmentAroundNode(way1, nearby);
     282                List<WaySegment> waysegmentsTwo = buildWaySegmentAroundNode(way2, nearby);
     283                List<WaySegment> waysegments = new ArrayList<>();
     284                Node twoNear = null;
     285                Node oneNear = null;
     286                for (WaySegment twoSegment : waysegmentsTwo) {
     287                    if (angle == getSmallestAngle(twoSegment.toWay(), nearby, node)) {
     288                        waysegments.add(twoSegment);
     289                        twoNear = getNearNode(twoSegment, nearby);
     290                        break;
     291                    }
     292                }
     293                for (WaySegment oneSegment: waysegmentsOne) {
     294                    if (oneSegment.toWay().containsNode(node)) {
     295                        waysegments.add(oneSegment);
     296                        oneNear = getNearNode(oneSegment, nearby);
     297                        break;
     298                    }
     299                }
     300                if (waysegments.size() >= 2) {
     301                    double distance1 = Geometry.getDistance(waysegments.get(0).toWay(), twoNear);
     302                    double distance2 = Geometry.getDistance(waysegments.get(1).toWay(), oneNear);
     303                    if (Math.min(distance1, distance2) < MAX_DISTANCE_OVERLAPPING)
     304                        createNearlyOverlappingError(primitiveIssues, waysegments);
     305                }
     306            }
     307        }
     308    }
     309
     310    private void createNearlyOverlappingError(Collection<? extends OsmPrimitive> primitiveIssues, Collection<WaySegment> waysegments) {
     311        TestError.Builder testError = TestError.builder(this, Severity.WARNING, NEARBY_NODE)
     312                .primitives(primitiveIssues)
     313                .highlightWaySegments(waysegments)
     314                .message(tr("Nearly overlapping ways"));
     315        errors.add(testError.build());
     316    }
     317
     318    private Node getNearNode(WaySegment segment, Node nearby) {
     319        return segment.getFirstNode() != nearby ? segment.getFirstNode() : segment.getSecondNode();
     320    }
     321
     322    private List<WaySegment> buildWaySegmentAroundNode(Way way, Node node) {
     323        List<WaySegment> waysegments = new ArrayList<>();
     324        int index = way.getNodes().indexOf(node);
     325        if (index >= way.getNodesCount() - 1) index--;
     326        waysegments.add(new WaySegment(way, index));
     327        if (index > 0) waysegments.add(new WaySegment(way, index - 1));
     328        return waysegments;
     329    }
     330
     331    private boolean alreadyFoundInRelevantTest(Collection<? extends OsmPrimitive> primitiveIssues) {
     332        List<TestError> tErrors = new ArrayList<>();
     333        if (previousErrors != null) tErrors.addAll(previousErrors);
     334        tErrors.addAll(getErrors());
     335        for (TestError error : tErrors) {
     336            int code = error.getCode();
     337            if ((code == SHORT_DISCONNECT || code == NEARBY_NODE
     338                    || code == OverlappingWays.OVERLAPPING_HIGHWAY
     339                    || code == OverlappingWays.DUPLICATE_WAY_SEGMENT
     340                    || code == OverlappingWays.OVERLAPPING_HIGHWAY_AREA
     341                    || code == OverlappingWays.OVERLAPPING_WAY
     342                    || code == OverlappingWays.OVERLAPPING_WAY_AREA
     343                    || code == OverlappingWays.OVERLAPPING_RAILWAY
     344                    || code == OverlappingWays.OVERLAPPING_RAILWAY_AREA)
     345                    && primitiveIssues.containsAll(error.getPrimitives())) {
     346                return true;
     347            }
     348        }
     349        return false;
     350    }
     351
     352    /**
     353     * Get the intersecting node of two ways
     354     * @param way1 A way that (hopefully) intersects with way2
     355     * @param way2 A way to find an intersection with
     356     * @return A collection of nodes where the ways intersect
     357     */
     358    public Collection<Node> getIntersectingNode(Way way1, Way way2) {
     359        HashSet<Node> nodes = new HashSet<>();
     360        for (Node node : way1.getNodes()) {
     361            if (way2.containsNode(node)) {
     362                nodes.add(node);
     363            }
     364        }
     365        return nodes;
     366    }
     367
     368    /**
     369     * Get the corner angle between nodes
     370     * @param way The way with additional nodes
     371     * @param intersection The node to get angles around
     372     * @param comparison The node to get angles from
     373     * @return The angle for comparison->intersection->(additional node) (normalized degrees)
     374     */
     375    public double getSmallestAngle(Way way, Node intersection, Node comparison) {
     376        Set<Node> neighbours = way.getNeighbours(intersection);
     377        double angle = Double.MAX_VALUE;
     378        EastNorth eastNorthIntersection = intersection.getEastNorth();
     379        EastNorth eastNorthComparison = comparison.getEastNorth();
     380        for (Node node : neighbours) {
     381            EastNorth eastNorthNode = node.getEastNorth();
     382            double tAngle = Geometry.getCornerAngle(eastNorthComparison, eastNorthIntersection, eastNorthNode);
     383            if (Math.abs(tAngle) < angle) angle = Math.abs(tAngle);
     384        }
     385        return Geometry.getNormalizedAngleInDegrees(angle);
     386    }
     387}
  • src/org/openstreetmap/josm/data/validation/tests/RoutingIslandsTest.java

     
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.data.validation.tests;
     3
     4import static org.openstreetmap.josm.tools.I18n.marktr;
     5import static org.openstreetmap.josm.tools.I18n.tr;
     6
     7import java.util.ArrayList;
     8import java.util.Arrays;
     9import java.util.Collection;
     10import java.util.Collections;
     11import java.util.HashMap;
     12import java.util.HashSet;
     13import java.util.List;
     14import java.util.Map;
     15import java.util.Set;
     16import java.util.function.BiPredicate;
     17import java.util.stream.Collectors;
     18
     19import org.openstreetmap.josm.data.osm.Node;
     20import org.openstreetmap.josm.data.osm.OsmPrimitive;
     21import org.openstreetmap.josm.data.osm.Relation;
     22import org.openstreetmap.josm.data.osm.TagMap;
     23import org.openstreetmap.josm.data.osm.Way;
     24import org.openstreetmap.josm.data.preferences.sources.ValidatorPrefHelper;
     25import org.openstreetmap.josm.data.validation.Severity;
     26import org.openstreetmap.josm.data.validation.Test;
     27import org.openstreetmap.josm.data.validation.TestError;
     28import org.openstreetmap.josm.gui.progress.ProgressMonitor;
     29import org.openstreetmap.josm.spi.preferences.Config;
     30import org.openstreetmap.josm.tools.Access;
     31import org.openstreetmap.josm.tools.Pair;
     32
     33/**
     34 * A test for routing islands
     35 *
     36 * @author Taylor Smock
     37 * @since xxx
     38 */
     39public class RoutingIslandsTest extends Test {
     40
     41    private static final Map<Integer, Severity> SEVERITY_MAP = new HashMap<>();
     42    /** The code for the routing island validation test */
     43    public static final int ROUTING_ISLAND = 3900;
     44    /** The code for ways that are not connected to other ways, and are routable */
     45    public static final int LONELY_WAY = ROUTING_ISLAND + 1;
     46    static {
     47        SEVERITY_MAP.put(ROUTING_ISLAND, Severity.OTHER);
     48        SEVERITY_MAP.put(LONELY_WAY, Severity.ERROR);
     49    }
     50
     51    private static final String HIGHWAY = "highway";
     52    private static final String WATERWAY = "waterway";
     53
     54    /**
     55     * This is mostly as a sanity check, and to avoid infinite recursion (shouldn't
     56     * happen, but still)
     57     */
     58    private static final int MAX_LOOPS = 1000;
     59    /** Highways to check for routing connectivity */
     60    private Set<Way> potentialHighways;
     61    /** Waterways to check for routing connectivity */
     62    private Set<Way> potentialWaterways;
     63
     64    /**
     65     * Constructs a new {@code RightAngleBuildingTest} test.
     66     */
     67    public RoutingIslandsTest() {
     68        super(tr("Routing islands"), tr("Checks for roads that cannot be reached or left."));
     69        super.setPartialSelection(false);
     70    }
     71
     72    @Override
     73    public void startTest(ProgressMonitor monitor) {
     74        super.startTest(monitor);
     75        potentialHighways = new HashSet<>();
     76        potentialWaterways = new HashSet<>();
     77    }
     78
     79    @Override
     80    public void endTest() {
     81        Access.AccessTags.getByTransportType(Access.AccessTags.LAND_TRANSPORT_TYPE).parallelStream().forEach(mode -> {
     82            runTest(mode.getKey(), potentialHighways);
     83            progressMonitor.setCustomText(mode.getKey());
     84        });
     85        Access.AccessTags.getByTransportType(Access.AccessTags.WATER_TRANSPORT_TYPE).parallelStream().forEach(mode -> {
     86            progressMonitor.setCustomText(mode.getKey());
     87            runTest(mode.getKey(), potentialWaterways);
     88        });
     89        super.endTest();
     90    }
     91
     92    @Override
     93    public void visit(Way way) {
     94        if (way.isUsable() && way.getNodes().parallelStream().anyMatch(node -> way.getDataSet().getDataSourceBounds()
     95                .parallelStream().anyMatch(source -> source.contains(node.getCoor())))) {
     96            if ((way.hasKey(HIGHWAY) || way.hasKey(WATERWAY))
     97                    && way.getNodes().parallelStream().flatMap(node -> node.getReferrers().parallelStream()).distinct()
     98                            .allMatch(way::equals)
     99                    && way.getNodes().parallelStream().noneMatch(Node::isOutsideDownloadArea)) {
     100                errors.add(TestError.builder(this, SEVERITY_MAP.get(LONELY_WAY), LONELY_WAY).primitives(way)
     101                        .message(tr("MapWithAI (experimental)"), marktr("Routable way not connected to other ways"))
     102                        .build());
     103            } else if ((ValidatorPrefHelper.PREF_OTHER.get() || ValidatorPrefHelper.PREF_OTHER_UPLOAD.get()
     104                    || !Severity.OTHER.equals(SEVERITY_MAP.get(ROUTING_ISLAND))) && !isBeforeUpload) {
     105                if (way.hasKey(HIGHWAY)) {
     106                    potentialHighways.add(way);
     107                } else if (way.hasKey(WATERWAY)) {
     108                    potentialWaterways.add(way);
     109                }
     110            }
     111        }
     112    }
     113
     114    private void runTest(String currentTransportMode, Collection<Way> potentialWays) {
     115        Set<Way> incomingWays = new HashSet<>();
     116        Set<Way> outgoingWays = new HashSet<>();
     117        findConnectedWays(currentTransportMode, potentialWays, incomingWays, outgoingWays);
     118        Collection<Way> realPotentialWays = (incomingWays.isEmpty() || outgoingWays.isEmpty())
     119                ? expandNetwork(currentTransportMode, potentialWays)
     120                : potentialWays;
     121
     122        if (incomingWays.isEmpty() || outgoingWays.isEmpty()) {
     123            findConnectedWays(currentTransportMode, realPotentialWays, incomingWays, outgoingWays);
     124        }
     125        runGenericTest(currentTransportMode, realPotentialWays, incomingWays, outgoingWays);
     126
     127    }
     128
     129    /**
     130     * Expand a network from an initial selection
     131     *
     132     * @param currentTransportMode The current transport mode
     133     * @param initial              The initial collection of ways
     134     * @return An expanded collection of ways, which should be all connected ways
     135     *         that allow the current transport mode.
     136     */
     137    private static Collection<Way> expandNetwork(String currentTransportMode, Collection<Way> initial) {
     138        Collection<Way> connected = initial.parallelStream().flatMap(way -> way.getNodes().parallelStream())
     139                .flatMap(node -> node.getReferrers().parallelStream()).filter(Way.class::isInstance)
     140                .map(Way.class::cast).distinct().collect(Collectors.toSet());
     141        if (connected.containsAll(initial) && initial.containsAll(connected)) {
     142            return connected;
     143        }
     144        return expandNetwork(currentTransportMode, connected);
     145    }
     146
     147    /**
     148     * This test is run when there are known incoming/outgoing ways
     149     *
     150     * @param currentTransportMode The current transport mode
     151     * @param potentialWays        The ways to check
     152     * @param incomingWays         The incoming ways
     153     * @param outgoingWays         The outgoing ways
     154     */
     155    private void runGenericTest(String currentTransportMode, Collection<Way> potentialWays,
     156            Collection<Way> incomingWays, Collection<Way> outgoingWays) {
     157        Set<Way> toIgnore = potentialWays.parallelStream()
     158                .filter(way -> incomingWays.contains(way) || outgoingWays.contains(way))
     159                .filter(way -> !Access.getPositiveAccessValues().contains(
     160                        getDefaultAccessTags(way).getOrDefault(currentTransportMode, Access.AccessTags.NO.getKey())))
     161                .collect(Collectors.toSet());
     162        incomingWays.removeAll(toIgnore);
     163        outgoingWays.removeAll(toIgnore);
     164
     165        checkForUnconnectedWays(incomingWays, outgoingWays, currentTransportMode);
     166        List<Pair<String, Set<Way>>> problematic = collectConnected(potentialWays.parallelStream()
     167                .filter(way -> !incomingWays.contains(way) || !outgoingWays.contains(way))
     168                .filter(way -> Access.getPositiveAccessValues().contains(
     169                        getDefaultAccessTags(way).getOrDefault(currentTransportMode, Access.AccessTags.NO.getKey())))
     170                .collect(Collectors.toSet()))
     171                        .parallelStream()
     172                        .map(way -> new Pair<>(
     173                                (incomingWays.containsAll(way) ? marktr("outgoing") : marktr("incoming")), way))
     174                        .collect(Collectors.toList());
     175        createErrors(problematic, currentTransportMode);
     176    }
     177
     178    /**
     179     * Find ways that may be connected to the wider network
     180     *
     181     * @param currentTransportMode The current mode of transport
     182     * @param potentialWays        The ways to check for connections
     183     * @param incomingWays         A collection that will have incoming ways after
     184     *                             this method is called
     185     * @param outgoingWays         A collection that will have outgoing ways after
     186     *                             this method is called
     187     */
     188    private static void findConnectedWays(String currentTransportMode, Collection<Way> potentialWays,
     189            Collection<Way> incomingWays, Collection<Way> outgoingWays) {
     190        potentialWays.stream().filter(Way::isUsable).filter(Way::isOutsideDownloadArea).forEach(way -> {
     191            Node firstNode = firstNode(way, currentTransportMode);
     192            Node lastNode = lastNode(way, currentTransportMode);
     193            Integer isOneway = isOneway(way, currentTransportMode);
     194            if (firstNode != null && firstNode.isOutsideDownloadArea()) {
     195                incomingWays.add(way);
     196            }
     197            if (lastNode != null && lastNode.isOutsideDownloadArea()) {
     198                outgoingWays.add(way);
     199            }
     200            if (isOneway == 0 && firstNode != null && lastNode != null
     201                    && (firstNode.isOutsideDownloadArea() || lastNode.isOutsideDownloadArea())) {
     202                incomingWays.add(way);
     203                outgoingWays.add(way);
     204            }
     205        });
     206    }
     207
     208    /**
     209     * Take a collection of ways and modify it so that it is a list of connected
     210     * ways
     211     *
     212     * @param ways A collection of ways that may or may not be connected
     213     * @return a list of sets of ways that are connected
     214     */
     215    private static List<Set<Way>> collectConnected(Collection<Way> ways) {
     216        ArrayList<Set<Way>> collected = new ArrayList<>();
     217        ArrayList<Way> listOfWays = new ArrayList<>(ways);
     218        final int maxLoop = Config.getPref().getInt("validator.routingislands.maxrecursion", MAX_LOOPS);
     219        for (int i = 0; i < listOfWays.size(); i++) {
     220            Way initial = listOfWays.get(i);
     221            Set<Way> connected = new HashSet<>();
     222            connected.add(initial);
     223            int loopCounter = 0;
     224            while (!getConnected(connected) && loopCounter < maxLoop) {
     225                loopCounter++;
     226            }
     227            if (listOfWays.removeAll(connected)) {
     228                /*
     229                 * Not an issue -- this ensures that everything is accounted for, only triggers
     230                 * when ways removed
     231                 */
     232                i--; // NOSONAR
     233            }
     234            collected.add(connected);
     235        }
     236        return collected;
     237    }
     238
     239    private static boolean getConnected(Collection<Way> ways) {
     240        TagMap defaultAccess = getDefaultAccessTags(ways.iterator().next());
     241        return ways.addAll(ways.parallelStream().flatMap(way -> way.getNodes().parallelStream())
     242                .flatMap(node -> node.getReferrers().parallelStream()).filter(Way.class::isInstance)
     243                .map(Way.class::cast).filter(way -> getDefaultAccessTags(way).equals(defaultAccess))
     244                .collect(Collectors.toSet()));
     245    }
     246
     247    /**
     248     * Create errors for a problematic way
     249     *
     250     * @param problematic The set of problematic ways (Pairs are
     251     *                    &lt;incoming/outgoing, Set&lt;Connected ways with same
     252     *                    issue&gt;&gt;)
     253     * @param mode        The transport mode
     254     */
     255    private void createErrors(List<Pair<String, Set<Way>>> problematic, String mode) {
     256        for (Pair<String, Set<Way>> ways : problematic) {
     257            errors.add(
     258                    TestError.builder(this, SEVERITY_MAP.getOrDefault(ROUTING_ISLAND, Severity.OTHER), ROUTING_ISLAND)
     259                            .message(tr("MapWithAI (experimental)"), marktr("Routing island"), "{1}: {0}", tr(ways.a),
     260                                    mode == null ? marktr("default") : mode)
     261                            .primitives(ways.b).build());
     262        }
     263    }
     264
     265    /**
     266     * Check for unconnected ways
     267     *
     268     * @param incoming             The current incoming ways (will be modified)
     269     * @param outgoing             The current outgoing ways (will be modified)
     270     * @param currentTransportMode The transport mode we are investigating (may be
     271     *                             {@code null})
     272     */
     273    public static void checkForUnconnectedWays(Collection<Way> incoming, Collection<Way> outgoing,
     274            String currentTransportMode) {
     275        int loopCount = 0;
     276        int maxLoops = Config.getPref().getInt("validator.routingislands.maxrecursion", MAX_LOOPS);
     277        do {
     278            loopCount++;
     279        } while (loopCount <= maxLoops && getWaysFor(incoming, currentTransportMode,
     280                (way, oldWay) -> oldWay.containsNode(firstNode(way, currentTransportMode))
     281                        && checkAccessibility(oldWay, way, currentTransportMode)));
     282        loopCount = 0;
     283        do {
     284            loopCount++;
     285        } while (loopCount <= maxLoops && getWaysFor(outgoing, currentTransportMode,
     286                (way, oldWay) -> oldWay.containsNode(lastNode(way, currentTransportMode))
     287                        && checkAccessibility(oldWay, way, currentTransportMode)));
     288    }
     289
     290    private static boolean getWaysFor(Collection<Way> directional, String currentTransportMode,
     291            BiPredicate<Way, Way> predicate) {
     292        Set<Way> toAdd = new HashSet<>();
     293        for (Way way : directional) {
     294            for (Node node : way.getNodes()) {
     295                Set<Way> referrers = node.getReferrers(true).parallelStream().filter(Way.class::isInstance)
     296                        .map(Way.class::cast).filter(tWay -> !directional.contains(tWay)).collect(Collectors.toSet());
     297                for (Way tWay : referrers) {
     298                    if (isOneway(tWay, currentTransportMode) == 0 || predicate.test(tWay, way) || tWay.isClosed()) {
     299                        toAdd.add(tWay);
     300                    }
     301                }
     302            }
     303        }
     304        return directional.addAll(toAdd);
     305    }
     306
     307    /**
     308     * Check if I can get to way to from way from (currently doesn't work with via
     309     * ways)
     310     *
     311     * @param from                 The from way
     312     * @param to                   The to way
     313     * @param currentTransportMode The specific transport mode to check
     314     * @return {@code true} if the to way can be accessed from the from way TODO
     315     *         clean up and work with via ways
     316     */
     317    public static boolean checkAccessibility(Way from, Way to, String currentTransportMode) {
     318        boolean isAccessible = true;
     319
     320        List<Relation> relations = from.getReferrers().parallelStream().distinct().filter(Relation.class::isInstance)
     321                .map(Relation.class::cast).filter(relation -> "restriction".equals(relation.get("type")))
     322                .collect(Collectors.toList());
     323        for (Relation relation : relations) {
     324            if (((relation.hasKey("except") && relation.get("except").contains(currentTransportMode))
     325                    || (currentTransportMode == null || currentTransportMode.trim().isEmpty()))
     326                    && relation.getMembersFor(Collections.singleton(from)).parallelStream()
     327                            .anyMatch(member -> "from".equals(member.getRole()))
     328                    && relation.getMembersFor(Collections.singleton(to)).parallelStream()
     329                            .anyMatch(member -> "to".equals(member.getRole()))) {
     330                isAccessible = false;
     331            }
     332        }
     333        return isAccessible;
     334    }
     335
     336    /**
     337     * Check if a node connects to the outside world
     338     *
     339     * @param node The node to check
     340     * @return true if outside download area, connects to an aeroport, or a water
     341     *         transport
     342     */
     343    public static Boolean outsideConnections(Node node) {
     344        boolean outsideConnections = false;
     345        if (node.isOutsideDownloadArea() || node.hasTag("amenity", "parking_entrance", "parking", "parking_space",
     346                "motorcycle_parking", "ferry_terminal")) {
     347            outsideConnections = true;
     348        }
     349        return outsideConnections;
     350    }
     351
     352    /**
     353     * Check if a way is oneway for a specific transport type
     354     *
     355     * @param way           The way to look at
     356     * @param transportType The specific transport type
     357     * @return See {@link Way#isOneway} (but may additionally return {@code null} if
     358     *         the transport type cannot route down that way)
     359     */
     360    public static Integer isOneway(Way way, String transportType) {
     361        if (transportType == null || transportType.trim().isEmpty()) {
     362            return way.isOneway();
     363        }
     364        String forward = transportType.concat(":forward");
     365        String backward = transportType.concat(":backward");
     366        boolean possibleForward = "yes".equals(way.get(forward)) || (!way.hasKey(forward) && way.isOneway() != -1);
     367        boolean possibleBackward = "yes".equals(way.get(backward)) || (!way.hasKey(backward) && way.isOneway() != 1);
     368        if (transportType.equals(Access.AccessTags.FOOT.getKey()) && !"footway".equals(way.get(HIGHWAY))
     369                && !way.hasTag("foot:forward") && !way.hasTag("foot:backward")) {
     370            /*
     371             * Foot is almost never oneway, especially on generic road types. There are some
     372             * cases on mountain paths.
     373             */
     374            return 0;
     375        }
     376        if (possibleForward && !possibleBackward) {
     377            return 1;
     378        } else if (!possibleForward && possibleBackward) {
     379            return -1;
     380        } else if (!possibleBackward) {
     381            return null;
     382        }
     383        return 0;
     384    }
     385
     386    /**
     387     * Get the first node of a way respecting the oneway for a transport type
     388     *
     389     * @param way           The way to get the node from
     390     * @param transportType The transport type
     391     * @return The first node for the specified transport type, or null if it is not
     392     *         routable
     393     */
     394    public static Node firstNode(Way way, String transportType) {
     395        Integer oneway = isOneway(way, transportType);
     396        Node node = (Integer.valueOf(-1).equals(oneway)) ? way.lastNode() : way.firstNode();
     397
     398        Map<String, String> accessValues = getDefaultAccessTags(way);
     399        boolean accessible = Access.getPositiveAccessValues()
     400                .contains(accessValues.getOrDefault(transportType, Access.AccessTags.NO.getKey()));
     401        return (transportType == null || accessible) ? node : null;
     402    }
     403
     404    /**
     405     * Get the last node of a way respecting the oneway for a transport type
     406     *
     407     * @param way           The way to get the node from
     408     * @param transportType The transport type
     409     * @return The last node for the specified transport type, or the last node of
     410     *         the way, or null if it is not routable
     411     */
     412    public static Node lastNode(Way way, String transportType) {
     413        Integer oneway = isOneway(way, transportType);
     414        Node node = (Integer.valueOf(-1).equals(oneway)) ? way.firstNode() : way.lastNode();
     415        Map<String, String> accessValues = getDefaultAccessTags(way);
     416        boolean accessible = Access.getPositiveAccessValues()
     417                .contains(accessValues.getOrDefault(transportType, Access.AccessTags.NO.getKey()));
     418        return (transportType == null || accessible) ? node : null;
     419    }
     420
     421    /**
     422     * Get the default access tags for a primitive
     423     *
     424     * @param primitive The primitive to get access tags for
     425     * @return The map of access tags to access
     426     */
     427    public static TagMap getDefaultAccessTags(OsmPrimitive primitive) {
     428        TagMap access = new TagMap();
     429        final TagMap tags;
     430        if (primitive.hasKey(HIGHWAY)) {
     431            tags = getDefaultHighwayAccessTags(primitive.getKeys());
     432        } else if (primitive.hasKey(WATERWAY)) {
     433            tags = getDefaultWaterwayAccessTags(primitive.getKeys());
     434        } else {
     435            tags = new TagMap();
     436        }
     437        tags.putAll(Access.expandAccessValues(tags));
     438
     439        for (String direction : Arrays.asList("", "forward:", "backward:")) {
     440            Access.getTransportModes().parallelStream().map(direction::concat).filter(tags::containsKey)
     441                    .forEach(mode -> access.put(mode, tags.get(direction.concat(mode))));
     442        }
     443        return access;
     444    }
     445
     446    private static TagMap getDefaultWaterwayAccessTags(TagMap tags) {
     447        if ("river".equals(tags.get(WATERWAY))) {
     448            tags.putIfAbsent("boat", Access.AccessTags.YES.getKey());
     449        }
     450        return tags;
     451    }
     452
     453    private static TagMap getDefaultHighwayAccessTags(TagMap tags) {
     454        String highway = tags.get(HIGHWAY);
     455
     456        if (tags.containsKey("sidewalk") && !tags.get("sidewalk").equals(Access.AccessTags.NO.getKey())) {
     457            tags.putIfAbsent(Access.AccessTags.FOOT.getKey(), Access.AccessTags.YES.getKey());
     458        }
     459
     460        if (tags.keySet().parallelStream()
     461                .anyMatch(str -> str.contains("cycleway") && !Access.AccessTags.NO.getKey().equals(tags.get(str)))) {
     462            tags.putIfAbsent(Access.AccessTags.BICYCLE.getKey(), Access.AccessTags.YES.getKey());
     463        }
     464
     465        if ("residential".equals(highway)) {
     466            tags.putIfAbsent(Access.AccessTags.VEHICLE.getKey(), Access.AccessTags.YES.getKey());
     467            tags.putIfAbsent(Access.AccessTags.FOOT.getKey(), Access.AccessTags.YES.getKey());
     468            tags.putIfAbsent(Access.AccessTags.BICYCLE.getKey(), Access.AccessTags.YES.getKey());
     469        } else if (Arrays.asList("service", "unclassified", "tertiary", "tertiary_link").contains(highway)) {
     470            tags.putIfAbsent(Access.AccessTags.VEHICLE.getKey(), Access.AccessTags.YES.getKey());
     471        } else if (Arrays.asList("secondary", "secondary_link").contains(highway)) {
     472            tags.putIfAbsent(Access.AccessTags.VEHICLE.getKey(), Access.AccessTags.YES.getKey());
     473        } else if (Arrays.asList("primary", "primary_link").contains(highway)) {
     474            tags.putIfAbsent(Access.AccessTags.VEHICLE.getKey(), Access.AccessTags.YES.getKey());
     475            tags.putIfAbsent(Access.AccessTags.HGV.getKey(), Access.AccessTags.YES.getKey());
     476        } else if (Arrays.asList("motorway", "trunk", "motorway_link", "trunk_link").contains(highway)) {
     477            tags.putIfAbsent(Access.AccessTags.VEHICLE.getKey(), Access.AccessTags.YES.getKey());
     478            tags.putIfAbsent(Access.AccessTags.BICYCLE.getKey(), Access.AccessTags.NO.getKey());
     479            tags.putIfAbsent(Access.AccessTags.FOOT.getKey(), Access.AccessTags.NO.getKey());
     480        } else if ("steps".equals(highway)) {
     481            tags.putIfAbsent(Access.AccessTags.ACCESS_KEY.getKey(), Access.AccessTags.NO.getKey());
     482            tags.putIfAbsent(Access.AccessTags.FOOT.getKey(), Access.AccessTags.YES.getKey());
     483        } else if ("path".equals(highway)) {
     484            tags.putIfAbsent(Access.AccessTags.MOTOR_VEHICLE.getKey(), Access.AccessTags.NO.getKey());
     485            tags.putIfAbsent(Access.AccessTags.EMERGENCY.getKey(), Access.AccessTags.DESTINATION.getKey());
     486        } else if ("footway".equals(highway)) {
     487            tags.putIfAbsent(Access.AccessTags.FOOT.getKey(), Access.AccessTags.DESIGNATED.getKey());
     488        } else if ("bus_guideway".equals(highway)) {
     489            tags.putIfAbsent(Access.AccessTags.ACCESS_KEY.getKey(), Access.AccessTags.NO.getKey());
     490            tags.putIfAbsent(Access.AccessTags.BUS.getKey(), Access.AccessTags.DESIGNATED.getKey());
     491        } else if ("road".equals(highway)) { // Don't expect these to be routable
     492            tags.putIfAbsent(Access.AccessTags.ACCESS_KEY.getKey(), Access.AccessTags.NO.getKey());
     493        } else {
     494            tags.putIfAbsent(Access.AccessTags.ACCESS_KEY.getKey(), Access.AccessTags.YES.getKey());
     495        }
     496        return tags;
     497    }
     498
     499    /**
     500     * Get the error level for a test
     501     *
     502     * @param test The integer value of the test error
     503     * @return The severity for the test
     504     */
     505    public static Severity getErrorLevel(int test) {
     506        return SEVERITY_MAP.get(test);
     507    }
     508
     509    /**
     510     * Set the error level for a test
     511     *
     512     * @param test     The integer value of the test error
     513     * @param severity The new severity for the test
     514     */
     515    public static void setErrorLevel(int test, Severity severity) {
     516        SEVERITY_MAP.put(test, severity);
     517    }
     518}
  • src/org/openstreetmap/josm/data/validation/tests/TagChecker.java

     
    194194     */
    195195    public TagChecker() {
    196196        super(tr("Tag checker"), tr("This test checks for errors in tag keys and values."));
     197        setShowElements(true);
    197198    }
    198199
    199200    @Override
  • src/org/openstreetmap/josm/gui/MapViewState.java

     
    131131        this(projecting, mvs.viewWidth, mvs.viewHeight, mvs.scale, mvs.topLeft, mvs.topLeftInWindow, mvs.topLeftOnScreen);
    132132    }
    133133
    134     private static Point findTopLeftInWindow(JComponent position) {
     134    static Point findTopLeftInWindow(JComponent position) {
    135135        Point result = new Point();
    136136        // better than using swing utils, since this allows us to use the method if no screen is present.
    137137        Container component = position;
     
    143143        return result;
    144144    }
    145145
    146     private static Point findTopLeftOnScreen(JComponent position) {
     146    static Point findTopLeftOnScreen(JComponent position) {
    147147        try {
    148148            return position.getLocationOnScreen();
    149149        } catch (JosmRuntimeException | IllegalArgumentException | IllegalStateException e) {
  • src/org/openstreetmap/josm/gui/NavigatableComponent.java

     
    17161716        )/512;
    17171717    }
    17181718}
     1719
  • src/org/openstreetmap/josm/gui/dialogs/ValidatorDialog.java

     
    174174        fixAction.setEnabled(false);
    175175        buttons.add(new SideButton(fixAction));
    176176
    177         if (ValidatorPrefHelper.PREF_USE_IGNORE.get()) {
     177        if (Boolean.TRUE.equals(ValidatorPrefHelper.PREF_USE_IGNORE.get())) {
    178178            ignoreAction = new AbstractAction() {
    179179                {
    180180                    putValue(NAME, tr("Ignore"));
     
    261261            updateSelection(ds.getAllSelected());
    262262        }
    263263        MainApplication.getLayerManager().addAndFireActiveLayerChangeListener(this);
    264 
     264        validateAction.updateEnabledState();
    265265    }
    266266
    267267    @Override
  • src/org/openstreetmap/josm/gui/download/OSMDownloadSource.java

     
    77import java.awt.Dimension;
    88import java.awt.Font;
    99import java.awt.GridBagLayout;
     10import java.lang.reflect.InvocationTargetException;
    1011import java.util.ArrayList;
     12import java.util.Collections;
    1113import java.util.List;
    1214import java.util.concurrent.ExecutionException;
    1315import java.util.concurrent.Future;
     
    2325import org.openstreetmap.josm.actions.downloadtasks.DownloadNotesTask;
    2426import org.openstreetmap.josm.actions.downloadtasks.DownloadOsmTask;
    2527import org.openstreetmap.josm.actions.downloadtasks.DownloadParams;
     28import org.openstreetmap.josm.actions.downloadtasks.DownloadTask;
    2629import org.openstreetmap.josm.actions.downloadtasks.PostDownloadHandler;
    2730import org.openstreetmap.josm.data.Bounds;
    2831import org.openstreetmap.josm.data.ProjectionBounds;
    2932import org.openstreetmap.josm.data.ViewportData;
     33import org.openstreetmap.josm.data.gpx.GpxData;
     34import org.openstreetmap.josm.data.osm.DataSet;
     35import org.openstreetmap.josm.data.osm.NoteData;
    3036import org.openstreetmap.josm.data.preferences.BooleanProperty;
    3137import org.openstreetmap.josm.gui.MainApplication;
    3238import org.openstreetmap.josm.gui.MapFrame;
     
    4854     */
    4955    public static final String SIMPLE_NAME = "osmdownloadpanel";
    5056
     57    /** The possible methods to get data */
     58    static final List<DataDownloadType> DOWNLOAD_POSSIBILITIES = new ArrayList<>();
     59    static {
     60        // Order is important (determines button order, and what gets zoomed to)
     61        DOWNLOAD_POSSIBILITIES.add(new OsmDataDownloadType());
     62        DOWNLOAD_POSSIBILITIES.add(new GpsDataDownloadType());
     63        DOWNLOAD_POSSIBILITIES.add(new NotesDataDownloadType());
     64    }
     65
    5166    @Override
    5267    public AbstractDownloadSourcePanel<OSMDownloadData> createPanel(DownloadDialog dialog) {
    5368        return new OSMDownloadSourcePanel(this, dialog);
     
    5974                .orElseThrow(() -> new IllegalArgumentException("OSM downloads requires bounds"));
    6075        boolean zoom = settings.zoomToData();
    6176        boolean newLayer = settings.asNewLayer();
    62         List<Pair<AbstractDownloadTask<?>, Future<?>>> tasks = new ArrayList<>();
    63 
    64         if (data.isDownloadOSMData()) {
    65             DownloadOsmTask task = new DownloadOsmTask();
    66             task.setZoomAfterDownload(zoom && !data.isDownloadGPX() && !data.isDownloadNotes());
    67             Future<?> future = task.download(new DownloadParams().withNewLayer(newLayer), bbox, null);
    68             MainApplication.worker.submit(new PostDownloadHandler(task, future));
    69             if (zoom) {
    70                 tasks.add(new Pair<>(task, future));
     77        final List<Pair<AbstractDownloadTask<?>, Future<?>>> tasks = new ArrayList<>();
     78        DataDownloadType zoomTask = zoom ? data.getDownloadPossibilities().stream().findFirst().orElse(null) : null;
     79        data.getDownloadPossibilities().parallelStream().filter(DataDownloadType::isEnabled).forEach(type -> {
     80            try {
     81                AbstractDownloadTask<?> task = type.getDownloadClass().getDeclaredConstructor().newInstance();
     82                task.setZoomAfterDownload(type.equals(zoomTask));
     83                Future<?> future = task.download(new DownloadParams().withNewLayer(newLayer), bbox, null);
     84                MainApplication.worker.submit(new PostDownloadHandler(task, future));
     85                if (zoom) {
     86                    tasks.add(new Pair<AbstractDownloadTask<?>, Future<?>>(task, future));
     87                }
     88            } catch (InstantiationException | IllegalAccessException | IllegalArgumentException
     89                    | InvocationTargetException | NoSuchMethodException | SecurityException e) {
     90                Logging.error(e);
    7191            }
    72         }
     92        });
    7393
    74         if (data.isDownloadGPX()) {
    75             DownloadGpsTask task = new DownloadGpsTask();
    76             task.setZoomAfterDownload(zoom && !data.isDownloadOSMData() && !data.isDownloadNotes());
    77             Future<?> future = task.download(new DownloadParams().withNewLayer(newLayer), bbox, null);
    78             MainApplication.worker.submit(new PostDownloadHandler(task, future));
    79             if (zoom) {
    80                 tasks.add(new Pair<>(task, future));
    81             }
    82         }
    83 
    84         if (data.isDownloadNotes()) {
    85             DownloadNotesTask task = new DownloadNotesTask();
    86             task.setZoomAfterDownload(zoom && !data.isDownloadOSMData() && !data.isDownloadGPX());
    87             Future<?> future = task.download(new DownloadParams(), bbox, null);
    88             MainApplication.worker.submit(new PostDownloadHandler(task, future));
    89             if (zoom) {
    90                 tasks.add(new Pair<>(task, future));
    91             }
    92         }
    93 
    9494        if (zoom && tasks.size() > 1) {
    9595            MainApplication.worker.submit(() -> {
    9696                ProjectionBounds bounds = null;
     
    129129    }
    130130
    131131    /**
     132     * @return The possible downloads that JOSM can make in the default Download
     133     *         screen
     134     * @since xxx
     135     */
     136    public static List<DataDownloadType> getDownloadTypes() {
     137        return Collections.unmodifiableList(DOWNLOAD_POSSIBILITIES);
     138    }
     139
     140    /**
     141     * @param type The DataDownloadType object to remove
     142     * @return true if the list was modified
     143     * @since xxx
     144     */
     145    public static boolean removeDownloadType(DataDownloadType type) {
     146        boolean modified = false;
     147        if (!(type instanceof OsmDataDownloadType) && !(type instanceof GpsDataDownloadType)
     148                && !(type instanceof NotesDataDownloadType)) {
     149            modified = DOWNLOAD_POSSIBILITIES.remove(type);
     150        }
     151        return modified;
     152    }
     153
     154    /**
     155     * Add a download type to the default JOSM download window
     156     *
     157     * @param type The initialized type to download
     158     * @return true if the list was modified
     159     * @since xxx
     160     */
     161    public static boolean addDownloadType(DataDownloadType type) {
     162        boolean modified = false;
     163        if (!(type instanceof OsmDataDownloadType) && !(type instanceof GpsDataDownloadType)
     164                && !(type instanceof NotesDataDownloadType) && DOWNLOAD_POSSIBILITIES.parallelStream()
     165                        .noneMatch(possibility -> type.getClass().isInstance(possibility))) {
     166            modified = DOWNLOAD_POSSIBILITIES.add(type);
     167        }
     168        return modified;
     169    }
     170
     171    /**
    132172     * The GUI representation of the OSM download source.
    133173     * @since 12652
    134174     */
    135175    public static class OSMDownloadSourcePanel extends AbstractDownloadSourcePanel<OSMDownloadData> {
    136 
    137         private final JCheckBox cbDownloadOsmData;
    138         private final JCheckBox cbDownloadGpxData;
    139         private final JCheckBox cbDownloadNotes;
    140176        private final JLabel sizeCheck = new JLabel();
    141177
    142         private static final BooleanProperty DOWNLOAD_OSM = new BooleanProperty("download.osm.data", true);
    143         private static final BooleanProperty DOWNLOAD_GPS = new BooleanProperty("download.osm.gps", false);
    144         private static final BooleanProperty DOWNLOAD_NOTES = new BooleanProperty("download.osm.notes", false);
    145 
    146178        /**
    147179         * Creates a new {@link OSMDownloadSourcePanel}.
    148180         * @param dialog the parent download dialog, as {@code DownloadDialog.getInstance()} might not be initialized yet
     
    159191
    160192            // adding the download tasks
    161193            add(new JLabel(tr("Data Sources and Types:")), GBC.std().insets(5, 5, 1, 5).anchor(GBC.CENTER));
    162             cbDownloadOsmData = new JCheckBox(tr("OpenStreetMap data"), true);
    163             cbDownloadOsmData.setToolTipText(tr("Select to download OSM data in the selected download area."));
    164             cbDownloadOsmData.getModel().addChangeListener(checkboxChangeListener);
    165 
    166             cbDownloadGpxData = new JCheckBox(tr("Raw GPS data"));
    167             cbDownloadGpxData.setToolTipText(tr("Select to download GPS traces in the selected download area."));
    168             cbDownloadGpxData.getModel().addChangeListener(checkboxChangeListener);
    169 
    170             cbDownloadNotes = new JCheckBox(tr("Notes"));
    171             cbDownloadNotes.setToolTipText(tr("Select to download notes in the selected download area."));
    172             cbDownloadNotes.getModel().addChangeListener(checkboxChangeListener);
    173 
    174194            Font labelFont = sizeCheck.getFont();
    175195            sizeCheck.setFont(labelFont.deriveFont(Font.PLAIN, labelFont.getSize()));
    176196
    177             add(cbDownloadOsmData, GBC.std().insets(1, 5, 1, 5));
    178             add(cbDownloadGpxData, GBC.std().insets(1, 5, 1, 5));
    179             add(cbDownloadNotes, GBC.eol().insets(1, 5, 1, 5));
     197            DOWNLOAD_POSSIBILITIES
     198                    .forEach(obj -> add(obj.getCheckBox(checkboxChangeListener), GBC.std().insets(1, 5, 1, 5)));
    180199            add(sizeCheck, GBC.eol().anchor(GBC.EAST).insets(5, 5, 5, 2));
    181200
    182201            setMinimumSize(new Dimension(450, 115));
     
    184203
    185204        @Override
    186205        public OSMDownloadData getData() {
    187             return new OSMDownloadData(
    188                     isDownloadOsmData(),
    189                     isDownloadNotes(),
    190                     isDownloadGpxData());
     206            return new OSMDownloadData(DOWNLOAD_POSSIBILITIES);
    191207        }
    192208
    193209        @Override
    194210        public void rememberSettings() {
    195             DOWNLOAD_OSM.put(isDownloadOsmData());
    196             DOWNLOAD_GPS.put(isDownloadGpxData());
    197             DOWNLOAD_NOTES.put(isDownloadNotes());
     211            DOWNLOAD_POSSIBILITIES.forEach(type -> type.getBooleanProperty().put(type.getCheckBox().isSelected()));
    198212        }
    199213
    200214        @Override
    201215        public void restoreSettings() {
    202             cbDownloadOsmData.setSelected(DOWNLOAD_OSM.get());
    203             cbDownloadGpxData.setSelected(DOWNLOAD_GPS.get());
    204             cbDownloadNotes.setSelected(DOWNLOAD_NOTES.get());
     216            DOWNLOAD_POSSIBILITIES.forEach(type -> type.getCheckBox().setSelected(type.isEnabled()));
    205217        }
    206218
    207219        @Override
     
    225237             * must be chosen : raw osm data, gpx data, notes.
    226238             * If none of those are selected, then the corresponding dialog is shown to inform the user.
    227239             */
    228             if (!isDownloadOsmData() && !isDownloadGpxData() && !isDownloadNotes()) {
     240            if (DOWNLOAD_POSSIBILITIES.parallelStream().noneMatch(DataDownloadType::isEnabled)) {
     241                StringBuilder line1 = new StringBuilder("<html>");
     242                StringBuilder line2 = new StringBuilder(tr("Please choose to either download"));
     243                DOWNLOAD_POSSIBILITIES.forEach(type -> {
     244                    if (line1.length() == 6) {
     245                        line1.append(tr("Neither"));
     246                    } else {
     247                        line1.append(tr("nor"));
     248                    }
     249                    line1.append(" <strong>").append(type.getCheckBox().getText()).append("</strong> ");
     250                    line2.append(' ').append(type.getCheckBox().getText()).append(tr(", or"));
     251                });
     252                line1.append(tr("is enabled.")).append("<br>");
     253                line2.append(tr(" all.")).append("</html>");
    229254                JOptionPane.showMessageDialog(
    230255                        this.getParent(),
    231                         tr("<html>Neither <strong>{0}</strong> nor <strong>{1}</strong> nor <strong>{2}</strong> is enabled.<br>"
    232                                         + "Please choose to either download OSM data, or GPX data, or Notes, or all.</html>",
    233                                 cbDownloadOsmData.getText(),
    234                                 cbDownloadGpxData.getText(),
    235                                 cbDownloadNotes.getText()
    236                         ),
     256                        line1.append(line2).toString(),
    237257                        tr("Error"),
    238258                        JOptionPane.ERROR_MESSAGE
    239259                );
     
    250270         * Replies true if the user selected to download OSM data
    251271         *
    252272         * @return true if the user selected to download OSM data
     273         * @deprecated since xxx -- use {@link OSMDownloadSource#getDownloadTypes} with
     274         *             {@code get(0).getCheckBox().isSelected()}
    253275         */
     276        @Deprecated
    254277        public boolean isDownloadOsmData() {
    255             return cbDownloadOsmData.isSelected();
     278            return DOWNLOAD_POSSIBILITIES.get(0).getCheckBox().isSelected();
    256279        }
    257280
    258281        /**
     
    259282         * Replies true if the user selected to download GPX data
    260283         *
    261284         * @return true if the user selected to download GPX data
     285         * @deprecated since xxx -- use {@link OSMDownloadSource#getDownloadTypes} with
     286         *             {@code get(1).getCheckBox().isSelected()}
    262287         */
     288        @Deprecated
    263289        public boolean isDownloadGpxData() {
    264             return cbDownloadGpxData.isSelected();
     290            return DOWNLOAD_POSSIBILITIES.get(1).getCheckBox().isSelected();
    265291        }
    266292
    267293        /**
     
    268294         * Replies true if user selected to download notes
    269295         *
    270296         * @return true if user selected to download notes
     297         * @deprecated since xxx -- use {@link OSMDownloadSource#getDownloadTypes} with
     298         *             {@code get(2).getCheckBox().isSelected()}
    271299         */
     300        @Deprecated
    272301        public boolean isDownloadNotes() {
    273             return cbDownloadNotes.isSelected();
     302            return DOWNLOAD_POSSIBILITIES.get(2).getCheckBox().isSelected();
    274303        }
    275304
    276305        @Override
     
    295324                return;
    296325            }
    297326
    298             boolean isAreaTooLarge = false;
    299             if (!isDownloadNotes() && !isDownloadOsmData() && !isDownloadGpxData()) {
    300                 isAreaTooLarge = false;
    301             } else if (isDownloadNotes() && !isDownloadOsmData() && !isDownloadGpxData()) {
    302                 // see max_note_request_area in https://github.com/openstreetmap/openstreetmap-website/blob/master/config/example.application.yml
    303                 isAreaTooLarge = bbox.getArea() > Config.getPref().getDouble("osm-server.max-request-area-notes", 25);
    304             } else {
    305                 // see max_request_area in https://github.com/openstreetmap/openstreetmap-website/blob/master/config/example.application.yml
    306                 isAreaTooLarge = bbox.getArea() > Config.getPref().getDouble("osm-server.max-request-area", 0.25);
    307             }
    308 
    309             displaySizeCheckResult(isAreaTooLarge);
     327            displaySizeCheckResult(DOWNLOAD_POSSIBILITIES.parallelStream()
     328                    .anyMatch(type -> type.isDownloadAreaTooLarge(bbox)));
    310329        }
    311330
    312331        private void displaySizeCheckResult(boolean isAreaTooLarge) {
     
    325344     * Encapsulates data that is required to download from the OSM server.
    326345     */
    327346    static class OSMDownloadData {
    328         private final boolean downloadOSMData;
    329         private final boolean downloadNotes;
    330         private final boolean downloadGPX;
    331347
    332         OSMDownloadData(boolean downloadOSMData, boolean downloadNotes, boolean downloadGPX) {
    333             this.downloadOSMData = downloadOSMData;
    334             this.downloadNotes = downloadNotes;
    335             this.downloadGPX = downloadGPX;
     348        private List<DataDownloadType> downloadPossibilities;
     349
     350        /**
     351         * @param downloadPossibilities A list of DataDownloadTypes (instantiated, with
     352         *                              options set)
     353         */
     354        OSMDownloadData(List<DataDownloadType> downloadPossibilities) {
     355            this.downloadPossibilities = downloadPossibilities;
    336356        }
    337357
    338         boolean isDownloadOSMData() {
    339             return downloadOSMData;
     358        /**
     359         * @return A list of DataDownloadTypes (instantiated, with options set)
     360         */
     361        public List<DataDownloadType> getDownloadPossibilities() {
     362            return downloadPossibilities;
    340363        }
     364    }
    341365
    342         boolean isDownloadNotes() {
    343             return downloadNotes;
     366    /**
     367     * An interface to allow arbitrary download sources and types in the primary
     368     * download window of JOSM
     369     *
     370     * @since xxx
     371     */
     372    interface DataDownloadType {
     373        /**
     374         * @return The checkbox to be added to the UI
     375         */
     376        default JCheckBox getCheckBox() {
     377            return getCheckBox(null);
    344378        }
    345379
    346         boolean isDownloadGPX() {
    347             return downloadGPX;
     380        /**
     381         * @param checkboxChangeListener The listener for checkboxes (may be
     382         *                               {@code null})
     383         * @return The checkbox to be added to the UI
     384         */
     385        JCheckBox getCheckBox(ChangeListener checkboxChangeListener);
     386
     387        /**
     388         * @return The {@link DownloadTask} class which will be getting the data
     389         */
     390        Class<? extends AbstractDownloadTask<?>> getDownloadClass();
     391
     392        /**
     393         * @return The boolean indicating the last state of the download type
     394         */
     395        default boolean isEnabled() {
     396            return getBooleanProperty().get();
    348397        }
     398
     399        /**
     400         * @return The boolean property for this particular download type
     401         */
     402        BooleanProperty getBooleanProperty();
     403
     404        /**
     405         * Check if the area is too large for the current DataDownloadType
     406         *
     407         * @param bound The bound that will be downloaded
     408         * @return {@code true} if we definitely cannot download the area;
     409         */
     410        boolean isDownloadAreaTooLarge(Bounds bound);
    349411    }
     412
     413    static class OsmDataDownloadType implements DataDownloadType {
     414        static final BooleanProperty IS_ENABLED = new BooleanProperty("download.osm.data", true);
     415        JCheckBox cbDownloadOsmData;
     416
     417        @Override
     418        public JCheckBox getCheckBox(ChangeListener checkboxChangeListener) {
     419            if (cbDownloadOsmData == null) {
     420                cbDownloadOsmData = new JCheckBox(tr("OpenStreetMap data"), true);
     421                cbDownloadOsmData.setToolTipText(tr("Select to download OSM data in the selected download area."));
     422                cbDownloadOsmData.getModel().addChangeListener(checkboxChangeListener);
     423            }
     424            if (checkboxChangeListener != null) {
     425                cbDownloadOsmData.getModel().addChangeListener(checkboxChangeListener);
     426            }
     427            return cbDownloadOsmData;
     428        }
     429
     430        @Override
     431        public Class<? extends AbstractDownloadTask<DataSet>> getDownloadClass() {
     432            return DownloadOsmTask.class;
     433        }
     434
     435        @Override
     436        public BooleanProperty getBooleanProperty() {
     437            return IS_ENABLED;
     438        }
     439
     440        @Override
     441        public boolean isDownloadAreaTooLarge(Bounds bound) {
     442            // see max_request_area in
     443            // https://github.com/openstreetmap/openstreetmap-website/blob/master/config/example.application.yml
     444            return bound.getArea() > Config.getPref().getDouble("osm-server.max-request-area", 0.25);
     445        }
     446    }
     447
     448    static class GpsDataDownloadType implements DataDownloadType {
     449        static final BooleanProperty IS_ENABLED = new BooleanProperty("download.osm.gps", false);
     450        private JCheckBox cbDownloadGpxData;
     451
     452        @Override
     453        public JCheckBox getCheckBox(ChangeListener checkboxChangeListener) {
     454            if (cbDownloadGpxData == null) {
     455                cbDownloadGpxData = new JCheckBox(tr("Raw GPS data"));
     456                cbDownloadGpxData.setToolTipText(tr("Select to download GPS traces in the selected download area."));
     457            }
     458            if (checkboxChangeListener != null) {
     459                cbDownloadGpxData.getModel().addChangeListener(checkboxChangeListener);
     460            }
     461
     462            return cbDownloadGpxData;
     463        }
     464
     465        @Override
     466        public Class<? extends AbstractDownloadTask<GpxData>> getDownloadClass() {
     467            return DownloadGpsTask.class;
     468        }
     469
     470        @Override
     471        public BooleanProperty getBooleanProperty() {
     472            return IS_ENABLED;
     473        }
     474
     475        @Override
     476        public boolean isDownloadAreaTooLarge(Bounds bound) {
     477            return false;
     478        }
     479    }
     480
     481    static class NotesDataDownloadType implements DataDownloadType {
     482        static final BooleanProperty IS_ENABLED = new BooleanProperty("download.osm.notes", false);
     483        private JCheckBox cbDownloadNotes;
     484
     485        @Override
     486        public JCheckBox getCheckBox(ChangeListener checkboxChangeListener) {
     487            if (cbDownloadNotes == null) {
     488                cbDownloadNotes = new JCheckBox(tr("Notes"));
     489                cbDownloadNotes.setToolTipText(tr("Select to download notes in the selected download area."));
     490            }
     491            if (checkboxChangeListener != null) {
     492                cbDownloadNotes.getModel().addChangeListener(checkboxChangeListener);
     493            }
     494
     495            return cbDownloadNotes;
     496        }
     497
     498        @Override
     499        public Class<? extends AbstractDownloadTask<NoteData>> getDownloadClass() {
     500            return DownloadNotesTask.class;
     501        }
     502
     503        @Override
     504        public BooleanProperty getBooleanProperty() {
     505            return IS_ENABLED;
     506        }
     507
     508        @Override
     509        public boolean isDownloadAreaTooLarge(Bounds bound) {
     510            // see max_note_request_area in
     511            // https://github.com/openstreetmap/openstreetmap-website/blob/master/config/example.application.yml
     512            return bound.getArea() > Config.getPref().getDouble("osm-server.max-request-area-notes", 25);
     513        }
     514    }
     515
    350516}
  • src/org/openstreetmap/josm/gui/io/BasicUploadSettingsPanel.java

     
    179179        setLayout(new GridBagLayout());
    180180        setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
    181181        add(buildUploadCommentPanel(), GBC.eol().fill(GBC.BOTH));
    182         add(pnlUploadParameterSummary, GBC.eol().fill(GBC.HORIZONTAL));
    183         add(cbRequestReview, GBC.eol().fill(GBC.HORIZONTAL));
     182        add(pnlUploadParameterSummary, GBC.eol().fill(GBC.BOTH));
     183        add(cbRequestReview, GBC.eol().fill(GBC.BOTH));
    184184        cbRequestReview.addItemListener(e -> changesetReviewModel.setReviewRequested(e.getStateChange() == ItemEvent.SELECTED));
    185185    }
    186186
  • src/org/openstreetmap/josm/gui/io/UploadDialog.java

     
    116116     * @return the unique instance of the upload dialog
    117117     */
    118118    public static synchronized UploadDialog getUploadDialog() {
    119         if (uploadDialog == null) {
     119        if (uploadDialog == null || true) {
    120120            uploadDialog = new UploadDialog();
    121121        }
    122122        return uploadDialog;
  • src/org/openstreetmap/josm/gui/layer/AbstractTileSourceLayer.java

     
    405405            super(name);
    406406            this.layer = layer;
    407407            this.tile = tile;
     408            boolean rnad = (tile.getSource() instanceof ImageryInfo);
    408409        }
    409410    }
    410411
  • src/org/openstreetmap/josm/gui/layer/imagery/ReprojectionTile.java

     
    66import java.awt.image.BufferedImage;
    77
    88import org.openstreetmap.gui.jmapviewer.Tile;
     9import org.openstreetmap.gui.jmapviewer.interfaces.ICoordinate;
    910import org.openstreetmap.gui.jmapviewer.interfaces.TileSource;
    1011import org.openstreetmap.josm.data.ProjectionBounds;
    1112import org.openstreetmap.josm.data.coor.EastNorth;
     13import org.openstreetmap.josm.data.coor.LatLon;
    1214import org.openstreetmap.josm.data.imagery.CoordinateConversion;
     15import org.openstreetmap.josm.data.imagery.ImageryInfo;
    1316import org.openstreetmap.josm.data.projection.Projection;
    1417import org.openstreetmap.josm.data.projection.ProjectionRegistry;
    1518import org.openstreetmap.josm.data.projection.Projections;
     
    222225            return 1;
    223226        return null;
    224227    }
     228
     229    /**
     230     * Check if this tile will be inside the downloaded area
     231     *
     232     * @return {@code true} if this tile is inside the downloaded area
     233     * @since xxx
     234     */
     235    public boolean isInDownloadArea() {
     236        if (source instanceof ImageryInfo && ((ImageryInfo) source).getBounds() != null) {
     237            ICoordinate coord = source.tileXYToLatLon(this);
     238            ((ImageryInfo) source).getBounds().contains(new LatLon(coord.getLat(), coord.getLon()));
     239        }
     240        return false;
     241    }
    225242}
  • src/org/openstreetmap/josm/gui/mappaint/Cascade.java

     
    153153        if (klass == float[].class)
    154154            return (T) toFloatArray(o);
    155155
     156        if (klass == String[].class)
     157            return (T) toStringArray(o);
     158
    156159        if (klass == Color.class)
    157160            return (T) toColor(o);
    158161
    159162        if (klass == String.class) {
    160             if (o instanceof Keyword)
    161                 return (T) ((Keyword) o).val;
    162             if (o instanceof Color) {
    163                 Color c = (Color) o;
    164                 int alpha = c.getAlpha();
    165                 if (alpha != 255)
    166                     return (T) String.format("#%06x%02x", ((Color) o).getRGB() & 0x00ffffff, alpha);
    167                 return (T) String.format("#%06x", ((Color) o).getRGB() & 0x00ffffff);
    168             }
    169 
    170             return (T) o.toString();
     163            return (T) toString(o);
    171164        }
    172165
    173166        return null;
     
    207200        return null;
    208201    }
    209202
     203    private static String toString(Object o) {
     204        if (o instanceof Keyword)
     205            return ((Keyword) o).val;
     206        if (o instanceof Color) {
     207            Color c = (Color) o;
     208            int alpha = c.getAlpha();
     209            if (alpha != 255)
     210                return String.format("#%06x%02x", ((Color) o).getRGB() & 0x00ffffff, alpha);
     211            return String.format("#%06x", ((Color) o).getRGB() & 0x00ffffff);
     212        }
     213        return o.toString();
     214    }
     215
     216    private static String[] toStringArray(Object o) {
     217        if (o instanceof String[]) {
     218            return (String[]) o;
     219        }
     220        if (o instanceof List) {
     221            List<?> l = (List<?>) o;
     222            String[] a = new String[l.size()];
     223            for (int i = 0; i < l.size(); ++i) {
     224                String s = toString(l.get(i));
     225                if (s == null)
     226                    return null;
     227                else
     228                    a[i] = s;
     229            }
     230            return a;
     231        }
     232        String s = toString(o);
     233        if (s != null)
     234            return new String[] {s};
     235        return null;
     236    }
     237
    210238    private static float[] toFloatArray(Object o) {
    211239        if (o instanceof float[])
    212240            return (float[]) o;
  • src/org/openstreetmap/josm/gui/mappaint/mapcss/Functions.java

     
    2424import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2525import org.openstreetmap.josm.data.osm.Relation;
    2626import org.openstreetmap.josm.data.osm.RelationMember;
     27import org.openstreetmap.josm.data.osm.SimplePrimitiveId;
     28import org.openstreetmap.josm.data.osm.TagMap;
    2729import org.openstreetmap.josm.data.osm.Way;
    2830import org.openstreetmap.josm.data.osm.search.SearchCompiler;
    2931import org.openstreetmap.josm.data.osm.search.SearchCompiler.Match;
     
    3436import org.openstreetmap.josm.gui.mappaint.MapPaintStyles;
    3537import org.openstreetmap.josm.gui.mappaint.mapcss.ExpressionFactory.NullableArguments;
    3638import org.openstreetmap.josm.io.XmlWriter;
     39import org.openstreetmap.josm.io.remotecontrol.AddTagsDialog;
    3740import org.openstreetmap.josm.tools.AlphanumComparator;
    3841import org.openstreetmap.josm.tools.ColorHelper;
    3942import org.openstreetmap.josm.tools.Geometry;
     
    493496    }
    494497
    495498    /**
     499     * Gets the first non-null value of the key {@code key} from the object's parent(s).
     500     * @param env the environment
     501     * @param key the OSM key
     502     * @param tagValues a pipe (|) separated list of key=value pairs, same syntax as
     503     * {@link AddTagsDialog#parseUrlTagsToKeyValues}. This ignores the child selector.
     504     * @return a list of non-null values of the key {@code key} from the object's parent(s)
     505     * with the tags in {@code tagValues}
     506     * @since xxx
     507     */
     508    public static List<String> parent_tags(final Environment env, String key, String tagValues) { // NO_UCD (unused code)
     509        if (env.osm != null) {
     510            String[][] expectedTags = AddTagsDialog.parseUrlTagsToKeyValues(tagValues);
     511            TagMap expectedTagMap = new TagMap();
     512            for (String[] tag : expectedTags) {
     513                expectedTagMap.put(tag[0], tag[1]);
     514            }
     515            return env.osm.getReferrers().parallelStream().filter(prim -> prim.get(key) != null)
     516                    .filter(prim -> expectedTagMap.entrySet().parallelStream().allMatch(
     517                            entry -> prim.hasKey(entry.getKey()) && prim.get(entry.getKey()).equals(entry.getValue())))
     518                    .map(prim -> prim.get(key)).sorted(AlphanumComparator.getInstance())
     519                    .collect(Collectors.toList());
     520        }
     521        return Collections.emptyList();
     522    }
     523
     524    /**
    496525     * Gets the value of the key {@code key} from the object's child.
    497526     * @param env the environment
    498527     * @param key the OSM key
     
    515544    }
    516545
    517546    /**
     547     * Gets a list of all OSM id's of the object's parent(s) with a specified key.
     548     *
     549     * @param env      the environment
     550     * @param key      the OSM key
     551     * @param keyValue the regex value of the OSM key
     552     * @return a list of non-null values of the OSM id's from the object's parent(s)
     553     * @since xxx
     554     */
     555    public static List<IPrimitive> parent_osm_primitives(final Environment env, String key, String keyValue) {
     556        if (env.parent == null) {
     557            if (env.osm != null) {
     558                final ArrayList<IPrimitive> parents = new ArrayList<>();
     559                for (IPrimitive parent : env.osm.getReferrers()) {
     560                    if ((key == null || parent.get(key) != null)
     561                            && (keyValue == null || regexp_test(keyValue, parent.get(key)))) {
     562                        parents.add(parent);
     563                    }
     564                }
     565                return new ArrayList<>(parents);
     566            }
     567            return Collections.emptyList();
     568        }
     569        return Collections.singletonList(env.parent);
     570    }
     571
     572    /**
     573     * Gets a list of all OSM id's of the object's parent(s) with a specified key.
     574     *
     575     * @param env the environment
     576     * @param key the OSM key
     577     * @return a list of non-null values of the OSM id's from the object's parent(s)
     578     * @since xxx
     579     */
     580    public static List<IPrimitive> parent_osm_primitives(final Environment env, String key) { // NO_UCD (unused code)
     581        return parent_osm_primitives(env, key, null);
     582    }
     583
     584    /**
     585     * Gets a list of all OSM id's of the object's parent(s).
     586     *
     587     * @param env the environment
     588     * @return a list of non-null values of the OSM id's from the object's parent(s)
     589     * @since xxx
     590     */
     591    public static List<IPrimitive> parent_osm_primitives(final Environment env) { // NO_UCD (unused code)
     592        return parent_osm_primitives(env, null, null);
     593    }
     594
     595    /**
     596     * Convert Primitives to a string
     597     *
     598     * @param primitives The primitives to convert
     599     * @return A list of strings in the format type + id (in the list order)
     600     * @see SimplePrimitiveId#toSimpleId
     601     * @since xxx
     602     */
     603    public static List<String> convert_primitives_to_string(List<IPrimitive> primitives) {
     604        return primitives.stream().map(Functions::convert_primitive_to_string).collect(Collectors.toList());
     605    }
     606
     607    /**
     608     * Convert a primitive to a string
     609     *
     610     * @param primitive The primitive to convert
     611     * @return A string in the format type + id
     612     * @see SimplePrimitiveId#toSimpleId
     613     * @since xxx
     614     */
     615    public static String convert_primitive_to_string(IPrimitive primitive) {
     616        return SimplePrimitiveId.toSimpleId(primitive);
     617    }
     618
     619    /**
    518620     * Returns the lowest distance between the OSM object and a GPX point
    519621     * <p>
    520622     * @param env the environment
  • src/org/openstreetmap/josm/gui/tagging/presets/TaggingPresetReader.java

     
    2929import org.openstreetmap.josm.gui.tagging.presets.items.CheckGroup;
    3030import org.openstreetmap.josm.gui.tagging.presets.items.Combo;
    3131import org.openstreetmap.josm.gui.tagging.presets.items.ComboMultiSelect;
     32import org.openstreetmap.josm.gui.tagging.presets.items.Implies;
    3233import org.openstreetmap.josm.gui.tagging.presets.items.ItemSeparator;
    3334import org.openstreetmap.josm.gui.tagging.presets.items.Key;
    3435import org.openstreetmap.josm.gui.tagging.presets.items.Label;
     
    142143        parser.map("item_separator", ItemSeparator.class);
    143144        parser.mapBoth("chunk", Chunk.class);
    144145        parser.map("reference", Reference.class);
     146        parser.map("implies", Implies.class);
    145147        return parser;
    146148    }
    147149
     
    314316                        } else if (o instanceof Key && ((Key) o).value == null) {
    315317                            ((Key) o).value = ""; // Fix #8530
    316318                        }
     319                        if (o instanceof Key) {
     320                            Logging.debug(o.toString());
     321                        }
    317322                        listEntries.clear();
    318323                        lastrole = null;
    319324                    }
  • src/org/openstreetmap/josm/gui/tagging/presets/items/Key.java

     
    1818    /** The hardcoded value for key */
    1919    public String value; // NOSONAR
    2020
     21    /** {@code true} if implied */
     22    public boolean implied; // NOSONAR
     23
     24    /** {@code true} if recommended (will add even if it is implied) */
     25    public boolean recommended; // NOSONAR
     26
    2127    @Override
    2228    public boolean addToPanel(JPanel p, Collection<OsmPrimitive> sel, boolean presetInitiallyMatches) {
    2329        return false;
     
    2531
    2632    @Override
    2733    public void addCommands(List<Tag> changedTags) {
    28         changedTags.add(asTag());
     34        addCommands(changedTags, false);
    2935    }
    3036
    3137    /**
     38     * Adds the new tags to apply to selected OSM primitives when the preset holding
     39     * this item is applied.
     40     *
     41     * @param changedTags The list of changed tags to modify if needed
     42     * @param allTags     Add all the tags
     43     */
     44    public void addCommands(List<Tag> changedTags, boolean allTags) {
     45        if (allTags || !implied || recommended) {
     46            changedTags.add(asTag());
     47        }
     48    }
     49
     50    /**
    3251     * Returns the {@link Tag} set by this item
    3352     * @return the tag
    3453     */
  • src/org/openstreetmap/josm/io/AbstractReader.java

     
    326326            throw new IllegalDataException(e);
    327327        } finally {
    328328            OptionalLong minId = externalIdMap.values().stream().mapToLong(AbstractPrimitive::getUniqueId).min();
    329             if (minId.isPresent() && minId.getAsLong() < AbstractPrimitive.currentUniqueId()) {
    330                 AbstractPrimitive.advanceUniqueId(minId.getAsLong());
     329            synchronized (AbstractPrimitive.class) {
     330                if (minId.isPresent() && minId.getAsLong() < AbstractPrimitive.currentUniqueId()) {
     331                    AbstractPrimitive.advanceUniqueId(minId.getAsLong());
     332                }
    331333            }
    332334            progressMonitor.finishTask();
    333335            progressMonitor.removeCancelListener(cancelListener);
  • src/org/openstreetmap/josm/io/imagery/ImageryReader.java

     
    222222                        "permission-ref",
    223223                        "country-code",
    224224                        "category",
     225                        "source",
    225226                        "icon",
    226227                        "date",
    227228                        TILE_SIZE,
     
    528529                        entry.setImageryCategory(category);
    529530                    entry.setImageryCategoryOriginalString(cat);
    530531                    break;
     532                case "source":
     533                    entry.setSource(accumulator.toString());
     534                    break;
    531535                default: // Do nothing
    532536                }
    533537                break;
  • src/org/openstreetmap/josm/plugins/PluginHandler.java

     
    8888    /**
    8989     * Deprecated plugins that are removed on start
    9090     */
    91     static final List<DeprecatedPlugin> DEPRECATED_PLUGINS;
     91    public static final List<DeprecatedPlugin> DEPRECATED_PLUGINS;
    9292    static {
    9393        String inCore = tr("integrated into main program");
    9494        String replacedByPlugin = marktr("replaced by new {0} plugin");
  • src/org/openstreetmap/josm/tools/Access.java

     
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.tools;
     3
     4import java.util.ArrayList;
     5import java.util.Arrays;
     6import java.util.Collection;
     7import java.util.Collections;
     8import java.util.Comparator;
     9import java.util.HashMap;
     10import java.util.HashSet;
     11import java.util.List;
     12import java.util.Map;
     13import java.util.Map.Entry;
     14import java.util.Objects;
     15import java.util.Set;
     16import java.util.stream.Collectors;
     17
     18import org.openstreetmap.josm.data.osm.OsmPrimitive;
     19
     20/**
     21 * Access tag related utilities
     22 *
     23 * @author Taylor Smock
     24 * @see <a href="https://wiki.openstreetmap.org/wiki/Key:access">Key:access</a>
     25 * @since xxx
     26 */
     27public final class Access {
     28    /**
     29     * Holds access tags to avoid typos
     30     */
     31    public enum AccessTags {
     32        /** Air, land, and sea */
     33        ALL_TRANSPORT_TYPE("all"),
     34
     35        /**
     36         * @see <a href="https://wiki.openstreetmap.org/wiki/Key:access">Key:access</a>
     37         */
     38        ACCESS_KEY("access", ALL_TRANSPORT_TYPE),
     39
     40        // Access tag values
     41        /**
     42         * @see <a href=
     43         *      "https://wiki.openstreetmap.org/wiki/Tag:access%3Dyes">Tag:access%3Dyes</a>
     44         */
     45        YES("yes"),
     46        /**
     47         * @see <a href=
     48         *      "https://wiki.openstreetmap.org/wiki/Tag:access%3Dofficial">Tag:access%3Dofficial</a>
     49         */
     50        OFFICIAL("official"),
     51        /**
     52         * @see <a href=
     53         *      "https://wiki.openstreetmap.org/wiki/Tag:access%3Ddesignated">Tag:access%3Ddesignated</a>
     54         */
     55        DESIGNATED("designated"),
     56        /**
     57         * @see <a href=
     58         *      "https://wiki.openstreetmap.org/wiki/Tag:access%3Ddestination">Tag:access%3Ddestination</a>
     59         */
     60        DESTINATION("destination"),
     61        /**
     62         * @see <a href=
     63         *      "https://wiki.openstreetmap.org/wiki/Tag:access%3Ddelivery">Tag:access%3Ddelivery</a>
     64         */
     65        DELIVERY("delivery"),
     66        /**
     67         * @see <a href=
     68         *      "https://wiki.openstreetmap.org/wiki/Tag:access%3Dcustomers">Tag:access%3Dcustomers</a>
     69         */
     70        CUSTOMERS("customers"),
     71        /**
     72         * @see <a href=
     73         *      "https://wiki.openstreetmap.org/wiki/Tag:access%3Dpermissive">Tag:access%3Dpermissive</a>
     74         */
     75        PERMISSIVE("permissive"),
     76        /**
     77         * @see <a href=
     78         *      "https://wiki.openstreetmap.org/wiki/Tag:access%3Dagricultural">Tag:access%3Dagricultural</a>
     79         */
     80        AGRICULTURAL("agricultural"),
     81        /**
     82         * @see <a href=
     83         *      "https://wiki.openstreetmap.org/wiki/Tag:access%3Dforestry">Tag:access%3Dforestry</a>
     84         */
     85        FORESTRY("forestry"),
     86        /**
     87         * @see <a href=
     88         *      "https://wiki.openstreetmap.org/wiki/Tag:access%3Dprivate">Tag:access%3Dprivate</a>
     89         */
     90        PRIVATE("private"),
     91        /**
     92         * @see <a href=
     93         *      "https://wiki.openstreetmap.org/wiki/Tag:access%3Dno">Tag:access%3Dno</a>
     94         */
     95        NO("no"),
     96        /**
     97         * @see <a href=
     98         *      "https://wiki.openstreetmap.org/wiki/Tag:access%3Ddiscouraged">Tag:access%3Ddiscouraged</a>
     99         */
     100        DISCOURAGED("discouraged"),
     101        /**
     102         * @see <a href=
     103         *      "https://wiki.openstreetmap.org/wiki/Tag:access%3Duse_sidepath">Tag:access%3Duse_sidepath</a>
     104         */
     105        USE_SIDEPATH("use_sidepath"),
     106        /**
     107         * @see <a href=
     108         *      "https://wiki.openstreetmap.org/wiki/Tag:access%3Ddismount">Tag:access%3Ddismount</a>
     109         */
     110        DISMOUNT("dismount"),
     111        // Land
     112        /** Land transport types */
     113        LAND_TRANSPORT_TYPE("land", ALL_TRANSPORT_TYPE),
     114        /**
     115         * @see <a href=
     116         *      "https://wiki.openstreetmap.org/wiki/Key:vehicle">Key:vehicle</a>
     117         */
     118        VEHICLE("vehicle", LAND_TRANSPORT_TYPE),
     119        /**
     120         * @see <a href=
     121         *      "https://wiki.openstreetmap.org/wiki/Key:motor_vehicle">Key:motor_vehicle</a>
     122         */
     123        MOTOR_VEHICLE("motor_vehicle", LAND_TRANSPORT_TYPE),
     124        /**
     125         * @see <a href=
     126         *      "https://wiki.openstreetmap.org/wiki/Key:trailer">Key:trailer</a>
     127         */
     128        TRAILER("trailer", LAND_TRANSPORT_TYPE),
     129        /** @see <a href="https://wiki.openstreetmap.org/wiki/Key:foot">Key:foot</a> */
     130        FOOT("foot", LAND_TRANSPORT_TYPE),
     131        /** @see <a href="https://wiki.openstreetmap.org/wiki/Key:ski">Key:ski</a> */
     132        SKI("ski", LAND_TRANSPORT_TYPE),
     133        /**
     134         * @see <a href=
     135         *      "https://wiki.openstreetmap.org/wiki/Key:inline_skates">Key:inline_skates</a>
     136         */
     137        INLINE_SKATES("inline_skates", LAND_TRANSPORT_TYPE),
     138        /**
     139         * @see <a href=
     140         *      "https://wiki.openstreetmap.org/wiki/Key:ice_skates">Key:ice_skates</a>
     141         */
     142        ICE_SKATES("ice_skates", LAND_TRANSPORT_TYPE),
     143        /**
     144         * @see <a href="https://wiki.openstreetmap.org/wiki/Key:horse">Key:horse</a>
     145         */
     146        HORSE("horse", LAND_TRANSPORT_TYPE),
     147        /**
     148         * @see <a href=
     149         *      "https://wiki.openstreetmap.org/wiki/Key:bicycle">Key:bicycle</a>
     150         */
     151        BICYCLE("bicycle", LAND_TRANSPORT_TYPE),
     152        /**
     153         * @see <a href=
     154         *      "https://wiki.openstreetmap.org/wiki/Key:carriage">Key:carriage</a>
     155         */
     156        CARRIAGE("carriage", LAND_TRANSPORT_TYPE),
     157        /**
     158         * @see <a href=
     159         *      "https://wiki.openstreetmap.org/wiki/Key:caravan">Key:caravan</a>
     160         */
     161        CARAVAN("caravan", LAND_TRANSPORT_TYPE),
     162        /**
     163         * @see <a href=
     164         *      "https://wiki.openstreetmap.org/wiki/Key:motorcycle">Key:motorcycle</a>
     165         */
     166        MOTORCYCLE("motorcycle", LAND_TRANSPORT_TYPE),
     167        /**
     168         * @see <a href="https://wiki.openstreetmap.org/wiki/Key:moped">Key:moped</a>
     169         */
     170        MOPED("moped", LAND_TRANSPORT_TYPE),
     171        /** @see <a href="https://wiki.openstreetmap.org/wiki/Key:mofa">Key:mofa</a> */
     172        MOFA("mofa", LAND_TRANSPORT_TYPE),
     173        /**
     174         * @see <a href=
     175         *      "https://wiki.openstreetmap.org/wiki/Key:motorcar">Key:motorcar</a>
     176         */
     177        MOTORCAR("motorcar", LAND_TRANSPORT_TYPE),
     178        /**
     179         * @see <a href=
     180         *      "https://wiki.openstreetmap.org/wiki/Key:motorhome">Key:motorhome</a>
     181         */
     182        MOTORHOME("motorhome", LAND_TRANSPORT_TYPE),
     183        /** @see <a href="https://wiki.openstreetmap.org/wiki/Key:psv">Key:psv</a> */
     184        PSV("psv", LAND_TRANSPORT_TYPE),
     185        /** @see <a href="https://wiki.openstreetmap.org/wiki/Key:bus">Key:bus</a> */
     186        BUS("bus", LAND_TRANSPORT_TYPE),
     187        /** @see <a href="https://wiki.openstreetmap.org/wiki/Key:taxi">Key:taxi</a> */
     188        TAXI("taxi", LAND_TRANSPORT_TYPE),
     189        /**
     190         * @see <a href=
     191         *      "https://wiki.openstreetmap.org/wiki/Key:tourist_bus">Key:tourist_bus</a>
     192         */
     193        TOURIST_BUS("tourist_bus", LAND_TRANSPORT_TYPE),
     194        /**
     195         * @see <a href="https://wiki.openstreetmap.org/wiki/Key:goods">Key:goods</a>
     196         */
     197        GOODS("goods", LAND_TRANSPORT_TYPE),
     198        /** @see <a href="https://wiki.openstreetmap.org/wiki/Key:hgv">Key:hgv</a> */
     199        HGV("hgv", LAND_TRANSPORT_TYPE),
     200        /** @see <a href="https://wiki.openstreetmap.org/wiki/Key:atv">Key:atv</a> */
     201        ATV("atv", LAND_TRANSPORT_TYPE),
     202        /**
     203         * @see <a href=
     204         *      "https://wiki.openstreetmap.org/wiki/Key:snowmobile">Key:snowmobile</a>
     205         */
     206        SNOWMOBILE("snowmobile", LAND_TRANSPORT_TYPE),
     207        /**
     208         * @see <a href=
     209         *      "https://wiki.openstreetmap.org/wiki/Key:hgv_articulated">Key:hgv_articulated</a>
     210         */
     211        HGV_ARTICULATED("hgv_articulated", LAND_TRANSPORT_TYPE),
     212        /** @see <a href="https://wiki.openstreetmap.org/wiki/Key:ski">Key:ski</a> */
     213        SKI_NORDIC("ski:nordic", LAND_TRANSPORT_TYPE),
     214        /** @see <a href="https://wiki.openstreetmap.org/wiki/Key:ski">Key:ski</a> */
     215        SKI_ALPINE("ski:alpine", LAND_TRANSPORT_TYPE),
     216        /** @see <a href="https://wiki.openstreetmap.org/wiki/Key:ski">Key:ski</a> */
     217        SKI_TELEMARK("ski:telemark", LAND_TRANSPORT_TYPE),
     218        /**
     219         * @see <a href="https://wiki.openstreetmap.org/wiki/Key:coach">Key:coach</a>
     220         */
     221        COACH("coach", LAND_TRANSPORT_TYPE),
     222        /**
     223         * @see <a href=
     224         *      "https://wiki.openstreetmap.org/wiki/Key:golf_cart">Key:golf_cart</a>
     225         */
     226        GOLF_CART("golf_cart", LAND_TRANSPORT_TYPE),
     227        /**
     228         * @see <a href=
     229         *      "https://wiki.openstreetmap.org/wiki/Key:minibus">Key:minibus</a>
     230         */
     231        MINIBUS("minibus", LAND_TRANSPORT_TYPE),
     232        /**
     233         * @see <a href=
     234         *      "https://wiki.openstreetmap.org/wiki/Key:share_taxi">Key:share_taxi</a>
     235         */
     236        SHARE_TAXI("share_taxi", LAND_TRANSPORT_TYPE),
     237        /** @see <a href="https://wiki.openstreetmap.org/wiki/Key:hov">Key:hov</a> */
     238        HOV("hov", LAND_TRANSPORT_TYPE),
     239        /**
     240         * @see <a href=
     241         *      "https://wiki.openstreetmap.org/wiki/Key:car_sharing">Key:car_sharing</a>
     242         */
     243        CAR_SHARING("car_sharing", LAND_TRANSPORT_TYPE),
     244        /**
     245         * Routers should default to {@code yes}, regardless of higher access rules,
     246         * assuming it is navigatible by vehicle
     247         *
     248         * @see <a href=
     249         *      "https://wiki.openstreetmap.org/wiki/Key:emergency">Key:emergency</a>
     250         */
     251        EMERGENCY("emergency", LAND_TRANSPORT_TYPE),
     252        /**
     253         * @see <a href="https://wiki.openstreetmap.org/wiki/Key:hazmat">Key:hazmat</a>
     254         */
     255        HAZMAT("hazmat", LAND_TRANSPORT_TYPE),
     256        /**
     257         * @see <a href=
     258         *      "https://wiki.openstreetmap.org/wiki/Key:disabled">Key:disabled</a>
     259         */
     260        DISABLED("disabled", LAND_TRANSPORT_TYPE),
     261
     262        // Water
     263        /** Water transport type */
     264        WATER_TRANSPORT_TYPE("water", ALL_TRANSPORT_TYPE),
     265        /**
     266         * @see <a href=
     267         *      "https://wiki.openstreetmap.org/wiki/Key:swimming">Key:swimming</a>
     268         */
     269        SWIMMING("swimming", WATER_TRANSPORT_TYPE),
     270        /** @see <a href="https://wiki.openstreetmap.org/wiki/Key:boat">Key:boat</a> */
     271        BOAT("boat", WATER_TRANSPORT_TYPE),
     272        /**
     273         * @see <a href=
     274         *      "https://wiki.openstreetmap.org/wiki/Key:fishing_vessel">Key:fishing_vessel</a>
     275         */
     276        FISHING_VESSEL("fishing_vessel", WATER_TRANSPORT_TYPE),
     277        /** @see <a href="https://wiki.openstreetmap.org/wiki/Key:ship">Key:ship</a> */
     278        SHIP("ship", WATER_TRANSPORT_TYPE),
     279        /**
     280         * @see <a href=
     281         *      "https://wiki.openstreetmap.org/wiki/Key:motorboat">Key:motorboat</a>
     282         */
     283        MOTORBOAT("motorboat", WATER_TRANSPORT_TYPE),
     284        /**
     285         * @see <a href=
     286         *      "https://wiki.openstreetmap.org/wiki/Key:sailboat">Key:sailboat</a>
     287         */
     288        SAILBOAT("sailboat", WATER_TRANSPORT_TYPE),
     289        /**
     290         * @see <a href="https://wiki.openstreetmap.org/wiki/Key:canoe">Key:canoe</a>
     291         */
     292        CANOE("canoe", WATER_TRANSPORT_TYPE),
     293        /**
     294         * @see <a href=
     295         *      "https://wiki.openstreetmap.org/wiki/Key:passenger">Key:passenger</a>
     296         */
     297        PASSENGER("passenger", WATER_TRANSPORT_TYPE),
     298        /**
     299         * @see <a href="https://wiki.openstreetmap.org/wiki/Key:cargo">Key:cargo</a>
     300         */
     301        CARGO("cargo", WATER_TRANSPORT_TYPE),
     302        /** @see <a href="https://wiki.openstreetmap.org/wiki/Key:isps">Key:isps</a> */
     303        ISPS("isps", WATER_TRANSPORT_TYPE),
     304        /** @see <a href="https://wiki.openstreetmap.org/wiki/Key:bulk">Key:bulk</a> */
     305        BULK("bulk", WATER_TRANSPORT_TYPE),
     306        /**
     307         * @see <a href="https://wiki.openstreetmap.org/wiki/Key:tanker">Key:tanker</a>
     308         */
     309        TANKER("tanker", WATER_TRANSPORT_TYPE),
     310        /**
     311         * @see <a href=
     312         *      "https://wiki.openstreetmap.org/wiki/Key:container">Key:container</a>
     313         */
     314        CONTAINER("container", WATER_TRANSPORT_TYPE),
     315        /** @see <a href="https://wiki.openstreetmap.org/wiki/Key:imdg">Key:imdg</a> */
     316        IMDG("imdg", WATER_TRANSPORT_TYPE),
     317        /**
     318         * @see <a href="https://wiki.openstreetmap.org/wiki/Key:tanker">Key:tanker</a>
     319         */
     320        TANKER_GAS("tanker:gas", WATER_TRANSPORT_TYPE),
     321        /**
     322         * @see <a href="https://wiki.openstreetmap.org/wiki/Key:tanker">Key:tanker</a>
     323         */
     324        TANKER_OIL("tanker:oil", WATER_TRANSPORT_TYPE),
     325        /**
     326         * @see <a href="https://wiki.openstreetmap.org/wiki/Key:tanker">Key:tanker</a>
     327         */
     328        TANKER_CHEMICAL("tanker:chemical", WATER_TRANSPORT_TYPE),
     329        /**
     330         * @see <a href="https://wiki.openstreetmap.org/wiki/Key:tanker">Key:tanker</a>
     331         */
     332        TANKER_SINGLEHULL("tanker:singlehull", WATER_TRANSPORT_TYPE),
     333
     334        // Trains
     335        /** Rail transport type */
     336        RAIL_TRANSPORT_TYPE("rail", ALL_TRANSPORT_TYPE),
     337        /**
     338         * @see <a href="https://wiki.openstreetmap.org/wiki/Key:train">Key:train</a>
     339         */
     340        TRAIN("train", RAIL_TRANSPORT_TYPE);
     341
     342        private String key;
     343        private AccessTags type;
     344
     345        AccessTags(String key) {
     346            this.key = key;
     347            this.type = null;
     348        }
     349
     350        AccessTags(String key, AccessTags type) {
     351            this.key = key;
     352            this.type = type;
     353        }
     354
     355        /**
     356         * @return The key for the enum
     357         */
     358        public String getKey() {
     359            return key;
     360        }
     361
     362        /**
     363         * @return The AccessTags transport type
     364         *         (RAIL_TRANSPORT_TYPE/WATER_TRANSPORT_TYPE/etc)
     365         */
     366        public AccessTags getTransportType() {
     367            return type;
     368        }
     369
     370        /**
     371         * Check if this is a parent transport type (air/sea/water/all)
     372         *
     373         * @param potentialDescendant The AccessTags that we want to check
     374         * @return true if valueOf is a child transport type of this
     375         */
     376        public boolean parentOf(AccessTags potentialDescendant) {
     377            AccessTags tmp = potentialDescendant;
     378            while (tmp != null && tmp != this) {
     379                tmp = tmp.getTransportType();
     380            }
     381            return tmp == this;
     382        }
     383
     384        /**
     385         * Get the enum that matches the mode
     386         *
     387         * @param childrenMode The mode to get the access tag
     388         * @return The AccessTags enum that matches the childrenMode, or null
     389         */
     390        public static AccessTags get(String childrenMode) {
     391            for (AccessTags value : values()) {
     392                if (value.getKey().equalsIgnoreCase(childrenMode)) {
     393                    return value;
     394                }
     395            }
     396            return null;
     397        }
     398
     399        /**
     400         * Get access tags that match a certain type
     401         *
     402         * @param type {@link AccessTags#WATER_TRANSPORT_TYPE},
     403         *             {@link AccessTags#LAND_TRANSPORT_TYPE},
     404         *             {@link AccessTags#RAIL_TRANSPORT_TYPE}, or
     405         *             {@link AccessTags#ALL_TRANSPORT_TYPE}
     406         * @return A collection of access tags that match the given transport type
     407         */
     408        public static Collection<AccessTags> getByTransportType(AccessTags type) {
     409            return Arrays.stream(values()).filter(type::parentOf).collect(Collectors.toList());
     410        }
     411    }
     412
     413    /**
     414     * The key for children modes for the map, see {@link Access#getAccessMethods}
     415     */
     416    public static final String CHILDREN = "children";
     417
     418    /** The key for parent modes for the map, see {@link Access#getAccessMethods} */
     419    public static final String PARENT = "parent";
     420
     421    /** This set has keys that indicate that access is possible */
     422    private static final Set<String> POSITIVE_ACCESS = new HashSet<>(Arrays.asList(AccessTags.YES, AccessTags.OFFICIAL,
     423            AccessTags.DESIGNATED, AccessTags.DESTINATION, AccessTags.DELIVERY, AccessTags.CUSTOMERS,
     424            AccessTags.PERMISSIVE, AccessTags.AGRICULTURAL, AccessTags.FORESTRY).stream().map(AccessTags::getKey)
     425            .collect(Collectors.toSet()));
     426
     427    /** This set has all basic restriction values (yes/no/permissive/private/...) */
     428    private static final Set<String> RESTRICTION_VALUES = new HashSet<>(
     429            Arrays.asList(AccessTags.PRIVATE, AccessTags.NO).stream().map(AccessTags::getKey)
     430                    .collect(Collectors.toSet()));
     431
     432    /** This set has transport modes (access/foot/ski/motor_vehicle/vehicle/...) */
     433    private static final Set<String> TRANSPORT_MODES = new HashSet<>(
     434            Arrays.asList(AccessTags.ACCESS_KEY, AccessTags.FOOT, AccessTags.SKI, AccessTags.INLINE_SKATES,
     435                    AccessTags.ICE_SKATES, AccessTags.HORSE, AccessTags.VEHICLE, AccessTags.BICYCLE,
     436                    AccessTags.CARRIAGE, AccessTags.TRAILER, AccessTags.CARAVAN, AccessTags.MOTOR_VEHICLE,
     437                    AccessTags.MOTORCYCLE, AccessTags.MOPED, AccessTags.MOFA, AccessTags.MOTORCAR, AccessTags.MOTORHOME,
     438                    AccessTags.PSV, AccessTags.BUS, AccessTags.TAXI, AccessTags.TOURIST_BUS, AccessTags.GOODS,
     439                    AccessTags.HGV, AccessTags.AGRICULTURAL, AccessTags.ATV, AccessTags.SNOWMOBILE,
     440                    AccessTags.HGV_ARTICULATED, AccessTags.SKI_NORDIC, AccessTags.SKI_ALPINE, AccessTags.SKI_TELEMARK,
     441                    AccessTags.COACH, AccessTags.GOLF_CART, AccessTags.MINIBUS, AccessTags.SHARE_TAXI,
     442                    AccessTags.CAR_SHARING, AccessTags.HOV, AccessTags.EMERGENCY, AccessTags.HAZMAT,
     443                    AccessTags.DISABLED
     444            ).stream().map(AccessTags::getKey).collect(Collectors.toSet()));
     445
     446    /**
     447     * Map&lt;Access Method, Map&lt;Parent/Child, List&lt;Access Methods&gt;&gt;&gt;
     448     */
     449    private static final Map<String, Map<String, List<String>>> accessMethods = new HashMap<>();
     450    static {
     451        RESTRICTION_VALUES.addAll(POSITIVE_ACCESS);
     452        defaultInheritance();
     453    }
     454
     455    private Access() {
     456        // Hide the constructor
     457    }
     458
     459    /**
     460     * Create the default access inheritance, as defined at <a href=
     461     * "https://wiki.openstreetmap.org/wiki/Key:access#Transport_mode_restrictions">Key:access#Transport_mode_restrictions</a>
     462     */
     463    private static void defaultInheritance() {
     464        addMode(null, AccessTags.ACCESS_KEY);
     465
     466        // Land
     467        addModes(AccessTags.ACCESS_KEY, AccessTags.FOOT, AccessTags.SKI, AccessTags.INLINE_SKATES,
     468                AccessTags.ICE_SKATES, AccessTags.HORSE, AccessTags.VEHICLE);
     469        addModes(AccessTags.SKI, AccessTags.SKI_NORDIC, AccessTags.SKI_ALPINE, AccessTags.SKI_TELEMARK);
     470        addModes(AccessTags.VEHICLE, AccessTags.BICYCLE, AccessTags.CARRIAGE, AccessTags.TRAILER,
     471                AccessTags.MOTOR_VEHICLE);
     472        addModes(AccessTags.TRAILER, AccessTags.CARAVAN);
     473        addModes(AccessTags.MOTOR_VEHICLE, AccessTags.MOTORCYCLE, AccessTags.MOPED, AccessTags.MOFA,
     474                AccessTags.MOTORCAR, AccessTags.MOTORHOME, AccessTags.TOURIST_BUS, AccessTags.COACH, AccessTags.GOODS,
     475                AccessTags.HGV, AccessTags.AGRICULTURAL, AccessTags.GOLF_CART, AccessTags.ATV, AccessTags.SNOWMOBILE,
     476                AccessTags.PSV, AccessTags.HOV, AccessTags.CAR_SHARING, AccessTags.EMERGENCY, AccessTags.HAZMAT,
     477                AccessTags.DISABLED);
     478        addMode(AccessTags.HGV, AccessTags.HGV_ARTICULATED);
     479        addModes(AccessTags.PSV, AccessTags.BUS, AccessTags.MINIBUS, AccessTags.SHARE_TAXI, AccessTags.TAXI);
     480
     481        // Water
     482        addModes(AccessTags.ACCESS_KEY, AccessTags.SWIMMING, AccessTags.BOAT, AccessTags.FISHING_VESSEL,
     483                AccessTags.SHIP);
     484        addModes(AccessTags.BOAT, AccessTags.MOTORBOAT, AccessTags.SAILBOAT, AccessTags.CANOE);
     485        addModes(AccessTags.SHIP, AccessTags.PASSENGER, AccessTags.CARGO, AccessTags.ISPS);
     486        addModes(AccessTags.CARGO, AccessTags.BULK, AccessTags.TANKER, AccessTags.CONTAINER, AccessTags.IMDG);
     487        addModes(AccessTags.TANKER, AccessTags.TANKER_GAS, AccessTags.TANKER_OIL, AccessTags.TANKER_CHEMICAL,
     488                AccessTags.TANKER_SINGLEHULL);
     489
     490        // Rail
     491        addModes(AccessTags.ACCESS_KEY, AccessTags.TRAIN);
     492    }
     493
     494    /**
     495     * Add multiple modes with a common parent
     496     *
     497     * @param parent The parent of all the modes
     498     * @param modes  The modes to add
     499     */
     500    public static void addModes(AccessTags parent, AccessTags... modes) {
     501        for (AccessTags mode : modes) {
     502            addMode(parent, mode);
     503        }
     504    }
     505
     506    /**
     507     * Add modes to a list, modifying parents as needed
     508     *
     509     * @param mode   The mode to be added
     510     * @param parent The parent of the mode
     511     */
     512    public static void addMode(AccessTags parent, AccessTags mode) {
     513        Objects.requireNonNull(mode, "Mode must not be null");
     514        if (parent != null) {
     515            Map<String, List<String>> parentMap = accessMethods.getOrDefault(parent.getKey(), new HashMap<>());
     516            accessMethods.putIfAbsent(parent.getKey(), parentMap);
     517            List<String> parentChildren = parentMap.getOrDefault(CHILDREN, new ArrayList<>());
     518            if (!parentChildren.contains(mode.getKey()))
     519                parentChildren.add(mode.getKey());
     520            parentMap.putIfAbsent(CHILDREN, parentChildren);
     521        }
     522        Map<String, List<String>> modeMap = accessMethods.getOrDefault(mode.getKey(), new HashMap<>());
     523        accessMethods.putIfAbsent(mode.getKey(), modeMap);
     524        List<String> modeParent = modeMap.getOrDefault(PARENT,
     525                Collections.singletonList(parent == null ? null : parent.getKey()));
     526        modeMap.putIfAbsent(PARENT, modeParent);
     527    }
     528
     529    /**
     530     * Get the number of parents a mode has
     531     *
     532     * @param mode The mode with parents
     533     * @return The number of parents the mode has
     534     */
     535    public static int depth(String mode) {
     536        String tempMode = mode;
     537        int maxCount = accessMethods.size();
     538        while (tempMode != null && maxCount > 0) {
     539            tempMode = accessMethods.getOrDefault(tempMode, Collections.emptyMap())
     540                    .getOrDefault(PARENT, Collections.emptyList()).get(0);
     541            if (tempMode != null)
     542                maxCount--;
     543        }
     544        return accessMethods.size() - maxCount;
     545    }
     546
     547    /**
     548     * Expand access modes to cover the children of that access mode (currently only
     549     * supports the default hierarchy)
     550     *
     551     * @param mode   The transport mode
     552     * @param access The access value (the children transport modes inherit this
     553     *               value)
     554     * @return A map of the mode and its children (does not include parents)
     555     */
     556    public static Map<String, String> expandAccessMode(String mode, String access) {
     557        return expandAccessMode(mode, access, AccessTags.ALL_TRANSPORT_TYPE);
     558    }
     559
     560    /**
     561     * Expand access modes to cover the children of that access mode (currently only
     562     * supports the default hierarchy)
     563     *
     564     * @param mode          The transport mode
     565     * @param access        The access value (the children transport modes inherit
     566     *                      this value)
     567     * @param transportType {@link AccessTags#ALL_TRANSPORT_TYPE},
     568     *                      {@link AccessTags#LAND_TRANSPORT_TYPE},
     569     *                      {@link AccessTags#WATER_TRANSPORT_TYPE},
     570     *                      {@link AccessTags#RAIL_TRANSPORT_TYPE}
     571     * @return A map of the mode and its children (does not include parents)
     572     */
     573    public static Map<String, String> expandAccessMode(String mode, String access, AccessTags transportType) {
     574        Map<String, String> accessModes = new HashMap<>();
     575        accessModes.put(mode, access);
     576        if (accessMethods.containsKey(mode)) {
     577            for (String childrenMode : accessMethods.getOrDefault(mode, Collections.emptyMap()).getOrDefault(CHILDREN,
     578                    Collections.emptyList())) {
     579                if (transportType.parentOf(AccessTags.get(childrenMode)))
     580                    accessModes.putAll(expandAccessMode(childrenMode, access, transportType));
     581            }
     582        }
     583        return accessModes;
     584    }
     585
     586    /**
     587     * Merge two access maps (more specific wins)
     588     *
     589     * @param map1 A map with access values (see {@link Access#expandAccessMode})
     590     * @param map2 A map with access values (see {@link Access#expandAccessMode})
     591     * @return The merged map
     592     */
     593    public static Map<String, String> mergeMaps(Map<String, String> map1, Map<String, String> map2) {
     594        Map<String, String> merged;
     595        if (map1.keySet().containsAll(map2.keySet())) {
     596            merged = new HashMap<>(map1);
     597            merged.putAll(map2);
     598        } else { // if they don't overlap or if map2 contains all of map1
     599            merged = new HashMap<>(map2);
     600            merged.putAll(map1);
     601        }
     602        return merged;
     603    }
     604
     605    /**
     606     * Get the set of values that can generally be considered to be accessible
     607     *
     608     * @return A set of values that can be used for routing purposes (unmodifiable)
     609     */
     610    public static Set<String> getPositiveAccessValues() {
     611        return Collections.unmodifiableSet(POSITIVE_ACCESS);
     612    }
     613
     614    /**
     615     * Get the valid restriction values ({@code unknown} is not included). See
     616     *
     617     * @return Valid values for restrictions (unmodifiable)
     618     * @see <a href=
     619     *      "https://wiki.openstreetmap.org/wiki/Key:access#List_of_possible_values">Key:access#List_of_possible_values</a>
     620     */
     621    public static Set<String> getRestrictionValues() {
     622        return Collections.unmodifiableSet(RESTRICTION_VALUES);
     623    }
     624
     625    /**
     626     * Get the valid transport modes. See
     627     *
     628     * @return Value transport modes (unmodifiable)
     629     * @see <a href=
     630     *      "https://wiki.openstreetmap.org/wiki/Key:access#Transport_mode_restrictions">Key:access#Transport_mode_restrictions</a>
     631     */
     632    public static Set<String> getTransportModes() {
     633        return Collections.unmodifiableSet(TRANSPORT_MODES);
     634    }
     635
     636    /**
     637     * Get the access method hierarchy.
     638     *
     639     * @return The hierarchy for access modes (unmodifiable)
     640     * @see <a href=
     641     *      "https://wiki.openstreetmap.org/wiki/Key:access#Transport_mode_restrictions">Key:access#Transport_mode_restrictions</a>
     642     */
     643    public static Map<String, Map<String, List<String>>> getAccessMethods() {
     644        Map<String, Map<String, List<String>>> map = new HashMap<>();
     645        for (Entry<String, Map<String, List<String>>> entry : map.entrySet()) {
     646            Map<String, List<String>> tMap = new HashMap<>();
     647            entry.getValue().forEach((key, list) -> tMap.put(key, Collections.unmodifiableList(list)));
     648            map.put(entry.getKey(), Collections.unmodifiableMap(tMap));
     649        }
     650        return Collections.unmodifiableMap(map);
     651    }
     652
     653    /**
     654     * Get the implied access values for a primitive
     655     *
     656     * @param primitive     A primitive with access values
     657     * @param transportType {@link AccessTags#ALL_TRANSPORT_TYPE},
     658     *                      {@link AccessTags#LAND_TRANSPORT_TYPE},
     659     *                      {@link AccessTags#WATER_TRANSPORT_TYPE},
     660     *                      {@link AccessTags#RAIL_TRANSPORT_TYPE}
     661     * @return The implied access values (for example, "hgv=designated" adds
     662     *         "hgv_articulated=designated")
     663     */
     664    public static Map<String, String> getAccessValues(OsmPrimitive primitive, AccessTags transportType) {
     665        Map<String, String> accessValues = new HashMap<>();
     666        TRANSPORT_MODES.stream().filter(primitive::hasKey)
     667                .map(mode -> expandAccessMode(mode, primitive.get(mode), transportType))
     668                .forEach(modeAccess -> {
     669                    Map<String, String> tMap = mergeMaps(accessValues, modeAccess);
     670                    accessValues.clear();
     671                    accessValues.putAll(tMap);
     672                });
     673        return accessValues;
     674    }
     675
     676    /**
     677     * Expand a map of access values
     678     *
     679     * @param accessValues A map of mode, access type values
     680     * @return The expanded access values
     681     */
     682    public static Map<String, String> expandAccessValues(Map<String, String> accessValues) {
     683        Map<String, String> modes = new HashMap<>();
     684        List<Map<String, String>> list = accessValues.entrySet().stream()
     685                .map(entry -> expandAccessMode(entry.getKey(), entry.getValue()))
     686                .sorted(Comparator.comparingInt(Map::size))
     687                .collect(Collectors.toCollection(ArrayList::new));
     688        Collections.reverse(list);
     689        for (Map<String, String> access : list) {
     690            modes = mergeMaps(modes, access);
     691        }
     692        return modes;
     693    }
     694}
  • test/unit/org/openstreetmap/josm/command/MoveCommandTest.java

     
    1010import java.util.Collections;
    1111import java.util.List;
    1212import java.util.Set;
     13import java.util.stream.Collectors;
    1314
     15import org.junit.Assert;
    1416import org.junit.Before;
    1517import org.junit.Rule;
    1618import org.junit.Test;
    1719import org.openstreetmap.josm.TestUtils;
    1820import org.openstreetmap.josm.command.CommandTest.CommandTestDataWithRelation;
     21import org.openstreetmap.josm.data.UndoRedoHandler;
    1922import org.openstreetmap.josm.data.coor.EastNorth;
    2023import org.openstreetmap.josm.data.coor.LatLon;
    2124import org.openstreetmap.josm.data.osm.DataSet;
    2225import org.openstreetmap.josm.data.osm.Node;
    2326import org.openstreetmap.josm.data.osm.OsmPrimitive;
     27import org.openstreetmap.josm.data.osm.PrimitiveData;
    2428import org.openstreetmap.josm.data.osm.User;
     29import org.openstreetmap.josm.data.osm.Way;
     30import org.openstreetmap.josm.data.osm.visitor.MergeSourceBuildingVisitor;
    2531import org.openstreetmap.josm.data.projection.ProjectionRegistry;
    2632import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    2733import org.openstreetmap.josm.testutils.JOSMTestRules;
     
    3945     */
    4046    @Rule
    4147    @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
    42     public JOSMTestRules test = new JOSMTestRules().preferences().i18n().projection();
     48    public JOSMTestRules test = new JOSMTestRules().preferences().i18n().projection().commands();
    4349    private CommandTestDataWithRelation testData;
    4450
    4551    /**
     
    272278            .suppress(Warning.NONFINAL_FIELDS)
    273279            .verify();
    274280    }
     281
     282    /**
     283     * Test {@link MoveCommand#executeCommand()} and {@link MoveCommand#undoCommand()} with {@link AddPrimitivesCommand}
     284     */
     285    @Test
     286    public void testUndoRedoWithAddPrimitivesCommand() {
     287        final DataSet to = new DataSet();
     288    final DataSet from = new DataSet();
     289    final Way way1 = TestUtils.newWay("highway=tertiary", new Node(new LatLon(0, 0)),
     290            new Node(new LatLon(0.1, 0.1)));
     291    way1.getNodes().stream().forEach(node -> from.addPrimitive(node));
     292    from.addPrimitive(way1);
     293    from.addPrimitive(new Node(new LatLon(-0.1, 0.1)));
     294
     295    from.setSelected(way1);
     296    MergeSourceBuildingVisitor builder = new MergeSourceBuildingVisitor(from);
     297    DataSet hull = builder.build();
     298
     299    List<PrimitiveData> primitiveAddData = hull.allPrimitives().stream().map(OsmPrimitive::save)
     300            .collect(Collectors.toList());
     301
     302    UndoRedoHandler.getInstance().add(new SequenceCommand("random sequence", new AddPrimitivesCommand(primitiveAddData, primitiveAddData, to)));
     303
     304    Node tNode = (Node) to.getPrimitiveById(way1.firstNode());
     305
     306    UndoRedoHandler.getInstance().add(new MoveCommand(tNode, LatLon.ZERO));
     307
     308    Assert.assertTrue(UndoRedoHandler.getInstance().getRedoCommands().isEmpty());
     309    Assert.assertEquals(2, UndoRedoHandler.getInstance().getUndoCommands().size());
     310
     311    UndoRedoHandler.getInstance().undo(UndoRedoHandler.getInstance().getUndoCommands().size());
     312    Assert.assertTrue(UndoRedoHandler.getInstance().getUndoCommands().isEmpty());
     313    Assert.assertEquals(2, UndoRedoHandler.getInstance().getRedoCommands().size());
     314    UndoRedoHandler.getInstance().redo(UndoRedoHandler.getInstance().getRedoCommands().size());
     315
     316    UndoRedoHandler.getInstance().undo(UndoRedoHandler.getInstance().getUndoCommands().size());
     317    UndoRedoHandler.getInstance().redo(UndoRedoHandler.getInstance().getRedoCommands().size());
     318
     319    UndoRedoHandler.getInstance().undo(UndoRedoHandler.getInstance().getUndoCommands().size());
     320    UndoRedoHandler.getInstance().redo(UndoRedoHandler.getInstance().getRedoCommands().size());
     321
     322    }
    275323}
  • test/unit/org/openstreetmap/josm/data/validation/tests/IntersectionIssuesTest.java

     
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.data.validation.tests;
     3
     4import java.util.Collection;
     5import java.util.HashSet;
     6import java.util.List;
     7
     8import org.junit.Assert;
     9import org.junit.Rule;
     10import org.junit.Test;
     11import org.openstreetmap.josm.TestUtils;
     12import org.openstreetmap.josm.data.coor.LatLon;
     13import org.openstreetmap.josm.data.osm.DataSet;
     14import org.openstreetmap.josm.data.osm.Node;
     15import org.openstreetmap.josm.data.osm.OsmPrimitive;
     16import org.openstreetmap.josm.data.osm.Relation;
     17import org.openstreetmap.josm.data.osm.Way;
     18import org.openstreetmap.josm.data.validation.TestError;
     19import org.openstreetmap.josm.testutils.JOSMTestRules;
     20import org.openstreetmap.josm.tools.Utils;
     21
     22import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
     23
     24/**
     25 * JUnit Test of "Intersection Issues" validation test.
     26 */
     27public class IntersectionIssuesTest {
     28
     29    /**
     30     * Setup test.
     31     */
     32    @Rule
     33    @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
     34    public JOSMTestRules test = new JOSMTestRules().projection();
     35
     36    private static List<TestError> test(DataSet ds) throws Exception {
     37        IntersectionIssues test = new IntersectionIssues();
     38        test.initialize();
     39        test.startTest(null);
     40        for (Way w : ds.getWays()) {
     41            test.visit(w);
     42        }
     43        test.endTest();
     44        return test.getErrors();
     45    }
     46
     47    private static Collection<OsmPrimitive> createCollection(OsmPrimitive... osmPrimitives) {
     48        HashSet<OsmPrimitive> collection = new HashSet<>();
     49        for (OsmPrimitive primitive : osmPrimitives) {
     50            if (collection.contains(primitive)) continue;
     51            if (primitive instanceof Node) {
     52                collection.add(primitive);
     53            } else if (primitive instanceof Way) {
     54                collection.addAll(((Way) primitive).getNodes());
     55                collection.add(primitive);
     56            } else if (primitive instanceof Relation) {
     57                Relation relation = (Relation) primitive;
     58                collection.add(relation);
     59                for (OsmPrimitive tPrim : relation.getMemberPrimitives()) {
     60                    collection.addAll(createCollection(tPrim));
     61                }
     62            }
     63        }
     64        return collection;
     65    }
     66
     67    /**
     68     * This test area has 3 ways, where two have the same name and one has a
     69     * different name where there is a short disconnect between the two with
     70     * the same name.
     71     * @return The collection of ways to test.
     72     */
     73    private static Collection<OsmPrimitive> getTestArea1() {
     74        Node node1 = new Node(new LatLon(43.85619540309, 18.36535033094));
     75        Node node2 = new Node(new LatLon(43.85658651031, 18.36534961159));
     76        Node node3 = new Node(new LatLon(43.85662897034, 18.36534953349));
     77        Node node4 = new Node(new LatLon(43.85694640771, 18.36534894963));
     78        Node node5 = new Node(new LatLon(43.85658576291, 18.36456808743));
     79        Node node6 = new Node(new LatLon(43.8566296379, 18.36604757608));
     80
     81        Way way1 = TestUtils.newWay("highway=residential name=\"Test Road 1\"",
     82                node1, node2);
     83        Way way2 = TestUtils.newWay("highway=residential name=\"Test Road 1\"",
     84                node3, node4);
     85        Way way3 = TestUtils.newWay("highway=residential name=\"Test Road 2\"",
     86                node5, node2, node3, node6);
     87
     88        return createCollection(way1, way2, way3);
     89    }
     90
     91    private static Collection<OsmPrimitive> getTestArea2() {
     92        Node node1 = new Node(new LatLon(43.85641709632, 18.36725849681));
     93        Node node2 = new Node(new LatLon(43.85680820208, 18.36725777746));
     94        Node node3 = new Node(new LatLon(43.85685066196, 18.36725769936));
     95        Node node4 = new Node(new LatLon(43.85716809815, 18.3672571155));
     96        Node node5 = new Node(new LatLon(43.85680745469, 18.3664762533));
     97        Node node6 = new Node(new LatLon(43.85685132951, 18.36795574195));
     98        Way way1 = TestUtils.newWay("highway=residential name=\"Test Road 1\"",
     99                node1, node2);
     100        Way way2 = TestUtils.newWay("highway=residential name=\"Test Road 1\"",
     101                node2, node3);
     102        Way way3 = TestUtils.newWay("highway=residential name=\"Test Road 1\"",
     103                node3, node4);
     104        Way way4 = TestUtils.newWay("highway=residential name=\"Test Road 2\"",
     105                node5, node2);
     106        Way way5 = TestUtils.newWay("highway=residential name=\"Test Road 2\"",
     107                node3, node6);
     108
     109        return createCollection(way1, way2, way3, way4, way5);
     110    }
     111
     112    private static Collection<OsmPrimitive> getTestArea3() {
     113        Node node1 = new Node(new LatLon(43.85570051259, 18.36651114378));
     114        Node node2 = new Node(new LatLon(43.85613408344, 18.36651034633));
     115        Node node3 = new Node(new LatLon(43.85645152344, 18.36650976248));
     116        Node node4 = new Node(new LatLon(43.85609087565, 18.36572890027));
     117        Node node5 = new Node(new LatLon(43.85609162303, 18.3665104064));
     118        Node node6 = new Node(new LatLon(43.85613475101, 18.36720838893));
     119        Way way1 = TestUtils.newWay("highway=residential name=\"Test Road 1\"",
     120                node1, node2, node3);
     121        Way way2 = TestUtils.newWay("highway=residential name=\"Test Road 2\"",
     122                node4, node5, node2, node6);
     123
     124        return createCollection(way1, way2);
     125    }
     126
     127    /**
     128     * This is a section of road that should be found (almost overlapping)
     129     * @return A collection of ways and nodes to be tested
     130     */
     131    private static Collection<OsmPrimitive> getTestAreaRealWorld1() {
     132        // This was at https://www.openstreetmap.org/node/6123937677
     133        Node node1 = new Node(new LatLon(16.4151329, -95.0267841));
     134        Node node2 = new Node(new LatLon(16.4150313, -95.0267948));
     135        Node node3 = new Node(new LatLon(16.4149297, -95.0268057));
     136        Way way1 = TestUtils.newWay("highway=residential name=Calle Los Olivos",
     137                node1, node3);
     138        Way way2 = TestUtils.newWay(
     139                "highway=residential name=Calle Camino Carretero (La Amistad)",
     140                node1, node2, node3);
     141
     142        return createCollection(way1, way2);
     143    }
     144
     145    /**
     146     * This is a section of road that is almost overlapping
     147     * @return A collection of ways and nodes to be tested
     148     */
     149    private static Collection<OsmPrimitive> getTestAreaRealWorld2() {
     150        // this was at https://www.openstreetmap.org/way/435783782
     151        Node node1 = new Node(new LatLon(38.9881335, 31.1968857));
     152        Node node2 = new Node(new LatLon(38.9879932, 31.1968928));
     153        Node node3 = new Node(new LatLon(38.9877181, 31.1969176));
     154        Node node4 = new Node(new LatLon(38.9873522, 31.1969247));
     155        Node node5 = new Node(new LatLon(38.9870915, 31.1969116));
     156
     157        Way way1 = TestUtils.newWay("highway=track", node1, node2, node3, node4, node5);
     158        Way way2 = TestUtils.newWay("highway=track", node1, node5);
     159
     160        return createCollection(way1, way2);
     161    }
     162
     163    /**
     164     * This is a roundabout that happened to be a false positive for the
     165     * disconnected road test
     166     * @return A collection of ways and nodes to be tested
     167     */
     168    private static Collection<OsmPrimitive> getTestAreaRealWorld3() {
     169        // this was at https://www.openstreetmap.org/way/50635342
     170        Node node1 = new Node(new LatLon(38.3260143, 26.3085291));
     171
     172        // This probably should have been a junction=roundabout, but I don't know that for certain
     173        Way way1 = TestUtils.newWay("highway=secondary name=\"Atatürk Blv.\" oneway=yes ref=D300", node1);
     174        way1.addNode(new Node(new LatLon(38.3260353, 26.308504)));
     175        way1.addNode(new Node(new LatLon(38.3260507, 26.308473)));
     176        way1.addNode(new Node(new LatLon(38.3260596, 26.308438)));
     177        way1.addNode(new Node(new LatLon(38.3260612, 26.3083978)));
     178        way1.addNode(new Node(new LatLon(38.3260542, 26.3083586)));
     179        way1.addNode(new Node(new LatLon(38.326039, 26.3083233)));
     180        way1.addNode(new Node(new LatLon(38.3260169, 26.3082945)));
     181        way1.addNode(new Node(new LatLon(38.3259895, 26.3082745)));
     182        way1.addNode(new Node(new LatLon(38.3259562, 26.3082644)));
     183        way1.addNode(new Node(new LatLon(38.325922, 26.3082673)));
     184        way1.addNode(new Node(new LatLon(38.3258899, 26.3082829)));
     185        way1.addNode(new Node(new LatLon(38.3258629, 26.3083099)));
     186        way1.addNode(new Node(new LatLon(38.3258434, 26.3083458)));
     187        way1.addNode(new Node(new LatLon(38.325833, 26.3083874)));
     188        way1.addNode(new Node(new LatLon(38.3258326, 26.3084308)));
     189        way1.addNode(new Node(new LatLon(38.3258422, 26.3084723)));
     190        way1.addNode(new Node(new LatLon(38.3258609, 26.3085085)));
     191        way1.addNode(new Node(new LatLon(38.3258821, 26.3085321)));
     192        way1.addNode(new Node(new LatLon(38.3259071, 26.3085484)));
     193        way1.addNode(new Node(new LatLon(38.3259345, 26.3085564)));
     194        way1.addNode(new Node(new LatLon(38.3259626, 26.3085558)));
     195        way1.addNode(new Node(new LatLon(38.3259898, 26.3085465)));
     196        way1.addNode(node1);
     197
     198        Way way2 = TestUtils.newWay("highway=secondary name=\"Atatürk Blv.\" oneway=yes ref=D300", node1);
     199        way2.addNode(new Node(new LatLon(38.3259914, 26.3086145)));
     200        way2.addNode(new Node(new LatLon(38.3259765, 26.3087124)));
     201        way2.addNode(new Node(new LatLon(38.3259728, 26.3087982)));
     202
     203        return createCollection(way1, way2);
     204    }
     205
     206    private static Collection<OsmPrimitive> getTestAreaRealWorld4() {
     207        // This was at https://www.openstreetmap.org/way/584296023
     208        Node node1 = new Node(new LatLon(14.3272233, 120.9600503));
     209        Node node2 = new Node(new LatLon(14.326624, 120.9605805));
     210        Way way1 = TestUtils.newWay("highway=service oneway=yes name=\'Congressional Avenue Transit Lane\"", node1,
     211                new Node(new LatLon(14.3270856, 120.9601202)),
     212                new Node(new LatLon(14.326801, 120.9603738)), node2);
     213        Way way2 = TestUtils.newWay("highway=tertiary name=\"Congressional Avenue\" oneway=yes", node1, node2);
     214
     215        return createCollection(way1, way2);
     216    }
     217
     218    private static Collection<OsmPrimitive> getTestAreaRealWorld5() {
     219        // False positive for disconnected road
     220        // This was at https://www.openstreetmap.org/way/375383808
     221        Node node1 = new Node(new LatLon(44.4554384, 25.9568208));
     222        Node roundaboutStart = new Node(new LatLon(44.4554752, 25.9568265));
     223        // Simplified roundabout
     224        Way roundabout = TestUtils.newWay("highway=primary junction=roundabout name=\"Șoseaua de Centură\"",
     225                roundaboutStart,
     226                new Node(new LatLon(44.4555956, 25.9567686)),
     227                new Node(new LatLon(44.4556529, 25.9564646)),
     228                new Node(new LatLon(44.4554982, 25.9563004)),
     229                new Node(new LatLon(44.4553037, 25.9564588)),
     230                new Node(new LatLon(44.455302, 25.9566607)),
     231                node1, roundaboutStart);
     232        Way flare = TestUtils.newWay("highway=primary name=\"Șoseaua de Centură\" oneway=yes",
     233                new Node(new LatLon(44.4553062, 25.9571151)),
     234                new Node(new LatLon(44.4553669, 25.9569653)),
     235                node1);
     236        return createCollection(roundabout, flare);
     237    }
     238
     239    private static DataSet createDataSet(Collection<OsmPrimitive> primitives) {
     240        DataSet ds = new DataSet();
     241        for (Node node : Utils.filteredCollection(primitives, Node.class)) {
     242            if (ds.containsNode(node)) continue;
     243            ds.addPrimitive(node);
     244        }
     245        for (Way way : Utils.filteredCollection(primitives, Way.class)) {
     246            for (Node node : way.getNodes()) {
     247                if (ds.containsNode(node)) continue;
     248                ds.addPrimitive(node);
     249            }
     250            if (ds.containsWay(way)) continue;
     251            ds.addPrimitive(way);
     252        }
     253        return ds;
     254    }
     255
     256    /**
     257     * Unit test for {@link IntersectionIssues#checkNearbyEnds}
     258     * @throws Exception if any error occurs
     259     */
     260    @Test
     261    public void testCheckNearbyEnds() throws Exception {
     262        /** TODO add the following real world areas:
     263         * https://www.openstreetmap.org/way/261432285
     264         */
     265        DataSet area1 = createDataSet(getTestArea1());
     266        List<TestError> testResults = test(area1);
     267        Assert.assertEquals(1, testResults.size());
     268        Assert.assertEquals(IntersectionIssues.SHORT_DISCONNECT, testResults.get(0).getCode());
     269
     270        DataSet area2 = createDataSet(getTestArea2());
     271        testResults = test(area2);
     272        Assert.assertEquals(1, testResults.size());
     273        Assert.assertEquals(IntersectionIssues.SHORT_DISCONNECT, testResults.get(0).getCode());
     274
     275        area1.mergeFrom(area2);
     276        testResults = test(area1);
     277        Assert.assertEquals(2, testResults.size());
     278        for (TestError error : testResults) {
     279            Assert.assertEquals(IntersectionIssues.SHORT_DISCONNECT, error.getCode());
     280        }
     281
     282        testResults = test(createDataSet(getTestAreaRealWorld2()));
     283        Assert.assertEquals(1, testResults.size());
     284        Assert.assertNotEquals(IntersectionIssues.SHORT_DISCONNECT, testResults.get(0).getCode());
     285
     286        testResults = test(createDataSet(getTestAreaRealWorld3()));
     287        if (testResults.size() == 1)
     288            Assert.assertNotEquals(IntersectionIssues.SHORT_DISCONNECT, testResults.get(0).getCode());
     289        Assert.assertTrue(testResults.size() <= 1);
     290
     291        testResults = test(createDataSet(getTestAreaRealWorld5()));
     292        if (testResults.size() >= 1) {
     293            for (TestError result : testResults) {
     294                Assert.assertNotEquals(IntersectionIssues.SHORT_DISCONNECT, result.getCode());
     295            }
     296        }
     297    }
     298
     299    /**
     300     * Unit test for {@link IntersectionIssues#checkNearbyNodes}
     301     * @throws Exception if any error occurs
     302     */
     303    @Test
     304    public void testCheckAlmostOverlappingWays() throws Exception {
     305        List<TestError> testResults = test(createDataSet(getTestArea1()));
     306        Assert.assertEquals(1, testResults.size());
     307        Assert.assertNotEquals(IntersectionIssues.NEARBY_NODE, testResults.get(0).getCode());
     308
     309        testResults = test(createDataSet(getTestArea3()));
     310        Assert.assertEquals(1, testResults.size());
     311        Assert.assertEquals(IntersectionIssues.NEARBY_NODE, testResults.get(0).getCode());
     312
     313        testResults = test(createDataSet(getTestAreaRealWorld1()));
     314        Assert.assertEquals(1, testResults.size());
     315        Assert.assertEquals(IntersectionIssues.NEARBY_NODE, testResults.get(0).getCode());
     316
     317        DataSet area4 = createDataSet(getTestAreaRealWorld2());
     318        testResults = test(area4);
     319        Assert.assertEquals(1, testResults.size());
     320        Assert.assertEquals(IntersectionIssues.NEARBY_NODE, testResults.get(0).getCode());
     321
     322        testResults = test(createDataSet(getTestAreaRealWorld4()));
     323        Assert.assertEquals(0, testResults.size());
     324    }
     325}
  • test/unit/org/openstreetmap/josm/data/validation/tests/RoutingIslandsTestTest.java

     
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.data.validation.tests;
     3
     4import static org.junit.Assert.assertEquals;
     5import static org.junit.Assert.assertFalse;
     6import static org.junit.Assert.assertNull;
     7import static org.junit.Assert.assertSame;
     8import static org.junit.Assert.assertTrue;
     9
     10import java.util.Arrays;
     11import java.util.Collections;
     12import java.util.HashSet;
     13import java.util.Set;
     14import java.util.stream.Collectors;
     15
     16import org.junit.Rule;
     17import org.junit.Test;
     18import org.openstreetmap.josm.TestUtils;
     19import org.openstreetmap.josm.data.Bounds;
     20import org.openstreetmap.josm.data.DataSource;
     21import org.openstreetmap.josm.data.coor.LatLon;
     22import org.openstreetmap.josm.data.osm.DataSet;
     23import org.openstreetmap.josm.data.osm.Node;
     24import org.openstreetmap.josm.data.osm.OsmPrimitive;
     25import org.openstreetmap.josm.data.osm.Way;
     26import org.openstreetmap.josm.data.validation.Severity;
     27import org.openstreetmap.josm.spi.preferences.Config;
     28import org.openstreetmap.josm.testutils.JOSMTestRules;
     29
     30import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
     31
     32/**
     33 * Test class for {@link RoutingIslandsTest}
     34 *
     35 * @author Taylor Smock
     36 * @since xxx
     37 */
     38public class RoutingIslandsTestTest {
     39    /**
     40     * Setup test.
     41     */
     42    @Rule
     43    @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
     44    public JOSMTestRules rule = new JOSMTestRules().projection().preferences().timeout(30000);
     45
     46    /**
     47     * Test method for {@link RoutingIslandsTest#RoutingIslandsTest()} and the
     48     * testing apparatus
     49     */
     50    @Test
     51    public void testRoutingIslandsTest() {
     52        RoutingIslandsTest.setErrorLevel(RoutingIslandsTest.ROUTING_ISLAND, Severity.WARNING);
     53        RoutingIslandsTest test = new RoutingIslandsTest();
     54        test.startTest(null);
     55        test.endTest();
     56        assertTrue(test.getErrors().isEmpty());
     57
     58        DataSet ds = new DataSet();
     59
     60        Way way1 = TestUtils.newWay("highway=residential", new Node(new LatLon(0, 0)), new Node(new LatLon(1, 1)));
     61        Way way2 = TestUtils.newWay("highway=residential", new Node(new LatLon(-1, 0)), way1.firstNode());
     62        addToDataSet(ds, way1);
     63        addToDataSet(ds, way2);
     64
     65        ds.addDataSource(new DataSource(new Bounds(0, 0, 1, 1), "openstreetmap.org"));
     66
     67        test.clear();
     68        test.startTest(null);
     69        test.visit(ds.allPrimitives());
     70        test.endTest();
     71        assertTrue(test.getErrors().isEmpty());
     72
     73        ds.addDataSource(new DataSource(new Bounds(-5, -5, 5, 5), "openstreetmap.org"));
     74        test.clear();
     75        test.startTest(null);
     76        test.visit(ds.allPrimitives());
     77        test.endTest();
     78        assertFalse(test.getErrors().isEmpty());
     79        assertEquals(2, test.getErrors().get(0).getPrimitives().size());
     80
     81        ds.clear();
     82        way1 = TestUtils.newWay("highway=motorway oneway=yes", new Node(new LatLon(39.1156655, -108.5465434)),
     83                new Node(new LatLon(39.1157251, -108.5496874)), new Node(new LatLon(39.11592, -108.5566841)));
     84        way2 = TestUtils.newWay("highway=motorway oneway=yes", new Node(new LatLon(39.1157244, -108.55674)),
     85                new Node(new LatLon(39.1155548, -108.5496901)), new Node(new LatLon(39.1154827, -108.5462431)));
     86        addToDataSet(ds, way1);
     87        addToDataSet(ds, way2);
     88        ds.addDataSource(
     89                new DataSource(new Bounds(new LatLon(39.1136949, -108.558445), new LatLon(39.117242, -108.5489166)),
     90                        "openstreetmap.org"));
     91        test.clear();
     92        test.startTest(null);
     93        test.visit(ds.allPrimitives());
     94        test.endTest();
     95        assertFalse(test.getErrors().isEmpty());
     96        Way way3 = TestUtils.newWay("highway=motorway oneway=no", way1.getNode(1), way2.getNode(1));
     97        addToDataSet(ds, way3);
     98        test.clear();
     99        test.startTest(null);
     100        test.visit(ds.allPrimitives());
     101        test.endTest();
     102        assertFalse(test.getErrors().isEmpty());
     103
     104        Node tNode = new Node(new LatLon(39.1158845, -108.5599312));
     105        addToDataSet(ds, tNode);
     106        way1.addNode(tNode);
     107        tNode = new Node(new LatLon(39.115723, -108.5599239));
     108        addToDataSet(ds, tNode);
     109        way2.addNode(0, tNode);
     110        test.clear();
     111        test.startTest(null);
     112        test.visit(ds.allPrimitives());
     113        test.endTest();
     114        assertTrue(test.getErrors().isEmpty());
     115    }
     116
     117    /**
     118     * Test roundabouts
     119     */
     120    @Test
     121    public void testRoundabouts() {
     122        RoutingIslandsTest test = new RoutingIslandsTest();
     123        Way roundabout = TestUtils.newWay("highway=residential junction=roundabout oneway=yes",
     124                new Node(new LatLon(39.119582, -108.5262686)), new Node(new LatLon(39.1196494, -108.5260935)),
     125                new Node(new LatLon(39.1197572, -108.5260784)), new Node(new LatLon(39.1197929, -108.526391)),
     126                new Node(new LatLon(39.1196595, -108.5264047)));
     127        roundabout.addNode(roundabout.firstNode()); // close it up
     128        DataSet ds = new DataSet();
     129        addToDataSet(ds, roundabout);
     130        ds.addDataSource(
     131                new DataSource(new Bounds(new LatLon(39.1182025, -108.527574), new LatLon(39.1210588, -108.5251112)),
     132                        "openstreetmap.org"));
     133        Way incomingFlare = TestUtils.newWay("highway=residential oneway=yes",
     134                new Node(new LatLon(39.1196377, -108.5257567)), roundabout.getNode(3));
     135        addToDataSet(ds, incomingFlare);
     136        Way outgoingFlare = TestUtils.newWay("highway=residential oneway=yes", roundabout.getNode(2),
     137                incomingFlare.firstNode());
     138        addToDataSet(ds, outgoingFlare);
     139
     140        Way outgoingRoad = TestUtils.newWay("highway=residential", incomingFlare.firstNode(),
     141                new Node(new LatLon(39.1175184, -108.5219623)));
     142        addToDataSet(ds, outgoingRoad);
     143
     144        test.startTest(null);
     145        test.visit(ds.allPrimitives());
     146        test.endTest();
     147        assertTrue(test.getErrors().isEmpty());
     148    }
     149
     150    /**
     151     * Test method for {@link RoutingIslandsTest#checkForUnconnectedWays}.
     152     */
     153    @Test
     154    public void testCheckForUnconnectedWaysIncoming() {
     155        RoutingIslandsTest.checkForUnconnectedWays(Collections.emptySet(), Collections.emptySet(), null);
     156        Way way1 = TestUtils.newWay("highway=residential oneway=yes", new Node(new LatLon(0, 0)),
     157                new Node(new LatLon(1, 1)));
     158        Set<Way> incomingSet = new HashSet<>();
     159        DataSet ds = new DataSet();
     160        way1.getNodes().forEach(ds::addPrimitive);
     161        ds.addPrimitive(way1);
     162        incomingSet.add(way1);
     163        RoutingIslandsTest.checkForUnconnectedWays(incomingSet, Collections.emptySet(), null);
     164        assertEquals(1, incomingSet.size());
     165        assertSame(way1, incomingSet.iterator().next());
     166
     167        Way way2 = TestUtils.newWay("highway=residential", way1.firstNode(), new Node(new LatLon(-1, -2)));
     168        way2.getNodes().parallelStream().filter(node -> node.getDataSet() == null).forEach(ds::addPrimitive);
     169        ds.addPrimitive(way2);
     170
     171        RoutingIslandsTest.checkForUnconnectedWays(incomingSet, Collections.emptySet(), null);
     172        assertEquals(2, incomingSet.size());
     173        assertTrue(incomingSet.parallelStream().allMatch(way -> Arrays.asList(way1, way2).contains(way)));
     174
     175        Way way3 = TestUtils.newWay("highway=residential", way2.lastNode(), new Node(new LatLon(-2, -1)));
     176        way3.getNodes().parallelStream().filter(node -> node.getDataSet() == null).forEach(ds::addPrimitive);
     177        ds.addPrimitive(way3);
     178
     179        incomingSet.clear();
     180        incomingSet.add(way1);
     181        RoutingIslandsTest.checkForUnconnectedWays(incomingSet, Collections.emptySet(), null);
     182        assertEquals(3, incomingSet.size());
     183        assertTrue(incomingSet.parallelStream().allMatch(way -> Arrays.asList(way1, way2, way3).contains(way)));
     184
     185        Config.getPref().putInt("validator.routingislands.maxrecursion", 1);
     186        incomingSet.clear();
     187        incomingSet.add(way1);
     188        RoutingIslandsTest.checkForUnconnectedWays(incomingSet, Collections.emptySet(), null);
     189        assertEquals(2, incomingSet.size());
     190        assertTrue(incomingSet.parallelStream().allMatch(way -> Arrays.asList(way1, way2).contains(way)));
     191    }
     192
     193    /**
     194     * Test method for {@link RoutingIslandsTest#checkForUnconnectedWays}.
     195     */
     196    @Test
     197    public void testCheckForUnconnectedWaysOutgoing() {
     198        RoutingIslandsTest.checkForUnconnectedWays(Collections.emptySet(), Collections.emptySet(), null);
     199        Way way1 = TestUtils.newWay("highway=residential oneway=yes", new Node(new LatLon(0, 0)),
     200                new Node(new LatLon(1, 1)));
     201        Set<Way> outgoingSet = new HashSet<>();
     202        DataSet ds = new DataSet();
     203        way1.getNodes().forEach(ds::addPrimitive);
     204        ds.addPrimitive(way1);
     205        outgoingSet.add(way1);
     206        RoutingIslandsTest.checkForUnconnectedWays(Collections.emptySet(), outgoingSet, null);
     207        assertEquals(1, outgoingSet.size());
     208        assertSame(way1, outgoingSet.iterator().next());
     209
     210        Way way2 = TestUtils.newWay("highway=residential", way1.firstNode(), new Node(new LatLon(-1, -2)));
     211        way2.getNodes().parallelStream().filter(node -> node.getDataSet() == null).forEach(ds::addPrimitive);
     212        ds.addPrimitive(way2);
     213
     214        RoutingIslandsTest.checkForUnconnectedWays(Collections.emptySet(), outgoingSet, null);
     215        assertEquals(2, outgoingSet.size());
     216        assertTrue(outgoingSet.parallelStream().allMatch(way -> Arrays.asList(way1, way2).contains(way)));
     217
     218        Way way3 = TestUtils.newWay("highway=residential", way2.lastNode(), new Node(new LatLon(-2, -1)));
     219        way3.getNodes().parallelStream().filter(node -> node.getDataSet() == null).forEach(ds::addPrimitive);
     220        ds.addPrimitive(way3);
     221
     222        outgoingSet.clear();
     223        outgoingSet.add(way1);
     224        RoutingIslandsTest.checkForUnconnectedWays(Collections.emptySet(), outgoingSet, null);
     225        assertEquals(3, outgoingSet.size());
     226        assertTrue(outgoingSet.parallelStream().allMatch(way -> Arrays.asList(way1, way2, way3).contains(way)));
     227
     228        Config.getPref().putInt("validator.routingislands.maxrecursion", 1);
     229        outgoingSet.clear();
     230        outgoingSet.add(way1);
     231        RoutingIslandsTest.checkForUnconnectedWays(Collections.emptySet(), outgoingSet, null);
     232        assertEquals(2, outgoingSet.size());
     233        assertTrue(outgoingSet.parallelStream().allMatch(way -> Arrays.asList(way1, way2).contains(way)));
     234    }
     235
     236    /**
     237     * Test method for {@link RoutingIslandsTest#outsideConnections(Node)}.
     238     */
     239    @Test
     240    public void testOutsideConnections() {
     241        Node node = new Node(new LatLon(0, 0));
     242        DataSet ds = new DataSet(node);
     243        ds.addDataSource(new DataSource(new Bounds(-0.1, -0.1, -0.01, -0.01), "Test bounds"));
     244        node.setOsmId(1, 1);
     245        assertTrue(RoutingIslandsTest.outsideConnections(node));
     246        ds.addDataSource(new DataSource(new Bounds(-0.1, -0.1, 0.1, 0.1), "Test bounds"));
     247        assertFalse(RoutingIslandsTest.outsideConnections(node));
     248        node.put("amenity", "parking_entrance");
     249        assertTrue(RoutingIslandsTest.outsideConnections(node));
     250    }
     251
     252    /**
     253     * Test method for {@link RoutingIslandsTest#isOneway(Way, String)}.
     254     */
     255    @Test
     256    public void testIsOneway() {
     257        Way way = TestUtils.newWay("highway=residential", new Node(new LatLon(0, 0)), new Node(new LatLon(1, 1)));
     258        assertEquals(Integer.valueOf(0), RoutingIslandsTest.isOneway(way, null));
     259        assertEquals(Integer.valueOf(0), RoutingIslandsTest.isOneway(way, " "));
     260        way.put("oneway", "yes");
     261        assertEquals(Integer.valueOf(1), RoutingIslandsTest.isOneway(way, null));
     262        assertEquals(Integer.valueOf(1), RoutingIslandsTest.isOneway(way, " "));
     263        way.put("oneway", "-1");
     264        assertEquals(Integer.valueOf(-1), RoutingIslandsTest.isOneway(way, null));
     265        assertEquals(Integer.valueOf(-1), RoutingIslandsTest.isOneway(way, " "));
     266
     267        way.put("vehicle:forward", "yes");
     268        assertEquals(Integer.valueOf(0), RoutingIslandsTest.isOneway(way, "vehicle"));
     269        way.put("vehicle:backward", "no");
     270        assertEquals(Integer.valueOf(1), RoutingIslandsTest.isOneway(way, "vehicle"));
     271        way.put("vehicle:forward", "no");
     272        assertNull(RoutingIslandsTest.isOneway(way, "vehicle"));
     273        way.put("vehicle:backward", "yes");
     274        assertEquals(Integer.valueOf(-1), RoutingIslandsTest.isOneway(way, "vehicle"));
     275
     276        way.put("oneway", "yes");
     277        way.remove("vehicle:backward");
     278        way.remove("vehicle:forward");
     279        assertEquals(Integer.valueOf(1), RoutingIslandsTest.isOneway(way, "vehicle"));
     280        way.remove("oneway");
     281        assertEquals(Integer.valueOf(0), RoutingIslandsTest.isOneway(way, "vehicle"));
     282
     283        way.put("oneway", "-1");
     284        assertEquals(Integer.valueOf(-1), RoutingIslandsTest.isOneway(way, "vehicle"));
     285    }
     286
     287    /**
     288     * Test method for {@link RoutingIslandsTest#firstNode(Way, String)}.
     289     */
     290    @Test
     291    public void testFirstNode() {
     292        Way way = TestUtils.newWay("highway=residential", new Node(new LatLon(0, 0)), new Node(new LatLon(1, 1)));
     293        assertEquals(way.firstNode(), RoutingIslandsTest.firstNode(way, null));
     294        way.put("oneway", "yes");
     295        assertEquals(way.firstNode(), RoutingIslandsTest.firstNode(way, null));
     296        way.put("oneway", "-1");
     297        assertEquals(way.lastNode(), RoutingIslandsTest.firstNode(way, null));
     298
     299        way.put("vehicle:forward", "yes");
     300        assertEquals(way.firstNode(), RoutingIslandsTest.firstNode(way, "vehicle"));
     301        way.put("vehicle:backward", "no");
     302        assertEquals(way.firstNode(), RoutingIslandsTest.firstNode(way, "vehicle"));
     303        way.put("vehicle:forward", "no");
     304        assertEquals(way.firstNode(), RoutingIslandsTest.firstNode(way, "vehicle"));
     305        way.put("vehicle:backward", "yes");
     306        assertEquals(way.lastNode(), RoutingIslandsTest.firstNode(way, "vehicle"));
     307    }
     308
     309    /**
     310     * Test method for {@link RoutingIslandsTest#lastNode(Way, String)}.
     311     */
     312    @Test
     313    public void testLastNode() {
     314        Way way = TestUtils.newWay("highway=residential", new Node(new LatLon(0, 0)), new Node(new LatLon(1, 1)));
     315        assertEquals(way.lastNode(), RoutingIslandsTest.lastNode(way, null));
     316        way.put("oneway", "yes");
     317        assertEquals(way.lastNode(), RoutingIslandsTest.lastNode(way, null));
     318        way.put("oneway", "-1");
     319        assertEquals(way.firstNode(), RoutingIslandsTest.lastNode(way, null));
     320
     321        way.put("vehicle:forward", "yes");
     322        assertEquals(way.lastNode(), RoutingIslandsTest.lastNode(way, "vehicle"));
     323        way.put("vehicle:backward", "no");
     324        assertEquals(way.lastNode(), RoutingIslandsTest.lastNode(way, "vehicle"));
     325        way.put("vehicle:forward", "no");
     326        assertEquals(way.lastNode(), RoutingIslandsTest.lastNode(way, "vehicle"));
     327        way.put("vehicle:backward", "yes");
     328        assertEquals(way.firstNode(), RoutingIslandsTest.lastNode(way, "vehicle"));
     329    }
     330
     331    /**
     332     * Test with a way that by default does not give access to motor vehicles
     333     */
     334    @Test
     335    public void testNoAccessWay() {
     336        Way i70w = TestUtils.newWay("highway=motorway hgv=designated", new Node(new LatLon(39.1058104, -108.5258586)),
     337                new Node(new LatLon(39.1052235, -108.5293733)));
     338        Way i70e = TestUtils.newWay("highway=motorway hgv=designated", new Node(new LatLon(39.1049905, -108.5293074)),
     339                new Node(new LatLon(39.1055829, -108.5257975)));
     340        Way testPath = TestUtils.newWay("highway=footway", i70w.lastNode(true), i70e.firstNode(true));
     341        DataSet ds = new DataSet();
     342        Arrays.asList(i70w, i70e, testPath).forEach(way -> addToDataSet(ds, way));
     343
     344        RoutingIslandsTest test = new RoutingIslandsTest();
     345        test.startTest(null);
     346        test.visit(ds.allPrimitives());
     347        test.endTest();
     348    }
     349
     350    private static void addToDataSet(DataSet ds, OsmPrimitive primitive) {
     351        if (primitive instanceof Way) {
     352            ((Way) primitive).getNodes().parallelStream().distinct().filter(node -> node.getDataSet() == null)
     353                    .forEach(ds::addPrimitive);
     354        }
     355        if (primitive.getDataSet() == null) {
     356            ds.addPrimitive(primitive);
     357        }
     358        Long id = Math.max(ds.allPrimitives().parallelStream().mapToLong(prim -> prim.getId()).max().orElse(0L), 0L);
     359        for (OsmPrimitive osm : ds.allPrimitives().parallelStream().filter(prim -> prim.getUniqueId() < 0)
     360                .collect(Collectors.toList())) {
     361            id++;
     362            osm.setOsmId(id, 1);
     363        }
     364    }
     365}
  • test/unit/org/openstreetmap/josm/gui/download/OSMDownloadSourceTest.java

     
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.gui.download;
     3
     4import static org.junit.Assert.assertEquals;
     5import static org.openstreetmap.josm.tools.I18n.tr;
     6
     7import java.util.List;
     8
     9import javax.swing.JCheckBox;
     10import javax.swing.event.ChangeListener;
     11
     12import org.junit.Before;
     13import org.junit.BeforeClass;
     14import org.junit.Rule;
     15import org.junit.Test;
     16import org.junit.rules.ExpectedException;
     17import org.openstreetmap.josm.actions.downloadtasks.AbstractDownloadTask;
     18import org.openstreetmap.josm.actions.downloadtasks.DownloadNotesTask;
     19import org.openstreetmap.josm.data.Bounds;
     20import org.openstreetmap.josm.data.preferences.BooleanProperty;
     21import org.openstreetmap.josm.gui.download.OSMDownloadSource.DataDownloadType;
     22import org.openstreetmap.josm.gui.download.OSMDownloadSource.GpsDataDownloadType;
     23import org.openstreetmap.josm.gui.download.OSMDownloadSource.NotesDataDownloadType;
     24import org.openstreetmap.josm.gui.download.OSMDownloadSource.OsmDataDownloadType;
     25import org.openstreetmap.josm.spi.preferences.Config;
     26import org.openstreetmap.josm.testutils.JOSMTestRules;
     27
     28import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
     29
     30/**
     31 * Unit tests of {@link OSMDownloadSource} class.
     32 *
     33 * @author Taylor Smock
     34 *
     35 */
     36public class OSMDownloadSourceTest {
     37
     38    /**
     39     * Setup tests
     40     */
     41    @Rule
     42    @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
     43    public JOSMTestRules test = new JOSMTestRules().preferences();
     44
     45    /**
     46     * Account for tests that require an exception.
     47     */
     48    @Rule
     49    public final ExpectedException exception = ExpectedException.none();
     50
     51    DataDownloadType testType;
     52
     53    static List<DataDownloadType> defaultDownloadTypes;
     54
     55    /**
     56     * Set the initial download types
     57     */
     58    @BeforeClass
     59    public static void setUpBeforeClass() {
     60        defaultDownloadTypes = OSMDownloadSource.getDownloadTypes();
     61    }
     62
     63    /**
     64     * Set up some common variables
     65     */
     66    @Before
     67    public void setUp() {
     68        testType = new DataDownloadType() {
     69            private JCheckBox cbTestBox;
     70
     71            @Override
     72            public JCheckBox getCheckBox(ChangeListener checkboxChangeListener) {
     73                if (cbTestBox == null) {
     74                    cbTestBox = new JCheckBox(tr("Notes"));
     75                    cbTestBox.setToolTipText(tr("Select to download notes in the selected download area."));
     76                }
     77                if (checkboxChangeListener != null) {
     78                    cbTestBox.getModel().addChangeListener(checkboxChangeListener);
     79                }
     80
     81                return cbTestBox;
     82            }
     83
     84            @Override
     85            public Class<? extends AbstractDownloadTask<?>> getDownloadClass() {
     86                return DownloadNotesTask.class;
     87            }
     88
     89            @Override
     90            public BooleanProperty getBooleanProperty() {
     91                return new BooleanProperty("download.osm.notes-test", false);
     92            }
     93
     94            @Override
     95            public boolean isDownloadAreaTooLarge(Bounds bound) {
     96                return bound.getArea() > Config.getPref().getDouble("osm-server.max-request-area-notes", 25);
     97            }
     98        };
     99    }
     100
     101    /**
     102     * Test that we have the default download sources
     103     */
     104    @Test
     105    public void testGetDownloadSources() {
     106        List<DataDownloadType> list = OSMDownloadSource.getDownloadTypes();
     107        assertEquals(1, list.parallelStream().filter(OsmDataDownloadType.class::isInstance).count());
     108        assertEquals(1, list.parallelStream().filter(GpsDataDownloadType.class::isInstance).count());
     109        assertEquals(1, list.parallelStream().filter(NotesDataDownloadType.class::isInstance).count());
     110    }
     111
     112    /**
     113     * Ensure that the default download sources cannot be removed
     114     */
     115    @Test
     116    public void testCannotRemoveDefaults() {
     117        for (DataDownloadType type : defaultDownloadTypes) {
     118            OSMDownloadSource.removeDownloadType(type);
     119            testGetDownloadSources();
     120        }
     121
     122        // This has to be last in JUnit 4 (it stops the test)
     123        exception.expect(UnsupportedOperationException.class);
     124        defaultDownloadTypes.remove(0);
     125    }
     126
     127    /**
     128     * Ensure that the default download sources cannot be added
     129     */
     130    @Test
     131    public void testCannotAddDefaults() {
     132        for (DataDownloadType type : defaultDownloadTypes) {
     133            OSMDownloadSource.addDownloadType(type);
     134            testGetDownloadSources();
     135        }
     136    }
     137
     138    /**
     139     * Test adding/removing/using a new source
     140     */
     141    @Test
     142    public void testAddNewSource() {
     143        OSMDownloadSource.addDownloadType(testType);
     144        OSMDownloadSource.addDownloadType(testType);
     145        OSMDownloadSource.addDownloadType(testType);
     146        testGetDownloadSources();
     147        assertEquals(1, OSMDownloadSource.getDownloadTypes().parallelStream()
     148                .filter(type -> testType.getClass().isInstance(type)).count());
     149
     150        OSMDownloadSource.removeDownloadType(testType);
     151        assertEquals(0, OSMDownloadSource.getDownloadTypes().parallelStream()
     152                .filter(type -> testType.getClass().isInstance(type)).count());
     153        OSMDownloadSource.removeDownloadType(testType);
     154        testGetDownloadSources();
     155    }
     156}
  • test/unit/org/openstreetmap/josm/testutils/JOSMTestRules.java

     
    2323import java.util.logging.Handler;
    2424
    2525import org.awaitility.Awaitility;
     26import org.junit.jupiter.api.extension.AfterEachCallback;
     27import org.junit.jupiter.api.extension.BeforeEachCallback;
     28import org.junit.jupiter.api.extension.ExtensionContext;
    2629import org.junit.rules.TemporaryFolder;
    2730import org.junit.rules.TestRule;
    2831import org.junit.runner.Description;
     
    7982 *
    8083 * @author Michael Zangl
    8184 */
    82 public class JOSMTestRules implements TestRule {
     85public class JOSMTestRules implements TestRule, AfterEachCallback, BeforeEachCallback {
    8386    private int timeout = isDebugMode() ? -1 : 10 * 1000;
    8487    private TemporaryFolder josmHome;
    8588    private boolean usePreferences = false;
     
    433436        return statement;
    434437    }
    435438
     439    @Override
     440    public void beforeEach(ExtensionContext context) throws Exception {
     441        Statement temporaryStatement = new Statement() {
     442            @Override
     443            public void evaluate() throws Throwable {
     444                // do nothing
     445            }
     446        };
     447        try {
     448            this.apply(temporaryStatement,
     449                    Description.createTestDescription(this.getClass(), "JOSMTestRules JUnit5 Compatibility"))
     450                    .evaluate();
     451        } catch (Throwable e) {
     452            throw new Exception(e);
     453        }
     454    }
     455
     456    @Override
     457    public void afterEach(ExtensionContext context) throws Exception {
     458        // do nothing for now
     459    }
     460
    436461    /**
    437462     * Set up before running a test
    438463     * @throws InitializationError If an error occurred while creating the required environment.
  • test/unit/org/openstreetmap/josm/tools/AccessTest.java

     
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.tools;
     3
     4import static org.junit.Assert.assertEquals;
     5
     6import java.util.Map;
     7
     8import org.junit.Test;
     9
     10/**
     11 * Test class for {@link Access}
     12 *
     13 * @author Taylor Smock
     14 * @since xxx
     15 */
     16public class AccessTest {
     17
     18    /**
     19     * Test that access tags inherit the expected values
     20     */
     21    @Test
     22    public void testInheritance() {
     23        assertEquals(Access.AccessTags.YES.getKey(),
     24                Access.expandAccessMode(Access.AccessTags.VEHICLE.getKey(), Access.AccessTags.YES.getKey())
     25                        .getOrDefault(Access.AccessTags.MOTOR_VEHICLE.getKey(), Access.AccessTags.NO.getKey()));
     26        assertEquals(Access.AccessTags.YES.getKey(),
     27                Access.expandAccessMode(Access.AccessTags.VEHICLE.getKey(), Access.AccessTags.YES.getKey())
     28                        .getOrDefault(Access.AccessTags.HGV.getKey(), Access.AccessTags.NO.getKey()));
     29        assertEquals(Access.AccessTags.YES.getKey(),
     30                Access.expandAccessMode(Access.AccessTags.VEHICLE.getKey(), Access.AccessTags.YES.getKey())
     31                        .getOrDefault(Access.AccessTags.HGV_ARTICULATED.getKey(), Access.AccessTags.NO.getKey()));
     32    }
     33
     34    /**
     35     * Test that access maps get merged properly ({@link Access#mergeMaps})
     36     */
     37    @Test
     38    public void testMergeMaps() {
     39        Map<String, String> mergedMaps = Access.mergeMaps(
     40                Access.expandAccessMode(Access.AccessTags.VEHICLE.getKey(), Access.AccessTags.YES.getKey()),
     41                Access.expandAccessMode(Access.AccessTags.HGV.getKey(), Access.AccessTags.DESIGNATED.getKey()));
     42        assertEquals(Access.AccessTags.YES.getKey(),
     43                mergedMaps.getOrDefault(Access.AccessTags.MOTORCAR.getKey(), Access.AccessTags.NO.getKey()));
     44        assertEquals(Access.AccessTags.DESIGNATED.getKey(),
     45                mergedMaps.getOrDefault(Access.AccessTags.HGV.getKey(), Access.AccessTags.NO.getKey()));
     46        assertEquals(Access.AccessTags.DESIGNATED.getKey(),
     47                mergedMaps.getOrDefault(Access.AccessTags.HGV_ARTICULATED.getKey(), Access.AccessTags.NO.getKey()));
     48
     49        mergedMaps = Access.mergeMaps(
     50                Access.expandAccessMode(Access.AccessTags.HGV.getKey(), Access.AccessTags.DESIGNATED.getKey()),
     51                Access.expandAccessMode(Access.AccessTags.VEHICLE.getKey(), Access.AccessTags.YES.getKey()));
     52        assertEquals(Access.AccessTags.YES.getKey(),
     53                mergedMaps.getOrDefault(Access.AccessTags.MOTORCAR.getKey(), Access.AccessTags.NO.getKey()));
     54        assertEquals(Access.AccessTags.DESIGNATED.getKey(),
     55                mergedMaps.getOrDefault(Access.AccessTags.HGV.getKey(), Access.AccessTags.NO.getKey()));
     56        assertEquals(Access.AccessTags.DESIGNATED.getKey(),
     57                mergedMaps.getOrDefault(Access.AccessTags.HGV_ARTICULATED.getKey(), Access.AccessTags.NO.getKey()));
     58    }
     59}