Add local reverse-geocode database for better performance#87
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds optional local reverse-geocoding support for navigation features, using an RGC database to reduce reliance on online Photon/Komoot lookups.
Changes:
- Adds RGC configuration paths and default navigation config options.
- Initializes/downloads a local RGC database in
NavigationModule. - Uses local RGC lookups in
OpenStreetMapAPI, with country-code fallback handling for warp creation/editing. - Adds the
alpslib-geodependency and repository resolution changes.
Reviewed changes
Copilot reviewed 9 out of 10 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
src/main/resources/modules/navigation/config.yml |
Adds local reverse-geocode database configuration. |
src/main/java/net/buildtheearth/buildteamtools/utils/io/ConfigPaths.java |
Adds config path constants for RGC settings. |
src/main/java/net/buildtheearth/buildteamtools/modules/network/api/OpenStreetMapAPI.java |
Adds local RGC lookup path before online fallback. |
src/main/java/net/buildtheearth/buildteamtools/modules/navigation/NavUtils.java |
Adds helper for resolving CCA2 from region names. |
src/main/java/net/buildtheearth/buildteamtools/modules/navigation/NavigationModule.java |
Adds RGC database file setup, download, and handler initialization. |
src/main/java/net/buildtheearth/buildteamtools/modules/navigation/components/warps/WarpsComponent.java |
Uses fallback CCA2 lookup when reverse geocode returns no code. |
src/main/java/net/buildtheearth/buildteamtools/modules/navigation/components/warps/menu/WarpEditMenu.java |
Uses fallback CCA2 lookup when changing warp location. |
settings.gradle.kts |
Enables mavenLocal() repository resolution. |
gradle/libs.versions.toml |
Adds alpslib-geo version catalog entries. |
build.gradle.kts |
Adds alpslib-geo as an implementation dependency. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| @Getter | ||
| @Nullable | ||
| private RgcHandler rgcHandler = null; |
There was a problem hiding this comment.
Quite sure that will not cause issues because we always read from main thread. also Rgc handler itself is not thread save
|
|
||
| reverse-geocode: | ||
| local-database: | ||
| # Whether to use the local database for reverse geocoding or not. If false, the online Nominatim API will be used. [true|false] |
| CompletableFuture<String[]> future = new CompletableFuture<>(); | ||
| String url = "https://photon.komoot.io/reverse?lat=" + coordinates[0] + "&lon=" + coordinates[1] + "&lang=en"; | ||
|
|
||
| if (NavigationModule.getInstance().isEnabled() && NavigationModule.getInstance().getRgcHandler() != null) { |
There was a problem hiding this comment.
Quite sure that will not cause issues
Qodana for JVM4 new problems were found
💡 Qodana analysis was run in the pull request mode: only the changed files were checked Contact Qodana teamContact us at qodana-support@jetbrains.com
|
3baac1b to
68868a8
Compare
…load and thread-safety fixes - Add optional offline country/region lookup using alpslib-geo RgcHandler - Automatically download and cache RGC database on first run from configured URL - Fall back to online Photon/Komoot API if local database disabled or unavailable - Mark rgcHandler field as volatile to guarantee cross-thread visibility - Mark Module.enabled as volatile to ensure reliable isEnabled() checks across threads - Schedule RgcHandler creation and all method calls on main thread to prevent concurrent access - Create parent directories before FileOutputStream to handle first-run download - Use try-with-resources for download streams to prevent resource leaks - Schedule RGC lookups on main thread when called from worker threads in OpenStreetMapAPI - Add getCCA2FromCountryName() fallback helper for country code lookup - Add RGC configuration options: enabled, url, path under reverse-geocode.local-database - Handle download failures gracefully with logging and fallback to API Dependencies: - Add com.alpsbte.alpslib:alpslib-geo:1.0.0 Files: - build.gradle.kts: add alpslib-geo dependency - gradle/libs.versions.toml: define alpslib-geo version - settings.gradle.kts: enable mavenLocal() (TEMPORARY - disable before merge) - NavigationModule.java: add RGC initialization with auto-download - Module.java: mark enabled field volatile - OpenStreetMapAPI.java: schedule RGC lookups on main thread - NavUtils.java: add getCCA2FromCountryName() helper - ConfigPaths.java: add RGC_LOCAL_DB_* constants - WarpsComponent.java, WarpEditMenu.java: use fallback country code lookup - config.yml: document RGC local-database settings
68868a8 to
a531451
Compare
| navigatorComponent = new NavigatorComponent(); | ||
| tpllComponent = new TpllComponent(); | ||
|
|
||
| var navConfig = BuildTeamTools.getInstance().getConfig(ConfigUtil.NAVIGATION); |
There was a problem hiding this comment.
This is deeply nested code plus a lot of if/elses, which makes it hard to read and expand in the future. It would be better to use a switch statement here and/or more seperate functions.
| * Returns the CCA2 code of the country of the given country name. | ||
| */ | ||
| public static String getCCA2FromCountryName(String countryName, Player clickPlayer) { | ||
| var region = Objects.requireNonNull(NetworkModule.getInstance().getBuildTeam()).getRegions().stream().filter(regionF -> regionF.getName().equals(countryName)).findFirst(); |
There was a problem hiding this comment.
Try to avoid long method chains like this. You can use a helper or facade method for this instead.
| @@ -1,11 +1,16 @@ | |||
| package net.buildtheearth.buildteamtools.modules.network.api; | |||
There was a problem hiding this comment.
You are using deeply nested code and a chain of if/elses here again. Use switch statements and/or seperate functions for this.
| if (NavigationModule.getInstance().isEnabled() && NavigationModule.getInstance().getRgcHandler() != null) { | ||
| ChatHelper.logDebug("Using custom file API to get country from location: %s, %s", coordinates[0], coordinates[1]); | ||
|
|
||
| // If we are not on main thread, schedule lookup on main thread and complete the outer future there |
There was a problem hiding this comment.
Try to avoid comments (especially in the way you wrote them) like this as you should already be able to read from function names what it is supposed to do. You can of course still add a comment if something is cases where it is really necessary to do so to understand something, but here that is not the case (same for line 44).
| return future; | ||
| } | ||
|
|
||
| String url = "https://photon.komoot.io/reverse?lat=" + coordinates[0] + "&lon=" + coordinates[1] + "&lang=en"; |
There was a problem hiding this comment.
Here it says "&lang=en". Did you check whether it always returns English names? Also it may be a good idea to expand the code like so that we can add more languages in the future, because of course not everyone in BTE speaks English. You do not have to implement this already, but there should at least be a class (or enum?) where you can define this easily.
| return future; | ||
| } | ||
|
|
||
| String url = "https://photon.komoot.io/reverse?lat=" + coordinates[0] + "&lon=" + coordinates[1] + "&lang=en"; |
There was a problem hiding this comment.
What about disputed areas on Earth? What names does it give back for that? This may not seem an issue, but people across the world - and thus, also in BTE - have different beliefs on what regions on Earth have what names and it may cause unnecessary discussions in-game or on our socials. I do not know the solution to this myself right now. Maybe give back multiple names for disputed areas? We could discuss this internally.
Dependencies:
Files: