Compare commits

..

18 Commits

Author SHA1 Message Date
zyphlar
acd97c816d Fallback to previous Coastlines 2025-08-04 05:18:22 +00:00
zyphlar
13aa12fb97 Try 18 Features threads 2025-08-04 05:17:45 +00:00
zyphlar
83ddd58bfc sftp fix 2025-08-04 05:17:17 +00:00
zyphlar
49c954ceb8 fix empty relations 2025-08-04 05:12:26 +00:00
zyphlar
31786731ca Settings change
Signed-off-by: zyphlar <zyphlar@gmail.com>
2025-07-28 13:54:08 +07:00
Konstantin Pastbin
c509263c5b [generator] Skip World map download and symbols regen
Signed-off-by: zyphlar <zyphlar@gmail.com>
2025-07-28 13:54:08 +07:00
Konstantin Pastbin
8aa1cfb083 [generator] Update conf path
Signed-off-by: zyphlar <zyphlar@gmail.com>
2025-07-28 13:54:08 +07:00
zyphlar
6537ca34cd Update generator scripts for docker/prod
Signed-off-by: zyphlar <zyphlar@gmail.com>
2025-07-28 13:54:08 +07:00
zyphlar
306aa002f0 Add docker run script
Signed-off-by: zyphlar <zyphlar@gmail.com>
2025-07-28 13:54:08 +07:00
Konstantin Pastbin
21743be44d Increase Features threads from 12 to 16
Signed-off-by: Konstantin Pastbin <konstantin.pastbin@gmail.com>
2025-07-28 13:54:08 +07:00
zyphlar
119650d7f3 Update tools/unix/docker_maps_generator.sh
Signed-off-by: zyphlar <zyphlar@noreply.codeberg.org>
2025-07-28 13:54:08 +07:00
zyphlar
be70c34eba Tweaks, get subway hooks proper
Signed-off-by: zyphlar <zyphlar@gmail.com>
2025-07-28 13:54:08 +07:00
Konstantin Pastbin
ac9b70d229 Update subways path
Signed-off-by: Konstantin Pastbin <konstantin.pastbin@gmail.com>
2025-07-28 13:54:08 +07:00
Konstantin Pastbin
85cec703e5 Update INI
Signed-off-by: Konstantin Pastbin <konstantin.pastbin@gmail.com>
2025-07-28 13:54:08 +07:00
zyphlar
5925fe85b2 Fix s3 variables
Signed-off-by: zyphlar <zyphlar@gmail.com>
2025-07-28 13:54:08 +07:00
zyphlar
f0458c9715 Map generation mostly working, but slow and not doing full planet with add-ins yet
Signed-off-by: zyphlar <zyphlar@gmail.com>
2025-07-28 13:54:08 +07:00
zyphlar
54fc3d0b64 On-server tweaks
Signed-off-by: zyphlar <zyphlar@gmail.com>
2025-07-28 13:54:08 +07:00
zyphlar
df70b29623 Add files to automatically generate maps with Docker
Signed-off-by: zyphlar <zyphlar@gmail.com>
2025-07-28 13:54:08 +07:00
4297 changed files with 948146 additions and 90714 deletions

View File

@@ -1,61 +1,48 @@
# Configuration file for clang-format, based on docs/CPP_STYLE.md.
---
BasedOnStyle: Google
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignConsecutiveMacros: AcrossEmptyLinesAndComments
AlignEscapedNewlines: LeftWithLastLine
AlignOperands: AlignAfterOperator
AllowShortBlocksOnASingleLine: Empty
AllowShortCaseLabelsOnASingleLine: true
AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: true
BraceWrapping:
AfterCaseLabel: true
AfterClass: true
AfterControlStatement: Always
AfterEnum: true
AfterExternBlock: true
AfterFunction: true
AfterNamespace: true
AfterObjCDeclaration: true
AfterStruct: true
AfterUnion: true
AfterExternBlock: true
BeforeCatch: true
BeforeElse: true
BeforeLambdaBody: true
BeforeWhile: true
IndentBraces: false
SplitEmptyFunction: false
SplitEmptyNamespace: false
SplitEmptyRecord: false
BinPackArguments: true
BinPackParameters: true
BreakAfterJavaFieldAnnotations: true
SplitEmptyNamespace: false
BreakBeforeBraces: Custom
BreakConstructorInitializers: BeforeComma
BreakInheritanceList: BeforeComma
ColumnLimit: 120
ConstructorInitializerIndentWidth: 2
ContinuationIndentWidth: 4
ContinuationIndentWidth: 2
DerivePointerAlignment: false
EmptyLineBeforeAccessModifier: Always
IncludeBlocks: Preserve
IndentAccessModifiers: false
IndentCaseLabels: false
IndentExternBlock: NoIndent
InsertBraces: false
InsertNewlineAtEOF: true
LambdaBodyIndentation: OuterScope
PackConstructorInitializers: CurrentLine
PackConstructorInitializers: Never
PointerAlignment: Middle
RemoveBracesLLVM: true
RemoveSemicolon: true
QualifierAlignment: Right
SpacesInContainerLiterals: false
Standard: Latest
TabWidth: 2
---
Language: Java
AllowShortFunctionsOnASingleLine: Empty
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,5 +1,6 @@
name: 🐞 Bug Report
description: Report a problem you've encountered
title: "bug: "
labels:
- bug
body:
@@ -66,4 +67,4 @@ body:
label: Additional context
description: Add any other context or comments that may be useful.
validations:
required: false
required: false

View File

@@ -1,5 +1,6 @@
name: "💡 Feature Request"
description: "Suggest an idea or improvement for CoMaps"
title: "feat: "
labels:
- "enhancement"
body:
@@ -43,4 +44,4 @@ body:
label: "Additional context"
description: "Any other context, comments, or screenshots to support your request."
validations:
required: false
required: false

View File

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

View File

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

View File

@@ -4,6 +4,9 @@ on:
schedule:
- 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:
precondition:
runs-on: ubuntu-latest
@@ -70,6 +73,10 @@ jobs:
SECURE_PROPERTIES: ${{ secrets.SECURE_PROPERTIES }}
RELEASE_KEYSTORE: ${{ secrets.RELEASE_KEYSTORE }}
- name: Configure repository
shell: bash
run: ./configure.sh
- name: Compile
shell: bash
working-directory: android

View File

@@ -2,6 +2,9 @@ name: Android Release Metadata
on:
workflow_dispatch: # Manual trigger
env:
JAVA_HOME: /usr/lib/jvm/temurin-17-jdk-amd64 # Java 17 is required for Android Gradle 8 plugin
jobs:
android-release-metadata:
name: Upload Google Play metadata

View File

@@ -5,6 +5,7 @@ on:
env:
RELEASE_NOTES: android/app/src/google/play/release-notes/en-US/default.txt
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:
tag:
@@ -116,6 +117,10 @@ jobs:
SECURE_PROPERTIES: ${{ secrets.SECURE_PROPERTIES }}
RELEASE_KEYSTORE: ${{ secrets.RELEASE_KEYSTORE }}
- name: Configure repository
shell: bash
run: ./configure.sh
- name: Set up SDK
shell: bash
run: echo "sdk.dir=$ANDROID_SDK_ROOT" > android/local.properties

View File

@@ -3,20 +3,20 @@ on:
workflow_dispatch: # Manual trigger
pull_request:
paths:
- packaging/app.comaps.comaps.metainfo.xml
- .forgejo/workflows/appstream-check.yaml # Run check on self change
- packaging/app.organicmaps.desktop.metainfo.xml
- .forgejo/workflows/appstream-check.yaml # Run check on self change
jobs:
validate-appstream:
name: Validate appstream metadata xml
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
steps:
- name: Checkout sources
uses: actions/checkout@v4
with:
fetch-depth: 1
sparse-checkout: |
packaging/app.comaps.comaps.metainfo.xml
packaging/app.organicmaps.desktop.metainfo.xml
- name: Install appstream validator and flatpak Builder
shell: bash
@@ -29,8 +29,8 @@ jobs:
- name: Lint appstream data with flatpak Builder
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
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:
should-run-check:
name: Should run coverage
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
outputs:
run-from-pr: ${{ steps.run-from-pr.outputs.run-from-pr }}
manually-triggered: ${{ steps.manually-triggered.outputs.manually-triggered }}
@@ -59,9 +59,14 @@ jobs:
coverage:
needs: should-run-check
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'}}
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
uses: actions/checkout@v4
with:
@@ -89,6 +94,10 @@ jobs:
llvm \
gcovr
- name: Configure repository
shell: bash
run: ./configure.sh
- name: Configure ccache
uses: hendrikmuhs/ccache-action@v1.2
with:

View File

@@ -5,4 +5,4 @@ jobs:
check:
runs-on: codeberg-tiny
steps:
- uses: https://github.com/KineticCafe/actions-dco@v1
- uses: https://github.com/KineticCafe/actions-dco@v1

View File

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

@@ -103,4 +103,4 @@ jobs:
-destination 'generic/platform=iOS' \
-quiet \
CODE_SIGNING_REQUIRED=NO \
CODE_SIGNING_ALLOWED=NO
CODE_SIGNING_ALLOWED=NO

View File

@@ -31,13 +31,18 @@ on:
jobs:
linux-no-unity:
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.
concurrency:
group: ${{ github.workflow }}-no-unity-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
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
uses: actions/checkout@v4
with:
@@ -66,6 +71,10 @@ jobs:
libqt6positioning6-plugins \
libqt6positioning6
- name: Configure repository
shell: bash
run: ./configure.sh
- name: Configure ccache
uses: hendrikmuhs/ccache-action@v1.2
with:
@@ -90,7 +99,7 @@ jobs:
linux-matrix:
name: Linux builds and tests
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
@@ -102,6 +111,11 @@ jobs:
cancel-in-progress: true
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
uses: actions/checkout@v4
@@ -128,6 +142,10 @@ jobs:
libqt6positioning6-plugins \
libqt6positioning6
- name: Configure repository
shell: bash
run: ./configure.sh
- name: Configure ccache
uses: hendrikmuhs/ccache-action@v1.2
with:

View File

@@ -57,6 +57,10 @@ jobs:
run: |
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew install ninja qt@6
- name: Configure repository
shell: bash
run: ./configure.sh
- name: Configure ccache
uses: hendrikmuhs/ccache-action@v1.2
with:

View File

@@ -7,7 +7,6 @@ on:
env:
JAVA_HOME: /usr/lib/jvm/temurin-17-jdk-amd64 # Java 17 is required for Android Gradle 8 plugin
SKIP_MAP_DOWNLOAD: true
jobs:
lint:
@@ -23,9 +22,9 @@ jobs:
shell: bash
run: git submodule update --depth 1 --init --recursive --jobs=$(($(nproc) * 20))
- name: Configure repository
- name: Init boost, generate textures
shell: bash
run: SKIP_GENERATE_SYMBOLS=1 ./configure.sh
run: ./configure.sh --skip-map-download
- name: Lint
shell: bash
@@ -66,7 +65,6 @@ jobs:
libxinerama-dev \
libxcursor-dev \
libxi-dev \
python3-protobuf \
zlib1g-dev
- name: Checkout sources
@@ -78,6 +76,10 @@ jobs:
shell: bash
run: git submodule update --depth 1 --init --recursive --jobs=$(($(nproc) * 20))
- name: Init boost, generate textures
shell: bash
run: ./configure.sh --skip-map-download
- name: Configure ccache
uses: hendrikmuhs/ccache-action@v1.2
with:

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

@@ -30,7 +30,6 @@ jobs:
run: |
brew install qt \
optipng
pip3 install "protobuf<3.21" --break-system-packages
- name: Checkout sources
uses: actions/checkout@v4
@@ -38,7 +37,7 @@ jobs:
shell: bash
run: git submodule update --depth 1 --init --recursive --jobs=$(($(sysctl -n hw.logicalcpu) * 20))
- name: Configure repository
- name: Init boost, download World map, generate textures
shell: bash
run: ./configure.sh

22
.gitignore vendored
View File

@@ -9,29 +9,24 @@ Makefile.Release
object_script.*.Debug
object_script.*.Release
compile_commands.json
*.local.*
stxxl.errlog
stxxl.log
screenlog.0
data/symbols/*/design/
data/styles/*/*/out/*
data/resources-*_design/*
# symbols png/sdf are now generated at build
data/symbols/**/symbols.png
data/symbols/**/symbols.sdf
data/resources-*_*/symbols.png
data/resources-*_*/symbols.sdf
data/drules_proto_default_design.bin
data/colors_design.txt
data/patterns_design.txt
data/bookmarks
data/edits.xml
data/World.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
# Compiled Python
*.pyc
@@ -50,9 +45,10 @@ omim.sdf
*.suo
*.aps
*.rc
!qt/res/windows/windows.rc
!qt/res/windows.rc
*.pdb
out/
out/*
qt/mapswithme.log
# XCode
xcode/keys/*

View File

@@ -1,5 +1,4 @@
cmake_minimum_required(VERSION 3.22.1)
project(omim C CXX)
set(CMAKE_CXX_STANDARD 20)
@@ -49,8 +48,6 @@ if (APPLE AND NOT ("${CMAKE_SYSTEM_NAME}" STREQUAL Android))
set(CMAKE_OBJCXX_VISIBILITY_PRESET hidden)
endif()
execute_process(COMMAND "./configure.sh" WORKING_DIRECTORY ${OMIM_ROOT})
message(STATUS "Using compiler ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}")
if (CMAKE_UNITY_BUILD)
@@ -106,7 +103,7 @@ if (${CMAKE_BUILD_TYPE} STREQUAL "Debug")
elseif (${CMAKE_BUILD_TYPE} MATCHES "Rel")
add_definitions(-DRELEASE)
if (NOT MSVC)
add_compile_options(-O3 $<$<CXX_COMPILER_ID:GNU>:-flto=auto>)
add_compile_options(-Ofast $<$<CXX_COMPILER_ID:GNU>:-flto=auto>) # Also enables -ffast-math
endif()
else()
message(FATAL_ERROR "Unknown build type: " ${CMAKE_BUILD_TYPE})
@@ -185,7 +182,7 @@ if (NOT PLATFORM_IPHONE AND NOT PLATFORM_ANDROID)
endif()
# 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})
if (USE_PCH)
message(STATUS "Precompiled headers are ON")
@@ -227,23 +224,50 @@ endif()
# Used in qt/ and shaders/
find_package(Python3 REQUIRED COMPONENTS Interpreter)
add_subdirectory(libs)
add_subdirectory(base)
add_subdirectory(coding)
add_subdirectory(descriptions)
add_subdirectory(drape)
add_subdirectory(drape_frontend)
add_subdirectory(editor)
add_subdirectory(ge0)
add_subdirectory(generator/mwm_diff)
add_subdirectory(geometry)
add_subdirectory(indexer)
add_subdirectory(kml)
add_subdirectory(map)
add_subdirectory(cppjansson)
add_subdirectory(platform)
add_subdirectory(routing)
add_subdirectory(routing_common)
add_subdirectory(search)
add_subdirectory(shaders)
add_subdirectory(storage)
add_subdirectory(tracking)
add_subdirectory(traffic)
add_subdirectory(transit)
if (PLATFORM_DESKTOP)
add_subdirectory(dev_sandbox)
omim_add_tool_subdirectory(feature_list)
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)
add_subdirectory(qt)
omim_add_tool_subdirectory(skin_generator)
endif()
if (GENERATOR_TOOL)
add_compile_options(-march=native -mtune=native)
message(STATUS "target CPU optimizations enabled, produced binaries will NOT work on a different CPU")
endif()
add_subdirectory(dev_sandbox)
endif()
omim_add_test_subdirectory(libs/qt_tstfrm)
omim_add_test_subdirectory(qt_tstfrm)
if (PLATFORM_ANDROID)
add_subdirectory(android/sdk/src/main/cpp)
add_subdirectory(android/app/src/main/cpp)
endif()

View File

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

View File

@@ -53,9 +53,6 @@ A community-led free & open source maps app based on [OpenStreetMap](https://www
<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://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>
@@ -125,8 +122,10 @@ You can help by donating, contributing code, translating, or by telling others a
- Build instructions: [docs/INSTALL.md](docs/INSTALL.md)
- Contribution guide: [docs/CONTRIBUTING.md](docs/CONTRIBUTING.md)
> [!NOTE]
> 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!
There is a dedicated [Zulip](https://codeberg.org/comaps/Governance/src/branch/main/contribute.md#3-team-messaging) chat for active contributors.
There is a dedicated Zulip chat for active contributors: [Zulip](https://comaps.zulipchat.com)
---
@@ -140,7 +139,7 @@ There is a dedicated [Zulip](https://codeberg.org/comaps/Governance/src/branch/m
## 💸 Funding
CoMaps is free. To fund development, we rely on your voluntary support ♥️
CoMaps is free. To stay that way, it relies on your 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).
@@ -161,4 +160,4 @@ MD5: 9cce0ffea281dc2f0e0a154d6d2e281e
## ⚖️ License
Licensed under the Apache License 2.0.
See [LICENSE](LICENSE), [NOTICE](NOTICE), and [data/copyright.html](data/copyright.html).
See [LICENSE](LICENSE), [NOTICE](NOTICE), and [data/copyright.html](data/copyright.html).

View File

@@ -18,4 +18,5 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
libxi-dev \
optipng
WORKDIR /root/comaps
RUN ./configure.sh
CMD ./gradlew -Parm64 assembleFdroidDebug

View File

@@ -19,13 +19,33 @@ apply plugin: 'com.android.application'
apply plugin: 'com.github.triplet.play'
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 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() {
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.appName = 'CoMaps'
@@ -37,10 +57,7 @@ project.ext.appName = 'CoMaps'
//}
android {
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'
namespace 'app.organicmaps'
dependenciesInfo {
// Disables dependency metadata when building APKs (for IzzyOnDroid/F-Droid)
@@ -62,23 +79,79 @@ android {
}
// All properties are read from gradle.properties file
compileSdk = propCompileSdkVersion.toInteger()
compileSdk propCompileSdkVersion.toInteger()
ndkVersion '28.2.13676358'
defaultConfig {
versionCode = rootProject.ext.versionCode
versionName = rootProject.ext.versionName
// Default package name is taken from the manifest and should be app.comaps
def ver = getVersion()
versionCode = ver.V1
versionName = ver.V2
println('Version: ' + versionName)
println('VersionCode: ' + versionCode)
minSdk = propMinSdkVersion.toInteger()
targetSdk = propTargetSdkVersion.toInteger()
minSdk propMinSdkVersion.toInteger()
targetSdk propTargetSdkVersion.toInteger()
applicationId project.ext.appId
buildConfigField 'String', 'SUPPORT_MAIL', '"android@comaps.app"'
// Should be customized in flavors.
buildConfigField 'String', 'REVIEW_URL', '""'
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'
@@ -128,10 +201,10 @@ android {
splits.abi {
boolean enabled = project.hasProperty('splitApk')
println ('Create separate apks: ' + enabled)
enable = enabled
enable enabled
reset()
include 'x86', 'armeabi-v7a', 'arm64-v8a', 'x86_64'
universalApk = true
universalApk true
}
lint {
@@ -144,7 +217,7 @@ android {
disable 'CustomSplashScreen'
// https://github.com/organicmaps/organicmaps/issues/3610
disable 'InsecureBaseConfiguration'
abortOnError = true
abortOnError true
}
gradle.projectsEvaluated {
@@ -203,29 +276,33 @@ android {
debug {
applicationIdSuffix '.debug' // Allows to install debug and release builds together
versionNameSuffix '-debug'
jniDebuggable true // Enable jni debug build
zipAlignEnabled true
signingConfig = signingConfigs.debug
signingConfig signingConfigs.debug
resValue 'string', 'app_name', 'CoMaps Debug'
// Do not generate separate debug symbols for debug apps, because we don't distribute them.
ndk.debugSymbolLevel = 'none'
}
release {
if (taskName.contains('release')) {
if (secureReleasePropertiesFileExists) {
println('Using RELEASE signing keys from secure.properties.release')
signingConfig = signingConfigs.release
signingConfig signingConfigs.release
} else {
println('NO RELEASE signing keys found')
println('Using DEBUG signing keys')
signingConfig = signingConfigs.debug
signingConfig signingConfigs.debug
}
}
minifyEnabled true
shrinkResources = true
shrinkResources true
// 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.
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
resValue 'string', 'app_name', project.ext.appName
// Full size symbols are too big for Google, 217mb aab vs 95mb.
ndk.debugSymbolLevel = 'symbol_table'
}
beta {
@@ -234,27 +311,37 @@ android {
if (taskName.contains('beta')) {
if (secureTestPropertiesFileExists) {
println('Using TEST signing keys from secure.properties.test')
signingConfig = signingConfigs.test
signingConfig signingConfigs.test
} else {
println('NO TEST signing keys found')
println('Using DEBUG signing keys')
signingConfig = signingConfigs.debug
signingConfig signingConfigs.debug
}
}
minifyEnabled true
shrinkResources = true
shrinkResources true
// 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.
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
matchingFallbacks = ['release'] // use dependencies of "release" build type
resValue 'string', 'app_name', 'CoMaps Test'
// Full size symbols are too big for Google, 217mb aab vs 95mb.
ndk.debugSymbolLevel = 'symbol_table'
}
}
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.
// TODO: Load all minor files via separate call to ReadAsString which can correctly handle compressed files in zip containers.
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']
localeFilters += [
"af",
@@ -311,7 +398,7 @@ android {
}
compileOptions {
coreLibraryDesugaringEnabled = true
coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
@@ -366,6 +453,10 @@ dependencies {
testImplementation libs.mockito.core
}
tasks.withType(JavaCompile) {
options.compilerArgs << '-Xlint:unchecked' << '-Xlint:deprecation'
}
android.applicationVariants.all { variant ->
def authorityValue = variant.applicationId + ".provider"
def authority = "\"" + authorityValue + "\""
@@ -413,7 +504,3 @@ huaweiPublish {
}
}
}
tasks.withType(JavaCompile).configureEach {
options.compilerArgs << '-Xlint:unchecked' << '-Xlint:deprecation'
}

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

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 +0,0 @@
সহজ মানচিত্র নেভিগেশন - আপনার যাত্রা সম্পর্কে আরও জানুন - সম্প্রদায় কর্তৃক পরিচালিত

View File

@@ -1 +0,0 @@
কোম্যাপস - অফলাইনে হাইকিং, সাইকেলিং এবং ড্রাইভিং করুন গোপনীয়তা সহ

View File

@@ -1 +0,0 @@
Navegació intuïtiva - Descobreix el teu camí - El poder de la comunitat

View File

@@ -1,7 +0,0 @@
• Data OpenStreetMap k 4. 8.
• vylepšené barvy mapy pro vodu, lesy, křoviny, různé vybavení, pěší zóny atd.
• přidány stanice lesní stráže, krytých parkovišť pro jízdní kola, únikových her, úschoven zavazadel, partnerských pošt
• vylepšeny výškové vrstevnice na 20 m pro některé oblíbené turistické oblasti
• podpora více zkratek a aliasů pro vyhledávání
• přidání ikon pro vyhledávání a záložky pro rychlé občerstvení, jízdní kola a dobíjecí stanice
• plynulejší pohyb šipky pro určení polohy

View File

@@ -1,7 +1,9 @@
• OpenStreetMap-Daten vom 4. August
• Verbesserte Farben für Wasser, Wälder, Gestrüpp, verschiedene Einrichtungen, Fussgängerbereiche etc.
Besucherstationen, überdachte Fahrradparkplätze, Escaperooms, Gepäckschließfächer, und Postpartner hinzugefügt
Konturhöhenlinien aktualisiert, bis zu 20m für beliebte Wanderregionen
Unterstützung für mehr Such-Abkürzungen und Synonyme
Such- und Lesezeichen-Symbole für Fast Food, Rad- und Lade-Stationen
Der Positionspfeil bewegt sich gleichmässiger
Wir stellen vor: Das neue CoMaps-Logo!
• Verbesserte Höhenlinien in vielen Regionen (Stufen von 20/50 m)
Links zu Panoramax-Bildern für ausgewählte POIs
OpenStreetMap-Daten vom 13. Juli
Neue Farben für viele Objekte und Farben werden früher angezeigt
Öffnungszeiten werden beim Antippen eines POI angezeigt
Verschiedene Arten von Feuchtgebieten
• Neue Farben für Vegetation und andere Features; einige neue Icons
• Wandern: bessere Darstellung der Höhenlinien

View File

@@ -1,7 +1,10 @@
• OpenStreetMap data as of August 4
• improve map colors for water, forests, scrubs, various amenities, pedestrian areas etc.
add ranger stations, covered bicycle parkings, escape games, luggage lockers, post office partners
upgrade altitude contour lines to 20m step for some popular hiking regions
support more search abbreviations and aliases
• add search and bookmark icons for fast food, bicycle and charging stations
more smooth position arrow movements
Introducing CoMaps logo!
upgrade altitude contour lines for many regions to 20 or 50 meters step
add Panoramax Picture links to selected POIs
OpenStreetMap data as of July 13
• add color fills to many features and display fills earlier for existing features
display opening hours state when selecting a POI
• split all wetlands into several distinct types
• update vegetation and other map colors, update some map icons
• outdoors: bolder altitude contour lines

View File

@@ -1,65 +0,0 @@
Una aplicación de mapas gratuita y de código abierto liderada por la comunidad, basada en los datos de OpenStreetMap y reforzada con un compromiso con la transparencia, la privacidad y la ausencia de fines de lucro. CoMaps es un fork o derivado de Organic Maps, que a su vez es un fork de Maps.ME.
<br><br>
Lee más sobre los motivos del proyecto y su dirección en <b><i>codeberg.org/comaps</i></b>.
<br><br>
Únete allí a la comunidad y ayuda a crear la mejor app de mapas
• Usa la aplicación y corre la voz sobre ella
• Envía comentarios y reporta problemas
• Actualiza los datos del mapa en la app o en el sitio web de OpenStreetMap
<br><br>
‣ <b>Enfocada en el uso sin conexión</b>: Planifica y navega tus viajes sin necesidad de conexión móvil, busca puntos de paso en rutas remotas, etc. Todas las funciones están diseñadas para funcionar sin conexión.
‣ <b>Respeta tu Privacidad</b>: La app está diseñada pensando en tu privacidad: no identifica personas, no rastrea y no recoge datos personales. Sin publicidad.
‣ <b>Sencilla y Pulida</b>: funciones esenciales fáciles de usar que simplemente funcionan.
‣ <b>Ahorra Batería y Espacio</b>: No consume la batería como otras apps de navegación. Los mapas compactos ahorran espacio valioso en tu teléfono.
‣ <b>Gratuita y Creada por la Comunidad</b>: Personas como tú ayudaron a construir la app añadiendo lugares a OpenStreetMap, probando funciones, dando opiniones y contribuyendo con desarrollo o financiación.
‣ <b>Toma de decisiones y finanzas abiertas y transparentes, sin ánimo de lucro y completamente de código abierto.</b>
<br><br>
<b>Funciones Principales</b>:
• Mapas detallados descargables con lugares que no aparecen en Google Maps
• Modo exterior con rutas de senderismo destacadas, campings, fuentes de agua, picos, curvas de nivel, etc.
• Caminos peatonales y carriles bici
• Puntos de interés como restaurantes, gasolineras, hoteles, tiendas, lugares turísticos y muchos más
• Búsqueda por nombre, dirección o categoría de punto de interés
• Navegación con indicaciones por voz para caminar, ir en bici o conducir
• Guarda tus lugares favoritos con un solo toque
• Artículos de Wikipedia sin conexión
• Capa de transporte subterráneo y rutas
• Grabación de rutas
• Exporta e importa favoritos y rutas en formatos KML, KMZ y GPX
• Modo oscuro para usar de noche
• Mejora los datos del mapa para todos usando un editor básico integrado
<br><br>
<b>La Libertad Está Aquí</b>
Descubre tu camino, navega el mundo con privacidad y con la comunidad como prioridad.

View File

@@ -1,7 +1,9 @@
• Datos de OpenStreetMap a fecha 2025.08.04
Mejora de colores del mapa para agua, bosques, matorrales, servicios, zonas peatonales, etc.
Añadidas estaciones de guardabosques, aparcamientos cubiertos de bicis, juegos de escape, consignas y oficinas de correo
Nuevas curvas de nivel (20 m) en regiones populares para senderismo
Más abreviaturas y alias de búsqueda
Iconos de búsqueda y marcadores para comida rápida, bicicletas y estaciones de recarga
Más fluidez de la flecha de posición
¡Presentamos el logo de CoMaps!
mejora de isolíneas con más detalle para muchas regiones
añade enlaces de imágenes de Panoramax a POIs seleccionados
datos de OpenStreetMap a 13 de julio
añadidos rellenos de color a muchas características
se muestra el estado de horarios de apertura al seleccionar un POI
se dividen los humedales en tipos distintos
• se actualiza la vegetación y otros colores del mapa, así como otros iconos
• exteriores: líneas de contorno de altitud más gruesas

View File

@@ -1 +0,0 @@
Navegación de mapa fácil - Descubre más en tu camino - Creado por la comunidad

View File

@@ -1 +0,0 @@
CoMaps - Senderismo, ciclismo y conducción offline

View File

@@ -1 +0,0 @@
ناوبری آسان نقشه - کشف بیشتر از سفر شما - توسط جامعه

View File

@@ -1 +0,0 @@
CoMaps - کوه نوردی، دوچرخه سواری و رانندگی افلاین و خصوصی

View File

@@ -0,0 +1,7 @@
Présentation du logo CoMaps !
• Amélioration des courbes daltitude à une précision de 20 ou 50 mètres pour de nombreuses régions
• Ajout d'un lien vers les images Panoramax des POI
• Données OpenStreetMap du 13 juillet
• Affichage de létat des heures douverture lors de la sélection dun POI
• Mise à jour du style(végétation et zones humides), mise à jour de certaines icônes de la carte
• Outdoors: Améliorations de la visibilité des courbes d'altitude

View File

@@ -1 +1 @@
Navigation de cartes facile - Découvrez le monde - Propulsé par la communauté
Navigation cartographique facile - Découvrez davantage de votre voyage - Propulsé par la communauté

View File

@@ -1 +0,0 @@
Könnyű térképes navigáció - Fedezz fel többet az útjaidról - A közösség erejével

View File

@@ -1 +0,0 @@
Navigation facile del mappa Discoperi tu viage Alimentate per le communitate

View File

@@ -1,7 +0,0 @@
• Dati di OpenStreetMap aggiornati al 4 Agosto
• Migliorati i colori per acqua, foreste, servizi etc
• Aggiunte le stazioni delle guardie forestali, i parcheggi coperti per bici, gli escape games e altri servizi
• Aggiornato l'intervallo delle isolinee a 20 m per le zone escursionistiche più popolari
• Aggiunto il supporto per un maggior numero di alias
• Aggiunte le icone per i fast food, i punti di ricarica e le biciclette
• Resi più fluidi i movimenti della freccia di posizione

View File

@@ -0,0 +1,9 @@
Wprowadzamy logo CoMaps!
• zwiększenie dokładności izolinii w wielu regionach w krokach 20 do 50 metrów
• dodanie linków do zdjęć z Panoramax do wybranych POI
• aktualizacja danych OpenStreetMap z 13 lipca
• dodanie wypełnienia kolorem dla wielu typów obiektów
• wyświetlanie stanu godzin otwarcia przy wyborze POI
• podział mokradeł na kilka typów
• aktualizacja koloru roślinności i innych kolorów, aktualizacja części ikon na mapie
• tryb outdoorowy: pogrubione warstwice wysokości

View File

@@ -1,7 +1,9 @@
• Dados OSM de 4/08
Melhoria nas cores para água, florestas, matagais, serviços, áreas de pedestres, etc.
• Adição de guarda-florestais, estacionamentos cobertos para bicicletas, jogos de fuga, armários para bagagem e parceiros postais
Melhoria na precisão de curvas de nível para 20 m em algumas regiões populares
Suporte a mais abreviações para busca
Adição de ícones de pesquisa e favoritos para fast food, bicicletas e estações de recarga
Movimentos mais suaves para seta de posição
Apresentamos o logo do CoMaps!
Curvas de nível mais detalhadas em muitas regiões
• Adicionados links de imagens do Panoramax para pontos de interesse selecionados
Dados OSM de 13/07
Adicionados preenchimentos de cor a muitos elementos
Exibição de horário de funcionamento ao selecionar um ponto de interesse
Divididas áreas úmidas em vários tipos distintos
• Atualizada cores/ícones para vegetação e outros elementos
• Ar livre: curvas de nível de altitude mais destacadas

View File

@@ -1 +1 @@
CoMaps - Mapas e Navegação Offline com Privacidade
CoMaps - Mapas com Privacidade

View File

@@ -1 +0,0 @@
Navegação fácil nos mapas - Descubra mais sobre o seu percurso - Feito por todos

View File

@@ -1 +0,0 @@
CoMaps - Mapas e Navegação - Offline e Privada

View File

@@ -1,7 +1,9 @@
• Карты OpenStreetMap от 4 августа
Улучшен цвет воды, леса, кустарников, различных объектов инфраструктуры, пешеходных зон и т.д.
Добавлены лесничества, крытые велопарковки, квесты, камеры хранения
Для некоторых популярных туристических регионов добавлены линии высот 20м
Поддержка дополнительных поисковых сокращений и синонимов
Добавлены иконки меток и результатов поиска для фастфуда, велопарковок и зарядных станций
Более плавное движение стрелки местоположения
Представляем логотип CoMaps!
Линии высот для многих регионов с шагом 20м или 50м
Ссылки на изображения Panoramax к выбранным POI
Карты OpenStreetMap от 13 июля
Заливки цветом ко многим объектам и более ранняя заливка для существующих объектов
Показ часов работы при выборе POI
Разные водно-болотные угодья отличаются цветом
• Обновлены цвета растительности и другие цвета на карте, изменены некоторые иконки
В стиле "Активный отдых" более четкие линии высот

View File

@@ -1,7 +1,9 @@
• подаци из OpenStreetMap-а од 4. августа
побољшане боје на мапи за воду, шуме, жбуње, разне објекте, пешачке зоне итд.
• додате станице ренџера, наткривена паркинг места за бицикле, escape room-ови, ормарићи за пртљаг
унапређене изохипсе на кораке од 20 м за популарне планинарске регионе
подршка за више скраћеница и алтернативних назива у претрази
додате иконе за претрагу и обележавање за брзу храну, бицикле и станице за пуњење
равномерније кретање стрелице која приказује позицију
Представљамо CoMaps лого!
ажуриране изохипсе за многе регионе на кораке од 20 или 50 метара
• додате везе ка Panoramax сликама за изабране тачке интересовања (POI)
подаци са OpenStreetMap-а од 13. јула
додате боје за многе елементе и раније приказивање постојећих површина
приказ стања радног времена при избору POI-ја
мочваре подељене на неколико различитих типова
• ажуриране боје вегетације и других елемената на мапи, ажуриране поједине иконе
• на отвореном: наглашеније изохипсе

View File

@@ -8,10 +8,10 @@ import android.app.PendingIntent;
import android.content.Context;
import android.location.Location;
import android.os.Looper;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresPermission;
import app.organicmaps.sdk.util.LocationUtils;
import app.organicmaps.sdk.util.log.Logger;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.common.api.ResolvableApiException;
import com.google.android.gms.location.FusedLocationProviderClient;
@@ -26,6 +26,9 @@ import com.google.android.gms.location.LocationSettingsStatusCodes;
import com.google.android.gms.location.Priority;
import com.google.android.gms.location.SettingsClient;
import app.organicmaps.sdk.util.LocationUtils;
import app.organicmaps.sdk.util.log.Logger;
class GoogleFusedLocationProvider extends BaseLocationProvider
{
private static final String TAG = GoogleFusedLocationProvider.class.getSimpleName();
@@ -69,75 +72,71 @@ class GoogleFusedLocationProvider extends BaseLocationProvider
{
Logger.d(TAG);
final LocationRequest locationRequest =
new LocationRequest
.Builder(Priority.PRIORITY_HIGH_ACCURACY, interval)
// Wait a few seconds for accurate locations initially, when accurate locations could not be computed on the
// device immediately. https://github.com/organicmaps/organicmaps/issues/2149
.setWaitForAccurateLocation(true)
// The desired location granularity should correspond to the client permission level. The client will be
// delivered fine locations while it has the Manifest.permission.ACCESS_FINE_LOCATION permission, coarse
// locations while it has only the Manifest.permission.ACCESS_COARSE_LOCATION permission, and no location
// if it lacks either.
.setGranularity(Granularity.GRANULARITY_PERMISSION_LEVEL)
// Sets the maximum age of an initial historical location delivered for this request.
.setMaxUpdateAgeMillis(60 * 60 * 1000L) // 1 hour
.build();
final LocationRequest locationRequest = new LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, interval)
// Wait a few seconds for accurate locations initially, when accurate locations could not be computed on the device immediately.
// https://github.com/organicmaps/organicmaps/issues/2149
.setWaitForAccurateLocation(true)
// The desired location granularity should correspond to the client permission level. The client will be
// delivered fine locations while it has the Manifest.permission.ACCESS_FINE_LOCATION permission, coarse
// locations while it has only the Manifest.permission.ACCESS_COARSE_LOCATION permission, and no location
// if it lacks either.
.setGranularity(Granularity.GRANULARITY_PERMISSION_LEVEL)
// Sets the maximum age of an initial historical location delivered for this request.
.setMaxUpdateAgeMillis(60 * 60 * 1000L) // 1 hour
.build();
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
builder.addLocationRequest(locationRequest);
builder.setAlwaysShow(true); // improves the wording/appearance of the dialog
final LocationSettingsRequest locationSettingsRequest = builder.build();
mSettingsClient.checkLocationSettings(locationSettingsRequest)
.addOnSuccessListener(locationSettingsResponse -> {
Logger.d(TAG, "Service is available");
mFusedLocationClient.requestLocationUpdates(locationRequest, mCallback, Looper.myLooper());
})
.addOnFailureListener(e -> {
try
mSettingsClient.checkLocationSettings(locationSettingsRequest).addOnSuccessListener(locationSettingsResponse -> {
Logger.d(TAG, "Service is available");
mFusedLocationClient.requestLocationUpdates(locationRequest, mCallback, Looper.myLooper());
}).addOnFailureListener(e -> {
try
{
int statusCode = ((ApiException) e).getStatusCode();
if (statusCode == LocationSettingsStatusCodes.RESOLUTION_REQUIRED)
{
// This case happens if at least one of the following system settings is off:
// 1. Location Services a.k.a GPS;
// 2. Google Location Accuracy a.k.a High Accuracy;
// 3. Both Wi-Fi && Mobile Data together (needed for 2).
//
// PendingIntent below will show a special Google "For better experience... enable (1) and/or (2) and/or (3)"
// dialog. This system dialog can change system settings if "Yes" is pressed. We can't do it from our app.
// However, we don't want to annoy a user who disabled (2) or (3) intentionally. GPS (1) is mandatory to
// continue, while (2) and (3) are not dealbreakers here.
//
// See https://github.com/organicmaps/organicmaps/issues/3846
//
if (LocationUtils.areLocationServicesTurnedOn(mContext))
{
int statusCode = ((ApiException) e).getStatusCode();
if (statusCode == LocationSettingsStatusCodes.RESOLUTION_REQUIRED)
{
// This case happens if at least one of the following system settings is off:
// 1. Location Services a.k.a GPS;
// 2. Google Location Accuracy a.k.a High Accuracy;
// 3. Both Wi-Fi && Mobile Data together (needed for 2).
//
// PendingIntent below will show a special Google "For better experience... enable (1) and/or (2) and/or
// (3)" dialog. This system dialog can change system settings if "Yes" is pressed. We can't do it from our
// app. However, we don't want to annoy a user who disabled (2) or (3) intentionally. GPS (1) is mandatory
// to continue, while (2) and (3) are not dealbreakers here.
//
// See https://github.com/organicmaps/organicmaps/issues/3846
//
if (LocationUtils.areLocationServicesTurnedOn(mContext))
{
Logger.d(TAG, "Don't show 'location resolution' dialog because location services are already on");
mFusedLocationClient.requestLocationUpdates(locationRequest, mCallback, Looper.myLooper());
return;
}
Logger.d(TAG, "Requesting 'location resolution' dialog");
final ResolvableApiException resolvable = (ResolvableApiException) e;
final PendingIntent pendingIntent = resolvable.getResolution();
// Call this callback in the next event loop to allow LocationHelper::start() to finish.
runLater(() -> mListener.onLocationResolutionRequired(pendingIntent));
return;
}
Logger.d(TAG, "Don't show 'location resolution' dialog because location services are already on");
mFusedLocationClient.requestLocationUpdates(locationRequest, mCallback, Looper.myLooper());
return;
}
catch (ClassCastException ex)
{
// Ignore, should be an impossible error.
// https://developers.google.com/android/reference/com/google/android/gms/location/SettingsClient
Logger.e(TAG, "An error that should be impossible: " + ex);
}
// Location settings are not satisfied. However, we have no way to fix the
// settings so we won't show the dialog.
Logger.e(TAG, "Service is not available: " + e);
Logger.d(TAG, "Requesting 'location resolution' dialog");
final ResolvableApiException resolvable = (ResolvableApiException) e;
final PendingIntent pendingIntent = resolvable.getResolution();
// Call this callback in the next event loop to allow LocationHelper::start() to finish.
runLater(mListener::onFusedLocationUnsupported);
});
runLater(() -> mListener.onLocationResolutionRequired(pendingIntent));
return;
}
}
catch (ClassCastException ex)
{
// Ignore, should be an impossible error.
// https://developers.google.com/android/reference/com/google/android/gms/location/SettingsClient
Logger.e(TAG, "An error that should be impossible: " + ex);
}
// Location settings are not satisfied. However, we have no way to fix the
// settings so we won't show the dialog.
Logger.e(TAG, "Service is not available: " + e);
// Call this callback in the next event loop to allow LocationHelper::start() to finish.
runLater(mListener::onFusedLocationUnsupported);
});
}
@Override

View File

@@ -1,12 +1,14 @@
package app.organicmaps.sdk.location;
import android.content.Context;
import androidx.annotation.NonNull;
import app.organicmaps.sdk.util.Config;
import app.organicmaps.sdk.util.log.Logger;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import app.organicmaps.sdk.util.Config;
import app.organicmaps.sdk.util.log.Logger;
public class LocationProviderFactory
{
private static final String TAG = LocationProviderFactory.class.getSimpleName();
@@ -16,8 +18,7 @@ public class LocationProviderFactory
return GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context) == ConnectionResult.SUCCESS;
}
public static BaseLocationProvider getProvider(@NonNull Context context,
@NonNull BaseLocationProvider.Listener listener)
public static BaseLocationProvider getProvider(@NonNull Context context, @NonNull BaseLocationProvider.Listener listener)
{
if (isGoogleLocationAvailable(context) && Config.useGoogleServices())
{

View File

@@ -1 +0,0 @@
সহজ মানচিত্র নেভিগেশন - আপনার যাত্রা সম্পর্কে আরও জানুন - সম্প্রদায় কর্তৃক পরিচালিত

View File

@@ -1 +0,0 @@
CoMaps - গোপনীয়তা সহ যাতায়াত

View File

@@ -1,36 +0,0 @@
CoMaps és una aplicació de mapes lliure i de codi obert a càrrec de la comunitat que es basa en les dades OpenStreetMap i es fonamenta en el compromís amb la transparència i la privadesa sense ànim de lucre.
Uneix-te a la comunitat i ajuda a crear la millor aplicació de mapes.
• Fes servir l'aplicació i recomana-la.
• Dona la teva opinió i comunica qualsevol problema.
• Actualitza les dades de mapes a l'aplicació o al web d'OpenStreetMap.
<i>Els teus comentaris i les valoracions de 5 estrelles són el que més ens ajuda.</i>
‣ <b>Disseny senzill i polit</b>: funcions bàsiques i fàcils de fer servir que funcionen i punt.
‣ <b>Centrada en l'ús sense connexió</b>: planifica viatges a l'estranger i navega sense haver d'accedir a les dades mòbils o cerca punts d'interès durant rutes d'excursionisme llargues. Totes les funcions de l'aplicació s'han dissenyat perquè funcionin sense connexió.
‣ <b>Respecte per la privadesa</b>: el disseny de l'aplicació prioritza la privadesa. No t'identifica, no fa cap seguiment i no recull dades personals. A més, no té anuncis.
‣ <b>Ús eficient de la bateria i l'espai</b>: consumeix menys bateria que altres aplicacions de navegació. Els mapes compactes ocupen molt poc espai al telèfon.
‣ <b>Lliure gràcies a la comunitat</b>: aquesta aplicació s'ha desenvolupat gràcies a persones com tu que han afegit llocs a OpenStreetMap, han provat funcions, n'han aportat comentaris i hi han contribuït amb diners i esforç.
‣ <b>És un projecte obert i transparent en les seves decisions i finances. No té cap ànim de lucre i és completament de codi obert.</b>
<b>Funcions principals</b>:
• Mapes detallats que es poden baixar i inclouen llocs que no apareixen a Google Maps
• Mode exterior en què es ressalten les rutes d'excursionisme, els llocs d'acampada, les fonts d'aigua, els pics i les línies de contorn, entre altres coses
• Zones per a vianants i carrils bici
• Punts d'interès, com ara restaurants, benzineres, hotels, botigues, atraccions turístiques i molt més
• Cerques per nom, adreça o categoria de punt d'interès
• Navegació amb indicacions per veu mentre camines, vas amb bicicleta o condueixes
• Adreces d'interès perquè desis els teus llocs preferits amb un toc
• Articles de Wikipedia sense connexió
• Capa de línies de metro amb direccions
• Enregistrament d'itineraris
• Exportació i importació d'adreces d'interès i itineraris en els formats KML, KMZ i GPX
• Mode fosc per fer servir l'aplicació a la nit
• Millora de les dades de mapes per a tothom amb un editor integrat bàsic
• Compatibilitat amb Android Auto
Pots informar de problemes a l'aplicació, suggerir idees i unir-te a la comunitat al web <b><i>comaps.app</i></b>.
<b>La llibertat ha arribat</b>
Descobreix el teu camí i explora el món amb la privadesa i la comunitat com a eix central!

View File

@@ -1 +0,0 @@
Navegació intuïtiva - Descobreix el teu camí - El poder de la comunitat

View File

@@ -1 +0,0 @@
CoMaps Navega amb privadesa

View File

@@ -1,71 +0,0 @@
Una aplicación de mapas gratuita y de código abierto liderada por la comunidad, basada en los datos de OpenStreetMap y reforzada con un compromiso con la transparencia, la privacidad y la ausencia de fines de lucro.
<br><br>
Únete a la comunidad y ayuda a crear la mejor app de mapas
• Usa la aplicación y corre la voz sobre ella
• Envía comentarios y reporta problemas
• Actualiza los datos del mapa en la app o en el sitio web de OpenStreetMap
<br><br>
<i>¡Tus comentarios y valoraciones de 5 estrellas son el mejor apoyo para nosotros!</i>
<br><br>
‣ <b>Sencilla y Pulida</b>: funciones esenciales fáciles de usar que simplemente funcionan.
‣ <b>Enfocada en el uso sin conexión</b>: Planifica y navega tus viajes sin necesidad de conexión móvil, busca puntos de paso en rutas remotas, etc. Todas las funciones están diseñadas para funcionar sin conexión.
‣ <b>Respeta tu Privacidad</b>: La app está diseñada pensando en tu privacidad: no identifica personas, no rastrea y no recoge datos personales. Sin publicidad.
‣ <b>Ahorra Batería y Espacio</b>: No consume la batería como otras apps de navegación. Los mapas compactos ahorran espacio valioso en tu teléfono.
‣ <b>Gratuita y Creada por la Comunidad</b>: Personas como tú ayudaron a construir la app añadiendo lugares a OpenStreetMap, probando funciones, dando opiniones y contribuyendo con desarrollo o financiación.
‣ <b>Toma de decisiones y finanzas abiertas y transparentes, sin ánimo de lucro y completamente de código abierto.</b>
<br><br>
<b>Funciones Principales</b>:
• Mapas detallados descargables con lugares que no aparecen en Google Maps
• Modo exterior con rutas de senderismo destacadas, campings, fuentes de agua, picos, curvas de nivel, etc.
• Caminos peatonales y carriles bici
• Puntos de interés como restaurantes, gasolineras, hoteles, tiendas, lugares turísticos y muchos más
• Búsqueda por nombre, dirección o categoría de punto de interés
• Navegación con indicaciones por voz para caminar, ir en bici o conducir
• Guarda tus lugares favoritos con un solo toque
• Artículos de Wikipedia sin conexión
• Capa de transporte subterráneo y rutas
• Grabación de rutas
• Exporta e importa favoritos y rutas en formatos KML, KMZ y GPX
• Modo oscuro para usar de noche
• Mejora los datos del mapa para todos usando un editor básico integrado
• Compatibilidad con Android Auto
<br><br>
Por favor, informa de errores, sugiere ideas y únete a nuestra comunidad en el sitio web <b><i>comaps.app</i></b>.
<br><br>
<b>La Libertad Está Aquí</b>
Descubre tu camino, navega el mundo con privacidad y con la comunidad como prioridad.

View File

@@ -1 +0,0 @@
Navegación de mapa fácil - Descubre más en tu camino - Creado por la comunidad

View File

@@ -1 +0,0 @@
CoMaps - Navega con Privacidad

View File

@@ -1 +1 @@
Navigation cartographique facile - Vivez de grands voyages - Propulsé par la communauté
Navigation cartographique facile - Découvrez davantage de votre voyage - Propulsé par la communauté

View File

@@ -1 +0,0 @@
Könnyű térképes navigáció - Fedezz fel többet az útjaidról - A közösség erejével

View File

@@ -1 +0,0 @@
CoMaps - Az adatvédő navigáció

View File

@@ -1 +0,0 @@
Navigation facile del mappa Discoperi tu viage Alimentate per le communitate

View File

@@ -1 +0,0 @@
CoMaps Naviga private

View File

@@ -1 +0,0 @@
കോമാപ്പ്സ് - സ്വകാര്യതയോടെ സഞ്ചരിക്കൂ

View File

@@ -1 +0,0 @@
CoMaps - Nawigacja szanująca prywatność

View File

@@ -1 +1 @@
CoMaps - Navegue Privadamente
CoMaps - Navegue privadamente

View File

@@ -1 +1 @@
CoMaps - Приватная навигация
CoMaps - Оффлайн навигация

View File

@@ -7,12 +7,12 @@ Topluluğa katılın ve en iyi harita uygulamasını oluşturmamıza yardım edi
<i>Geri bildirimleriniz ve 5 yıldızlı yorumlarınız bizim için en iyi destektir!</i>
‣ <b>Basit ve Temiz</b>: Sadece temel, kullanımı basit ve işe yarayan özellikler.
‣ <b>Çevrimdışı Odaklı</b>: Mobil veriye ihtiyaç duymadan yurt dışı seyahatinizi planlayın ve gezin, uzun bir yürüyüş sırasında rotanızdaki noktaları bulun ve daha fazlası. Tüm özellikler çevrimdışı çalışmak üzere tasarlanmıştır.
‣ <b>Basit ve Temiz</b>: Sadece temel, kullanımı basit, işe yarayan özellikler.
‣ <b>Çevrimdışı Odaklı</b>: Mobil veriye ihtiyaç duymadan yurt dışı seyahatinizi planlayın ve gezin, uzun bir yürüyüş sırasında rotanızdaki noktaları bulun ve daha fazlası . Tüm özellikler çevrimdışı çalışmak üzere tasarlanmıştır.
‣ <b>Gizliliğe Saygılı</b>: Uygulama gizliliğe saygılı olarak tasarlanmıştır. Kullanıcı profilinizi çıkarmaz, sizi takip etmez ve kişisel bilgi toplamaz. Üstelik tamamen reklamsızdır.
‣ <b>Pil ve Depolamanızdan Tasarruf Eder</b>: Diğer navigasyon uygulamaları gibi pilinizi sömürmez. Kompakt harita dosyaları, değerli depolama alanınızdan tasarruf eder.
‣ <b>Ücretsizdir ve Gücünü Topluluktan Alır</b>: Sizin gibi insanlar OpenStreetMap'e yer ekleyerek, yeni özellikleri test ederek, geri bildirimde bulunarak, program geliştirme becerileri ve bağışlarla katkıda bulunarak bu uygulamanın oluşturulmasına yardımcı oldular.
‣ <b>Açık ve Şeffaf Bir Şekilde Yürütülen Karar Alma ve Fonlama Süreçlerine Sahip, Kâr Amacı Gütmeyen ve Tamamen Açık Kaynaklı Bir Uygulama.</b>
‣ <b>Pil ve Depolamanızdan Tasarruf Eder</b>: Diğer navigasyon uygulamaları gibi pilinizi sömürmez. Compact maps değerli depolama alanınızdan tasarruf eder.
‣ <b>Ücretsizdir ve Gücünü Topluluktan Alır</b>: Sizin gibi insanlar OpenStreetMap'e yer ekleyerek, yeni özellikleri test ederek, geri bildirimde bulunarak, program geliştirme becerileri ve bağışlarla katkıda bulunarak uygulamanın oluşturulmasına yardımcı oldu.
‣ <b>Açık ve Şeffaf Şekilde Yürütülen Karar Alma ve Fonlama Süreçleri, Kâr Amacı Gütmez ve Tamamen Açık Kaynaklı.</b>
<b>Ana Özellikler</b>:
• Google Haritalar'da bulunmayan yerleri içeren, çevrimdışı detaylı haritalar

View File

@@ -6,7 +6,7 @@
<!-- Requiring "android.hardware.touchscreen" here breaks DeX mode -->
<uses-feature
android:glEsVersion="0x00030000"
android:glEsVersion="0x00020000"
android:required="true"/>
<uses-feature
android:name="android.hardware.wifi"
@@ -75,7 +75,6 @@
android:backupInForeground="true"
android:fullBackupContent="@xml/backup_content"
android:dataExtractionRules="@xml/backup_content_v31"
android:enableOnBackInvokedCallback="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:localeConfig="@xml/locales_config"
@@ -377,7 +376,6 @@
<activity
android:name="app.organicmaps.downloader.DownloaderActivity"
android:enableOnBackInvokedCallback="true"
android:configChanges="orientation|screenLayout|screenSize"
android:screenOrientation="fullUser"
android:label="@string/download_maps"

View File

@@ -43,10 +43,6 @@ set(SRC
app/organicmaps/sdk/core/jni_java_methods.cpp
app/organicmaps/sdk/core/logging.cpp
app/organicmaps/sdk/bookmarks/data/BookmarkManager.cpp
app/organicmaps/sdk/bookmarks/data/Icon.cpp
app/organicmaps/sdk/bookmarks/data/Icon.hpp
app/organicmaps/sdk/bookmarks/data/PredefinedColors.cpp
app/organicmaps/sdk/bookmarks/data/PredefinedColors.hpp
app/organicmaps/sdk/DownloadResourcesLegacyActivity.cpp
app/organicmaps/sdk/editor/Editor.cpp
app/organicmaps/sdk/editor/OpeningHours.cpp

View File

@@ -0,0 +1,186 @@
#include "Framework.hpp"
#include "defines.hpp"
#include "storage/downloader.hpp"
#include "storage/storage.hpp"
#include "platform/downloader_defines.hpp"
#include "platform/http_request.hpp"
#include "platform/platform.hpp"
#include "coding/internal/file_data.hpp"
#include "coding/reader_streambuf.hpp"
#include "base/file_name_utils.hpp"
#include "base/logging.hpp"
#include "base/string_utils.hpp"
#include "app/organicmaps/sdk/core/jni_helper.hpp"
#include <functional>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
using namespace downloader;
using namespace storage;
using namespace std::placeholders;
/// Special error codes to notify GUI about free space
//@{
#define ERR_DOWNLOAD_SUCCESS 0
#define ERR_DISK_ERROR -1
#define ERR_NOT_ENOUGH_FREE_SPACE -2
#define ERR_STORAGE_DISCONNECTED -3
#define ERR_DOWNLOAD_ERROR -4
#define ERR_NO_MORE_FILES -5
#define ERR_FILE_IN_PROGRESS -6
//@}
namespace
{
static std::vector<platform::CountryFile> g_filesToDownload;
static int g_totalDownloadedBytes;
static int g_totalBytesToDownload;
static std::shared_ptr<HttpRequest> g_currentRequest;
} // namespace
extern "C"
{
using Callback = HttpRequest::Callback;
static int HasSpaceForFiles(Platform & pl, std::string const & sdcardPath, size_t fileSize)
{
switch (pl.GetWritableStorageStatus(fileSize))
{
case Platform::STORAGE_DISCONNECTED:
return ERR_STORAGE_DISCONNECTED;
case Platform::NOT_ENOUGH_SPACE:
return ERR_NOT_ENOUGH_FREE_SPACE;
default:
return static_cast<int>(fileSize);
}
}
JNIEXPORT jint JNICALL
Java_app_organicmaps_sdk_DownloadResourcesLegacyActivity_nativeGetBytesToDownload(JNIEnv * env, jclass clazz)
{
// clear all
g_filesToDownload.clear();
g_totalBytesToDownload = 0;
g_totalDownloadedBytes = 0;
using namespace storage;
Storage const & storage = g_framework->GetStorage();
auto const status = storage.GetForceDownloadWorlds(g_filesToDownload);
for (auto const & cf : g_filesToDownload)
g_totalBytesToDownload += cf.GetRemoteSize();
int res;
if (status == Storage::WorldStatus::ERROR_CREATE_FOLDER ||
status == Storage::WorldStatus::ERROR_MOVE_FILE)
{
res = ERR_DISK_ERROR;
}
else
{
Platform & pl = GetPlatform();
res = HasSpaceForFiles(pl, pl.WritableDir(), g_totalBytesToDownload);
}
if (res == ERR_STORAGE_DISCONNECTED)
LOG(LWARNING, ("External file system is not available"));
else if (res == ERR_NOT_ENOUGH_FREE_SPACE)
LOG(LWARNING, ("Not enough space to extract files"));
g_currentRequest.reset();
if (status == Storage::WorldStatus::WAS_MOVED)
{
g_framework->ReloadWorldMaps();
res = ERR_DOWNLOAD_SUCCESS; // reset possible storage error if we moved files
}
return res;
}
static void DownloadFileFinished(std::shared_ptr<jobject> obj, HttpRequest const & req)
{
auto const status = req.GetStatus();
ASSERT_NOT_EQUAL(status, DownloadStatus::InProgress, ());
int errorCode = ERR_DOWNLOAD_ERROR;
if (status == DownloadStatus::Completed)
errorCode = ERR_DOWNLOAD_SUCCESS;
g_currentRequest.reset();
if (errorCode == ERR_DOWNLOAD_SUCCESS)
{
auto const & curFile = g_filesToDownload.back();
size_t const sz = curFile.GetRemoteSize();
LOG(LDEBUG, ("finished downloading", curFile.GetName(), "size", sz, "bytes"));
g_totalDownloadedBytes += sz;
LOG(LDEBUG, ("totalDownloadedBytes:", g_totalDownloadedBytes));
g_filesToDownload.pop_back();
}
JNIEnv * env = jni::GetEnv();
jmethodID methodID = jni::GetMethodID(env, *obj, "onFinish", "(I)V");
env->CallVoidMethod(*obj, methodID, errorCode);
}
static void DownloadFileProgress(std::shared_ptr<jobject> listener, HttpRequest const & req)
{
JNIEnv * env = jni::GetEnv();
static jmethodID methodID = jni::GetMethodID(env, *listener, "onProgress", "(I)V");
env->CallVoidMethod(*listener, methodID, static_cast<jint>(g_totalDownloadedBytes + req.GetProgress().m_bytesDownloaded));
}
JNIEXPORT jint JNICALL
Java_app_organicmaps_sdk_DownloadResourcesLegacyActivity_nativeStartNextFileDownload(JNIEnv * env, jclass clazz, jobject listener)
{
if (g_filesToDownload.empty())
return ERR_NO_MORE_FILES;
/// @todo One downloader instance with cached servers. All this routine will be refactored some time.
static auto downloader = storage::GetDownloader();
storage::Storage const & storage = g_framework->GetStorage();
downloader->SetDataVersion(storage.GetCurrentDataVersion());
downloader->EnsureMetaConfigReady([&storage, ptr = jni::make_global_ref(listener)]()
{
auto const & curFile = g_filesToDownload.back();
auto const fileName = curFile.GetFileName(MapFileType::Map);
LOG(LINFO, ("Downloading file", fileName));
g_currentRequest.reset(HttpRequest::GetFile(
downloader->MakeUrlListLegacy(fileName),
storage.GetFilePath(curFile.GetName(), MapFileType::Map),
curFile.GetRemoteSize(),
std::bind(&DownloadFileFinished, ptr, _1),
std::bind(&DownloadFileProgress, ptr, _1),
0, false));
});
return ERR_FILE_IN_PROGRESS;
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_DownloadResourcesLegacyActivity_nativeCancelCurrentFile(JNIEnv * env, jclass clazz)
{
LOG(LDEBUG, ("cancelCurrentFile, currentRequest=", g_currentRequest));
g_currentRequest.reset();
}
}

View File

@@ -0,0 +1,222 @@
#pragma once
#include <jni.h>
#include "map/framework.hpp"
#include "map/place_page_info.hpp"
#include "map/power_management/power_manager.hpp"
#include "search/result.hpp"
#include "drape_frontend/gui/skin.hpp"
#include "drape/pointers.hpp"
#include "drape/graphics_context_factory.hpp"
#include "indexer/feature_decl.hpp"
#include "indexer/map_style.hpp"
#include "platform/country_defines.hpp"
#include "platform/location.hpp"
#include "geometry/avg_vector.hpp"
#include "base/timer.hpp"
#include <cstdint>
#include <map>
#include <memory>
#include <mutex>
class DataSource;
struct FeatureID;
namespace search
{
struct EverywhereSearchParams;
}
namespace android
{
enum CoordinatesFormat // See Java enum app.organicmaps.widget.placepage.CoordinatesFormat for all possible values.
{
LatLonDMS = 0, // Latitude, Longitude in degrees minutes seconds format, comma separated
LatLonDecimal = 1, // Latitude, Longitude in decimal format, comma separated
OLCFull = 2, // Open location code, full format
OSMLink = 3, // Link to the OSM. E.g. https://osm.org/go/xcXjyqQlq-?m=
UTM = 4, // Universal Transverse Mercator
MGRS = 5 // Military Grid Reference System
};
// Keep in sync `public @interface ChoosePositionMode`in Framework.java.
enum class ChoosePositionMode
{
None = 0,
Editor = 1,
Api = 2,
};
class Framework : private power_management::PowerManager::Subscriber
{
private:
drape_ptr<dp::ThreadSafeFactory> m_oglContextFactory;
drape_ptr<dp::GraphicsContextFactory> m_vulkanContextFactory;
::Framework m_work;
math::LowPassVector<float, 3> m_sensors[2];
double m_lastCompass = 0;
std::string m_searchQuery;
std::map<gui::EWidget, gui::Position> m_guiPositions;
void TrafficStateChanged(TrafficManager::TrafficState state);
void TransitSchemeStateChanged(TransitReadManager::TransitSchemeState state);
void IsolinesSchemeStateChanged(IsolinesManager::IsolinesState state);
void MyPositionModeChanged(location::EMyPositionMode mode, bool routingActive);
location::TMyPositionModeChanged m_myPositionModeSignal;
TrafficManager::TrafficStateChangedFn m_onTrafficStateChangedFn;
TransitReadManager::TransitStateChangedFn m_onTransitStateChangedFn;
IsolinesManager::IsolinesStateChangedFn m_onIsolinesStateChangedFn;
ChoosePositionMode m_isChoosePositionMode = ChoosePositionMode::None;
bool m_isSurfaceDestroyed = false;
public:
Framework(std::function<void()> && afterMapsLoaded);
storage::Storage & GetStorage();
DataSource const & GetDataSource();
void ShowNode(storage::CountryId const & countryId, bool zoomToDownloadButton);
void OnLocationError(int/* == location::TLocationStatus*/ newStatus);
void OnLocationUpdated(location::GpsInfo const & info);
void OnCompassUpdated(location::CompassInfo const & info, bool forceRedraw);
bool CreateDrapeEngine(JNIEnv * env, jobject jSurface, int densityDpi, bool firstLaunch,
bool launchByDeepLink, uint32_t appVersionCode, bool isCustomROM);
bool IsDrapeEngineCreated() const;
void UpdateDpi(int dpi);
bool DestroySurfaceOnDetach();
void DetachSurface(bool destroySurface);
bool AttachSurface(JNIEnv * env, jobject jSurface);
void PauseSurfaceRendering();
void ResumeSurfaceRendering();
void SetMapStyle(MapStyle mapStyle);
void MarkMapStyle(MapStyle mapStyle);
MapStyle GetMapStyle() const;
void SetupMeasurementSystem();
RoutingManager & GetRoutingManager() { return m_work.GetRoutingManager(); }
void SetRouter(routing::RouterType type) { m_work.GetRoutingManager().SetRouter(type); }
routing::RouterType GetRouter() const { return m_work.GetRoutingManager().GetRouter(); }
routing::RouterType GetLastUsedRouter() const
{
return m_work.GetRoutingManager().GetLastUsedRouter();
}
void Resize(JNIEnv * env, jobject jSurface, int w, int h);
struct Finger
{
Finger(int64_t id, float x, float y)
: m_id(id)
, m_x(x)
, m_y(y)
{
}
int64_t m_id;
float m_x, m_y;
};
void Scale(double factor, m2::PointD const & pxPoint, bool isAnim);
void Scroll(double distanceX, double distanceY);
void Touch(int action, Finger const & f1, Finger const & f2, uint8_t maskedPointer);
bool Search(search::EverywhereSearchParams const & params);
std::string GetLastSearchQuery() { return m_searchQuery; }
void ClearLastSearchQuery() { m_searchQuery.clear(); }
void AddLocalMaps();
void RemoveLocalMaps();
void ReloadWorldMaps();
m2::PointD GetViewportCenter() const;
void AddString(std::string const & name, std::string const & value);
void Scale(::Framework::EScaleMode mode);
void Scale(m2::PointD const & centerPt, int targetZoom, bool animate);
void ChangeTrackColor(kml::TrackId trackId, dp::Color color);
void ReplaceBookmark(kml::MarkId markId, kml::BookmarkData & bm);
void ReplaceTrack(kml::TrackId trackId, kml::TrackData & trackData);
void MoveBookmark(kml::MarkId markId, kml::MarkGroupId curCat, kml::MarkGroupId newCat);
void MoveTrack(kml::TrackId trackId, kml::MarkGroupId curCat, kml::MarkGroupId newCat);
::Framework * NativeFramework();
bool IsDownloadingActive();
void ExecuteMapApiRequest();
void DeactivatePopup();
void DeactivateMapSelectionCircle();
// std::string GetOutdatedCountriesString();
void SetMyPositionModeListener(location::TMyPositionModeChanged const & fn);
location::EMyPositionMode GetMyPositionMode() const;
void SwitchMyPositionNextMode();
void SetTrafficStateListener(TrafficManager::TrafficStateChangedFn const & fn);
void SetTransitSchemeListener(TransitReadManager::TransitStateChangedFn const & fn);
void SetIsolinesListener(IsolinesManager::IsolinesStateChangedFn const & fn);
bool IsTrafficEnabled();
void EnableTraffic();
void DisableTraffic();
void Save3dMode(bool allow3d, bool allow3dBuildings);
void Set3dMode(bool allow3d, bool allow3dBuildings);
void Get3dMode(bool & allow3d, bool & allow3dBuildings);
void SetMapLanguageCode(std::string const & languageCode);
std::string GetMapLanguageCode();
void SetChoosePositionMode(ChoosePositionMode mode, bool isBusiness, m2::PointD const * optionalPosition);
ChoosePositionMode GetChoosePositionMode();
void UpdateMyPositionRoutingOffset(int offsetY);
void SetupWidget(gui::EWidget widget, float x, float y, dp::Anchor anchor);
void ApplyWidgets();
void CleanWidgets();
place_page::Info & GetPlacePageInfo();
bool IsAutoRetryDownloadFailed();
bool IsDownloadOn3gEnabled();
void EnableDownloadOn3g();
// int ToDoAfterUpdate() const;
// PowerManager::Subscriber overrides:
void OnPowerFacilityChanged(power_management::Facility const facility, bool enabled) override;
void OnPowerSchemeChanged(power_management::Scheme const actualScheme) override;
FeatureID BuildFeatureId(JNIEnv * env, jobject featureId);
};
}
extern std::unique_ptr<android::Framework> g_framework;
::Framework * frm();

View File

@@ -7,23 +7,26 @@
extern "C"
{
static void LocationStateModeChanged(location::EMyPositionMode mode, std::shared_ptr<jobject> const & listener)
static void LocationStateModeChanged(location::EMyPositionMode mode,
std::shared_ptr<jobject> const & listener)
{
JNIEnv * env = jni::GetEnv();
env->CallVoidMethod(*listener, jni::GetMethodID(env, *listener.get(), "onMyPositionModeChanged", "(I)V"),
static_cast<jint>(mode));
env->CallVoidMethod(*listener, jni::GetMethodID(env, *listener.get(),
"onMyPositionModeChanged", "(I)V"), static_cast<jint>(mode));
}
// public static void nativeSwitchToNextMode();
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_location_LocationState_nativeSwitchToNextMode(JNIEnv * env,
jclass clazz)
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_location_LocationState_nativeSwitchToNextMode(JNIEnv * env, jclass clazz)
{
ASSERT(g_framework, ());
g_framework->SwitchMyPositionNextMode();
}
// private static int nativeGetMode();
JNIEXPORT jint JNICALL Java_app_organicmaps_sdk_location_LocationState_nativeGetMode(JNIEnv * env, jclass clazz)
JNIEXPORT jint JNICALL
Java_app_organicmaps_sdk_location_LocationState_nativeGetMode(JNIEnv * env, jclass clazz)
{
// GetMyPositionMode() is initialized only after drape creation.
// https://github.com/organicmaps/organicmaps/issues/1128#issuecomment-1784435190
@@ -32,31 +35,34 @@ JNIEXPORT jint JNICALL Java_app_organicmaps_sdk_location_LocationState_nativeGet
}
// public static void nativeSetListener(ModeChangeListener listener);
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_location_LocationState_nativeSetListener(JNIEnv * env, jclass clazz,
jobject listener)
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_location_LocationState_nativeSetListener(JNIEnv * env, jclass clazz,
jobject listener)
{
ASSERT(g_framework, ());
g_framework->SetMyPositionModeListener(
std::bind(&LocationStateModeChanged, std::placeholders::_1, jni::make_global_ref(listener)));
g_framework->SetMyPositionModeListener(std::bind(&LocationStateModeChanged, std::placeholders::_1,
jni::make_global_ref(listener)));
}
// public static void nativeRemoveListener();
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_location_LocationState_nativeRemoveListener(JNIEnv * env, jclass clazz)
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_location_LocationState_nativeRemoveListener(JNIEnv * env, jclass clazz)
{
ASSERT(g_framework, ());
g_framework->SetMyPositionModeListener(location::TMyPositionModeChanged());
}
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_location_LocationState_nativeOnLocationError(JNIEnv * env, jclass clazz,
int errorCode)
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_location_LocationState_nativeOnLocationError(JNIEnv * env, jclass clazz, int errorCode)
{
ASSERT(g_framework, ());
g_framework->OnLocationError(errorCode);
}
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_location_LocationState_nativeLocationUpdated(
JNIEnv * env, jclass clazz, jlong time, jdouble lat, jdouble lon, jfloat accuracy, jdouble altitude, jfloat speed,
jfloat bearing)
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_location_LocationState_nativeLocationUpdated(JNIEnv * env, jclass clazz, jlong time,
jdouble lat, jdouble lon, jfloat accuracy,
jdouble altitude, jfloat speed, jfloat bearing)
{
ASSERT(g_framework, ());
location::GpsInfo info;
@@ -84,4 +90,4 @@ JNIEXPORT void JNICALL Java_app_organicmaps_sdk_location_LocationState_nativeLoc
g_framework->OnLocationUpdated(info);
GpsTracker::Instance().OnLocationUpdated(info);
}
} // extern "C"
} // extern "C"

View File

@@ -0,0 +1,190 @@
#include "Framework.hpp"
#include "app/organicmaps/sdk/core/jni_helper.hpp"
#include "app/organicmaps/sdk/platform/AndroidPlatform.hpp"
#include "storage/storage_defines.hpp"
#include "base/logging.hpp"
#include "platform/settings.hpp"
namespace
{
void OnRenderingInitializationFinished(std::shared_ptr<jobject> const & listener)
{
JNIEnv * env = jni::GetEnv();
env->CallVoidMethod(*listener, jni::GetMethodID(env, *listener.get(),
"onRenderingInitializationFinished", "()V"));
}
} // namespace
extern "C"
{
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_Map_nativeCreateEngine(JNIEnv * env, jclass,
jobject surface, jint density,
jboolean firstLaunch,
jboolean isLaunchByDeepLink,
jint appVersionCode,
jboolean isCustomROM)
{
return g_framework->CreateDrapeEngine(env, surface, density, firstLaunch, isLaunchByDeepLink,
base::asserted_cast<uint32_t>(appVersionCode), isCustomROM);
}
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_Map_nativeIsEngineCreated(JNIEnv *, jclass)
{
return g_framework->IsDrapeEngineCreated();
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_Map_nativeUpdateEngineDpi(JNIEnv *, jclass, jint dpi)
{
return g_framework->UpdateDpi(dpi);
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_Map_nativeExecuteMapApiRequest(JNIEnv * env, jclass)
{
return g_framework->ExecuteMapApiRequest();
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_Map_nativeSetRenderingInitializationFinishedListener(
JNIEnv *, jclass, jobject listener)
{
if (listener)
{
g_framework->NativeFramework()->SetGraphicsContextInitializationHandler(
std::bind(&OnRenderingInitializationFinished, jni::make_global_ref(listener)));
}
else
{
g_framework->NativeFramework()->SetGraphicsContextInitializationHandler(nullptr);
}
}
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_Map_nativeAttachSurface(JNIEnv * env, jclass, jobject surface)
{
return g_framework->AttachSurface(env, surface);
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_Map_nativeDetachSurface(JNIEnv *, jclass, jboolean destroySurface)
{
g_framework->DetachSurface(destroySurface);
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_Map_nativeSurfaceChanged(JNIEnv * env, jclass, jobject surface, jint w, jint h)
{
g_framework->Resize(env, surface, w, h);
}
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_Map_nativeDestroySurfaceOnDetach(JNIEnv *, jclass)
{
return g_framework->DestroySurfaceOnDetach();
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_Map_nativePauseSurfaceRendering(JNIEnv *, jclass)
{
g_framework->PauseSurfaceRendering();
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_Map_nativeResumeSurfaceRendering(JNIEnv *, jclass)
{
g_framework->ResumeSurfaceRendering();
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_Map_nativeUpdateMyPositionRoutingOffset(JNIEnv * env, jclass clazz, int offsetY)
{
g_framework->UpdateMyPositionRoutingOffset(offsetY);
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_Map_nativeApplyWidgets(JNIEnv *, jclass)
{
g_framework->ApplyWidgets();
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_Map_nativeCleanWidgets(JNIEnv *, jclass)
{
g_framework->CleanWidgets();
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_Map_nativeSetupWidget(
JNIEnv *, jclass, jint widget, jfloat x, jfloat y, jint anchor)
{
g_framework->SetupWidget(static_cast<gui::EWidget>(widget), x, y, static_cast<dp::Anchor>(anchor));
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_Map_nativeCompassUpdated(JNIEnv *, jclass, jdouble north, jboolean forceRedraw)
{
location::CompassInfo info;
info.m_bearing = north;
g_framework->OnCompassUpdated(info, forceRedraw);
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_Map_nativeScalePlus(JNIEnv *, jclass)
{
g_framework->Scale(::Framework::SCALE_MAG);
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_Map_nativeScaleMinus(JNIEnv *, jclass)
{
g_framework->Scale(::Framework::SCALE_MIN);
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_Map_nativeOnScroll(
JNIEnv *, jclass, jdouble distanceX, jdouble distanceY)
{
g_framework->Scroll(distanceX, distanceY);
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_Map_nativeOnScale(
JNIEnv *, jclass, jdouble factor, jdouble focusX, jdouble focusY, jboolean isAnim)
{
g_framework->Scale(factor, {focusX, focusY}, isAnim);
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_Map_nativeOnTouch(JNIEnv *, jclass, jint action,
jint id1, jfloat x1, jfloat y1,
jint id2, jfloat x2, jfloat y2,
jint maskedPointer)
{
g_framework->Touch(action,
android::Framework::Finger(id1, x1, y1),
android::Framework::Finger(id2, x2, y2), maskedPointer);
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_Map_nativeStorageConnected(JNIEnv *, jclass)
{
android::Platform::Instance().OnExternalStorageStatusChanged(true);
g_framework->AddLocalMaps();
}
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_Map_nativeStorageDisconnected(JNIEnv *, jclass)
{
android::Platform::Instance().OnExternalStorageStatusChanged(false);
g_framework->RemoveLocalMaps();
}
} // extern "C"

View File

@@ -21,6 +21,7 @@
#include <unordered_map>
#include <vector>
namespace
{
// The last 5% are left for applying diffs.
@@ -43,10 +44,7 @@ struct TBatchedData
TBatchedData(storage::CountryId const & countryId, storage::NodeStatus const newStatus,
storage::NodeErrorCode const errorCode, bool isLeaf)
: m_countryId(countryId)
, m_newStatus(newStatus)
, m_errorCode(errorCode)
, m_isLeaf(isLeaf)
: m_countryId(countryId), m_newStatus(newStatus), m_errorCode(errorCode), m_isLeaf(isLeaf)
{}
};
@@ -66,11 +64,11 @@ struct CountryItemBuilder
{
jclass m_class;
jmethodID m_ctor;
jfieldID m_Id, m_Name, m_DirectParentId, m_TopmostParentId, m_DirectParentName, m_TopmostParentName, m_Description,
m_Size, m_EnqueuedSize, m_TotalSize, m_ChildCount, m_TotalChildCount, m_Present, m_Progress, m_DownloadedBytes,
m_BytesToDownload, m_Category, m_Status, m_ErrorCode;
jfieldID m_Id, m_Name, m_DirectParentId, m_TopmostParentId, m_DirectParentName, m_TopmostParentName,
m_Description, m_Size, m_EnqueuedSize, m_TotalSize, m_ChildCount, m_TotalChildCount,
m_Present, m_Progress, m_DownloadedBytes, m_BytesToDownload, m_Category, m_Status, m_ErrorCode;
CountryItemBuilder(JNIEnv * env)
CountryItemBuilder(JNIEnv *env)
{
m_class = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/downloader/CountryItem");
m_ctor = jni::GetConstructorID(env, m_class, "(Ljava/lang/String;)V");
@@ -97,7 +95,10 @@ struct CountryItemBuilder
}
DECLARE_BUILDER_INSTANCE(CountryItemBuilder);
jobject Create(JNIEnv * env, jobject id) const { return env->NewObject(m_class, m_ctor, id); }
jobject Create(JNIEnv * env, jobject id) const
{
return env->NewObject(m_class, m_ctor, id);
}
};
static storage::CountryId const GetRootId(JNIEnv * env, jstring root)
@@ -108,54 +109,52 @@ static storage::CountryId const GetRootId(JNIEnv * env, jstring root)
extern "C"
{
// static String nativeGetRoot();
JNIEXPORT jstring JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeGetRoot(JNIEnv * env, jclass clazz)
JNIEXPORT jstring JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeGetRoot(JNIEnv * env, jclass clazz)
{
return jni::ToJavaString(env, GetStorage().GetRootId());
}
// static boolean nativeMoveFile(String oldFile, String newFile);
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeMoveFile(JNIEnv * env, jclass clazz,
jstring oldFile,
jstring newFile)
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeMoveFile(JNIEnv * env, jclass clazz, jstring oldFile, jstring newFile)
{
return base::MoveFileX(jni::ToNativeString(env, oldFile), jni::ToNativeString(env, newFile));
}
// static boolean nativeHasSpaceToDownloadAmount(long bytes);
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeHasSpaceToDownloadAmount(JNIEnv * env,
jclass clazz,
jlong bytes)
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeHasSpaceToDownloadAmount(JNIEnv * env, jclass clazz, jlong bytes)
{
return storage::IsEnoughSpaceForDownload(bytes);
}
// static boolean nativeHasSpaceToDownloadCountry(String root);
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeHasSpaceToDownloadCountry(JNIEnv * env,
jclass clazz,
jstring root)
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeHasSpaceToDownloadCountry(JNIEnv * env, jclass clazz, jstring root)
{
return storage::IsEnoughSpaceForDownload(jni::ToNativeString(env, root), GetStorage());
}
// static boolean nativeHasSpaceToUpdate(String root);
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeHasSpaceToUpdate(JNIEnv * env,
jclass clazz,
jstring root)
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeHasSpaceToUpdate(JNIEnv * env, jclass clazz, jstring root)
{
return IsEnoughSpaceForUpdate(jni::ToNativeString(env, root), GetStorage());
}
// static int nativeGetDownloadedCount();
JNIEXPORT jint JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeGetDownloadedCount(JNIEnv * env,
jclass clazz)
JNIEXPORT jint JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeGetDownloadedCount(JNIEnv * env, jclass clazz)
{
return static_cast<jint>(GetStorage().GetDownloadedFilesCount());
}
// static @Nullable UpdateInfo nativeGetUpdateInfo(@Nullable String root);
JNIEXPORT jobject JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeGetUpdateInfo(JNIEnv * env, jclass clazz,
jstring root)
JNIEXPORT jobject JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeGetUpdateInfo(JNIEnv * env, jclass clazz, jstring root)
{
storage::Storage::UpdateInfo info;
if (!GetStorage().GetUpdateInfo(GetRootId(env, root), info))
@@ -169,8 +168,7 @@ JNIEXPORT jobject JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeG
return env->NewObject(infoClass, ctor, info.m_numberOfMwmFilesToUpdate, info.m_totalDownloadSizeInBytes);
}
static void UpdateItemShort(JNIEnv * env, jobject item, storage::NodeStatus const status,
storage::NodeErrorCode const error)
static void UpdateItemShort(JNIEnv * env, jobject item, storage::NodeStatus const status, storage::NodeErrorCode const error)
{
auto const & ciBuilder = CountryItemBuilder::Instance(env);
@@ -213,8 +211,7 @@ static void UpdateItem(JNIEnv * env, jobject item, storage::NodeAttrs const & at
}
// Description
env->SetObjectField(item, ciBuilder.m_Description,
SLR(env, jni::ToJavaString(env, attrs.m_nodeLocalDescription)).get());
env->SetObjectField(item, ciBuilder.m_Description, SLR(env, jni::ToJavaString(env, attrs.m_nodeLocalDescription)).get());
// Sizes
env->SetLongField(item, ciBuilder.m_Size, attrs.m_localMwmSize);
@@ -270,21 +267,18 @@ static void PutItemsToList(
}
}
// static void nativeListItems(@Nullable String root, double lat, double lon, boolean hasLocation, boolean myMapsMode,
// List<CountryItem> result);
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeListItems(JNIEnv * env, jclass clazz,
jstring parent, jdouble lat,
jdouble lon, jboolean hasLocation,
jboolean myMapsMode,
jobject result)
// static void nativeListItems(@Nullable String root, double lat, double lon, boolean hasLocation, boolean myMapsMode, List<CountryItem> result);
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeListItems(JNIEnv * env, jclass clazz, jstring parent, jdouble lat, jdouble lon, jboolean hasLocation, jboolean myMapsMode, jobject result)
{
if (hasLocation && !myMapsMode)
{
storage::CountriesVec near;
g_framework->NativeFramework()->GetCountryInfoGetter().GetRegionsCountryId(mercator::FromLatLon(lat, lon), near);
PutItemsToList(env, result, near, ItemCategory::NEAR_ME,
[](storage::CountryId const & countryId, storage::NodeAttrs const & attrs) -> bool
{ return !attrs.m_present; });
[](storage::CountryId const & countryId, storage::NodeAttrs const & attrs) -> bool {
return !attrs.m_present;
});
}
storage::CountriesVec downloaded, available;
@@ -297,8 +291,8 @@ JNIEXPORT void JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeList
}
// static void nativeUpdateItem(CountryItem item);
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeGetAttributes(JNIEnv * env, jclass,
jobject item)
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeGetAttributes(JNIEnv * env, jclass, jobject item)
{
auto const & ciBuilder = CountryItemBuilder::Instance(env);
jstring id = static_cast<jstring>(env->GetObjectField(item, ciBuilder.m_Id));
@@ -310,8 +304,8 @@ JNIEXPORT void JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeGetA
}
// static void nativeGetStatus(String root);
JNIEXPORT jint JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeGetStatus(JNIEnv * env, jclass clazz,
jstring root)
JNIEXPORT jint JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeGetStatus(JNIEnv * env, jclass clazz, jstring root)
{
storage::NodeStatuses ns;
GetStorage().GetNodeStatuses(jni::ToNativeString(env, root), ns);
@@ -319,8 +313,8 @@ JNIEXPORT jint JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeGetS
}
// static void nativeGetError(String root);
JNIEXPORT jint JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeGetError(JNIEnv * env, jclass clazz,
jstring root)
JNIEXPORT jint JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeGetError(JNIEnv * env, jclass clazz, jstring root)
{
storage::NodeStatuses ns;
GetStorage().GetNodeStatuses(jni::ToNativeString(env, root), ns);
@@ -328,23 +322,22 @@ JNIEXPORT jint JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeGetE
}
// static String nativeGetName(String root);
JNIEXPORT jstring JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeGetName(JNIEnv * env, jclass clazz,
jstring root)
JNIEXPORT jstring JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeGetName(JNIEnv * env, jclass clazz, jstring root)
{
return jni::ToJavaString(env, GetStorage().GetNodeLocalName(jni::ToNativeString(env, root)));
}
// static @Nullable String nativeFindCountry(double lat, double lon);
JNIEXPORT jstring JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeFindCountry(JNIEnv * env, jclass clazz,
jdouble lat, jdouble lon)
JNIEXPORT jstring JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeFindCountry(JNIEnv * env, jclass clazz, jdouble lat, jdouble lon)
{
return jni::ToJavaString(
env, g_framework->NativeFramework()->GetCountryInfoGetter().GetRegionCountryId(mercator::FromLatLon(lat, lon)));
return jni::ToJavaString(env, g_framework->NativeFramework()->GetCountryInfoGetter().GetRegionCountryId(mercator::FromLatLon(lat, lon)));
}
// static boolean nativeIsDownloading();
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeIsDownloading(JNIEnv * env,
jclass clazz)
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeIsDownloading(JNIEnv * env, jclass clazz)
{
return static_cast<jboolean>(GetStorage().IsDownloadInProgress());
}
@@ -372,14 +365,14 @@ static void EndBatchingCallbacks(JNIEnv * env)
for (TBatchedData const & dataItem : key.second)
{
// Create StorageCallbackData instance…
static jclass batchDataClass =
jni::GetGlobalClassRef(env, "app/organicmaps/sdk/downloader/MapManager$StorageCallbackData");
static jclass batchDataClass = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/downloader/MapManager$StorageCallbackData");
static jmethodID batchDataCtor = jni::GetConstructorID(env, batchDataClass, "(Ljava/lang/String;IIZ)V");
jni::TScopedLocalRef const id(env, jni::ToJavaString(env, dataItem.m_countryId));
jni::TScopedLocalRef const item(
env, env->NewObject(batchDataClass, batchDataCtor, id.get(), static_cast<jint>(dataItem.m_newStatus),
static_cast<jint>(dataItem.m_errorCode), dataItem.m_isLeaf));
jni::TScopedLocalRef const item(env, env->NewObject(batchDataClass, batchDataCtor, id.get(),
static_cast<jint>(dataItem.m_newStatus),
static_cast<jint>(dataItem.m_errorCode),
dataItem.m_isLeaf));
// …and put it into the resulting list
env->CallBooleanMethod(list.get(), listBuilder.m_add, item.get());
}
@@ -394,8 +387,8 @@ static void EndBatchingCallbacks(JNIEnv * env)
}
// static void nativeDownload(String root);
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeDownload(JNIEnv * env, jclass clazz,
jstring root)
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeDownload(JNIEnv * env, jclass clazz, jstring root)
{
StartBatchingCallbacks();
GetStorage().DownloadNode(jni::ToNativeString(env, root));
@@ -403,8 +396,8 @@ JNIEXPORT void JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeDown
}
// static boolean nativeRetry(String root);
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeRetry(JNIEnv * env, jclass clazz,
jstring root)
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeRetry(JNIEnv * env, jclass clazz, jstring root)
{
StartBatchingCallbacks();
GetStorage().RetryDownloadNode(jni::ToNativeString(env, root));
@@ -412,8 +405,8 @@ JNIEXPORT void JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeRetr
}
// static void nativeUpdate(String root);
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeUpdate(JNIEnv * env, jclass clazz,
jstring root)
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeUpdate(JNIEnv * env, jclass clazz, jstring root)
{
StartBatchingCallbacks();
GetStorage().UpdateNode(GetRootId(env, root));
@@ -421,8 +414,8 @@ JNIEXPORT void JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeUpda
}
// static void nativeCancel(String root);
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeCancel(JNIEnv * env, jclass clazz,
jstring root)
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeCancel(JNIEnv * env, jclass clazz, jstring root)
{
StartBatchingCallbacks();
GetStorage().CancelDownloadNode(GetRootId(env, root));
@@ -430,8 +423,8 @@ JNIEXPORT void JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeCanc
}
// static void nativeDelete(String root);
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeDelete(JNIEnv * env, jclass clazz,
jstring root)
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeDelete(JNIEnv * env, jclass clazz, jstring root)
{
StartBatchingCallbacks();
auto const countryId = jni::ToNativeString(env, root);
@@ -439,7 +432,8 @@ JNIEXPORT void JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeDele
EndBatchingCallbacks(env);
}
static void StatusChangedCallback(std::shared_ptr<jobject> const & listenerRef, storage::CountryId const & countryId)
static void StatusChangedCallback(std::shared_ptr<jobject> const & listenerRef,
storage::CountryId const & countryId)
{
storage::NodeStatuses ns;
GetStorage().GetNodeStatuses(countryId, ns);
@@ -451,48 +445,42 @@ static void StatusChangedCallback(std::shared_ptr<jobject> const & listenerRef,
EndBatchingCallbacks(jni::GetEnv());
}
static void ProgressChangedCallback(std::shared_ptr<jobject> const & listenerRef, storage::CountryId const & countryId,
downloader::Progress const & progress)
static void ProgressChangedCallback(std::shared_ptr<jobject> const & listenerRef,
storage::CountryId const & countryId, downloader::Progress const & progress)
{
JNIEnv * env = jni::GetEnv();
jmethodID const methodID = jni::GetMethodID(env, *listenerRef, "onProgress", "(Ljava/lang/String;JJ)V");
env->CallVoidMethod(*listenerRef, methodID, jni::ToJavaString(env, countryId), progress.m_bytesDownloaded,
progress.m_bytesTotal);
env->CallVoidMethod(*listenerRef, methodID, jni::ToJavaString(env, countryId),
progress.m_bytesDownloaded, progress.m_bytesTotal);
}
// static int nativeSubscribe(StorageCallback listener);
JNIEXPORT jint JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeSubscribe(JNIEnv * env, jclass clazz,
jobject listener)
JNIEXPORT jint JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeSubscribe(JNIEnv * env, jclass clazz, jobject listener)
{
return GetStorage().Subscribe(
std::bind(&StatusChangedCallback, jni::make_global_ref(listener), std::placeholders::_1),
std::bind(&ProgressChangedCallback, jni::make_global_ref(listener), std::placeholders::_1,
std::placeholders::_2));
return GetStorage().Subscribe(std::bind(&StatusChangedCallback, jni::make_global_ref(listener), std::placeholders::_1),
std::bind(&ProgressChangedCallback, jni::make_global_ref(listener), std::placeholders::_1, std::placeholders::_2));
}
// static void nativeUnsubscribe(int slot);
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeUnsubscribe(JNIEnv * env, jclass clazz,
jint slot)
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeUnsubscribe(JNIEnv * env, jclass clazz, jint slot)
{
GetStorage().Unsubscribe(slot);
}
// static void nativeSubscribeOnCountryChanged(CurrentCountryChangedListener listener);
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeSubscribeOnCountryChanged(JNIEnv * env,
jclass clazz,
jobject listener)
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeSubscribeOnCountryChanged(JNIEnv * env, jclass clazz, jobject listener)
{
ASSERT(!g_countryChangedListener, ());
g_countryChangedListener = env->NewGlobalRef(listener);
auto const callback = [](storage::CountryId const & countryId)
{
auto const callback = [](storage::CountryId const & countryId) {
JNIEnv * env = jni::GetEnv();
jmethodID methodID =
jni::GetMethodID(env, g_countryChangedListener, "onCurrentCountryChanged", "(Ljava/lang/String;)V");
env->CallVoidMethod(g_countryChangedListener, methodID,
jni::TScopedLocalRef(env, jni::ToJavaString(env, countryId)).get());
jmethodID methodID = jni::GetMethodID(env, g_countryChangedListener, "onCurrentCountryChanged", "(Ljava/lang/String;)V");
env->CallVoidMethod(g_countryChangedListener, methodID, jni::TScopedLocalRef(env, jni::ToJavaString(env, countryId)).get());
};
storage::CountryId const & prev = g_framework->NativeFramework()->GetLastReportedCountry();
@@ -503,8 +491,8 @@ JNIEXPORT void JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeSubs
}
// static void nativeUnsubscribeOnCountryChanged();
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeUnsubscribeOnCountryChanged(JNIEnv * env,
jclass clazz)
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeUnsubscribeOnCountryChanged(JNIEnv * env, jclass clazz)
{
g_framework->NativeFramework()->SetCurrentCountryChangedListener(nullptr);
@@ -513,16 +501,15 @@ JNIEXPORT void JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeUnsu
}
// static boolean nativeHasUnsavedEditorChanges(String root);
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeHasUnsavedEditorChanges(JNIEnv * env,
jclass clazz,
jstring root)
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeHasUnsavedEditorChanges(JNIEnv * env, jclass clazz, jstring root)
{
return g_framework->NativeFramework()->HasUnsavedEdits(jni::ToNativeString(env, root));
}
// static void nativeGetPathTo(String root, List<String> result);
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeGetPathTo(JNIEnv * env, jclass clazz,
jstring root, jobject result)
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeGetPathTo(JNIEnv * env, jclass clazz, jstring root, jobject result)
{
auto const listAddMethod = jni::ListBuilder::Instance(env).m_add;
@@ -533,9 +520,8 @@ JNIEXPORT void JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeGetP
}
// static int nativeGetOverallProgress(String[] countries);
JNIEXPORT jint JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeGetOverallProgress(JNIEnv * env,
jclass clazz,
jobjectArray jcountries)
JNIEXPORT jint JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeGetOverallProgress(JNIEnv * env, jclass clazz, jobjectArray jcountries)
{
int const size = env->GetArrayLength(jcountries);
storage::CountriesVec countries;
@@ -557,29 +543,29 @@ JNIEXPORT jint JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeGetO
}
// static boolean nativeIsAutoretryFailed();
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeIsAutoretryFailed(JNIEnv * env,
jclass clazz)
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeIsAutoretryFailed(JNIEnv * env, jclass clazz)
{
return g_framework->IsAutoRetryDownloadFailed();
}
// static boolean nativeIsDownloadOn3gEnabled();
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeIsDownloadOn3gEnabled(JNIEnv * env,
jclass clazz)
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeIsDownloadOn3gEnabled(JNIEnv * env, jclass clazz)
{
return g_framework->IsDownloadOn3gEnabled();
}
// static void nativeEnableDownloadOn3g();
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeEnableDownloadOn3g(JNIEnv * env,
jclass clazz)
JNIEXPORT void JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeEnableDownloadOn3g(JNIEnv * env, jclass clazz)
{
g_framework->EnableDownloadOn3g();
}
// static @Nullable String nativeGetSelectedCountry();
JNIEXPORT jstring JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeGetSelectedCountry(JNIEnv * env,
jclass clazz)
JNIEXPORT jstring JNICALL
Java_app_organicmaps_sdk_downloader_MapManager_nativeGetSelectedCountry(JNIEnv * env, jclass clazz)
{
if (!g_framework->NativeFramework()->HasPlacePageInfo())
return nullptr;
@@ -587,4 +573,4 @@ JNIEXPORT jstring JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeG
storage::CountryId const & res = g_framework->GetPlacePageInfo().GetCountryId();
return (res == storage::kInvalidCountryId ? nullptr : jni::ToJavaString(env, res));
}
} // extern "C"
} // extern "C"

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