Migrate to eclipse formatter to support multiple IDEs (#122)

pull/130/head
Michael Barry 2022-03-08 21:08:03 -05:00 zatwierdzone przez GitHub
rodzic bce75230f2
commit cce51668f2
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
119 zmienionych plików z 3330 dodań i 2518 usunięć

Wyświetl plik

@ -1,4 +1,5 @@
---
name: Bug report
about: Create a report to help improve Planetiler
title: "[BUG] "

Wyświetl plik

@ -1,4 +1,5 @@
---
name: Feature request
about: Suggest an idea for Planetiler
title: "[FEATURE] "

Wyświetl plik

@ -15,7 +15,8 @@ updates:
ignore:
- dependency-name: "com.graphhopper:graphhopper-reader-osm"
- package-ecosystem: maven
directory: "/planetiler-examples"
# workaround for https://github.com/dependabot/dependabot-core/issues/4425
directory: "/.github/planetiler-examples-dependabot"
open-pull-requests-limit: 1
schedule:
interval: daily

Wyświetl plik

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
This is just a workaround for https://github.com/dependabot/dependabot-core/issues/4425 so that
dependabot can update planetiler-examples/standalone.pom.xml without referring directly to a pom.xml with a
non-standard name.
-->
<project
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<modelVersion>4.0.0</modelVersion>
<groupId>com.onthegomap.planetiler</groupId>
<artifactId>planetiler-examples-parent-for-dependabot</artifactId>
<version>HEAD</version>
<packaging>pom</packaging>
<modules>
<module>../../planetiler-examples/pom.xml</module>
</modules>
</project>

Wyświetl plik

@ -34,10 +34,10 @@ jobs:
cache: 'maven'
- name: Build with mvnw (linux/mac)
if: ${{ !contains(matrix.os, 'windows') }}
run: ./mvnw ${{matrix.args}} --batch-mode -no-transfer-progress package jib:buildTar --file pom.xml
run: ./mvnw ${{matrix.args}} --batch-mode -no-transfer-progress package verify jib:buildTar --file pom.xml
- name: Build with mvnw.cmd (windows)
if: ${{ contains(matrix.os, 'windows') }}
run: mvnw.cmd ${{matrix.args}} --batch-mode -no-transfer-progress package jib:buildTar --file pom.xml
run: mvnw.cmd ${{matrix.args}} --batch-mode -no-transfer-progress package verify jib:buildTar --file pom.xml
shell: cmd
regenerate:
@ -54,7 +54,7 @@ jobs:
cache: 'maven'
- run: ./scripts/regenerate-openmaptiles.sh
- run: ./mvnw -DskipTests --batch-mode -no-transfer-progress clean install -pl planetiler-basemap -am
- run: ./mvnw --batch-mode -no-transfer-progress test -pl planetiler-basemap
- run: ./mvnw --batch-mode -no-transfer-progress verify -pl planetiler-basemap
examples:
name: Example project
@ -69,7 +69,7 @@ jobs:
java-version: 17
distribution: 'temurin'
- name: Build and test
run: mvn --batch-mode -no-transfer-progress package --file pom.xml
run: mvn --batch-mode -no-transfer-progress package --file standalone.pom.xml
working-directory: planetiler-examples
- name: Find jar
run: mv target/*with-deps.jar ./run.jar

8
.gitignore vendored
Wyświetl plik

@ -5,11 +5,19 @@ target/
!.mvn/wrapper/*.jar
*.log
# idea
*/.idea
.idea/*
*.iml
!.idea/codeStyles
!.idea/vcs.xml
!.idea/eclipseCodeFormatter.xml
# eclipse
.classpath
.project
.settings
bin/
TODO

Wyświetl plik

@ -265,6 +265,7 @@
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="XML">
<option name="RIGHT_MARGIN" value="120" />
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="2" />
@ -594,4 +595,4 @@
</indentOptions>
</codeStyleSettings>
</code_scheme>
</component>
</component>

Wyświetl plik

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="EclipseCodeFormatterProjectSettings">
<option name="projectSpecificProfile">
<ProjectSpecificProfile>
<option name="formatter" value="ECLIPSE" />
<option name="importOrder" value="#;" />
<option name="pathToConfigFileJava" value="$PROJECT_DIR$/eclipse-formatter.xml" />
<option name="selectedJavaProfile" value="Planetiler" />
</ProjectSpecificProfile>
</option>
</component>
</project>

5
.mvn/jvm.config 100644
Wyświetl plik

@ -0,0 +1,5 @@
--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED
--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED
--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED
--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED

11
.vscode/settings.json vendored 100644
Wyświetl plik

@ -0,0 +1,11 @@
{
"java.format.settings.url": "eclipse-formatter.xml",
"java.format.settings.profile": "Planetiler",
"java.completion.importOrder": [
"#",
""
],
"java.sources.organizeImports.staticStarThreshold": 5,
"java.sources.organizeImports.starThreshold": 999,
"java.saveActions.organizeImports": true
}

Wyświetl plik

@ -121,3 +121,4 @@ Finally, a single-threaded writer writes encoded vector tiles to the output MBTi
- Create the largest prepared statement supported by SQLite (999 parameters)
- Iterate through finished vector tile batches until the prepared statement is full, flush to disk, then repeat
- Then flush any remaining tiles at the end

Wyświetl plik

@ -1,6 +1,14 @@
# Contributing to Planetiler
Pull requests are welcome! To set up your development environment:
Pull requests are welcome! Any pull request should:
- Include at least one unit test to verify the change in behavior
- Include an end-to-end test
in [PlanetilerTests.java](planetiler-core/src/test/java/com/onthegomap/planetiler/PlanetilerTests.java)
to verify any major new user-facing features work
- Format the change `./mvnw spotless:apply` and test with `./mvnw verify` before pushing
To set up your local development environment:
- Fork the repo
- Install Java 16 or later. You can download Java manually from [Adoptium](https://adoptium.net/installation.html) or
@ -15,30 +23,57 @@ Pull requests are welcome! To set up your development environment:
- on windows: `mvnw.cmd clean test`
- or if you already have maven installed globally on your machine: `mvn clean test`
To edit the code:
GitHub Workflows will run regression tests on any pull request.
- [Install IntelliJ IDE](https://www.jetbrains.com/help/idea/installation-guide.html)
## IDE Setup
You can use any text editor as long as you format the code and test before pushing. A good IDE will make things a lot
easier though.
### IntelliJ IDEA (recommended)
- [Install IntelliJ IDEA](https://www.jetbrains.com/help/idea/installation-guide.html)
- Install
the [Adapter for Eclipse Code Formatter plugin](https://plugins.jetbrains.com/plugin/6546-adapter-for-eclipse-code-formatter)
- In IntelliJ, click `Open`, navigate to the the `pom.xml` file in the local copy of this repo, and `Open`
then `Open as Project`
- If IntelliJ asks (and you trust the code) then click `Trust Project`
- If any java source files show "Cannot resolve symbol..." errors for Planetiler classes, you might need to
select: `File -> Invalidate Caches... -> Just Restart`.
- If you see a "Project JDK is not defined" error, then choose `Setup SDK` and point IntelliJ at the Java 16 or later
installed on your system
- Recommended: Under `Preferences -> Tools -> Actions on Save` (or `File -> Settings -> Tools -> Actions on Save` on Linux) select `Reformat code` and `Optimize imports` to
automatically format code on save.
- Under `Preferences -> Tools -> Actions on Save` (or `File -> Settings -> Tools -> Actions on Save` on Linux)
select `Reformat code` and `Optimize imports` to automatically format code on save.
- To verify everything works correctly, right click on `planetiler-core/src/test/java` folder and
click `Run 'All Tests'`
Any pull request should:
Troubleshooting:
- Include at least one unit test to verify the change in behavior
- Include an end-to-end test
in [PlanetilerTests.java](planetiler-core/src/test/java/com/onthegomap/planetiler/PlanetilerTests.java)
to verify any major new user-facing features work
- Use IntelliJ's auto-formatting for modified files (this should get enabled automatically)
- Be free of IntelliJ warnings for modified files
- If any java source files show "Cannot resolve symbol..." errors for Planetiler classes, you might need to
select: `File -> Invalidate Caches... -> Just Restart`.
- If you see a "Project JDK is not defined" error, then choose `Setup SDK` and point IntelliJ at the Java 16 or later
installed on your system
GitHub Workflows will run regression tests on any pull request.
### Visual Studio Code
TODO: Set up checkstyle and an auto-formatter to enforce standards, so you can use any IDE.
- Install the [Extension Pack for Java](https://marketplace.visualstudio.com/items?itemName=vscjava.vscode-java-pack)
- In VSCode, click `File -> Open` and navigate to Planetiler directory
- If VSCode asks (and you trust the code) then click `Yes I trust the authors`
- To verify everything works correctly, go to the `Testing` tab and click `Run Tests`
Learn more about using VSCode with Java [here](https://code.visualstudio.com/docs/languages/java).
### Eclipse
- In [Eclipse for Java Developers](https://www.eclipse.org/downloads/packages/), click `File -> Import ...`
then `Maven -> Existing Maven Projects`, navigate to Planetiler directory, and click `Finish`
- Under `Eclipse -> Preferences...`:
- Under `Java -> Code Style -> Formatter` and choose `Import...`
choose [`eclipse-formatter.xml`](eclipse-formatter.xml) from the root of this project. Then choose `Planetiler` as
the Active profile.
- Under `Java -> Editor -> Save Actions` check `Perform selected actions on save`, `Format source code`
, `Format all lines` and `Organize imports`
- Under `Java -> Code Style -> Organize Imports` change the `number of static imports needed for .*` to 5, then remove
the groups and add 2 new groups:
- `New Static...` and `*`
- `New...` and `*`
- To verify everything works correctly, right click on `planetiler-core/src/test/java` folder and
click `Run As -> JUnit Test`
TODO: Set up checkstyle

Wyświetl plik

@ -50,10 +50,11 @@ Additionally, the `planetiler-basemap` module is based on [OpenMapTiles](https:/
## Data
| source | license | used as default | included in repo |
| source | license | used as default | included in repo |
|----------------------------|--------------------------------------------------------------------------------------------------------------------------------------|-----------------|------------------|
| OpenStreetMap (OSM) data | [ODBL](https://www.openstreetmap.org/copyright) | yes | yes |
| Natural Earth | [public domain](https://www.naturalearthdata.com/about/terms-of-use/) | yes | yes |
| OSM Lakelines | [MIT](https://github.com/lukasmartinelli/osm-lakelines), data from OSM [ODBL](https://www.openstreetmap.org/copyright) | yes | no |
| OSM Water Polygons | [acknowledgement](https://osmdata.openstreetmap.de/info/license.html), data from OSM [ODBL](https://www.openstreetmap.org/copyright) | yes | yes |
| Wikidata name translations | [CCO](https://www.wikidata.org/wiki/Wikidata:Licensing) | no | no |

Wyświetl plik

@ -15,10 +15,12 @@ First decide where to get the `planet.osm.pbf` file:
- Or a [Daylight Distribution](https://daylightmap.org/) snapshot from Facebook that includes extra quality/consistency
checks, and add-ons like ML-detected roads and buildings. Combine add-ons and re-number
using [osmium-tool](https://osmcode.org/osmium-tool/):
```bash
osmium apply-changes daylight.osm.pbf admin.osc.bz2 <buildings.osc.bz2, ...> -o everything.osm.pbf
osmium renumber everything.osm.pbf -o planet.osm.pbf
```
NOTE: you need at least `admin.osc.bz2` for the `boundary` layer to show. This takes about 2.5 hours and needs as much
RAM as the `planet.osm.pbf` size.

Wyświetl plik

@ -118,7 +118,7 @@ See the [planetiler-examples](planetiler-examples) project.
Some example runtimes (excluding downloading resources):
| Input | Profile | Machine | Time | mbtiles size | Logs |
| Input | Profile | Machine | Time | mbtiles size | Logs |
|-------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------|----------------------------------------------------------|---------------------------|--------------|--------------------------------------------------------------------------------------------------------------------------------|
| s3://osm-pds/2021/planet-211011.osm.pbf (65GB) | Basemap | DO 16cpu 128GB | 3h9m cpu:42h1m avg:13.3 | 99GB | [logs](planet-logs/v0.1.0-planet-do-16cpu-128gb.txt), [VisualVM Profile](planet-logs/v0.1.0-planet-do-16cpu-128gb.nps) |
| [Daylight Distribution v1.6](https://daylightmap.org/2021/09/29/daylight-v16-released.html) with ML buildings and admin boundaries (67GB) | Basemap | DO 16cpu 128GB | 3h13m cpu:43h40m avg:13.5 | 101GB | [logs](planet-logs/v0.1.0-daylight-do-16cpu-128gb.txt) |

Wyświetl plik

@ -0,0 +1,480 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<profiles version="21">
<profile kind="CodeFormatterProfile" name="Planetiler" version="21">
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration"
value="preserve_positions"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.align_with_spaces" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_before_code_block" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_switch_case_expressions"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="20"/>
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
<setting id="org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_record_components" value="20"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="20"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_logical_operator" value="20"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_annotation_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_record_declaration"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments"
value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_abstract_method" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.keep_enum_constant_declaration_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.align_variable_declarations_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="20"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="20"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator" value="20"/>
<setting id="org.eclipse.jdt.core.formatter.keep_anonymous_type_declaration_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_switch_case_expressions" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_shift_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header"
value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_code_block" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="20"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_parameters" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_loops" value="20"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_for_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation" value="preserve_positions"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_enum_constant" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.text_block_indentation" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="20"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_module_statements" value="20"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_names_descriptions" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_if_then_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression_chain" value="20"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_annotations" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="20"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assertion_message_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines" value="2147483647"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator" value="20"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="84"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="20"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="20"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_not_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration"
value="preserve_positions"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="20"/>
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_arguments" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="20"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_package" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header"
value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_record_header" value="true"/>
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_tag_description" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_record_constructor" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_string_concatenation" value="20"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_shift_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_shift_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_do_while_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_record_components" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_additive_operator" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_getter_setter_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_record_declaration"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_relational_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_logical_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation" value="preserve_positions"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_record_declaration"
value="preserve_positions"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_default" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="17"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="-1"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_method_body" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_descriptions_grouped" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="120"/>
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_method_body_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_loop_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_type_declaration_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_additive_operator" value="20"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_constructor"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_relational_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_record_declaration_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_lambda_body" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="20"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="20"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_parameter" value="48"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_relational_operator" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="20"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_additive_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_record_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_after_code_block" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="20"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="20"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_type" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_local_variable" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_default" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_between_different_tags" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_additive_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_field" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_conditional_operator" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_shift_operator" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause" value="separate_lines_if_wrapped"/>
<setting id="org.eclipse.jdt.core.formatter.keep_code_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_record_components" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_record_declaration"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="20"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assignment_operator" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_lambda_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_method" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_record_constructor_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_declaration"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assertion_message" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration"
value="do not insert"/>
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_logical_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="20"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_record_declaration" value="20"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_relational_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="20"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_last_class_body_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_while_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_logical_operator" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_statement_group_in_switch" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration"
value="preserve_positions"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_enum_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_code_block" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_string_concatenation" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="120"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
</profile>
</profiles>

Wyświetl plik

@ -27,15 +27,15 @@ import java.util.List;
* <p>
* Layer implementations extend these interfaces to subscribe to elements from different sources:
* <ul>
* <li>{@link LakeCenterlineProcessor}</li>
* <li>{@link NaturalEarthProcessor}</li>
* <li>{@link OsmWaterPolygonProcessor}</li>
* <li>{@link OsmAllProcessor} to process every OSM feature</li>
* <li>{@link OsmRelationPreprocessor} to process every OSM relation during first pass through OSM file</li>
* <li>A {@link Tables.RowHandler} implementation in {@code Tables.java} to process input features filtered and parsed
* according to the imposm3 mappings defined in the OpenMapTiles schema. Each element corresponds to a row in the
* table that imposm3 would have generated, with generated methods for accessing the data that would have been in each
* column</li>
* <li>{@link LakeCenterlineProcessor}</li>
* <li>{@link NaturalEarthProcessor}</li>
* <li>{@link OsmWaterPolygonProcessor}</li>
* <li>{@link OsmAllProcessor} to process every OSM feature</li>
* <li>{@link OsmRelationPreprocessor} to process every OSM relation during first pass through OSM file</li>
* <li>A {@link Tables.RowHandler} implementation in {@code Tables.java} to process input features filtered and parsed
* according to the imposm3 mappings defined in the OpenMapTiles schema. Each element corresponds to a row in the table
* that imposm3 would have generated, with generated methods for accessing the data that would have been in each
* column</li>
* </ul>
* Layers can also subscribe to notifications when we finished processing an input source by implementing
* {@link FinishHandler} or post-process features in that layer before rendering the output tile by implementing
@ -118,9 +118,8 @@ public class BasemapProfile extends ForwardingProfile {
return new RowDispatch(constructor.create(), handlers);
}).simplify().index();
wikidataMappings = Tables.MAPPINGS
.mapResults(constructor ->
handlerMap.getOrDefault(constructor.rowClass(), List.of()).stream()
.anyMatch(handler -> !IgnoreWikidata.class.isAssignableFrom(handler.handlerClass()))
.mapResults(constructor -> handlerMap.getOrDefault(constructor.rowClass(), List.of()).stream()
.anyMatch(handler -> !IgnoreWikidata.class.isAssignableFrom(handler.handlerClass()))
).filterResults(b -> b).simplify().index();
// register a handler for all OSM elements that forwards to imposm3 "table row" handler methods
@ -149,8 +148,8 @@ public class BasemapProfile extends ForwardingProfile {
if (elem instanceof OsmElement.Node) {
return wikidataMappings.getOrElse(SimpleFeature.create(EMPTY_POINT, tags), false);
} else if (elem instanceof OsmElement.Way) {
return wikidataMappings.getOrElse(SimpleFeature.create(EMPTY_POLYGON, tags), false)
|| wikidataMappings.getOrElse(SimpleFeature.create(EMPTY_LINE, tags), false);
return wikidataMappings.getOrElse(SimpleFeature.create(EMPTY_POLYGON, tags), false) ||
wikidataMappings.getOrElse(SimpleFeature.create(EMPTY_LINE, tags), false);
} else if (elem instanceof OsmElement.Relation) {
return wikidataMappings.getOrElse(SimpleFeature.create(EMPTY_POLYGON, tags), false);
} else {
@ -201,14 +200,13 @@ public class BasemapProfile extends ForwardingProfile {
}
/**
* Layers should implement this interface to subscribe to elements from <a href="https://www.naturalearthdata.com/">natural
* earth</a>.
* Layers should implement this interface to subscribe to elements from
* <a href="https://www.naturalearthdata.com/">natural earth</a>.
*/
public interface NaturalEarthProcessor {
/**
* Process an element from {@code table} in the<a href="https://www.naturalearthdata.com/">natural earth
* source</a>.
* Process an element from {@code table} in the<a href="https://www.naturalearthdata.com/">natural earth source</a>.
*
* @see Profile#processFeature(SourceFeature, FeatureCollector)
*/
@ -216,8 +214,8 @@ public class BasemapProfile extends ForwardingProfile {
}
/**
* Layers should implement this interface to subscribe to elements from <a href="https://github.com/lukasmartinelli/osm-lakelines">OSM
* lake centerlines source</a>.
* Layers should implement this interface to subscribe to elements from
* <a href="https://github.com/lukasmartinelli/osm-lakelines">OSM lake centerlines source</a>.
*/
public interface LakeCenterlineProcessor {
@ -231,8 +229,8 @@ public class BasemapProfile extends ForwardingProfile {
}
/**
* Layers should implement this interface to subscribe to elements from <a href="https://osmdata.openstreetmap.de/data/water-polygons.html">OSM
* water polygons source</a>.
* Layers should implement this interface to subscribe to elements from
* <a href="https://osmdata.openstreetmap.de/data/water-polygons.html">OSM water polygons source</a>.
*/
public interface OsmWaterPolygonProcessor {

Wyświetl plik

@ -38,14 +38,14 @@ import org.yaml.snakeyaml.LoaderOptions;
import org.yaml.snakeyaml.Yaml;
/**
* Generates code in the {@code generated} package from the OpenMapTiles schema crawled from a tag or branch in the <a
* href="https://github.com/openmaptiles/openmaptiles">OpenMapTiles GitHub repo</a>.
* Generates code in the {@code generated} package from the OpenMapTiles schema crawled from a tag or branch in the
* <a href="https://github.com/openmaptiles/openmaptiles">OpenMapTiles GitHub repo</a>.
* <p>
* {@code OpenMapTilesSchema.java} contains the output layer definitions (i.e. attributes and allowed values) so that
* layer implementations in {@code layers} package can reference them instead of hard-coding.
* <p>
* {@code Tables.java} contains the <a href="https://github.com/omniscale/imposm3">imposm3</a> table definitions from
* mapping.yaml files in the OpenMapTiles repo. Layers in the {@code layer} package can extend the {@code Handler}
* mapping.yaml files in the OpenMapTiles repo. Layers in the {@code layer} package can extend the {@code Handler}
* nested class for a table definition to "subscribe" to OSM elements that imposm3 would put in that table.
* <p>
* To run use {@code ./scripts/regenerate-openmaptiles.sh}
@ -169,8 +169,7 @@ public class Generate {
emitLayerSchemaDefinitions(config.tileset, layers, packageName, output, tag);
emitTableDefinitions(tables, packageName, output, tag);
LOGGER.info(
"Done generating code in 'generated' package, now run IntelliJ 'Reformat Code' operation with 'Optimize imports' and 'Cleanup code' options selected.");
LOGGER.info("Done!");
}
/** Generates {@code OpenMapTilesSchema.java} */
@ -178,56 +177,57 @@ public class Generate {
Path output, String tag)
throws IOException {
StringBuilder schemaClass = new StringBuilder();
schemaClass.append("""
%s
package %s;
import static com.onthegomap.planetiler.expression.Expression.*;
import com.onthegomap.planetiler.config.PlanetilerConfig;
import com.onthegomap.planetiler.stats.Stats;
import com.onthegomap.planetiler.expression.MultiExpression;
import com.onthegomap.planetiler.basemap.Layer;
import com.onthegomap.planetiler.util.Translations;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* All vector tile layer definitions, attributes, and allowed values generated from the
* <a href="https://github.com/openmaptiles/openmaptiles/blob/%s/openmaptiles.yaml">OpenMapTiles vector tile schema %s</a>.
*/
@SuppressWarnings("unused")
public class OpenMapTilesSchema {
public static final String NAME = %s;
public static final String DESCRIPTION = %s;
public static final String VERSION = %s;
public static final String ATTRIBUTION = %s;
public static final List<String> LANGUAGES = List.of(%s);
/** Returns a list of expected layer implementation instances from the {@code layers} package. */
public static List<Layer> createInstances(Translations translations, PlanetilerConfig config, Stats stats) {
return List.of(
%s
);
}
schemaClass.append(
"""
.formatted(
GENERATED_FILE_HEADER,
packageName,
escapeJavadoc(tag),
escapeJavadoc(tag),
Format.quote(info.name),
Format.quote(info.description),
Format.quote(info.version),
Format.quote(info.attribution),
info.languages.stream().map(Format::quote).collect(joining(", ")),
layers.stream()
.map(
l -> "new com.onthegomap.planetiler.basemap.layers.%s(translations, config, stats)"
.formatted(lowerUnderscoreToUpperCamel(l.layer.id)))
.collect(joining("," + LINE_SEPARATOR))
.indent(6).trim()
));
%s
package %s;
import static com.onthegomap.planetiler.expression.Expression.*;
import com.onthegomap.planetiler.config.PlanetilerConfig;
import com.onthegomap.planetiler.stats.Stats;
import com.onthegomap.planetiler.expression.MultiExpression;
import com.onthegomap.planetiler.basemap.Layer;
import com.onthegomap.planetiler.util.Translations;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* All vector tile layer definitions, attributes, and allowed values generated from the
* <a href="https://github.com/openmaptiles/openmaptiles/blob/%s/openmaptiles.yaml">OpenMapTiles vector tile schema %s</a>.
*/
@SuppressWarnings("unused")
public class OpenMapTilesSchema {
public static final String NAME = %s;
public static final String DESCRIPTION = %s;
public static final String VERSION = %s;
public static final String ATTRIBUTION = %s;
public static final List<String> LANGUAGES = List.of(%s);
/** Returns a list of expected layer implementation instances from the {@code layers} package. */
public static List<Layer> createInstances(Translations translations, PlanetilerConfig config, Stats stats) {
return List.of(
%s
);
}
"""
.formatted(
GENERATED_FILE_HEADER,
packageName,
escapeJavadoc(tag),
escapeJavadoc(tag),
Format.quote(info.name),
Format.quote(info.description),
Format.quote(info.version),
Format.quote(info.attribution),
info.languages.stream().map(Format::quote).collect(joining(", ")),
layers.stream()
.map(
l -> "new com.onthegomap.planetiler.basemap.layers.%s(translations, config, stats)"
.formatted(lowerUnderscoreToUpperCamel(l.layer.id)))
.collect(joining("," + LINE_SEPARATOR))
.indent(6).trim()
));
for (var layer : layers) {
String layerCode = generateCodeForLayer(tag, layer);
schemaClass.append(layerCode);
@ -344,68 +344,70 @@ public class Generate {
String tag)
throws IOException {
StringBuilder tablesClass = new StringBuilder();
tablesClass.append("""
%s
package %s;
tablesClass.append(
"""
%s
package %s;
import static com.onthegomap.planetiler.expression.Expression.*;
import static com.onthegomap.planetiler.expression.Expression.*;
import com.onthegomap.planetiler.expression.Expression;
import com.onthegomap.planetiler.expression.MultiExpression;
import com.onthegomap.planetiler.FeatureCollector;
import com.onthegomap.planetiler.reader.SourceFeature;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.onthegomap.planetiler.expression.Expression;
import com.onthegomap.planetiler.expression.MultiExpression;
import com.onthegomap.planetiler.FeatureCollector;
import com.onthegomap.planetiler.reader.SourceFeature;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* OSM element parsers generated from the <a href="https://github.com/omniscale/imposm3">imposm3</a> table definitions
* in the <a href="https://github.com/openmaptiles/openmaptiles/blob/%s/openmaptiles.yaml">OpenMapTiles vector tile schema</a>.
*
* These filter and parse the raw OSM key/value attribute pairs on tags into records with fields that match the
* columns in the tables that imposm3 would generate. Layer implementations can "subscribe" to elements from each
* "table" but implementing the table's {@code Handler} interface and use the element's typed API to access
* attributes.
*/
@SuppressWarnings("unused")
public class Tables {
/** A parsed OSM element that would appear in a "row" of the imposm3 table. */
public interface Row {
/**
* OSM element parsers generated from the <a href="https://github.com/omniscale/imposm3">imposm3</a> table definitions
* in the <a href="https://github.com/openmaptiles/openmaptiles/blob/%s/openmaptiles.yaml">OpenMapTiles vector tile schema</a>.
*
* These filter and parse the raw OSM key/value attribute pairs on tags into records with fields that match the
* columns in the tables that imposm3 would generate. Layer implementations can "subscribe" to elements from each
* "table" but implementing the table's {@code Handler} interface and use the element's typed API to access
* attributes.
*/
@SuppressWarnings("unused")
public class Tables {
/** A parsed OSM element that would appear in a "row" of the imposm3 table. */
public interface Row {
/** Returns the original OSM element. */
SourceFeature source();
}
/** Returns the original OSM element. */
SourceFeature source();
}
/** A functional interface that the constructor of a new table row can be coerced to. */
@FunctionalInterface
public interface Constructor {
/** A functional interface that the constructor of a new table row can be coerced to. */
@FunctionalInterface
public interface Constructor {
Row create(SourceFeature source, String mappingKey);
}
Row create(SourceFeature source, String mappingKey);
}
/** The {@code rowClass} of an imposm3 table row and its constructor coerced to a {@link Constructor}. */
public record RowClassAndConstructor(
Class<? extends Row> rowClass,
Constructor create
) {}
/** The {@code rowClass} of an imposm3 table row and its constructor coerced to a {@link Constructor}. */
public record RowClassAndConstructor(
Class<? extends Row> rowClass,
Constructor create
) {}
/** A functional interface that the typed handler method that a layer implementation can be coerced to. */
@FunctionalInterface
public interface RowHandler<T extends Row> {
/** A functional interface that the typed handler method that a layer implementation can be coerced to. */
@FunctionalInterface
public interface RowHandler<T extends Row> {
/** Process a typed element according to the profile. */
void process(T element, FeatureCollector features);
}
/** Process a typed element according to the profile. */
void process(T element, FeatureCollector features);
}
/** The {@code handlerClass} of a layer handler and it's {@code process} method coerced to a {@link RowHandler}. */
public record RowHandlerAndClass<T extends Row>(
Class<?> handlerClass,
RowHandler<T> handler
) {}
""".formatted(GENERATED_FILE_HEADER, packageName, escapeJavadoc(tag)));
/** The {@code handlerClass} of a layer handler and it's {@code process} method coerced to a {@link RowHandler}. */
public record RowHandlerAndClass<T extends Row>(
Class<?> handlerClass,
RowHandler<T> handler
) {}
"""
.formatted(GENERATED_FILE_HEADER, packageName, escapeJavadoc(tag)));
List<String> classNames = new ArrayList<>();
Map<String, String> fieldNameToType = new TreeMap<>();
@ -489,17 +491,19 @@ public class Generate {
));
""".formatted(
classNames.stream().map(
className -> "MultiExpression.entry(new RowClassAndConstructor(%s.class, %s::new), %s.MAPPING)".formatted(
className, className, className))
className -> "MultiExpression.entry(new RowClassAndConstructor(%s.class, %s::new), %s.MAPPING)".formatted(
className, className, className))
.collect(joining("," + LINE_SEPARATOR)).indent(2).strip()
).indent(2));
String handlerCondition = classNames.stream().map(className ->
"""
if (handler instanceof %s.Handler typedHandler) {
result.computeIfAbsent(%s.class, cls -> new ArrayList<>()).add(new RowHandlerAndClass<>(typedHandler.getClass(), typedHandler::process));
}""".formatted(className, className)
).collect(joining(LINE_SEPARATOR));
String handlerCondition = classNames.stream()
.map(
className -> """
if (handler instanceof %s.Handler typedHandler) {
result.computeIfAbsent(%s.class, cls -> new ArrayList<>()).add(new RowHandlerAndClass<>(typedHandler.getClass(), typedHandler::process));
}"""
.formatted(className, className)
).collect(joining(LINE_SEPARATOR));
tablesClass.append("""
/**
* Returns a map from imposm3 "table row" class to the layers that have a handler for it from a list of layer
@ -518,15 +522,15 @@ public class Generate {
}
/**
* Returns an {@link Expression} that implements the same logic as the <a href="https://imposm.org/docs/imposm3/latest/mapping.html">Imposm3
* Data Mapping</a> definition for a table.
* Returns an {@link Expression} that implements the same logic as the
* <a href="https://imposm.org/docs/imposm3/latest/mapping.html">Imposm3 Data Mapping</a> definition for a table.
*/
static Expression parseImposm3MappingExpression(Imposm3Table table) {
if (table.type_mappings != null) {
return or(
table.type_mappings.entrySet().stream().map(entry ->
parseImposm3MappingExpression(entry.getKey(), entry.getValue(), table.filters)
).toList()
table.type_mappings.entrySet().stream()
.map(entry -> parseImposm3MappingExpression(entry.getKey(), entry.getValue(), table.filters)
).toList()
).simplify();
} else {
return parseImposm3MappingExpression(table.type, table.mapping, table.filters);
@ -534,8 +538,8 @@ public class Generate {
}
/**
* Returns an {@link Expression} that implements the same logic as the <a href="https://imposm.org/docs/imposm3/latest/mapping.html#filters">Imposm3
* Data Mapping filters</a> for a table.
* Returns an {@link Expression} that implements the same logic as the
* <a href="https://imposm.org/docs/imposm3/latest/mapping.html#filters">Imposm3 Data Mapping filters</a> for a table.
*/
static Expression parseImposm3MappingExpression(String type, JsonNode mapping, Imposm3Filters filters) {
return and(

Wyświetl plik

@ -51,7 +51,8 @@ import com.onthegomap.planetiler.util.Translations;
/**
* Defines the logic for generating map elements in the {@code aerodrome_label} layer from source features.
* <p>
* This class is ported to Java from <a href="https://github.com/openmaptiles/openmaptiles/tree/master/layers/aerodrome_label">OpenMapTiles
* This class is ported to Java from
* <a href="https://github.com/openmaptiles/openmaptiles/tree/master/layers/aerodrome_label">OpenMapTiles
* aerodrome_layer sql files</a>.
*/
public class AerodromeLabel implements

Wyświetl plik

@ -45,8 +45,8 @@ import com.onthegomap.planetiler.util.Translations;
/**
* Defines the logic for generating map elements in the {@code aeroway} layer from source features.
* <p>
* This class is ported to Java from <a href="https://github.com/openmaptiles/openmaptiles/tree/master/layers/aeroway">OpenMapTiles
* aeroway sql files</a>.
* This class is ported to Java from
* <a href="https://github.com/openmaptiles/openmaptiles/tree/master/layers/aeroway">OpenMapTiles aeroway sql files</a>.
*/
public class Aeroway implements
OpenMapTilesSchema.Aeroway,
@ -54,8 +54,7 @@ public class Aeroway implements
Tables.OsmAerowayPolygon.Handler,
Tables.OsmAerowayPoint.Handler {
public Aeroway(Translations translations, PlanetilerConfig config, Stats stats) {
}
public Aeroway(Translations translations, PlanetilerConfig config, Stats stats) {}
@Override
public void process(Tables.OsmAerowayPolygon element, FeatureCollector features) {

Wyświetl plik

@ -86,8 +86,9 @@ import org.slf4j.LoggerFactory;
* Defines the logic for generating map elements for country, state, and town boundaries in the {@code boundary} layer
* from source features.
* <p>
* This class is ported to Java from <a href="https://github.com/openmaptiles/openmaptiles/tree/master/layers/boundary">OpenMapTiles
* boundary sql files</a>.
* This class is ported to Java from
* <a href="https://github.com/openmaptiles/openmaptiles/tree/master/layers/boundary">OpenMapTiles boundary sql
* files</a>.
*/
public class Boundary implements
OpenMapTilesSchema.Boundary,
@ -164,13 +165,13 @@ public class Boundary implements
BoundaryInfo info = switch (table) {
case "ne_110m_admin_0_boundary_lines_land" -> new BoundaryInfo(2, 0, 0);
case "ne_50m_admin_0_boundary_lines_land" -> new BoundaryInfo(2, 1, 3);
case "ne_10m_admin_0_boundary_lines_land" -> feature.hasTag("featurecla", "Lease Limit") ? null
: new BoundaryInfo(2, 4, 4);
case "ne_10m_admin_0_boundary_lines_land" -> feature.hasTag("featurecla", "Lease Limit") ? null :
new BoundaryInfo(2, 4, 4);
case "ne_10m_admin_1_states_provinces_lines" -> {
Double minZoom = Parse.parseDoubleOrNull(feature.getTag("min_zoom"));
yield minZoom != null && minZoom <= 7 ? new BoundaryInfo(4, 1, 4) :
minZoom != null && minZoom <= 7.7 ? new BoundaryInfo(4, 4, 4) :
null;
null;
}
default -> null;
};
@ -250,8 +251,8 @@ public class Boundary implements
int minzoom =
(maritime && minAdminLevel == 2) ? 4 :
minAdminLevel <= 4 ? 5 :
minAdminLevel <= 6 ? 9 :
minAdminLevel <= 8 ? 11 : 12;
minAdminLevel <= 6 ? 9 :
minAdminLevel <= 8 ? 11 : 12;
if (addCountryNames && !regionIds.isEmpty()) {
// save for later
try {
@ -398,8 +399,7 @@ public class Boundary implements
try {
Geometry combined = polygonizer.getGeometry().union();
if (combined.isEmpty()) {
LOGGER.warn("Unable to form closed polygon for OSM relation " + regionId
+ " (likely missing edges)");
LOGGER.warn("Unable to form closed polygon for OSM relation " + regionId + " (likely missing edges)");
} else {
countryBoundaries.put(regionId, PreparedGeometryFactory.prepare(combined));
}
@ -429,8 +429,7 @@ public class Boundary implements
}
/**
* Minimal set of information extracted from a boundary relation to be used when processing each way in that
* relation.
* Minimal set of information extracted from a boundary relation to be used when processing each way in that relation.
*/
private record BoundaryRelation(
long id,
@ -443,17 +442,15 @@ public class Boundary implements
@Override
public long estimateMemoryUsageBytes() {
return CLASS_HEADER_BYTES
+ MemoryEstimator.estimateSizeLong(id)
+ MemoryEstimator.estimateSizeInt(adminLevel)
+ estimateSize(disputed)
+ POINTER_BYTES + estimateSize(name)
+ POINTER_BYTES + estimateSize(claimedBy)
+ POINTER_BYTES + estimateSize(iso3166alpha3);
return CLASS_HEADER_BYTES + MemoryEstimator.estimateSizeLong(id) + MemoryEstimator.estimateSizeInt(adminLevel) +
estimateSize(disputed) + POINTER_BYTES + estimateSize(name) + POINTER_BYTES + estimateSize(claimedBy) +
POINTER_BYTES + estimateSize(iso3166alpha3);
}
}
/** Information to hold onto from processing a way in a boundary relation to determine the left/right region ID later. */
/**
* Information to hold onto from processing a way in a boundary relation to determine the left/right region ID later.
*/
private record CountryBoundaryComponent(
int adminLevel,
boolean disputed,

Wyświetl plik

@ -60,8 +60,9 @@ import java.util.Map;
/**
* Defines the logic for generating map elements for buildings in the {@code building} layer from source features.
* <p>
* This class is ported to Java from <a href="https://github.com/openmaptiles/openmaptiles/tree/master/layers/building">OpenMapTiles
* building sql files</a>.
* This class is ported to Java from
* <a href="https://github.com/openmaptiles/openmaptiles/tree/master/layers/building">OpenMapTiles building sql
* files</a>.
*/
public class Building implements
OpenMapTilesSchema.Building,
@ -154,10 +155,8 @@ public class Building implements
parseDoubleOrNull(element.buildingminLevel())
);
int renderHeight = (int) Math.ceil(height != null ? height
: levels != null ? (levels * 3.66) : 5);
int renderMinHeight = (int) Math.floor(minHeight != null ? minHeight
: minLevels != null ? (minLevels * 3.66) : 0);
int renderHeight = (int) Math.ceil(height != null ? height : levels != null ? (levels * 3.66) : 5);
int renderMinHeight = (int) Math.floor(minHeight != null ? minHeight : minLevels != null ? (minLevels * 3.66) : 0);
if (renderHeight < 3660 && renderMinHeight < 3660) {
var feature = features.polygon(LAYER_NAME).setBufferPixels(BUFFER_SIZE)

Wyświetl plik

@ -45,15 +45,15 @@ import com.onthegomap.planetiler.util.Translations;
/**
* Defines the logic for generating map elements in the {@code housenumber} layer from source features.
* <p>
* This class is ported to Java from <a href="https://github.com/openmaptiles/openmaptiles/tree/master/layers/housenumber">OpenMapTiles
* housenumber sql files</a>.
* This class is ported to Java from
* <a href="https://github.com/openmaptiles/openmaptiles/tree/master/layers/housenumber">OpenMapTiles housenumber sql
* files</a>.
*/
public class Housenumber implements
OpenMapTilesSchema.Housenumber,
Tables.OsmHousenumberPoint.Handler {
public Housenumber(Translations translations, PlanetilerConfig config, Stats stats) {
}
public Housenumber(Translations translations, PlanetilerConfig config, Stats stats) {}
@Override
public void process(Tables.OsmHousenumberPoint element, FeatureCollector features) {

Wyświetl plik

@ -57,8 +57,9 @@ import java.util.Set;
* Defines the logic for generating map elements for natural land cover polygons like ice, sand, and forest in the
* {@code landcover} layer from source features.
* <p>
* This class is ported to Java from <a href="https://github.com/openmaptiles/openmaptiles/tree/master/layers/landcover">OpenMapTiles
* landcover sql files</a>.
* This class is ported to Java from
* <a href="https://github.com/openmaptiles/openmaptiles/tree/master/layers/landcover">OpenMapTiles landcover sql
* files</a>.
*/
public class Landcover implements
OpenMapTilesSchema.Landcover,

Wyświetl plik

@ -55,8 +55,8 @@ import java.util.Set;
* Defines the logic for generating map elements for man-made land use polygons like cemeteries, zoos, and hospitals in
* the {@code landuse} layer from source features.
* <p>
* This class is ported to Java from <a href="https://github.com/openmaptiles/openmaptiles/tree/master/layers/landuse">OpenMapTiles
* landuse sql files</a>.
* This class is ported to Java from
* <a href="https://github.com/openmaptiles/openmaptiles/tree/master/layers/landuse">OpenMapTiles landuse sql files</a>.
*/
public class Landuse implements
OpenMapTilesSchema.Landuse,
@ -75,8 +75,7 @@ public class Landuse implements
FieldValues.CLASS_NEIGHBOURHOOD
);
public Landuse(Translations translations, PlanetilerConfig config, Stats stats) {
}
public Landuse(Translations translations, PlanetilerConfig config, Stats stats) {}
@Override
public void processNaturalEarth(String table, SourceFeature feature, FeatureCollector features) {

Wyświetl plik

@ -65,8 +65,9 @@ import org.slf4j.LoggerFactory;
* Defines the logic for generating map elements for mountain peak label points in the {@code mountain_peak} layer from
* source features.
* <p>
* This class is ported to Java from <a href="https://github.com/openmaptiles/openmaptiles/tree/master/layers/mountain_peak">OpenMapTiles
* mountain_peak sql files</a>.
* This class is ported to Java from
* <a href="https://github.com/openmaptiles/openmaptiles/tree/master/layers/mountain_peak">OpenMapTiles mountain_peak
* sql files</a>.
*/
public class MountainPeak implements
BasemapProfile.NaturalEarthProcessor,

Wyświetl plik

@ -62,8 +62,8 @@ import java.util.Locale;
* Defines the logic for generating map elements for designated parks polygons and their label points in the {@code
* park} layer from source features.
* <p>
* This class is ported to Java from <a href="https://github.com/openmaptiles/openmaptiles/tree/master/layers/park">OpenMapTiles
* park sql files</a>.
* This class is ported to Java from
* <a href="https://github.com/openmaptiles/openmaptiles/tree/master/layers/park">OpenMapTiles park sql files</a>.
*/
public class Park implements
OpenMapTilesSchema.Park,

Wyświetl plik

@ -76,8 +76,8 @@ import org.locationtech.jts.geom.Point;
* Defines the logic for generating label points for populated places like continents, countries, cities, and towns in
* the {@code place} layer from source features.
* <p>
* This class is ported to Java from <a href="https://github.com/openmaptiles/openmaptiles/tree/master/layers/place">OpenMapTiles
* place sql files</a>.
* This class is ported to Java from
* <a href="https://github.com/openmaptiles/openmaptiles/tree/master/layers/place">OpenMapTiles place sql files</a>.
*/
public class Place implements
OpenMapTilesSchema.Place,
@ -142,11 +142,11 @@ public class Place implements
// ORDER BY "rank" ASC NULLS LAST,
.orderByInt(rank == null ? 15 : rank, 0, 15) // 4 bits
// place ASC NULLS LAST,
.thenByInt(place == null ? 15 : place.ordinal(), 0, 15) // 4 bits
.thenByInt(place == null ? 15 : place.ordinal(), 0, 15) // 4 bits
// population DESC NULLS LAST,
.thenByLog(population, MAX_CITY_POPULATION, 1, 1 << (SORT_KEY_BITS - 13) - 1)
// length(name) ASC
.thenByInt(name == null ? 0 : name.length(), 0, 31) // 5 bits
.thenByInt(name == null ? 0 : name.length(), 0, 31) // 5 bits
.get();
}
@ -340,9 +340,9 @@ public class Place implements
int minzoom = rank != null && rank == 1 ? 2 :
rank != null && rank <= 8 ? Math.max(3, rank - 1) :
placeType.ordinal() <= PlaceType.TOWN.ordinal() ? 7 :
placeType.ordinal() <= PlaceType.VILLAGE.ordinal() ? 8 :
placeType.ordinal() <= PlaceType.SUBURB.ordinal() ? 11 : 14;
placeType.ordinal() <= PlaceType.TOWN.ordinal() ? 7 :
placeType.ordinal() <= PlaceType.VILLAGE.ordinal() ? 8 :
placeType.ordinal() <= PlaceType.SUBURB.ordinal() ? 11 : 14;
var feature = features.point(LAYER_NAME).setBufferPixels(BUFFER_SIZE)
.putAttrs(LanguageUtils.getNames(element.source().tags(), translations))
@ -420,9 +420,7 @@ public class Place implements
}
/**
* Information extracted from a natural earth place label that will be inspected when joining with OpenStreetMap
* data.
* Information extracted from a natural earth place label that will be inspected when joining with OpenStreetMap data.
*/
private record NaturalEarthPoint(String name, String wikidata, int scaleRank, Set<String> names) {}
}

Wyświetl plik

@ -61,8 +61,8 @@ import java.util.Map;
* Defines the logic for generating map elements for things like shops, parks, and schools in the {@code poi} layer from
* source features.
* <p>
* This class is ported to Java from <a href="https://github.com/openmaptiles/openmaptiles/tree/master/layers/poi">OpenMapTiles
* poi sql files</a>.
* This class is ported to Java from
* <a href="https://github.com/openmaptiles/openmaptiles/tree/master/layers/poi">OpenMapTiles poi sql files</a>.
*/
public class Poi implements
OpenMapTilesSchema.Poi,
@ -136,19 +136,8 @@ public class Poi implements
setupPoiFeature(element, features.centroidIfConvex(LAYER_NAME));
}
private <T extends
Tables.WithSubclass &
Tables.WithStation &
Tables.WithFunicular &
Tables.WithSport &
Tables.WithInformation &
Tables.WithReligion &
Tables.WithMappingKey &
Tables.WithName &
Tables.WithIndoor &
Tables.WithLayer &
Tables.WithSource>
void setupPoiFeature(T element, FeatureCollector.Feature output) {
private <T extends Tables.WithSubclass & Tables.WithStation & Tables.WithFunicular & Tables.WithSport & Tables.WithInformation & Tables.WithReligion & Tables.WithMappingKey & Tables.WithName & Tables.WithIndoor & Tables.WithLayer & Tables.WithSource> void setupPoiFeature(
T element, FeatureCollector.Feature output) {
String rawSubclass = element.subclass();
if ("station".equals(rawSubclass) && "subway".equals(element.station())) {
rawSubclass = "subway";

Wyświetl plik

@ -80,8 +80,9 @@ import org.slf4j.LoggerFactory;
* Defines the logic for generating map elements for roads, shipways, railroads, and paths in the {@code transportation}
* layer from source features.
* <p>
* This class is ported to Java from <a href="https://github.com/openmaptiles/openmaptiles/tree/master/layers/transportation">OpenMapTiles
* transportation sql files</a>.
* This class is ported to Java from
* <a href="https://github.com/openmaptiles/openmaptiles/tree/master/layers/transportation">OpenMapTiles transportation
* sql files</a>.
*/
public class Transportation implements
OpenMapTilesSchema.Transportation,
@ -214,7 +215,7 @@ public class Transportation implements
private static String railwayClass(String value) {
return value == null ? null :
RAILWAY_RAIL_VALUES.contains(value) ? "rail" :
RAILWAY_TRANSIT_VALUES.contains(value) ? "transit" : null;
RAILWAY_TRANSIT_VALUES.contains(value) ? "transit" : null;
}
static String highwayClass(String highway, String publicTransport, String construction, String manMade) {
@ -320,8 +321,8 @@ public class Transportation implements
Geometry wayGeometry = element.source().worldGeometry();
if (greatBritain.intersects(wayGeometry)) {
Transportation.RouteNetwork networkType =
"motorway".equals(element.highway()) ? Transportation.RouteNetwork.GB_MOTORWAY
: Transportation.RouteNetwork.GB_TRUNK;
"motorway".equals(element.highway()) ? Transportation.RouteNetwork.GB_MOTORWAY :
Transportation.RouteNetwork.GB_TRUNK;
String network = "motorway".equals(element.highway()) ? "omt-gb-motorway" : "omt-gb-trunk";
result.add(new RouteRelation(refMatcher.group(), network, networkType, (byte) -1,
0));
@ -434,7 +435,7 @@ public class Transportation implements
private boolean isPierPolygon(Tables.OsmHighwayLinestring element) {
if ("pier".equals(element.manMade())) {
try {
if (element.source().worldGeometry() instanceof LineString lineString && lineString.isClosed()) {
if (element.source().worldGeometry()instanceof LineString lineString && lineString.isClosed()) {
// ignore this because it's a polygon
return true;
}

Wyświetl plik

@ -67,7 +67,8 @@ import java.util.function.Function;
* Defines the logic for generating map elements for road, shipway, rail, and path names in the {@code
* transportation_name} layer from source features.
* <p>
* This class is ported to Java from <a href="https://github.com/openmaptiles/openmaptiles/tree/master/layers/transportation_name">OpenMapTiles
* This class is ported to Java from
* <a href="https://github.com/openmaptiles/openmaptiles/tree/master/layers/transportation_name">OpenMapTiles
* transportation_name sql files</a>.
*/
public class TransportationName implements
@ -222,7 +223,7 @@ public class TransportationName implements
int minzoom = FieldValues.CLASS_TRUNK.equals(baseClass) ? 8 :
FieldValues.CLASS_MOTORWAY.equals(baseClass) ? 6 :
isLink ? 13 : 12; // fallback - get from line minzoom, but floor at 12
isLink ? 13 : 12; // fallback - get from line minzoom, but floor at 12
// inherit min zoom threshold from visible road, and ensure we never show a label on a road that's not visible yet.
minzoom = Math.max(minzoom, transportation.getMinzoom(element, highwayClass));
@ -235,8 +236,8 @@ public class TransportationName implements
.setAttr(Fields.REF, ref)
.setAttr(Fields.REF_LENGTH, ref != null ? ref.length() : null)
.setAttr(Fields.NETWORK,
(relation != null && relation.networkType() != null) ? relation.networkType().name
: !nullOrEmpty(ref) ? "road" : null)
(relation != null && relation.networkType() != null) ? relation.networkType().name :
!nullOrEmpty(ref) ? "road" : null)
.setAttr(Fields.CLASS, highwayClass)
.setAttr(Fields.SUBCLASS, highwaySubclass(highwayClass, null, highway))
.setMinPixelSize(0)
@ -314,7 +315,7 @@ public class TransportationName implements
Function<Map<String, Object>, Double> lengthLimitCalculator =
zoom >= 14 ? (p -> 0d) :
minLength > 0 ? (p -> minLength) :
this::getMinLengthForName;
this::getMinLengthForName;
var result = FeatureMerge.mergeLineStrings(items, lengthLimitCalculator, tolerance, BUFFER_SIZE);
if (limitMerge) {
// remove temp keys that were just used to improve line merging

Wyświetl plik

@ -49,8 +49,8 @@ import com.onthegomap.planetiler.util.Translations;
/**
* Defines the logic for generating map elements for oceans and lakes in the {@code water} layer from source features.
* <p>
* This class is ported to Java from <a href="https://github.com/openmaptiles/openmaptiles/tree/master/layers/water">OpenMapTiles
* water sql files</a>.
* This class is ported to Java from
* <a href="https://github.com/openmaptiles/openmaptiles/tree/master/layers/water">OpenMapTiles water sql files</a>.
*/
public class Water implements
OpenMapTilesSchema.Water,

Wyświetl plik

@ -61,8 +61,9 @@ import org.slf4j.LoggerFactory;
* Defines the logic for generating map elements for ocean and lake names in the {@code water_name} layer from source
* features.
* <p>
* This class is ported to Java from <a href="https://github.com/openmaptiles/openmaptiles/tree/master/layers/water_name">OpenMapTiles
* water_name sql files</a>.
* This class is ported to Java from
* <a href="https://github.com/openmaptiles/openmaptiles/tree/master/layers/water_name">OpenMapTiles water_name sql
* files</a>.
*/
public class WaterName implements
OpenMapTilesSchema.WaterName,

Wyświetl plik

@ -63,8 +63,9 @@ import java.util.Map;
/**
* Defines the logic for generating river map elements in the {@code waterway} layer from source features.
* <p>
* This class is ported to Java from <a href="https://github.com/openmaptiles/openmaptiles/tree/master/layers/waterway">OpenMapTiles
* waterway sql files</a>.
* This class is ported to Java from
* <a href="https://github.com/openmaptiles/openmaptiles/tree/master/layers/waterway">OpenMapTiles waterway sql
* files</a>.
*/
public class Waterway implements
OpenMapTilesSchema.Waterway,

Wyświetl plik

@ -49,7 +49,8 @@ import java.util.stream.Stream;
* Utilities to extract common name fields (name, name_en, name_de, name:latin, name:nonlatin, name_int) that the
* OpenMapTiles schema uses across any map element with a name.
* <p>
* Ported from <a href="https://github.com/openmaptiles/openmaptiles-tools/blob/master/sql/zzz_language.sql">openmaptiles-tools</a>.
* Ported from
* <a href="https://github.com/openmaptiles/openmaptiles-tools/blob/master/sql/zzz_language.sql">openmaptiles-tools</a>.
*/
public class LanguageUtils {
@ -101,12 +102,12 @@ public class LanguageUtils {
* element should have, derived from name, int_name, name:en, and name:de tags on the input element.
*
* <ul>
* <li>name is the original name value from the element</li>
* <li>name_en is the original name:en value from the element, or name if missing</li>
* <li>name_de is the original name:de value from the element, or name/ name_en if missing</li>
* <li>name:latin is the first of name, int_name, or any name: attribute that contains only latin characters</li>
* <li>name:nonlatin is any nonlatin part of name if present</li>
* <li>name_int is the first of int_name name:en name:latin name</li>
* <li>name is the original name value from the element</li>
* <li>name_en is the original name:en value from the element, or name if missing</li>
* <li>name_de is the original name:de value from the element, or name/ name_en if missing</li>
* <li>name:latin is the first of name, int_name, or any name: attribute that contains only latin characters</li>
* <li>name:nonlatin is any nonlatin part of name if present</li>
* <li>name_int is the first of int_name name:en name:latin name</li>
* </ul>
*/
public static Map<String, Object> getNamesWithoutTranslations(Map<String, Object> tags) {
@ -126,8 +127,8 @@ public class LanguageUtils {
String nameDe = string(tags.get("name:de"));
boolean isLatin = containsOnlyLatinCharacters(name);
String latin = isLatin ? name
: Stream.concat(Stream.of(nameEn, intName, nameDe), getAllNameTranslationsBesidesEnglishAndGerman(tags))
String latin = isLatin ? name :
Stream.concat(Stream.of(nameEn, intName, nameDe), getAllNameTranslationsBesidesEnglishAndGerman(tags))
.filter(LanguageUtils::containsOnlyLatinCharacters)
.findFirst().orElse(null);
if (latin == null && translations != null && translations.getShouldTransliterate()) {

Wyświetl plik

@ -61,8 +61,8 @@ public abstract class AbstractLayerTest {
if (vals[i - 1] > vals[i]) {
fail(
Arrays.toString(vals) +
System.lineSeparator() + "element at " + (i - 1) + " (" + vals[i - 1] + ") is greater than element at " + i
+ " (" + vals[i] + ")");
System.lineSeparator() + "element at " + (i - 1) + " (" + vals[i - 1] + ") is greater than element at " +
i + " (" + vals[i] + ")");
}
}
}

Wyświetl plik

@ -414,60 +414,60 @@ public class BoundaryTest extends AbstractLayerTest {
// shared edge
assertFeatures(14, List.of(), process(SimpleFeature.createFakeOsmFeature(
newLineString(0, 0, 0, 10),
Map.of(),
OSM_SOURCE,
null,
3,
Stream.concat(
profile.preprocessOsmRelation(country1).stream(),
profile.preprocessOsmRelation(country2).stream()
).map(r -> new OsmReader.RelationMember<>("", r)).toList()
)
newLineString(0, 0, 0, 10),
Map.of(),
OSM_SOURCE,
null,
3,
Stream.concat(
profile.preprocessOsmRelation(country1).stream(),
profile.preprocessOsmRelation(country2).stream()
).map(r -> new OsmReader.RelationMember<>("", r)).toList()
)
));
// other 2 edges of country 1
assertFeatures(14, List.of(), process(SimpleFeature.createFakeOsmFeature(
newLineString(0, 0, 5, 10),
Map.of(),
OSM_SOURCE,
null,
4,
profile.preprocessOsmRelation(country1).stream().map(r -> new OsmReader.RelationMember<>("", r))
.toList()
)
newLineString(0, 0, 5, 10),
Map.of(),
OSM_SOURCE,
null,
4,
profile.preprocessOsmRelation(country1).stream().map(r -> new OsmReader.RelationMember<>("", r))
.toList()
)
));
assertFeatures(14, List.of(), process(SimpleFeature.createFakeOsmFeature(
newLineString(0, 10, 5, 10),
Map.of(),
OSM_SOURCE,
null,
4,
profile.preprocessOsmRelation(country1).stream().map(r -> new OsmReader.RelationMember<>("", r))
.toList()
)
newLineString(0, 10, 5, 10),
Map.of(),
OSM_SOURCE,
null,
4,
profile.preprocessOsmRelation(country1).stream().map(r -> new OsmReader.RelationMember<>("", r))
.toList()
)
));
// other 2 edges of country 2
assertFeatures(14, List.of(), process(SimpleFeature.createFakeOsmFeature(
newLineString(0, 0, -5, 10),
Map.of(),
OSM_SOURCE,
null,
4,
profile.preprocessOsmRelation(country2).stream().map(r -> new OsmReader.RelationMember<>("", r))
.toList()
)
newLineString(0, 0, -5, 10),
Map.of(),
OSM_SOURCE,
null,
4,
profile.preprocessOsmRelation(country2).stream().map(r -> new OsmReader.RelationMember<>("", r))
.toList()
)
));
assertFeatures(14, List.of(), process(SimpleFeature.createFakeOsmFeature(
newLineString(0, 10, -5, 10),
Map.of(),
OSM_SOURCE,
null,
4,
profile.preprocessOsmRelation(country2).stream().map(r -> new OsmReader.RelationMember<>("", r))
.toList()
)
newLineString(0, 10, -5, 10),
Map.of(),
OSM_SOURCE,
null,
4,
profile.preprocessOsmRelation(country2).stream().map(r -> new OsmReader.RelationMember<>("", r))
.toList()
)
));
List<FeatureCollector.Feature> features = new ArrayList<>();

Wyświetl plik

@ -203,7 +203,7 @@ public class LandcoverTest extends AbstractLayerTest {
throws GeometryException {
assertEquals(expected,
profile.postProcessLayerFeatures("landcover", zoom, in).stream().map(
VectorTile.Feature::attrs)
VectorTile.Feature::attrs)
.toList());
}
}

Wyświetl plik

@ -44,9 +44,9 @@ public class LanduseTest extends AbstractLayerTest {
"_minzoom", 9,
"_maxzoom", 14
)), process(polygonFeature(Map.of(
"landuse", "railway",
"amenity", "school"
))));
"landuse", "railway",
"amenity", "school"
))));
assertFeatures(13, List.of(Map.of("_layer", "poi"), Map.of(
"_layer", "landuse",
"class", "school",
@ -66,8 +66,8 @@ public class LanduseTest extends AbstractLayerTest {
"_layer", "landuse",
"class", "cemetery"
)), process(polygonFeature(Map.of(
"amenity", "grave_yard"
))));
"amenity", "grave_yard"
))));
}
@Test

Wyświetl plik

@ -24,7 +24,7 @@ public class ParkTest extends AbstractLayerTest {
"name", "Grand Canyon National Park",
"name_int", "Grand Canyon National Park",
"name:latin", "Grand Canyon National Park",
// "name:es", "es name", // don't include all translations
// "name:es", "es name", // don't include all translations
"_minzoom", 5,
"_maxzoom", 14
)), process(polygonFeature(Map.of(

Wyświetl plik

@ -110,8 +110,8 @@ public class WaterTest extends AbstractLayerTest {
"_minzoom", 6,
"_maxzoom", 14
)), process(polygonFeature(Map.of(
"leisure", "swimming_pool"
))));
"leisure", "swimming_pool"
))));
assertFeatures(14, List.of(), process(polygonFeature(Map.of(
"natural", "bay"
))));

Wyświetl plik

@ -17,7 +17,7 @@ import java.util.Random;
import org.locationtech.jts.geom.Geometry;
/**
* Performance tests for {@link MultiExpression}. Times how long a sample of elements from an OSM input file take to
* Performance tests for {@link MultiExpression}. Times how long a sample of elements from an OSM input file take to
* match.
*/
public class BasemapMapping {

Wyświetl plik

@ -22,13 +22,16 @@ import org.locationtech.jts.geom.Geometry;
* feature.
* <p>
* For example to add a polygon feature for a lake and a center label point with its name:
* <pre>{@code
*
* <pre>
* {@code
* featureCollector.polygon("water")
* .setAttr("class", "lake");
* featureCollector.centroid("water_name")
* .setAttr("class", "lake")
* .setAttr("name", element.getString("name"));
* }</pre>
* }
* </pre>
*/
public class FeatureCollector implements Iterable<FeatureCollector.Feature> {
@ -265,9 +268,8 @@ public class FeatureCollector implements Iterable<FeatureCollector.Feature> {
* feature that appear later (higher sort key) in a layer.
*/
public Feature setSortKey(int sortKey) {
assert sortKey >= FeatureGroup.SORT_KEY_MIN && sortKey <= FeatureGroup.SORT_KEY_MAX :
"Sort key " + sortKey + " outside of allowed range [" + FeatureGroup.SORT_KEY_MIN + ", "
+ FeatureGroup.SORT_KEY_MAX + "]";
assert sortKey >= FeatureGroup.SORT_KEY_MIN && sortKey <= FeatureGroup.SORT_KEY_MAX : "Sort key " + sortKey +
" outside of allowed range [" + FeatureGroup.SORT_KEY_MIN + ", " + FeatureGroup.SORT_KEY_MAX + "]";
this.sortKey = sortKey;
return this;
}
@ -349,8 +351,8 @@ public class FeatureCollector implements Iterable<FeatureCollector.Feature> {
/**
* Sets zoom-specific overrides to the number of pixels of detail to render outside the visible tile boundary.
* <p>
* If {@code buffer} is {@code null} or returns {@code null}, the buffer pixels will default to {@link
* #setBufferPixels(double)}.
* If {@code buffer} is {@code null} or returns {@code null}, the buffer pixels will default to
* {@link #setBufferPixels(double)}.
*/
public Feature setBufferPixelOverrides(ZoomFunction<Number> buffer) {
bufferPixelOverrides = buffer;
@ -365,8 +367,8 @@ public class FeatureCollector implements Iterable<FeatureCollector.Feature> {
* features to emit.
*/
public double getMinPixelSizeAtZoom(int zoom) {
return zoom == config.maxzoom() ? minPixelSizeAtMaxZoom
: ZoomFunction.applyAsDoubleOrElse(minPixelSize, zoom, defaultMinPixelSize);
return zoom == config.maxzoom() ? minPixelSizeAtMaxZoom :
ZoomFunction.applyAsDoubleOrElse(minPixelSize, zoom, defaultMinPixelSize);
}
/**
@ -400,8 +402,8 @@ public class FeatureCollector implements Iterable<FeatureCollector.Feature> {
/**
* Overrides the default minimum pixel size at and below {@code zoom} with {@code minPixelSize}.
* <p>
* This replaces all previous zoom overrides that were set. To use multiple zoom-level thresholds, create a {@link
* ZoomFunction} explicitly and pass it to {@link #setMinPixelSizeOverrides(ZoomFunction)}.
* This replaces all previous zoom overrides that were set. To use multiple zoom-level thresholds, create a
* {@link ZoomFunction} explicitly and pass it to {@link #setMinPixelSizeOverrides(ZoomFunction)}.
*/
public Feature setMinPixelSizeBelowZoom(int zoom, double minPixelSize) {
if (zoom >= config.maxzoom()) {
@ -429,7 +431,8 @@ public class FeatureCollector implements Iterable<FeatureCollector.Feature> {
* Sets the minimum length of line features or square root of the minimum area of polygon features to emit at all
* zoom levels, including the maximum zoom-level of the map.
* <p>
* This replaces previous default values, but not overrides set with {@link #setMinPixelSizeOverrides(ZoomFunction)}.
* This replaces previous default values, but not overrides set with
* {@link #setMinPixelSizeOverrides(ZoomFunction)}.
*/
public Feature setMinPixelSizeAtAllZooms(int minPixelSize) {
this.minPixelSizeAtMaxZoom = minPixelSize;
@ -440,8 +443,8 @@ public class FeatureCollector implements Iterable<FeatureCollector.Feature> {
* Returns the simplification tolerance for lines and polygons in tile pixels at {@code zoom}.
*/
public double getPixelToleranceAtZoom(int zoom) {
return zoom == config.maxzoom() ? pixelToleranceAtMaxZoom
: ZoomFunction.applyAsDoubleOrElse(pixelTolerance, zoom, defaultPixelTolerance);
return zoom == config.maxzoom() ? pixelToleranceAtMaxZoom :
ZoomFunction.applyAsDoubleOrElse(pixelTolerance, zoom, defaultPixelTolerance);
}
/**
@ -497,8 +500,8 @@ public class FeatureCollector implements Iterable<FeatureCollector.Feature> {
* Overrides the default simplification tolerance for lines and polygons in tile pixels at and below {@code zoom}
* with {@code minPixelSize}.
* <p>
* This replaces all previous zoom overrides that were set. To use multiple zoom-level thresholds, create a {@link
* ZoomFunction} explicitly and pass it to {@link #setPixelToleranceOverrides(ZoomFunction)}
* This replaces all previous zoom overrides that were set. To use multiple zoom-level thresholds, create a
* {@link ZoomFunction} explicitly and pass it to {@link #setPixelToleranceOverrides(ZoomFunction)}
*/
public Feature setPixelToleranceBelowZoom(int zoom, double tolerance) {
if (zoom == config.maxzoom()) {
@ -519,9 +522,10 @@ public class FeatureCollector implements Iterable<FeatureCollector.Feature> {
public double getPointLabelGridPixelSizeAtZoom(int zoom) {
double result = ZoomFunction.applyAsDoubleOrElse(labelGridPixelSize, zoom, DEFAULT_LABEL_GRID_SIZE);
// TODO is this enough? what about a grid square that ends just before the start of the tile
assert result <= getBufferPixelsAtZoom(zoom) :
"to avoid inconsistent rendering of the same point between adjacent tiles, buffer pixel size should be >= label grid size but in '%s' buffer pixel size=%f was greater than label grid size=%f".formatted(
getLayer(), getBufferPixelsAtZoom(zoom), result);
assert result <= getBufferPixelsAtZoom(
zoom) : "to avoid inconsistent rendering of the same point between adjacent tiles, buffer pixel size should be >= label grid size but in '%s' buffer pixel size=%f was greater than label grid size=%f"
.formatted(
getLayer(), getBufferPixelsAtZoom(zoom), result);
return result;
}
@ -550,7 +554,7 @@ public class FeatureCollector implements Iterable<FeatureCollector.Feature> {
* @param labelGridSize a function that returns the size of the label grid to use at each zoom level. If function is
* or returns null for a zoom-level, no label grid will be computed.
* @see <a href="https://github.com/mapbox/postgis-vt-util/blob/master/src/LabelGrid.sql">LabelGrid postgis
* function</a>
* function</a>
*/
public Feature setPointLabelGridPixelSize(ZoomFunction<Number> labelGridSize) {
this.labelGridPixelSize = labelGridSize;
@ -565,7 +569,7 @@ public class FeatureCollector implements Iterable<FeatureCollector.Feature> {
* set for label grid size. To set multiple thresholds, use the other method directly.
*
* @see <a href="https://github.com/mapbox/postgis-vt-util/blob/master/src/LabelGrid.sql">LabelGrid postgis
* function</a>
* function</a>
*/
public Feature setPointLabelGridPixelSize(int maxzoom, double size) {
return setPointLabelGridPixelSize(ZoomFunction.maxZoom(maxzoom, size));
@ -579,7 +583,7 @@ public class FeatureCollector implements Iterable<FeatureCollector.Feature> {
* @param labelGridLimit a function that returns the size of the label grid to use at each zoom level. If function
* is or returns null for a zoom-level, no label grid will be computed.
* @see <a href="https://github.com/mapbox/postgis-vt-util/blob/master/src/LabelGrid.sql">LabelGrid postgis
* function</a>
* function</a>
*/
public Feature setPointLabelGridLimit(ZoomFunction<Number> labelGridLimit) {
this.labelGridLimit = labelGridLimit;
@ -590,9 +594,9 @@ public class FeatureCollector implements Iterable<FeatureCollector.Feature> {
* Limits the density of points on an output tile at and below {@code maxzoom} by only emitting the {@code limit}
* features with lowest sort-key in each square of a {@code size x size} pixel grid.
* <p>
* This is a thin wrapper around {@link #setPointLabelGridPixelSize(ZoomFunction)} and {@link
* #setPointLabelGridLimit(ZoomFunction)}. It replaces any previous value set for label grid size or limit. To set
* multiple thresholds, use the other methods directly.
* This is a thin wrapper around {@link #setPointLabelGridPixelSize(ZoomFunction)} and
* {@link #setPointLabelGridLimit(ZoomFunction)}. It replaces any previous value set for label grid size or limit.
* To set multiple thresholds, use the other methods directly.
* <p>
* NOTE: the label grid is computed within each tile independently of its neighbors, so to ensure consistent limits
* and ranking of a point rendered in adjacent tiles, be sure to set the buffer pixel size to at least be larger
@ -602,7 +606,7 @@ public class FeatureCollector implements Iterable<FeatureCollector.Feature> {
* @param size the label grid size to use when computing hashes
* @param limit the number of lowest-sort-key points to include in each square of the grid
* @see <a href="https://github.com/mapbox/postgis-vt-util/blob/master/src/LabelGrid.sql">LabelGrid postgis
* function</a>
* function</a>
*/
public Feature setPointLabelGridSizeAndLimit(int maxzoom, double size, int limit) {
return setPointLabelGridPixelSize(ZoomFunction.maxZoom(maxzoom, size))
@ -655,11 +659,11 @@ public class FeatureCollector implements Iterable<FeatureCollector.Feature> {
}
/**
* Sets the value for {@code key} attribute at or above {@code minzoom}. Below {@code minzoom} it will be ignored.
* Sets the value for {@code key} attribute at or above {@code minzoom}. Below {@code minzoom} it will be ignored.
* <p>
* Replaces all previous value that has been for {@code key} at any zoom level. To have a value that changes at
* multiple zoom level thresholds, call {@link #setAttr(String, Object)} with a manually-constructed {@link
* ZoomFunction} value.
* Replaces all previous value that has been for {@code key} at any zoom level. To have a value that changes at
* multiple zoom level thresholds, call {@link #setAttr(String, Object)} with a manually-constructed
* {@link ZoomFunction} value.
*/
public Feature setAttrWithMinzoom(String key, Object value, int minzoom) {
return setAttr(key, ZoomFunction.minZoom(minzoom, value));

Wyświetl plik

@ -33,13 +33,13 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* A collection of utilities for merging features with the same attributes in a rendered tile from {@link
* Profile#postProcessLayerFeatures(String, int, List)} immediately before a tile is written to the output mbtiles
* file.
* A collection of utilities for merging features with the same attributes in a rendered tile from
* {@link Profile#postProcessLayerFeatures(String, int, List)} immediately before a tile is written to the output
* mbtiles file.
* <p>
* Unlike postgis-based solutions that have a full view of all features after they are loaded into the databse, the
* planetiler engine only sees a single input feature at a time while processing source features, then only has
* visibility into multiple features when they are grouped into a tile immediately before emitting. This ends up being
* visibility into multiple features when they are grouped into a tile immediately before emitting. This ends up being
* sufficient for most real-world use-cases but to do anything more that requires a view of multiple features
* <em>not</em> within the same tile, {@link Profile} implementations must store input features manually.
*/
@ -53,8 +53,7 @@ public class FeatureMerge {
}
/** Don't instantiate */
private FeatureMerge() {
}
private FeatureMerge() {}
/**
* Combines linestrings with the same set of attributes into a multilinestring where segments with touching endpoints
@ -69,7 +68,7 @@ public class FeatureMerge {
* @param tolerance after merging, simplify linestrings using this pixel tolerance, or -1 to skip simplification step
* @param buffer number of pixels outside the visible tile area to include detail for, or -1 to skip clipping step
* @return a new list containing all unaltered features in their original order, then each of the merged groups
* ordered by the index of the first element in that group from the input list.
* ordered by the index of the first element in that group from the input list.
*/
public static List<VectorTile.Feature> mergeLineStrings(List<VectorTile.Feature> features,
double minLength, double tolerance, double buffer) {
@ -78,7 +77,7 @@ public class FeatureMerge {
/**
* Merges linestrings with the same attributes like {@link #mergeLineStrings(List, double, double, double)} except
* with a dynamic length limit computed by {@code lengthLimitCalculator} for the attributes of each group.
* with a dynamic length limit computed by {@code lengthLimitCalculator} for the attributes of each group.
*/
public static List<VectorTile.Feature> mergeLineStrings(List<VectorTile.Feature> features,
Function<Map<String, Object>, Double> lengthLimitCalculator, double tolerance, double buffer) {
@ -186,7 +185,7 @@ public class FeatureMerge {
* @param features all features in a layer
* @param minArea minimum area in square tile pixels of polygons to emit
* @return a new list containing all unaltered features in their original order, then each of the merged groups
* ordered by the index of the first element in that group from the input list.
* ordered by the index of the first element in that group from the input list.
* @throws GeometryException if an error occurs encoding the combined geometry
*/
public static List<VectorTile.Feature> mergeOverlappingPolygons(List<VectorTile.Feature> features, double minArea)
@ -215,7 +214,7 @@ public class FeatureMerge {
* @param buffer the amount (in tile pixels) to expand then contract polygons by in order to combine
* almost-touching polygons
* @return a new list containing all unaltered features in their original order, then each of the merged groups
* ordered by the index of the first element in that group from the input list.
* ordered by the index of the first element in that group from the input list.
* @throws GeometryException if an error occurs encoding the combined geometry
*/
public static List<VectorTile.Feature> mergeNearbyPolygons(List<VectorTile.Feature> features, double minArea,

Wyświetl plik

@ -14,13 +14,13 @@ import java.util.function.Consumer;
* A framework for building complex {@link Profile Profiles} that need to be broken apart into multiple handlers (i.e.
* one per layer).
* <p>
* Individual handlers added with {@link #registerHandler(Handler)} can listen on events by implementing these
* handlers:
* Individual handlers added with {@link #registerHandler(Handler)} can listen on events by implementing these handlers:
* <ul>
* <li>{@link OsmRelationPreprocessor} to process every OSM relation during first pass through OSM file</li>
* <li>{@link FeatureProcessor} to handle features from a particular source (added through {@link #registerSourceHandler(String, FeatureProcessor)})</li>
* <li>{@link FinishHandler} to be notified whenever we finish processing each source</li>
* <li>{@link FeaturePostProcessor} to post-process features in a layer before rendering the output tile</li>
* <li>{@link OsmRelationPreprocessor} to process every OSM relation during first pass through OSM file</li>
* <li>{@link FeatureProcessor} to handle features from a particular source (added through
* {@link #registerSourceHandler(String, FeatureProcessor)})</li>
* <li>{@link FinishHandler} to be notified whenever we finish processing each source</li>
* <li>{@link FeaturePostProcessor} to post-process features in a layer before rendering the output tile</li>
* </ul>
* See {@code OpenMapTilesProfile} for a full implementation using this framework.
*/
@ -52,8 +52,8 @@ public abstract class ForwardingProfile implements Profile {
}
/**
* Call {@code handler} for different events based on which interfaces {@code handler} implements: {@link
* OsmRelationPreprocessor}, {@link FinishHandler}, or {@link FeaturePostProcessor}.
* Call {@code handler} for different events based on which interfaces {@code handler} implements:
* {@link OsmRelationPreprocessor}, {@link FinishHandler}, or {@link FeaturePostProcessor}.
*/
public void registerHandler(Handler handler) {
this.handlers.add(handler);
@ -161,8 +161,7 @@ public abstract class ForwardingProfile implements Profile {
public interface Handler {
/** Free any resources associated with this profile (i.e. shared data structures) */
default void release() {
}
default void release() {}
}
public interface HandlerForLayer extends Handler {
@ -187,8 +186,7 @@ public abstract class ForwardingProfile implements Profile {
public interface OsmNodePreprocessor extends Handler {
/**
* Extracts information from an OSM node during pass 1 of the input OSM data that the profile may need during
* pass2.
* Extracts information from an OSM node during pass 1 of the input OSM data that the profile may need during pass2.
*
* @see Profile#preprocessOsmNode(OsmElement.Node)
*/

Wyświetl plik

@ -39,7 +39,9 @@ import org.slf4j.LoggerFactory;
* common use-cases.
* <p>
* For example:
* <pre><code>
*
* <pre>
* <code>
* public static void main(String[] args) {
* Planetiler.create(arguments)
* .setProfile(new CustomProfile())
@ -48,7 +50,8 @@ import org.slf4j.LoggerFactory;
* .addOsmSource("osm", Path.of("source.osm.pbf"))
* .setOutput("mbtiles", Path.of("output.mbtiles"))
* .run();
* }</code></pre>
* }</code>
* </pre>
* <p>
* Each call to a builder API mutates the runner instance and returns it for more chaining.
* <p>
@ -140,9 +143,9 @@ public class Planetiler {
* @param name string to use in stats and logs to identify this stage
* @param defaultPath path to the input file to use if {@code name_path} argument is not set
* @param defaultUrl remote URL that the file to download if {@code download=true} argument is set and {@code
* name_url} argument is not set. As a shortcut, can use "geofabrik:monaco" or
* "geofabrik:australia" shorthand to find an extract by name from <a
* href="https://download.geofabrik.de/">Geofabrik download site</a> or "aws:latest" to download
* name_url} argument is not set. As a shortcut, can use "geofabrik:monaco" or
* "geofabrik:australia" shorthand to find an extract by name from
* <a href="https://download.geofabrik.de/">Geofabrik download site</a> or "aws:latest" to download
* the latest {@code planet.osm.pbf} file from <a href="https://registry.opendata.aws/osm/">AWS
* Open Data Registry</a>.
* @return this runner instance for chaining
@ -180,8 +183,8 @@ public class Planetiler {
}
/**
* Adds a new ESRI shapefile source that will be processed using a projection inferred from the shapefile when {@link
* #run()} is called.
* Adds a new ESRI shapefile source that will be processed using a projection inferred from the shapefile when
* {@link #run()} is called.
* <p>
* To override the location of the {@code shapefile} file, set {@code name_path=newpath.shp.zip} in the arguments.
*
@ -197,13 +200,12 @@ public class Planetiler {
}
/**
* Adds a new ESRI shapefile source that will be processed using an explicit projection when {@link #run()} is
* called.
* Adds a new ESRI shapefile source that will be processed using an explicit projection when {@link #run()} is called.
* <p>
* To override the location of the {@code shapefile} file, set {@code name_path=newpath.shp.zip} in the arguments.
*
* @param projection the Coordinate Reference System authority code to use, parsed with {@link
* org.geotools.referencing.CRS#decode(String)}
* @param projection the Coordinate Reference System authority code to use, parsed with
* {@link org.geotools.referencing.CRS#decode(String)}
* @param name string to use in stats and logs to identify this stage
* @param defaultPath path to the input file to use if {@code name_path} key is not set through arguments. Can be a
* {@code .shp} file with other shapefile components in the same directory, or a {@code .zip} file
@ -216,8 +218,8 @@ public class Planetiler {
}
/**
* Adds a new ESRI shapefile source that will be processed with a projection inferred from the shapefile when {@link
* #run()} is called.
* Adds a new ESRI shapefile source that will be processed with a projection inferred from the shapefile when
* {@link #run()} is called.
* <p>
* If the file does not exist and {@code download=true} argument is set, then the file will first be downloaded from
* {@code defaultUrl}.
@ -248,8 +250,8 @@ public class Planetiler {
* To override the location of the {@code shapefile} file, set {@code name_path=newpath.shp.zip} in the arguments and
* to override the download URL set {@code name_url=http://url/of/shapefile.zip}.
*
* @param projection the Coordinate Reference System authority code to use, parsed with {@link
* org.geotools.referencing.CRS#decode(String)}
* @param projection the Coordinate Reference System authority code to use, parsed with
* {@link org.geotools.referencing.CRS#decode(String)}
* @param name string to use in stats and logs to identify this stage
* @param defaultPath path to the input file to use if {@code name_path} key is not set through arguments. Can be a
* {@code .shp} file with other shapefile components in the same directory, or a {@code .zip} file
@ -332,8 +334,8 @@ public class Planetiler {
}
/**
* Updates {@link #translations()} to use name translations fetched from wikidata based on the <a
* href="https://www.wikidata.org/wiki/Wikidata:OpenStreetMap">wikidata tag</a> on OSM elements.
* Updates {@link #translations()} to use name translations fetched from wikidata based on the
* <a href="https://www.wikidata.org/wiki/Wikidata:OpenStreetMap">wikidata tag</a> on OSM elements.
* <p>
* When either {@code only_fetch_wikidata} or {@code fetch_wikidata} arguments are set to true, this downloads
* translations for every OSM element that the profile cares about and stores them to {@code defaultWikidataCache} (or
@ -393,8 +395,7 @@ public class Planetiler {
}
/**
* Sets the location of the output {@code .mbtiles} file to write rendered tiles to. Fails if the file already
* exists.
* Sets the location of the output {@code .mbtiles} file to write rendered tiles to. Fails if the file already exists.
* <p>
* To override the location of the file, set {@code argument=newpath.mbtiles} in the arguments.
*
@ -570,9 +571,8 @@ public class Planetiler {
if (available < requested) {
var format = Format.defaultInstance();
String warning =
"Planetiler needs ~" + format.storage(requested) + " on " + fs + " during " + phase
+ " phase, which only has "
+ format.storage(available) + " available";
"Planetiler needs ~" + format.storage(requested) + " on " + fs + " during " + phase +
" phase, which only has " + format.storage(available) + " available";
if (config.force() || requested < available * 1.25) {
LOGGER.warn(warning + ", may fail.");
} else {
@ -592,9 +592,9 @@ public class Planetiler {
if (jvmMemory < requested) {
String warning =
"Planetiler needs ~" + format.storage(requested) + " memory for the JVM, but only "
+ format.storage(jvmMemory) + " is available, try setting -Xmx=" + format.storage(requested).toLowerCase(
Locale.ROOT);
"Planetiler needs ~" + format.storage(requested) + " memory for the JVM, but only " +
format.storage(jvmMemory) + " is available, try setting -Xmx=" + format.storage(requested).toLowerCase(
Locale.ROOT);
if (config.force() || requested < jvmMemory * 1.25) {
LOGGER.warn(warning + ", may fail.");
} else {

Wyświetl plik

@ -14,17 +14,18 @@ import java.util.function.Consumer;
* <p>
* This includes:
* <ul>
* <li>How source features (OSM elements, shapefile elements, etc.) map to output features and their tags</li>
* <li>How vector tile features in an output tile should be post-processed (see {@link FeatureMerge})</li>
* <li>What attributes to include in the mbtiles metadata output (see {@link Mbtiles})</li>
* <li>Whether {@link Wikidata} class should fetch wikidata translations for an OSM element</li>
* <li>How source features (OSM elements, shapefile elements, etc.) map to output features and their tags</li>
* <li>How vector tile features in an output tile should be post-processed (see {@link FeatureMerge})</li>
* <li>What attributes to include in the mbtiles metadata output (see {@link Mbtiles})</li>
* <li>Whether {@link Wikidata} class should fetch wikidata translations for an OSM element</li>
* </ul>
* <p>
* {@link Profile#processFeature(SourceFeature, FeatureCollector)} only handles a single element at a time. To "join"
* elements across or within sources, implementations can store data in instance fields and wait to process them until
* an element is encountered in a later source, or the {@link Profile#finish(String, FeatureCollector.Factory, Consumer)}
* method is called for a source. All methods may be called concurrently by multiple threads, so implementations must be
* careful to ensure access to instance fields is thread-safe.
* an element is encountered in a later source, or the
* {@link Profile#finish(String, FeatureCollector.Factory, Consumer)} method is called for a source. All methods may be
* called concurrently by multiple threads, so implementations must be careful to ensure access to instance fields is
* thread-safe.
* <p>
* For complex profiles, {@link ForwardingProfile} provides a framework for splitting the logic up into several handlers
* (i.e. one per layer) and forwarding each element/event to the handlers that care about it.
@ -40,8 +41,7 @@ public interface Profile {
*
* @param node the OSM node
*/
default void preprocessOsmNode(OsmElement.Node node) {
}
default void preprocessOsmNode(OsmElement.Node node) {}
/**
* Allows profile to extract any information it needs from a {@link OsmElement.Way} during the first pass through OSM
@ -51,8 +51,7 @@ public interface Profile {
*
* @param way the OSM way
*/
default void preprocessOsmWay(OsmElement.Way way) {
}
default void preprocessOsmWay(OsmElement.Way way) {}
/**
* Extracts information from <a href="https://wiki.openstreetmap.org/wiki/Relation">OSM relations</a> that will be
@ -63,8 +62,8 @@ public interface Profile {
* The default implementation returns {@code null} to ignore all relations
*
* @param relation the OSM relation
* @return a list of relation info instances with information extracted from the relation to pass to {@link
* #processFeature(SourceFeature, FeatureCollector)}, or {@code null} to ignore.
* @return a list of relation info instances with information extracted from the relation to pass to
* {@link #processFeature(SourceFeature, FeatureCollector)}, or {@code null} to ignore.
*/
default List<OsmRelationInfo> preprocessOsmRelation(OsmElement.Relation relation) {
return null;
@ -74,7 +73,7 @@ public interface Profile {
* Generates output features for any input feature that should appear in the map.
* <p>
* Multiple threads may invoke this method concurrently for a single data source so implementations should ensure
* thread-safe access to any shared data structures. Separate data sources are processed sequentially.
* thread-safe access to any shared data structures. Separate data sources are processed sequentially.
* <p>
* All OSM nodes are processed first, then ways, then relations.
*
@ -84,8 +83,7 @@ public interface Profile {
void processFeature(SourceFeature sourceFeature, FeatureCollector features);
/** Free any resources associated with this profile (i.e. shared data structures) */
default void release() {
}
default void release() {}
/**
* Apply any post-processing to features in an output layer of a tile before writing it to the output file
@ -101,8 +99,8 @@ public interface Profile {
* @param layer the output layer name
* @param zoom zoom level of the tile
* @param items all the output features in this layer in this tile
* @return the new list of output features or {@code null} to not change anything. Set any elements of the list to
* {@code null} if they should be ignored.
* @return the new list of output features or {@code null} to not change anything. Set any elements of the list to
* {@code null} if they should be ignored.
* @throws GeometryException for any recoverable geometric operation failures - the framework will log the error, emit
* the original input features, and continue processing other tiles
*/
@ -131,7 +129,7 @@ public interface Profile {
* Returns the attribution of the generated tileset to put into {@link Mbtiles} metadata
*
* @see <a href="https://www.openstreetmap.org/copyright">https://www.openstreetmap.org/copyright</a> for attribution
* requirements of any map using OpenStreetMap data
* requirements of any map using OpenStreetMap data
* @see <a href="https://github.com/mapbox/mbtiles-spec/blob/master/1.3/spec.md#metadata">MBTiles specification</a>
*/
default String attribution() {
@ -179,8 +177,7 @@ public interface Profile {
* @param next a consumer to pass finished map features to
*/
default void finish(String sourceName, FeatureCollector.Factory featureCollectors,
Consumer<FeatureCollector.Feature> next) {
}
Consumer<FeatureCollector.Feature> next) {}
/**
* Returns true if this profile will use any of the elements from an input source.
@ -224,8 +221,7 @@ public interface Profile {
class NullProfile implements Profile {
@Override
public void processFeature(SourceFeature sourceFeature, FeatureCollector features) {
}
public void processFeature(SourceFeature sourceFeature, FeatureCollector features) {}
@Override
public List<VectorTile.Feature> postProcessLayerFeatures(String layer, int zoom,

Wyświetl plik

@ -57,12 +57,12 @@ import vector_tile.VectorTileProto;
* Encodes a single output tile containing JTS {@link Geometry} features into the compact binary Mapbox Vector Tile
* format.
* <p>
* This class is copied from
* <a href="https://github.com/ElectronicChartCentre/java-vector-tile/blob/master/src/main/java/no/ecc/vectortile/VectorTileEncoder.java">VectorTileEncoder.java</a>
* and
* <a href="https://github.com/ElectronicChartCentre/java-vector-tile/blob/master/src/main/java/no/ecc/vectortile/VectorTileDecoder.java">VectorTileDecoder.java</a>
* This class is copied from <a href=
* "https://github.com/ElectronicChartCentre/java-vector-tile/blob/master/src/main/java/no/ecc/vectortile/VectorTileEncoder.java">VectorTileEncoder.java</a>
* and <a href=
* "https://github.com/ElectronicChartCentre/java-vector-tile/blob/master/src/main/java/no/ecc/vectortile/VectorTileDecoder.java">VectorTileDecoder.java</a>
* and modified to decouple geometry encoding from vector tile encoding so that encoded commands can be stored in the
* sorted feature map prior to encoding vector tiles. The internals are also refactored to improve performance by using
* sorted feature map prior to encoding vector tiles. The internals are also refactored to improve performance by using
* hppc primitive collections.
*
* @see <a href="https://github.com/mapbox/vector-tile-spec/tree/master/2.1">Mapbox Vector Tile Specification</a>
@ -389,8 +389,9 @@ public class VectorTile {
}
/**
* Encodes a JTS geometry according to <a href="https://github.com/mapbox/vector-tile-spec/tree/master/2.1#43-geometry-encoding">Geometry
* Encoding Specification</a>.
* Encodes a JTS geometry according to
* <a href="https://github.com/mapbox/vector-tile-spec/tree/master/2.1#43-geometry-encoding">Geometry Encoding
* Specification</a>.
*
* @param geometry the JTS geometry to encoded
* @return the geometry type and command array for the encoded geometry
@ -498,6 +499,7 @@ public class VectorTile {
MOVE_TO(1),
LINE_TO(2),
CLOSE_PATH(7);
final int value;
Command(int value) {
@ -506,8 +508,9 @@ public class VectorTile {
}
/**
* A vector tile encoded as a list of commands according to the <a href="https://github.com/mapbox/vector-tile-spec/tree/master/2.1#43-geometry-encoding">vector
* tile specification</a>.
* A vector tile encoded as a list of commands according to the
* <a href="https://github.com/mapbox/vector-tile-spec/tree/master/2.1#43-geometry-encoding">vector tile
* specification</a>.
* <p>
* To encode extra precision in intermediate feature geometries, the geometry contained in {@code commands} is scaled
* to a tile extent of {@code EXTENT * 2^scale}, so when the {@code scale == 0} the extent is {@link #EXTENT} and when
@ -635,7 +638,7 @@ public class VectorTile {
/**
* Encodes a geometry as a sequence of integers according to the
* <a href="https://github.com/mapbox/vector-tile-spec/tree/master/2.1#43-geometry-encoding">Geometry * Encoding
* <a href="https://github.com/mapbox/vector-tile-spec/tree/master/2.1#43-geometry-encoding">Geometry * Encoding
* Specification</a>.
*/
private static class CommandEncoder {

Wyświetl plik

@ -90,10 +90,8 @@ public final class FeatureGroup implements Consumer<SortableFeature>, Iterable<F
* value contains grouping information.
*/
static long encodeKey(int tile, byte layer, int sortKey, boolean hasGroup) {
return ((long) tile << 32L)
| ((long) (layer & 0xff) << 24L)
| (((sortKey - SORT_KEY_MIN) & SORT_KEY_MASK) << 1L)
| (hasGroup ? 1 : 0);
return ((long) tile << 32L) | ((long) (layer & 0xff) << 24L) | (((sortKey - SORT_KEY_MIN) & SORT_KEY_MASK) << 1L) |
(hasGroup ? 1 : 0);
}
static boolean extractHasGroupFromKey(long key) {

Wyświetl plik

@ -1,6 +1,5 @@
package com.onthegomap.planetiler.collection;
import com.carrotsearch.hppc.IntObjectHashMap;
import com.carrotsearch.hppc.LongByteHashMap;
import com.carrotsearch.hppc.LongByteMap;

Wyświetl plik

@ -99,8 +99,7 @@ public interface LongLongMap extends Closeable, MemoryEstimator.HasEstimate, Dis
static LongLongMap noop() {
return new LongLongMap() {
@Override
public void put(long key, long value) {
}
public void put(long key, long value) {}
@Override
public long get(long key) {
@ -113,8 +112,7 @@ public interface LongLongMap extends Closeable, MemoryEstimator.HasEstimate, Dis
}
@Override
public void close() {
}
public void close() {}
};
}

Wyświetl plik

@ -97,10 +97,10 @@ public class Arguments {
* <p>
* Priority order:
* <ol>
* <li>command-line arguments: {@code java ... key=value}</li>
* <li>jvm properties: {@code java -Dplanetiler.key=value ...}</li>
* <li>environmental variables: {@code PLANETILER_KEY=value java ...}</li>
* <li>in a config file from "config" argument from any of the above</li>
* <li>command-line arguments: {@code java ... key=value}</li>
* <li>jvm properties: {@code java -Dplanetiler.key=value ...}</li>
* <li>environmental variables: {@code PLANETILER_KEY=value java ...}</li>
* <li>in a config file from "config" argument from any of the above</li>
* </ol>
*
* @param args command-line args provide to main entrypoint method
@ -253,8 +253,8 @@ public class Arguments {
/**
* Returns a {@link Stats} implementation based on the arguments provided.
* <p>
* If {@code pushgateway} is set then it uses a stats implementation that pushes to prometheus through a <a
* href="https://github.com/prometheus/pushgateway">push gateway</a> every {@code pushgateway.interval} seconds.
* If {@code pushgateway} is set then it uses a stats implementation that pushes to prometheus through a
* <a href="https://github.com/prometheus/pushgateway">push gateway</a> every {@code pushgateway.interval} seconds.
* Otherwise, uses an in-memory stats implementation.
*/
public Stats getStats() {

Wyświetl plik

@ -17,9 +17,12 @@ import java.util.stream.Stream;
* <p>
* Calling {@code toString()} on any expression will generate code that can be used to recreate an identical copy of the
* original expression, assuming that the generated code includes:
* <pre>{@code
*
* <pre>
* {@code
* import static com.onthegomap.planetiler.expression.Expression.*;
* }</pre>
* }
* </pre>
*/
public interface Expression {
@ -99,10 +102,10 @@ public interface Expression {
* <p>
* Allowed values:
* <ul>
* <li>"linestring"</li>
* <li>"point"</li>
* <li>"polygon"</li>
* <li>"relation_member"</li>
* <li>"linestring"</li>
* <li>"point"</li>
* <li>"polygon"</li>
* <li>"relation_member"</li>
* </ul>
*/
static MatchType matchType(String type) {
@ -190,7 +193,9 @@ public interface Expression {
return replace(a::equals, b);
}
/** Returns a copy of this expression where every nested instance matching {@code replace} is replaced with {@code b}. */
/**
* Returns a copy of this expression where every nested instance matching {@code replace} is replaced with {@code b}.
*/
default Expression replace(Predicate<Expression> replace, Expression b) {
if (replace.test(this)) {
return b;

Wyświetl plik

@ -29,7 +29,7 @@ import java.util.function.Predicate;
*
* @param <T> type of data value associated with each expression
*/
public record MultiExpression<T>(List<Entry<T>> expressions) {
public record MultiExpression<T> (List<Entry<T>> expressions) {
public static <T> MultiExpression<T> of(List<Entry<T>> expressions) {
return new MultiExpression<>(expressions);
@ -94,8 +94,8 @@ public record MultiExpression<T>(List<Entry<T>> expressions) {
if (expressions.isEmpty()) {
return new EmptyIndex<>();
}
boolean caresAboutGeometryType = expressions.stream().anyMatch(entry ->
entry.expression.contains(exp -> exp instanceof Expression.MatchType));
boolean caresAboutGeometryType =
expressions.stream().anyMatch(entry -> entry.expression.contains(exp -> exp instanceof Expression.MatchType));
return caresAboutGeometryType ? new GeometryTypeIndex<>(this) : new KeyIndex<>(this);
}
@ -308,13 +308,13 @@ public record MultiExpression<T>(List<Entry<T>> expressions) {
}
/** An expression/value pair with unique ID to store whether we evaluated it yet. */
private record EntryWithId<T>(T result, Expression expression, int id) {}
private record EntryWithId<T> (T result, Expression expression, int id) {}
/**
* An {@code expression} to evaluate on input elements and {@code result} value to return when the element matches.
*/
public record Entry<T>(T result, Expression expression) {}
public record Entry<T> (T result, Expression expression) {}
/** The result when an expression matches, along with the input element tag {@code keys} that triggered the match. */
public record Match<T>(T match, List<String> keys) {}
public record Match<T> (T match, List<String> keys) {}
}

Wyświetl plik

@ -22,7 +22,8 @@ import org.locationtech.jts.geom.util.GeometryTransformer;
* A utility to simplify geometries using Douglas Peucker simplification algorithm without any attempt to repair
* geometries that become invalid due to simplification.
* <p>
* This class is adapted from <a href="https://github.com/locationtech/jts/blob/master/modules/core/src/main/java/org/locationtech/jts/simplify/DouglasPeuckerSimplifier.java">org.locationtech.jts.simplify.DouglasPeuckerSimplifier</a>
* This class is adapted from <a href=
* "https://github.com/locationtech/jts/blob/master/modules/core/src/main/java/org/locationtech/jts/simplify/DouglasPeuckerSimplifier.java">org.locationtech.jts.simplify.DouglasPeuckerSimplifier</a>
* with modifications to avoid collapsing small polygons since the subsequent area filter will remove them more
* accurately and performance improvement to put the results in a {@link MutableCoordinateSequence} which uses a
* primitive double array instead of allocating lots of {@link Coordinate} objects.
@ -148,4 +149,3 @@ public class DouglasPeuckerSimplifier {
}
}
}

Wyświetl plik

@ -90,12 +90,13 @@ public class GeoUtils {
* right is (1,1).
*/
public static final Envelope WORLD_BOUNDS = new Envelope(0, 1, 0, 1);
/** Bounds for the entire area of the planet that a web mercator projection covers in latitude/longitude coordinates. */
/**
* Bounds for the entire area of the planet that a web mercator projection covers in latitude/longitude coordinates.
*/
public static final Envelope WORLD_LAT_LON_BOUNDS = toLatLonBoundsBounds(WORLD_BOUNDS);
// should not instantiate
private GeoUtils() {
}
private GeoUtils() {}
/**
* Returns a copy of {@code geom} transformed from latitude/longitude coordinates to web mercator where top-left
@ -191,16 +192,16 @@ public class GeoUtils {
}
/**
* Returns the web mercator Y coordinate of the latitude/longitude encoded with {@link #encodeFlatLocation(double,
* double)}.
* Returns the web mercator Y coordinate of the latitude/longitude encoded with
* {@link #encodeFlatLocation(double, double)}.
*/
public static double decodeWorldY(long encoded) {
return (((double) (encoded & LOWER_32_BIT_MASK)) / HALF_QUANTIZED_WORLD_SIZE) - 1;
}
/**
* Returns the web mercator X coordinate of the latitude/longitude encoded with {@link #encodeFlatLocation(double,
* double)}.
* Returns the web mercator X coordinate of the latitude/longitude encoded with
* {@link #encodeFlatLocation(double, double)}.
*/
public static double decodeWorldX(long encoded) {
return (((double) (encoded >>> 32)) / HALF_QUANTIZED_WORLD_SIZE) - 1;

Wyświetl plik

@ -21,10 +21,8 @@ public enum GeometryType {
}
public static GeometryType valueOf(Geometry geom) {
return geom instanceof Puntal ? POINT
: geom instanceof Lineal ? LINE
: geom instanceof Polygonal ? POLYGON
: UNKNOWN;
return geom instanceof Puntal ? POINT : geom instanceof Lineal ? LINE : geom instanceof Polygonal ? POLYGON :
UNKNOWN;
}
public static GeometryType valueOf(VectorTileProto.Tile.GeomType geomType) {

Wyświetl plik

@ -21,12 +21,11 @@ import org.locationtech.jts.index.strtree.STRtree;
@ThreadSafe
public class PointIndex<T> {
private record GeomWithData<T>(Coordinate coord, T data) {}
private record GeomWithData<T> (Coordinate coord, T data) {}
private final STRtree index = new STRtree();
private PointIndex() {
}
private PointIndex() {}
public static <T> PointIndex<T> create() {
return new PointIndex<>();

Wyświetl plik

@ -19,12 +19,11 @@ import org.locationtech.jts.index.strtree.STRtree;
@ThreadSafe
public class PolygonIndex<T> {
private record GeomWithData<T>(Polygon poly, T data) {}
private record GeomWithData<T> (Polygon poly, T data) {}
private final STRtree index = new STRtree();
private PolygonIndex() {
}
private PolygonIndex() {}
public static <T> PolygonIndex<T> create() {
return new PolygonIndex<>();
@ -78,7 +77,7 @@ public class PolygonIndex<T> {
List<?> items = index.query(point.getEnvelopeInternal());
// optimization: if there's only one then skip checking contains/distance
if (items.size() == 1) {
if (items.get(0) instanceof GeomWithData<?> value) {
if (items.get(0)instanceof GeomWithData<?> value) {
@SuppressWarnings("unchecked") T t = (T) value.data;
return List.of(t);
}

Wyświetl plik

@ -38,8 +38,7 @@ import org.sqlite.SQLiteConfig;
/**
* Interface into an mbtiles sqlite file containing tiles and metadata about the tileset.
*
* @see <a href="https://github.com/mapbox/mbtiles-spec/blob/master/1.3/spec.md">MBTiles
* Specification</a>
* @see <a href="https://github.com/mapbox/mbtiles-spec/blob/master/1.3/spec.md">MBTiles Specification</a>
*/
public final class Mbtiles implements Closeable {
@ -157,8 +156,8 @@ public final class Mbtiles implements Closeable {
return execute(
"create table " + METADATA_TABLE + " (" + METADATA_COL_NAME + " text, " + METADATA_COL_VALUE + " text);",
"create unique index name on " + METADATA_TABLE + " (" + METADATA_COL_NAME + ");",
"create table " + TILES_TABLE + " (" + TILES_COL_Z + " integer, " + TILES_COL_X + " integer, " + TILES_COL_Y
+ ", " + TILES_COL_DATA + " blob);"
"create table " + TILES_TABLE + " (" + TILES_COL_Z + " integer, " + TILES_COL_X + " integer, " + TILES_COL_Y +
", " + TILES_COL_DATA + " blob);"
);
}
@ -237,11 +236,10 @@ public final class Mbtiles implements Closeable {
* Data contained in the {@code json} row of the metadata table
*
* @see <a href="https://github.com/mapbox/mbtiles-spec/blob/master/1.3/spec.md#vector-tileset-metadata">MBtiles
* schema</a>
* schema</a>
*/
public record MetadataJson(
@JsonProperty("vector_layers")
List<VectorLayer> vectorLayers
@JsonProperty("vector_layers") List<VectorLayer> vectorLayers
) {
public MetadataJson(VectorLayer... layers) {
@ -265,9 +263,12 @@ public final class Mbtiles implements Closeable {
}
public enum FieldType {
@JsonProperty("Number") NUMBER,
@JsonProperty("Boolean") BOOLEAN,
@JsonProperty("String") STRING;
@JsonProperty("Number")
NUMBER,
@JsonProperty("Boolean")
BOOLEAN,
@JsonProperty("String")
STRING;
/**
* Per the spec: attributes whose type varies between features SHOULD be listed as "String"
@ -352,7 +353,9 @@ public final class Mbtiles implements Closeable {
}
}
/** A high-throughput writer that accepts new tiles and queues up the writes to execute them in fewer large-batches. */
/**
* A high-throughput writer that accepts new tiles and queues up the writes to execute them in fewer large-batches.
*/
public class BatchedTileWriter implements AutoCloseable {
// max number of parameters in a prepared statements is 999
@ -374,9 +377,8 @@ public final class Mbtiles implements Closeable {
}
try {
return connection.prepareStatement(
"INSERT INTO " + TILES_TABLE + " (" + TILES_COL_Z + "," + TILES_COL_X + "," + TILES_COL_Y + ","
+ TILES_COL_DATA
+ ") VALUES " + String.join(", ", groups) + ";");
"INSERT INTO " + TILES_TABLE + " (" + TILES_COL_Z + "," + TILES_COL_X + "," + TILES_COL_Y + "," +
TILES_COL_DATA + ") VALUES " + String.join(", ", groups) + ";");
} catch (SQLException throwables) {
throw new IllegalStateException("Could not create prepared statement", throwables);
}
@ -443,8 +445,10 @@ public final class Mbtiles implements Closeable {
public Metadata setMetadata(String name, Object value) {
if (value != null) {
LOGGER.debug("Set mbtiles metadata: " + name + "=" + value);
try (PreparedStatement statement = connection.prepareStatement(
"INSERT INTO " + METADATA_TABLE + " (" + METADATA_COL_NAME + "," + METADATA_COL_VALUE + ") VALUES(?, ?);")) {
try (
PreparedStatement statement = connection.prepareStatement(
"INSERT INTO " + METADATA_TABLE + " (" + METADATA_COL_NAME + "," + METADATA_COL_VALUE + ") VALUES(?, ?);")
) {
statement.setString(1, name);
statement.setString(2, value.toString());
statement.execute();

Wyświetl plik

@ -99,10 +99,10 @@ public class Verify {
/**
* Returns a verification result of a basic set of checks on an mbtiles file:
* <ul>
* <li>has a metadata and tiles table</li>
* <li>has a name metadata attribute</li>
* <li>has at least one tile</li>
* <li>all vector tile geometries are valid</li>
* <li>has a metadata and tiles table</li>
* <li>has a name metadata attribute</li>
* <li>has at least one tile</li>
* <li>all vector tile geometries are valid</li>
* </ul>
*/
public static Verify verify(Mbtiles mbtiles) {

Wyświetl plik

@ -29,8 +29,9 @@ import org.opengis.referencing.operation.MathTransform;
* <p>
* Shapefile processing handled by geotools {@link ShapefileDataStore}.
*
* @see <a href="https://www.esri.com/content/dam/esrisites/sitecore-archive/Files/Pdfs/library/whitepapers/pdfs/shapefile.pdf">ESRI
* Shapefile Specification</a>
* @see <a href=
* "https://www.esri.com/content/dam/esrisites/sitecore-archive/Files/Pdfs/library/whitepapers/pdfs/shapefile.pdf">ESRI
* Shapefile Specification</a>
*/
public class ShapefileReader extends SimpleReader implements Closeable {
@ -72,8 +73,8 @@ public class ShapefileReader extends SimpleReader implements Closeable {
* Renders map features for all elements from an ESRI Shapefile based on the mapping logic defined in {@code profile}.
* Overrides the coordinate reference system defined in the shapefile.
*
* @param sourceProjection code for the coordinate reference system of the input data, to be parsed by {@link
* CRS#decode(String)}
* @param sourceProjection code for the coordinate reference system of the input data, to be parsed by
* {@link CRS#decode(String)}
* @param sourceName string ID for this reader to use in logs and stats
* @param input path to the {@code .shp} file on disk, or a {@code .zip} file containing the shapefile
* components
@ -95,8 +96,7 @@ public class ShapefileReader extends SimpleReader implements Closeable {
* Infers the coordinate reference system from the shapefile.
*
* @param sourceName string ID for this reader to use in logs and stats
* @param input path to the {@code .shp} file on disk, or a {@code .zip} file containing the shapefile
* components
* @param input path to the {@code .shp} file on disk, or a {@code .zip} file containing the shapefile components
* @param writer consumer for rendered features
* @param config user-defined parameters controlling number of threads and log interval
* @param profile logic that defines what map features to emit for each source feature

Wyświetl plik

@ -83,14 +83,14 @@ public class SimpleFeature extends SourceFeature {
return new SimpleFeature(latLonGeometry, null, tags, source, sourceLayer, id, relations) {
@Override
public boolean canBePolygon() {
return latLonGeometry instanceof Polygonal || (latLonGeometry instanceof LineString line
&& OsmReader.canBePolygon(line.isClosed(), area, latLonGeometry.getNumPoints()));
return latLonGeometry instanceof Polygonal || (latLonGeometry instanceof LineString line &&
OsmReader.canBePolygon(line.isClosed(), area, latLonGeometry.getNumPoints()));
}
@Override
public boolean canBeLine() {
return latLonGeometry instanceof MultiLineString || (latLonGeometry instanceof LineString line
&& OsmReader.canBeLine(line.isClosed(), area, latLonGeometry.getNumPoints()));
return latLonGeometry instanceof MultiLineString || (latLonGeometry instanceof LineString line &&
OsmReader.canBeLine(line.isClosed(), area, latLonGeometry.getNumPoints()));
}
@Override
@ -103,15 +103,14 @@ public class SimpleFeature extends SourceFeature {
@Override
public Geometry latLonGeometry() {
return latLonGeometry != null ? latLonGeometry
: (latLonGeometry = GeoUtils.worldToLatLonCoords(worldGeometry));
return latLonGeometry != null ? latLonGeometry : (latLonGeometry = GeoUtils.worldToLatLonCoords(worldGeometry));
}
@Override
public Geometry worldGeometry() {
// we expect outer polygons to appear before inner ones, so process ones with larger areas first
return worldGeometry != null ? worldGeometry
: (worldGeometry = GeoUtils.sortPolygonsByAreaDescending(GeoUtils.latLonToWorldCoords(latLonGeometry)));
return worldGeometry != null ? worldGeometry :
(worldGeometry = GeoUtils.sortPolygonsByAreaDescending(GeoUtils.latLonToWorldCoords(latLonGeometry)));
}
@Override

Wyświetl plik

@ -19,11 +19,11 @@ import org.locationtech.jts.geom.Polygon;
/**
* Base class for input features read from a data source.
* <p>
* Provides cached convenience methods with lazy initialization for geometric attributes derived from {@link
* #latLonGeometry()} and {@link #worldGeometry()} to avoid computing them if not needed, and recomputing them if needed
* by multiple features.
* Provides cached convenience methods with lazy initialization for geometric attributes derived from
* {@link #latLonGeometry()} and {@link #worldGeometry()} to avoid computing them if not needed, and recomputing them if
* needed by multiple features.
* <p>
* All geometries except for {@link #latLonGeometry()} return elements in world web mercator coordinates where (0,0) is
* All geometries except for {@link #latLonGeometry()} return elements in world web mercator coordinates where (0,0) is
* the northwest corner and (1,1) is the southeast corner of the planet.
*/
public abstract class SourceFeature implements WithTags {
@ -46,7 +46,7 @@ public abstract class SourceFeature implements WithTags {
* Constructs a new input feature.
*
* @param tags string key/value pairs associated with this element
* @param source source name that profile can use to distinguish between elements from different data sources
* @param source source name that profile can use to distinguish between elements from different data sources
* @param sourceLayer layer name within {@code source} that profile can use to distinguish between different kinds
* of elements in a given source.
* @param relationInfos relations that this element is contained within
@ -116,7 +116,7 @@ public abstract class SourceFeature implements WithTags {
return centroid != null ? centroid : (centroid =
canBePolygon() ? polygon().getCentroid() :
canBeLine() ? line().getCentroid() :
worldGeometry().getCentroid());
worldGeometry().getCentroid());
}
/** Returns and caches {@link Geometry#getInteriorPoint()} of this geometry in world web mercator coordinates. */
@ -124,13 +124,13 @@ public abstract class SourceFeature implements WithTags {
return pointOnSurface != null ? pointOnSurface : (pointOnSurface =
canBePolygon() ? polygon().getInteriorPoint() :
canBeLine() ? line().getInteriorPoint() :
worldGeometry().getInteriorPoint());
worldGeometry().getInteriorPoint());
}
private Geometry computeCentroidIfConvex() throws GeometryException {
if (!canBePolygon()) {
return centroid();
} else if (polygon() instanceof Polygon poly &&
} else if (polygon()instanceof Polygon poly &&
poly.getNumInteriorRing() == 0 &&
GeoUtils.isConvex(poly.getExteriorRing())) {
return centroid();
@ -216,7 +216,7 @@ public abstract class SourceFeature implements WithTags {
/**
* Returns this feature as a valid {@link Polygon} or {@link MultiPolygon} in world web mercator coordinates.
* <p>
* Validating and fixing invalid polygons can be expensive, so use only if necessary. Invalid polygons will also be
* Validating and fixing invalid polygons can be expensive, so use only if necessary. Invalid polygons will also be
* fixed at render-time.
*
* @throws GeometryException if an error occurs constructing the geometry, or of this feature should not be
@ -283,7 +283,7 @@ public abstract class SourceFeature implements WithTags {
* @param relationInfoClass class of the processed relation data
* @param <T> type of {@code relationInfoClass}
* @return A list containing the OSM relation info along with the role that this element is tagged with in that
* relation
* relation
*/
// TODO this should be in a specialized OSM subclass, not the generic superclass
public <T extends OsmRelationInfo> List<OsmReader.RelationMember<T>> relationInfo(
@ -295,8 +295,7 @@ public abstract class SourceFeature implements WithTags {
if (result == null) {
result = new ArrayList<>();
}
@SuppressWarnings("unchecked")
OsmReader.RelationMember<T> casted = (OsmReader.RelationMember<T>) info;
@SuppressWarnings("unchecked") OsmReader.RelationMember<T> casted = (OsmReader.RelationMember<T>) info;
result.add(casted);
}
}

Wyświetl plik

@ -13,12 +13,11 @@ public interface OsmBlockSource extends Closeable {
void forEachBlock(Consumer<Block> consumer);
@Override
default void close() {
}
default void close() {}
/**
* An individual block of raw bytes from an osm.pbf file that can be decompressed/parsed with {@link
* #decodeElements()}.
* An individual block of raw bytes from an osm.pbf file that can be decompressed/parsed with
* {@link #decodeElements()}.
*/
interface Block {

Wyświetl plik

@ -23,7 +23,9 @@ public interface OsmElement extends WithTags {
int cost();
enum Type {
NODE, WAY, RELATION
NODE,
WAY,
RELATION
}
/** An un-handled element read from the .osm.pbf file (i.e. file header). */
@ -165,7 +167,9 @@ public interface OsmElement extends WithTags {
return 1 + tags.size() + members.size() * 3;
}
/** A node, way, or relation contained in a relation with an optional "role" to clarify the purpose of each member. */
/**
* A node, way, or relation contained in a relation with an optional "role" to clarify the purpose of each member.
*/
public record Member(
Type type,
long ref,

Wyświetl plik

@ -162,15 +162,15 @@ public class OsmReader implements Closeable, MemoryEstimator.HasEstimate {
node.encodedLocation();
if (nodesDone) {
throw new IllegalArgumentException(
"Input file must be sorted with nodes first, then ways, then relations. Encountered node " + node.id()
+ " after a way or relation");
"Input file must be sorted with nodes first, then ways, then relations. Encountered node " + node.id() +
" after a way or relation");
}
} else if (element instanceof OsmElement.Way way) {
nodesDone = true;
if (waysDone) {
throw new IllegalArgumentException(
"Input file must be sorted with nodes first, then ways, then relations. Encountered way " + way.id()
+ " after a relation");
"Input file must be sorted with nodes first, then ways, then relations. Encountered way " + way.id() +
" after a relation");
}
} else if (element instanceof OsmElement.Relation) {
nodesDone = waysDone = true;
@ -519,7 +519,7 @@ public class OsmReader implements Closeable, MemoryEstimator.HasEstimate {
* @param role "role" of the relation member
* @param relation user-provided data about the relation from pass1
*/
public record RelationMember<T extends OsmRelationInfo>(String role, T relation) {}
public record RelationMember<T extends OsmRelationInfo> (String role, T relation) {}
/** Raw relation membership data that gets encoded/decoded into a long. */
private record RelationMembership(String role, long relationId) {}

Wyświetl plik

@ -11,7 +11,7 @@ import org.openstreetmap.osmosis.osmbinary.Osmformat;
* This class is copied from Osmosis.
*
* @author Brett Henderson
* <p>
* <p>
*/
public class PbfFieldDecoder {

Wyświetl plik

@ -71,8 +71,8 @@ public class FeatureRenderer implements Consumer<FeatureCollector.Feature> {
renderPoint(feature, point.getCoordinates());
} else if (geom instanceof MultiPoint points) {
renderPoint(feature, points);
} else if (geom instanceof Polygon || geom instanceof MultiPolygon || geom instanceof LineString
|| geom instanceof MultiLineString) {
} else if (geom instanceof Polygon || geom instanceof MultiPolygon || geom instanceof LineString ||
geom instanceof MultiLineString) {
renderLineOrPolygon(feature, geom);
} else if (geom instanceof GeometryCollection collection) {
for (int i = 0; i < collection.getNumGeometries(); i++) {

Wyświetl plik

@ -22,9 +22,9 @@ import org.locationtech.jts.geom.Polygon;
* <p>
* The {@code List<List<CoordinateSequence>>} format is:
* <ul>
* <li>For linestrings: {@code [[linestring], [linestring], ...]}</li> for each linestring in the collection
* <li>For polygons: {@code [[outer ring, inner ring, inner ring], [outer ring, inner ring, ...], ...]}</li> for each
* polygon in the multipolygon
* <li>For linestrings: {@code [[linestring], [linestring], ...]}</li> for each linestring in the collection
* <li>For polygons: {@code [[outer ring, inner ring, inner ring], [outer ring, inner ring, ...], ...]}</li> for each
* polygon in the multipolygon
* </ul>
*/
class GeometryCoordinateSequences {
@ -36,14 +36,13 @@ class GeometryCoordinateSequences {
* For {@link LineString LineStrings} that means all linestrings over a certain length.
* <p>
* For {@link Polygon Polygons} that means all lists of [exterior, interior...] ring coordinate sequences where the
* ring is over a certain area. This utility also ensures that exterior and interior rings use counter-clockwise
* ring is over a certain area. This utility also ensures that exterior and interior rings use counter-clockwise
* winding.
*
* @param geom one or more linestings or polygons
* @param minSize minimum length of linestrings, or minimum area of exterior/interior rings to include
* @return the coordinate sequences of the geometry
* @throws IllegalArgumentException if {@code geom} contains anything other than linestrings or polygons (i.e.
* points)
* @throws IllegalArgumentException if {@code geom} contains anything other than linestrings or polygons (i.e. points)
*/
static List<List<CoordinateSequence>> extractGroups(Geometry geom, double minSize) {
List<List<CoordinateSequence>> result = new ArrayList<>();

Wyświetl plik

@ -200,7 +200,9 @@ class TiledGeometry {
out.addPoint(x, ay + (by - ay) * t);
}
/** Adds a new point to {@code out} where the line segment from (ax,ay) to (bx,by) crosses a horizontal line at y=y. */
/**
* Adds a new point to {@code out} where the line segment from (ax,ay) to (bx,by) crosses a horizontal line at y=y.
*/
private static void intersectY(MutableCoordinateSequence out, double ax, double ay, double bx, double by, double y) {
double t = (y - ay) / (by - ay);
out.addPoint(ax + (bx - ax) * t, y);
@ -221,15 +223,15 @@ class TiledGeometry {
/**
* Slices a geometry into tiles and stores in member fields for a single "copy" of the world.
* <p>
* Instead of handling content outside -180 to 180 degrees longitude, return {@link Direction#LEFT} or {@link
* Direction#RIGHT} to indicate whether this method should be called again with a different {@code xOffset} to process
* wrapped content.
* Instead of handling content outside -180 to 180 degrees longitude, return {@link Direction#LEFT} or
* {@link Direction#RIGHT} to indicate whether this method should be called again with a different {@code xOffset} to
* process wrapped content.
*
* @param groups the geometry
* @param xOffset offset to apply to each X coordinate (-2^z handles content that wraps too far east and 2^z handles
* content that wraps too far west)
* @return {@link Direction#LEFT} if there is more content to the west and {@link Direction#RIGHT} if there is more
* content to the east.
* content to the east.
*/
private EnumSet<Direction> sliceWorldCopy(List<List<CoordinateSequence>> groups, int xOffset) {
EnumSet<Direction> overflow = EnumSet.noneOf(Direction.class);
@ -603,5 +605,8 @@ class TiledGeometry {
}
}
private enum Direction {RIGHT, LEFT}
private enum Direction {
RIGHT,
LEFT
}
}

Wyświetl plik

@ -51,8 +51,7 @@ public interface Counter {
*/
class SingleThreadCounter implements Readable {
private SingleThreadCounter() {
}
private SingleThreadCounter() {}
private final AtomicLong counter = new AtomicLong(0);
@ -75,8 +74,7 @@ public interface Counter {
*/
class MultiThreadCounter implements Readable {
private MultiThreadCounter() {
}
private MultiThreadCounter() {}
// keep track of all counters that have been handed out to threads so far
// and on read, add up the counts from each

Wyświetl plik

@ -37,7 +37,7 @@ public class ProcessInfo {
for (GarbageCollectorMXBean garbageCollectorMXBean : ManagementFactory.getGarbageCollectorMXBeans()) {
if (garbageCollectorMXBean instanceof NotificationEmitter emitter) {
emitter.addNotificationListener((notification, handback) -> {
if (notification.getUserData() instanceof CompositeData compositeData) {
if (notification.getUserData()instanceof CompositeData compositeData) {
var info = GarbageCollectionNotificationInfo.from(compositeData);
GcInfo gcInfo = info.getGcInfo();
postGcMemoryUsage.set(gcInfo.getMemoryUsageAfterGc().entrySet().stream()

Wyświetl plik

@ -9,12 +9,15 @@ import java.util.Optional;
* A utility for measuring the wall and CPU time that this JVM consumes between snapshots.
* <p>
* For example:
* <pre>{@code
*
* <pre>
* {@code
* var start = ProcessTime.now();
* // do expensive work...
* var end - ProcessTime.now();
* LOGGER.log("Expensive work took " + end.minus(start));
* }</pre>
* }
* </pre>
*/
public record ProcessTime(Duration wall, Optional<Duration> cpu, Duration gc) {

Wyświetl plik

@ -166,8 +166,8 @@ public class ProgressLoggers {
last.set(valueNow);
lastTime.set(now);
String result =
"[ " + formatter.apply(valueNow) + " " + padLeft(format.percent(1f * valueNow / total), 4)
+ " " + formatter.apply(valueDiff / timeDiff) + "/s ]";
"[ " + formatter.apply(valueNow) + " " + padLeft(format.percent(1f * valueNow / total), 4) + " " +
formatter.apply(valueDiff / timeDiff) + "/s ]";
return (color && valueDiff > 0) ? green(result) : result;
}));
return this;
@ -188,12 +188,9 @@ public class ProgressLoggers {
/** Adds the current number of items in a queue and the queue's size to the output. */
public ProgressLoggers addQueueStats(WorkQueue<?> queue) {
loggers.add(new WorkerPipelineLogger(() ->
" -> " + padLeft("(" +
format.numeric(queue.getPending(), false)
+ "/" +
format.numeric(queue.getCapacity(), false)
+ ")", 9)
loggers.add(new WorkerPipelineLogger(() -> " -> " + padLeft("(" +
format.numeric(queue.getPending(), false) + "/" +
format.numeric(queue.getCapacity(), false) + ")", 9)
));
return this;
}

Wyświetl plik

@ -271,8 +271,8 @@ class PrometheusStats implements Stats {
}
/**
* Reports stats on all in-memory objects sizes being monitored through {@link #monitorInMemoryObject(String,
* MemoryEstimator.HasEstimate)}.
* Reports stats on all in-memory objects sizes being monitored through
* {@link #monitorInMemoryObject(String, MemoryEstimator.HasEstimate)}.
*/
private class HeapObjectSizeCollector extends Collector {

Wyświetl plik

@ -17,9 +17,9 @@ import org.slf4j.LoggerFactory;
/**
* A utility that collects and reports more detailed statistics about the JVM and running tasks than logs can convey.
* <p>
* {@link #inMemory()} stores basic stats in-memory to report at the end of the job and {@link
* #prometheusPushGateway(String, String, Duration)} pushes stats at a regular interval to a <a
* href="https://github.com/prometheus/pushgateway">prometheus push gateway</a>.
* {@link #inMemory()} stores basic stats in-memory to report at the end of the job and
* {@link #prometheusPushGateway(String, String, Duration)} pushes stats at a regular interval to a
* <a href="https://github.com/prometheus/pushgateway">prometheus push gateway</a>.
*/
public interface Stats extends AutoCloseable {
@ -29,8 +29,8 @@ public interface Stats extends AutoCloseable {
}
/**
* Returns a new stat collector pushes stats at a regular interval to a <a href="https://github.com/prometheus/pushgateway">prometheus
* push gateway</a> at {@code destination}.
* Returns a new stat collector pushes stats at a regular interval to a
* <a href="https://github.com/prometheus/pushgateway">prometheus push gateway</a> at {@code destination}.
*/
static Stats prometheusPushGateway(String destination, String job, Duration interval) {
return PrometheusStats.createAndStartPushing(destination, job, interval);
@ -43,7 +43,7 @@ public interface Stats extends AutoCloseable {
default void printSummary() {
Format format = Format.defaultInstance();
Logger LOGGER = LoggerFactory.getLogger(getClass());
System.out.println();
LOGGER.info("");
LOGGER.info("-".repeat(40));
timers().printSummary();
LOGGER.info("-".repeat(40));
@ -145,15 +145,13 @@ public interface Stats extends AutoCloseable {
class InMemory implements Stats {
/** use {@link #inMemory()} */
private InMemory() {
}
private InMemory() {}
private final Timers timers = new Timers();
private final Map<String, Path> monitoredFiles = new ConcurrentSkipListMap<>();
@Override
public void wroteTile(int zoom, int bytes) {
}
public void wroteTile(int zoom, int bytes) {}
@Override
public Timers timers() {
@ -166,12 +164,10 @@ public interface Stats extends AutoCloseable {
}
@Override
public void monitorInMemoryObject(String name, MemoryEstimator.HasEstimate object) {
}
public void monitorInMemoryObject(String name, MemoryEstimator.HasEstimate object) {}
@Override
public void counter(String name, Supplier<Number> supplier) {
}
public void counter(String name, Supplier<Number> supplier) {}
@Override
public Counter.MultiThreadCounter longCounter(String name) {
@ -184,24 +180,19 @@ public interface Stats extends AutoCloseable {
}
@Override
public void counter(String name, String label, Supplier<Map<String, Counter.Readable>> values) {
}
public void counter(String name, String label, Supplier<Map<String, Counter.Readable>> values) {}
@Override
public void processedElement(String elemType, String layer) {
}
public void processedElement(String elemType, String layer) {}
@Override
public void dataError(String errorCode) {
}
public void dataError(String errorCode) {}
@Override
public void gauge(String name, Supplier<Number> value) {
}
public void gauge(String name, Supplier<Number> value) {}
@Override
public void emittedFeatures(int z, String layer, int numFeatures) {
}
public void emittedFeatures(int z, String layer, int numFeatures) {}
@Override
public void close() {

Wyświetl plik

@ -95,7 +95,7 @@ public class Timers {
Stage stage = new Stage(timer);
timers.put(name, stage);
Stage last = currentStage.getAndSet(stage);
System.out.println();
LOGGER.info("");
LOGGER.info("Starting...");
return () -> {
LOGGER.info("Finished in " + timers.get(name).timer.stop());

Wyświetl plik

@ -77,13 +77,11 @@ public class AwsOsm {
@JsonIgnoreProperties(ignoreUnknown = true)
record IndexXml(
@JacksonXmlProperty(localName = "Contents")
@JacksonXmlElementWrapper(useWrapping = false)
List<ContentXml> contents
@JacksonXmlElementWrapper(useWrapping = false) List<ContentXml> contents
) {}
@JsonIgnoreProperties(ignoreUnknown = true)
record ContentXml(
@JacksonXmlProperty(localName = "Key")
String key
@JacksonXmlProperty(localName = "Key") String key
) {}
}

Wyświetl plik

@ -46,20 +46,23 @@ import org.slf4j.LoggerFactory;
* changes.
* <p>
* For example:
* <pre>{@code
*
* <pre>
* {@code
* Downloader.create(PlanetilerConfig.defaults())
* .add("natural_earth", "http://url/of/natural_earth.zip", Path.of("natural_earth.zip"))
* .add("osm", "http://url/of/file.osm.pbf", Path.of("file.osm.pbf"))
* .run();
* }</pre>
* }
* </pre>
* <p>
* As a shortcut to find the URL of a file to download from the <a href="https://download.geofabrik.de/">Geofabrik
* download site</a>, you can use "geofabrik:extract name" (i.e. "geofabrik:monaco" or "geofabrik:australia") to look up
* a {@code .osm.pbf} download URL in the <a href="https://download.geofabrik.de/technical.html">Geofabrik JSON
* index</a>.
* <p>
* You can also use "aws:latest" to download the latest {@code planet.osm.pbf} file from the <a
* href="https://registry.opendata.aws/osm/">AWS Open Data Registry</a>.
* You can also use "aws:latest" to download the latest {@code planet.osm.pbf} file from the
* <a href="https://registry.opendata.aws/osm/">AWS Open Data Registry</a>.
*/
@SuppressWarnings("UnusedReturnValue")
public class Downloader {
@ -198,9 +201,8 @@ public class Downloader {
LOGGER.info("Skipping " + resourceToDownload.id + ": " + resourceToDownload.output + " already up-to-date");
return CompletableFuture.completedFuture(null);
} else {
String redirectInfo = metadata.canonicalUrl.equals(resourceToDownload.url)
? ""
: " (redirected to " + metadata.canonicalUrl + ")";
String redirectInfo = metadata.canonicalUrl.equals(resourceToDownload.url) ? "" :
" (redirected to " + metadata.canonicalUrl + ")";
LOGGER.info("Downloading " + resourceToDownload.url + redirectInfo + " to " + resourceToDownload.output);
FileUtils.delete(resourceToDownload.output);
FileUtils.createParentDirectories(resourceToDownload.output);
@ -237,8 +239,8 @@ public class Downloader {
if (totalPendingBytes > availableBytes) {
var format = Format.defaultInstance();
String warning =
"Attempting to download " + format.storage(totalPendingBytes) + " to " + fs + " which only has "
+ format.storage(availableBytes) + " available";
"Attempting to download " + format.storage(totalPendingBytes) + " to " + fs + " which only has " +
format.storage(availableBytes) + " available";
if (config.force()) {
LOGGER.warn(warning + ", will probably fail.");
} else {
@ -254,9 +256,8 @@ public class Downloader {
if (redirects > MAX_REDIRECTS) {
throw new IllegalStateException("Exceeded " + redirects + " redirects for " + url);
}
return httpHead(url).thenComposeAsync(response -> response.redirect.isPresent()
? httpHeadFollowRedirects(response.redirect.get(), redirects + 1)
: CompletableFuture.completedFuture(response));
return httpHead(url).thenComposeAsync(response -> response.redirect.isPresent() ?
httpHeadFollowRedirects(response.redirect.get(), redirects + 1) : CompletableFuture.completedFuture(response));
}
CompletableFuture<ResourceMetadata> httpHead(String url) {
@ -280,7 +281,8 @@ public class Downloader {
boolean supportsRangeRequest = headers.allValues(ACCEPT_RANGES).contains("bytes");
ResourceMetadata metadata = new ResourceMetadata(location, url, contentLength, supportsRangeRequest);
return HttpResponse.BodyHandlers.replacing(metadata).apply(responseInfo);
}).thenApply(HttpResponse::body);
})
.thenApply(HttpResponse::body);
}
private CompletableFuture<?> httpDownload(ResourceToDownload resource, Path tmpPath) {
@ -320,9 +322,8 @@ public class Downloader {
try (var fileChannel = FileChannel.open(tmpPath, WRITE)) {
while (range.size() > 0) {
try (
var inputStream = (ranges || range.start > 0)
? openStreamRange(canonicalUrl, range.start, range.end)
: openStream(canonicalUrl);
var inputStream = (ranges || range.start > 0) ? openStreamRange(canonicalUrl, range.start, range.end) :
openStream(canonicalUrl);
var input = new ProgressChannel(Channels.newChannel(inputStream), resource.progress)
) {
// ensure this file has been allocated up to the start of this block
@ -333,8 +334,8 @@ public class Downloader {
throw new IOException("Transferred 0 bytes but " + range.size() + " expected: " + canonicalUrl);
} else if (transferred != range.size() && !metadata.acceptRange) {
throw new IOException(
"Transferred " + transferred + " bytes but " + range.size() + " expected: " + canonicalUrl
+ " and server does not support range requests");
"Transferred " + transferred + " bytes but " + range.size() + " expected: " + canonicalUrl +
" and server does not support range requests");
}
range = new Range(range.start + transferred, range.end);
}

Wyświetl plik

@ -19,8 +19,7 @@ public class FileUtils {
private static final Logger LOGGER = LoggerFactory.getLogger(FileUtils.class);
private FileUtils() {
}
private FileUtils() {}
/** Returns a stream that lists all files in {@code fileSystem}. */
public static Stream<Path> walkFileSystem(FileSystem fileSystem) {

Wyświetl plik

@ -31,7 +31,7 @@ public class Geofabrik {
* Fetches the Geofabrik index and searches for a {@code .osm.pbf} resource to download where ID or name field
* contains all the tokens in {@code searchQuery}.
* <p>
* If an exact match is found, returns that. Otherwise, looks for a resource that contains {@code searchQuery} as a
* If an exact match is found, returns that. Otherwise, looks for a resource that contains {@code searchQuery} as a
* substring.
* <p>
* The index is only fetched once and cached after that.
@ -48,8 +48,10 @@ public class Geofabrik {
private synchronized static IndexJson getAndCacheIndex(PlanetilerConfig config) {
if (index == null) {
try (InputStream inputStream = Downloader.openStream("https://download.geofabrik.de/index-v1-nogeom.json",
config)) {
try (
InputStream inputStream = Downloader.openStream("https://download.geofabrik.de/index-v1-nogeom.json",
config)
) {
index = parseIndexJson(inputStream);
} catch (IOException e) {
throw new IllegalStateException(e);

Wyświetl plik

@ -19,12 +19,12 @@ import java.util.Map;
import java.util.Set;
/**
* Parse utilities ported to Java from <a href="https://github.com/omniscale/imposm3/blob/master/mapping/columns.go">omniscale/imposm3:mapping/columns.go</a>
* Parse utilities ported to Java from <a href=
* "https://github.com/omniscale/imposm3/blob/master/mapping/columns.go">omniscale/imposm3:mapping/columns.go</a>
*/
public class Imposm3Parsers {
private Imposm3Parsers() {
}
private Imposm3Parsers() {}
private static String string(Object object) {
return object == null ? null : object.toString();

Wyświetl plik

@ -8,8 +8,7 @@ import org.slf4j.MDC;
*/
public class LogUtil {
private LogUtil() {
}
private LogUtil() {}
private static final String STAGE_KEY = "stage";

Wyświetl plik

@ -8,8 +8,7 @@ import java.util.regex.Pattern;
*/
public class Parse {
private Parse() {
}
private Parse() {}
private static final Pattern INT_SUBSTRING_PATTERN = Pattern.compile("^(-?\\d+)(\\D|$)");
private static final Pattern TO_ROUND_INT_SUBSTRING_PATTERN = Pattern.compile("^(-?[\\d.]+)(\\D|$)");

Wyświetl plik

@ -8,20 +8,24 @@ import com.onthegomap.planetiler.collection.FeatureGroup;
* ordering approximates the desired ordering.
* <p>
* Sort keys get packed into {@link FeatureGroup#SORT_KEY_BITS} bits, so sort key components need to specify the range
* and number of levels the range gets packed into. Requests that exceed the total number of available levels will
* fail.
* and number of levels the range gets packed into. Requests that exceed the total number of available levels will fail.
* <p>
* To sort by a field descending, specify its range from high to low.
* <p>
* For example this SQL ordering:
* <pre>{@code
*
* <pre>
* {@code
* ORDER BY rank ASC,
* population DESC,
* length(name) ASC
* }</pre>
* }
* </pre>
* <p>
* would become:
* <pre>{@code
*
* <pre>
* {@code
* feature.setSortKey(
* SortKey
* .orderByInt(rank, MIN_RANK, MAX_RANK)
@ -29,7 +33,8 @@ import com.onthegomap.planetiler.collection.FeatureGroup;
* .thenByInt(name.length(), 0, MAX_LENGTH)
* .get()
* )
* }</pre>
* }
* </pre>
*/
public class SortKey {
@ -37,8 +42,7 @@ public class SortKey {
private long possibleValues = 1;
private int result = 0;
private SortKey() {
}
private SortKey() {}
/** Returns a new sort key where elements with {@code value == true} sort after ones where {@code value == false} */
public static SortKey orderByTruesLast(boolean value) {

Wyświetl plik

@ -51,8 +51,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* A utility to download name translations from wikidata for all OSM elements with a <a
* href="https://wiki.openstreetmap.org/wiki/Key:wikidata">wikidata tag</a>.
* A utility to download name translations from wikidata for all OSM elements with a
* <a href="https://wiki.openstreetmap.org/wiki/Key:wikidata">wikidata tag</a>.
*/
public class Wikidata {
@ -371,8 +371,7 @@ public class Wikidata {
private final LongObjectMap<Map<String, String>> data = Hppc.newLongObjectHashMap();
public WikidataTranslations() {
}
public WikidataTranslations() {}
/** Returns a map from language code to translated name for {@code qid}. */
public Map<String, String> get(long qid) {

Wyświetl plik

@ -64,15 +64,14 @@ public interface ZoomFunction<T> extends IntFunction<T> {
}
/**
* A zoom function that lets you set the value to return for a zoom level in meters and when called, it returns how
* A zoom function that lets you set the value to return for a zoom level in meters and when called, it returns how
* many pixels long that number of meters is at the equator.
*/
class MeterToPixelThresholds implements ZoomFunction<Number> {
private final TreeMap<Integer, Number> levels = new TreeMap<>();
private MeterToPixelThresholds() {
}
private MeterToPixelThresholds() {}
/** Sets the value to return at {@code zoom} in meters. */
public MeterToPixelThresholds put(int zoom, double meters) {

Wyświetl plik

@ -13,20 +13,24 @@ import javax.annotation.concurrent.ThreadSafe;
* When a group of worker threads are processing large blocks, some may finish early, resulting in idle time at the end
* waiting for the "long pole in the tent" to finish:
*
* <pre>{@code
* <pre>
* {@code
* busy idle | done
* worker1: ===========>xxxxxx|
* worker2: ===============>xx|
* worker3: =================>|
* worker4: =============>xxxx|
* }</pre>
* }
* </pre>
* <p>
* This utility wraps the operation to perform on each element and then works through items in 3 phases:
*
* <ol>
* <li>If all threads are still busy, process it in the same thread</li>
* <li>If some threads are done, enqueue the item onto a work queue (but if it is full, just process it in the same thread)</li>
* <li>When the thread is done processing input elements, then process items off of the work queue until it is empty and all other workers are finished</li>
* <li>If all threads are still busy, process it in the same thread</li>
* <li>If some threads are done, enqueue the item onto a work queue (but if it is full, just process it in the same
* thread)</li>
* <li>When the thread is done processing input elements, then process items off of the work queue until it is empty and
* all other workers are finished</li>
* </ol>
*
* @param <T> The type of element being processed

Wyświetl plik

@ -104,4 +104,3 @@ public class WeightedHandoffQueue<T> implements AutoCloseable, IterableOnce<T> {
return itemBatch == null ? null : itemBatch.poll();
}
}

Wyświetl plik

@ -19,9 +19,9 @@ import java.util.function.Consumer;
* <p>
* Wraps a standard {@link BlockingDeque}, with a few customizations:
* <ul>
* <li>items are buffered into configurable-sized batches before putting on the actual queue to reduce contention</li>
* <li>writers can mark the queue "finished" with {@link #close()} and readers will get {@code null} when there are
* no more items to read</li>
* <li>items are buffered into configurable-sized batches before putting on the actual queue to reduce contention</li>
* <li>writers can mark the queue "finished" with {@link #close()} and readers will get {@code null} when there are no
* more items to read</li>
* </ul>
* <p>
* Once a thread starts reading from this queue, it needs to finish otherwise all items might not be read.
@ -123,7 +123,9 @@ public class WorkQueue<T> implements AutoCloseable, IterableOnce<T>, Consumer<T>
return (pendingBatchesCapacity + writers.size() + readers.size()) * batchSize;
}
/** Caches thread-local values so that a single thread can accept new items without having to do thread-local lookups. */
/**
* Caches thread-local values so that a single thread can accept new items without having to do thread-local lookups.
*/
private class WriterForThread implements Consumer<T> {
final AtomicReference<Queue<T>> writeBatchRef = new AtomicReference<>(null);
@ -173,7 +175,9 @@ public class WorkQueue<T> implements AutoCloseable, IterableOnce<T>, Consumer<T>
}
}
/** Caches thread-local values so that a single thread can read new items without having to do thread-local lookups. */
/**
* Caches thread-local values so that a single thread can read new items without having to do thread-local lookups.
*/
private class ReaderForThread implements IterableOnce<T> {
Queue<T> readBatch = null;
@ -221,4 +225,3 @@ public class WorkQueue<T> implements AutoCloseable, IterableOnce<T>, Consumer<T>
}
}
}

Wyświetl plik

@ -16,7 +16,9 @@ import java.util.function.Consumer;
* A mini-framework for chaining sequential steps that run in dedicated threads with a queue between each.
* <p>
* For example:
* <pre>{@code
*
* <pre>
* {@code
* WorkerPipeline.start("name", stats)
* .readFrom("reader", List.of(1, 2, 3))
* .addBuffer("reader_queue", 10)
@ -24,13 +26,14 @@ import java.util.function.Consumer;
* .addBuffer("writer_queue", 10)
* .sinkToConsumer("writer", 1, result -> writeToDisk(result))
* .await();
* }</pre>
* }
* </pre>
* <p>
* NOTE: to do any forking/joining, you must construct and wire-up queues and each sequence of steps manually.
*
* @param <T> input type of this pipeline
*/
public record WorkerPipeline<T>(
public record WorkerPipeline<T> (
String name,
WorkerPipeline<?> previous,
WorkQueue<T> inputQueue,
@ -213,7 +216,7 @@ public record WorkerPipeline<T>(
*
* @param <O> type of elements that the next step must process
*/
public record Builder<O>(
public record Builder<O> (
String prefix,
String name,
// keep track of previous elements so that build can wire-up the computation graph

Wyświetl plik

@ -90,8 +90,7 @@ public class PlanetilerTests {
}
@Override
public void close() {
}
public void close() {}
}.process(featureGroup, config);
}
@ -1507,8 +1506,7 @@ public class PlanetilerTests {
}
@Override
public void release() {
}
public void release() {}
@Override
public List<VectorTile.Feature> postProcessLayerFeatures(String layer, int zoom,
@ -1577,9 +1575,9 @@ public class PlanetilerTests {
Path tempOsm = tempDir.resolve("monaco-temp.osm.pbf");
Files.copy(originalOsm, tempOsm);
Planetiler.create(Arguments.fromArgs(
"--tmpdir", tempDir.toString(),
"--free-osm-after-read"
))
"--tmpdir", tempDir.toString(),
"--free-osm-after-read"
))
.setProfile(new Profile.NullProfile() {
@Override
public void processFeature(SourceFeature source, FeatureCollector features) {
@ -1625,25 +1623,25 @@ public class PlanetilerTests {
@Test
public void testPlanetilerMemoryCheck(@TempDir Path tempDir) {
assertThrows(Exception.class, () -> runWithProfile(tempDir, new Profile.NullProfile() {
@Override
public long estimateIntermediateDiskBytes(long osmSize) {
return Long.MAX_VALUE / 10L;
}
}, false)
@Override
public long estimateIntermediateDiskBytes(long osmSize) {
return Long.MAX_VALUE / 10L;
}
}, false)
);
assertThrows(Exception.class, () -> runWithProfile(tempDir, new Profile.NullProfile() {
@Override
public long estimateOutputBytes(long osmSize) {
return Long.MAX_VALUE / 10L;
}
}, false)
@Override
public long estimateOutputBytes(long osmSize) {
return Long.MAX_VALUE / 10L;
}
}, false)
);
assertThrows(Exception.class, () -> runWithProfile(tempDir, new Profile.NullProfile() {
@Override
public long estimateRamRequired(long osmSize) {
return Long.MAX_VALUE / 10L;
}
}, false)
@Override
public long estimateRamRequired(long osmSize) {
return Long.MAX_VALUE / 10L;
}
}, false)
);
}

Wyświetl plik

@ -504,11 +504,9 @@ public class TestUtils {
public record Way(
long id,
@JacksonXmlProperty(localName = "nd")
@JacksonXmlElementWrapper(useWrapping = false)
List<NodeRef> nodeRefs,
@JacksonXmlElementWrapper(useWrapping = false) List<NodeRef> nodeRefs,
@JacksonXmlProperty(localName = "tag")
@JacksonXmlElementWrapper(useWrapping = false)
List<Tag> tags
@JacksonXmlElementWrapper(useWrapping = false) List<Tag> tags
) {}
@JacksonXmlRootElement(localName = "member")
@ -520,11 +518,9 @@ public class TestUtils {
public record Relation(
long id,
@JacksonXmlProperty(localName = "member")
@JacksonXmlElementWrapper(useWrapping = false)
List<RelationMember> members,
@JacksonXmlElementWrapper(useWrapping = false) List<RelationMember> members,
@JacksonXmlProperty(localName = "tag")
@JacksonXmlElementWrapper(useWrapping = false)
List<Tag> tags
@JacksonXmlElementWrapper(useWrapping = false) List<Tag> tags
) {}
// @JsonIgnoreProperties(ignoreUnknown = true)
@ -535,14 +531,11 @@ public class TestUtils {
String attribution,
String license,
@JacksonXmlProperty(localName = "node")
@JacksonXmlElementWrapper(useWrapping = false)
List<Node> nodes,
@JacksonXmlElementWrapper(useWrapping = false) List<Node> nodes,
@JacksonXmlProperty(localName = "way")
@JacksonXmlElementWrapper(useWrapping = false)
List<Way> ways,
@JacksonXmlElementWrapper(useWrapping = false) List<Way> ways,
@JacksonXmlProperty(localName = "relation")
@JacksonXmlElementWrapper(useWrapping = false)
List<Relation> relation
@JacksonXmlElementWrapper(useWrapping = false) List<Relation> relation
) {}
private static final XmlMapper xmlMapper = new XmlMapper();
@ -594,8 +587,7 @@ public class TestUtils {
int minzoom, int maxzoom) {
try {
List<String> failures = new ArrayList<>();
outer:
for (int zoom = 0; zoom <= 14; zoom++) {
outer: for (int zoom = 0; zoom <= 14; zoom++) {
boolean shouldFind = zoom >= minzoom && zoom <= maxzoom;
var coord = TileCoord.aroundLngLat(lng, lat, zoom);
Geometry tilePoint = GeoUtils.point(coord.lngLatToTileCoords(lng, lat));

Wyświetl plik

@ -48,7 +48,8 @@ import org.locationtech.jts.precision.GeometryPrecisionReducer;
import vector_tile.VectorTileProto;
/**
* This class is copied from https://github.com/ElectronicChartCentre/java-vector-tile/blob/master/src/test/java/no/ecc/vectortile/VectorTileEncoderTest.java
* This class is copied from
* https://github.com/ElectronicChartCentre/java-vector-tile/blob/master/src/test/java/no/ecc/vectortile/VectorTileEncoderTest.java
* and modified based on the changes in VectorTileEncoder, and adapted to junit 5.
*/
public class VectorTileTest {
@ -366,59 +367,58 @@ public class VectorTileTest {
var scaleUp = AffineTransformation.scaleInstance(256d / 4096, 256d / 4096);
var scaleDown = scaleUp.getInverse();
return Stream.of(
newPoint(0, 0),
newPoint(0.25, -0.25),
newPoint(0, 0),
newPoint(0.25, -0.25),
newPoint(1.25, 1.25),
newPoint(1.5, 1.5),
newMultiPoint(
newPoint(1.25, 1.25),
newPoint(1.5, 1.5),
newMultiPoint(
newPoint(1.25, 1.25),
newPoint(1.5, 1.5)
),
newLineString(0, 0, 1.2, 1.2),
newPoint(1.5, 1.5)
),
newLineString(0, 0, 1.2, 1.2),
newLineString(0, 0, 0.1, 0.1),
newLineString(0, 0, 1, 1, 1.2, 1.2, 2, 2),
newLineString(8000, 8000, 8000, 8001, 8001, 8001),
newLineString(-4000, -4000, -4000, -4001, -4001, -4001),
newMultiLineString(
newLineString(0, 0, 1, 1),
newLineString(1.1, 1.1, 2, 2)
),
newMultiLineString(
newLineString(0, 0, 0.1, 0.1),
newLineString(0, 0, 1, 1, 1.2, 1.2, 2, 2),
newLineString(8000, 8000, 8000, 8001, 8001, 8001),
newLineString(-4000, -4000, -4000, -4001, -4001, -4001),
newMultiLineString(
newLineString(0, 0, 1, 1),
newLineString(1.1, 1.1, 2, 2)
),
newMultiLineString(
newLineString(0, 0, 0.1, 0.1),
newLineString(1.1, 1.1, 2, 2)
),
newMultiLineString(
newLineString(-10, -10, -9, -9),
newLineString(0, 0, 0.1, 0.1),
newLineString(1.1, 1.1, 2, 2)
),
newLineString(1.1, 1.1, 2, 2)
),
newMultiLineString(
newLineString(-10, -10, -9, -9),
newLineString(0, 0, 0.1, 0.1),
newLineString(1.1, 1.1, 2, 2)
),
newPolygon(0, 0, 1, 0, 1, 1, 0, 1, 0, 0),
newPolygon(0, 0, 0.1, 0, 0.1, 0.1, 0, 0.1, 0, 0),
newPolygon(0, 0, 1, 0, 1, 0.1, 1, 1, 0, 1, 0, 0),
newMultiPolygon(
newPolygon(0, 0, 1, 0, 1, 1, 0, 1, 0, 0),
newPolygon(0, 0, 0.1, 0, 0.1, 0.1, 0, 0.1, 0, 0),
newPolygon(0, 0, 1, 0, 1, 0.1, 1, 1, 0, 1, 0, 0),
newMultiPolygon(
newPolygon(0, 0, 1, 0, 1, 1, 0, 1, 0, 0),
newPolygon(0, 0, -1, 0, -1, -1, 0, -1, 0, 0)
),
newPolygon(0, 0, 1, 0, 1, 1, 0, 1, 0, 0.1, 0, 0)
).map(scaleUp::transform)
.flatMap(geometry -> scales.stream().flatMap(scale ->
Stream.of(
dynamicTest(scaleDown.transform(geometry) + " scale: " + scale, () -> {
PrecisionModel pm = new PrecisionModel((4096 << scale) / 256d);
assertSameGeometry(
GeometryPrecisionReducer.reduce(geometry, pm),
VectorTile.encodeGeometry(geometry, scale).decode()
);
}),
dynamicTest(scaleDown.transform(geometry) + " unscale: " + scale, () -> {
PrecisionModel pm = new PrecisionModel((4096 << scale) / 256d);
PrecisionModel pm0 = new PrecisionModel(4096d / 256);
assertSameGeometry(
GeometryPrecisionReducer.reduce(GeometryPrecisionReducer.reduce(geometry, pm), pm0),
VectorTile.encodeGeometry(geometry, scale).unscale().decode()
);
})
)
newPolygon(0, 0, -1, 0, -1, -1, 0, -1, 0, 0)
),
newPolygon(0, 0, 1, 0, 1, 1, 0, 1, 0, 0.1, 0, 0)
).map(scaleUp::transform)
.flatMap(geometry -> scales.stream().flatMap(scale -> Stream.of(
dynamicTest(scaleDown.transform(geometry) + " scale: " + scale, () -> {
PrecisionModel pm = new PrecisionModel((4096 << scale) / 256d);
assertSameGeometry(
GeometryPrecisionReducer.reduce(geometry, pm),
VectorTile.encodeGeometry(geometry, scale).decode()
);
}),
dynamicTest(scaleDown.transform(geometry) + " unscale: " + scale, () -> {
PrecisionModel pm = new PrecisionModel((4096 << scale) / 256d);
PrecisionModel pm0 = new PrecisionModel(4096d / 256);
assertSameGeometry(
GeometryPrecisionReducer.reduce(GeometryPrecisionReducer.reduce(geometry, pm), pm0),
VectorTile.encodeGeometry(geometry, scale).unscale().decode()
);
})
)
));
}

Wyświetl plik

@ -279,9 +279,8 @@ public class FeatureGroupTest {
int tileB, byte layerB, int sortKeyB, boolean hasGroupB
) {
assertTrue(
FeatureGroup.encodeKey(tileA, layerA, sortKeyA, hasGroupA)
<
FeatureGroup.encodeKey(tileB, layerB, sortKeyB, hasGroupB)
FeatureGroup.encodeKey(tileA, layerA, sortKeyA, hasGroupA) < FeatureGroup.encodeKey(tileB, layerB, sortKeyB,
hasGroupB)
);
}

Wyświetl plik

@ -62,15 +62,15 @@ public class OsmInputFileTest {
@Test
public void testGetHeader() {
assertEquals(new OsmHeader(
expectedBounds,
List.of("OsmSchema-V0.6", "DenseNodes"),
List.of(),
"osmium/1.8.0",
"",
Instant.parse("2021-04-21T20:21:46Z"),
2947,
"http://download.geofabrik.de/europe/monaco-updates"
),
expectedBounds,
List.of("OsmSchema-V0.6", "DenseNodes"),
List.of(),
"osmium/1.8.0",
"",
Instant.parse("2021-04-21T20:21:46Z"),
2947,
"http://download.geofabrik.de/europe/monaco-updates"
),
new OsmInputFile(path).getHeader()
);
}

Some files were not shown because too many files have changed in this diff Show More