98 Commits

Author SHA1 Message Date
sora a8c4529ee8 Update app/build.gradle 2026-07-05 15:04:10 +02:00
bot e7a3f09547 Merge pull request 'Update dependency mapshaper to v0.7.37' (#544) from renovate/mapshaper-0.x-lockfile into main 2026-07-05 04:01:31 +02:00
Renovate Bot 579cf75ca2 Update dependency mapshaper to v0.7.37 2026-07-05 02:01:19 +00:00
bot 121b34c034 Merge pull request 'Lock file maintenance' (#543) from renovate/lock-file-maintenance into main 2026-07-04 04:01:37 +02:00
Renovate Bot 97014e9454 Lock file maintenance 2026-07-04 02:01:35 +00:00
bot 674106923f Merge pull request 'Update dependency mapshaper to v0.7.35' (#542) from renovate/mapshaper-0.x-lockfile into main 2026-07-03 04:01:22 +02:00
Renovate Bot e21dad8ed7 Update dependency mapshaper to v0.7.35 2026-07-03 02:01:13 +00:00
bot b2cca2332b Merge pull request 'Update dependency androidx.compose.ui:ui-tooling to v1.11.4' (#541) from renovate/androidx.compose.ui-ui-tooling-1.x into main 2026-07-03 04:01:00 +02:00
Renovate Bot 13ad82df95 Update dependency androidx.compose.ui:ui-tooling to v1.11.4 2026-07-03 02:00:56 +00:00
bot 2befea2325 Merge pull request 'Update dependency androidx.compose.material:material to v1.11.4' (#540) from renovate/androidx.compose.material-material-1.x into main 2026-07-02 04:00:59 +02:00
bot f45cc57049 Merge pull request 'Update dependency androidx.compose:compose-bom to v2026.06.01' (#539) from renovate/androidx.compose-compose-bom-2026.x into main 2026-07-02 04:00:57 +02:00
Renovate Bot a7f05d5d80 Update dependency androidx.compose.material:material to v1.11.4 2026-07-02 02:00:56 +00:00
Renovate Bot 269e844a4c Update dependency androidx.compose:compose-bom to v2026.06.01 2026-07-02 02:00:54 +00:00
bot 818fc49e3d Merge pull request 'Update plugin com.mikepenz.aboutlibraries.plugin to v15.0.3' (#538) from renovate/com.mikepenz.aboutlibraries.plugin-15.x into main 2026-07-01 04:01:06 +02:00
bot 8a3f7f7621 Merge pull request 'Update dependency com.mikepenz:aboutlibraries-core to v15.0.3' (#537) from renovate/com.mikepenz-aboutlibraries-core-15.x into main 2026-07-01 04:01:01 +02:00
Renovate Bot 8c50670a9d Update plugin com.mikepenz.aboutlibraries.plugin to v15.0.3 2026-07-01 02:01:00 +00:00
Renovate Bot 141ea67d2e Update dependency com.mikepenz:aboutlibraries-core to v15.0.3 2026-07-01 02:00:54 +00:00
soraefir 291fae7aec Fix hash 2026-06-30 07:48:24 +02:00
bot 7a04440eca Merge pull request 'Update dependency com.mikepenz:aboutlibraries-compose-m3 to v15.0.3' (#536) from renovate/com.mikepenz-aboutlibraries-compose-m3-15.x into main 2026-06-30 04:01:17 +02:00
Renovate Bot 691d2e4ea1 Update dependency com.mikepenz:aboutlibraries-compose-m3 to v15.0.3 2026-06-30 02:01:09 +00:00
bot dd5c9387f9 Merge pull request 'Lock file maintenance' (#535) from renovate/lock-file-maintenance into main 2026-06-28 04:01:16 +02:00
Renovate Bot 6038d132ec Lock file maintenance 2026-06-28 02:01:11 +00:00
bot 6a0ac3e5c7 Merge pull request 'Update plugin com.mikepenz.aboutlibraries.plugin to v15' (#534) from renovate/com.mikepenz.aboutlibraries.plugin-15.x into main 2026-06-27 04:01:17 +02:00
Renovate Bot 327a6550b4 Update plugin com.mikepenz.aboutlibraries.plugin to v15 2026-06-27 02:01:15 +00:00
bot 7027d0ffb1 Merge pull request 'Update dependency gradle to v9.6.1' (#533) from renovate/gradle-9.x into main 2026-06-27 04:01:07 +02:00
Renovate Bot 15b33b59ed Update dependency gradle to v9.6.1 2026-06-27 02:00:56 +00:00
bot 36787717ff Merge pull request 'Update dependency com.mikepenz:aboutlibraries-core to v15.0.2' (#532) from renovate/com.mikepenz-aboutlibraries-core-15.x into main 2026-06-27 04:00:54 +02:00
Renovate Bot c27aef23c0 Update dependency com.mikepenz:aboutlibraries-core to v15.0.2 2026-06-27 02:00:49 +00:00
bot a9e567d299 Merge pull request 'Update dependency com.mikepenz:aboutlibraries-compose-m3 to v15.0.2' (#531) from renovate/com.mikepenz-aboutlibraries-compose-m3-15.x into main 2026-06-26 04:00:52 +02:00
Renovate Bot 468fb4ab13 Update dependency com.mikepenz:aboutlibraries-compose-m3 to v15.0.2 2026-06-26 02:00:43 +00:00
bot e952de3c17 Merge pull request 'Update dependency mapshaper to v0.7.33' (#530) from renovate/mapshaper-0.x-lockfile into main 2026-06-24 04:01:11 +02:00
Renovate Bot da1793bc21 Update dependency mapshaper to v0.7.33 2026-06-24 02:01:02 +00:00
bot 650a59b1ac Merge pull request 'Update dependency mapshaper to v0.7.32' (#529) from renovate/mapshaper-0.x-lockfile into main 2026-06-23 04:01:22 +02:00
Renovate Bot 5a9284749c Update dependency mapshaper to v0.7.32 2026-06-23 02:01:11 +00:00
bot 981fc5ebf4 Merge pull request 'Update dependency com.mikepenz:aboutlibraries-core to v15' (#528) from renovate/com.mikepenz-aboutlibraries-core-15.x into main 2026-06-22 04:01:27 +02:00
Renovate Bot 78f5fe7c35 Update dependency com.mikepenz:aboutlibraries-core to v15 2026-06-22 02:01:18 +00:00
bot bdf2911a1c Merge pull request 'Update dependency com.mikepenz:aboutlibraries-compose-m3 to v15' (#527) from renovate/com.mikepenz-aboutlibraries-compose-m3-15.x into main 2026-06-21 04:01:41 +02:00
Renovate Bot 40b2040f25 Update dependency com.mikepenz:aboutlibraries-compose-m3 to v15 2026-06-21 02:01:35 +00:00
bot 48c88d85a4 Merge pull request 'Update actions/checkout action to v7' (#526) from renovate/actions-checkout-7.x into main 2026-06-21 04:01:27 +02:00
Renovate Bot 727c828128 Update actions/checkout action to v7 2026-06-21 02:01:23 +00:00
bot cce6719158 Merge pull request 'Update dependency gradle to v9.6.0' (#525) from renovate/gradle-9.x into main 2026-06-20 04:02:45 +02:00
Renovate Bot 13a79baa2b Update dependency gradle to v9.6.0 2026-06-20 02:02:30 +00:00
bot c956fb9876 Merge pull request 'Update dependency mapshaper to v0.7.29' (#524) from renovate/mapshaper-0.x-lockfile into main 2026-06-20 04:01:49 +02:00
Renovate Bot 339ac468f3 Update dependency mapshaper to v0.7.29 2026-06-20 02:01:40 +00:00
bot f1eacee394 Merge pull request 'Update dependency androidx.compose:compose-bom to v2026.06.00' (#523) from renovate/androidx.compose-compose-bom-2026.x into main 2026-06-19 04:02:06 +02:00
bot a000fb4a3d Merge pull request 'Update dependency mapshaper to v0.7.28' (#522) from renovate/mapshaper-0.x-lockfile into main 2026-06-19 04:02:03 +02:00
Renovate Bot 16ff2e1bc8 Update dependency androidx.compose:compose-bom to v2026.06.00 2026-06-19 02:02:03 +00:00
Renovate Bot 6ee16f02ab Update dependency mapshaper to v0.7.28 2026-06-19 02:01:54 +00:00
bot fd05d9b6f5 Merge pull request 'Update dependency androidx.compose.ui:ui-tooling to v1.11.3' (#521) from renovate/androidx.compose.ui-ui-tooling-1.x into main 2026-06-18 04:01:30 +02:00
bot eece41d0ba Merge pull request 'Update dependency androidx.compose.material:material to v1.11.3' (#520) from renovate/androidx.compose.material-material-1.x into main 2026-06-18 04:01:29 +02:00
Renovate Bot b609704cc1 Update dependency androidx.compose.ui:ui-tooling to v1.11.3 2026-06-18 02:01:27 +00:00
Renovate Bot 39436f473a Update dependency androidx.compose.material:material to v1.11.3 2026-06-18 02:01:23 +00:00
bot ce2721025a Merge pull request 'Update dependency mapshaper to v0.7.26' (#519) from renovate/mapshaper-0.x-lockfile into main 2026-06-16 04:02:04 +02:00
Renovate Bot 371a2aa35f Update dependency mapshaper to v0.7.26 2026-06-16 02:01:52 +00:00
bot 0f986616ae Merge pull request 'Update dependency mapshaper to v0.7.24' (#518) from renovate/mapshaper-0.x-lockfile into main 2026-06-15 04:01:52 +02:00
Renovate Bot eb948c2e59 Update dependency mapshaper to v0.7.24 2026-06-15 02:01:40 +00:00
bot 4fe43c5fc6 Merge pull request 'Lock file maintenance' (#517) from renovate/lock-file-maintenance into main 2026-06-14 04:02:19 +02:00
Renovate Bot eed23b35d4 Lock file maintenance 2026-06-14 02:02:17 +00:00
bot e9d46d0824 Merge pull request 'Update dependency mapshaper to v0.7.23' (#516) from renovate/mapshaper-0.x-lockfile into main 2026-06-14 04:01:58 +02:00
Renovate Bot ccd18f3717 Update dependency mapshaper to v0.7.23 2026-06-14 02:01:46 +00:00
bot 1e78f269c1 Merge pull request 'Lock file maintenance' (#515) from renovate/lock-file-maintenance into main 2026-06-13 04:02:05 +02:00
Renovate Bot 0740c00014 Lock file maintenance 2026-06-13 02:02:01 +00:00
bot 740526104b Merge pull request 'Lock file maintenance' (#514) from renovate/lock-file-maintenance into main 2026-06-07 04:04:22 +02:00
Renovate Bot f807fa62d2 Lock file maintenance 2026-06-07 02:04:13 +00:00
sora 18725261e3 Update app/build.gradle 2026-06-06 19:34:25 +02:00
soraefir cc1a0c1aca Fix region saving bug 2026-06-06 19:30:18 +02:00
soraefir f2a5efcec5 Update saving logic 2026-06-06 18:54:09 +02:00
soraefir cfa784991b Updated SVGs and improved scripting
# Conflicts:
#	yarn.lock
2026-06-06 18:23:41 +02:00
soraefir 14f8543d3d Fix zoom and topbar 2026-06-06 18:23:26 +02:00
soraefir 5705749d12 Fix Caspian Sea 2026-06-06 18:23:26 +02:00
bot 1d0b814e77 Merge pull request 'Lock file maintenance' (#513) from renovate/lock-file-maintenance into main 2026-06-06 04:01:52 +02:00
Renovate Bot ecc26f811a Lock file maintenance 2026-06-06 02:01:48 +00:00
bot 8cd93d866b Merge pull request 'Update plugin org.jetbrains.kotlin.plugin.serialization to v2.4.0' (#512) from renovate/org.jetbrains.kotlin.plugin.serialization-2.x into main 2026-06-05 04:05:29 +02:00
Renovate Bot 6bf4034e1e Update plugin org.jetbrains.kotlin.plugin.serialization to v2.4.0 2026-06-05 02:02:00 +00:00
bot 977321ddb5 Merge pull request 'Update plugin org.jetbrains.kotlin.plugin.compose to v2.4.0' (#511) from renovate/org.jetbrains.kotlin.plugin.compose-2.x into main 2026-06-04 04:11:32 +02:00
bot bee96b5d9b Merge pull request 'Update plugin org.jetbrains.kotlin.android to v2.4.0' (#510) from renovate/org.jetbrains.kotlin.android-2.x into main 2026-06-04 04:11:19 +02:00
Renovate Bot 6d21f0da6d Update plugin org.jetbrains.kotlin.plugin.compose to v2.4.0 2026-06-04 02:11:18 +00:00
Renovate Bot 445ccbcac0 Update plugin org.jetbrains.kotlin.android to v2.4.0 2026-06-04 02:02:01 +00:00
bot 225e5bfdc8 Merge pull request 'Lock file maintenance' (#509) from renovate/lock-file-maintenance into main 2026-05-31 04:02:13 +02:00
Renovate Bot 0c446f0d59 Lock file maintenance 2026-05-31 02:02:04 +00:00
bot 7c0b9bda80 Merge pull request 'Update dependency mapshaper to v0.7.22' (#508) from renovate/mapshaper-0.x-lockfile into main 2026-05-30 04:02:10 +02:00
Renovate Bot eaa0278764 Update dependency mapshaper to v0.7.22 2026-05-30 02:02:02 +00:00
bot eeac01f638 Merge pull request 'Update dependency com.mikepenz:aboutlibraries-compose-m3 to v14.2.1' (#504) from renovate/com.mikepenz-aboutlibraries-compose-m3-14.x into main 2026-05-30 04:01:32 +02:00
Renovate Bot 9f8d5aaa18 Update dependency com.mikepenz:aboutlibraries-compose-m3 to v14.2.1 2026-05-30 02:01:26 +00:00
sora cdb9d51257 Update README.md 2026-05-29 19:01:20 +02:00
bot 2d6b895f57 Merge pull request 'Update dependency mapshaper to v0.7.21' (#507) from renovate/mapshaper-0.x-lockfile into main 2026-05-28 04:02:20 +02:00
Renovate Bot 80e191a50d Update dependency mapshaper to v0.7.21 2026-05-28 02:02:07 +00:00
bot 4114185a73 Merge pull request 'Update plugin com.mikepenz.aboutlibraries.plugin to v14.2.1' (#506) from renovate/com.mikepenz.aboutlibraries.plugin-14.x into main 2026-05-26 04:01:40 +02:00
bot 24fe56c02a Merge pull request 'Update dependency com.mikepenz:aboutlibraries-core to v14.2.1' (#505) from renovate/com.mikepenz-aboutlibraries-core-14.x into main 2026-05-26 04:01:35 +02:00
Renovate Bot d83234cf5b Update plugin com.mikepenz.aboutlibraries.plugin to v14.2.1 2026-05-26 02:01:33 +00:00
Renovate Bot e608b22c0c Update dependency com.mikepenz:aboutlibraries-core to v14.2.1 2026-05-26 02:01:31 +00:00
soraefir f8ed30cd73 Fix Top bar padding on android16+ 2026-05-25 15:20:41 +02:00
soraefir c50933908c Fix crash due to rename 2026-05-25 14:14:42 +02:00
bot 77edae3585 Merge pull request 'Update dependency com.mikepenz:aboutlibraries to v14.2.1' (#503) from renovate/com.mikepenz-aboutlibraries-14.x into main 2026-05-25 04:01:29 +02:00
Renovate Bot 50c152084e Update dependency com.mikepenz:aboutlibraries to v14.2.1 2026-05-25 02:01:22 +00:00
sora b0a107c749 Update README.md 2026-05-24 11:58:56 +02:00
bot 91050826b2 Merge pull request 'Lock file maintenance' (#502) from renovate/lock-file-maintenance into main 2026-05-24 04:04:58 +02:00
Renovate Bot 1004119fed Lock file maintenance 2026-05-24 02:04:55 +00:00
25 changed files with 6880 additions and 20952 deletions
+1 -1
View File
@@ -23,7 +23,7 @@ jobs:
contents: write contents: write
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v7
with: with:
fetch-depth: 0 fetch-depth: 0
+3 -1
View File
@@ -5,6 +5,8 @@
<p>A virtual scratchmap of the world</p> <p>A virtual scratchmap of the world</p>
<a href="https://ko-fi.com/I2I615VP5M"><img src="https://ko-fi.com/img/githubbutton_sm.svg" alt="ko-fi"></a>
<br>
<img src="https://forthebadge.com/images/badges/built-for-android.svg" alt="Built for Android"> <img src="https://forthebadge.com/images/badges/built-for-android.svg" alt="Built for Android">
<img src="https://forthebadge.com/images/badges/built-with-love.svg" alt="Built with love"> <img src="https://forthebadge.com/images/badges/built-with-love.svg" alt="Built with love">
<br> <br>
@@ -71,7 +73,7 @@ Thanks to all contributors, the developers of our dependencies, and our users.
## 📝 License ## 📝 License
``` ```
Copyright (C) 2024 Helcel & MYDOLI Copyright (C) 2026 Helcel & MYDOLI
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+16 -10
View File
@@ -1,8 +1,8 @@
plugins { plugins {
id 'com.android.application' id 'com.android.application'
id 'org.jetbrains.kotlin.plugin.serialization' version '2.3.21' id 'org.jetbrains.kotlin.plugin.serialization' version '2.4.0'
id 'org.jetbrains.kotlin.plugin.compose' version '2.3.21' id 'org.jetbrains.kotlin.plugin.compose' version '2.4.0'
id 'com.mikepenz.aboutlibraries.plugin' version '14.2.0' id 'com.mikepenz.aboutlibraries.plugin' version '15.0.3'
} }
android { android {
@@ -15,7 +15,7 @@ android {
applicationId 'net.helcel.beans' applicationId 'net.helcel.beans'
minSdk = 28 minSdk = 28
targetSdk = 37 targetSdk = 37
versionName "1.2b" versionName "1.4"
versionCode project.hasProperty('VERSION_CODE') ? project.property('VERSION_CODE').toInteger() : 1 versionCode project.hasProperty('VERSION_CODE') ? project.property('VERSION_CODE').toInteger() : 1
} }
signingConfigs { signingConfigs {
@@ -87,7 +87,7 @@ aboutLibraries {
dependencies { dependencies {
implementation 'androidx.compose.material3:material3:1.4.0' implementation 'androidx.compose.material3:material3:1.4.0'
implementation "androidx.compose.material:material:1.11.2" implementation "androidx.compose.material:material:1.11.4"
implementation 'androidx.compose.material:material-icons-extended:1.7.8' implementation 'androidx.compose.material:material-icons-extended:1.7.8'
implementation 'androidx.navigation:navigation-compose:2.9.8' implementation 'androidx.navigation:navigation-compose:2.9.8'
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs_nio:2.1.5' coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs_nio:2.1.5'
@@ -105,11 +105,17 @@ dependencies {
implementation 'com.caverock:androidsvg-aar:1.4' implementation 'com.caverock:androidsvg-aar:1.4'
implementation 'com.github.chrisbanes:PhotoView:2.3.0' implementation 'com.github.chrisbanes:PhotoView:2.3.0'
implementation 'com.mikepenz:aboutlibraries:14.2.0' implementation 'com.mikepenz:aboutlibraries:14.2.1'
implementation 'com.mikepenz:aboutlibraries-compose-m3:14.2.0' implementation 'com.mikepenz:aboutlibraries-compose-m3:15.0.3'
implementation 'com.mikepenz:aboutlibraries-core:14.2.0' implementation 'com.mikepenz:aboutlibraries-core:15.0.3'
implementation platform('androidx.compose:compose-bom:2026.05.01') implementation platform('androidx.compose:compose-bom:2026.06.01')
debugImplementation 'androidx.compose.ui:ui-tooling:1.11.2' debugImplementation 'androidx.compose.ui:ui-tooling:1.11.4'
}
tasks.configureEach { task ->
if (task.name.startsWith("merge") && task.name.endsWith("Assets")) {
task.outputs.upToDateWhen { false }
}
} }
File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.1 MiB

After

Width:  |  Height:  |  Size: 3.9 MiB

File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.0 MiB

After

Width:  |  Height:  |  Size: 3.7 MiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.1 MiB

After

Width:  |  Height:  |  Size: 4.0 MiB

@@ -9,10 +9,12 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.material.Icon import androidx.compose.material.Icon
import androidx.compose.material.IconButton import androidx.compose.material.IconButton
import androidx.compose.material.MaterialTheme import androidx.compose.material.MaterialTheme
import androidx.compose.material.Scaffold import androidx.compose.material.Scaffold
import androidx.compose.material.Surface
import androidx.compose.material.Text import androidx.compose.material.Text
import androidx.compose.material.TopAppBar import androidx.compose.material.TopAppBar
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
@@ -22,6 +24,8 @@ import androidx.compose.material.icons.filled.Settings
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView import androidx.compose.ui.viewinterop.AndroidView
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost import androidx.navigation.compose.NavHost
@@ -46,12 +50,12 @@ class MainScreen : ComponentActivity() {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
actionBar?.hide() actionBar?.hide()
Settings.start(this) Settings.start(this)
GeoLocImporter.importStates(this)
Data.loadData(this, Int.MIN_VALUE) Data.loadData(this, Int.MIN_VALUE)
GeoLocImporter.importStates(this)
setContent { setContent {
SysTheme { SysTheme {
Box(modifier = Modifier.fillMaxSize().background(MaterialTheme.colors.background)) { Box(modifier = Modifier.fillMaxSize().background(MaterialTheme.colors.primary).statusBarsPadding(),) {
AppNavHost(psvg, css) AppNavHost(psvg, css)
} }
} }
@@ -110,6 +114,7 @@ class MainScreen : ComponentActivity() {
PhotoView(ctx).apply { PhotoView(ctx).apply {
setLayerType(ImageView.LAYER_TYPE_SOFTWARE, null) setLayerType(ImageView.LAYER_TYPE_SOFTWARE, null)
setImageDrawable(drawable) setImageDrawable(drawable)
maximumScale = 32f
scaleType = ImageView.ScaleType.FIT_CENTER scaleType = ImageView.ScaleType.FIT_CENTER
} }
}, modifier = Modifier.fillMaxSize()) }, modifier = Modifier.fillMaxSize())
@@ -168,8 +168,10 @@ fun SettingsScreen(navController: NavHostController = settingsNav()) {
EditPlaceDialog(true) { EditPlaceDialog(true) {
showEdit = false showEdit = false
val g = Data.selected_group val g = Data.selected_group
if (it && g != null) if (it && g != null) {
Data.visits.reassignAllVisitedToGroup(g.key) Data.visits.reassignAllVisitedToGroup(g.key)
Data.saveData()
}
} }
LazyColumn( LazyColumn(
@@ -216,8 +218,10 @@ fun SettingsScreen(navController: NavHostController = settingsNav()) {
deleteMode = true, deleteMode = true,
onDismiss = { onDismiss = {
val g = Data.selected_group val g = Data.selected_group
if (g != null) if (g != null) {
Data.visits.reassignAllVisitedToGroup(g.key) Data.visits.reassignAllVisitedToGroup(g.key)
Data.saveData()
}
showDialog = false showDialog = false
}) })
} }
@@ -54,27 +54,51 @@ fun EditPlaceScreenPreview(){
EditPlaceScreen(Group.EEE) EditPlaceScreen(Group.EEE)
} }
fun syncVisited(loc: GeoLoc?=World.WWW){ fun syncVisited(loc: GeoLoc?=World.WWW): Boolean {
var changed = false
loc?.children?.forEach { tt -> loc?.children?.forEach { tt ->
tt.children.forEach {itc-> tt.children.forEach {itc->
if(Data.visits.getVisited(itc) in listOf(AUTO_GROUP,NO_GROUP)) { if(Data.visits.getVisited(itc) in listOf(AUTO_GROUP,NO_GROUP)) {
if(itc.children.any { c -> Data.visits.getVisited(c) != NO_GROUP }) val newState = if(itc.children.any { c -> Data.visits.getVisited(c) != NO_GROUP })
Data.visits.setVisited(itc, AUTO_GROUP) AUTO_GROUP
else else
Data.visits.setVisited(itc, NO_GROUP) NO_GROUP
if (Data.visits.getVisited(itc) != newState) {
Data.visits.setVisited(itc, newState)
changed = true
}
} }
} }
if(Data.visits.getVisited(tt) in listOf(AUTO_GROUP,NO_GROUP)) { if(Data.visits.getVisited(tt) in listOf(AUTO_GROUP,NO_GROUP)) {
if(tt.children.any { itc -> Data.visits.getVisited(itc) != NO_GROUP }) val newState = if(tt.children.any { itc -> Data.visits.getVisited(itc) != NO_GROUP })
Data.visits.setVisited(tt, AUTO_GROUP) AUTO_GROUP
else else
Data.visits.setVisited(tt, NO_GROUP) NO_GROUP
if (Data.visits.getVisited(tt) != newState) {
Data.visits.setVisited(tt, newState)
changed = true
}
} }
} }
// Sync World from Continents
if (loc != null && Data.visits.getVisited(loc) in listOf(AUTO_GROUP, NO_GROUP)) {
val newState = if(loc.children.any { Data.visits.getVisited(it) != NO_GROUP })
AUTO_GROUP
else
NO_GROUP
if (Data.visits.getVisited(loc) != newState) {
Data.visits.setVisited(loc, newState)
changed = true
}
}
return changed
} }
@Composable @Composable
fun EditPlaceScreen(loc: GeoLoc, onExit:()->Unit={}) { fun EditPlaceScreen(loc: GeoLoc, onExit:()->Unit={}) {
val visits by Data.visits.visitsFlow.collectAsState()
var showEdit by remember { mutableStateOf(false) } var showEdit by remember { mutableStateOf(false) }
val tabs : SnapshotStateList<GeoLoc> = remember { mutableStateListOf(loc) } val tabs : SnapshotStateList<GeoLoc> = remember { mutableStateListOf(loc) }
val ctx = LocalContext.current val ctx = LocalContext.current
@@ -84,7 +108,12 @@ fun EditPlaceScreen(loc: GeoLoc, onExit:()->Unit={}) {
selectedTab = tabs.lastIndex selectedTab = tabs.lastIndex
} }
SideEffect { SideEffect {
syncVisited() // visits is used to trigger sync whenever data changes
if (visits.isNotEmpty() || true) {
if (syncVisited()) {
Data.saveData()
}
}
} }
BackHandler { BackHandler {
if (tabs.size > 1) tabs.removeAt(tabs.lastIndex) if (tabs.size > 1) tabs.removeAt(tabs.lastIndex)
@@ -95,6 +124,7 @@ fun EditPlaceScreen(loc: GeoLoc, onExit:()->Unit={}) {
showEdit = false showEdit = false
if (it) { if (it) {
Data.visits.setVisited(Data.selected_geoloc, NO_GROUP) Data.visits.setVisited(Data.selected_geoloc, NO_GROUP)
syncVisited()
Data.saveData() Data.saveData()
if (Data.selected_geoloc!=null && Data.selected_geoloc!!.children.any { itc-> Data.visits.getVisited(itc) != NO_GROUP }) { if (Data.selected_geoloc!=null && Data.selected_geoloc!!.children.any { itc-> Data.visits.getVisited(itc) != NO_GROUP }) {
@@ -103,6 +133,7 @@ fun EditPlaceScreen(loc: GeoLoc, onExit:()->Unit={}) {
} }
if (Data.selected_group != null && Data.selected_geoloc != null) { if (Data.selected_group != null && Data.selected_geoloc != null) {
Data.visits.setVisited(Data.selected_geoloc, Data.selected_group!!.key) Data.visits.setVisited(Data.selected_geoloc, Data.selected_group!!.key)
syncVisited()
Data.saveData() Data.saveData()
} }
Data.selected_geoloc = null Data.selected_geoloc = null
@@ -144,12 +175,14 @@ fun EditPlaceScreen(loc: GeoLoc, onExit:()->Unit={}) {
Data.visits.getVisited(itc)!= NO_GROUP } == true) AUTO_GROUP Data.visits.getVisited(itc)!= NO_GROUP } == true) AUTO_GROUP
else NO_GROUP else NO_GROUP
) )
Data.saveData()
Data.selected_group = null Data.selected_group = null
} else { } else {
Data.selected_group = null Data.selected_group = null
showEdit=true showEdit=true
} }
syncVisited()
Data.saveData()
}) })
} }
@@ -43,14 +43,14 @@ object Data {
if (groups.size() == 0) { if (groups.size() == 0) {
groups.setGroup(DEFAULT_GROUP, "Visited", groups.setGroup(DEFAULT_GROUP, "Visited",
ContextCompat.getColor(ctx, R.color.blue).toDrawable()) ContextCompat.getColor(ctx, R.color.blue).toDrawable())
saveData()
} }
saveData()
} }
fun saveData() { fun saveData() {
if(groups.id != visits.id) return if(groups.id != visits.id) return
val id = groups.id val id = groups.id
sharedPreferences.edit { sharedPreferences.edit(commit=true) {
putString("groups_$id", groupsSerial.writeTo(groups)) putString("groups_$id", groupsSerial.writeTo(groups))
putString("visits_$id", visitsSerial.writeTo(visits)) putString("visits_$id", visitsSerial.writeTo(visits))
} }
@@ -3,6 +3,7 @@ package net.helcel.beans.helper
import android.graphics.Color import android.graphics.Color
import android.graphics.drawable.ColorDrawable import android.graphics.drawable.ColorDrawable
import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.Serializer import kotlinx.serialization.Serializer
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
@@ -24,19 +25,25 @@ const val AUTO_GROUP = -1
@Serializable @Serializable
class Groups(val id: Int, private val groups: HashMap<Int, Group>) { class Groups(val id: Int, @SerialName("grps") private val groups: HashMap<Int, Group>) {
@kotlinx.serialization.Transient @kotlinx.serialization.Transient
private val _groupsFlow = MutableStateFlow<List<Group>>(groups.values.toList()) private val _groupsFlow = MutableStateFlow<List<Group>>(groups.values.toList())
@kotlinx.serialization.Transient @kotlinx.serialization.Transient
val groupsFlow: StateFlow<List<Group>> = _groupsFlow.asStateFlow() val groupsFlow: StateFlow<List<Group>> = _groupsFlow.asStateFlow()
fun setGroup(key: Int, name: String, col: ColorDrawable) { fun setGroup(key: Int, name: String, col: ColorDrawable) {
val old = groups[key]
if (old != null && old.name == name && old.color.color == col.color) return
groups[key] = Group(key, name, col) groups[key] = Group(key, name, col)
_groupsFlow.value = groups.values.toList() updateFlow()
} }
fun deleteGroup(key: Int) { fun deleteGroup(key: Int) {
groups.remove(key) groups.remove(key)
updateFlow()
}
private fun updateFlow() {
_groupsFlow.value = groups.values.toList() _groupsFlow.value = groups.values.toList()
} }
@@ -19,24 +19,25 @@ class Visits(val id: Int, private val locs: HashMap<String, Int>) {
val visitsFlow: StateFlow<Map<String,Int>> = _visitsFlow val visitsFlow: StateFlow<Map<String,Int>> = _visitsFlow
fun setVisited(key: GeoLoc?, b: Int) { fun setVisited(key: GeoLoc?, b: Int) {
if (key == null) if (key == null || locs[key.code] == b)
return return
_visitsFlow.value = _visitsFlow.value.toMutableMap().apply {
this[key.code] = b
}
locs[key.code] = b locs[key.code] = b
updateFlow()
}
private fun updateFlow() {
_visitsFlow.value = locs.toMap()
} }
fun deleteVisited(key: Int) { fun deleteVisited(key: Int) {
val keysToDelete = locs val keysToDelete = locs
.filter { it.value == key } .filter { it.value == key }
.map { it.key } .map { it.key }
_visitsFlow.value = _visitsFlow.value.toMutableMap().apply { if (keysToDelete.isEmpty()) return
keysToDelete.forEach { this.remove(it)}
}
keysToDelete.forEach { keysToDelete.forEach {
locs.remove(it) locs.remove(it)
} }
updateFlow()
} }
fun getVisited(key: GeoLoc): Int { fun getVisited(key: GeoLoc): Int {
@@ -60,13 +61,19 @@ class Visits(val id: Int, private val locs: HashMap<String, Int>) {
} }
fun reassignAllVisitedToGroup(group: Int) { fun reassignAllVisitedToGroup(group: Int) {
var changed = false
val keys = locs.filter { (_, grp) -> val keys = locs.filter { (_, grp) ->
grp !in listOf(NO_GROUP, AUTO_GROUP) grp !in listOf(NO_GROUP, AUTO_GROUP)
}.keys }.keys
keys.forEach { keys.forEach {
locs[it] = group if (locs[it] != group) {
locs[it] = group
changed = true
}
}
if (changed) {
updateFlow()
} }
_visitsFlow.value = locs
} }
@OptIn(ExperimentalSerializationApi::class) @OptIn(ExperimentalSerializationApi::class)
@@ -0,0 +1,50 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="128"
android:viewportHeight="128">
<group android:scaleX="0.8918919"
android:scaleY="0.8918919"
android:translateX="6.918919"
android:translateY="6.918919">
<group
android:scaleX="1.5"
android:scaleY="1.5"
android:translateX="10"
android:translateY="10">
<path
android:pathData="M36,36m-28,0a28,28 0,1 1,56 0a28,28 0,1 1,-56 0"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="@color/blue"
android:strokeColor="#000000"
android:strokeLineCap="round"/>
</group>
<group
android:scaleX="1.25"
android:scaleY="1.25"
android:translateX="18"
android:translateY="18">
<path
android:pathData="M56.803,45.75c0.599,-0.299 1.157,-0.672 1.663,-1.11 0.804,-0.698 1.463,-1.546 1.94,-2.497 0.599,-1.303 0.883,-2.728 0.829,-4.161 0.034,-1.498 -0.154,-2.994 -0.558,-4.437 -0.451,-1.645 -1.104,-3.229 -1.944,-4.714 -0.967,-2.141 -2.28,-4.108 -3.887,-5.822 -1.242,-1.326 -2.757,-2.366 -4.44,-3.048 -0.877,-0.372 -1.821,-0.56 -2.774,-0.553 -1.402,0.074 -2.729,0.697 -3.882,1.389 -1.285,0.81 -2.244,1.735 -2.771,3.053 -0.739,2.362 0.827,4.821 1.113,5.269 0.003,0.005 0.187,0.281 0.555,0.832 1.512,2.264 1.589,2.358 1.666,2.495 0.646,1.221 1.114,2.528 1.389,3.882 1.043,4.001 1.565,6.001 2.223,6.932 1.208,1.71 3.455,3.414 5.826,3.325 1.059,-0.088 2.093,-0.371 3.05,-0.835Z"
android:strokeWidth="2"
android:fillColor="@color/white"
android:strokeColor="#000000"
android:strokeLineCap="round"/>
<path
android:pathData="M22,41c-1.54,0.554 -2.83,1.642 -3.636,3.066 -0.714,1.365 -0.957,2.928 -0.693,4.445 0.178,1.247 0.632,2.439 1.329,3.488 2.032,3.228 5.383,4.423 7,5 1.613,0.561 3.295,0.897 5,1 2.387,0.205 6.923,0.535 11,-2 1.287,-0.665 2.335,-1.713 3,-3 0.661,-1.601 0.661,-3.399 0,-5 -0.389,-1.156 -1.121,-2.165 -2.099,-2.894 -0.919,-0.599 -1.974,-0.956 -3.069,-1.039 -2.057,-0.313 -2.756,0.139 -5.014,0.057 -1.271,-0.019 -2.534,-0.214 -3.753,-0.577 -3.036,-0.95 -3.33,-2.457 -5.889,-2.829 -1.066,-0.158 -2.155,-0.061 -3.177,0.282Z"
android:strokeWidth="2"
android:fillColor="@color/white"
android:strokeColor="#000000"
android:strokeLineCap="round"/>
<path
android:pathData="M12.7,26.975c1.758,-3.604 5.311,-3.191 9.58,-7.091 2.701,-2.469 2.858,-4.078 5.613,-5.202 1.407,-0.644 2.984,-0.819 4.498,-0.5 2.053,0.475 3.761,1.891 4.61,3.819 1.116,2.742 -0.314,5.437 -1.398,7.482 -0.951,1.689 -2.167,3.215 -3.602,4.518 -1.479,1.552 -3.161,2.898 -5,4 -2.629,1.541 -6.332,3.711 -9.989,2.43 -1.481,-0.548 -2.768,-1.521 -3.699,-2.796 -1.496,-1.906 -1.735,-4.512 -0.612,-6.659Z"
android:strokeWidth="2"
android:fillColor="@color/white"
android:strokeColor="#000000"
android:strokeLineCap="round"/>
</group>
</group>
</vector>
+15
View File
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.Beans" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<!-- Status bar color in dark mode -->
<item name="android:statusBarColor">@color/blue</item>
<!-- Window background in dark mode -->
<item name="android:windowBackground">@color/darkgray</item>
<item name="android:windowLightStatusBar">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="colorPrimary">@color/blue</item>
<item name="colorPrimaryDark">@color/blue</item>
<item name="colorAccent">@color/blue</item>
</style>
</resources>
+7
View File
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.Beans" parent="android:Theme.Material.Light.NoActionBar">
<item name="android:statusBarColor">@color/blue</item>
<item name="android:windowBackground">@color/blue</item>
</style>
</resources>
+16
View File
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.Beans" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<!-- Status bar color -->
<item name="android:statusBarColor">@color/blue</item>
<!-- Window background - shows through statusBarsPadding() area -->
<item name="android:windowBackground">@color/blue</item>
<item name="android:windowLightStatusBar">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<!-- Optional: Primary colors for the theme -->
<item name="colorPrimary">@color/blue</item>
<item name="colorPrimaryDark">@color/blue</item>
<item name="colorAccent">@color/blue</item>
</style>
</resources>
+1 -1
View File
@@ -2,5 +2,5 @@
plugins { plugins {
id 'com.android.application' version '9.2.1' apply false id 'com.android.application' version '9.2.1' apply false
id 'com.android.library' version '9.2.1' apply false id 'com.android.library' version '9.2.1' apply false
id 'org.jetbrains.kotlin.android' version '2.3.21' apply false id 'org.jetbrains.kotlin.android' version '2.4.0' apply false
} }
+52 -8
View File
@@ -1,8 +1,10 @@
#!/bin/node #!/bin/node
import {readFileSync, existsSync} from 'fs' import {readFileSync,writeFileSync,existsSync} from 'fs'
import area from '@turf/area' import area from '@turf/area'
import * as turf from '@turf/turf' import * as turf from '@turf/turf'
import * as path from 'path';
import { JSDOM } from 'jsdom';
const countries = const countries =
@@ -24,7 +26,7 @@ const countries =
const groups = { const groups = {
"EEE":["ALB","AND","AUT","BLR","BEL","BIH","BGR","HRV","CYP","CZE","DNK","EST","FIN","FRA","DEU","GRC","HUN","ISL","IRL","ITA","KAZ","XKO","LVA","LIE","LTU","LUX","MLT","MDA","MCO","MNE","NLD","MKD","NOR","POL","PRT","ROU","RUS","SMR","SRB","SVK","SVN","ESP","SWE","CHE","UKR","GBR","VAT","XAD"], "EEE":["ALA","ALB","AND","AUT","BLR","BEL","BIH","BGR","HRV","CYP","CZE","DNK","EST","FIN","FRA","DEU","GIB","GGY","GRC","HUN","ISL","IRL","IMN","JEY","ITA","KAZ","XKO","LVA","LIE","LTU","LUX","MLT","MDA","MCO","MNE","NLD","MKD","NOR","SJM","POL","PRT","ROU","RUS","SMR","SRB","SVK","SVN","ESP","SWE","CHE","UKR","GBR","VAT","XAD"],
"ABB":["AFG","ARM","AZE","BHR","BGD","BTN","BRN","KHM","CHN","GEO","HKG","IND","IDN","IRN","IRQ","ISR","JPN","JOR","KWT","KGZ","LAO","LBN","MAC","MYS","MDV","MNG","MMR","NPL","PRK","OMN","PAK","PSE","PHL","QAT","SAU","SGP","KOR","LKA","SYR","TWN","TJK","THA","TLS","TUR","TKM","ARE","UZB","VNM","YEM","ZNC"], "ABB":["AFG","ARM","AZE","BHR","BGD","BTN","BRN","KHM","CHN","GEO","HKG","IND","IDN","IRN","IRQ","ISR","JPN","JOR","KWT","KGZ","LAO","LBN","MAC","MYS","MDV","MNG","MMR","NPL","PRK","OMN","PAK","PSE","PHL","QAT","SAU","SGP","KOR","LKA","SYR","TWN","TJK","THA","TLS","TUR","TKM","ARE","UZB","VNM","YEM","ZNC"],
"FFF":["DZA","AGO","BDI","BEN","BWA","BFA","BDI","CPV","CMR","CAF","TCD","COM","COG","COD","CIV","DJI","EGY","GNQ","ERI","SWZ","ETH","GAB","GMB","GHA","GIN","GNB","KEN","LSO","LBR","LBY","MDG","MWI","MLI","MRT","MUS","MYT","MAR","MOZ","NAM","NER","NGA","COD","REU","RWA","STP","SEN","SYC","SLE","SOM","ZAF","SSD","SHN","SDN","TZA","TGO","TUN","UGA","COD","ZMB","ZWE","ESH"], "FFF":["DZA","AGO","BDI","BEN","BWA","BFA","BDI","CPV","CMR","CAF","TCD","COM","COG","COD","CIV","DJI","EGY","GNQ","ERI","SWZ","ETH","GAB","GMB","GHA","GIN","GNB","KEN","LSO","LBR","LBY","MDG","MWI","MLI","MRT","MUS","MYT","MAR","MOZ","NAM","NER","NGA","COD","REU","RWA","STP","SEN","SYC","SLE","SOM","ZAF","SSD","SHN","SDN","TZA","TGO","TUN","UGA","COD","ZMB","ZWE","ESH"],
"NNN":["ABW","AIA","ATG","BHS","BRB","BLZ","BMU","VGB","CAN","CYM","CRI","CUB","CUW","DMA","DOM","SLV","GRL","GRD","GLP","GTM","HTI","HND","JAM","MTQ","MEX","MSR","ANT","CUW","NIC","PAN","PRI","KNA","LCA","MAF","SPM","VCT","TTO","TCA","USA","XCL"], "NNN":["ABW","AIA","ATG","BHS","BRB","BLZ","BMU","VGB","CAN","CYM","CRI","CUB","CUW","DMA","DOM","SLV","GRL","GRD","GLP","GTM","HTI","HND","JAM","MTQ","MEX","MSR","ANT","CUW","NIC","PAN","PRI","KNA","LCA","MAF","SPM","VCT","TTO","TCA","USA","XCL"],
@@ -32,7 +34,6 @@ const groups = {
"UUU":["ASM","AUS","COK","FJI","PYF","GUM","KIR","MHL","FSM","NRU","NCL","NZL","NIU","NFK","MNP","PLW","PNG","PCN","SLB","TKL","TON","TUV","VUT","WLF"], "UUU":["ASM","AUS","COK","FJI","PYF","GUM","KIR","MHL","FSM","NRU","NCL","NZL","NIU","NFK","MNP","PLW","PNG","PCN","SLB","TKL","TON","TUV","VUT","WLF"],
"XXX":[ "XXX":[
"ATA", // Antarctica: not in any other region "ATA", // Antarctica: not in any other region
"ALA",// Åland Islands: an autonomous region of Finland, but not a member of the EU or UN
"BES",// Bonaire, Sint Eustatius and Saba: special municipalities of the Netherlands in the Caribbean "BES",// Bonaire, Sint Eustatius and Saba: special municipalities of the Netherlands in the Caribbean
"BVT",// Bouvet Island: an uninhabited territory of Norway in the South Atlantic "BVT",// Bouvet Island: an uninhabited territory of Norway in the South Atlantic
"IOT",// British Indian Ocean Territory: a British overseas territory in the Indian Ocean "IOT",// British Indian Ocean Territory: a British overseas territory in the Indian Ocean
@@ -40,16 +41,11 @@ const groups = {
"CCK",// Cocos (Keeling) Islands: an Australian external territory in the Indian Ocean "CCK",// Cocos (Keeling) Islands: an Australian external territory in the Indian Ocean
"FRO",// Faroe Islands: an autonomous region of Denmark "FRO",// Faroe Islands: an autonomous region of Denmark
"ATF",// French Southern and Antarctic Lands: a territory of France located in the southern Indian Ocean "ATF",// French Southern and Antarctic Lands: a territory of France located in the southern Indian Ocean
"GIB",// Gibraltar: a British overseas territory located at the southern tip of the Iberian Peninsula
"GGY",// Guernsey: a British Crown dependency in the English Channel
"HMD",// Heard Island and McDonald Islands: an uninhabited Australian external territory in the southern Indian Ocean "HMD",// Heard Island and McDonald Islands: an uninhabited Australian external territory in the southern Indian Ocean
"IMN",// Isle of Man: a British Crown dependency located in the Irish Sea
"JEY",// Jersey: a British Crown dependency located in the English Channel
"BLM",// Saint Barthélemy: an overseas collectivity of France in the Caribbean "BLM",// Saint Barthélemy: an overseas collectivity of France in the Caribbean
"WSM",// Samoa: an independent island nation in the South Pacific "WSM",// Samoa: an independent island nation in the South Pacific
"SXM",// Sint Maarten: a constituent country of the Kingdom of the Netherlands in the Caribbean "SXM",// Sint Maarten: a constituent country of the Kingdom of the Netherlands in the Caribbean
"SGS",// South Georgia and the South Sandwich Islands: a British overseas territory in the southern Atlantic Ocean "SGS",// South Georgia and the South Sandwich Islands: a British overseas territory in the southern Atlantic Ocean
"SJM",// Svalbard and Jan Mayen: an archipelago administered by Norway
"UMI",// United States Minor Outlying Islands: a collection of nine insular areas of the United States "UMI",// United States Minor Outlying Islands: a collection of nine insular areas of the United States
"VIR",// United States Virgin Islands: an unincorporated territory of the United States in the Caribbean "VIR",// United States Virgin Islands: an unincorporated territory of the United States in the Caribbean
] ]
@@ -166,4 +162,52 @@ async function run(){
} }
} }
function fixSvg(svgPath) {
const countryToRegion = {};
for (const [region, countries] of Object.entries(groups)) {
countries.forEach(country => countryToRegion[country] = region);
}
const absoluteInputPath = path.resolve(svgPath);
if (!existsSync(absoluteInputPath)) {
throw new Error(`Input file not found at: ${absoluteInputPath}`);
}
const svgContent = readFileSync(absoluteInputPath, 'utf8');
const dom = new JSDOM(svgContent, { contentType: 'image/svg+xml' });
const document = dom.window.document;
const svgRoot = document.querySelector('svg');
if (!svgRoot) {
throw new Error("Invalid or empty SVG structure encountered.");
}
if (svgRoot.getAttribute('data-processed') === 'true') {
console.log(`Skipping: File at "${svgPath}" has already been processed.`);
return;
}
const elementGroups = Array.from(svgRoot.querySelectorAll('g'));
elementGroups.forEach(group => {
const currentId = group.getAttribute('id') || '';
const baseIsoCode = currentId.replace(/\d+$/, '');
const regionKey = countryToRegion[baseIsoCode] || 'XXXX';
let regionGroup = svgRoot.querySelector(`g[id="${regionKey}"]`);
if (!regionGroup) {
regionGroup = document.createElementNS('http://w3.org', 'g');
regionGroup.setAttribute('id', regionKey);
svgRoot.appendChild(regionGroup);
}
regionGroup.appendChild(group);
});
svgRoot.setAttribute('data-processed', 'true');
const absoluteOutputPath = path.resolve(svgPath);
let cleanXmlString = svgRoot.outerHTML;
cleanXmlString = cleanXmlString.replace(/[\r\n]+/g, '');
cleanXmlString = cleanXmlString.replace(/xmlns="http:\/\/w3\.org"\s?/g, '');
cleanXmlString = cleanXmlString.replace(/xmlns="http:\/\/www\.w3\.org\/2000\/svg"\s?/g, '');
cleanXmlString = cleanXmlString.replace('<svg', '<svg xmlns="http://www.w3.org/2000/svg"');
writeFileSync(absoluteOutputPath, cleanXmlString, 'utf8');
}
run() run()
fixSvg("./app/src/main/assets/loxim01.svg")
fixSvg("./app/src/main/assets/webmercator01.svg")
fixSvg("./app/src/main/assets/aeqd01.svg")
+49 -5
View File
@@ -8,10 +8,11 @@ GADM_BASEPATH="https://geodata.ucdavis.edu/gadm"
mapshaper="./node_modules/mapshaper/bin/mapshaper" mapshaper="./node_modules/mapshaper/bin/mapshaper"
ATA_URL="https://media.githubusercontent.com/media/wmgeolab/geoBoundaries/905b0baf5f4fb3b9ccf45293647dcacdb2b799d4/releaseData/gbOpen/ATA/ADM0/geoBoundaries-ATA-ADM0_simplified.geojson" ATA_URL="https://media.githubusercontent.com/media/wmgeolab/geoBoundaries/905b0baf5f4fb3b9ccf45293647dcacdb2b799d4/releaseData/gbOpen/ATA/ADM0/geoBoundaries-ATA-ADM0_simplified.geojson"
# Caspian Sea: "XCA"
countries=( countries=(
"AFG" "XAD" "ALA" "ALB" "DZA" "ASM" "AND" "AGO" "AIA" "ATG" "ARG" "ARM" "ABW" "AUS" "AUT" "AZE" "AFG" "XAD" "ALA" "ALB" "DZA" "ASM" "AND" "AGO" "AIA" "ATG" "ARG" "ARM" "ABW" "AUS" "AUT" "AZE"
"BHS" "BHR" "BGD" "BRB" "BLR" "BEL" "BLZ" "BEN" "BMU" "BTN" "BOL" "BES" "BIH" "BWA" "BVT" "BRA" "IOT" "VGB" "BRN" "BGR" "BFA" "BDI" "KHM" "BHS" "BHR" "BGD" "BRB" "BLR" "BEL" "BLZ" "BEN" "BMU" "BTN" "BOL" "BES" "BIH" "BWA" "BVT" "BRA" "IOT" "VGB" "BRN" "BGR" "BFA" "BDI" "KHM"
"CMR" "CAN" "CPV" "XCA" "CYM" "CAF" "TCD" "CHL" "CHN" "CXR" "XCL" "CCK" "COL" "COM" "COK" "CRI" "CIV" "HRV" "CUB" "CUW" "CYP" "CZE" "COD" "CMR" "CAN" "CPV" "CYM" "CAF" "TCD" "CHL" "CHN" "CXR" "XCL" "CCK" "COL" "COM" "COK" "CRI" "CIV" "HRV" "CUB" "CUW" "CYP" "CZE" "COD"
"DNK" "DJI" "DMA" "DOM" "ECU" "EGY" "SLV" "GNQ" "ERI" "EST" "ETH" "FLK" "FRO" "FJI" "FIN" "FRA" "GUF" "PYF" "ATF" "DNK" "DJI" "DMA" "DOM" "ECU" "EGY" "SLV" "GNQ" "ERI" "EST" "ETH" "FLK" "FRO" "FJI" "FIN" "FRA" "GUF" "PYF" "ATF"
"GAB" "GMB" "GEO" "DEU" "GHA" "GIB" "GRC" "GRL" "GRD" "GLP" "GUM" "GTM" "GGY" "GIN" "GNB" "GUY" "HTI" "HMD" "HND" "HUN" "GAB" "GMB" "GEO" "DEU" "GHA" "GIB" "GRC" "GRL" "GRD" "GLP" "GUM" "GTM" "GGY" "GIN" "GNB" "GUY" "HTI" "HMD" "HND" "HUN"
"ISL" "IND" "IDN" "IRN" "IRQ" "IRL" "IMN" "ISR" "ITA" "JAM" "JPN" "JEY" "JOR" "KAZ" "KEN" "KIR" "XKO" "KWT" "KGZ" "ISL" "IND" "IDN" "IRN" "IRQ" "IRL" "IMN" "ISR" "ITA" "JAM" "JPN" "JEY" "JOR" "KAZ" "KEN" "KIR" "XKO" "KWT" "KGZ"
@@ -115,6 +116,47 @@ toSVG_1() {
"$mapshaper" -i combine-files ${input_files[@]} -proj aeqd +lat_0=90 -simplify 0.005 weighted keep-shapes resolution=1200x1200 -o ./app/src/main/assets/aeqd1.svg svg-data=GID_0,COUNTRY,GID,NAME id-field=GID "$mapshaper" -i combine-files ${input_files[@]} -proj aeqd +lat_0=90 -simplify 0.005 weighted keep-shapes resolution=1200x1200 -o ./app/src/main/assets/aeqd1.svg svg-data=GID_0,COUNTRY,GID,NAME id-field=GID
} }
generate_svg_map() {
local OUT_FILE="$1" # First argument: Output destination path
local PROJ_ARGS="$2" # Second argument: Projection parameters
shift 2 # Remove the first two arguments, leaving only the files
local FILES_TO_RUN=("$@") # Capture all remaining arguments as the file array
echo "Generating: $OUT_FILE using projection [$PROJ_ARGS]"
echo "Processing ${#FILES_TO_RUN[@]} files..."
local JS_PIPELINE_LOGIC="
const conflicts = {
'Z01': 'IND', 'Z04': 'IND', 'Z05': 'IND', 'Z07': 'IND', 'Z09': 'IND',
'Z02': 'CHN', 'Z03': 'CHN','Z08': 'CHN',
'Z06': 'PAK'
};
let rawCode = GID_0 || 'UNK';
let cCode = conflicts[rawCode] ? conflicts[rawCode] : rawCode;
let isGidMissing = (!GID || GID === 'undefined' || GID === 'null' || GID === '');
if (isGidMissing) {
COUNTRY_GROUP = cCode+'2';
} else {
COUNTRY_GROUP = cCode+'1';
}
"
"$mapshaper" -i "${FILES_TO_RUN[@]}" combine-files \
-snap \
-merge-layers force\
-proj $PROJ_ARGS densify \
-simplify 2% weighted keep-shapes \
-filter-islands min-area=0 \
-sort 'this.area' ascending \
-each "$JS_PIPELINE_LOGIC" \
-split COUNTRY_GROUP \
-o "$OUT_FILE" \
format=svg \
id-field=GID \
precision=0.1 \
target=*
}
toSVG_01() { toSVG_01() {
input_files=() input_files=()
@@ -136,9 +178,9 @@ toSVG_01() {
fi fi
done done
"$mapshaper" -i combine-files ${input_files[@]} snap -proj loxim densify -simplify 0.001 weighted keep-shapes -o ./app/src/main/assets/loxim01.svg svg-data=GID_0,COUNTRY,GID,NAME id-field=GID generate_svg_map "./app/src/main/assets/loxim01.svg" "loxim" "${input_files[@]}"
"$mapshaper" -i combine-files ${input_files[@]} snap -proj webmercator densify -simplify 0.001 weighted keep-shapes -o ./app/src/main/assets/webmercator01.svg svg-data=GID_0,COUNTRY,GID,NAME id-field=GID generate_svg_map "./app/src/main/assets/webmercator01.svg" "webmercator" "${input_files[@]}"
"$mapshaper" -i combine-files ${input_files[@]} snap -proj aeqd +lat_0=90 densify -simplify 0.001 weighted keep-shapes -o ./app/src/main/assets/aeqd01.svg svg-data=GID_0,COUNTRY,GID,NAME id-field=GID generate_svg_map "./app/src/main/assets/aeqd01.svg" "aeqd +lat_0=90" "${input_files[@]}"
} }
do_1() { do_1() {
@@ -153,10 +195,12 @@ do_0() {
do do
download_0 "$country" download_0 "$country"
done done
wget -q -O "./temp/1/ATA.json" "$ATA_URL" wget -q -O "./temp/0/ATA.json" "$ATA_URL"
} }
# do_0 # do_0
# do_1 # do_1
# toSVG_0 # toSVG_0
# toSVG_1 # toSVG_1
toSVG_01 toSVG_01
#CUW, CCK, XCL, CXR, IOT, BVT, ABW, FLK, GIB, HMD, KIR, SXM, MDV, MCO, NIU, NFK, PCN, MAF, SGS, VAT
+2 -2
View File
@@ -1,7 +1,7 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionSha256Sum=bafc141b619ad6350fd975fc903156dd5c151998cc8b058e8c1044ab5f7b031f distributionSha256Sum=9c0f7faeeb306cb14e4279a3e084ca6b596894089a0638e68a07c945a32c9e14
distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.1-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-9.6.1-bin.zip
networkTimeout=10000 networkTimeout=10000
retries=0 retries=0
retryBackOffMs=500 retryBackOffMs=500
Vendored
+2 -2
View File
@@ -20,7 +20,7 @@
############################################################################## ##############################################################################
# #
# Gradle start up script for POSIX generated by Gradle. # gradlew start up script for POSIX generated by Gradle.
# #
# Important for running: # Important for running:
# #
@@ -29,7 +29,7 @@
# bash, then to run this script, type that shell name before the whole # bash, then to run this script, type that shell name before the whole
# command line, like: # command line, like:
# #
# ksh Gradle # ksh gradlew
# #
# Busybox and similar reduced shells will NOT work, because this script # Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features: # requires all of these POSIX shell features:
Vendored
+2 -2
View File
@@ -19,7 +19,7 @@
@if "%DEBUG%"=="" @echo off @if "%DEBUG%"=="" @echo off
@rem ########################################################################## @rem ##########################################################################
@rem @rem
@rem Gradle startup script for Windows @rem gradlew startup script for Windows
@rem @rem
@rem ########################################################################## @rem ##########################################################################
@@ -72,7 +72,7 @@ echo location of your Java installation. 1>&2
@rem Execute Gradle @rem Execute gradlew
@rem endlocal doesn't take effect until after the line is parsed and variables are expanded @rem endlocal doesn't take effect until after the line is parsed and variables are expanded
@rem which allows us to clear the local environment before executing the java command @rem which allows us to clear the local environment before executing the java command
endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel
+1 -1
View File
@@ -3,7 +3,7 @@
"@turf/area": "^7.3.5", "@turf/area": "^7.3.5",
"@turf/turf": "^7.3.5", "@turf/turf": "^7.3.5",
"jsdom": "^29.1.1", "jsdom": "^29.1.1",
"mapshaper": "^0.7.19" "mapshaper": "^0.7.22"
}, },
"type": "module" "type": "module"
} }
+3473 -4569
View File
File diff suppressed because it is too large Load Diff