Compare commits

..

3 Commits

Author SHA1 Message Date
Viktor Govako
6368ba477f Assign external URI for Kayak hotels.
Signed-off-by: Viktor Govako <viktor.govako@gmail.com>
2025-05-08 21:13:33 +07:00
Viktor Govako
e7c04c5459 Kayak flow.
Signed-off-by: Viktor Govako <viktor.govako@gmail.com>
2025-05-08 21:13:33 +07:00
Viktor Govako
556a474fda Restore booking flow.
Signed-off-by: Viktor Govako <viktor.govako@gmail.com>
2025-05-08 21:13:33 +07:00
9186 changed files with 1182664 additions and 354785 deletions

View File

@@ -1,61 +1,448 @@
# Configuration file for clang-format, based on docs/CPP_STYLE.md. # Configuration file for clang-format, based on docs/CPP_STYLE.md.
BasedOnStyle: Google
AccessModifierOffset: -2 ---
AlignAfterOpenBracket: Align BasedOnStyle: Google
AlignConsecutiveMacros: AcrossEmptyLinesAndComments IndentWidth: 2
AlignEscapedNewlines: LeftWithLastLine BreakBeforeBraces: Allman
AlignOperands: AlignAfterOperator
AllowShortBlocksOnASingleLine: Empty
AllowShortCaseLabelsOnASingleLine: true
AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
BraceWrapping:
AfterCaseLabel: true
AfterClass: true
AfterControlStatement: Always
AfterEnum: true
AfterExternBlock: true
AfterFunction: true
AfterNamespace: true
AfterObjCDeclaration: true
AfterStruct: true
AfterUnion: true
BeforeCatch: true
BeforeElse: true
BeforeLambdaBody: true
BeforeWhile: true
SplitEmptyFunction: false
SplitEmptyNamespace: false
SplitEmptyRecord: false
BinPackArguments: true
BinPackParameters: true
BreakAfterJavaFieldAnnotations: true
BreakBeforeBraces: Custom
BreakConstructorInitializers: BeforeComma
BreakInheritanceList: BeforeComma
ColumnLimit: 120 ColumnLimit: 120
---
Language: Cpp
AccessModifierOffset: -2
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: true
AllowShortFunctionsOnASingleLine: true
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
BreakConstructorInitializersBeforeComma: true
ConstructorInitializerIndentWidth: 2 ConstructorInitializerIndentWidth: 2
ContinuationIndentWidth: 4
DerivePointerAlignment: false DerivePointerAlignment: false
EmptyLineBeforeAccessModifier: Always
IncludeBlocks: Preserve
IndentAccessModifiers: false
IndentCaseLabels: false IndentCaseLabels: false
IndentExternBlock: NoIndent NamespaceIndentation: None
InsertBraces: false
InsertNewlineAtEOF: true
LambdaBodyIndentation: OuterScope
PackConstructorInitializers: CurrentLine
PointerAlignment: Middle PointerAlignment: Middle
RemoveBracesLLVM: true SortIncludes: true
RemoveSemicolon: true Standard: c++20
QualifierAlignment: Right IncludeBlocks: Regroup
SpacesInContainerLiterals: false IncludeCategories:
Standard: Latest # Tests --------------------------------------------------------------------------------------------
TabWidth: 2 - Regex: '^"track_analyzing/track_analyzing_tests/'
Priority: 4730
- Regex: '^"poly_borders/poly_borders_tests/'
Priority: 4740
- Regex: '^"generator/generator_integration_tests/'
Priority: 4750
- Regex: '^"generator/generator_tests/'
Priority: 4751
- Regex: '^"generator/mwm_diff_tests/'
Priority: 4752
- Regex: '^"map/style_tests/'
Priority: 4760
- Regex: '^"map/mwm_tests/'
Priority: 4761
- Regex: '^"map/map_tests/'
Priority: 4762
- Regex: '^"map/map_integration_tests/'
Priority: 4763
- Regex: '^"ge0/ge0_tests/'
Priority: 4765
- Regex: '^"openlr/openlr_tests/'
Priority: 4770
- Regex: '^"descriptions/descriptions_tests/'
Priority: 4790
- Regex: '^"ugc/ugc_tests'
Priority: 4810
- Regex: '^"search/search_integration_tests/'
Priority: 4820
- Regex: '^"search/search_tests/'
Priority: 4821
- Regex: '^"search/search_quality/search_quality_tests/'
Priority: 4822
- Regex: '^"drape_frontend/drape_frontend_tests/'
Priority: 4830
- Regex: '^"routing/routing_tests/'
Priority: 4840
- Regex: '^"routing/routing_integration_tests/'
Priority: 4841
- Regex: '^"routing/routing_quality/routing_quality_tests/'
Priority: 4842
- Regex: '^"routing/routing_consistency_tests/'
Priority: 4843
- Regex: '^"routing/routing_benchmarks/'
Priority: 4844
- Regex: '^"kml/kml_tests'
Priority: 4850
- Regex: '^"tracking/tracking_tests/'
Priority: 4860
- Regex: '^"partners_api/partners_api_tests/'
Priority: 4870
- Regex: '^"traffic/traffic_tests/'
Priority: 4880
- Regex: '^"storage/storage_tests/'
Priority: 4890
- Regex: '^"storage/storage_integration_tests/'
Priority: 4891
- Regex: '^"editor/editor_tests/'
Priority: 4900
- Regex: '^"editor/osm_auth_tests/'
Priority: 4910
- Regex: '^"drape/drape_tests/'
Priority: 4920
- Regex: '^"transit/transit_tests'
Priority: 4930
- Regex: '^"routing_common/routing_common_tests/'
Priority: 4940
- Regex: '^"indexer/indexer_tests/'
Priority: 4950
- Regex: '^"platform/platform_tests/'
Priority: 4960
- Regex: '^"coding/coding_tests/'
Priority: 4970
- Regex: '^"geometry/geometry_tests/'
Priority: 4980
- Regex: '^"base/base_tests/'
Priority: 4990
- Regex: '^"testing/'
Priority: 5000
# Binaries (tools) ---------------------------------------------------------------------------------
- Regex: '^"openlr/openlr_match_quality/openlr_assessment_tool/'
Priority: 18908
- Regex: '^"search/search_quality/assessment_tool/'
Priority: 18909
- Regex: '^"qt/'
Priority: 18910
- Regex: '^"track_analyzing/track_analyzer/'
Priority: 19000
- Regex: '^"feature_list/'
Priority: 19100
- Regex: '^"generator/booking_quality_check/'
Priority: 19206
- Regex: '^"generator/complex_generator/'
Priority: 19207
- Regex: '^"generator/feature_segments_checker/'
Priority: 19208
- Regex: '^"generator/srtm_coverage_checker/'
Priority: 19209
- Regex: '^"generator/generator_tool/'
Priority: 19210
- Regex: '^"map/extrapolation_benchmark/'
Priority: 19309
- Regex: '^"map/benchmark_tool/'
Priority: 19310
- Regex: '^"openlr/openlr_stat/'
Priority: 19400
- Regex: '^"search/search_quality/booking_dataset_generator/'
Priority: 19707
- Regex: '^"search/search_quality/features_collector_tool/'
Priority: 19708
- Regex: '^"search/search_quality/samples_generation_tool/'
Priority: 19709
- Regex: '^"search/search_quality/search_quality_tool/'
Priority: 19710
- Regex: '^"track_generator/'
Priority: 19800
- Regex: '^"routing/routing_quality/routing_quality_tool/'
Priority: 19909
- Regex: '^"routing/routes_builder/routes_builder_tool/'
Priority: 19910
- Regex: '^"skin_generator/'
Priority: 20000
# Libraries ----------------------------------------------------------------------------------------
- Regex: '^"poly_borders/'
Priority: 46700
- Regex: '^"track_analyzing/'
Priority: 46800
- Regex: '^"generator/mwm_diff/pymwm_diff/'
Priority: 46907
- Regex: '^"generator/mwm_diff/'
Priority: 46908
- Regex: '^"generator/generator_tests_support/'
Priority: 46909
- Regex: '^"generator/'
Priority: 46910
- Regex: '^"map/'
Priority: 47000
- Regex: '^"ge0/'
Priority: 47050
- Regex: '^"openlr/'
Priority: 47100
- Regex: '^"descriptions/'
Priority: 47300
- Regex: '^"search/search_quality/'
Priority: 47407
- Regex: '^"search/search_tests_support/'
Priority: 47408
- Regex: '^"search/pysearch/'
Priority: 47409
- Regex: '^"search/'
Priority: 47410
- Regex: '^"ugc/'
Priority: 47500
- Regex: '^"track_generator/pytrack_generator/'
Priority: 47600
- Regex: '^"routing/routing_quality/api/'
Priority: 47707
- Regex: '^"routing/routing_quality/'
Priority: 47708
- Regex: '^"routing/routes_builder/'
Priority: 47709
- Regex: '^"routing/'
Priority: 47710
- Regex: '^"tracking/pytracking/'
Priority: 47809
- Regex: '^"tracking/'
Priority: 47810
- Regex: '^"partners_api/'
Priority: 47900
- Regex: '^"traffic/pytraffic/'
Priority: 48109
- Regex: '^"traffic/'
Priority: 48110
- Regex: '^"storage/'
Priority: 48200
- Regex: '^"editor/editor_tests_support/'
Priority: 48309
- Regex: '^"editor/'
Priority: 48310
- Regex: '^"drape_frontend/'
Priority: 48500
- Regex: '^"shaders/'
Priority: 48600
- Regex: '^"drape/'
Priority: 48700
- Regex: '^"qt_tstfrm/'
Priority: 48800
- Regex: '^"kml/pykmlib/'
Priority: 48909
- Regex: '^"kml/'
Priority: 48910
- Regex: '^"transit/'
Priority: 49000
- Regex: '^"routing_common/'
Priority: 49100
- Regex: '^"indexer/'
Priority: 49200
- Regex: '^"platform/platform_tests_support/'
Priority: 49409
- Regex: '^"platform/'
Priority: 49410
- Regex: '^"coding/'
Priority: 49500
- Regex: '^"geometry/'
Priority: 49600
- Regex: '^"base/'
Priority: 49700
- Regex: '^"pyhelpers/'
Priority: 49800
- Regex: '^"app/organicmaps/util/'
Priority: 49840
- Regex: '^"app/organicmaps/maps/'
Priority: 49850
- Regex: '^"app/organicmaps/platform/'
Priority: 49860
- Regex: '^"app/organicmaps/opengl/'
Priority: 49870
- Regex: '^"app/organicmaps/vulkan/'
Priority: 49880
- Regex: '^"app/organicmaps/core/'
Priority: 49890
- Regex: '^"private\.h"$'
Priority: 49900
- Regex: '^"std/'
Priority: 50000
- Regex: '^"defines\.hpp"$'
Priority: 50100
- Regex: '^<Qt.*>$'
Priority: 50140
- Regex: '^<jni.h>$'
Priority: 50180
- Regex: '^<.*>$'
Priority: 50200
- Regex: '^"(3party/boost|boost)/'
Priority: 50300
- Regex: '^<boost'
Priority: 50300
- Regex: '^"3party/.*'
Priority: 50400
- Regex: '^"build_version\.hpp"$'
Priority: 99999
--- ---
Language: Java Language: Java
AllowShortFunctionsOnASingleLine: Empty BreakAfterJavaFieldAnnotations: true
---
Language: ObjC
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Left
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: true
BinPackParameters: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Attach
BreakBeforeInheritanceComma: false
BreakInheritanceList: AfterColon
BreakBeforeTernaryOperators: true
BreakStringLiterals: true
ColumnLimit: 120
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 2
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^<.*\.h>'
Priority: 1
- Regex: '^<.*'
Priority: 2
- Regex: '.*'
Priority: 3
IncludeIsMainRegex: '([-_](test|unittest))?$'
IndentCaseLabels: true
IndentPPDirectives: None
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Never
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Right
ReflowComments: true
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: false
SpacesInContainerLiterals: false
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Auto
TabWidth: 8
UseTab: Never

View File

@@ -1,8 +0,0 @@
# Files that should not be formatted.
./3party
# A patched copy of the https://registry.khronos.org/OpenGL/api/GLES3/gl3.h
./android/sdk/src/main/cpp/app/organicmaps/sdk/opengl/gl3stub.h
# Formatting it leads to crashes in runtime. Newer protobuf may fix it.
./libs/indexer/drules_struct.pb.cc
# No need to format this 3party tool.
tools/osmctools/*.c

View File

@@ -1,55 +1,69 @@
# All non-assigned.
* @organicmaps/mergers
# Visual design. # Visual design.
/android/app/src/main/res/drawable*/ @comaps/design /android/app/src/main/res/drawable*/ @organicmaps/design
/android/app/src/main/res/font/ @comaps/design /android/app/src/main/res/font/ @organicmaps/design
/android/app/src/main/res/mipmap*/ @comaps/design /android/app/src/main/res/mipmap*/ @organicmaps/design
/data/*.ttf @comaps/design /data/*.ttf @organicmaps/design
/data/resources-svg/ @comaps/design /data/resources-svg/ @organicmaps/design
/data/search-icons/ @comaps/design /data/search-icons/ @organicmaps/design
/iphone/Maps/Images.xcassets/ @comaps/design /iphone/Maps/Images.xcassets/ @organicmaps/design
# Android. # Android.
/android/ @comaps/android /android/ @organicmaps/android
/android/app/src/main/java/app/comaps/car/ @comaps/android-auto /android/app/src/main/java/app/organicmaps/car/ @organicmaps/android-auto
/docs/ANDROID_LOCATION_TEST.md @comaps/android /docs/ANDROID_LOCATION_TEST.md @organicmaps/android
/docs/JAVA_STYLE.md @comaps/android /docs/JAVA_STYLE.md @organicmaps/android
# no owner for translation changes # no owner for translation changes
/android/app/src/main/res/values*/strings.xml /android/app/src/main/res/values*/strings.xml
# iOS. # iOS.
/iphone/ @comaps/ios /iphone/ @organicmaps/ios
/xcode/ @comaps/ios /xcode/ @organicmaps/ios
/docs/OBJC_STYLE.md @comaps/ios /docs/OBJC_STYLE.md @organicmaps/ios
# no owner for translation changes # no owner for translation changes
/iphone/plist.txt /iphone/plist.txt
/iphone/Maps/LocalizedStrings/ /iphone/Maps/LocalizedStrings/
# Qt
/qt/ @organicmaps/qt
# Rendering
/drape/ @organicmaps/rendering
/drape_frontend/ @organicmaps/rendering
# Map Data.
/tools/python/maps_generator/ @organicmaps/data
/generator/ @organicmaps/data
/topography_generator/ @organicmaps/data
/data/borders/ @organicmaps/data
/data/conf/isolines/ @organicmaps/data
/docs/SUBWAY_GENERATION.md @organicmaps/data
/docs/MAPS.md @organicmaps/data
/docs/EXPERIMENTAL_PUBLIC_TRANSPORT_SUPPORT.md @organicmaps/data
# no owner (changed often to add a new POI) # no owner (changed often to add a new POI)
/generator/generator_tests/osm_type_test.cpp /generator/generator_tests/osm_type_test.cpp
# Map Styles. # Map Styles.
/data/styles/ @comaps/styles /data/styles/ @organicmaps/styles
/data/types.txt @comaps/styles /data/types.txt @organicmaps/styles
/data/visibility.txt @comaps/styles /data/visibility.txt @organicmaps/styles
/data/mapcss-mapping.csv @comaps/styles /data/mapcss-mapping.csv @organicmaps/styles
/data/replaced_tags.txt @comaps/styles /data/replaced_tags.txt @organicmaps/styles
/data/classificator.txt @comaps/styles /data/classificator.txt @organicmaps/styles
/data/drules_* @comaps/styles /data/drules_* @organicmaps/styles
/docs/STYLES.md /docs/STYLES.md
/tools/kothic/ @comaps/styles /tools/kothic/ @organicmaps/styles
# DevOps. # DevOps.
/.forgejo/workflows @comaps/devops /.forgejo/workflows @organicmaps/devops
/android/*gradle* @comaps/devops /android/*gradle* @organicmaps/devops
/docs/RELEASE_MANAGEMENT.md @comaps/devops /docs/RELEASE_MANAGEMENT.md @organicmaps/devops
/xcode/fastlane/ @comaps/devops /xcode/fastlane/ @organicmaps/devops
/tools/python/maps_generator/ @comaps/devops # Growth.
/generator/ @comaps/devops README.md @organicmaps/growth
/topography_generator/ @comaps/devops /.forgejo/FUNDING.yml @organicmaps/growth
/data/borders/ @comaps/devops /android/app/src/fdroid/play/ @organicmaps/growth
/data/conf/isolines/ @comaps/devops /android/app/src/google/play/ @organicmaps/growth
/docs/SUBWAY_GENERATION.md @comaps/devops /iphone/metadata/ @organicmaps/growth
/docs/MAPS.md @comaps/devops
/docs/EXPERIMENTAL_PUBLIC_TRANSPORT_SUPPORT.md @comaps/devops
# Legal. # Legal.
LEGAL @comaps/admins LEGAL @organicmaps/legal
LICENSE @comaps/admins LICENSE @organicmaps/legal
NOTICE @comaps/admins NOTICE @organicmaps/legal
CONTRIBUTORS @comaps/admins CONTRIBUTORS @organicmaps/legal
/docs/CODE_OF_CONDUCT.md @comaps/admins /docs/CODE_OF_CONDUCT.md @organicmaps/legal
/docs/DCO.md @comaps/admins /docs/DCO.md @organicmaps/legal
/docs/GOVERNANCE.md @comaps/admins /docs/GOVERNANCE.md @organicmaps/legal

View File

@@ -1,3 +1 @@
open_collective: comaps open_collective: comaps
liberapay: comaps
custom: ["https://comaps.app/donate/"]

View File

@@ -1,69 +0,0 @@
name: 🐞 Bug Report
description: Report a problem you've encountered
labels:
- bug
body:
- type: markdown
attributes:
value: |
⚠ **Have you searched for similar, already existing issues?**
Please do that before submitting a new one.
- type: textarea
id: issue-description
attributes:
label: Describe the issue
description: Please write a clear and concise description of the issue here.
placeholder: Describe what is not working as expected...
validations:
required: true
- type: textarea
id: steps-to-reproduce
attributes:
label: Steps to reproduce
description: Describe the steps needed to reproduce the issue.
placeholder: |
1. Go to '...'
2. Click on '...'
3. Scroll down to '...'
4. See the error
validations:
required: true
- type: textarea
id: expected-behavior
attributes:
label: Expected behaviour
description: A clear and concise description of what you expected to happen.
placeholder: I expected that...
validations:
required: false
- type: textarea
id: screenshots
attributes:
label: Screenshots
description: If applicable, add screenshots or screen recordings to help explain your problem.
validations:
required: false
- type: textarea
id: system-info
attributes:
label: System information
description: Provide information about the system where the issue occurred.
placeholder: |
- OS: e.g. Ubuntu 22, iOS 12
- CoMaps version: e.g. 1.2.3
- Device model: e.g. iPhone 6, Samsung S22
validations:
required: true
- type: textarea
id: additional-context
attributes:
label: Additional context
description: Add any other context or comments that may be useful.
validations:
required: false

View File

@@ -0,0 +1,38 @@
---
name: Bug Report
about: Describe your issue in detail to help us improve CoMaps
title: ''
labels: ''
assignees: ''
---
⚠ Have you searched for similar, already existing issues?
**Describe the issue**
Please write a clear and concise description of the issue here.
**Steps to reproduce**
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behaviour**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots or screen recordings to help explain your problem.
**System information:**
- Operating system and its version: [iOS 12, Android 10, Ubuntu 22, MacOS Big Sur, etc.]
- CoMaps version: [you can find it by tapping the button with the CoMaps logo]
- Device Model: [e.g. iPhone 6, Samsung S22]
**Additional context**
Please add any other context or comments here that may be useful.

View File

@@ -1,7 +1,7 @@
blank_issues_enabled: true blank_issues_enabled: true
contact_links: contact_links:
- name: Translations - name: Translations
url: https://codeberg.org/comaps/comaps/src/branch/main/docs/TRANSLATIONS.md url: https://codeberg.org/comaps/comaps/blob/master/docs/TRANSLATIONS.md
about: Translate CoMaps into your language about: Translate CoMaps into your language
- name: News - name: News
url: https://comaps.app/news/ url: https://comaps.app/news/

View File

@@ -1,46 +0,0 @@
name: "💡 Feature Request"
description: "Suggest an idea or improvement for CoMaps"
labels:
- "enhancement"
body:
- type: markdown
attributes:
value: |
⚠ **Have you searched for similar, already existing issues?**
Please make sure your idea hasn't been suggested before.
- type: textarea
id: related-problem
attributes:
label: "What problem would this feature help solve?"
description: "Share how this feature could make the experience better, smoother, or more enjoyable."
placeholder: "It would be great if..."
validations:
required: true
- type: textarea
id: ideal-solution
attributes:
label: "Describe the ideal solution"
description: "What would you like to see in CoMaps?"
placeholder: "I would like CoMaps to..."
validations:
required: false
- type: textarea
id: alternatives
attributes:
label: "Describe alternatives you have considered"
description: |
How do you solve this issue now with CoMaps or other apps?
You can also share screenshots or examples from other apps.
validations:
required: false
- type: textarea
id: additional-context
attributes:
label: "Additional context"
description: "Any other context, comments, or screenshots to support your request."
validations:
required: false

View File

@@ -0,0 +1,27 @@
---
name: Feature Request
about: Suggest an idea for CoMaps
title: ''
labels: []
assignees: ''
---
⚠ Have you searched for similar, already existing issues?
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. For example:
I'm always frustrated when [...]
**Describe the ideal solution**
A clear and concise description of what you want to see in CoMaps.
**Describe alternatives you have considered**
- How do you solve this issue now with CoMaps or other apps?
- Attach any examples, screenshots, or screen recordings from other apps that help us to better understand the idea.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@@ -3,7 +3,7 @@ on:
workflow_dispatch: # Manual trigger workflow_dispatch: # Manual trigger
push: push:
branches: branches:
- main - master
paths-ignore: paths-ignore:
- .gitignore - .gitignore
- .forgejo/** - .forgejo/**
@@ -32,6 +32,9 @@ on:
- track_generator/** - track_generator/**
- xcode/** - xcode/**
env:
JAVA_HOME: /usr/lib/jvm/temurin-17-jdk-amd64 # Java 17 is required for Android Gradle 8 plugin
jobs: jobs:
android-google-beta: android-google-beta:
name: Android Google Beta name: Android Google Beta
@@ -68,6 +71,10 @@ jobs:
SECURE_PROPERTIES: ${{ secrets.SECURE_PROPERTIES }} SECURE_PROPERTIES: ${{ secrets.SECURE_PROPERTIES }}
RELEASE_KEYSTORE: ${{ secrets.RELEASE_KEYSTORE }} RELEASE_KEYSTORE: ${{ secrets.RELEASE_KEYSTORE }}
- name: Configure repository
shell: bash
run: ./configure.sh
- name: Compile - name: Compile
shell: bash shell: bash
working-directory: android working-directory: android

View File

@@ -1,4 +1,4 @@
name: Android Check Store Metadata name: Android Check Metadata
on: on:
workflow_dispatch: # Manual trigger workflow_dispatch: # Manual trigger
pull_request: pull_request:
@@ -21,8 +21,5 @@ jobs:
android android
tools/python/check_store_metadata.py tools/python/check_store_metadata.py
- name: Check Google Play metadata - name: Check metadata
run: ./tools/python/check_store_metadata.py gplay run: ./tools/python/check_store_metadata.py android
- name: Check F-Droid metadata
run: ./tools/python/check_store_metadata.py fdroid

View File

@@ -3,7 +3,7 @@ on:
workflow_dispatch: # Manual trigger workflow_dispatch: # Manual trigger
push: push:
branches: branches:
- main - master
pull_request: pull_request:
paths-ignore: paths-ignore:
- .gitignore - .gitignore
@@ -34,6 +34,9 @@ on:
- track_generator/** - track_generator/**
- xcode/** - xcode/**
env:
JAVA_HOME: /usr/lib/jvm/temurin-17-jdk-amd64 # Java 17 is required for Android Gradle 8 plugin
jobs: jobs:
lint: lint:
name: Android Lint name: Android Lint
@@ -48,6 +51,10 @@ jobs:
shell: bash shell: bash
run: git submodule update --depth 1 --init --recursive --jobs=$(($(nproc) * 20)) run: git submodule update --depth 1 --init --recursive --jobs=$(($(nproc) * 20))
- name: Configure repository
shell: bash
run: ./configure.sh
- name: Lint - name: Lint
shell: bash shell: bash
working-directory: android working-directory: android
@@ -86,6 +93,10 @@ jobs:
shell: bash shell: bash
run: git submodule update --depth 1 --init --recursive --jobs=$(($(nproc) * 20)) run: git submodule update --depth 1 --init --recursive --jobs=$(($(nproc) * 20))
- name: Configure repository
shell: bash
run: ./configure.sh
- name: Configure ccache - name: Configure ccache
uses: hendrikmuhs/ccache-action@v1.2 uses: hendrikmuhs/ccache-action@v1.2
with: with:

View File

@@ -4,6 +4,9 @@ on:
schedule: schedule:
- cron: '0 5 * * 0' # Once per week at 05:00 UTC - cron: '0 5 * * 0' # Once per week at 05:00 UTC
env:
JAVA_HOME: /usr/lib/jvm/temurin-17-jdk-amd64 # Java 17 is required for Android Gradle 8 plugin
jobs: jobs:
precondition: precondition:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -70,6 +73,10 @@ jobs:
SECURE_PROPERTIES: ${{ secrets.SECURE_PROPERTIES }} SECURE_PROPERTIES: ${{ secrets.SECURE_PROPERTIES }}
RELEASE_KEYSTORE: ${{ secrets.RELEASE_KEYSTORE }} RELEASE_KEYSTORE: ${{ secrets.RELEASE_KEYSTORE }}
- name: Configure repository
shell: bash
run: ./configure.sh
- name: Compile - name: Compile
shell: bash shell: bash
working-directory: android working-directory: android

View File

@@ -2,29 +2,41 @@ name: Android Release Metadata
on: on:
workflow_dispatch: # Manual trigger workflow_dispatch: # Manual trigger
env:
JAVA_HOME: /usr/lib/jvm/temurin-17-jdk-amd64 # Java 17 is required for Android Gradle 8 plugin
jobs: jobs:
android-release-metadata: android-release-metadata:
name: Upload Google Play metadata name: Upload Google Play metadata
runs-on: ubuntu-latest runs-on: ubuntu-latest
environment: production environment: production
steps: steps:
- name: Checkout - name: Checkout sources
uses: actions/checkout@v4
- name: Parallel submodules checkout
shell: bash
run: git submodule update --depth 1 --init --recursive --jobs=$(($(nproc) * 20))
- name: Checkout screenshots
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
fetch-depth: 1 repository: ${{ secrets.SCREENSHOTS_REPO }}
sparse-checkout: | ssh-key: ${{ secrets.SCREENSHOTS_SSH_KEY }}
android ref: master
tools/python/check_store_metadata.py path: screenshots
- name: Restore release keys - name: Restore release keys
shell: bash shell: bash
run: | run: |
echo "$PRIVATE_H" | base64 -d > private.h
echo "$GOOGLE_PLAY_JSON" | base64 -d > android/app/google-play.json echo "$GOOGLE_PLAY_JSON" | base64 -d > android/app/google-play.json
env: env:
PRIVATE_H: ${{ secrets.PRIVATE_H }}
GOOGLE_PLAY_JSON: ${{ secrets.GOOGLE_PLAY_JSON }} GOOGLE_PLAY_JSON: ${{ secrets.GOOGLE_PLAY_JSON }}
- name: Upload - name: Upload
shell: bash shell: bash
run: ./gradlew publishGoogleReleaseListing run: ./gradlew prepareGoogleReleaseListing publishGoogleReleaseListing
working-directory: android working-directory: android
timeout-minutes: 5 timeout-minutes: 5

View File

@@ -5,6 +5,7 @@ on:
env: env:
RELEASE_NOTES: android/app/src/google/play/release-notes/en-US/default.txt RELEASE_NOTES: android/app/src/google/play/release-notes/en-US/default.txt
FDROID_VERSION: android/app/src/fdroid/play/version.yaml FDROID_VERSION: android/app/src/fdroid/play/version.yaml
JAVA_HOME: /usr/lib/jvm/temurin-17-jdk-amd64 # Java 17 is required for Android Gradle 8 plugin
jobs: jobs:
tag: tag:
@@ -96,7 +97,7 @@ jobs:
with: with:
repository: ${{ secrets.SCREENSHOTS_REPO }} repository: ${{ secrets.SCREENSHOTS_REPO }}
ssh-key: ${{ secrets.SCREENSHOTS_SSH_KEY }} ssh-key: ${{ secrets.SCREENSHOTS_SSH_KEY }}
ref: main ref: master
path: screenshots path: screenshots
- name: Restore release keys - name: Restore release keys
@@ -116,6 +117,10 @@ jobs:
SECURE_PROPERTIES: ${{ secrets.SECURE_PROPERTIES }} SECURE_PROPERTIES: ${{ secrets.SECURE_PROPERTIES }}
RELEASE_KEYSTORE: ${{ secrets.RELEASE_KEYSTORE }} RELEASE_KEYSTORE: ${{ secrets.RELEASE_KEYSTORE }}
- name: Configure repository
shell: bash
run: ./configure.sh
- name: Set up SDK - name: Set up SDK
shell: bash shell: bash
run: echo "sdk.dir=$ANDROID_SDK_ROOT" > android/local.properties run: echo "sdk.dir=$ANDROID_SDK_ROOT" > android/local.properties
@@ -151,7 +156,7 @@ jobs:
cat ${{ env.RELEASE_NOTES }} cat ${{ env.RELEASE_NOTES }}
echo "" echo ""
echo "See [a detailed announce](https://organicmaps.app/news/) on our website when app updates are published in all stores." echo "See [a detailed announce](https://organicmaps.app/news/) on our website when app updates are published in all stores."
echo "You can get automatic app updates from Codeberg [using Obtainium](https://codeberg.org/comaps/comaps/wiki/Installing-Organic-Maps-from-GitHub-using-Obtainium)." echo "You can get automatic app updates from Codeberg [using Obtainium](https://codeberg.com/comaps/comaps/wiki/Installing-Organic-Maps-from-GitHub-using-Obtainium)."
echo "" echo ""
echo "sha256sum:" echo "sha256sum:"
echo -e '\n```' echo -e '\n```'

View File

@@ -3,20 +3,20 @@ on:
workflow_dispatch: # Manual trigger workflow_dispatch: # Manual trigger
pull_request: pull_request:
paths: paths:
- packaging/app.comaps.comaps.metainfo.xml - packaging/app.organicmaps.desktop.metainfo.xml
- .forgejo/workflows/appstream-check.yaml # Run check on self change - .forgejo/workflows/appstream-check.yaml # Run check on self change
jobs: jobs:
validate-appstream: validate-appstream:
name: Validate appstream metadata xml name: Validate appstream metadata xml
runs-on: ubuntu-latest runs-on: ubuntu-24.04
steps: steps:
- name: Checkout sources - name: Checkout sources
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
fetch-depth: 1 fetch-depth: 1
sparse-checkout: | sparse-checkout: |
packaging/app.comaps.comaps.metainfo.xml packaging/app.organicmaps.desktop.metainfo.xml
- name: Install appstream validator and flatpak Builder - name: Install appstream validator and flatpak Builder
shell: bash shell: bash
@@ -25,12 +25,16 @@ jobs:
sudo apt install -y \ sudo apt install -y \
flatpak flatpak
sudo flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo sudo flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
sudo flatpak install -y org.flatpak.Builder sudo flatpak install -y org.freedesktop.appstream-glib org.flatpak.Builder
- name: Validate appstream data
shell: bash
run: flatpak run org.freedesktop.appstream-glib validate --nonet packaging/app.organicmaps.desktop.metainfo.xml
- name: Lint appstream data with flatpak Builder - name: Lint appstream data with flatpak Builder
shell: bash shell: bash
run: flatpak run --command=flatpak-builder-lint org.flatpak.Builder appstream packaging/app.comaps.comaps.metainfo.xml run: flatpak run --command=flatpak-builder-lint org.flatpak.Builder appstream packaging/app.organicmaps.desktop.metainfo.xml
- name: Run appstreamcli in pedantic mode - name: Run appstreamcli in pedantic mode
shell: bash shell: bash
run: flatpak run --command=appstreamcli org.flatpak.Builder validate --pedantic packaging/app.comaps.comaps.metainfo.xml run: flatpak run --command=appstreamcli org.flatpak.Builder validate --pedantic packaging/app.organicmaps.desktop.metainfo.xml

View File

@@ -33,7 +33,7 @@ concurrency:
jobs: jobs:
should-run-check: should-run-check:
name: Should run coverage name: Should run coverage
runs-on: ubuntu-latest runs-on: ubuntu-24.04
outputs: outputs:
run-from-pr: ${{ steps.run-from-pr.outputs.run-from-pr }} run-from-pr: ${{ steps.run-from-pr.outputs.run-from-pr }}
manually-triggered: ${{ steps.manually-triggered.outputs.manually-triggered }} manually-triggered: ${{ steps.manually-triggered.outputs.manually-triggered }}
@@ -59,9 +59,14 @@ jobs:
coverage: coverage:
needs: should-run-check needs: should-run-check
name: Generate coverage report name: Generate coverage report
runs-on: ubuntu-latest runs-on: ubuntu-24.04
if: ${{ needs.should-run-check.outputs.run-from-pr == 'true' || needs.should-run-check.outputs.manually-triggered == 'true'}} if: ${{ needs.should-run-check.outputs.run-from-pr == 'true' || needs.should-run-check.outputs.manually-triggered == 'true'}}
steps: steps:
- name: Free disk space by removing .NET, Android and Haskell
shell: bash
run: |
sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc
- name: Checkout sources - name: Checkout sources
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
@@ -89,6 +94,10 @@ jobs:
llvm \ llvm \
gcovr gcovr
- name: Configure repository
shell: bash
run: ./configure.sh
- name: Configure ccache - name: Configure ccache
uses: hendrikmuhs/ccache-action@v1.2 uses: hendrikmuhs/ccache-action@v1.2
with: with:

View File

@@ -1,9 +0,0 @@
name: DCO
on: [pull_request]
jobs:
check:
runs-on: ubuntu-latest
steps:
- name: Check for Developer Certificate of Origin (DCO) compliance
uses: https://github.com/KineticCafe/actions-dco@fb284c903a7673a3d4b0bdd104479a6f0d46dae7 # v1.3.6

View File

@@ -3,20 +3,20 @@ on:
workflow_dispatch: # Manual trigger workflow_dispatch: # Manual trigger
pull_request: pull_request:
paths: paths:
- qt/res/linux/app.comaps.comaps.desktop - qt/res/app.organicmaps.desktop.desktop
- .forgejo/workflows/desktop-file-check.yaml # Run check on self change - .forgejo/workflows/desktop-file-check.yaml # Run check on self change
jobs: jobs:
validate-desktop-file: validate-desktop-file:
name: Validate .desktop file name: Validate .desktop file
runs-on: ubuntu-latest runs-on: ubuntu-24.04
steps: steps:
- name: Checkout sources - name: Checkout sources
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
fetch-depth: 1 fetch-depth: 1
sparse-checkout: | sparse-checkout: |
qt/res/linux/app.comaps.comaps.desktop qt/res/app.organicmaps.desktop.desktop
- name: Install desktop-file-validate tool - name: Install desktop-file-validate tool
shell: bash shell: bash
@@ -27,4 +27,4 @@ jobs:
- name: Validate desktop file - name: Validate desktop file
shell: bash shell: bash
run: desktop-file-validate qt/res/linux/app.comaps.comaps.desktop && echo "Successfully validated .desktop file" run: desktop-file-validate qt/res/app.organicmaps.desktop.desktop && echo "Successfully validated .desktop file"

View File

@@ -3,7 +3,7 @@ on:
workflow_dispatch: # Manual trigger workflow_dispatch: # Manual trigger
push: push:
branches: branches:
- main - master
paths-ignore: paths-ignore:
- .gitignore - .gitignore
- .forgejo/** - .forgejo/**
@@ -35,7 +35,7 @@ jobs:
name: Apple TestFlight name: Apple TestFlight
runs-on: macos-15 runs-on: macos-15
env: env:
DEVELOPER_DIR: /Applications/Xcode_26.app/Contents/Developer DEVELOPER_DIR: /Applications/Xcode_16.app/Contents/Developer
LANG: en_US.UTF-8 # Fastlane complains that the terminal is using ASCII. LANG: en_US.UTF-8 # Fastlane complains that the terminal is using ASCII.
LANGUAGE: en_US.UTF-8 LANGUAGE: en_US.UTF-8
LC_ALL: en_US.UTF-8 LC_ALL: en_US.UTF-8

View File

@@ -3,7 +3,7 @@ on:
workflow_dispatch: # Manual trigger workflow_dispatch: # Manual trigger
push: push:
branches: branches:
- main - master
pull_request: pull_request:
paths-ignore: paths-ignore:
- .gitignore - .gitignore
@@ -37,11 +37,11 @@ jobs:
name: Build iOS name: Build iOS
runs-on: macos-15 runs-on: macos-15
env: env:
DEVELOPER_DIR: /Applications/Xcode_26.app/Contents/Developer DEVELOPER_DIR: /Applications/Xcode_16.app/Contents/Developer
LANG: en_US.UTF-8 # Fastlane complains that the terminal is using ASCII. LANG: en_US.UTF-8 # Fastlane complains that the terminal is using ASCII.
LANGUAGE: en_US.UTF-8 LANGUAGE: en_US.UTF-8
LC_ALL: en_US.UTF-8 LC_ALL: en_US.UTF-8
TEST_RESULTS_BUNDLE_NAME: CoMaps-Test-Results TEST_RESULTS_BUNDLE_NAME: OMaps-Test-Results
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
@@ -74,8 +74,8 @@ jobs:
shell: bash shell: bash
run: | run: |
xcodebuild test \ xcodebuild test \
-workspace xcode/CoMaps.xcworkspace \ -workspace xcode/omim.xcworkspace \
-scheme CoMaps \ -scheme OMaps \
-configuration Debug \ -configuration Debug \
-sdk iphonesimulator \ -sdk iphonesimulator \
-destination 'platform=iOS Simulator,name=iPhone 16 Pro Max,OS=latest' \ -destination 'platform=iOS Simulator,name=iPhone 16 Pro Max,OS=latest' \
@@ -97,10 +97,10 @@ jobs:
shell: bash shell: bash
run: | run: |
xcodebuild build \ xcodebuild build \
-workspace xcode/CoMaps.xcworkspace \ -workspace xcode/omim.xcworkspace \
-scheme CoMaps \ -scheme OMaps \
-configuration Release \ -configuration Release \
-destination 'generic/platform=iOS' \ -destination 'generic/platform=iOS' \
-quiet \ -quiet \
CODE_SIGNING_REQUIRED=NO \ CODE_SIGNING_REQUIRED=NO \
CODE_SIGNING_ALLOWED=NO CODE_SIGNING_ALLOWED=NO

View File

@@ -7,7 +7,7 @@ jobs:
name: iOS Release name: iOS Release
runs-on: macos-15 runs-on: macos-15
env: env:
DEVELOPER_DIR: /Applications/Xcode_26.app/Contents/Developer DEVELOPER_DIR: /Applications/Xcode_16.app/Contents/Developer
LANG: en_US.UTF-8 # Fastlane complains that the terminal is using ASCII. LANG: en_US.UTF-8 # Fastlane complains that the terminal is using ASCII.
LANGUAGE: en_US.UTF-8 LANGUAGE: en_US.UTF-8
LC_ALL: en_US.UTF-8 LC_ALL: en_US.UTF-8
@@ -29,7 +29,7 @@ jobs:
with: with:
repository: ${{ secrets.SCREENSHOTS_REPO }} repository: ${{ secrets.SCREENSHOTS_REPO }}
ssh-key: ${{ secrets.SCREENSHOTS_SSH_KEY }} ssh-key: ${{ secrets.SCREENSHOTS_SSH_KEY }}
ref: main ref: master
path: screenshots path: screenshots
- name: Checkout keywords - name: Checkout keywords
@@ -37,7 +37,7 @@ jobs:
with: with:
repository: ${{ secrets.KEYWORDS_REPO }} repository: ${{ secrets.KEYWORDS_REPO }}
ssh-key: ${{ secrets.KEYWORDS_SSH_KEY }} ssh-key: ${{ secrets.KEYWORDS_SSH_KEY }}
ref: main ref: master
path: keywords path: keywords
- name: Update metadata - name: Update metadata

View File

@@ -3,7 +3,7 @@ on:
workflow_dispatch: # Manual trigger workflow_dispatch: # Manual trigger
push: push:
branches: branches:
- main - master
pull_request: pull_request:
paths-ignore: paths-ignore:
- .gitignore - .gitignore
@@ -31,13 +31,18 @@ on:
jobs: jobs:
linux-no-unity: linux-no-unity:
name: Linux no unity build name: Linux no unity build
runs-on: ubuntu-latest runs-on: ubuntu-24.04
# Cancels previous jobs if the same branch or PR was updated again. # Cancels previous jobs if the same branch or PR was updated again.
concurrency: concurrency:
group: ${{ github.workflow }}-no-unity-${{ github.event.pull_request.number || github.ref }} group: ${{ github.workflow }}-no-unity-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true cancel-in-progress: true
steps: steps:
- name: Free disk space by removing .NET, Android and Haskell
shell: bash
run: |
sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc
- name: Checkout sources - name: Checkout sources
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
@@ -66,6 +71,10 @@ jobs:
libqt6positioning6-plugins \ libqt6positioning6-plugins \
libqt6positioning6 libqt6positioning6
- name: Configure repository
shell: bash
run: ./configure.sh
- name: Configure ccache - name: Configure ccache
uses: hendrikmuhs/ccache-action@v1.2 uses: hendrikmuhs/ccache-action@v1.2
with: with:
@@ -81,7 +90,7 @@ jobs:
# -g1 should slightly reduce build time. # -g1 should slightly reduce build time.
run: | run: |
cmake . -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug \ cmake . -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_CXX_FLAGS=-g1 -DCMAKE_UNITY_BUILD=OFF -DCMAKE_CXX_FLAGS=-g1 -DUNITY_DISABLE=ON
- name: Compile - name: Compile
shell: bash shell: bash
@@ -90,7 +99,7 @@ jobs:
linux-matrix: linux-matrix:
name: Linux builds and tests name: Linux builds and tests
runs-on: ubuntu-latest runs-on: ubuntu-24.04
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
@@ -102,6 +111,11 @@ jobs:
cancel-in-progress: true cancel-in-progress: true
steps: steps:
- name: Free disk space by removing .NET, Android and Haskell
shell: bash
run: |
sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc
- name: Checkout sources - name: Checkout sources
uses: actions/checkout@v4 uses: actions/checkout@v4
@@ -128,19 +142,15 @@ jobs:
libqt6positioning6-plugins \ libqt6positioning6-plugins \
libqt6positioning6 libqt6positioning6
- name: Configure repository
shell: bash
run: ./configure.sh
- name: Configure ccache - name: Configure ccache
uses: hendrikmuhs/ccache-action@v1.2 uses: hendrikmuhs/ccache-action@v1.2
with: with:
key: ${{ github.workflow }}-unity-${{ matrix.compiler.CC }}-${{ matrix.CMAKE_BUILD_TYPE }} key: ${{ github.workflow }}-unity-${{ matrix.compiler.CC }}-${{ matrix.CMAKE_BUILD_TYPE }}
- name: Configure repository
shell: bash
env:
SKIP_MAP_DOWNLOAD: 1
SKIP_GENERATE_SYMBOLS: 1
SKIP_GENERATE_DRULES: 1
run: ./configure.sh
- name: CMake - name: CMake
shell: bash shell: bash
env: env:

View File

@@ -3,7 +3,7 @@ on:
workflow_dispatch: # Manual trigger workflow_dispatch: # Manual trigger
push: push:
branches: branches:
- main - master
pull_request: pull_request:
paths-ignore: paths-ignore:
- .gitignore - .gitignore
@@ -32,7 +32,7 @@ jobs:
name: macOS builds and tests name: macOS builds and tests
runs-on: macos-15 runs-on: macos-15
env: env:
DEVELOPER_DIR: /Applications/Xcode_26.app/Contents/Developer DEVELOPER_DIR: /Applications/Xcode_16.app/Contents/Developer
HOMEBREW_NO_ANALYTICS: 1 HOMEBREW_NO_ANALYTICS: 1
HOMEBREW_NO_INSTALL_CLEANUP: 1 HOMEBREW_NO_INSTALL_CLEANUP: 1
strategy: strategy:
@@ -57,6 +57,10 @@ jobs:
run: | run: |
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew install ninja qt@6 HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew install ninja qt@6
- name: Configure repository
shell: bash
run: ./configure.sh
- name: Configure ccache - name: Configure ccache
uses: hendrikmuhs/ccache-action@v1.2 uses: hendrikmuhs/ccache-action@v1.2
with: with:

View File

@@ -1,577 +0,0 @@
name: map-generator
on:
workflow_dispatch: # Manual trigger
inputs:
map-generator-test:
description: 'Test (non-prod) generation?'
required: false
default: false
type: boolean
# run-copy-coasts:
# description: 'Copy last used coastlines?'
# required: false
# default: true
# type: boolean
run-isolines:
description: 'Update altitude isolines?'
required: false
default: false
type: boolean
run-tiger:
description: 'Update TIGER address data?'
required: false
default: true
type: boolean
run-planet-pbf:
description: 'Update PBF planet (for Wiki & subways)?'
required: false
default: true
type: boolean
run-subways:
description: 'Update subways?'
required: false
default: true
type: boolean
run-wiki:
description: 'Update Wikipedia descriptions?'
required: false
default: true
type: boolean
run-planet-o5m:
description: 'Update O5M planet (for mapgen)?'
required: false
default: true
type: boolean
run-mapgen:
description: 'Run maps generation?'
required: false
default: true
type: boolean
map-generator-continue:
description: 'Continue previous map generation?'
required: false
default: false
type: boolean
# map-generator-countries:
# description: 'Generate specific MWMs? (i.e. "US_New York_*, foo")'
# required: false
# type: string
run-upload:
description: 'Upload latest maps to CDN?'
required: false
default: false
type: boolean
# reset:
# description: 'Reset part of the system?'
# required: false
# default: 'no'
# type: choice
# options:
# - 'no'
# - wiki-ratelimit
## RCLONE_CONF is multi-line text containing keys and credentials for us2,ru1,fi1,de1 servers
env:
RCLONE_CONF: ${{ secrets.RCLONE_CONF }}
WIKIMEDIA_USERNAME: ${{ secrets.WIKIMEDIA_USERNAME }}
WIKIMEDIA_PASSWORD: ${{ secrets.WIKIMEDIA_PASSWORD }}
ZULIP_BOT_EMAIL: ${{ secrets.ZULIP_BOT_EMAIL }}
ZULIP_API_KEY: ${{ secrets.ZULIP_API_KEY }}
MWMTEST: ${{ inputs.map-generator-test }}
MWMCONTINUE: ${{ inputs.map-generator-continue }}
# MWMCOUNTRIES: ${{ inputs.map-generator-countries }}
DEBIAN_FRONTEND: noninteractive
TZ: Etc/UTC
jobs:
clone-repos:
name: Clone Git Repos
runs-on: mapfilemaker
container:
image: codeberg.org/comaps/maps_generator:f6d53d54f794
volumes:
- /mnt/4tbexternal:/mnt/4tbexternal
concurrency:
group: ${{ github.workflow }}-map-generator-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
steps:
- uses: actions/cache@v4
with:
path: "~"
key: cache-${{ github.run_id }}-${{ github.run_attempt }}
- name: Checkout main repo
shell: bash
run: |
echo "Cloning $FORGEJO_SERVER_URL/$FORGEJO_REPOSITORY branch $FORGEJO_REF_NAME"
cd ~
git clone --depth 1 --recurse-submodules --shallow-submodules -b $FORGEJO_REF_NAME --single-branch $FORGEJO_SERVER_URL/$FORGEJO_REPOSITORY.git comaps
- name: Checkout wikiparser repo
shell: bash
run: |
cd ~
git clone --depth 1 --single-branch https://codeberg.org/comaps/wikiparser.git
- name: Checkout subways repo
shell: bash
run: |
cd ~
git clone --depth 1 --single-branch https://codeberg.org/comaps/subways.git
copy-coasts:
# if: inputs.run-copy-coasts
name: Copy Previously Generated Coasts
runs-on: mapfilemaker
container:
image: codeberg.org/comaps/maps_generator:f6d53d54f794
volumes:
- /mnt/4tbexternal/:/mnt/4tbexternal/
- /mnt/4tbexternal/osm-planet:/home/planet
concurrency:
group: ${{ github.workflow }}-map-generator-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
steps:
- name: Copy Coasts
shell: bash
run: |
echo "WorldCoasts available:"
ls -al /mnt/4tbexternal/osm-maps/*/intermediate_data/WorldCoasts.*
if [ -f /mnt/4tbexternal/osm-maps/*/intermediate_data/WorldCoasts.geom ]; then
echo "Before:"
ls -al /home/planet/latest_coasts*
# TODO: don't copy coasts from test generations
cp -p /mnt/4tbexternal/osm-maps/*/intermediate_data/WorldCoasts.geom /home/planet/latest_coasts.geom
cp -p /mnt/4tbexternal/osm-maps/*/intermediate_data/WorldCoasts.rawgeom /home/planet/latest_coasts.rawgeom
echo "After:"
ls -al /home/planet/latest_coasts*
else
echo "No WorldCoasts found."
fi
update-isolines:
if: inputs.run-isolines
name: Update Isolines
runs-on: mapfilemaker
needs:
- clone-repos
container:
image: codeberg.org/comaps/maps_generator:f6d53d54f794
volumes:
- /mnt/4tbexternal/:/mnt/4tbexternal/
- /mnt/4tbexternal/osm-planet:/home/planet
concurrency:
group: ${{ github.workflow }}-map-generator-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
steps:
- uses: actions/cache@v4
with:
path: "~"
key: cache-${{ github.run_id }}-${{ github.run_attempt }}
# TODO: we only need to update these if our SRTM or countries change
# TODO: after update, verify that sizable files exist: /home/planet/isolines/*.isolines
- name: Update Isolines
shell: bash
# TODO: preserve previous isolines version?
# TODO: cleanup the tmp-tiles dir after completion
run: |
cd ~/comaps/
./tools/unix/build_omim.sh -p ~ -R topography_generator_tool
rm -rf /home/planet/isolines/
mkdir /home/planet/isolines/
~/omim-build-relwithdebinfo/topography_generator_tool \
--profiles_path=./data/conf/isolines/isolines-profiles.json \
--countries_to_generate_path=./data/conf/isolines/countries-to-generate.json \
--tiles_isolines_out_dir=/home/planet/isolines/tmp-tiles/ \
--countries_isolines_out_dir=/home/planet/isolines/ \
--data_dir=./data/ \
--srtm_path=/home/planet/SRTM-patched-europe/ \
--threads=96
- name: Check isolines
shell: bash
run: |
NUMISO=$(ls -al /home/planet/isolines/*.isolines | wc -l)
echo "Found $NUMISO isolines"
if [ $NUMISO -lt 10 ]; then
echo "ERROR: Did generation fail?"
exit 1
fi
- name: Notify Zulip
run: |
curl -X POST https://comaps.zulipchat.com/api/v1/messages \
-u $ZULIP_BOT_EMAIL:$ZULIP_API_KEY \
--data-urlencode type=stream \
--data-urlencode 'to="DevOps"' \
--data-urlencode topic=codeberg-bot \
--data-urlencode 'content=Isolines are done!'
update-tiger:
if: inputs.run-tiger
name: Update TIGER
runs-on: mapfilemaker
needs:
- clone-repos
container:
image: codeberg.org/comaps/maps_generator:f6d53d54f794
volumes:
- /mnt/4tbexternal/:/mnt/4tbexternal/
- /mnt/4tbexternal/osm-planet:/home/planet
concurrency:
group: ${{ github.workflow }}-map-generator-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
steps:
- uses: actions/cache@v4
with:
path: "~"
key: cache-${{ github.run_id }}-${{ github.run_attempt }}
- name: Build address_parser
shell: bash
run: |
cd ~/comaps
#rm -rf ~/omim-build-relwithdebinfo/CMakeCache.txt
#rm -rf ~/omim-build-relwithdebinfo/CMakeFiles
./tools/unix/build_omim.sh -p ~ -R address_parser_tool
- name: Update TIGER from Nominatim
shell: bash
# TODO: use curl instead of wget2
run: |
# TODO: maybe remove old osm-planet/tiger first?
cd /home/planet/
mkdir -p tiger
wget2 https://nominatim.org/data/tiger-nominatim-preprocessed-latest.csv.tar.gz
cd ~/comaps
tar -xOzf /home/planet/tiger-nominatim-preprocessed-latest.csv.tar.gz | ~/omim-build-relwithdebinfo/address_parser_tool --output_path=/home/planet/tiger
update-planet-pbf:
if: inputs.run-planet-pbf
name: Update PBF Planet
runs-on: mapfilemaker
container:
image: codeberg.org/comaps/maps_generator:f6d53d54f794
volumes:
- /mnt/4tbexternal/:/mnt/4tbexternal/
- /mnt/4tbexternal/osm-planet:/home/planet
concurrency:
group: ${{ github.workflow }}-map-generator-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
steps:
- name: Download Planet File if Absent
shell: bash
# TODO: replace wget2 with curl -Z
run: |
if [ ! -d /home/planet/planet/ ]; then
mkdir -p /home/planet/planet/
fi
if [ ! -f /home/planet/planet/planet-latest.osm.pbf ]; then
cd /home/planet/planet/
wget2 --verbose --progress=bar --continue https://ftpmirror.your.org/pub/openstreetmap/pbf/planet-latest.osm.pbf
else
echo "planet-latest.osm.pbf was found, raw download not required."
fi
- name: Update PBF Planet
shell: bash
run: |
cd /home/planet/planet/
rm -f planet-latest-new.osm.pbf
pyosmium-up-to-date planet-latest.osm.pbf -o planet-latest-new.osm.pbf -v --size 16384
mv planet-latest-new.osm.pbf planet-latest.osm.pbf
- name: Notify Zulip
run: |
curl -X POST https://comaps.zulipchat.com/api/v1/messages \
-u $ZULIP_BOT_EMAIL:$ZULIP_API_KEY \
--data-urlencode type=stream \
--data-urlencode 'to="DevOps"' \
--data-urlencode topic=codeberg-bot \
--data-urlencode 'content=PBF planet update is done!'
update-subways:
if: inputs.run-subways
name: Update Subways
runs-on: mapfilemaker
needs:
- clone-repos
container:
image: codeberg.org/comaps/maps_generator:f6d53d54f794
volumes:
- /mnt/4tbexternal/:/mnt/4tbexternal/
- /mnt/4tbexternal/osm-planet:/home/planet
concurrency:
group: ${{ github.workflow }}-map-generator-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
steps:
- uses: actions/cache@v4
with:
path: "~"
key: cache-${{ github.run_id }}-${{ github.run_attempt }}
- name: Update Subways
shell: bash
run: |
cd ~/comaps/
cp tools/unix/maps/settings.sh.prod tools/unix/maps/settings.sh
./tools/unix/maps/generate_subways.sh
- name: Notify Zulip
run: |
curl -X POST https://comaps.zulipchat.com/api/v1/messages \
-u $ZULIP_BOT_EMAIL:$ZULIP_API_KEY \
--data-urlencode type=stream \
--data-urlencode 'to="DevOps"' \
--data-urlencode topic=codeberg-bot \
--data-urlencode 'content=Subways are done!'
wiki-update:
if: inputs.run-wiki
name: Update Wikipedia
runs-on: mapfilemaker
needs:
- clone-repos
container:
image: codeberg.org/comaps/maps_generator:f6d53d54f794
volumes:
- /mnt/4tbexternal/:/mnt/4tbexternal/
- /mnt/4tbexternal/osm-planet:/home/planet
concurrency:
group: ${{ github.workflow }}-map-generator-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
steps:
- uses: actions/cache@v4
with:
path: "~"
key: cache-${{ github.run_id }}-${{ github.run_attempt }}
- name: Check for planet file
shell: bash
# TODO: remove debug output
run: |
if [ ! -f /home/planet/planet/planet-latest.osm.pbf ]; then
echo "ERROR: No file at /home/planet/planet/planet-latest.osm.pbf"
ls -al /home/planet/
ls -al /home/planet/planet/
exit 1
fi
- name: Only get new dumps once per 30 days
shell: bash
run: |
if [[ '${{ inputs.reset }}' == 'wiki-ratelimit' ]]; then
echo "Bypassing wiki rate limit upon request."
exit 0
fi
datediff() {
d1=$(date -d "$1" +%s)
d2=$(date -d "$2" +%s)
echo $(( (d1 - d2) / 86400 ))
}
RECENTDUMPDATE=$(find /home/planet/wikipedia/dumps/ -mindepth 1 -maxdepth 1 -iname "2*" -type d | sort -n -r | head -1 | cut -d/ -f6)
TODAY=$(date +%Y%m%d)
DATEDIFF=$(datediff $TODAY $RECENTDUMPDATE)
if [ $DATEDIFF -lt 30 ]; then
echo "ERROR: The most recent wiki dump is from $RECENTDUMPDATE, $DATEDIFF days ago. Wikimedia limits users to 15 snapshot requests per month."
echo "Set the 'reset' option to 'wiki-ratelimit' to bypass this."
ls -al /home/planet/wikipedia/dumps/
exit 1
fi
- name: Update Wikipedia from Enterprise API
shell: bash
run: |
#todo: curl in download.sh can fail when rate limited and even save error messages to the output. need to validate.
#downloading all languages can also trigger rate limits or fail as well. needs work.
#also: a failure to download means a failure to build, and could result in no wiki descriptions etc.
#also-also: do we want to remove old wiki data in planet between builds? pastk: no need, its being updated / augmented
mkdir -p /home/planet/wikipedia/dumps
mkdir -p /home/planet/wikipedia/build
cd ~/wikiparser
ls -al
echo "Downloading ..."
./download.sh /home/planet/wikipedia/dumps
ls -al /home/planet/wikipedia/dumps/*
echo "Running ..."
./run.sh /home/planet/wikipedia/build \
/home/planet/planet/planet-latest.osm.pbf \
/home/planet/wikipedia/dumps/latest/*.tar.gz
echo "DONE"
- name: Check that the latest dumps are present, recent, and not super tiny
shell: bash
run: |
FAILCHECK=0
# Check all .tar.gz files in /home/planet/wikipedia/dumps/latest/
for file in /home/planet/wikipedia/dumps/latest/*.tar.gz; do
# Check if file exists (handles case where glob doesn't match)
[ -e "$file" ] || continue
# Get file size in MB and modification time in days
size_mb=$(stat -f%z "$file" 2>/dev/null | awk '{print int($1/1024/1024)}' || stat -c%s "$file" | awk
'{print int($1/1024/1024)}')
days_old=$(find "$file" -mtime -7 | wc -l)
# Verify conditions
if [ "$size_mb" -lt 100 ]; then
echo "FAIL: $file is only ${size_mb}MB (< 100MB)"
FAILCHECK=1
elif [ "$days_old" -eq 0 ]; then
echo "FAIL: $file is older than 7 days"
ls -al $file
FAILCHECK=1
else
echo "PASS: $file (${size_mb}MB, modified within 7 days)"
fi
done
exit $FAILCHECK
- name: Notify Zulip
run: |
curl -X POST https://comaps.zulipchat.com/api/v1/messages \
-u $ZULIP_BOT_EMAIL:$ZULIP_API_KEY \
--data-urlencode type=stream \
--data-urlencode 'to="DevOps"' \
--data-urlencode topic=codeberg-bot \
--data-urlencode 'content=Wiki update is done!'
update-planet-o5m:
if: inputs.run-planet-o5m
name: Update O5M Planet
runs-on: mapfilemaker
container:
image: codeberg.org/comaps/maps_generator:f6d53d54f794
volumes:
- /mnt/4tbexternal/:/mnt/4tbexternal/
- /mnt/4tbexternal/osm-planet:/home/planet
concurrency:
group: ${{ github.workflow }}-map-generator-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
steps:
- name: Check for O5M Planet File
shell: bash
run: |
if [ ! -f /home/planet/planet/planet.o5m ]; then
echo "WARN: No file at /home/planet/planet/planet.o5m"
if [ ! -f /home/planet/planet/planet-latest.osm.pbf ]; then
echo "ERROR: No file at /home/planet/planet/planet-latest.osm.pbf"
ls -al /home/planet/
ls -al /home/planet/planet/
exit 1
fi
echo "Converting planet-latest.osm.pbf to planet.o5m"
cd /home/planet/planet/
osmconvert -v --drop-author --drop-version --hash-memory=4000 planet-latest.osm.pbf -o=planet.o5m
echo "Conversion is done."
fi
- name: Update O5M planet
run: |
echo "Starting..."
cd /home/planet/planet/
rm -f planet-new.o5m
osmupdate -v --drop-author --drop-version --hash-memory=4000 --max-merge=32 --out-o5m planet.o5m planet-new.o5m
mv planet-new.o5m planet.o5m
echo "Done."
- name: Notify Zulip
run: |
curl -X POST https://comaps.zulipchat.com/api/v1/messages \
-u $ZULIP_BOT_EMAIL:$ZULIP_API_KEY \
--data-urlencode type=stream \
--data-urlencode 'to="DevOps"' \
--data-urlencode topic=codeberg-bot \
--data-urlencode 'content=O5M planet update is done!'
generate-maps:
if: inputs.run-mapgen
name: Generate Maps
runs-on: mapfilemaker
needs:
- clone-repos
timeout-minutes: 40320
container:
image: codeberg.org/comaps/maps_generator:f6d53d54f794
volumes:
- /mnt/4tbexternal/:/mnt/4tbexternal/
- /mnt/4tbexternal/osm-planet:/home/planet
options: --ulimit nofile=262144:262144
concurrency:
group: ${{ github.workflow }}-map-generator-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
steps:
- uses: actions/cache@v4
with:
path: "~"
key: cache-${{ github.run_id }}-${{ github.run_attempt }}
- name: Make output folders if necessary
shell: bash
run: |
if [ ! -d /mnt/4tbexternal/osm-maps ]; then
mkdir -p /mnt/4tbexternal/osm-maps
fi
- name: Get SRTM if necessary
# TODO: it should be a separate step like Wiki or isolines
shell: bash
run: |
if [ ! -d /home/planet/SRTM-patched-europe/ ]; then
echo "ERROR: NO SRTM"
exit 1
fi
- name: Run docker_maps_generator.sh
shell: bash
run: |
cd ~/comaps
bash ./tools/unix/maps/docker_maps_generator.sh
- name: Notify Zulip
run: |
curl -X POST https://comaps.zulipchat.com/api/v1/messages \
-u $ZULIP_BOT_EMAIL:$ZULIP_API_KEY \
--data-urlencode type=stream \
--data-urlencode 'to="DevOps"' \
--data-urlencode topic=codeberg-bot \
--data-urlencode 'content=Generator is done!'
upload-maps:
if: inputs.run-upload
name: Upload Maps
runs-on: mapfilemaker
container:
image: codeberg.org/comaps/maps_generator:f6d53d54f794
volumes:
- /mnt/4tbexternal/:/mnt/4tbexternal/
- /mnt/4tbexternal/osm-planet:/home/planet
concurrency:
group: ${{ github.workflow }}-map-generator-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
steps:
- uses: actions/cache@v4
with:
path: "~"
key: cache-${{ github.run_id }}-${{ github.run_attempt }}
- name: Write config file
run: |
mkdir -p ~/.config/rclone/
echo "${{ secrets.RCLONE_CONF }}" > ~/.config/rclone/rclone.conf
- name: Upload map files to CDNs
shell: bash
run: |
shopt -s nullglob
buildfolder=$(find /mnt/4tbexternal/osm-maps/ -mindepth 1 -maxdepth 1 -iname "2*" -type d | sort -n -r | head -1 | cut -d/ -f5)
builddate=$(find /mnt/4tbexternal/osm-maps/*/ -mindepth 1 -maxdepth 1 -iname "2*" -type d | sort -n -r | head -1 | cut -d/ -f6)
mwmfiles=( /mnt/4tbexternal/osm-maps/$buildfolder/$builddate/*.mwm )
if (( ${#mwmfiles[@]} )); then
echo "<$(date +%T)> Uploading maps from $buildfolder/$builddate..."
cd ~/comaps/tools/unix/maps
./upload_to_cdn.sh /mnt/4tbexternal/osm-maps/$buildfolder/$builddate
echo "<$(date +%T)> Finished uploading maps from $buildfolder/$builddate."
else
echo "<$(date +%T)> No MWM files in /mnt/4tbexternal/osm-maps/$buildfolder/$builddate/*.mwm, not uploading maps."
echo "<$(date +%T)> Found top level: $(ls -alt /mnt/4tbexternal/osm-maps/*)"
echo "<$(date +%T)> Found second level: $(ls -alt /mnt/4tbexternal/osm-maps/$buildfolder/*)"
fi
- name: Notify Zulip
run: |
curl -X POST https://comaps.zulipchat.com/api/v1/messages \
-u $ZULIP_BOT_EMAIL:$ZULIP_API_KEY \
--data-urlencode type=stream \
--data-urlencode 'to="DevOps"' \
--data-urlencode topic=codeberg-bot \
--data-urlencode 'content=Upload is done!'

View File

@@ -1,129 +0,0 @@
name: process_subways
on:
workflow_dispatch: # Manual trigger
env:
PLANET: /home/planet/planet/planet.o5m
TMPDIR: /tmp
HTML_DIR: "/mnt/4tbexternal/osm-planet/subway/validator"
DUMP: "$HTML_DIR"
SKIP_PLANET_UPDATE: "1"
DEBIAN_FRONTEND: nonnteractive
TZ: Etc/UTC
# /var/www/html/subways is mapped as a volume on cdn-fi-1
# as is /tmp/planet
jobs:
clone-repos:
name: Clone Git Repos
runs-on: mapfilemaker
container:
image: codeberg.org/comaps/maps_generator:f6d53d54f794
volumes:
- /mnt/4tbexternal:/mnt/4tbexternal
concurrency:
group: ${{ github.workflow }}-process-subways-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
steps:
- uses: actions/cache@v4
with:
path: "~"
key: cache-${{ github.run_id }}-${{ github.run_attempt }}
- name: Checkout subways repo
shell: bash
run: |
cd ~
git clone --depth 1 --single-branch https://codeberg.org/comaps/subways.git
update-planet-o5m:
name: Update O5M Planet
runs-on: mapfilemaker
container:
image: codeberg.org/comaps/maps_generator:f6d53d54f794
volumes:
- /mnt/4tbexternal/:/mnt/4tbexternal/
- /mnt/4tbexternal/osm-planet:/home/planet
concurrency:
group: ${{ github.workflow }}-process-subways-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
steps:
- name: Check for O5M Planet File
shell: bash
run: |
if [ ! -f /home/planet/planet/planet.o5m ]; then
echo "WARN: No file at /home/planet/planet/planet.o5m"
if [ ! -f /home/planet/planet/planet-latest.osm.pbf ]; then
echo "ERROR: No file at /home/planet/planet/planet-latest.osm.pbf"
ls -al /home/planet/
ls -al /home/planet/planet/
exit 1
fi
echo "Converting planet-latest.osm.pbf to planet.o5m"
cd /home/planet/planet/
osmconvert -v --drop-author --drop-version --hash-memory=4000 planet-latest.osm.pbf -o=planet.o5m
echo "Conversion is done."
fi
- name: Update O5M planet
run: |
echo "Starting..."
cd /home/planet/planet/
rm -f planet-new.o5m
osmupdate -v --drop-author --drop-version --hash-memory=4000 --max-merge=32 --out-o5m planet.o5m planet-new.o5m
mv planet-new.o5m planet.o5m
echo "Done."
- name: Notify Zulip
run: |
curl -X POST https://comaps.zulipchat.com/api/v1/messages \
-u $ZULIP_BOT_EMAIL:$ZULIP_API_KEY \
--data-urlencode type=stream \
--data-urlencode 'to="DevOps"' \
--data-urlencode topic=codeberg-bot \
--data-urlencode 'content=O5M planet update is done!'
update-subways:
if: inputs.run-subways
name: Update Subways
runs-on: mapfilemaker
needs:
- clone-repos
container:
image: codeberg.org/comaps/maps_generator:f6d53d54f794
volumes:
- /mnt/4tbexternal/:/mnt/4tbexternal/
- /mnt/4tbexternal/osm-planet:/home/planet
concurrency:
group: ${{ github.workflow }}-map-generator-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
steps:
- uses: actions/cache@v4
with:
path: "~"
key: cache-${{ github.run_id }}-${{ github.run_attempt }}
- name: Update Subways
shell: bash
run: |
cd ~/comaps/
cp tools/unix/maps/settings.sh.prod tools/unix/maps/settings.sh
./tools/unix/maps/generate_subways.sh
- name: Compare with VK validation
shell: bash
run: |
cd ~/subways
if [ -f "$HTML_DIR/index.html" ]; then
echo "Comparing local validation with VK's validation..."
python3 ./scripts/compare_html_validation.py "$HTML_DIR/index.html" \
--vk-url "https://maps.vk.com/osm/tools/subways/latest/index.html"
else
echo "Local index.html not found at $HTML_DIR/index.html"
exit 1
fi
- name: Notify Zulip
run: |
curl -X POST https://comaps.zulipchat.com/api/v1/messages \
-u $ZULIP_BOT_EMAIL:$ZULIP_API_KEY \
--data-urlencode type=stream \
--data-urlencode 'to="DevOps"' \
--data-urlencode topic=codeberg-bot \
--data-urlencode 'content=Subways are done!'

View File

@@ -0,0 +1,22 @@
name: Close stale PRs
on:
schedule:
- cron: "0 0 * * *" # Runs every day at midnight
jobs:
stale:
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- uses: actions/stale@v9
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
days-before-pr-stale: 180 # 6 months before warning
days-before-pr-close: 365 # Closed after 12 months
stale-pr-label: "stale"
stale-pr-message: "Hi! This PR has been inactive for 6 months. If it's still relevant, please update it to let us know youd like to keep it open 😊"
close-pr-message: "This PR has been automatically closed after 12 months of inactivity."
days-before-issue-stale: -1 # Issues are never stale
days-before-issue-close: -1 # Issues are never closed
remove-stale-when-updated: true

3
.github/FUNDING.yml vendored
View File

@@ -1,3 +0,0 @@
open_collective: comaps
liberapay: comaps
custom: ["https://comaps.app/donate/"]

View File

@@ -1,110 +0,0 @@
name: Android Check
on:
workflow_dispatch: # Manual trigger
push:
branches:
- main
env:
JAVA_HOME: /usr/lib/jvm/temurin-21-jdk-amd64 # Java 21 is required for Android Gradle 8 plugin
SKIP_MAP_DOWNLOAD: true
jobs:
lint:
name: Android Lint
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Parallel submodules checkout
shell: bash
run: git submodule update --depth 1 --init --recursive --jobs=$(($(nproc) * 20))
- name: Install protobuf
shell: bash
run: |
sudo apt-get update -y
sudo apt-get install -y python3-pip
pip install "protobuf<3.21" --break-system-packages
- name: Configure repository
shell: bash
run: ./configure.sh
- name: Lint
shell: bash
working-directory: android
run: ./gradlew -Pandroidauto=true lint
android-check:
name: Build Android apps
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
flavor: [WebBeta, FdroidDebug]
include:
- flavor: WebBeta
arch: arm64
- flavor: FdroidDebug
arch: arm32
# Cancels previous jobs if the same branch or PR was updated again.
concurrency:
group: ${{ github.workflow }}-${{ matrix.flavor }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
steps:
- name: Install build tools and dependencies
shell: bash
run: |
sudo apt-get update -y
sudo apt-get install -y ninja-build \
qt6-base-dev \
qt6-declarative-dev \
qt6-positioning-dev \
libqt6svg6-dev \
optipng \
libfreetype-dev \
libharfbuzz-dev \
libxrandr-dev \
libxinerama-dev \
libxcursor-dev \
libxi-dev \
python3-pip \
zlib1g-dev
pip install "protobuf<3.21" --break-system-packages
- name: Checkout sources
uses: actions/checkout@v4
with:
fetch-depth: 200 # enough to get all commits for the current day
- name: Parallel submodules checkout
shell: bash
run: git submodule update --depth 1 --init --recursive --jobs=$(($(nproc) * 20))
- name: Configure ccache
uses: hendrikmuhs/ccache-action@v1.2
with:
key: ${{ github.workflow }}-${{ matrix.flavor }}
- name: Compile ${{ matrix.flavor }}
shell: bash
working-directory: android
env:
CMAKE_C_COMPILER_LAUNCHER: ccache
CMAKE_CXX_COMPILER_LAUNCHER: ccache
run: |
cmake --version
ninja --version
./gradlew -P${{ matrix.arch }} assemble${{ matrix.flavor }}
- name: Upload ${{ matrix.flavor }} apk
uses: actions/upload-artifact@v4
with:
name: android-${{ matrix.flavor }}
path: android/app/build/outputs/apk/**/CoMaps-*.apk
if-no-files-found: error

View File

@@ -1,51 +0,0 @@
name: Code style check
on:
pull_request:
branches: [ master ]
paths: # Should stay in sync with tools/unix/clang-format.sh
- '.github/workflows/code-style-check.yaml'
- 'android/app/src/**.java'
- 'android/sdk/src/**.java'
- 'android/sdk/src/main/cpp/**.[ch]pp'
- 'dev_sandbox/**.[ch]pp'
- 'generator/**.[ch]pp'
- 'iphone/**.[ch]pp'
- 'iphone/**.[hm]'
- 'iphone/**.mm'
- 'libs/**.[ch]pp'
- 'libs/**.[hm]'
- '!libs/indexer/drules_struct.pb.h'
- 'libs/**.mm'
- 'qt/**.[ch]pp'
- 'qt/**.h'
- 'tools/**.[ch]pp'
- '.clang-format'
- '.clang-format-ignore'
jobs:
code-style-check:
runs-on: ubuntu-latest
steps:
- name: Install clang-format
run: |
sudo apt purge -y clang-format-18 # Remove default old version of clang-format
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
echo 'deb http://apt.llvm.org/noble/ llvm-toolchain-noble-20 main' | sudo tee /etc/apt/sources.list.d/llvm-toolchain-noble-20.list
sudo apt-get update
sudo apt-get install -y clang-format-20
sudo update-alternatives --force --install /usr/bin/clang-format clang-format /usr/bin/clang-format-20 10
sudo update-alternatives --force --install /usr/bin/git-clang-format git-clang-format /usr/bin/git-clang-format-20 10
clang-format --version
- name: Checkout sources
uses: actions/checkout@v4
- name: Check code style
run: tools/unix/clang-format.sh
- name: Post clang-format comments
if: failure()
uses: reviewdog/action-suggester@v1.21.0
with:
tool_name: clang-format
fail_level: error

View File

@@ -1,91 +0,0 @@
name: iOS Check
on:
workflow_dispatch: # Manual trigger
push:
branches:
- main
jobs:
ios-check:
name: Build iOS
runs-on: macos-26
env:
DEVELOPER_DIR: /Applications/Xcode_26.1.app/Contents/Developer
LANG: en_US.UTF-8 # Fastlane complains that the terminal is using ASCII.
LANGUAGE: en_US.UTF-8
LC_ALL: en_US.UTF-8
TEST_RESULTS_BUNDLE_NAME: CoMaps-Test-Results
SIMULATOR_DEVICE: 'iPhone 17 Pro Max'
strategy:
fail-fast: false
matrix:
buildType: [Debug, Release]
# Cancels previous jobs if the same branch or PR was updated again.
concurrency:
group: ${{ github.workflow }}-${{ matrix.buildType }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
steps:
- name: Install dependencies
run: |
brew install qt \
optipng
pip3 install "protobuf<3.21" --break-system-packages
xcodebuild -downloadComponent metalToolchain
xcodebuild -downloadPlatform iOS
- name: Checkout sources
uses: actions/checkout@v4
- name: Parallel submodules checkout
shell: bash
run: git submodule update --depth 1 --init --recursive --jobs=$(($(sysctl -n hw.logicalcpu) * 20))
- name: Configure repository
shell: bash
run: ./configure.sh
- name: Configure Xcode cache
uses: irgaly/xcode-cache@v1
with:
key: xcode-cache-deriveddata-${{ github.workflow }}-${{ matrix.buildType }}-${{ github.sha }}
restore-keys: xcode-cache-deriveddata-${{ github.workflow }}-${{ matrix.buildType }}
- name: Build and Run Tests (Debug)
if: matrix.buildType == 'Debug'
shell: bash
run: |
# Start sim before the build to make sure it's booted when tests start.
xcrun simctl boot "${{ env.SIMULATOR_DEVICE }}" || true
xcrun simctl bootstatus "${{ env.SIMULATOR_DEVICE }}" -b
xcodebuild test \
-workspace xcode/CoMaps.xcworkspace \
-scheme CoMaps \
-configuration Debug \
-sdk iphonesimulator \
-destination "platform=iOS Simulator,name=${{ env.SIMULATOR_DEVICE }},OS=latest" \
-quiet \
-resultBundlePath ${{ env.TEST_RESULTS_BUNDLE_NAME }}.xcresult \
CODE_SIGNING_REQUIRED=NO \
CODE_SIGNING_ALLOWED=NO
- name: Upload Test Results On Failure (Debug)
if: ${{ matrix.buildType == 'Debug' && failure() }}
uses: actions/upload-artifact@v4
with:
name: ${{ env.TEST_RESULTS_BUNDLE_NAME }}-${{ github.run_number }}.xcresult
path: ${{ env.TEST_RESULTS_BUNDLE_NAME }}.xcresult
if-no-files-found: error
- name: Build (Release)
if: matrix.buildType == 'Release'
shell: bash
run: |
xcodebuild build \
-workspace xcode/CoMaps.xcworkspace \
-scheme CoMaps \
-configuration Release \
-destination 'generic/platform=iOS' \
-quiet \
CODE_SIGNING_REQUIRED=NO \
CODE_SIGNING_ALLOWED=NO

49
.gitignore vendored
View File

@@ -9,35 +9,23 @@ Makefile.Release
object_script.*.Debug object_script.*.Debug
object_script.*.Release object_script.*.Release
compile_commands.json compile_commands.json
*.local.*
stxxl.errlog stxxl.errlog
stxxl.log stxxl.log
screenlog.0 screenlog.0
data/styles/*/*/out/*
data/resources-*_design/*
# symbols png/sdf are now generated at build # symbols png/sdf are now generated at build
data/symbols/**/symbols.png data/resources-*_*/symbols.png
data/symbols/**/symbols.sdf data/resources-*_*/symbols.sdf
data/drules_proto_default_design.bin
data/colors_design.txt
data/patterns_design.txt
data/bookmarks data/bookmarks
data/edits.xml data/edits.xml
data/World.mwm data/World.mwm
data/WorldCoasts.mwm data/WorldCoasts.mwm
data/world_mwm/*
data/*_hash
data/drules_proto*
data/classificator.txt*
data/types.txt*
data/visibility.txt*
data/colors.txt*
data/patterns.txt*
# TODO: designer is not used at the moment
# data/symbols/*/design/
# data/colors_design.txt
# data/patterns_design.txt
# Auto-generated from data/categories-strings/* by tools/unix/generate_categories.sh
data/categories.txt
# Compiled Python # Compiled Python
*.pyc *.pyc
@@ -56,9 +44,10 @@ omim.sdf
*.suo *.suo
*.aps *.aps
*.rc *.rc
!qt/res/windows/windows.rc !qt/res/windows.rc
*.pdb *.pdb
out/ out/*
qt/mapswithme.log
# XCode # XCode
xcode/keys/* xcode/keys/*
@@ -73,7 +62,7 @@ iphone/*/build/*
tools/emacsmode/build tools/emacsmode/build
**/DerivedData/* **/DerivedData/*
**/xcshareddata/* **/xcshareddata/*
!iphone/Maps/Maps.xcodeproj/xcshareddata/xcschemes/CoMaps.xcscheme !iphone/Maps/Maps.xcodeproj/xcshareddata/xcschemes/OMaps.xcscheme
**/xcuserdata **/xcuserdata
**/xcschemes **/xcschemes
iphone/**/*.moved-aside iphone/**/*.moved-aside
@@ -150,13 +139,14 @@ private.h
android/release.keystore android/release.keystore
android/secure.properties android/secure.properties
android/libnotify.properties android/libnotify.properties
android/google-services.json
android/google-play.json android/google-play.json
android/firebase-app-distribution.json
android/firebase-test-lab.json
android/huawei-appgallery.json android/huawei-appgallery.json
android/res/xml/network_security_config.xml android/res/xml/network_security_config.xml
./server/ ./server/
iphone/Maps/app.omaps/ iphone/Maps/app.omaps/
# Generated file
libs/indexer/localized_types_map.cpp
*.li *.li
@@ -188,7 +178,10 @@ tools/python/*/venv/
# Configs # Configs
tools/python/maps_generator/var/etc/map_generator.ini tools/python/maps_generator/var/etc/map_generator.ini
tools/python/routing/etc/*.ini tools/python/routing/etc/*.ini
tools/unix/maps/settings.sh
# Helpers
/node_modules/
/package-lock.json
# Visual Studio # Visual Studio
.vs .vs
@@ -196,3 +189,9 @@ tools/unix/maps/settings.sh
# VS Code # VS Code
.vscode .vscode
.cache .cache
# AppStore metadata
screenshots/
android/src/google/play/listings/
keywords/
iphone/metadata/**/keywords.txt

12
.gitmodules vendored
View File

@@ -1,12 +1,12 @@
[submodule "tools/osmctools"] [submodule "tools/osmctools"]
path = tools/osmctools path = tools/osmctools
url = https://github.com/organicmaps/osmctools.git url = https://git.omaps.dev/organicmaps/osmctools.git
[submodule "tools/kothic"] [submodule "tools/kothic"]
path = tools/kothic path = tools/kothic
url = https://codeberg.org/comaps/kothic.git url = https://git.omaps.dev/organicmaps/kothic.git
[submodule "3party/protobuf/protobuf"] [submodule "3party/protobuf/protobuf"]
path = 3party/protobuf/protobuf path = 3party/protobuf/protobuf
url = https://codeberg.org/comaps/protobuf.git url = https://git.omaps.dev/organicmaps/protobuf.git
[submodule "3party/Vulkan-Headers"] [submodule "3party/Vulkan-Headers"]
path = 3party/Vulkan-Headers path = 3party/Vulkan-Headers
url = https://github.com/KhronosGroup/Vulkan-Headers.git url = https://github.com/KhronosGroup/Vulkan-Headers.git
@@ -17,7 +17,7 @@
ignore = dirty ignore = dirty
[submodule "3party/just_gtfs"] [submodule "3party/just_gtfs"]
path = 3party/just_gtfs path = 3party/just_gtfs
url = https://github.com/organicmaps/just_gtfs.git url = https://git.omaps.dev/organicmaps/just_gtfs.git
branch = for-usage-as-submodule branch = for-usage-as-submodule
[submodule "3party/expat"] [submodule "3party/expat"]
path = 3party/expat path = 3party/expat
@@ -65,7 +65,3 @@
[submodule "3party/imgui/imgui"] [submodule "3party/imgui/imgui"]
path = 3party/imgui/imgui path = 3party/imgui/imgui
url = https://github.com/ocornut/imgui url = https://github.com/ocornut/imgui
[submodule "3party/glaze"]
path = 3party/glaze
url = https://github.com/stephenberry/glaze
branch = main

View File

@@ -31,10 +31,9 @@ if (NOT WITH_SYSTEM_PROVIDED_3PARTY)
set(JANSSON_WITHOUT_TESTS ON) set(JANSSON_WITHOUT_TESTS ON)
add_subdirectory(jansson/jansson/) add_subdirectory(jansson/jansson/)
target_include_directories(jansson INTERFACE "${PROJECT_BINARY_DIR}/3party/jansson/jansson/include") target_include_directories(jansson INTERFACE "${PROJECT_BINARY_DIR}/3party/jansson/jansson/include")
add_library(jansson::jansson ALIAS jansson)
# Add gflags library. # Add gflags library.
set(GFLAGS_BUILD_TESTING OFF)
set(GFLAGS_BUILD_PACKAGING OFF)
add_subdirectory(gflags) add_subdirectory(gflags)
target_compile_options(gflags_nothreads_static PRIVATE $<$<CXX_COMPILER_ID:GNU>:-Wno-subobject-linkage>) target_compile_options(gflags_nothreads_static PRIVATE $<$<CXX_COMPILER_ID:GNU>:-Wno-subobject-linkage>)
@@ -57,7 +56,6 @@ endif()
add_subdirectory(agg) add_subdirectory(agg)
add_subdirectory(bsdiff-courgette) add_subdirectory(bsdiff-courgette)
add_subdirectory(glaze)
add_subdirectory(minizip) add_subdirectory(minizip)
add_subdirectory(open-location-code) add_subdirectory(open-location-code)
add_subdirectory(opening_hours) add_subdirectory(opening_hours)

View File

@@ -4,9 +4,7 @@ set(FT_DISABLE_HARFBUZZ ON)
add_subdirectory(freetype) add_subdirectory(freetype)
# Fix warning with ONE_PIXEL macro clash. # Fix warning with ONE_PIXEL macro clash.
if(NOT MSVC) target_compile_options(freetype PRIVATE -Wno-macro-redefined)
target_compile_options(freetype PRIVATE -Wno-macro-redefined)
endif()
# Use ft2build.h from the current directory instead of the default. # Use ft2build.h from the current directory instead of the default.
target_include_directories(freetype target_include_directories(freetype

Submodule 3party/glaze deleted from 5a58d7936e

View File

@@ -11,23 +11,14 @@ target_include_directories(${PROJECT_NAME}
harfbuzz/src harfbuzz/src
) )
if (MSVC) # Keep these settigns in sync with xcode/harfbuzz project.
target_compile_options(${PROJECT_NAME} target_compile_options(${PROJECT_NAME}
PRIVATE PRIVATE
/GR- -fno-rtti
/EHsc- -fno-exceptions
/Zc:threadSafeInit- -fno-threadsafe-statics
) $<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:-Wno-format-pedantic>
else() )
# Keep these settings in sync with xcode/harfbuzz project.
target_compile_options(${PROJECT_NAME}
PRIVATE
-fno-rtti
-fno-exceptions
-fno-threadsafe-statics
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:-Wno-format-pedantic>
)
endif()
target_compile_definitions(${PROJECT_NAME} target_compile_definitions(${PROJECT_NAME}
PRIVATE PRIVATE
@@ -37,20 +28,14 @@ target_compile_definitions(${PROJECT_NAME}
#$<$<BOOL:${APPLE}>:HAVE_CORETEXT> #$<$<BOOL:${APPLE}>:HAVE_CORETEXT>
HAVE_ATEXIT HAVE_ATEXIT
HAVE_GETPAGESIZE HAVE_GETPAGESIZE
HAVE_MMAP
HAVE_MPROTECT HAVE_MPROTECT
HAVE_PTHREAD
HAVE_SYSCONF HAVE_SYSCONF
HAVE_SYS_MMAN_H
HAVE_UNISTD_H
) )
if (NOT MSVC)
target_compile_definitions(${PROJECT_NAME}
PRIVATE
HAVE_MMAP
HAVE_PTHREAD
HAVE_SYS_MMAN_H
HAVE_UNISTD_H
)
endif()
target_link_libraries(${PROJECT_NAME} Freetype::Freetype) target_link_libraries(${PROJECT_NAME} Freetype::Freetype)
add_library(harfbuzz::harfbuzz ALIAS harfbuzz) add_library(harfbuzz::harfbuzz ALIAS harfbuzz)

View File

@@ -172,7 +172,6 @@ add_library(icuuc
icu/icu4c/source/common/uvector.cpp icu/icu4c/source/common/uvector.cpp
icu/icu4c/source/common/uvectr32.cpp icu/icu4c/source/common/uvectr32.cpp
icu/icu4c/source/common/uvectr64.h icu/icu4c/source/common/uvectr64.h
icu/icu4c/source/common/wintz.cpp
icu/icu4c/source/common/wintz.h icu/icu4c/source/common/wintz.h
) )

View File

@@ -11,7 +11,6 @@ set(SRC
protobuf/src/google/protobuf/message_lite.cc protobuf/src/google/protobuf/message_lite.cc
protobuf/src/google/protobuf/repeated_field.cc protobuf/src/google/protobuf/repeated_field.cc
protobuf/src/google/protobuf/stubs/atomicops_internals_x86_gcc.cc protobuf/src/google/protobuf/stubs/atomicops_internals_x86_gcc.cc
protobuf/src/google/protobuf/stubs/atomicops_internals_x86_msvc.cc
protobuf/src/google/protobuf/stubs/bytestream.cc protobuf/src/google/protobuf/stubs/bytestream.cc
protobuf/src/google/protobuf/stubs/common.cc protobuf/src/google/protobuf/stubs/common.cc
protobuf/src/google/protobuf/stubs/int128.cc protobuf/src/google/protobuf/stubs/int128.cc

View File

@@ -7,6 +7,7 @@
#include <boost/utility/enable_if.hpp> #include <boost/utility/enable_if.hpp>
#include <boost/utility.hpp> #include <boost/utility.hpp>
#include <boost/type_traits/is_pod.hpp> #include <boost/type_traits/is_pod.hpp>
#include <boost/iostreams/device/mapped_file.hpp>
#include "mappable_vector.hpp" #include "mappable_vector.hpp"
@@ -282,6 +283,12 @@ namespace succinct { namespace mapper {
return mapper.bytes_read(); return mapper.bytes_read();
} }
template <typename T>
size_t map(T& val, boost::iostreams::mapped_file_source const& m, uint64_t flags = 0, const char* friendly_name = "<TOP>")
{
return map(val, m.data(), flags, friendly_name);
}
template <typename T> template <typename T>
uint64_t size_of(T& val) uint64_t size_of(T& val)
{ {

View File

@@ -8,6 +8,7 @@
#include <stdint.h> #include <stdint.h>
#include <boost/iterator/iterator_facade.hpp> #include <boost/iterator/iterator_facade.hpp>
#include <boost/iostreams/device/mapped_file.hpp>
namespace succinct { namespace util { namespace succinct { namespace util {
@@ -204,6 +205,29 @@ namespace succinct { namespace util {
std::string m_cur_value; std::string m_cur_value;
}; };
struct mmap_lines
{
typedef buffer_line_iterator iterator;
typedef buffer_line_iterator const_iterator;
mmap_lines(std::string filename)
: m_map(filename)
{}
const_iterator begin() const
{
return const_iterator(m_map.data(), m_map.size());
}
const_iterator end() const
{
return const_iterator();
}
private:
boost::iostreams::mapped_file_source m_map;
};
struct input_error : std::invalid_argument struct input_error : std::invalid_argument
{ {
input_error(std::string const& what) input_error(std::string const& what)

View File

@@ -19,18 +19,7 @@ extern "C" {
#endif #endif
#include "vulkan_wrapper.h" #include "vulkan_wrapper.h"
#if defined(_WIN32)
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <windows.h>
#else
#include <dlfcn.h> #include <dlfcn.h>
#endif
int InitVulkan(void) { int InitVulkan(void) {
#if defined(__APPLE__) #if defined(__APPLE__)
@@ -41,9 +30,6 @@ int InitVulkan(void) {
if (!libvulkan) { if (!libvulkan) {
libvulkan = dlopen("libMoltenVK.dylib", RTLD_NOW | RTLD_LOCAL); libvulkan = dlopen("libMoltenVK.dylib", RTLD_NOW | RTLD_LOCAL);
} }
#elif defined( _WIN32 )
HMODULE libvulkan = LoadLibraryA("vulkan-1.dll");
auto dlsym = [](HMODULE h, char const * name) { return GetProcAddress(h, name); };
#else #else
void* libvulkan = dlopen("libvulkan.so.1", RTLD_NOW | RTLD_LOCAL); void* libvulkan = dlopen("libvulkan.so.1", RTLD_NOW | RTLD_LOCAL);
if (!libvulkan) { if (!libvulkan) {

View File

@@ -1,9 +1,8 @@
cmake_minimum_required(VERSION 3.22.1) cmake_minimum_required(VERSION 3.22.1)
project(omim C CXX) project(omim C CXX)
set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD 20)
set(CMAKE_C_STANDARD 23) set(CMAKE_C_STANDARD 17)
# Our code does not rely on gnu extensions. # Our code does not rely on gnu extensions.
set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_C_EXTENSIONS OFF) set(CMAKE_C_EXTENSIONS OFF)
@@ -12,53 +11,46 @@ set(CMAKE_C_VISIBILITY_PRESET hidden)
set(CMAKE_CXX_VISIBILITY_PRESET hidden) set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN ON) set(CMAKE_VISIBILITY_INLINES_HIDDEN ON)
# Disable build-id generation to make builds reproducible.
if (NOT APPLE)
add_link_options("LINKER:--build-id=none")
endif()
# Fixes warning ld: warning: ignoring duplicate libraries on Mac and Windows. # Fixes warning ld: warning: ignoring duplicate libraries on Mac and Windows.
if (POLICY CMP0156) if (POLICY CMP0156)
cmake_policy(SET CMP0156 NEW) cmake_policy(SET CMP0156 NEW)
endif() endif()
set(OMIM_ROOT ${CMAKE_SOURCE_DIR})
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${OMIM_ROOT}/cmake")
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
include(OmimPlatform)
include(OmimOptions)
include(OmimConfig)
include(OmimHelpers)
include(OmimTesting)
if (APPLE AND NOT ("${CMAKE_SYSTEM_NAME}" STREQUAL Android)) if (APPLE AND NOT ("${CMAKE_SYSTEM_NAME}" STREQUAL Android))
# OBJC/OBJCXX are needed to skip m/mm files in Unity builds. # OBJC/OBJCXX are needed to skip m/mm files in Unity builds.
# https://gitlab.kitware.com/cmake/cmake/-/issues/21963 # https://gitlab.kitware.com/cmake/cmake/-/issues/21963
enable_language(OBJC) enable_language(OBJC)
set(CMAKE_OBJC_EXTENSIONS OFF) set(CMAKE_OBJC_EXTENSIONS OFF)
set(CMAKE_OBJC_STANDARD 23) set(CMAKE_OBJC_STANDARD 11)
set(CMAKE_OBJC_FLAGS -fobjc-arc) set(CMAKE_OBJC_FLAGS -fobjc-arc)
set(CMAKE_OBJC_VISIBILITY_PRESET hidden) set(CMAKE_OBJC_VISIBILITY_PRESET hidden)
enable_language(OBJCXX) enable_language(OBJCXX)
set(CMAKE_OBJCXX_EXTENSIONS OFF) set(CMAKE_OBJCXX_EXTENSIONS OFF)
set(CMAKE_OBJCXX_STANDARD 23) set(CMAKE_OBJCXX_STANDARD 20)
set(CMAKE_OBJCXX_FLAGS -fobjc-arc) set(CMAKE_OBJCXX_FLAGS -fobjc-arc)
set(CMAKE_OBJCXX_VISIBILITY_PRESET hidden) set(CMAKE_OBJCXX_VISIBILITY_PRESET hidden)
endif() endif()
message(STATUS "Using compiler ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}") message(STATUS "Using compiler ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}")
if (CMAKE_UNITY_BUILD) option(COVERAGE_REPORT "Configure for coverage report" OFF)
message(STATUS "Using Unity Build with batch ${CMAKE_UNITY_BUILD_BATCH_SIZE}, use -DCMAKE_UNITY_BUILD=OFF to disable it.")
option(UNITY_DISABLE "Disable unity build" OFF)
if (NOT UNITY_DISABLE AND NOT DEFINED ENV{UNITY_DISABLE})
set(CMAKE_UNITY_BUILD ON)
if (DEFINED ENV{UNITY_BUILD_BATCH_SIZE})
set(CMAKE_UNITY_BUILD_BATCH_SIZE $ENV{UNITY_BUILD_BATCH_SIZE})
else()
set(CMAKE_UNITY_BUILD_BATCH_SIZE 50)
endif()
message(STATUS "Using Unity Build with batch ${CMAKE_UNITY_BUILD_BATCH_SIZE}, export UNITY_DISABLE=1 or use -DUNITY_DISABLE=ON to disable it.")
endif() endif()
if (USE_CCACHE) option(CCACHE_DISABLE "Disable ccache" OFF)
if (NOT CCACHE_DISABLE AND NOT DEFINED ENV{CCACHE_DISABLE})
find_program(CCACHE_PROGRAM ccache HINTS /usr/local/bin/) find_program(CCACHE_PROGRAM ccache HINTS /usr/local/bin/)
if (CCACHE_PROGRAM) if (CCACHE_PROGRAM)
message(STATUS "Using ccache, use -DUSE_CCACHE=OFF to disable it.") message(STATUS "Using ccache, export CCACHE_DISABLE=1 or use -DCCACHE_DISABLE=ON to disable it.")
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}") set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}")
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK "${CCACHE_PROGRAM}") set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK "${CCACHE_PROGRAM}")
set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_PROGRAM}") set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_PROGRAM}")
@@ -66,13 +58,44 @@ if (USE_CCACHE)
endif() endif()
endif() endif()
option(COLORS_DISABLE "Disable colored compiler output" OFF)
if (NOT DEFINED ENV{COLORS_DISABLE} AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
message(STATUS "export COLORS_DISABLE=1 or use -DCOLORS_DISABLE=ON to disable colored compiler output.")
add_compile_options($<$<CXX_COMPILER_ID:GNU>:-fdiagnostics-color=always> $<$<CXX_COMPILER_ID:Clang,AppleClang>:-fcolor-diagnostics>)
add_link_options($<$<CXX_COMPILER_ID:GNU>:-fdiagnostics-color=always> $<$<CXX_COMPILER_ID:Clang,AppleClang>:-fcolor-diagnostics>)
endif()
option(WITH_SYSTEM_PROVIDED_3PARTY "Enable compilation with system provided dependencies" OFF)
set(OMIM_ROOT ${CMAKE_SOURCE_DIR})
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${OMIM_ROOT}/cmake")
include(OmimHelpers)
include(OmimTesting)
set(PLATFORM_DESKTOP TRUE)
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(PLATFORM_LINUX TRUE)
elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
set(PLATFORM_MAC TRUE)
elseif (CMAKE_SYSTEM_NAME STREQUAL "Windows")
set(PLATFORM_WIN TRUE)
elseif (CMAKE_SYSTEM_NAME STREQUAL "Android")
set(PLATFORM_ANDROID TRUE)
set(PLATFORM_DESKTOP FALSE)
elseif (CMAKE_SYSTEM_NAME STREQUAL "iOS")
set(PLATFORM_IPHONE TRUE)
set(PLATFORM_DESKTOP FALSE)
else()
message(FATAL_ERROR "Unsupported platform: ${CMAKE_SYSTEM_NAME}")
endif()
if(${PLATFORM_MAC}) if(${PLATFORM_MAC})
set(XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC YES) set(XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC YES)
# Metal language support # Metal language support
list(APPEND CMAKE_MODULE_PATH ${OMIM_ROOT}/3party/CMake-MetalShaderSupport/cmake) list(APPEND CMAKE_MODULE_PATH ${OMIM_ROOT}/3party/CMake-MetalShaderSupport/cmake)
include(CheckLanguage) include(CheckLanguage)
include(CMakeMetalInformation)
include(MetalShaderSupport) include(MetalShaderSupport)
check_language(Metal) check_language(Metal)
if(CMAKE_Metal_COMPILER) if(CMAKE_Metal_COMPILER)
@@ -80,12 +103,29 @@ if(${PLATFORM_MAC})
endif() endif()
endif() endif()
# Sanitizer
if (PLATFORM_DESKTOP)
# https://clang.llvm.org/docs/UsersManual.html#controlling-code-generation
set(BUILD_WITH_SANITIZER None CACHE STRING "Set to 'address' or others to enable sanitizer")
if (NOT ${BUILD_WITH_SANITIZER} MATCHES "None")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=${BUILD_WITH_SANITIZER} -fno-omit-frame-pointer")
set(CMAKE_LINKER_FLAGS "${CMAKE_LINKER_FLAGS} -fsanitize=${BUILD_WITH_SANITIZER} -fno-omit-frame-pointer")
message(STATUS "Enable sanitizer: ${BUILD_WITH_SANITIZER}")
endif()
endif()
# Set build type:
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
endif()
# Global compile options for all configurations. # Global compile options for all configurations.
if (MSVC) if (MSVC)
add_compile_options(/utf-8) add_compile_options(/utf-8)
add_link_options(/INCREMENTAL:NO) add_link_options(/INCREMENTAL:NO)
else() else()
add_compile_options(-ffast-math $<$<CXX_COMPILER_ID:GNU>:-Wno-psabi>) add_compile_options(-ffast-math)
endif() endif()
if (PLATFORM_WIN) if (PLATFORM_WIN)
@@ -104,22 +144,110 @@ if (${CMAKE_BUILD_TYPE} STREQUAL "Debug")
elseif (${CMAKE_BUILD_TYPE} MATCHES "Rel") elseif (${CMAKE_BUILD_TYPE} MATCHES "Rel")
add_definitions(-DRELEASE) add_definitions(-DRELEASE)
if (NOT MSVC) if (NOT MSVC)
add_compile_options(-O3 $<$<CXX_COMPILER_ID:GNU>:-flto=auto>) add_compile_options(-Ofast) # Also enables -ffast-math
endif() endif()
else() else()
message(FATAL_ERROR "Unknown build type: " ${CMAKE_BUILD_TYPE}) message(FATAL_ERROR "Unknown build type: " ${CMAKE_BUILD_TYPE})
endif() endif()
if (${CMAKE_BUILD_TYPE} STREQUAL "RelWithDebInfo") message(STATUS "Build type: " ${CMAKE_BUILD_TYPE})
add_compile_options(-fno-omit-frame-pointer) # End of setting build type
# Options
# Call `make package` after cmake to build design tool.
option(BUILD_DESIGNER "Build application as design tool" OFF)
if (BUILD_DESIGNER)
message(STATUS "Designer tool building is enabled")
add_definitions(-DBUILD_DESIGNER)
endif() endif()
message(STATUS "Build type: " ${CMAKE_BUILD_TYPE}) option(BUILD_STANDALONE "Build standalone application" OFF)
if (BUILD_STANDALONE)
message(STATUS "Standalone building is enabled")
add_definitions(-DBUILD_STANDALONE)
endif()
option(USE_ASAN "Enable Address Sanitizer" OFF)
option(USE_TSAN "Enable Thread Sanitizer" OFF)
option(USE_LIBFUZZER "Enable LibFuzzer" OFF)
option(PYBINDINGS "Create makefiles for building python bindings" OFF)
option(SKIP_QT_GUI "Skip building of Qt GUI" OFF)
option(USE_PCH "Use precompiled headers" OFF)
option(NJOBS "Number of parallel processes" OFF)
option(ENABLE_VULKAN_DIAGNOSTICS "Enable Vulkan diagnostics" OFF)
option(ENABLE_TRACE "Enable Tracing" OFF)
if (NJOBS)
message(STATUS "Number of parallel processes: ${NJOBS}")
set(CMAKE_JOB_POOLS custom=${NJOBS})
set(CMAKE_JOB_POOL_COMPILE custom)
set(CMAKE_JOB_POOL_LINK custom)
set(CMAKE_JOB_POOL_PRECOMPILE_HEADER custom)
endif()
# GCC 10.0 is required to support <charconv> header inclusion in base/string_utils.hpp
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 10.0)
message(FATAL_ERROR "Minimum supported g++ version is 10.0, yours is ${CMAKE_CXX_COMPILER_VERSION}")
endif()
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(PCH_EXTENSION "pch")
endif()
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
set(PCH_EXTENSION "gch")
endif()
if (PLATFORM_LINUX)
option(USE_PPROF "Enable Google Profiler" OFF)
endif()
if (USE_ASAN)
message(STATUS "Address Sanitizer is enabled")
endif()
if (USE_TSAN)
message(STATUS "Thread Sanitizer is enabled")
endif()
if (USE_ASAN AND USE_TSAN)
message(FATAL_ERROR "Can't use two different sanitizers together")
endif()
if (USE_LIBFUZZER)
message(STATUS "LibFuzzer is enabled")
endif()
if (USE_PPROF)
message(STATUS "Google Profiler is enabled")
add_definitions(-DUSE_PPROF)
endif()
if (USE_HEAPPROF)
message(STATUS "Heap Profiler is enabled")
endif()
if (ENABLE_VULKAN_DIAGNOSTICS)
message(WARNING "Vulkan diagnostics are enabled. Be aware of performance impact!")
add_definitions(-DENABLE_VULKAN_DIAGNOSTICS)
endif()
if (ENABLE_TRACE)
message(STATUS "Tracing is enabled")
add_definitions(-DENABLE_TRACE)
endif()
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
# Set environment variables
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR})
set(LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR})
if (PLATFORM_LINUX OR PLATFORM_ANDROID) if (PLATFORM_LINUX OR PLATFORM_ANDROID)
find_program(LLD_FOUND ld.lld) find_program(LLD_FOUND ld.lld)
if (LLD_FOUND) if (LLD_FOUND)
message(STATUS "Using ld.lld linker") message(STATUS "Using ld.ldd linker")
set(CMAKE_EXE_LINKER_FLAGS "-fuse-ld=lld") set(CMAKE_EXE_LINKER_FLAGS "-fuse-ld=lld")
else() else()
find_program(GOLD_FOUND ld.gold) find_program(GOLD_FOUND ld.gold)
@@ -162,15 +290,37 @@ if (NOT PLATFORM_IPHONE AND NOT PLATFORM_ANDROID)
find_package(Qt6 COMPONENTS REQUIRED ${qt_components} PATHS $ENV{QT_PATH} /opt/homebrew/opt/qt@6 /usr/local/opt/qt@6 /usr/lib/x86_64-linux-gnu/qt6) find_package(Qt6 COMPONENTS REQUIRED ${qt_components} PATHS $ENV{QT_PATH} /opt/homebrew/opt/qt@6 /usr/local/opt/qt@6 /usr/lib/x86_64-linux-gnu/qt6)
set(MINIMUM_REQUIRED_QT_VERSION 6.4.0) set(MINIMUM_REQUIRED_QT_VERSION 6.4.0)
if (Qt6_VERSION VERSION_LESS ${MINIMUM_REQUIRED_QT_VERSION}) if (Qt6Widgets_VERSION VERSION_LESS ${MINIMUM_REQUIRED_QT_VERSION})
message(FATAL_ERROR "Unsupported Qt version: ${Qt6_VERSION}, the minimum required is ${MINIMUM_REQUIRED_QT_VERSION}") message(FATAL_ERROR "Unsupported Qt version: ${Qt6Widgets_VERSION}, the minimum required is ${MINIMUM_REQUIRED_QT_VERSION}")
else() else()
message(STATUS "Found Qt version: ${Qt6_VERSION}") message(STATUS "Found Qt version: ${Qt6Widgets_VERSION}")
endif() endif()
endif() endif()
# To allow #include "base/file_name.hpp" in all sources. # To allow #include "base/file_name.hpp" in all sources.
include_directories("${CMAKE_HOME_DIRECTORY}" "${CMAKE_HOME_DIRECTORY}/libs" "${CMAKE_HOME_DIRECTORY}/tools") include_directories(${CMAKE_HOME_DIRECTORY})
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
if (USE_ASAN)
add_compile_options(
"-fsanitize=address"
"-fno-omit-frame-pointer"
)
endif()
if (USE_TSAN)
add_compile_options(
"-fsanitize=thread"
"-fno-omit-frame-pointer"
)
endif()
if (USE_LIBFUZZER)
add_compile_options(
"-fsanitize=fuzzer"
)
endif()
if (USE_PCH) if (USE_PCH)
message(STATUS "Precompiled headers are ON") message(STATUS "Precompiled headers are ON")
@@ -182,7 +332,7 @@ if (USE_PCH)
endif() endif()
# Should be on the root level, not in 3party, so tests can get these dependencies. # Should be on the root level, not in 3party, so tests can get these dependencies.
if (PLATFORM_LINUX) if (PLATFORM_LINUX OR PLATFORM_WIN)
find_package(ICU COMPONENTS uc i18n data REQUIRED) find_package(ICU COMPONENTS uc i18n data REQUIRED)
find_package(Freetype REQUIRED) find_package(Freetype REQUIRED)
find_package(harfbuzz REQUIRED) find_package(harfbuzz REQUIRED)
@@ -209,49 +359,49 @@ if (PLATFORM_DESKTOP AND NOT WITH_SYSTEM_PROVIDED_3PARTY)
include_directories("${PROJECT_BINARY_DIR}/3party/gflags/include") include_directories("${PROJECT_BINARY_DIR}/3party/gflags/include")
endif() endif()
# Fix for #include <boost/regex.hpp>
include_directories("${OMIM_ROOT}/3party/boost")
# Used in qt/ and shaders/ # Used in qt/ and shaders/
find_package(Python3 REQUIRED COMPONENTS Interpreter) find_package(Python3 REQUIRED COMPONENTS Interpreter)
execute_process( add_subdirectory(base)
COMMAND ${Python3_EXECUTABLE} -c "import google.protobuf; add_subdirectory(coding)
print(google.protobuf.__version__)" add_subdirectory(descriptions)
RESULT_VARIABLE PROTOBUF_CHECK add_subdirectory(drape)
OUTPUT_VARIABLE PROTOBUF_VERSION add_subdirectory(drape_frontend)
OUTPUT_STRIP_TRAILING_WHITESPACE add_subdirectory(editor)
ERROR_QUIET add_subdirectory(ge0)
) add_subdirectory(generator/mwm_diff)
add_subdirectory(geometry)
if(PROTOBUF_CHECK EQUAL 0) add_subdirectory(indexer)
if(PROTOBUF_VERSION VERSION_LESS "4.0.0") add_subdirectory(kml)
message(STATUS "Python protobuf ${PROTOBUF_VERSION} found (< 4.0)") add_subdirectory(map)
else() add_subdirectory(cppjansson)
message(FATAL_ERROR "Python protobuf ${PROTOBUF_VERSION} found, but version < 4.0 required") add_subdirectory(platform)
endif() add_subdirectory(routing)
else() add_subdirectory(routing_common)
message(FATAL_ERROR "Python protobuf not found. Install version <4.0") add_subdirectory(search)
endif() add_subdirectory(shaders)
add_subdirectory(storage)
add_subdirectory(tracking)
add_subdirectory(libs) add_subdirectory(traffic)
add_subdirectory(transit)
if (PLATFORM_DESKTOP) if (PLATFORM_DESKTOP)
add_subdirectory(dev_sandbox) omim_add_tool_subdirectory(feature_list)
add_subdirectory(generator) add_subdirectory(generator)
add_subdirectory(tools) add_subdirectory(openlr)
add_subdirectory(poly_borders)
omim_add_tool_subdirectory(topography_generator)
add_subdirectory(track_analyzing)
omim_add_tool_subdirectory(track_generator)
if (NOT SKIP_QT_GUI) if (NOT SKIP_QT_GUI)
add_subdirectory(qt) add_subdirectory(qt)
omim_add_tool_subdirectory(skin_generator)
endif() endif()
if (GENERATOR_TOOL) add_subdirectory(dev_sandbox)
add_compile_options(-march=native -mtune=native)
message(STATUS "target CPU optimizations enabled, produced binaries will NOT work on a different CPU")
endif()
endif() endif()
omim_add_test_subdirectory(libs/qt_tstfrm) omim_add_test_subdirectory(qt_tstfrm)
if (PLATFORM_ANDROID) if (PLATFORM_ANDROID)
add_subdirectory(android/sdk/src/main/cpp) add_subdirectory(android/app/src/main/cpp)
endif() endif()

View File

@@ -1,20 +1,12 @@
This file contains a list of people who have contributed to this project. This file contains a list of people who have contributed to this project.
It is not necessarily comprehensive as contributors must manually add themselves. Its not neccesarily comprehensive.
Feel free to add yourself here along with your first contribution! Feel free to add yourself here along with your first contribution!
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
CoMaps contributors: CoMaps contributors:
(in alphabetical order) (in alphabetic order)
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
Bastian Greshake Tzovaras
clover sage
Harry Bond <me@hbond.xyz>
NoelClick
thesupertechie
vikiawv
Yannik Bloscheck
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
Organic Maps (formerly OMaps) contributors: Organic Maps (formerly OMaps) contributors:
(in alphabetic order) (in alphabetic order)

View File

@@ -1 +1 @@
See [docs/INSTALL.md](docs/INSTALL.md) See [docs/INSTALL.md](docs/INSTALL.md)

274
README.md
View File

@@ -1,172 +1,170 @@
<!-- Navigation Bar --> <!--<div align="center">
<p align="center"> <img src="qt/res/logo.png" height="100"/>
<a href="https://codeberg.org/comaps#comaps">Project Intro</a> | </div>-->
<a href="https://codeberg.org/comaps/Governance#comaps-project-governance-docs">Governance</a> | <h1 align="center"">CoMaps - Discover more of your journey, powered by the community</h1>
<a href="https://codeberg.org/comaps/Governance/src/branch/main/FAQ.md">FAQ</a> |
<a href="#contributing">Contribute</a> |
<a href="https://www.comaps.app/donate">Donate</a> | CoMaps is a new community-driven maps app project born out of the desire to create a truly open, transparent, and community-focused navigation app. Our mission is to provide easy, offline navigation for travellers, drivers, hikers, and cyclists, with a strong emphasis on open-source principles and respecting data privacy. We are committed to building a world where the top choice for navigation software is free and developed through open collaboration.
<a href="https://codeberg.org/comaps#keep-connected">Keep Connected</a>
### Community Action
The CoMaps project was initiated in response to the growing concerns and dissatisfaction within the Organic Maps community. The original Organic Maps project, while initially promoted as an open community effort, faced significant issues related to governance, transparency, and the potential for shareholder profit at the expense of the community. These concerns were detailed in an open letter to Organic Maps shareholders, which can be found [here](https://openletter.earth/open-letter-to-organic-maps-shareholders-a0bf770c). Despite some positive steps, the lack of a substantive resolution has led to the decision to start a new independent project.
### New Path Forward
At CoMaps, we are dedicated to ensuring that all project-related efforts are conducted in public, providing full transparency in decision-making, priorities, goals, financials, and operations. We believe in community decision-making, where those impacted by decisions have a voice and are empowered to participate. Our project operates as a not-for-profit entity, focusing on creating value for the community rather than generating profit. We are committed to maintaining the complete codebase and associated resources under Free and Open Source Software licenses, ensuring that development is open and transparent.
Privacy is an important part of the project. The app does not track users or collect personal data behind the scenes; if there is potential of data collection, for example sharing app logs with tech support, it is fully disclosed and requires opt-in consent. Funding for CoMaps primarily comes from community donations, and possibility of grants and B2B products, as long as they align with the principles and are approved by the community. All assets created or acquired are owned by the community and used for its benefit.
We are building a navigation app that is not only easy to use and fast, but also reflects the values of openness, transparency, and community collaboration. Join us in creating a navigation solution that truly serves the public good.
Read on about project's principles and governance structure in the [dedicated repo](https://codeberg.org/comaps/governance#core-principles-work-in-progress).
<br>
## [CoMaps](https://comaps.app) Hike, Bike, Drive Offline Easy Map Navigation with Privacy
A community-led maps app based on an open source foundation and reinforced with commitment to transparency, privacy and being not-for-profit.
Join the community and help make the best maps app
Use the app and spread the word about it
Give feedback and report issues
Update map data in the app or on the [OpenStreetMap](https://www.openstreetmap.org) website
Your [donations](https://opencollective.com/comaps/donate) and positive reviews motivate and inspire us, thanks ❤️!
**We're working on getting first app releases out soon, please stay tuned!**
<!--
[<img src="docs/badges/apple-appstore.png" alt="App Store" width="160">](https://apps.apple.com/app/comaps/id1567437057)
[<img src="docs/badges/google-play.png" alt="Google Play" width="160">](https://play.google.com/store/apps/details?id=app.comaps)
[<img src="docs/badges/fdroid.png" alt="F-Droid" width="160">](https://f-droid.org/en/packages/app.comaps/)
-->
<p float="left">
<img src="android/app/src/fdroid/play/listings/en-US/graphics/phone-screenshots/1.jpg" width="180" />
<img src="android/app/src/fdroid/play/listings/en-US/graphics/phone-screenshots/2.jpg" width="180" />
<img src="android/app/src/fdroid/play/listings/en-US/graphics/phone-screenshots/3.jpg" width="180" />
<img src="android/app/src/fdroid/play/listings/en-US/graphics/phone-screenshots/4.jpg" width="180" />
</p> </p>
<div align="center" > **Offline-focused**: Plan and navigate your trip abroad without the need for cellular service, search waypoints while on a distant hike, etc. All app functions are designed to work offline.
<img src="docs/badges/logo.svg" width="150">
</div> **No Data Collection**: The app is designed with privacy in mind - does not identify people, does not track, and does not collect any information.
**Save Your Battery**: Efficiently uses the battery during your travels, doesnt drain your battery like other navigation apps.
**Free and Built by the Community**: People like you helped build the app by adding locations to OpenStreetMap, giving feedback on features, and contributing code on Codeberg in the open-source community.
### Principles
1. Transparency
2. Community Decision-making
3. Not-for-profit
4. Open source
5. Privacy-focused
6. Clear Funding
7. Assets for Public Interest
<div align="center"> ### Respecting Privacy
<h1><a href="https://comaps.app/">CoMaps</a></h1> • No tracking
<h2>Hike, Bike, Drive Offline - Easy Map Navigation with Privacy</h2> • No data collection
</div> • No ads
<div align="center">
<p align="center">
<a href="https://codeberg.org/comaps/comaps/src/branch/main/LICENSE">
<img src="https://img.shields.io/github/license/comaps/comaps?style=for-the-badge&logo=opensourceinitiative&logoColor=white&color=588157" alt="License"/>
</a>
<a href="https://github.com/comaps/comaps/actions/workflows/android-check.yaml">
<img src="https://img.shields.io/github/actions/workflow/status/comaps/comaps/.github/workflows/android-check.yaml?label=Android%20Build&logo=android&logoColor=white&style=for-the-badge" alt="Android Build Status"/>
</a>
<a href="https://github.com/comaps/comaps/actions/workflows/ios-check.yaml">
<img src="https://img.shields.io/github/actions/workflow/status/comaps/comaps/.github/workflows/ios-check.yaml?label=iOS%20Build&logo=apple&logoColor=white&style=for-the-badge" alt="iOS Build Status"/>
</a>
<a href="https://opencollective.com/comaps">
<img src="https://img.shields.io/opencollective/all/comaps?label=Open%20Collective%20Donors&logo=opencollective&logoColor=white&style=for-the-badge&color=588157" alt="Open Collective Donors"/>
</a>
<a href="https://liberapay.com/CoMaps">
<img src="https://img.shields.io/liberapay/patrons/CoMaps.svg?label=Liberapay%20Patrons&logo=liberapay&logoColor=white&style=for-the-badge&color=588157" alt="Liberapay Patrons"/>
</a>
</p>
</div>
---
A community-led free & open source maps app based on [OpenStreetMap](https://www.openstreetmap.org), built for transparency, privacy, and not-for-profit values. A fork of Organic Maps, originally based on Maps.ME.
<p align="center">
<a href="https://apps.apple.com/app/comaps/id6747180809">
<img src="docs/badges/apple-appstore.png" alt="App Store" width="160"/>
</a>
<a href="https://play.google.com/store/apps/details?id=app.comaps.google">
<img src="docs/badges/google-play.png" alt="Google Play" width="160"/>
</a>
<a href="https://f-droid.org/en/packages/app.comaps.fdroid/">
<img src="docs/badges/fdroid.png" alt="F-Droid" width="160"/>
</a>
<a href="https://apt.izzysoft.de/fdroid/index/apk/app.comaps">
<img src="docs/badges/izzyondroid.png" alt="Obtainium" width="160"/>
</a>
<a href="https://apps.obtainium.imranr.dev/redirect?r=obtainium://add/https://codeberg.org/comaps/comaps">
<img src="docs/badges/obtainium.png" alt="Obtainium" width="160"/>
</a>
<a href="https://codeberg.org/comaps/comaps/releases">
<img src="docs/badges/codeberg.png" alt="Codeberg" width="160"/>
</a>
</p>
<!-- Screenshots --> ## Features
<p align="center">
<img src="android/app/src/fdroid/play/listings/en-US/graphics/phone-screenshots/1.png" width="180" />
<img src="android/app/src/fdroid/play/listings/en-US/graphics/phone-screenshots/2.png" width="180" />
<img src="android/app/src/fdroid/play/listings/en-US/graphics/phone-screenshots/3.png" width="180" />
<img src="android/app/src/fdroid/play/listings/en-US/graphics/phone-screenshots/4.png" width="180" />
<img src="android/app/src/fdroid/play/listings/en-US/graphics/phone-screenshots/5.png" width="180" />
<img src="android/app/src/fdroid/play/listings/en-US/graphics/phone-screenshots/6.png" width="180" />
</p>
--- • Search by name or an address or by point of interest category
## ⚡️ Highlights • Navigation with voice announcements for walking, cycling, or driving
- **Offline-first**: Navigate without a connection • Track recording
- **Privacy-respecting**: No tracking, ads or data collection
- **Lightweight**: Battery- and space-efficient
- **Simple**: Polished, user-focused interface
- **Cross-platform**: Available for Android, iOS, MacOS, and Linux.
- **Community-built**: Free, open source, and collaborative
- **Transparent**: Open finances and governance
--- • Export and import bookmarks and tracks in KML, KMZ, GPX formats
## 🚀 Main Features
- Downloadable detailed maps with places which are not available with Google Maps ### Maps
- Outdoor mode with highlighted hiking trails, campsites, water sources, peaks, contour lines, etc • Downloadable detailed maps from OpenStreetMap with places which are not available with Google Maps
- Walking paths and cycleways • Hiking trails, walking paths and cycleways
- Points of interest like restaurants, gas stations, hotels, shops, sightseeings and many more • Contour lines, elevation profiles and peaks
- Search by name or an address or by point of interest category • Points of interest like restaurants, gas stations, hotels, shops, sightseeings and many more
- Navigation with voice announcements for walking, cycling, or driving
- Bookmark your favorite places with a single tap
- Offline Wikipedia articles Please report app issues, suggest ideas and join our community at comaps.app website.
- Subway transit layer and directions Freedom Is Here Discover your journey, navigate the world with privacy and community at the forefront.
- Track recording
- Export and import bookmarks and tracks in KML, KMZ, GPX formats <a name="contributing">
- A dark mode to use during the night ## Contributing
- Improve map data for everyone using a basic built-in editor ### Who is paying for development?
- Android Auto and CarPlay support The app is free for everyone, so we rely on donations. Please [donate](https://opencollective.com/comaps/donate) to support the CoMaps community and see this open project thrive!
***Freedom Is Here Navigate the world with privacy and community at the forefront.***
---
## 🤝 Contributing
You can help by donating, contributing code, translating, or by telling others about it. To build the best maps app there is a need for software development, design, product, community development, and other areas. Reach out to us and let us know how you want to help.
- Build instructions: [docs/INSTALL.md](docs/INSTALL.md)
- Contribution guide: [docs/CONTRIBUTING.md](docs/CONTRIBUTING.md)
There is a dedicated [Zulip](https://codeberg.org/comaps/Governance/src/branch/main/contribute.md#3-team-messaging) chat for active contributors.
---
## 💬 Feedback
- Rate us on [App Store](https://apps.apple.com/app/comaps/id6747180809) and [Google Play](https://play.google.com/store/apps/details?id=app.comaps.google)
- Star our repos on Codeberg
- Report bugs or request features on the [issue tracker](https://codeberg.org/comaps/comaps/issues)
---
## 💸 Funding
CoMaps is free. To fund development, we rely on your voluntary support ♥️
Donate via [OpenCollective](https://opencollective.com/comaps/donate) or [Liberapay](https://liberapay.com/CoMaps).
The project's financial information is completely open and transparent at [our Open Collective](https://opencollective.com/comaps). The project's financial information is completely open and transparent at [our Open Collective](https://opencollective.com/comaps).
--- ### How can I help with CoMaps?
## 🔒 Privacy You can help by donating, by helping build the product, or by telling others about it. To build a great product there is a need for software development, design, product, community development, and other areas. Reach out to us and let us know how you want to help.
The Android app has been reviewed by [Exodus Privacy](https://reports.exodus-privacy.eu.org/en/reports/app.comaps.google/latest/). If you want to build the project, check [docs/INSTALL.md](docs/INSTALL.md). If you want to help the project,
see [docs/CONTRIBUTING.md](docs/CONTRIBUTING.md). You can [help in many ways](https://comaps.app/support-us/), the ability to code is not necessary.
To [verify](https://developer.android.com/studio/command-line/apksigner#usage-verify) the APK, use the following signing certificate fingerprints: Some docs might be outdated, contain broken links or old references to Organic Maps, etc. Its a work in progress and help is much appreciated!
```
SHA-256: 4894e8e6963627ef660031d8593fe77297f835acb4e23810003e926135023b4c
SHA-1: 8b7b5739f917e9f7c681671ced0c9c8562123ade
MD5: 9cce0ffea281dc2f0e0a154d6d2e281e
```
To verify CoMaps via [AppVerifier](https://github.com/soupslurpr/AppVerifier), use the following signing certificate fingerprint: <!-- uncomment when linked resources are ready
``` ### Feedback
app.comaps
48:94:E8:E6:96:36:27:EF:66:00:31:D8:59:3F:E7:72:97:F8:35:AC:B4:E2:38:10:00:3E:92:61:35:02:3B:4C
```
---
## ⚖️ License - **Rate us on the [App Store](https://apps.apple.com/app/comaps/id1567437057)
and [Google Play](https://play.google.com/store/apps/details?id=app.comaps)**.
- **Star us on Codeberg**.
- Report bugs or issues to [the issue tracker](https://codeberg.org/comaps/comaps/issues).
-->
### Connect with us
[Bluesky](https://bsky.app/profile/comaps.app)
| [Facebook](https://www.facebook.com/CoMapsCommunity/)
| [Instagram](https://www.instagram.com/comapscommunity/)
| [Lemmy](https://sopuli.xyz/c/CoMaps)
| [LinkedIn](https://www.linkedin.com/company/comaps-community/)
| [Mastodon](https://floss.social/@CoMaps)
| [Matrix](https://matrix.to/#/#comaps:matrix.org)
| [Open Collective](https://opencollective.com/comaps)
| [Reddit](https://www.reddit.com/r/CoMaps/)
| [Telegram](https://t.me/CoMapsApp) [EN Chat](https://t.me/CoMaps_EN) [RU Chat](https://t.me/CoMaps_RU)
| [Threads](https://www.threads.com/@comapscommunity)
| [TikTok](https://www.tiktok.com/@comapscommunity)
## What's the difference to Organic Maps?
CoMaps is a fork/spin-off of Organic Maps, which in turn is a fork/spin-off of Maps.me. The CoMaps project emerged in response to the growing concerns and dissatisfaction with the Organic Maps leadership. The original Organic Maps project, while initially promoted as an open community effort, faced significant issues related to governance, transparency, and the potential of shareholder profit at the expense of the community. These concerns were detailed in an open letter to Organic Maps shareholders, which can be found [here](https://openletter.earth/open-letter-to-organic-maps-shareholders-a0bf770c). Despite some positive steps, the lack of a substantial resolution has led former Organic Maps contributors to the decision to start a new independent project.
With CoMaps, we want to overcome these issues by moving to a nonprofit structure (not finished yet), greater inclusivity in decision-making, and financial transparency.
## Governance
See the [Principles](https://codeberg.org/comaps/governance).
The CoMaps community abides by the CNCF [code of conduct](docs/CODE_OF_CONDUCT.md).
### Copyrights
Licensed under the Apache License, Version 2.0. See
[LICENSE](LICENSE),
[NOTICE](NOTICE)
and [data/copyright.html](data/copyright.html)
for more information.
Licensed under the Apache License 2.0.
See [LICENSE](LICENSE), [NOTICE](NOTICE), and [data/copyright.html](data/copyright.html).

View File

@@ -1,17 +0,0 @@
## Reporting Vulnerabilities
You can report a security vulnerability by creating an issue or send mail to security@comaps.app
## Verifying Fingerprints
To [verify](https://developer.android.com/studio/command-line/apksigner#usage-verify) the APK, use the following signing certificate fingerprints:
```
SHA-256: 4894e8e6963627ef660031d8593fe77297f835acb4e23810003e926135023b4c
SHA-1: 8b7b5739f917e9f7c681671ced0c9c8562123ade
MD5: 9cce0ffea281dc2f0e0a154d6d2e281e
```
To verify CoMaps via [AppVerifier](https://github.com/soupslurpr/AppVerifier), use the following signing certificate fingerprint:
```
app.comaps
48:94:E8:E6:96:36:27:EF:66:00:31:D8:59:3F:E7:72:97:F8:35:AC:B4:E2:38:10:00:3E:92:61:35:02:3B:4C
```

12
android/.idea/icon.svg generated
View File

@@ -1,4 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" width="64pt" height="64pt" viewBox="0 0 835 835"> <?xml version="1.0" encoding="UTF-8"?>
<path d="M698.5 141.1a20 20 0 0 1 30.8-1.3A416 416 0 0 1 835 417.4a416 416 0 0 1-93.3 263 20 20 0 0 1-31.3-.6l-43-56.6a20 20 0 0 1-.2-24 307 307 0 0 0 59.3-181.8c0-74.2-26.2-142.3-69.9-195.6a20 20 0 0 1-.5-24.8zM260.7 456.4a20 20 0 0 1-7.7-36.7l282-177.4a20 20 0 0 1 29.9 22.7l-97 318.9a20 20 0 0 1-37.5 2.2l-49.2-111.5z" style="fill:#ccdfca"/> <!-- Created with Inkscape (http://www.inkscape.org/) -->
<path d="M626.3 753a20 20 0 0 1-6.2 29.6A416 416 0 0 1 417.5 835 417.7 417.7 0 0 1 0 417.4 417.7 417.7 0 0 1 603.3 43.5a20 20 0 0 1 7 30l-42.4 55.8a20 20 0 0 1-24.2 6.1 307 307 0 0 0-126.2-27 309 309 0 0 0-309 309c0 170.6 138.5 309 309 309a307 307 0 0 0 141.6-34.3 20 20 0 0 1 25.1 5.6z" style="fill:#fefdf6"/> <svg version="1.1" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape">
</svg> <g inkscape:groupmode="layer" inkscape:label="Layer 1">
<rect fill="#006c35" fill-opacity="1.0" x="0" y="0" width="1024" height="1024"/>
<path fill="#ffffff" d="m861.3562052 256.9139426c18.220574 48.4374573-79.2585233 166.2022835-172.1806378 196.4226995-168.0803471-58.2153969-173.5457836 39.5504743-311.1096159 132.4296677 162.6149552 112.4329497 332.9737882 24.8856325 329.7844002-85.7673036-127.9956457 73.3254376-208.1650824 81.3238121-254.1719349 79.1032962 154.8710218-30.6636026 322.0404219-125.7633124 357.0667834-165.7616685 0.032202 1.7749817 0.049863 3.5523114 0.049863 5.33456 0 191.0905993-295.1650572 474.6148576-295.1650572 474.6148576s-154.5086464-147.95159-239.9499331-302.4701423c-11.943516-0.1614425-83.8230022 25.9633002-110.3310391-9.051445-29.6082623-39.1049397 80.1693081-170.2028122 175.3699196-209.3102117 170.3563508 77.3261904 263.7351577-123.0971499 317.0292402-134.2068293-158.9688193-94.2135154-316.1183714-55.5493358-333.8847017 84.4353407 88.3675802-50.2172465 196.7775505-78.65765 246.8822227-76.4346744-140.7606999 28.7623957-301.9981102 132.8752019-350.2809443 172.4255642 0-159.041983 132.1505407-287.9677052 295.1650569-287.9677052 96.4018995 0 182.0095151 45.0859887 235.8744518 114.8252613 0.00335 0 96.1884344-31.2834041 109.851981 11.3787329zm-33.7059144 14.218972c-12.6607646-17.2289278-56.7341326 2.8936807-56.7341326 2.8936807 6.1678152 10.3446685 11.7002555 21.0960758 16.5352245 32.2084942 4.8995467 11.2622344 9.0867303 22.8954305 12.5044868 34.8382086 0 0 45.0041042-46.3863227 27.6944213-69.9403835zm-629.5734431 294.3797539c13.6858848 18.6189721 61.3258973-3.1309266 61.3258973-3.1309266-6.6716772-11.1802827-12.6484216-22.8033047-17.8755617-34.8139472-5.2966478-12.1727565-9.8213865-24.7454316-13.5171072-37.6545218 0 0-48.6427553 50.1397674-29.9332284 75.5993956z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 753 B

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -1,21 +0,0 @@
FROM ubuntu:latest
ENV TZ=Etc/UTC
ENV QT_QPA_PLATFORM=offscreen
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
cmake \
qt6-base-dev \
qt6-svg-dev \
qt6-positioning-dev \
libicu-dev \
libfreetype-dev \
libharfbuzz-dev \
libxrandr-dev \
libxinerama-dev \
libxcursor-dev \
libxi-dev \
optipng
WORKDIR /root/comaps
CMD ./gradlew -Parm64 assembleFdroidDebug

View File

@@ -1,8 +1,8 @@
To build, install and run e.g. a Web Debug version on your device/emulator: './gradlew runWebDebug' To build, install and run e.g. a Web Debug version on your device/emulator: './gradlew runWebDebug'
Or to compile a redistributable Fdroid Test apk for testing: './gradlew assembleFdroidBeta' Or to compile a redistributable Fdroid Beta apk for testing: './gradlew assembleFdroidBeta'
Or to build test apks for all flavors: './gradlew assembleBeta' Or to build beta apks for all flavors: './gradlew assembleBeta'
To see all available build targets './gradlew tasks' To see all available build targets './gradlew tasks'

View File

@@ -2,14 +2,18 @@
/nativeOutputs /nativeOutputs
# ignore private keys # ignore private keys
/secure.properties.test /google-services.json
/secure.properties.release /secure.properties
/comaps-test.keystore /release.keystore
/comaps-release.keystore /secure.properties
/libnotify.properties /libnotify.properties
/google-services.json
/google-play.json /google-play.json
/firebase-app-distribution.json
/firebase-test-lab.json
/huawei-appgallery.json /huawei-appgallery.json
/agconnect-services.json /agconnect-services.json
/src/main/res/xml/network_security_config.xml
# ignore flags symlinks # ignore flags symlinks
/src/main/res/drawable-xhdpi/??.png /src/main/res/drawable-xhdpi/??.png
@@ -25,5 +29,5 @@
/src/main/res/drawable-mdpi/uk_scotland.png /src/main/res/drawable-mdpi/uk_scotland.png
/src/main/res/drawable-mdpi/uk_wales.png /src/main/res/drawable-mdpi/uk_wales.png
# Symlinked to F-Droid relnotes by tools/unix/link_gplay_relnotes.sh # ignore autogenerated metadata (see prepareGoogleReleaseListing in build.gradle)
/src/google/play/release-notes /src/google/play/listings

View File

@@ -3,82 +3,175 @@ buildscript {
google() google()
mavenCentral() mavenCentral()
} }
//
// The magic below is needed to disable Google Firebase Services during the build time.
// Unfortunately, the only way to disable Gradle plugins is to add these hardcore switches to buildscript().
//
// Detect flavors from the task name. // Detect flavors from the task name.
def taskName = getGradle().getStartParameter().getTaskRequests().toString().toLowerCase() def taskName = getGradle().getStartParameter().getTaskRequests().toString().toLowerCase()
def isFdroid = taskName.contains('fdroid') def isFdroid = taskName.contains('fdroid')
def isBeta = taskName.contains('beta')
// Firebase Crashlytics compile-time feature flag: -Pfirebase=true|false
def googleFirebaseServicesFlag = findProperty('firebase')
// Enable Firebase for all beta flavors except fdroid only if google-services.json exists.
def googleFirebaseServicesDefault = isBeta && !isFdroid && file("$projectDir/google-services.json").exists()
ext.googleFirebaseServicesEnabled = googleFirebaseServicesFlag != null ?
googleFirebaseServicesFlag == '' || googleFirebaseServicesFlag.toBoolean() :
googleFirebaseServicesDefault
dependencies { dependencies {
classpath libs.android.tools classpath 'com.android.tools.build:gradle:8.7.3'
classpath(libs.triplet.play.publisher)
classpath(libs.huawei.publish) if (googleFirebaseServicesEnabled) {
println('Building with Google Firebase Services')
classpath 'com.google.gms:google-services:4.4.2'
classpath 'com.google.firebase:firebase-crashlytics-gradle:3.0.2'
classpath 'com.google.firebase:firebase-appdistribution-gradle:5.0.0'
} else {
println('Building without Google Firebase Services')
}
classpath('com.github.triplet.gradle:play-publisher:3.10.1')
classpath('ru.cian:huawei-publish-gradle-plugin:1.4.2')
} }
} }
repositories {
google()
mavenCentral()
maven { url 'https://www.jitpack.io' } // MPAndroidChart
}
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
if (googleFirebaseServicesEnabled) {
apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.crashlytics'
apply plugin: 'com.google.firebase.appdistribution'
}
apply plugin: 'com.github.triplet.play' apply plugin: 'com.github.triplet.play'
apply plugin: 'ru.cian.huawei-publish-gradle-plugin' apply plugin: 'ru.cian.huawei-publish-gradle-plugin'
def run(cmd) {
def stdout = new ByteArrayOutputStream()
exec {
commandLine = cmd
standardOutput = stdout
}
return stdout.toString()
}
import com.github.triplet.gradle.androidpublisher.ReleaseStatus import com.github.triplet.gradle.androidpublisher.ReleaseStatus
import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform
def getVersion() {
def isWindows = DefaultNativePlatform.getCurrentOperatingSystem().isWindows()
def bash = isWindows ? 'C:\\Program Files\\Git\\bin\\bash.exe' : 'bash'
def versionCode = Integer.parseInt(run([bash, '../../tools/unix/version.sh', 'android_code']).trim())
def versionName = run([bash, '../../tools/unix/version.sh', 'android_name']).trim()
return new Tuple2(versionCode, versionName)
}
def getCommitMessage() { def getCommitMessage() {
return run(['git', '--no-pager', 'show', '-s', '--format=%s%n%n%b', 'HEAD']).trim() return run(['git', '--no-pager', 'show', '-s', '--format=%s%n%n%b', 'HEAD']).trim()
} }
def osName = System.properties['os.name'].toLowerCase()
project.ext.appId = 'app.comaps' project.ext.appId = 'app.comaps'
project.ext.appName = 'CoMaps' project.ext.appName = 'CoMaps'
// I have Java 21 installed, but this doesn't work on MacOS.
java { //java {
toolchain { // toolchain {
languageVersion.set(JavaLanguageVersion.of(21)) // languageVersion.set(JavaLanguageVersion.of(17))
} // }
} //}
android { android {
namespace = 'app.organicmaps' namespace 'app.organicmaps'
// TODO: it should not be here, but in sdk/build.gradle. But for some reason it should be specified here as well.
ndkVersion = '28.2.13676358'
dependenciesInfo {
// Disables dependency metadata when building APKs (for IzzyOnDroid/F-Droid)
includeInApk = false
// Disables dependency metadata when building Android App Bundles (for Google Play)
includeInBundle = false
}
buildFeatures { buildFeatures {
dataBinding = true dataBinding = true
buildConfig = true buildConfig = true
} }
// Users are complaining that the app should be re-downloaded from the Play Store after changing the language.
bundle {
language {
enableSplit = false
}
}
// All properties are read from gradle.properties file // All properties are read from gradle.properties file
compileSdk = propCompileSdkVersion.toInteger() compileSdk propCompileSdkVersion.toInteger()
ndkVersion '27.2.12479018'
defaultConfig { defaultConfig {
versionCode = rootProject.ext.versionCode // Default package name is taken from the manifest and should be app.comaps
versionName = rootProject.ext.versionName def ver = getVersion()
versionCode = ver.V1
versionName = ver.V2
println('Version: ' + versionName) println('Version: ' + versionName)
println('VersionCode: ' + versionCode) println('VersionCode: ' + versionCode)
minSdk = propMinSdkVersion.toInteger() minSdk propMinSdkVersion.toInteger()
targetSdk = propTargetSdkVersion.toInteger() targetSdk propTargetSdkVersion.toInteger()
applicationId project.ext.appId applicationId project.ext.appId
buildConfigField 'String', 'SUPPORT_MAIL', '"android@comaps.app"' buildConfigField 'String', 'SUPPORT_MAIL', '"android@comaps.app"'
// Should be customized in flavors. // Should be customized in flavors.
buildConfigField 'String', 'REVIEW_URL', '""' buildConfigField 'String', 'REVIEW_URL', '""'
resourceConfigurations += [project.ext.supportedLocalizations]
base.archivesName = appName.replaceAll('\\s','') + '-' + defaultConfig.versionCode externalNativeBuild {
def pchFlag = 'OFF'
if (project.hasProperty('pch')) pchFlag = 'ON'
ndk.debugSymbolLevel = 'full' def njobs = ''
if (project.hasProperty('njobs')) njobs = project.getProperty('njobs')
def enableVulkanDiagnostics = 'OFF'
if (project.hasProperty('enableVulkanDiagnostics')) {
enableVulkanDiagnostics = project.getProperty('enableVulkanDiagnostics')
}
def enableTrace = 'OFF'
if (project.hasProperty('enableTrace')) {
enableTrace = project.getProperty('enableTrace')
}
cmake {
cppFlags '-fexceptions', '-frtti'
// There is no sense to enable sections without gcc's --gc-sections flag.
cFlags '-fno-function-sections', '-fno-data-sections',
'-Wno-extern-c-compat'
arguments '-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=c++_static',
"-DOS=$osName", '-DSKIP_TESTS=ON', '-DSKIP_TOOLS=ON', "-DUSE_PCH=$pchFlag",
"-DNJOBS=$njobs", "-DENABLE_VULKAN_DIAGNOSTICS=$enableVulkanDiagnostics",
"-DENABLE_TRACE=$enableTrace"
targets 'organicmaps'
}
}
// Use, for example, -Parm32 gradle parameter to build only for armeabi-v7a.
ndk {
abiFilters = new HashSet<>()
if (project.hasProperty('arm32') || project.hasProperty('armeabi-v7a')) {
abiFilters.add('armeabi-v7a')
}
if (project.hasProperty('arm64') || project.hasProperty('arm64-v8a')) {
abiFilters.add('arm64-v8a')
}
if (project.hasProperty('x86')) {
abiFilters.add('x86')
}
if (project.hasProperty('x86_64') || project.hasProperty('x64')) {
abiFilters.add('x86_64')
}
if (abiFilters.isEmpty()) {
abiFilters.add('armeabi-v7a')
abiFilters.add('arm64-v8a')
// For the emulator, chromebooks and some Intel Atom devices.
abiFilters.add('x86_64')
}
println('Building for ' + abiFilters + ' archs.')
}
setProperty('archivesBaseName', appName.replaceAll('\\s','') + '-' + defaultConfig.versionCode)
} }
flavorDimensions += 'default' flavorDimensions += 'default'
@@ -89,29 +182,26 @@ android {
google { google {
dimension 'default' dimension 'default'
applicationIdSuffix '.google'
versionName = android.defaultConfig.versionName + '-Google' versionName = android.defaultConfig.versionName + '-Google'
buildConfigField 'String', 'SUPPORT_MAIL', '"gplay@comaps.app"' buildConfigField 'String', 'SUPPORT_MAIL', '"gplay@comaps.app"'
buildConfigField 'String', 'REVIEW_URL', '"market://details?id=app.comaps.google"' buildConfigField 'String', 'REVIEW_URL', '"market://details?id=app.comaps"'
} }
// Distributed directly by the project, e.g. in repo releases, chats, etc.
web { web {
dimension 'default' dimension 'default'
versionName = android.defaultConfig.versionName applicationIdSuffix '.web'
versionName = android.defaultConfig.versionName + '-Web'
buildConfigField 'String', 'SUPPORT_MAIL', '"apk@comaps.app"' buildConfigField 'String', 'SUPPORT_MAIL', '"apk@comaps.app"'
} }
fdroid { fdroid {
dimension 'default' dimension 'default'
applicationIdSuffix '.fdroid'
versionName = android.defaultConfig.versionName + '-FDroid' versionName = android.defaultConfig.versionName + '-FDroid'
buildConfigField 'String', 'SUPPORT_MAIL', '"fdroid@comaps.app"' buildConfigField 'String', 'SUPPORT_MAIL', '"fdroid@comaps.app"'
} }
huawei { huawei {
dimension 'default' dimension 'default'
applicationIdSuffix '.huawei'
versionName = android.defaultConfig.versionName + '-Huawei' versionName = android.defaultConfig.versionName + '-Huawei'
versionCode = HUAWEI_VERSION_CODE_BASE + android.defaultConfig.versionCode versionCode = HUAWEI_VERSION_CODE_BASE + android.defaultConfig.versionCode
buildConfigField 'String', 'SUPPORT_MAIL', '"huawei@comaps.app"' buildConfigField 'String', 'SUPPORT_MAIL', '"huawei@comaps.app"'
@@ -128,202 +218,154 @@ android {
splits.abi { splits.abi {
boolean enabled = project.hasProperty('splitApk') boolean enabled = project.hasProperty('splitApk')
println ('Create separate apks: ' + enabled) println ('Create separate apks: ' + enabled)
enable = enabled enable enabled
reset() reset()
include 'x86', 'armeabi-v7a', 'arm64-v8a', 'x86_64' include 'x86', 'armeabi-v7a', 'arm64-v8a', 'x86_64'
universalApk = true universalApk true
} }
lint { lint {
disable 'MissingTranslation' disable 'MissingTranslation'
// https://github.com/organicmaps/organicmaps/issues/3551 // https://github.com/organicmaps/organicmaps/issues/3551
disable 'MissingQuantity', 'UnusedQuantity' disable 'MissingQuantity', 'UnusedQuantity'
// https://github.com/organicmaps/organicmaps/issues/3550
disable 'ByteOrderMark'
// https://github.com/organicmaps/organicmaps/issues/1077 // https://github.com/organicmaps/organicmaps/issues/1077
disable 'CustomSplashScreen' disable 'CustomSplashScreen'
// https://github.com/organicmaps/organicmaps/issues/3610 // https://github.com/organicmaps/organicmaps/issues/3610
disable 'InsecureBaseConfiguration' disable 'InsecureBaseConfiguration'
abortOnError = true abortOnError true
} }
gradle.projectsEvaluated { gradle.projectsEvaluated {
android.applicationVariants.all { variant -> android.applicationVariants.all { variant ->
def task = variant.name.capitalize() def task = variant.name.capitalize()
project.task(type: Exec, "run${task}", dependsOn: "install${task}") { project.task(type: Exec, "run${task}", dependsOn: "install${task}") {
commandLine android.getAdbExe(), 'shell', 'am', 'start', '-n', "$applicationId/app.organicmaps.DownloadResourcesActivity", '-a', 'android.intent.action.MAIN', '-c', 'android.intent.category.LAUNCHER' commandLine android.getAdbExe(), 'shell', 'am', 'start', '-n', "$applicationId/app.comaps.DownloadResourcesActivity", '-a', 'android.intent.action.MAIN', '-c', 'android.intent.category.LAUNCHER'
} }
} }
} }
def secureReleasePropertiesFileExists = file('secure.properties.release').exists() def securityPropertiesFileExists = file('secure.properties').exists()
if (secureReleasePropertiesFileExists) { if (securityPropertiesFileExists) {
apply from: 'secure.properties.release' apply from: 'secure.properties'
}
def secureTestPropertiesFileExists = file('secure.properties.test').exists()
if (secureTestPropertiesFileExists) {
apply from: 'secure.properties.test'
} }
signingConfigs { signingConfigs {
debug { debug {
storeFile file('comaps-debug.keystore') storeFile file('debug.keystore')
storePassword '12345678' storePassword '12345678'
keyAlias 'CoMaps Debug' keyAlias 'debug'
keyPassword '12345678' keyPassword '12345678'
} }
test {
if (secureTestPropertiesFileExists) {
storeFile file(secretTestStoreFile)
storePassword secretTestStorePassword
keyAlias secretTestKeyAlias
keyPassword secretTestKeyPassword
} else {
println('secure.properties.test doesn\'t exist')
}
}
release { release {
if (secureReleasePropertiesFileExists) { if (securityPropertiesFileExists) {
storeFile file(secretReleaseStoreFile) println('The release signing keys are available')
storePassword secretReleaseStorePassword storeFile file(spropStoreFile)
keyAlias secretReleaseKeyAlias storePassword spropStorePassword
keyPassword secretReleaseKeyPassword keyAlias spropKeyAlias
keyPassword spropKeyPassword
} else { } else {
println('secure.properties.release doesn\'t exist') println('The release signing keys are unavailable')
} }
} }
} }
buildTypes { buildTypes {
def taskName = getGradle().getStartParameter().getTaskRequests().toString().toLowerCase()
debug { debug {
applicationIdSuffix '.debug' // Allows to install debug and release builds together applicationIdSuffix '.debug' // Allows to install debug and release builds together
versionNameSuffix '-debug' versionNameSuffix '-debug'
jniDebuggable true // Enable jni debug build
zipAlignEnabled true zipAlignEnabled true
signingConfig = signingConfigs.debug signingConfig signingConfigs.debug
resValue 'string', 'app_name', 'CoMaps Debug' resValue 'string', 'app_name', 'Debug CoMaps'
// Do not generate separate debug symbols for debug apps, because we don't distribute them.
ndk.debugSymbolLevel = 'none'
if (googleFirebaseServicesEnabled) {
// Keep debug symbols for test lab.
ndk.debugSymbolLevel = 'symbol_table'
firebaseCrashlytics {
nativeSymbolUploadEnabled true
}
}
} }
release { release {
if (taskName.contains('release')) { signingConfig signingConfigs.release
if (secureReleasePropertiesFileExists) {
println('Using RELEASE signing keys from secure.properties.release')
signingConfig = signingConfigs.release
} else {
println('NO RELEASE signing keys found')
println('Using DEBUG signing keys')
signingConfig = signingConfigs.debug
}
}
minifyEnabled true minifyEnabled true
shrinkResources = true shrinkResources true
// Includes the default ProGuard rules files that are packaged with the Android Gradle plugin. // Includes the default ProGuard rules files that are packaged with the Android Gradle plugin.
// To learn more, go to the documentation section about R8 configuration files. // To learn more, go to the documentation section about R8 configuration files.
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
resValue 'string', 'app_name', project.ext.appName resValue 'string', 'app_name', project.ext.appName
// Full size symbols are too big for Google, 217mb aab vs 95mb.
ndk.debugSymbolLevel = 'symbol_table'
if (googleFirebaseServicesEnabled) {
firebaseCrashlytics {
nativeSymbolUploadEnabled true
}
}
} }
beta { beta {
applicationIdSuffix '.test' applicationIdSuffix '.beta'
versionNameSuffix '-test' versionNameSuffix '-beta'
if (taskName.contains('beta')) { signingConfig signingConfigs.release
if (secureTestPropertiesFileExists) {
println('Using TEST signing keys from secure.properties.test')
signingConfig = signingConfigs.test
} else {
println('NO TEST signing keys found')
println('Using DEBUG signing keys')
signingConfig = signingConfigs.debug
}
}
minifyEnabled true minifyEnabled true
shrinkResources = true shrinkResources true
// Includes the default ProGuard rules files that are packaged with the Android Gradle plugin. // Includes the default ProGuard rules files that are packaged with the Android Gradle plugin.
// To learn more, go to the documentation section about R8 configuration files. // To learn more, go to the documentation section about R8 configuration files.
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
matchingFallbacks = ['release'] // use dependencies of "release" build type matchingFallbacks = ['debug', 'release']
resValue 'string', 'app_name', 'CoMaps Test' resValue 'string', 'app_name', 'Beta CoMaps'
// Full size symbols are too big for Google, 217mb aab vs 95mb.
ndk.debugSymbolLevel = 'symbol_table'
if (googleFirebaseServicesEnabled) {
firebaseCrashlytics {
nativeSymbolUploadEnabled true
}
firebaseAppDistribution {
// A new beta release is created for each commit.
// Use the last commit message for the release notes.
releaseNotes = getCommitMessage()
groups = 'qa' // Notify only selected people.
serviceCredentialsFile = "$projectDir/firebase-app-distribution.json"
}
}
}
}
externalNativeBuild {
cmake {
version '3.22.1+'
buildStagingDirectory './nativeOutputs'
path '../../CMakeLists.txt'
} }
} }
// We don't compress these extensions in assets/ because our random FileReader can't read zip-compressed files from apk. // We don't compress these extensions in assets/ because our random FileReader can't read zip-compressed files from apk.
// TODO: Load all minor files via separate call to ReadAsString which can correctly handle compressed files in zip containers. // TODO: Load all minor files via separate call to ReadAsString which can correctly handle compressed files in zip containers.
androidResources { androidResources {
ignoreAssetsPattern = '!.svn:!.git:!.DS_Store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~' ignoreAssetsPattern '!.svn:!.git:!.DS_Store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~'
noCompress = ['txt', 'bin', 'html', 'png', 'json', 'mwm', 'ttf', 'sdf', 'ui', 'config', 'csv', 'spv', 'obj'] noCompress = ['txt', 'bin', 'html', 'png', 'json', 'mwm', 'ttf', 'sdf', 'ui', 'config', 'csv', 'spv', 'obj']
localeFilters += [
"af",
"ar",
"az",
"be",
"bg",
"ca",
"cs",
"da",
"de",
"el",
"en",
"en-rGB",
"es",
"es-rMX",
"et",
"eu",
"fa",
"fi",
"fr",
"fr-rCA",
"iw",
"hi",
"hu",
"in",
"it",
"ja",
"ko",
"lt",
"lv",
"mr",
"mt",
"nb",
"nl",
"pl",
"pt",
"pt-rBR",
"ro",
"ru",
"sk",
"sr",
"sv",
"sw",
"th",
"tr",
"uk",
"vi",
"zh",
"zh-rHK",
"zh-rMO",
"zh-rTW"
]
} }
compileOptions { compileOptions {
coreLibraryDesugaringEnabled = true coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_21 sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_21 targetCompatibility JavaVersion.VERSION_17
} }
} }
dependencies { dependencies {
implementation project(':sdk') coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.4'
coreLibraryDesugaring libs.android.tools.desugar
// Google Play Location Services // Google Play Location Services
// TODO(@pastk): enabled via microG in all flavors,
// so move google/java/app/organicmaps/location/* into main/ and remove symlinks.
// //
// Please add symlinks to google/java/app/organicmaps/location for each new gms-enabled flavor below: // Please add symlinks to google/java/app/organicmaps/location for each new gms-enabled flavor below:
// ``` // ```
@@ -332,35 +374,55 @@ dependencies {
// ls -la src/$flavor/java/app/organicmaps/location/GoogleFusedLocationProvider.java // ls -la src/$flavor/java/app/organicmaps/location/GoogleFusedLocationProvider.java
// ``` // ```
// //
// microG project's FOSS re-implementation of the proprietary libs.google.services.location webImplementation 'com.google.android.gms:play-services-location:21.3.0'
implementation libs.microg.services.location googleImplementation 'com.google.android.gms:play-services-location:21.3.0'
huaweiImplementation 'com.google.android.gms:play-services-location:21.3.0'
// This is the microG project's re-implementation which is permissible on
// F-droid because it's Apache-2.0.
fdroidImplementation 'org.microg.gms:play-services-location:0.3.6.244735'
// Google Firebase Services
if (googleFirebaseServicesEnabled) {
// Import the BoM for the Firebase platform
implementation platform('com.google.firebase:firebase-bom:33.5.1')
// Add the dependencies for the Crashlytics and Analytics libraries
// When using the BoM, you don't specify versions in Firebase library dependencies
implementation 'com.google.firebase:firebase-crashlytics'
implementation 'com.google.firebase:firebase-crashlytics-ndk'
}
// This line is added as a workaround for duplicate classes error caused by some outdated dependency: // This line is added as a workaround for duplicate classes error caused by some outdated dependency:
// > A failure occurred while executing com.android.build.gradle.internal.tasks.CheckDuplicatesRunnable // > A failure occurred while executing com.android.build.gradle.internal.tasks.CheckDuplicatesRunnable
// We don't use Kotlin, but some dependencies are actively using it. // We don't use Kotlin, but some dependencies are actively using it.
// See https://stackoverflow.com/a/75719642 // See https://stackoverflow.com/a/75719642
implementation libs.androidx.core implementation 'androidx.core:core:1.15.0'
implementation(platform(libs.jetbrains.kotlin.bom)) implementation(platform('org.jetbrains.kotlin:kotlin-bom:2.1.10'))
implementation libs.androidx.annotation implementation 'androidx.annotation:annotation:1.9.1'
implementation libs.androidx.appcompat implementation 'androidx.appcompat:appcompat:1.7.0'
implementation libs.androidx.car.app implementation 'androidx.car.app:app:1.7.0-rc01'
implementation libs.androidx.car.app.projected implementation 'androidx.car.app:app-projected:1.7.0-rc01'
implementation libs.androidx.constraintlayout implementation 'androidx.constraintlayout:constraintlayout:2.2.0'
implementation libs.androidx.fragment implementation 'androidx.fragment:fragment:1.8.5'
implementation libs.androidx.preference implementation 'androidx.preference:preference:1.2.1'
implementation libs.androidx.recyclerview implementation 'androidx.recyclerview:recyclerview:1.3.2'
implementation libs.androidx.work.runtime implementation 'androidx.work:work-runtime:2.10.0'
implementation libs.androidx.lifecycle.process implementation 'androidx.lifecycle:lifecycle-process:2.8.7'
implementation libs.android.material implementation 'com.google.android.material:material:1.12.0'
// Fix for app/organicmaps/util/FileUploadWorker.java:14: error: cannot access ListenableFuture // Fix for app/organicmaps/util/FileUploadWorker.java:14: error: cannot access ListenableFuture
// https://github.com/organicmaps/organicmaps/issues/6106 // https://github.com/organicmaps/organicmaps/issues/6106
implementation libs.google.guava implementation 'com.google.guava:guava:33.3.0-android'
implementation libs.appdevnext.androidchart implementation 'com.github.devnullorthrow:MPAndroidChart:3.2.0-alpha'
implementation 'net.jcip:jcip-annotations:1.0'
// Test Dependencies // Test Dependencies
androidTestImplementation libs.androidx.test.junit androidTestImplementation 'androidx.test.ext:junit:1.2.1'
testImplementation libs.junit testImplementation 'junit:junit:4.13.2'
testImplementation libs.mockito.core testImplementation 'org.mockito:mockito-core:5.15.2'
testImplementation 'org.mockito:mockito-inline:5.2.0'
}
tasks.withType(JavaCompile) {
options.compilerArgs << '-Xlint:unchecked' << '-Xlint:deprecation'
} }
android.applicationVariants.all { variant -> android.applicationVariants.all { variant ->
@@ -372,12 +434,37 @@ android.applicationVariants.all { variant ->
variant.resValue 'string', 'app_id', variant.applicationId variant.resValue 'string', 'app_id', variant.applicationId
} }
task prepareGoogleReleaseListing {
// Prepares Google Play metainfo from F-Droid metainfo.
final sourceFlavor = 'fdroid'
final targetFlavor = 'google'
doLast {
final sourceDir = new File("${projectDir}/src/$sourceFlavor/play/listings")
final targetDir = new File("${projectDir}/src/$targetFlavor/play/listings")
final sourceFiles = fileTree(dir: sourceDir,
include: '**/*.txt', exclude: "**/*-${targetFlavor}.txt")
sourceFiles.each { File sourceFile ->
final locale = sourceFile.parentFile.getName()
final targetLocaleDir = new File(targetDir, locale)
if (!targetLocaleDir.isDirectory())
targetLocaleDir.mkdirs()
final targetFile = new File(targetLocaleDir, sourceFile.getName())
// Override Google-specific values by using ${name}-google.txt files.
final overrideFile = new File(sourceFile.getPath().replace('.txt', "-${targetFlavor}.txt"))
targetFile.text = overrideFile.exists() ? overrideFile.text : sourceFile.text
}
copy {
from "${projectDir}/../../screenshots/android"
into targetDir
}
}
}
play { play {
enabled.set(false) enabled.set(false)
track.set('production') track.set('production')
defaultToAppBundles.set(true) defaultToAppBundles.set(true)
releaseStatus.set(ReleaseStatus.IN_PROGRESS) releaseStatus.set(ReleaseStatus.IN_PROGRESS)
userFraction.set(0.2d) // Rollout to 20% of users
serviceAccountCredentials.set(file('google-play.json')) serviceAccountCredentials.set(file('google-play.json'))
} }
@@ -411,7 +498,3 @@ huaweiPublish {
} }
} }
} }
tasks.withType(JavaCompile).configureEach {
options.compilerArgs << '-Xlint:unchecked' << '-Xlint:deprecation'
}

Binary file not shown.

BIN
android/app/debug.keystore Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/bg_app_icon_test"/>
<foreground android:drawable="@drawable/ic_launcher_foreground_test"/>
<monochrome android:drawable="@drawable/ic_launcher_foreground_monochrome"/>
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/bg_app_icon_debug"/>
<foreground android:drawable="@drawable/ic_launcher_foreground_debug"/>
<monochrome android:drawable="@drawable/ic_launcher_foreground_monochrome"/>
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

View File

@@ -1 +1 @@
https://www.comaps.app/ https://organicmaps.app/

View File

@@ -0,0 +1,53 @@
‣ تطبيقنا المجاني لا يتتبعك ولا يحتوي على إعلانات ويحتاج إلى دعمك.
‣ يتم تحسينه باستمرار من قبل المساهمين وفريقنا الصغير، في أوقات فراغنا.
‣ إذا كان هناك شيء خاطئ أو مفقود على الخريطة، يرجى إصلاحه في <b>OpenStreetMap</b> وانظر إلى تعديلاتك في تحديث الخرائط المستقبلية.
‣ إذا لم ينجح التنقل أو البحث، يرجى إرسال بريد إلكتروني إلينا. نرد على <i>كل بريد إلكتروني</i> وسنصلحه في أسرع وقت ممكن!
<b>ملاحظاتك ومراجعات الخمس نجوم هي أفضل المحفزات لنا!</b>
الميزات الرئيسية:
• مجاني، مفتوح المصدر، لا إعلانات، لا تتبع
• خرائط مفصلة غير متصلة بالإنترنت مع أماكن غير موجودة على خرائط Google، وذلك بفضل مجتمع <b>OpenStreetMap</b>
• طرق ركوب الدراجات ومسارات المشي لمسافات طويلة ومسارات المشي
• خطوط الكنتور وملامح الارتفاع والقمم والمنحدرات
• المشي بدوران وركوب الدراجات والملاحة التجريبية بالسيارة مع التوجيه الصوتي
• البحث السريع في وضع عدم الاتصال
• العلامات المرجعية وتتبع التصدير والاستيراد بأشكال KML و KMZ و GPX
• الوضع المظلم لحماية عينيك
لا يوجد نظام وسائل النقل العام وخرائط الأقمار الصناعية وغيرها من الميزات الرائعة <i>حتى الآن</i> في الخرائط العضوية. ولكن مع <i>مساعدتك ودعمك</i>، يمكننا أن نجعل هذا العالم أفضل خطوة بخطوة.
الخرائط العضوية هي <b>نقية وعضوية، مصنوعة من الحب</b>:
• تجربة سريعة مشتعلة في وضع عدم الاتصال
• يحترم خصوصيتك
• يحفظ بطاريتك
• لا توجد رسوم غير متوقعة لبيانات الهاتف المحمول
• سهل الاستخدام، مع تضمين أهم الميزات فقط
خالية من أجهزة التعقب والأشياء السيئة الأخرى:
• لا إعلانات
• لا تتبع
• عدم جمع البيانات
• لا يوجد اتصال هاتفي بالمنزل
• لا تسجيل مزعج
• لا توجد دروس إلزامية
• لا بريد إلكتروني مزعج
• لا توجد إشعارات دفع
• لا توجد أواني حلوى
• لا مبيدات عضوية بالكامل
في Organic Maps نعتقد أن <b>الخصوصية هي حق أساسي من حقوق الإنسان:</b>
• Organic Maps هو مشروع مفتوح المصدر يحركه المجتمع المستقل
• نحن نحمي خصوصيتك من أعين المتطفلين لدى شركات التقنيات الكبيرة
•ابق آمنًا بغض النظر عن مكان وجودك
يتم العثور على أجهزة تعقب صفرية والأذونات المطلوبة بشكل ضئيل فقط وفقًا لتقرير Exodus Privacy.
الرجاء زيارة <b><i>organicmaps.app</i></b> للحصول على مزيد من التفاصيل والأسئلة الشائعة، والاتصال بنا مباشرة على @OrganicMapsApp في Telegram.
ارفض المراقبة - احتضن حريتك.
<b>أعطي Organic Maps تجربة!</b>

View File

@@ -0,0 +1,8 @@
• New OpenStreetMap data as of February 27
• Ability to manually arrange intermediate route points
• Share a single selected track from the list
• Improved routing for bicycles
• Display a system notification when downloading maps and don't interrupt background downloads
• Added a flashing Track Recording widget
…more details at omaps.org/news

View File

@@ -0,0 +1 @@
التنقل بالخصوصية - مفتوح المصدر و مُدار من طرف المُجتمع

View File

@@ -0,0 +1 @@
تنزه Organic Maps بدون إنترنت

View File

@@ -0,0 +1 @@
Organic Maps: تنزه والدراجة والقيادة بدون إنترنت

View File

@@ -0,0 +1 @@
https://www.youtube.com/watch?v=dK-CUuy82Uc

View File

@@ -1 +0,0 @@
CoMaps - Mapas ensin conexón con privacidá

View File

@@ -0,0 +1,53 @@
‣ Our free app does not track you, does not have ads, and it needs your support.
‣ It is constantly being improved by contributors and our small team, in our free time.
‣ If something is wrong or missing on the map, please fix it in <b>OpenStreetMap</b> and see your changes in the future maps update.
‣ If navigation or search doesn't work, please check it on osm.org first, and then email us. We reply to <i>EVERY</i> email, and we'll fix it ASAP!
<b>Your feedback and 5-star reviews are the best motivators for us!</b>
Key features:
• Free, open-source, no ads, no tracking
• Detailed offline maps with places that don't exist on Google maps, thanks to the <b>OpenStreetMap</b> community
• Cycling routes, hiking trails, and walking paths
• Contour lines, elevation profiles, peaks, and slopes
• Turn-by-turn walking, cycling, and car navigation with voice guidance and Android Auto
• Fast offline search
• Bookmarks and tracks export and import in KML, KMZ, GPX formats
• Dark mode to protect your eyes
There is no public transport, satellite maps, and other cool features <i>yet</i> in Organic Maps. But with <i>your help and support</i>, we can make better maps step by step.
Organic Maps is <b>pure and organic, made with love</b>:
• Blazing fast offline experience
• Respects your privacy
• Saves your battery
• No unexpected mobile data charges
• Simple to use, with only most important features included
Free from trackers and other bad stuff:
• No ads
• No tracking
• No data collection
• No phoning home
• No annoying registration
• No mandatory tutorials
• No noisy email spam
• No push notifications
• No crapware
• N̶o̶ ̶p̶e̶s̶t̶i̶c̶i̶d̶e̶s̶ Purely organic
At Organic Maps, we believe that <b>privacy is a fundamental human right</b>:
• Organic Maps is an indie community-driven open-source project
• We protect privacy from Big Tech's prying eyes
• Stay safe no matter wherever you are
Zero trackers and only minimally required permissions are found according to Exodus Privacy Report.
Please visit <b><i>organicmaps.app</i></b> website for additional details and FAQ, and contact us directly at @OrganicMapsApp in Telegram.
Reject surveillance - embrace your freedom.
<b>Give Organic Maps a try!</b>

View File

@@ -0,0 +1,8 @@
• New OpenStreetMap data as of February 27
• Ability to manually arrange intermediate route points
• Share a single selected track from the list
• Improved routing for bicycles
• Display a system notification when downloading maps and don't interrupt background downloads
• Added a flashing Track Recording widget
…more details at omaps.org/news

View File

@@ -0,0 +1 @@
Open-source, community-driven maps for travelers, tourists, cyclists & hikers

View File

@@ -0,0 +1 @@
Organic Maps: offline maps

View File

@@ -0,0 +1 @@
Organic Maps Offline Hike, Bike, GPS Navigation

View File

@@ -0,0 +1 @@
https://www.youtube.com/watch?v=dK-CUuy82Uc

View File

@@ -0,0 +1,53 @@
‣ Our free app does not track you, does not have ads, and it needs your support.
‣ It is constantly being improved by contributors and our small team, in our free time.
‣ If something is wrong or missing on the map, please fix it in <b>OpenStreetMap</b> and see your changes in the future maps update.
‣ If navigation or search doesn't work, please check it on osm.org first, and then email us. We reply to <i>EVERY</i> email, and we'll fix it ASAP!
<b>Your feedback and 5-star reviews are the best motivators for us!</b>
Key features:
• Free, open-source, no ads, no tracking
• Detailed offline maps with places that don't exist on Google maps, thanks to the <b>OpenStreetMap</b> community
• Cycling routes, hiking trails, and walking paths
• Contour lines, elevation profiles, peaks, and slopes
• Turn-by-turn walking, cycling, and car navigation with voice guidance and Android Auto
• Fast offline search
• Bookmarks and tracks export and import in KML, KMZ, GPX formats
• Dark mode to protect your eyes
There is no public transport, satellite maps, and other cool features <i>yet</i> in Organic Maps. But with <i>your help and support</i>, we can make better maps step by step.
Organic Maps is <b>pure and organic, made with love</b>:
• Blazing fast offline experience
• Respects your privacy
• Saves your battery
• No unexpected mobile data charges
• Simple to use, with only most important features included
Free from trackers and other bad stuff:
• No ads
• No tracking
• No data collection
• No phoning home
• No annoying registration
• No mandatory tutorials
• No noisy email spam
• No push notifications
• No crapware
• N̶o̶ ̶p̶e̶s̶t̶i̶c̶i̶d̶e̶s̶ Purely organic
At Organic Maps, we believe that <b>privacy is a fundamental human right</b>:
• Organic Maps is an indie community-driven open-source project
• We protect privacy from Big Tech's prying eyes
• Stay safe no matter wherever you are
Zero trackers and only minimally required permissions are found according to Exodus Privacy Report.
Please visit <b><i>organicmaps.app</i></b> website for additional details and FAQ, and contact us directly at @OrganicMapsApp in Telegram.
Reject surveillance - embrace your freedom.
<b>Give Organic Maps a try!</b>

View File

@@ -0,0 +1,8 @@
• Новыя дадзеныя OpenStreetMap ад 27 лютага
• Магчымасць уручную расстаўляць прамежкавыя кропкі маршруту
• Экспарт аднаго абранага трэка са спісу
• Палепшаная маршрутызацыя для веласіпедыстаў
• Дададзена сістэмнае апавяшчэнне пры загрузцы карт, фонавыя загрузкі больш не перарываюцца
• Дададзены мігатлівы віджэт запісу трэка
…і шматлікае іншае на omaps.org/news

View File

@@ -0,0 +1 @@
Open-source, community-driven maps for travelers, tourists, cyclists & hikers

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