kopia lustrzana https://github.com/onthegomap/planetiler
Migrate to eclipse formatter to support multiple IDEs (#122)
rodzic
bce75230f2
commit
cce51668f2
|
@ -1,4 +1,5 @@
|
|||
---
|
||||
|
||||
name: Bug report
|
||||
about: Create a report to help improve Planetiler
|
||||
title: "[BUG] "
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
---
|
||||
|
||||
name: Feature request
|
||||
about: Suggest an idea for Planetiler
|
||||
title: "[FEATURE] "
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
|
@ -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
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 |
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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) |
|
||||
|
|
|
@ -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>
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
Plik diff jest za duży
Load Diff
Plik diff jest za duży
Load Diff
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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) {}
|
||||
}
|
||||
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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] + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<>();
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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"
|
||||
))));
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
*/
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package com.onthegomap.planetiler.collection;
|
||||
|
||||
|
||||
import com.carrotsearch.hppc.IntObjectHashMap;
|
||||
import com.carrotsearch.hppc.LongByteHashMap;
|
||||
import com.carrotsearch.hppc.LongByteMap;
|
||||
|
|
|
@ -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() {}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {}
|
||||
}
|
||||
|
|
|
@ -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 {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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<>();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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) {}
|
||||
|
|
|
@ -11,7 +11,7 @@ import org.openstreetmap.osmosis.osmbinary.Osmformat;
|
|||
* This class is copied from Osmosis.
|
||||
*
|
||||
* @author Brett Henderson
|
||||
* <p>
|
||||
* <p>
|
||||
*/
|
||||
public class PbfFieldDecoder {
|
||||
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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<>();
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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) {
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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
|
||||
) {}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -8,8 +8,7 @@ import org.slf4j.MDC;
|
|||
*/
|
||||
public class LogUtil {
|
||||
|
||||
private LogUtil() {
|
||||
}
|
||||
private LogUtil() {}
|
||||
|
||||
private static final String STAGE_KEY = "stage";
|
||||
|
||||
|
|
|
@ -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|$)");
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -104,4 +104,3 @@ public class WeightedHandoffQueue<T> implements AutoCloseable, IterableOnce<T> {
|
|||
return itemBatch == null ? null : itemBatch.poll();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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>
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Plik diff jest za duży
Load Diff
|
@ -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)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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()
|
||||
);
|
||||
})
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
Ładowanie…
Reference in New Issue