Repo created

This commit is contained in:
Fr4nz D13trich 2025-11-22 13:58:55 +01:00
parent 4af19165ec
commit 68073add76
12458 changed files with 12350765 additions and 2 deletions

View file

@ -0,0 +1,111 @@
# Android Location Test Cases
This document describes manual testing flows to validate location
implementation on Android.
0. Initial start
- Remove the app with all data and install it again;
- Enable Wi-Fi and Location (normal behavior);
- Start the app and ensure that system dialog about location permissions
appears on the top of splash screen;
- Grant "Precise" or "Approximately" (doesn't matter) permissions
for "Only this time".
- [FDroid only] Initial map download dialog should appear and suggest to
download map of your area (a check box);
- The main map screen should start with cool animation to your current location.
1. GPS cold start
- Disable Wi-Fi, disable Cellular Data, enable Location;
- Get under a roof and away from the open sky and any windows;
- Restart device, start the app
- Wait until location is detected, or go outside to have the open sky and wait
for a few minutes so the device can find GPS satellites, without locking device
and switching to another apps.
- The screen should be automatically on all the time during the process.
This test-case should work with the same behavior regardless of
"Google Play Services" option in the app settings.
2. Location disabled by user
- Follow first 3 steps from (1) above but stop detecting location by pressing
the location "rotating radar" button;
- Check that location icon is crossed out;
- Switch to some other app and back;
- Check that location icon is crossed out;
- Kill the app and start it again;
- Check that location icon is crossed out;
- Tap on location button;
- Ensure that location search has started;
- Wait until location is found under the open sky.
This test-case should work with the same behavior regardless of
"Google Play Services" option in the app settings.
3. Google location dialog (positive case)
- Use Google flavor and enable Google Play Location in the app settings;
- Disable Location, but enable Cellular Data and/or Wi-Fi;
- Start the app;
- Check that location icon is crossed out immediately;
- "To continue, turn on device location, which uses Google's location service"
Google dialog should appear;
- Tap "OK" in the dialog;
- Check that system location has been enabled;
- The app will start searching for location as in (1) case.
4. Google location dialog (negative case)
- Try the same steps as in (3), but tap "No thanks" button in the dialog.
- Check that location icon is crossed out immediately;
- "To continue, turn on..." Google dialog should appear;
- Tap "No thanks" button again;
- Check that location icon is still crossed out;
- Switch to some other app and back;
- Check that location icon is still crossed out and
"To continue, turn on..." dialog doesn't appear automatically;
- Kill the app and start it again;
- Check that location icon is still crossed out and
"To continue, turn on..." dialog doesn't appear automatically;
- Tap on location button - "To continue, turn on device..." dialog
should re-appear again.
5. CoMaps location dialog (negative case)
- Use non-Google flavor or disable Google Play Location in the app settings;
- Disable Wi-Fi, disable Cellular Data, disable Location;
- Start the app and initiate location search by tapping on location button;
- "Please enable Location Services" information dialog should appear;
- Check that location icon is crossed out immediately;
- Switch to some other app and back;
- Check that location icon is still crossed out and
"Please enable Location Services" dialog doesn't appear automatically;
- Kill the app and start it again;
- Check that location icon is still crossed out and
"Please enable Location Services" dialog doesn't appear automatically;
- Tap on location button - "Please enable Location Services" dialog
should re-appear again.
6. Location disabled when app is running
- Disable Wi-Fi, disable Cellular Data, enable Location;
- Get location acquired in the app (the blue location arrow);
- Disable system Location by swiping down from Android's menu bar
to disable location via "Quick settings" panel WITHOUT switching
to Settings or any other apps;
- "Please enable Location Services" or "For better experiences..."
dialog should appear immediately, depending in Google Play Service
availability;
- Further taps on location button will lead to (4) or (5).
7. Pending (searching) location mode
- Disable Wi-Fi, disable cellular data, and enable location.
- Move your phone away from the open sky and any windows to make sure that GPS can't be acquired.
- If the location search hasn't already begun, press the location button to start it.
- The location icon MUST be "locating" while searching for a GPS signal, and location icon should be displayed in the system tray.
- Touch, drag or try to zoom in and zoom out the map - the icon MUST NOT change from "locating" mode.
- Press the location button to disable location search, its icon should change, and system location icon disappear after a few seconds.
- Press the location button again to start searching for location.

14
docs/CODE_OF_CONDUCT.md Normal file
View file

@ -0,0 +1,14 @@
# Community Code of Conduct
This project follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md).
Here is an excerpt:
> _As contributors and maintainers of this project, and in the interest
> of fostering an open and welcoming community, we pledge to respect
> all people who contribute through reporting issues, posting feature
> requests, updating documentation, submitting pull requests or patches,
> and other activities._
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported via <conduct@comaps.app>.

13
docs/COMMUNICATION.md Normal file
View file

@ -0,0 +1,13 @@
# Communication
## Telegram Channel
Please subscribe to our [Telegram Channel](https://t.me/CoMapsApp) for updates.
## Telegram Group
Please join our [Telegram Group](https://t.me/CoMaps_EN) to discuss with other users.
## Code of Conduct
The CoMaps community abides by the [CNCF code of conduct](CODE_OF_CONDUCT.md).

124
docs/CONTRIBUTING.md Normal file
View file

@ -0,0 +1,124 @@
# Contributing
Thank you for your interest in contributing to CoMaps!
## How Can I Contribute?
- [Donate](https://opencollective.com/comaps/donate)
- [Submit a bug report or a feature request](#bug-reports-and-feature-requests)
There are things to do for everyone:
- [For translators](#translations)
- [For UI/UX and graphic designers](#ui-ux-map-styling-and-icons)
- [For developers](#code-contributions)
- [Day-to-day activities](#day-to-day-activities) like user support, testing, issue management, community relations, etc.
- [Submitting your work](#submitting-your-changes)
If you'd like to help in any other way or if there are any related questions - please [contact us](https://codeberg.org/comaps#keep-connected).
### Bug Reports and Feature Requests
[Submit an issue](https://codeberg.org/comaps/comaps/issues) and describe your feature idea or report a bug.
Please check if there are no similar issues already submitted by someone else.
When reporting a bug please provide as much information as possible: OS and application versions,
list of actions leading to a bug, a log file produced by the app.
When using CoMaps app on a device, use the built-in "Report a bug" option:
on Android it creates a new e-mail with a log file attached. Enabling logs in CoMaps settings on Android
before sending the bug report also helps us a lot with debugging.
### Translations
CoMaps is available in 35 languages already, but some of them are incomplete and existing translations need regular updates as the app evolves.
See [translations instructions](TRANSLATIONS.md) for details.
### UI/UX, map styling and icons
CoMaps has a strong focus on easy to use UI and smooth user experience. Feel free to join UI/UX discussions in relevant issues. Mockups are very welcome!
If you're into graphic design then CoMaps needs good, clear and free-to-use icons for hundreds of map features / POIs.
Check CoMaps' [design principles](https://codeberg.org/comaps/comaps/wiki/Design-Principles). Post your icons onto relevant issues or take a next step and [integrate them](STYLES.md) yourself.
Check the [map styling instructions](STYLES.md) and work on adding new map features and other open map styles issues.
### Code Contributions
Please follow instructions in [INSTALL.md](INSTALL.md) to set up your development environment.
You will find a list of issues for new contributors [here](https://codeberg.org/comaps/comaps/issues?labels=393881%2c393944) to help you get started with simple tasks.
**We do not assign issues to first-time contributors.** Any such request notifies our contributors and the development team, and creates unnecessary noise that distracts us from the work. Just make a PR - and it will be reviewed.
Sometimes it's better to discuss and confirm your vision of the fix or implementation before working on an issue. Our main focus is on simplicity and convenience for everyone, not only for geeks.
Please [learn how to use `git rebase`](https://git-scm.com/book/en/v2/Git-Branching-Rebasing) (or rebase via any git tool with a graphical interface, e.g. [Fork for Mac](https://git-fork.com/) is quite good) to amend your commits in the PR and maintain a clean logical commit history for your changes/branches.
We strive to help onboard new developers but we don't always have enough time to guide newcomers step-by-step and explain everything in detail. For that reason we might ask you to read lots of the documentation and study the existing code.
- [Pull Request Guide](PR_GUIDE.md).
- [Directories structure](STRUCTURE.md)
- [C++ Style Guide](CPP_STYLE.md).
- [Java Style Guide](JAVA_STYLE.md).
- [Swift Style Guide](SWIFT_STYLE.md).
- [Objective-C Style Guide](OBJC_STYLE.md).
...and more in the [docs folder](./) of the repository.
### Day-to-day Activities
Please help us:
- processing users questions and feedback in chats, app stores, email and social media and creating follow-up issues or updating existing ones
- reproducing and triaging reported bugs
- [testing upcoming features and bug fixes for Android, iOS and desktop versions](TESTING.md)
- keeping [issues](https://codeberg.org/comaps/comaps/issues) in order (check for duplicates, organize, assign labels, link related issues, etc.)
- composing nice user-centric release notes and news items
- etc.
You can also contribute in [other ways](https://codeberg.org/comaps/Governance/src/branch/main/contribute.md).
## Submitting your changes
All contributions to CoMaps repositories should be submitted via
[pull requests](https://forgejo.org/docs/latest/user/pull-requests-and-git-flow/)
and signed-off with the [Developers Certificate of Origin](#legal-requirements).
Each pull request is reviewed by CoMaps maintainers to ensure its quality.
Sometimes the review process even for smallest commits can be very thorough.
### Legal Requirements
When contributing to this project, you must agree that you have authored 100%
of the content, that you have the necessary rights to the content and that
the content you contribute may be provided under the project license.
To contribute you must assure that you have read and are following the rules
stated in the [Developers Certificate of Origin](DCO.md) (DCO). We have
borrowed this procedure from the Linux kernel project to improve tracking of
who did what, and for legal reasons.
To sign-off a patch, just add a line in the commit message saying:
Signed-off-by: Some Developer <somedev@example.com>
Git has a flag that can sign a commit for you. An example using it is:
git commit -s -m 'An example commit message'
Or, if you're making edits using Codeberg UI, check "Add a Signed-off-by trailer
by the committer at the end of the commit log message" before saving.
You can sign-off using your pseudonym or real name, and using
"somedev@noreply.codeberg.org" as an email instead of a real one.
## Team Messaging
If you have contributed and interested in contributing more through collaboration with the project team, you are welcome to join Zulip. Zulip is for contributors who regularly collaborate on work with the team, and it is different from Telegram, Matrix or Mastodon which are for broader discussion. If you are interested in further contributing, use this link to join the CoMaps org on Zulip chat:
https://comaps.zulipchat.com/join/e5e3c4zurmfxykrtbiiq6qrw/
When you join Zulip, in Watercooler > Signups do an intro with the team:
- Short background, professional and personal
- Why are you contributing to CoMaps
- What you think about projects' principles and direction https://codeberg.org/comaps/Governance#core-principles
- Contribution so far (link Issue, PR, etc)
- What you would like to contribute

219
docs/CPP_STYLE.md Normal file
View file

@ -0,0 +1,219 @@
Most of our coding style is specified in a configuration file for [ClangFormat](http://clang.llvm.org/docs/ClangFormat.html).
To automatically format a file, install `clang-format` and run:
clang-format -i file.cpp file.hpp other_file.cpp
---
In general, [Google's coding standard](https://google.github.io/styleguide/cppguide.html) is used, and we strongly encourage to read it.
Below are our specific (but not all!) exceptions to the Google's coding standard:
- All C++ code should conform to the C++23 standard.
- We use `.cpp` and `.hpp` files, not `.cc` and `.h` (`.c` and `.h` are used for C code), in UTF-8 encoding.
- File names are lowercase with underscores, like `file_reader.cpp`.
- We use `#pragma once` instead of the `#define` Guard in header files.
- Includes are sorted and grouped by directory, there should be newlines between different directories.
- Order of directories in includes: "current_dir/current_file.hpp", includes from other dirs sorted by dependencies (e.g. indexer, then coding, then base), "defines.hpp", C++ standard library headers, boost headers, 3party.
- We ARE using C++ exceptions.
- We are using all features of C++17 and C++23 except `std::filesystem`, `std::to_chars`, `std::from_chars` and `std::format` which are not fully supported on all platforms.
- We try to limit the usage of boost libraries which require linking (and prefer C++23 types over their boost counterparts).
Naming and formatting
- We ALWAYS use two spaces indent and don't use tabs.
- We don't have strict limits on line width, but keep it reasonable to fit on the screen. The advised width is that written in the [.clang-format](.clang-format) file (currently 100).
- Doxygen-style comments can be used.
- Underscores are allowed only in prefixes for member variables and namespace names, like `int m_countriesCount; namespace utf_parser`.
- Use right-to-left order for variables/params: `string const & s` (reference to the const string).
- In one line `if`, `for`, `while` we do not use brackets, even if a one line `for` or `while` is combined with one line `if`.
- Space after the keyword in conditions and loops. Space after `;` in `for` loop.
- Space between binary operators: `x = y * y + z * z`.
- Space after double dash.
- We use `using` keyword instead of `typedef`.
- We do not use the Systems Hungarian Notation: do not add the "p" suffix to your pointer variable names and the "T" prefix or suffix to your type names.
- Compile-time constants must be named in CamelCase, starting with a lower-case `k`, e.g. `kCompileTimeConstant` and marked as `constexpr` when possible.
- Values of enum classes must be named in CamelCase, e.g. `enum class Color { Red, Green, LightBlue };`.
- Macros and C-style enums must be named in UPPER_CASE, and enum values must be prefixed with a capitalized enum name.
Note that macros complicate debugging, and old-style enums have dangerous implicit conversions to integers, and tend to clutter
containing namespaces. Avoid them when possible - use `const` or `constexpr` instead of macros, and enum classes instead of enums.
**We write code without warnings!**
## Formatting Example/Guide/Reference
```cpp
#pragma once
#include <math>
uint16_t constexpr kBufferSize = 255;
// C-style enums are ALL_CAPS. But remember that C++11 enum classes are preferred.
enum Type
{
TYPE_INTEGER,
TYPE_FLOAT,
TYPE_STRING
};
using TMyTypeStartsWithCapitalTLetter = double;
class ComplexClass
{
public:
Complex(double rePart, double imPart) : m_re(rePart), m_im(imPart) {}
double Modulus() const
{
double const rere = m_re * m_re;
double const imim = m_im * m_im;
return sqrt(rere + imim);
}
double OneLineMethod() const { return m_re; }
private:
// We use the "m_" prefix for member variables.
double m_re;
double m_im;
};
namespace
{
void CamelCaseFunctionName(int lowerCamelCaseVar)
{
static int counter = 0;
counter += lowerCamelCaseVar;
}
} // namespace
namespace lower_case
{
template <typename TypenameWithoutAffixes>
void SomeFoo(int a, int b,
TypenameWithoutAffixes /* We avoid compilation warnings. */)
{
for (int i = 0; i < a; ++i)
{
// IMPORTANT! We DON'T use one-liners for if statements for easier debugging.
// The following syntax is invalid: if (i < b) Bar(i);
if (i < b)
Bar(i);
else
{
Bar(i);
Bar(b);
// Commented out the call.
// Bar(c);
}
}
}
} // namespace lower_case
// Switch formatting.
int Foo(int a)
{
switch (a)
{
case 1:
Bar(1);
break;
case 2:
{
Bar(2);
break;
}
case 3:
default:
Bar(3);
break;
}
return 0;
}
// Loops formatting.
if (condition)
foo();
else
bar();
if (condition)
{
if (condition)
foo();
else
bar();
}
for (size_t i = 0; i < size; ++i)
foo(i);
while (true)
if (condition)
break;
// Space after the keyword.
if (condition)
{
}
for (size_t i = 0; i < 5; ++i)
{
}
while (condition)
{
}
switch (i)
{
}
// Space between operators, and don't use space between unary operator and expression.
x = 0;
x = -5;
++x;
x--;
x *= 5;
if (x && !y)
{
}
v = w * x + y / z;
v = w * (x + z);
// Space after double dash. And full sentences in comments.
```
## Tips and Hints
- If you see outdated code which can be improved, DO IT NOW (but in a separate pull request or commit)!
- Your code should work at least on [mac|linux|android][x86|x86_64], [ios|android][x86|armv7|arm64] architectures
- Your code should compile with C++23 compiler
- Avoid using any new 3party library if it is not fully tested and supported on all our platforms
- Cover your code with unit tests. See examples for existing libraries
- Check Base and Coding libraries for most of the basic functions
- Ask your team if you have any questions
- Use dev@comaps.app mailing list to ask all developers and bugs@comaps.app mailing list to post bugs
- Release builds contain debugging information (for profiling), production builds do not
- If you don't have enough time to make it right, leave a `// TODO(DeveloperName): need to fix it` comment
### Some useful macros:
- `#ifdef DEBUG | RELEASE`
- `#ifdef OMIM_OS_ANDROID | OMIM_OS_IPHONE | OMIM_OS_MAC` (and some other useful OS-related macros, see `std/target_os.hpp`)
- Use `ASSERT(expression, (out message))` and `ASSERT_XXXXXX` macros often to check code validity in DEBUG builds
- Use `CHECK(expression, (out message))` and `CHECK_XXXXXX` macros to check code validity in all builds
- Use `LOG(level, (message))` for logging, below is more detailed description for level:
- `LINFO` - always prints log message
- `LDEBUG` - logs only in DEBUG
- `LWARNING` - the same as `LINFO` but catches your attention
- `LERROR` - the same as `LWARNING`, but crashes in DEBUG and works in RELEASE
- `LCRITICAL` - the same as `LERROR` and ALWAYS crashes
- Need scope guard? Check `SCOPE_GUARD(name, func)`
- Use `std::array::size()` to calculate plain C-array's size
- Declare your own exceptions with `DECLARE_EXCEPTION(name, baseException)`, where `baseException` is usually `RootException`
- Throw exceptions with `MYTHROW(exceptionName, (message))`
- A lot of useful string conversion utils are in `base/string_utils.hpp`

100
docs/CREDENTIALS.md Normal file
View file

@ -0,0 +1,100 @@
This file contains a list of all sensitive credentials, access keys, authentication tokens, and security certificates used by CI/CD (Forgejo Actions).
- [PRIVATE\_H](#private_h)
- [RELEASE\_KEYSTORE](#release_keystore)
- [SECURE\_PROPERTIES](#secure_properties)
- [GOOGLE\_PLAY\_JSON](#google_play_json)
- [HUAWEI\_APPGALLERY\_JSON](#huawei_appgallery_json)
- [AGCONNECT\_SERVICES\_JSON](#agconnect_services_json)
- [APPSTORE\_JSON](#appstore_json)
- [CERTIFICATES\_DEV\_P12](#certificates_dev_p12)
- [CERTIFICATES\_DISTR\_P12](#certificates_distr_p12)
- [APPSTORE\_CERTIFICATE\_PASSWORD](#appstore_certificate_password)
## PRIVATE_H
Shared compile-time secrets for all platforms.
```bash
gh secret set PRIVATE_H --env beta --body "$(base64 < private.h)"
gh secret set PRIVATE_H --env production --body "$(base64 < private.h)"
```
## RELEASE_KEYSTORE
Android Java-compatible keystore with certificates used for signing APKs.
```bash
gh secret set RELEASE_KEYSTORE --env beta --body "$(base64 < android/app/release.keystore)"
gh secret set RELEASE_KEYSTORE --env production --body "$(base64 < android/app/release.keystore)"
```
## SECURE_PROPERTIES
Android Gradle configuration file containing the passwords for the `release.keystore`.
```bash
gh secret set SECURE_PROPERTIES --env beta --body "$(base64 < android/app/secure.properties)"
gh secret set SECURE_PROPERTIES --env production --body "$(base64 < android/app/secure.properties)"
```
## GOOGLE_PLAY_JSON
Credentials for uploading Android releases to Google Play.
```bash
gh secret set GOOGLE_PLAY_JSON --env production --body "$(base64 < android/app/google-play.json)"
```
## HUAWEI_APPGALLERY_JSON
Credentials for uploading Android releases to Huawei AppGallery.
```bash
gh secret set HUAWEI_APPGALLERY_JSON --env production --body "$(base64 < android/app/huawei-appgallery.json)"
```
## AGCONNECT_SERVICES_JSON
Credentials for Huawei Mobile Services (HMS) to use Location Kit (not yet finished).
```bash
gh secret set AGCONNECT_SERVICES_JSON --env beta --body "$(base64 < android/app/agconnect-services.json)"
gh secret set AGCONNECT_SERVICES_JSON --env production --body "$(base64 < android/app/agconnect-services.json)"
```
## APPSTORE_JSON
Credentials for uploading iOS releases to Apple AppStore Connect.
```bash
gh secret set APPSTORE_JSON --env beta --body "$(base64 < xcode/keys/appstore.json)"
gh secret set APPSTORE_JSON --env production --body "$(base64 < xcode/keys/appstore.json)"
```
## CERTIFICATES_DEV_P12
Credentials for signing iOS releases - dev keys.
```bash
gh secret set CERTIFICATES_DEV_P12 --env beta --body "$(base64 < xcode/keys/CertificatesDev.p12)"
gh secret set CERTIFICATES_DEV_P12 --env production --body "$(base64 < xcode/keys/CertificatesDev.p12)"
```
## CERTIFICATES_DISTR_P12
Credentials for signing iOS releases - AppStore keys.
```bash
gh secret set CERTIFICATES_DISTR_P12 --env beta --body "$(base64 < xcode/keys/CertificatesDistr.p12)"
gh secret set CERTIFICATES_DISTR_P12 --env production --body "$(base64 < xcode/keys/CertificatesDistr.p12)"
```
## APPSTORE_CERTIFICATE_PASSWORD
Password for `CertificatesDistr.p12`.
```bash
gh secret set APPSTORE_CERTIFICATE_PASSWORD --env beta
gh secret set APPSTORE_CERTIFICATE_PASSWORD --env production
```

53
docs/DCO.md Normal file
View file

@ -0,0 +1,53 @@
# Developer's Certificate of Origin
## CLA vs DCO
This project uses **Developer's Certificate of Origin (DCO)** instead of **Contributor License Agreement (CLA)**. It is often easier to get started contributing under a DCO than a CLA.
When one is developing software for a company they need to have the company sign the Corporate CLA before contributing. That means there is a step after the business decides to contribute where legal documents need to be signed and exchanged. Once this is done there are steps to associate people with those legal documents. All of this takes time. In some companies this process can take weeks or longer.
We wanted to make it simpler to contribute.
## What Is A DCO?
A DCO is lightweight way for a developer to certify that they wrote or otherwise have the right to submit code or documentation to a project. The way a developer does this is by adding a Signed-off-by line to a commit. When they do this they are agreeing to the DCO.
The full text of the DCO can be found at <https://developercertificate.org>. It reads:
> Developer Certificate of Origin Version 1.1
>
> Copyright (C) 2004, 2006 The Linux Foundation and its contributors. 1 Letterman Drive Suite D4700 San Francisco, CA, 94129
>
> Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
>
> Developer's Certificate of Origin 1.1
>
> By making a contribution to this project, I certify that:
>
> (a) The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or
>
> (b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or
>
> (c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it.
>
> (d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved.
An example signed commit message might look like:
```
An example commit message
Signed-off-by: Some Developer <somedev@example.com>
```
Git has a flag that can sign a commit for you. An example using it is:
```
$ git commit -s -m 'An example commit message'
```
In the past, once someone wanted to contribute they needed to go through the CLA process first. Now they just need to signoff on the commit.
## Contributors
Please feel free to add your name to [CONTRIBUTORS](https://codeberg.org/comaps/comaps/src/branch/main/CONTRIBUTORS) in your first PR.

76
docs/DEBUG_COMMANDS.md Normal file
View file

@ -0,0 +1,76 @@
# Available debug commands
CoMaps exposes debug commands to help you control the native components (engine, editor, navigation, ...). **These commands are not intended for regular users** and are only used for debug purposes. Please only use these commands if you are working on CoMaps.
Each command is entered in the search input (Android and iOS) and are activated as soon as the full search keyword is entered. Unless specified, the effects triggered are discarded after a restart.
For more information, please see the source code at [`Framework::ParseSearchQueryCommand`](../map/framework.cpp).
## Drape
### Themes
- `?dark` or `mapstyle:dark`: Enable night mode for the map view only. You may need to change the zoom level to reload the view.
- `?light` or `mapstyle:light`: Enable light mode for the map view only. You may need to change the zoom level to reload the view.
- `?odark` or `mapstyle:outdoors_dark`: Same as `?dark`, but using the outdoor variant.
- `?olight` or `mapstyle:outdoors_light`: Same as `?light`, but using the outdoor variant.
- `?vdark` or `mapstyle:vdark`: Same as `?dark`, but using the vehicle variant.
- `?vlight` or `mapstyle:vlight`: Same as `?light`, but using the vehicle variant.
### Post processing
- `?aa` or `effect:antialiasing`: Enable antialiasing.
- `?no-aa` or `effect:no-antialiasing`: Disable antialiasing.
### Map layers
- `?scheme`: Enable the subway layer.
- `?no-scheme`: Disable the subway layer.
- `?isolines`: Enable the isolines layer.
- `?no-isolines`: Disable the isolines layer.
### 3D mode (for the Qt desktop app only)
- `?3d`: Enable 3D (perspective) mode.
- `?b3d`: Enable 3D buildings.
- `?2d`: Disable 3D mode and buildings.
The source code is at [`SearchPanel::Try3dModeCmd`](../qt/search_panel.cpp).
### Information
- `?debug-info`: Show renderer version, zoom scale and FPS counter in the top left corner of the map.
- `?debug-info-always`: Same as `?debug-info`, but persists across restarts.
- `?no-debug-info`: Disables the debug info.
- `?debug-rect`: Shows boxes around icons and labels. When the icon/label is shown, the box is green. When the icon/label cannot be shown, the box is red with a blue arrow indicating which icon/label prevents rendering. When the icon/label is not ready for display, the box is yellow (check the `Update` method of [`dp::OverlayHandle`](../drape/overlay_handle.hpp) and derived classes for more information).
- `?no-debug-rect`: Disables the debug boxes.
### Drape rendering engine
All the following commands require an app restart:
- `?gl`: Forces the OpenGL renderer. OpenGL renderer is supported on all platforms and is used by default on older Android devices and on the desktop.
- `?vulkan`: Forces the Vulkan renderer on Android. Vulkan is used by default on newer Android 7+ devices.
- `?metal`: Forces the Metal renderer. It is used by default on iOS and can be ported/enabled with some effort on Mac OS X too.
## Editor
- `?edits`: Shows the list of map edits (local and uploaded) made with the app in the search results. Useful to debug what was not uploaded yet.
- `?eclear`: Clears the locally stored list of edits. Warning: all local changes that are not yet uploaded to OpenStreetMap.org will be lost! Everything that was already uploaded to OSM stays there untouched.
## Routing
- `?debug-cam`: Force-enables speed cameras in all countries.
- `?no-debug-cam`: Reverts speed camera setting to default.
## GPS
- `?gpstrackaccuracy:XXX`: Changes the accuracy of the GPS while recording tracks. Replace `XXX` by the desired horizontal accuracy. Works only on iOS for now.
## Place Page
- `?all-types`: Shows all internal types in place page
- `?no-all-types`: Disables showing all internal types in place page
## Search
- `?wiki`: Search results for all elements with Wikipedia links

View file

@ -0,0 +1,78 @@
# Experimental support of public transport from GTFS
## Introduction to the experimental public transport feature
At the moment our app does not have full support for public transport. What we have now:
- Scarce transit data collected from OSM which includes subway, light rail, monorail and train routes and stops. Let's call it the [OSM transit](SUBWAY_GENERATION.md) from now on.
- The "Subway layer" for visual representation of the OSM transit.
- "Subway navigation" - OSM transit routing.
:bus: But you can turn on the experimental feature of [GTFS](https://developers.google.com/transit/gtfs/reference) public transport and use it inside the CoMaps app. It includes all [transit types definded by GTFS specification:](https://developers.google.com/transit/gtfs/reference/extended-route-types) bus, train, ferry, aerial lifts of different kinds, trolleybus and much more. Let's call this version of transit data **GTFS transit** from now on.
To mix in the experimental GTFS transit into the OSM transit data you should follow these steps:
1. Run the pipeline for downloading and preparing GTFS data about public transport.
2. Switch to the new version of the transit routing section in maps: build maps with the GTFS transit section with the help of special options for generator_tool.
After completing these steps you will have maps with:
:star: Proper public transport navigation. You'll have the opportunity to build public transport routes with transfers from one type of public transport to another (e.g. bus -> train, monorail -> subway, etc). The route is built according to the transit schedules, days off and exceptions in timetables.
:star: "Subway layer" with old OSM transit data but in new visual representation. It differs from the current layer in handling parallel segments of different routes with the same color. In current version we draw separate polyline for each route. It looks a little bit messy, and the new version fixes this: we collapse single-colored parallel routes into one line.
Most of the data collisions between OSM and GTFS sources are excluded, because we filter all subway data from GTFS on purpose. There still could be collisions in light rail, monorail and train data, but it is not a problem: on the "Subway layer" we show data only from OSM. In routing we choose optimal route from GTFS and OSM.
**Why is this feature experimental?** The main reason is that it is not properly tested. Also it lacks new user interfaces for filtering public transport by type, setting departure time and routing "follow mode".
## Instructions for turning on full public transport support
1. Run the python script for collecting GTFS feeds from two GTFS aggregators: [Transitland](https://www.transit.land/) and [OpenMobilityData.](http://transitfeeds.com/feeds) You can find the script in omim/tools/python/transit/gtfs/. It is called download_gtfs.py. It crawls all the feeds from these aggregators, loads feed zips and extracts as subdirectories to the specified directory.
Example:
```
python3 download_gtfs.py --path=dir_for_storing_feeds --mode=fullrun --source=all --transitland_api_key=YOUR_KEY_FOR_TRANSITLAND_API
```
In this example all accessible feeds from Transitland and OpenMobilityData will be downloaded to the `dir_for_storing_feeds` directory. But if you don't want to create key for Transitland API you can run this tool for crawling OpenMobilityData only:
```
python3 download_gtfs.py --path=dir_for_storing_feeds --mode=fullrun --source=mobilitydb
```
After completing this step you will have directory containing subdirectories with GTFS feeds.
2. Build and run the C++ tool for filtering, combining and transforming GTFS feeds (downloaded on the previous step) to the intermediate json files. Later they will be passed to the generator_tool for creating transit section in new format. You can find the tool in `omim/transit/world_feed/gtfs_converter.` The tool is` gtfs_converter.`
It can be run in two modes: for handling GTFS-only or for merging data from GTFS and OSM.
Example of running `gtfs_converter` for merging GTFS and OSM data:
```
./gtfs_converter --path_mapping=mapping.txt --path_mapping_edges=mapping_edges.txt --path_gtfs_feeds=dir_for_storing_feeds --path_subway_json=subway_latest.json --path_json=result_json_dir --path_resources=omim/data
```
Example of running `gtfs_converter` for saving only GTFS data (without OSM):
```
./gtfs_converter --path_mapping=mapping.txt --path_mapping_edges=mapping_edges.txt --path_gtfs_feeds=dir_for_storing_feeds --path_json=result_json_dir --path_resources=omim/data
```
:exclamation: GTFS data often changes: some routes are cancelled, some stops are built, timetables constantly change. **If you're planning to build maps periodically, more than once, then you must take care of the safety of files with transit entities ids which are generated by `gtfs_converter.`** The goal is to make transit entities consistent between re-runs of the tool so that routing between old regions and the new ones doesn't fail. It is better to backup files specified as `path_mapping` and `path_mapping_edges`. When you run `gtfs_converter` the first time these files are created. Subsequent launches update existing files.
After completing this step you will have directory with line-by-line jsons in the directory specified by `path_json` option of `gtfs_converter.`
3. In map_generator.ini uncomment `SUBWAY_URL` parameter and set `TRANSIT_URL` parameter to the directory created on the previous step. Example:
```
TRANSIT_URL: file:///home/result_json_dir
```
Run generator tool [as usual](../tools/python/maps_generator) with this ini config. After it is done you'll have mwms with transit section in experimental GTFS format.
:checkered_flag: Use the resulting mwms in your app. Enjoy the experimental public transport in CoMaps!
## If you have questions
Feel free to ask [mesozoic-drones](https://github.com/mesozoic-drones), you can also do it by mail: mesozoic.drones@gmail.com

419
docs/INSTALL.md Normal file
View file

@ -0,0 +1,419 @@
# Building
- [System requirements](#system-requirements)
- [Getting sources](#getting-sources)
- [Android](#android-app)
- [iOS](#ios-app)
- [Desktop](#desktop-app)
- [Map data and styles](#map-data-and-styles)
## System requirements
To build and run CoMaps you'll need a machine with at least 4Gb of RAM and 20-30Gb of disk space depending on your target platform. Expect to download 2-5Gb of files.
## Getting sources
First of all get the source code. The full CoMaps sources repository is ~3Gb in size, there are various [clone options](#special-cases-options) to reduce the download size to suit your needs.
Clone the repository including all submodules (see [Special cases options](#special-cases-options) below)
(if you plan to contribute and propose pull requests then use a web interface at https://codeberg.org/comaps/comaps to fork the repository first and use your fork's URL in the command below)
Follow the instructions for your OS, and afterwards the repository is prepared to build a CoMaps app!
### Linux
Clone the repository
```bash
git clone --recurse-submodules --shallow-submodules https://codeberg.org/comaps/comaps.git
```
Install required packages (Ubuntu/Debian):
```bash
sudo apt install build-essential cmake qt6-base-dev qt6-svg-dev qt6-positioning-dev libicu-dev libfreetype-dev libharfbuzz-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev optipng python3-pip ninja-build
pip install "protobuf<3.21" --break-system-packages
```
Go into the cloned repository and configure it for development:
```bash
cd comaps
./configure.sh
```
If you plan to publish the app privately in stores check [special options](#special-cases-options).
### Windows
You need to have [Git for Windows](https://git-scm.com/download/win) installed and Git bash available in the PATH.
It's necessary to enable symlink support:
1. Activate _Windows Development Mode_ to enable symlinks globally:
- Windows 10: _Settings_ -> _Update and Security_ -> _For Developers_ -> _Activate Developer Mode_
- Windows 11: _Settings_ -> _Privacy and Security_ -> _For Developers_ -> _Activate Developer Mode_
- Press Win + R, run `ms-settings:developers` and _Activate Developer Mode_
2. Enable [symlinks](https://git-scm.com/docs/git-config#Documentation/git-config.txt-coresymlinks) support in git. The easiest way is to reinstall the latest [Git for Windows](https://git-scm.com/download/win) with the "Enable Symlinks" checkbox checked. If you don't want to reinstall Git, then you can add `-c core.symlinks=true` parameter to the clone command below to enable symlinks for the repository.
```bash
git config --global core.symlinks true
```
Clone the repository
```bash
git clone --recurse-submodules --shallow-submodules https://codeberg.org/comaps/comaps.git
```
For _Windows 10_: You should be able to build the project by following either of these setup methods:
**Setup 1: Using WSL**
1. Install [WSL](https://learn.microsoft.com/en-us/windows/wsl/install) on your machine.
2. Install g++ by running the following command in WSL: `sudo apt install g++`
**Setup 2: Using Visual Studio Developer Command Prompt**
Install the [Visual Studio Developer Command Prompt](https://docs.microsoft.com/en-us/visualstudio/ide/reference/command-prompt-powershell?view=vs-2022) (make sure to choose the latest MSVC x64/x86 build tool and Windows 10/11 SDK as individual components while installing Visual Studio).
### macOS
Install required build dependencies and Xcode
1. Install Xcode Command Line Tools
2. Install [Xcode](https://apps.apple.com/app/xcode/id497799835?mt=12) from the App Store
3. Install [Homebrew](https://brew.sh) and required dependencies
4. Clone and configure the repository to be able to build the iOS app later
#### Xcode Command Line Tools
```bash
xcode-select --install
```
#### Homebrew packages
```bash
brew install wget optipng cmake ninja qt
pip3 install "protobuf<3.21"
```
#### Clone the repository
```bash
git clone --recurse-submodules --shallow-submodules https://codeberg.org/comaps/comaps.git
cd comaps
./configure.sh
```
### Special cases options
If you're only doing a one-off build or your internet bandwidth or disk space is limited, add following options to the `git clone` command:
- a `--filter=blob:limit=128k` option to make a _partial clone_ (saves ~4Gb), i.e. blob files over 128k in size will be excluded from the history and downloaded on-demand - is suitable for generic development.
If you mistakenly did a `git clone` without checking out submodules, you can run `git submodule update --init --recursive --depth 1`.
To be able to publish the app in stores e.g. in Google Play its necessary to populate some configs with private keys, etc.
If you need Organic Maps and Maps.ME commits history (before the CoMaps fork) run:
```bash
git remote add om-historic https://codeberg.org/comaps/om-historic.git
git fetch --tags om-historic
git replace squashed-history historic-commits
```
It'll seamlessly replace the squashed first "Organic Maps sources as of 02.04.2025" commit with all prior commits which will work with all git commands as usual.
The `om-historic.git` repo is ~1Gb only as various historic blobs, bundled 3rd-party deps, etc. were removed from it.
If you really need them (e.g. to build a very old app version) then refer to full organicmaps.git repo please.
## Android app
### Preparing
Linux, MacOS, or Windows should work to build CoMaps for Android.
Ensure that you have at least 30GB of free space and Python 3 installed.
Install [Android Studio](https://developer.android.com/studio).
Run Android Studio and open the project in `android/` directory!
This is important, otherwise the following menus won't be visible.
Configure Android Studio:
- Open "SDK Manager" (under "More Actions" in a welcome screen or a three-dot menu in a list of recent projects screen or "Tools" top menu item in an open project).
- Switch to "SDK Tools" tab.
- Check "Show Package Details" checkbox.
- Select "CMake" version **3.22.1** or higher.
- Click "Apply" and wait for downloads and installation to finish.
- In the left pane menu select "Appearance & Behavior > System Settings > Memory Settings".
- Set "IDE max heap size" to 2048MB or more (otherwise the Studio might get stuck on "Updating indexes" when opening the project).
Configure the repository with Android SDK paths. You can do it either by [setting](https://developer.android.com/tools#environment-variables) a global environment variable pointing at your Android SDK:
```
ANDROID_HOME=<here is the absolute path to the root folder of your Android SDK installation>
```
or by running the following script, that creates `android/local.properties` file with the line `sdk.dir=<path to your Android SDK>` in it:
_Linux:_
```bash
./tools/android/set_up_android.py --sdk $HOME/Android/Sdk
```
_macOS:_
```bash
./tools/android/set_up_android.py --sdk $HOME/Library/Android/Sdk
```
_Windows 10:_ no action needed, should work out of the box.
### Set up the emulator
Set up a virtual device to use [emulator](https://developer.android.com/studio/run/emulator) ("Tools > Device Manager") or [use a hardware device for debugging](https://developer.android.com/studio/run/device).
For the emulator its recommended to choose the latest supported API Level system image. Use ABI _x86_64_ for Intel-based processors and _arm64-v8a_ for ARM-based processors (e.g. M1/M2 Macs).
### Building
There is a matrix of different build variants:
- _[Type](https://codeberg.org/comaps/comaps/src/commit/d02aefbf12a1a201090b40b395585e679b04c798/android/app/build.gradle#L278)_:
- `Debug` is a debug version with all checks enabled.
- `Beta` is a manual build for testing.
- `Release` is a fully optimized version for app stores.
- _[Flavor](https://codeberg.org/comaps/comaps/src/commit/d02aefbf12a1a201090b40b395585e679b04c798/android/app/build.gradle#L179)_:
- `Web` is a light APK without any bundled maps.
- `Google` is a full Google Play store version including a low-zoom overview world map.
- `Fdroid` is a version for publishing on the [F-Droid](https://f-droid.org/) open source apps store (no bundled maps; FOSS microG services instead of Google's).
- ...and other flavors like `Huawei`.
You can choose a build variant in Android Studio's "Build > Select Build Variant..." menu. There you can also choose a target architecture (Active ABI) like _x86_64_ (for e.g. emulator) or _arm64-v8a_ (many modern devices).
In order to build the Google variant, you need a special key which only the core developers have. For community members who want to contribute, the best selection is "fdroidBeta" or "fdroidDebug" depending on the use case.
The Active ABI can be set to "arm64-v8a".
To build and run the app in the emulator or on a hardware device use a "Run > Run (android)" menu item or press the Play / Debug button on the top right of the IDE.
To build a redistributable APK use a "Build > Build Bundle(s) / APK(s) > Build APK(s)" menu item. Generated APKs are stored in `build/outputs/apk/`.
See also https://developer.android.com/studio/run.
### Debugging
To enable logging in case of crashes, after installing a debug version, run:
```bash
adb shell pm grant app.organicmaps.debug android.permission.READ_LOGS
```
### Android Auto Development
Android Auto can be developed and tested without having a physical device by using [Desktop Head Unit (DHU)](https://developer.android.com/training/cars/testing/dhu). Go to Android Studio > Tools -> SDK Manager -> SDK Tools and enable "Android Auto Desktop Head Unit".
[Android Auto App](https://play.google.com/store/apps/details?id=com.google.android.projection.gearhead) is required for Auto functionality. The app should be installed from Google Play before connecting a phone to the Desktop Head Unit or a real car. Android Auto doesn't work on phones without Google Play Services.
To run Android Auto, connect the phone using USB cable and run the Desktop Head Unit with `--usb` flag:
```
~/Library/Android/sdk/extras/google/auto/desktop-head-unit --usb
```
```
[REDACTED]
[I]: Found device 'SAMSUNG SAMSUNG_Android XXXXXXXXX' in accessory mode (vid=18d1, pid=2d01).
[I]: Found accessory: ifnum: 0, rd_ep: 129, wr_ep: 1
[I]: Attaching to USB device...
[I]: Attached!
```
CoMaps icon will appear in the application list in DHU.
### More options
#### Building from the command line
First configure `PATH` to prefer `cmake` from the Android SDK instead of the default system install:
_Linux:_
```bash
export PATH=$HOME/Android/Sdk/cmake/3.22.1/bin:$PATH
```
_macOS:_
```bash
export PATH=$HOME/Library/Android/Sdk/cmake/3.22.1/bin:$PATH
```
Check if you have a system-wide Java Runtime Environment (JRE) installed:
```bash
java -version
```
If your system doesn't have a JRE installed or Java version is less than 21 (OpenJDK)
or you want command line builds to use a JRE version bundled with the Studio
then set the `JAVA_HOME` environment variable:
_Linux:_
```bash
export JAVA_HOME=<path-to-android-studio-installation>/android-studio/jre
```
_macOS:_
```bash
export JAVA_HOME=<path-to-android-studio-installation>/Contents/jre/Contents/Home
```
Run the builds from the android subdirectory of the repository:
```bash
cd android
```
To build, install and run e.g. a _Web Debug_ version on your device/emulator:
```bash
./gradlew runWebDebug
```
Or to compile a redistributable _Fdroid Beta_ APK for testing:
```bash
./gradlew assembleFdroidBeta
```
Or to build _Beta_ APKs for all _Flavors_:
```bash
./gradlew assembleBeta
```
Run `./gradlew tasks` to see all possible build variants.
Intermediate files for each build (_Type_ + _Flavor_ + target arch) take ~3-4.5Gb of space.
To remove all intermediate build files run `./gradlew clean`.
By default the build will run for all 3 target architectures: _arm64-v8a_, _armeabi-v7a_ and _x86_64_. To speed up your build include only the arch you need by adding e.g. a `-Parm64` option to the gradle build command (other options are `-Parm32` for _armeabi-v7a_, `-Px64` for _x86_64_ and `-Px86` for _x86_).
To create separate APKs for all target arches add a `-PsplitAPK` option (by default all arches are combined in one "fat" APK).
Adding a `-Ppch` (use precompiled headers) option makes builds ~15% faster.
If building makes your computer slow and laggy, then try lowering the priority of the build process by adding a `--priority=low` option and/or add a `-Pnjobs=<N>` option to limit the number of parallel processes.
See also https://developer.android.com/studio/build/building-cmdline.
To add any of those options to in-studio builds list them in "Command-line Options" in "File > Settings... > Build, Execution, Deployment > Compiler"
#### Reduce resource usage
If you are low on RAM, disk space or traffic there are ways to reduce system requirements:
- exclude the `cpp` folder from indexing - if you do not make any work on the C++ code, this will greatly improve the start-up performance and the ram usage of Android Studio; Click on the `Project` tab on the left, find the `cpp` folder (should be next to the `java` folder), right click on it and select `Mark Directory as` -> `Excluded` (red folder icon), then restart Android Studio;
- in Android Studio enable "File > Power Save Mode";
- disable the "Android NDK Support" plugin in "Settings -> Plugins" completely and use another IDE (Visual Studio Code, Qt Creator, etc.) for editing C++ code instead;
- don't install Android Studio, run builds and emulator from command line (download [command line tools](https://developer.android.com/studio#command-line-tools-only) first and then use the [`sdkmanager`](https://developer.android.com/tools/sdkmanager) tool to install all required packages: `platform-tools`, `build-tools`, a [right version](#preparing-1) of `cmake`, maybe `emulator`...; then [set env vars](https://developer.android.com/tools#environment-variables));
- build only for target arches you actually need, e.g. `arm64`;
- for debugging use an older emulated device with low RAM and screen resolution, e.g. "Nexus S";
- make sure the emulator uses [hardware acceleration](https://developer.android.com/studio/run/emulator-acceleration);
- don't use emulator, debug on a hardware device instead.
#### Alternatives for working with C++ code
Android Studio has issues in parsing the C++ part of the project, please let us know if you know how to resolve it. As a workaround, for working C++ suggestions, you may use:
- [Qt Creator](https://www.qt.io/product/development-tools), see [setup/usage instructions](QT_CREATOR.md)
- [Xcode](https://developer.apple.com/xcode/)
- [CLion](https://www.jetbrains.com/clion/)
For Xcode it is required to run `cmake . -g Xcode` to generate project files, while CLion and QT Creator can import CMakeLists.txt.
#### Enable Vulkan Validation
1. Download Vulkan Validation Layers
```bash
./tools/android/download_vulkan_validation_layers.py
```
2. Set `enableVulkanDiagnostics=ON` in `gradle.properties`.
If you build the app from command line, the parameter can be passed via command line.
E.g.
```
./gradlew -Parm64 -PenableVulkanDiagnostics=ON runGoogleDebug
```
#### Enable tracing
1. Set `enableTrace=ON` in `gradle.properties`.
2. Follow the guide https://perfetto.dev/docs/quickstart/android-tracing to set-up Perfetto
Example of command line for running system tracing:
```
./record_android_trace -a app.organicmaps.debug -o trace_file.perfetto-trace -t 30s -b 64mb sched freq idle am wm gfx view binder_driver hal dalvik camera input res memory
```
## iOS app
### Preparing
Building CoMaps for iOS requires a Mac.
Ensure that you have at least 20GB of free space.
Perform the steps in [getting all sources](#getting-sources), including configuring the repository
Enroll in the [Apple Developer Program](https://developer.apple.com/programs/) (you can run CoMaps in Simulator without this step).
### Configuring Xcode
Set up your developer account and add certificates:
- Open Xcode.
- Click "Xcode" → "Preferences".
- Open "Account" tab.
- Enter account credentials from the previous step.
- Click "Manage Certificates".
- Click "+" and choose "Apple Development".
- You may also need to register your Mac in your Apple Developer account.
Reconfigure the project to use your developer signing keys:
- Open `xcode/CoMaps.xcworkspace` in Xcode.
- Click on the "Maps" project and select the "CoMaps" target.
- Open "Signing & Capabilities" tab.
- Choose a unique bundle identifier (not app.comaps.debug) and your team.
- Select "Automatically manage signing".
- Click on "CoMapsTests" target.
- Choose a unique bundle identifier based on the one you chose previously (e.g. app.comapsdev.tests) and your team.
- Click on "CoMapsWidgetExtension" target.
- Choose a unique bundle identifier based on the one you chose previously (e.g. app.comapsdev.debug.widgetextension) and your team.
If you want to run CoMaps on a real device, you have to remove the CarPlay entitlement. Open `iphone/Maps/CoMaps-Debug.entitlements`
and remove the `com.apple.developer.carplay-maps` entry. Now you can sign your app again in the "Signing & Capabilities" tab. Testing CarPlay
on a real device requires [requesting entitlements from Apple](https://developer.apple.com/documentation/carplay/requesting_carplay_entitlements).
### Building and running
Open `xcode/CoMaps.xcworkspace` in Xcode.
Select "CoMaps" product scheme.
- Choose "Your Mac (Designed for iPad)" to run on Mac without using Simulator.
- Choose either "iPhone _" or "iPad _" to run in the Simulator.
Compile and run the project ("Product" → "Run").
### CarPlay
To test CarPlay, simply select "I/O" → "External Displays" → "CarPlay" in the Simulator
### Spoofing GPS
The Simulator supports setting a specific location or spoofing a GPX track. This is especially handy when testing CarPlay
To select an Apple predetermined track or specific custom location, choose "Features" → "Location" in the Simulator
To simulate a custom GPX track use `python3 tools/python/ios_simulator_load_gpx.py <path to your gpx>` which is a wrapper for `xcrun simctl location`. Default values are 60 km/h and 0.1s update intervals, but can be customized
## Desktop app
See [install_desktop](INSTALL_DESKTOP.md) to install and build Desktop app for Linux and Mac OS
## Map data and styles
See readme for the [map generator](MAPS.md) and [styles](STYLES.md) if you need to customize the map files and styles.

304
docs/INSTALL_DESKTOP.md Normal file
View file

@ -0,0 +1,304 @@
## Desktop app
### Preparing
You need a Linux or a MacOS machine to build a desktop version of CoMaps. [Windows](#windows) users can use the [WSL](https://learn.microsoft.com/en-us/windows/wsl/) (Windows Subsystem for Linux) and follow ["Linux or Mac"](#linux-or-mac) steps described below.
### Linux or MacOS
Ensure that you have at least 20GB of free space.
Install Cmake (**3.22.1** minimum), Boost, Qt 6 and other dependencies.
Installing *ccache* can speed up active development.
#### Ubuntu
##### Fully supported versions
_Ubuntu 24.04 or newer:_
```bash
sudo apt update && sudo apt install -y \
build-essential \
clang \
cmake \
ninja-build \
python3 \
qt6-base-dev \
qt6-positioning-dev \
libc++-dev \
libfreetype-dev \
libglvnd-dev \
libgl1-mesa-dev \
libharfbuzz-dev \
libicu-dev \
libqt6svg6-dev \
libqt6positioning6-plugins \
libqt6positioning6 \
libsqlite3-dev \
libxrandr-dev \
libxinerama-dev \
libxcursor-dev \
libxi-dev \
python3-protobuf \
zlib1g-dev
```
##### Workarounds for older Ubuntu versions
| Software | Minimum version | Impacted Ubuntu release | Workaround |
| --------- | --------------- | ----------------------- | ----------------------------------------------------------- |
| CMake | `3.22.1` | `20.04` and older | Install newer `cmake` from [PPA](https://apt.kitware.com/) or from `snap`<br> with `sudo snap install --classic cmake` |
| FreeType | `2.13.1` | `22.04` and older | Install newer `libfreetype6` and `libfreetype-dev` from [PPA](https://launchpad.net/~reviczky/+archive/ubuntu/freetype) |
| GeoClue | `2.5.7` | `20.04` and older | Install newer `geoclue-2.0` from [PPA](https://launchpad.net/~savoury1/+archive/ubuntu/backports) |
| Qt 6 | `6.4.0` | `22.04` and older | Build and install Qt 6.4 manually |
```bash
sudo add-apt-repository -y ppa:savoury1/qt-6-2
```
#### Linux Mint
Check which Ubuntu version is the `PACKAGE BASE` for your Linux Mint release [here](https://www.linuxmint.com/download_all.php),
and apply the [Ubuntu workarounds accordingly](#workarounds-for-older-ubuntu-versions).
#### Fedora
```bash
sudo dnf install -y \
clang \
cmake \
ninja-build \
freetype-devel \
libicu-devel \
libstdc++-devel \
mesa-libGL-devel \
libglvnd-devel \
qt6-qtbase-devel \
qt6-qtpositioning \
qt6-qtpositioning-devel \
qt6-qtsvg-devel \
python3-protobuf \
sqlite-devel
```
#### Alpine
```bash
sudo apk add \
cmake \
freetype-dev \
g++ \
icu-dev \
mesa-gl \
ninja-build \
qt6-qtbase-dev \
qt6-qtpositioning-dev \
qt6-qtsvg-dev \
samurai \
py3-protobuf \
sqlite-dev
```
#### macOS
```bash
brew install cmake ninja qt@6
pip3 install "protobuf<3.21"
```
### Windows
We haven't compiled CoMaps on Windows *natively* in a long time, somes adaptations is required to support Windows.
You'll need to have python3, cmake, ninja, and QT6 in the PATH, and Visual Studio 2022 or Visual Studio 2022 Build Tools installed. Use [Visual Studio Developer Command Prompt](https://learn.microsoft.com/en-us/visualstudio/ide/reference/command-prompt-powershell?view=vs-2022) or generate Visual Studio project files with CMake to build the project.
However, it is possible to use the WSL (Windows Subsystem for Linux) to run GUI applications.
#### Windows 11 (WSL)
To run Linux GUI apps, you'll need to [install a driver](https://learn.microsoft.com/en-us/windows/wsl/tutorials/gui-apps) matching your system. This enables a virtual GPU allowing hardware-accelerated OpenGL rendering.
- [Intel GPU Driver](https://www.intel.com/content/www/us/en/download/19344/intel-graphics-windows-dch-drivers.html)
- [AMD GPU Driver](https://www.amd.com/en/support)
- [NVIDIA GPU Driver](https://www.nvidia.com/Download/index.aspx?lang=en-us)
Once a GPU driver is installed and you have [built the app](#building-1) you should be able to [run](#running) it without any additional steps.
#### Windows 10 (WSL)
For Windows 10 you should do these steps (taken from [here](https://techcommunity.microsoft.com/t5/windows-dev-appconsult/running-wsl-gui-apps-on-windows-10/ba-p/1493242), check this blog post if you have any problems):
1. Download and install [VcXsrv Windows X Server](https://sourceforge.net/projects/vcxsrv/).
2. Run _XLaunch_ app to launch X Server. During settings make sure "Disable access control" checkbox is selected.
3. (optionally) Click "Save configuration" and save configuration to some file (for example to _config.xlaunch_). With this you will be able to quickly run the desktop app in the future.
4. When asked about firewall, allow access for both public and private networks.
5. Add this line:
```bash
export DISPLAY=$(ip route|awk '/^default/{print $3}'):0.0
```
to _/etc/bash.bashrc_ file.
6. Restart WSL.
Now when you want to run the desktop app you just need to first launch the X Server on Windows (for example, by running previously saved _config.xlaunch_ file) and then you should be able to [build](#building-1) and [run](#running) the app from WSL.
Running X Server is also required to run `generate_symbols.sh` script when you change icons for [styles](STYLES.md)
### Building
To build a desktop app:
```bash
tools/unix/build_omim.sh -r desktop
```
The output binary will go into `../omim-build-release`.
Check `tools/unix/build_omim.sh -h` for more build options, e.g. to build a debug version.
Besides _desktop_ there are other targets like _generator_tool_, to see a full list execute:
```bash
tools/unix/build_omim.sh -d help
```
#### Build issues
- If you get "not enough memory" errors during builds, you may disable
[CMake Unity Builds](https://cmake.org/cmake/help/latest/prop_tgt/UNITY_BUILD.html) by passing
`-DCMAKE_UNITY_BUILD=OFF` option to `cmake` invocation. Or you can reduce Unity build batch size from
the default `24` to a lower value (`2`-`16`) by passing `-DCMAKE_UNITY_BUILD_BATCH_SIZE=8`.
Note that these changes may significantly increase the full build time.
### Running
The generated binaries appear in `../omim-build-<buildtype>`.
A desktop app binary is `CoMaps`. To run e.g. a release version:
_Linux:_
```bash
../omim-build-release/CoMaps
```
_macOS:_
```bash
../omim-build-release/CoMaps.app/Contents/MacOS/CoMaps
```
### Testing
Compile all unit tests in Debug mode:
```bash
cmake . -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug
cmake --build build --target all
```
Run all unit tests:
```bash
cd build
ctest -L "omim-test" --output-on-failure
```
To run a limited set of tests, use `-R <regex>` flag. To exclude some tests, use `-E <regex>` flag:
```bash
cd build
ctest -R "base_tests|coding_tests" --output-on-failure
ctest -L "omim-test" -E "base_tests|coding_tests" --output-on-failure
```
Some tests are known to be broken and disabled on CI.
### Test Coverage
To generate a test coverage report you'll need [gcovr](https://gcovr.com) and gcov tools installed.
Installing gcovr on Linux:
```bash
pip3 install gcovr
```
Installing gcovr on MacOS:
```bash
brew install gcovr
```
Installing gcov on Linux:
```bash
# If you're using GCC compiler
sudo apt-get install cpp
# If you're using Clang compiler
sudo apt-get install llvm
```
Installing gcov on MacOS:
```bash
# If you're using AppleClang compiler it should already be installed
# If you're using Clang compiler
brew install llvm
```
Steps to generate coverage report:
1. Configure cmake with `-DCOVERAGE_REPORT=ON` flag:
```bash
cmake . -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_CXX_FLAGS=-g1 -DCOVERAGE_REPORT=ON
```
2. Compile unit tests.
3. Run unit tests.
4. Run coverage report generation:
```bash
cd build
cmake --build . --target omim_coverage
```
5. Report can be found in the `build/coverage_report` folder.
### Debug commands
CoMaps has some "hidden" debug commands that you can trigger by entering them into the search box.
For example you can switch theme which is very useful for checking [styles](STYLES.md) changes.
There are also other commands for turning on/off isolines, anti-aliasing, etc. Check [DEBUG_COMMANDS.md](DEBUG_COMMANDS.md) to learn about them.
### Debugging in an IDE
To harness the power of an IDE for debugging, you can set up [Qt Creator](QT_CREATOR.md) to work with CoMaps code. This gives you options such as setting breakpoints, examining variables while the code is running, examining call stacks and using debugging tools such as Valgrind.
### More options
To make the desktop app display maps in a different language add a `-lang` option, e.g. for the Russian language:
```bash
../omim-build-release/CoMaps -lang ru
```
By default `CoMaps` expects a repository's `data` folder to be present in the current working directory, add a `-data_path` option to override it.
Check `CoMaps -help` for a list of all run-time options.
When running the desktop app with lots of maps, increase the open files limit. In MacOS the default value is only 256.
Use `ulimit -n 2000`, put it into `~/.bash_profile` to apply it to all new sessions.
In MacOS to increase this limit globally, add `limit maxfiles 2048 2048` to `/etc/launchd.conf`
and run
```bash
echo 'ulimit -n 2048' | sudo tee -a /etc/profile
```
If you have Qt installed in an unusual directory, use `QT_PATH` variable (`SET (QT_PATH "your-path-to-qt")`). You can skip building tests
with `CMAKE_CONFIG=-DSKIP_TESTS` variable. You would need 1.5 GB of memory
to compile the `stats` module.
The `build_omim.sh` script basically runs these commands:
```bash
cmake <path_to_omim> -DCMAKE_BUILD_TYPE={Debug|Release}
<make or ninja> [<target>] -j <number_of_processes>
```

11
docs/JAVA_STYLE.md Normal file
View file

@ -0,0 +1,11 @@
# Java Style Guide
The Android app follows the style defined in `android/config/AndroidStudioCodestyle.xml`. Code not respecting this style will not be accepted and you will be asked by reviewers to edit your PR.
## Importing the style in Android Studio
You can import this configuration file in Android Studio to allow automatically formatting Java files. When Android Studio is open, go to `File -> Settings` then open the section `Editor -> Code Style -> Java`. Here click on the gear icon next to the dropdown at the top of the page and select `Import Scheme...`. Select `android/config/AndroidStudioCodestyle.xml` and press `OK` in the next dialog.
## Formatting a file
Before making a commit, please reformat your files using `Code -> Reformat File`. In the opening dialog, select the scope `Only VCS changed text` and tick all the optional checkbox (optimize imports, rearrange code and code cleanup).

1
docs/MAPS.md Normal file
View file

@ -0,0 +1 @@
Please refer to maps_generator tool [instructions](../tools/python/maps_generator/README.md).

413
docs/OBJC_STYLE.md Normal file
View file

@ -0,0 +1,413 @@
# Objective-C Style Guide
## Credits
This styleguide is base on [raywenderlich.com Objective-C Style Guide](https://github.com/raywenderlich/objective-c-style-guide) .
## Background
Here are some of the documents from Apple that informed the style guide. If something isn't mentioned here, it's probably covered in great detail in one of these:
- [The Objective-C Programming Language](http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Introduction/introObjectiveC.html)
- [Cocoa Fundamentals Guide](https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CocoaFundamentals/Introduction/Introduction.html)
- [Coding Guidelines for Cocoa](https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CodingGuidelines/CodingGuidelines.html)
- [iOS App Programming Guide](http://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneosprogrammingguide/Introduction/Introduction.html)
## Language
US English should be used.
```objc
UIColor *myColor = [UIColor whiteColor];
```
## Code Organization
Use `#pragma mark -` to categorize methods in functional groupings and protocol/delegate implementations following this general structure.
```objc
#pragma mark - Lifecycle
- (instancetype)init {}
- (void)dealloc {}
- (void)viewDidLoad {}
- (void)viewWillAppear:(BOOL)animated {}
- (void)didReceiveMemoryWarning {}
#pragma mark - Custom Accessors
- (void)setCustomProperty:(id)value {}
- (id)customProperty {}
#pragma mark - IBActions
- (IBAction)submitData:(id)sender {}
#pragma mark - Public
- (void)publicMethod {}
#pragma mark - Private
- (void)privateMethod {}
#pragma mark - Protocol conformance
#pragma mark - UITextFieldDelegate
#pragma mark - UITableViewDataSource
#pragma mark - UITableViewDelegate
#pragma mark - NSCopying
- (id)copyWithZone:(NSZone *)zone {}
#pragma mark - NSObject
- (NSString *)description {}
```
## Spacing
- Indent using 2 spaces (this conserves space in print and makes line wrapping less likely). Never indent with tabs. Be sure to set this preference in Xcode.
- Method braces and other braces (`if`/`else`/`switch`/`while` etc.) always open on the same line as the statement but close on a new line.
```objc
if (user.isHappy) {
//Do something
} else {
//Do something else
}
```
- There should be exactly one blank line between methods to aid in visual clarity and organization. Whitespace within methods should separate functionality, but often there should probably be new methods.
- Prefer using auto-synthesis. But if necessary, `@synthesize` and `@dynamic` should each be declared on new lines in the implementation.
- Colon-aligning method invocation should often be avoided. There are cases where a method signature may have >= 3 colons and colon-aligning makes the code more readable. Please do **NOT** however colon align methods containing blocks because Xcode's indenting makes it illegible.
```objc
// blocks are easily readable
[UIView animateWithDuration:1.0 animations:^{
// something
} completion:^(BOOL finished) {
// something
}];
```
## Comments
When they are needed, comments should be used to explain **why** a particular piece of code does something. Any comments that are used must be kept up-to-date or deleted.
Block comments should generally be avoided, as code should be as self-documenting as possible, with only the need for intermittent, few-line explanations.
## Naming
Long, descriptive method and variable names are good.
```objc
UIButton *settingsButton;
```
A three letter prefix 'MWM' should be used for class names and constants.
Constants should be camel-case with all words capitalized and prefixed by the related class name for clarity.
```objc
static NSTimeInterval const MWMTransitionAnimationDuration = 0.3;
```
Properties should be camel-case with the leading word being lowercase. Use auto-synthesis for properties rather than manual @synthesize statements unless you have good reason.
```objc
@property(strong, nonatomic) NSString *descriptiveVariableName;
```
### Underscores
When using properties, instance variables should always be accessed and mutated using `self.`. This means that all properties will be visually distinct, as they will all be prefaced with `self.`.
An exception to this: inside initializers, the backing instance variable (i.e. \_variableName) should be used directly to avoid any potential side effects of the getters/setters.
Local variables should not contain underscores.
## Methods
In method signatures, there should be a space after the method type (-/+ symbol). There should be a space between the method segments (matching Apple's style). Always include a keyword and be descriptive with the word before the argument which describes the argument.
The usage of the word "and" is reserved. It should not be used for multiple parameters as illustrated in the `initWithWidth:height:` example below.
```objc
- (void)setExampleText:(NSString *)text image:(UIImage *)image;
- (void)sendAction:(SEL)aSelector to:(id)anObject forAllCells:(BOOL)flag;
- (id)viewWithTag:(NSInteger)tag;
- (instancetype)initWithWidth:(CGFloat)width height:(CGFloat)height;
```
## Variables
Variables should be named as descriptively as possible. Single letter variable names should be avoided except in `for ()` loops.
Asterisks indicating pointers belong with the variable, e.g., `NSString *text` not `NSString* text` or `NSString * text`, except in the case of constants.
[Private properties](#private-properties) should be used in place of instance variables whenever possible. Although using instance variables is a valid way of doing things, by agreeing to prefer properties our code will be more consistent.
Direct access to instance variables that 'back' properties should be avoided except in initializer methods (`init`, `initWithCoder:`, etc…), `dealloc` methods and within custom setters and getters. For more information on using Accessor Methods in Initializer Methods and dealloc, see [here](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.html#//apple_ref/doc/uid/TP40004447-SW6).
```objc
@interface MWMUser : NSObject
@property(copy, nonatomic) NSString *userName;
@end
```
## Property Attributes
Property attributes should be explicitly listed, and will help new programmers when reading the code.
```objc
@property(strong, nonatomic) IBOutlet UIView *containerView;
@property(strong, nonatomic) NSString *userName;
```
Properties with mutable counterparts (e.g. NSString) should prefer `copy` instead of `strong`.
Why? Even if you declared a property as `NSString` somebody might pass in an instance of an `NSMutableString` and then change it without you noticing that.
```objc
@property(copy, nonatomic) NSString *userName;
```
## Dot-Notation Syntax
Dot syntax is purely a convenient wrapper around accessor method calls. When you use dot syntax, the property is still accessed or changed using getter and setter methods. Read more [here](https://developer.apple.com/library/ios/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html)
Dot-notation should **always** be used for accessing and mutating properties, as it makes code more concise. Bracket notation is preferred in all other instances.
```objc
NSInteger arrayCount = [self.array count];
view.backgroundColor = [UIColor orangeColor];
[UIApplication sharedApplication].delegate;
```
## Literals
`NSString`, `NSDictionary`, `NSArray`, and `NSNumber` literals should be used whenever creating immutable instances of those objects. Pay special care that `nil` values can not be passed into `NSArray` and `NSDictionary` literals, as this will cause a crash.
```objc
NSArray *names = @[@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul"];
NSDictionary *productManagers = @{@"iPhone": @"Kate", @"iPad": @"Kamal", @"Mobile Web": @"Bill"};
NSNumber *shouldUseLiterals = @YES;
NSNumber *buildingStreetNumber = @10018;
```
## Constants
Constants are preferred over in-line string literals or numbers, as they allow for easy reproduction of commonly used variables and can be quickly changed without the need for find and replace. Constants should be declared as `static` constants and not `#define`s unless explicitly being used as a macro.
```objc
static NSString * const MWMApplicationName = @"maps.me";
static CGFloat const MWMButtonWidth = 50.0;
```
## Enumerated Types
When using `enum`s, it is recommended to use the new fixed underlying type specification because it has stronger type checking and code completion. The SDK now includes a macro to facilitate and encourage use of fixed underlying types: `NS_ENUM()`
```objc
typedef NS_ENUM(NSUInteger, MWMMyPositionMode) {
MWMMyPositionModePendingPosition,
MWMMyPositionModeNotFollowNoPosition,
MWMMyPositionModeNotFollow,
MWMMyPositionModeFollow,
MWMMyPositionModeFollowAndRotate
};
```
You can also make explicit value assignments (showing older k-style constant definition):
```objc
typedef NS_ENUM(NSUInteger, DurationInHours) {
One = 1,
Two = 2,
Six = 6,
Twelve = 12,
Day = 24
};
```
Older k-style constant definitions should be **avoided** unless writing CoreFoundation C code (unlikely).
## Case Statements
Braces are not required for case statements, unless enforced by the complier.
When a case contains more than one line, braces should be added.
```objc
switch (condition) {
case 1:
// ...
break;
case 2: {
// ...
// Multi-line example using braces
break;
}
case 3:
// ...
break;
default:
// ...
break;
}
```
## Private Properties
Private properties should be declared in class extensions (anonymous categories) in the implementation file of a class. Named categories (such as `MWMPrivate` or `private`) should never be used unless extending another class. The Anonymous category can be shared/exposed for testing using the <headerfile>+Private.h file naming convention.
```objc
@interface MWMPlacePageViewController ()
@property(strong, nonatomic) GADBannerView *googleAdView;
@property(strong, nonatomic) ADBannerView *iAdView;
@property(strong, nonatomic) UIWebView *adXWebView;
@end
```
## Booleans
Objective-C uses `YES` and `NO`. Therefore `true` and `false` should only be used for CoreFoundation, C or C++ code. Since `nil` resolves to `NO` it is unnecessary to compare it in conditions. Never compare something directly to `YES`, because `YES` is defined to 1 and a `BOOL` can be up to 8 bits.
This allows for more consistency across files and greater visual clarity.
```objc
if (someObject) {}
if (![anotherObject boolValue]) {}
```
If the name of a `BOOL` property is expressed as an adjective, the property can omit the “is” prefix but specifies the conventional name for the get accessor, for example:
```objc
@property (assign, getter=isEditable) BOOL editable;
```
Text and example taken from the [Cocoa Naming Guidelines](https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CodingGuidelines/Articles/NamingIvarsAndTypes.html#//apple_ref/doc/uid/20001284-BAJGIIJE).
## Conditionals
Conditional bodies should always use braces even when a conditional body could be written without braces (e.g., it is one line only) to prevent errors. These errors include adding a second line and expecting it to be part of the if-statement. Another, [even more dangerous defect](http://programmers.stackexchange.com/a/16530) may happen where the line "inside" the if-statement is commented out, and the next line unwittingly becomes part of the if-statement. In addition, this style is more consistent with all other conditionals, and therefore more easily scannable.
```objc
if (!error) {
return success;
}
```
### Ternary Operator
The Ternary operator, `?:` , should only be used when it increases clarity or code neatness. A single condition is usually all that should be evaluated. Evaluating multiple conditions is usually more understandable as an `if` statement, or refactored into instance variables. In general, the best use of the ternary operator is during assignment of a variable and deciding which value to use.
Non-boolean variables should be compared against something, and parentheses are added for improved readability. If the variable being compared is a boolean type, then no parentheses are needed.
```objc
NSInteger value = 5;
result = (value != 0) ? x : y;
BOOL isHorizontal = YES;
result = isHorizontal ? x : y;
```
## Init Methods
Init methods should follow the convention provided by Apple's generated code template. A return type of 'instancetype' should also be used instead of 'id'.
```objc
- (instancetype)init {
self = [super init];
if (self) {
// ...
}
return self;
}
```
See [Class Constructor Methods](#class-constructor-methods) for link to article on instancetype.
## Class Constructor Methods
Where class constructor methods are used, these should always return type of 'instancetype' and never 'id'. This ensures the compiler correctly infers the result type.
```objc
@interface Airplane
+ (instancetype)airplaneWithType:(RWTAirplaneType)type;
@end
```
More information on instancetype can be found on [NSHipster.com](http://nshipster.com/instancetype/).
## CGRect Functions
When accessing the `x`, `y`, `width`, or `height` of a `CGRect`, always use the [`CGGeometry` functions](https://developer.apple.com/documentation/coregraphics/cggeometry) instead of direct struct member access. From Apple's `CGGeometry` reference:
> All functions described in this reference that take CGRect data structures as inputs implicitly standardize those rectangles before calculating their results. For this reason, your applications should avoid directly reading and writing the data stored in the CGRect data structure. Instead, use the functions described here to manipulate rectangles and to retrieve their characteristics.
```objc
CGRect frame = self.view.frame;
CGFloat x = CGRectGetMinX(frame);
CGFloat y = CGRectGetMinY(frame);
CGFloat width = CGRectGetWidth(frame);
CGFloat height = CGRectGetHeight(frame);
CGRect frame = CGRectMake(0.0, 0.0, width, height);
```
## Golden Path
When coding with conditionals, the left hand margin of the code should be the "golden" or "happy" path. That is, don't nest `if` statements. Multiple return statements are OK.
```objc
- (void)someMethod {
if (![someOther boolValue]) {
return;
}
//Do something important
}
```
## Error handling
When methods return an error parameter by reference, switch on the returned value, not the error variable.
```objc
NSError *error;
if (![self trySomethingWithError:&error]) {
// Handle Error
}
```
Some of Apples APIs write garbage values to the error parameter (if non-NULL) in successful cases, so switching on the error can cause false negatives (and subsequently crash).
## Line Breaks
Line length should not exceed 120 characters.
For example:
```objc
[MWMPushNotifications application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
```
If a method declaration/call does not fit on a single line, put each parameter on its own line
```objc
[MWMPushNotifications application:application
didReceiveRemoteNotification:userInfo
fetchCompletionHandler:completionHandler];
```
## Objective-C and C++
In general, C++ should be avoided in iOS-specific code. C++ can only be used when you need to call our Core API. In this case you should create some adapter classes which will work with both Objective-C and Swift. If .mm file contains C++ class, all code inside that class should be formatted according to [C++ coding style](CPP_STYLE.md), even if it contains Objective-C code lines.
C++ can't be used in Objective-C header files.

69
docs/PR_GUIDE.md Normal file
View file

@ -0,0 +1,69 @@
# Pull Request Guidelines
This document gives some guidelines to write and review PR with essential elements.
## Writing a Pull Request (PR):
- A PR should have a reasonable size and reflect only one idea, a feature, a bugfix, or a refactoring. This helps to review and limit regressions in the app
- If you want to work on more than one feature/bug/refactoring at once, please create separate PRs for these.
- New functionality and unit or integration tests for it should be developed in the same PR
- Every commit of all PRs should be compilable under all platforms and all tests should pass. If changes break unit or integration tests, then these tests should be fixed, ideally before opening a PR.
- Every commit should reflect a completed idea and have an understandable comment. Review fixes should be merged into one commit
- All commits and PR captions should be written in English.
- We suggest PRs should have prefixes in square brackets depending on the changed subsystem. For example, [routing], [generator], or [android]. Commits may have several prefixes (See `git log --oneline|egrep -o '\[[0-9a-z]*\]'|sort|uniq -c|sort -nr|less` for ideas.)
- Use imperative mood in commit's message, e.g. `[core] Fix gcc warnings` not `[core] Fixed gcc warnings`
- When some source files are changed and then some other source files based on them are auto-generated, they should be committed in different commits. For example, if you change style (mapcss) files, then put auto-generated files into a separate [styles] Regenerate commit
- All code bases should conform to ./docs/CPP_STYLE.md, ./docs/OBJC_STYLE.md, ./docs/JAVA_STYLE.md or other style in ./docs/ depending on the language
- The description field of every PR should contain a description to explain **what and why** vs. how.
- If your changes are visual (e.g. app UI or map style changes) then please add before/after screenshots or videos.
- Link Codeberg issues into the description field, [See tutorial](https://forgejo.org/docs/latest/user/linked-references/)
## Review a Pull Request (PR):
- We expect all comments to be polite, including for PR reviews. For PRs feedback should also only concern the PR
- It's better to ask the developer to make the code simpler or add comments to the codebase than to understand the code through the developer's explanation
- If a developer changes the PR significantly, the reviewers who have already approved the PR should be informed about these changes
- A reviewer should pay attention not only to the code base but also to the description of the PR and commits
- We prefer PRs to be approved by at least two reviewers. To have a different vision about how the feature/bugs are implemented or fixed, to help to find bugs and test the PR
- If a reviewer doesn't have time to review all the PR they should write about it explicitly. For example, LGTM for android part
- If a reviewer and a developer cannot find a compromise, a third opinion should be sought
- A PR which should not be merged after review should be marked as a draft.
### Reviewing pull requests of first-time contributors
First-time contributors are likely to be less familiar with both the project code but also the way CoMaps as a community operates.
Some of them might also not be too familiar with using git (e.g. for rebasing branches or signing DCOs).
For those reasons they might require more effort from reviewers.
At the same time, new contributors are the lifeblood that keeps CoMaps sustainable by ensuring that enough people are contributing code. For that reason, it's important to help those newcomers in their on-boarding.
To help newcomers in feeling welcome and getting onboarded, some suggestions for what to include:
- Thank the contributor for opening a PR (they volunteered time to help the project! And offering code to a new community can be nerve-wrecking.)
- Where applicable:
* Notes on how to sign the DCO/rebase commits
* The necessary constructive feedback if there are things that need to be improved before a PR can be merged
- Give the contributor another thank you for their effort, signal that the community is open for helping further (e.g. on Codeberg and link to Matrix/TG/Zulip)
Here's a small template that can help writing feedback to first-time contributors:
> Thank you so much for this contribution - and welcome to CoMaps!
>
> For CoMaps, we use the [_Developers Certficate of Origin_](https://codeberg.org/comaps/comaps/src/branch/main/docs/DCO.md) for contributors to certify that they wrote/have the right to submit their code to our project. This helps ensure that CoMaps can remain open source as it gives us some legal protection. You can sign it by signing your commit. The easiest way is to amend your existing commit with `git commit -s -m 'your commit message'`. If you are using the Codeberg interface you can also sign your commit by selection _"Add a Signed-off-by trailer by the committer at the end of the commit log message."_.
>
> If you haven't yet, you could also add yourself to our [CONTRIBUTOR](https://codeberg.org/comaps/comaps/src/branch/main/CONTRIBUTORS) file with your name or pseudonym if you want (that would also give you a chance to sign the commit if needed).
> There are a few things that could help improve your PR/would need to be fixed / I have a few questions about… (the actual PR feedback)
>
> I hope that helps! If anything is unclear, please don't hesitate to get in touch on here, or reach out via our chat channels. You can find most of us [on different Matrix/Telegram channels](https://codeberg.org/comaps/Governance/wiki/Chat-rooms) or [on our contributor Zulip](https://comaps.zulipchat.com/join/e5e3c4zurmfxykrtbiiq6qrw/).
>
> Thanks again for putting this PR together!
## Recommendations for making PRs:
- Functions and methods should not be long. In most cases, it's good if the whole body of a function or method fits on the monitor. It's good to write a function or a method shorter than 60 lines
- If you are solving a big task it's worth splitting it into subtasks and developing one or several PRs for every subtask.
- In most cases refactoring should be done in a separate PR
- If you want to refactor a significant part of the codebase, it's worth discussing it with all developers in an issue before starting work
- It's worth using the 'Resolve' conversation button to minimize the list of comments in a PR

147
docs/QT_CREATOR.md Normal file
View file

@ -0,0 +1,147 @@
# Qt Creator
As mentioned in [Building](INSTALL.md), there are several IDEs which can be used for CoMaps development. At the time of this writing, Qt Creator is the only FOSS IDE known to work with the CoMaps C++ codebase.
Qt Creator supports C++, JavaScript, Python and QML, but it lacks support for Java and Swift. A workaround is to use Qt Creator for core development, including testing the desktop version, and a different IDE (e.g. Android Studio, Xcode) for languages not supported by Qt Creator.
Running a project from Qt Creator requires three things:
* A build configuration, telling Qt Creator how to build the artifact we want to run
* A deployment method, telling Qt Creator how and where to deploy the build artifact to the environment where it is going to run (default is to deploy locally, i.e. run artifacts from wherever the build job places them)
* A run configuration, telling Qt Creator what to run and how
Before we get there, however, we need to create a new project in Qt Creator and import the code.
## Import the code
The first step is to create a new project in Qt Creator and import the code.
Start Qt Creator. In the Welcome screen, click **New Project**.
In the dialog, select **Import Project** in the left column and **Import Existing Project** in the middle column, then click **Choose...**.
In the **Location** step of the wizard dialog, enter a name for the project (e.g. `comaps`) and choose the root folder of the CoMaps source code. Click **Next**.
In the **Files** step of the wizard dialog, accept the default settings by clicking **Next**.
In the **Project Management** step, choose **None** for version control (to keep the Qt Creator project files out of git). Click **Finish**.
## Set up build configurations
Next, we need to tell Qt Creator how to build the artifacts.
* In the mode selector (top part of the pane on the left), click **Projects**.
* On the left side of the content area, in the **Build & Run** section, click **Build**.
You can now modify the existing build configuration, or add new ones. The default build configuration is not very helpful, therefore it is safe to mess with or just delete.
The build configuration for a release version of CoMaps (Linux desktop) is as follows:
* Generic Manager:
* Build directory: the directory where the CoMaps source code resides, e.g. `/home/user/src/comaps`.
* Build Steps:
* Custom Process Step:
* Command: `./tools/unix/build_omim.sh`
* Arguments: `-r desktop`
* Working directory: `%{buildDir}` (default value)
* Clean Steps:
* Custom Process Step:
* Command: `./tools/unix/build_omim.sh`
* Arguments: `-r clean`
* Working directory: `%{buildDir}` (default value)
* Build Environment:
* Use System Environment (default). If you need some specific environment variables, you can set them here.
This can easily be adapted to any other artifact which can be built with `build_omim.sh`. Simply change the arguments in the custom process step in Build Steps. For example, `-d desktop` would produce a debug version of the desktop app.
Qt Creator defines some variables which can be used in paths and command lines, both in build and run configurations. When editing one of the values (the cursor must be in the respective field), click the icon in the right corner of the control to get a list of variables that can be used. Some particularly useful ones:
* `%{Env:HOME}`: Home dir (on Linux this makes use of system environment variables)
* `%{sourceDir}`: Root directory of the source code
* `%{buildDir}`: Build directory, where build artifacts will be placed
## Set up run configurations
Now we need to tell Qt Creator how to run the artifact we have built. This is very similar to setting up a build configuration.
The following example is for running the release version of CoMaps (Linux desktop):
* Run:
* Executable: the fully qualified path to the executable, e.g. `/home/user/src/omim-build-release/CoMaps`.
* Command line arguments: supply as needed
* Working directory: `%{buildDir}` (default value) should be OK for most cases. This would be the directory from which you run the executable; `%{buildDir}` is the build dir from the build configuration.
* Run in terminal: usually not needed (even for console applicatons), unless your application expects user input on the console. (Console output will be available in the IDE.)
* Run Environment:
* Use Build Environment should work for most cases.
* Debugger Settings:
* Enable C++: enabled (default) you will probably want this
* Enable QML: leave disabled for now
* Valgrind Settings: leave default for now (unless you are familiar with Valgrind and are planning on using it)
* QML Profiler Settings: leave default for now (unless you are familiar with QML Profiler and are planning on using it)
## Run, debug or build
Click the kit selector (screen icon in the lower half of the pane on the left, below the mode selector) to select your build, deployment and run configurations.
Using the three buttons below the kit selector, you can now run, debug or build the artifact you selected.
The output pane at the bottom of the screen lets you view results of the process:
* Issues: errors and warnings from the build process
* Compile Output: the entire console output from the build process
* Application Output: console output from the application
## Beyond the basics
### Building artifacts with CMake
If you want to build an artifact with CMake, heres how. The following example is for building `traff_assessment_tool` (a tool on the `traffic` branch). It uses a build dir named `build`, which must be created beforehand, in your CoMaps source dir. Then set up a build configuration as follows:
* Generic Manager:
* Build directory: the directory where the CoMaps source code resides, e.g. `/home/user/src/comaps`.
* Build Steps:
* Custom Process Step:
* Command: `cmake`
* Arguments: `. -B build`
* Working directory: `%{buildDir}` (default value)
* Custom Process Step:
* Command: `cmake`
* Arguments: `--build build --target traff_assessment_tool`
* Working directory: `%{buildDir}` (default value)
* Clean Steps:
* Custom Process Step:
* Command: `cmake`
* Arguments: `--target clean`
* Working directory: `%{buildDir}` (default value)
* Build Environment:
* Use System Environment (default), see above
### Using Valgrind
Qt Creator comes with support for [Valgrind](https://www.valgrind.org/), a powerful and useful tool when you need to track down issues related to memory access.
Especially when you encounter sporadic issues that are difficult to reproduce reliably, it is highly recommended you run your code through the Valgrind suite to rule out faulty memory access or race conditions as the culprit.
Valgrind needs to be installed separately, preferably from packages (under Linux) or from the website.
Qt Creator comes with default settings for Valgrind, which should work for most use cases.
To use Valgrind, click **Debug** in the pane on the left. In the debug view, in the pane below the code editor window, choose the debugging tool you want to use:
* Memcheck: detects issues related to memory access (accessing uninitialized memory, using memory that has already been freed memory, or accessing memory beyond what has been allocated).
* Callgrind: a call graph analyzer, examines calling relationships between functions.
To start a debugging session, click the debug button (green arrow with a bug) **in the debug pane, next to the drop-down box not in the left pane** (although both look the same, the button in the left pane will start the normal debugger, not the tool you have chosen).
Be aware that Valgrind runs code in its own virtual machine, which considerably slows down execution. Even without any checks, code takes about 45 times as long to execute as it would normally.
The debug view also offers other tools, which are not part of Valgrind.
Valgrind also includes Helgrind, which is useful in detecting race conditions between threads, typically when there is an issue with thread synchronization. However, Qt Creator has no native support for running Helgrind from the IDE as of 2025. There is a [feature request](https://bugreports.qt.io/browse/QTCREATORBUG-25838) for it, which also describes a workaround:
* Run Helgrind from the command line with `--xml=yes --xml-file=helgrind.xml` (this logs output to an XML file)
* In the Qt Creator debugger pane, select **Memcheck** and click **Load External XML Log File** (open folder icon), then load `helgrind.xml`.
This may still fail, as Helgrind output is somewhat different from Memcheck output.
Of course, you can always run Helgrind from the command line in the standard way, without using the IDE.

View file

@ -0,0 +1,75 @@
# Release Management
## Apple App Store
### Upload metadata and screenshots to the App Store
Use [Forgejo Actions](../.forgejo/workflows/ios-release.yaml).
### Check metadata
Use [Forgejo Actions](../.forgejo/workflows/ios-check.yaml).
Local check:
```bash
./tools/python/check_store_metadata.py ios
```
### Downloading screenshots from the App Store
Get xcode/keys/appstore.json - App Store API Key.
Get screenshots/ - a repository with screenshots.
Download metadata:
```bash
cd xcode
./fastlane download_metadata
```
Download screenshots:
```bash
cd xcode
./fastlane download_screenshots
```
## Google Play
### Upload metadata and screenshots to Google Play
Use [Forgejo Actions](../.forgejo/workflows/android-release-metadata.yaml).
### Uploading a new version to Google Play
Use [Forgejo Actions](../.forgejo/workflows/android-release.yaml).
Promote version to "Production" manually in Google Play Console.
### Uploading a new version to Huawei AppGallery
Use [Forgejo Actions](../.forgejo/workflows/android-release.yaml).
### Checking metadata
Use [Forgejo Actions](../.forgejo/workflows/android-check.yaml).
Checking locally:
```bash
./tools/python/check_store_metadata.py android
```
### Downloading metadata and screenshots from Google Play
Get `android/google-play.json` - Google Play API Key.
Get `screenshots/` - a repository with screenshots.
Download metadata:
```bash
./tools/android/download_googleplay_metadata.sh
```

6
docs/ROADMAP.md Normal file
View file

@ -0,0 +1,6 @@
# Roadmap
## Milestones
Milestones define when an issue, pull request, and/or roadmap item is to be completed. Issues are the what, milestones are the when. Development is complex therefore roadmap items can move between milestones depending on the remaining development and testing required to release a change.
[View active milestones](https://codeberg.org/comaps/comaps/milestones).

117
docs/STRUCTURE.md Normal file
View file

@ -0,0 +1,117 @@
# Directories Structure
## Platforms
- `android/` - Android UI.
- `iphone/` - iOS UI.
- `xcode/` - XCode workspace.
- `qt/` - desktop application.
## Data
`data/` folder contains data files for the application: maps, styles, country borders, etc.:
- `benchmarks/` -
- `borders/` - polygons describing countries' borders.
- `conf/isolines/` - per-country isoline profiles.
- `vulkan_shaders/` -
- `countries.txt` - map files hierarchy and checksums.
- `countries_meta.txt` - country/region languages and driving sides.
- `hierarchy.txt` - countries/map regions hierarchy, languages used and Wikidata IDs.
- `faq.html` - FAQ text displayed in the "?"/Help screen.
- `copyright.html` - attributions to 3rd-party libraries, map data, icons, fonts.
- `minsk-pass.mwm`,`minsk-pass.osm.bz2` - a small map used for tests.
There are some other files not mentioned here.
### Map features / classificator
- `mapcss-mapping.csv` - mapping between OSM tags and CoMaps types.
- `replaced_tags.txt` - merging similar OSM tags.
- `mixed_tags.txt` - pedestrian streets of high popularity.
- `editor.config` - built-in OSM data editor configuration (editable POIs, their attributes, etc.).
- `config.xsd` - XML schema for `editor.config`.
Automatically generated:
- `classificator.txt` - hierarchical list of all CoMaps types.
- `types.txt`
### Styles and icons
- `symbols/` - symbols for different screen DPIs
- `symbols/default/` - default resources used on all sceen DPIs
- `symbols-svg/` - social networks icons
- `search-icons/svg/` - source SVG files for search categories icons
- `styles/` - map [style files](STYLES.md#files)
Automatically [generated](STYLES.md#technical-details):
- `symbols/` - icons skin files in various resolutions for `dark` and `light` themes.
- `drules_proto*` - binary drawing rules files.
- `colors.txt`,`patterns.txt`,`visibility.txt`
### Strings and translations
[Translation files](TRANSLATIONS.md#translation-files):
- `strings/`
- `categories.txt`,`categories_cuisines.txt`,`categories_brands.txt`,`countries_names.txt`
Misc strings:
- `countries_synonyms.csv` - alternative country names.
- `synonyms.txt` - country and region names abbreviations and short names.
- `languages.txt` - native language names.
Automatically [generated](TRANSLATIONS.md#technical-details):
- `countries-strings/` - country and map region names JSON localization files.
- `sound-strings/` - Text-To-Speech JSON localization files.
## Tools
- `tools/` - various scripts for building packages and maps, testing, managing translations etc.
- `generator/` - map building tool.
- `poly_borders/` - borders post-processing tool.
- `skin_generator/` - a console app for building skin files with icons and symbols.
- `topography_generator/` - generates isolines from SRTM data.
- `track_generator/` - generates smooth tracks based on waypoints from KML.
## C++ Core
- `3party/` - external libraries, sometimes modified.
- `base/` - some base things, like macros, logging, caches etc.
- `cmake/` - CMake helper files.
- `coding/` - I/O classes and data processing.
- `descriptions/` -
- `dev_sandbox/` - developer tool for debugging rendering.
- `drape_frontend/` - scene and resource manager for the Drape library.
- `drape/` - the new graphics library core.
- `editor/` - built-in OSM data editor.
- `feature_list/` -
- `ge0/` - external API of the application.
- `geometry/` - geometry primitives we use.
- `indexer/` - processor for map files, classificator, styles.
- `kml/` - manipulation of KML files.
- `map/` - app business logic, including a scene manager.
- `openlr/` -
- `packaging/` - packaging specs for various distributions.
- `platform/` - platform abstraction classes: file paths, http requests, location services.
- `pyhelpers/` -
- `qt_tstfrm/` - widgets for visual testing.
- `routing_common/` -
- `routing/` - in-app routing engine.
- `search/` - ranking and searching classes.
- `shaders/` - shaders for rendering.
- `std/` - standard headers wrappers, for Boost, STL, C-rt.
- `storage/` - map reading function.
- `testing/` - common interfaces for tests.
- `track_analyzing/` -
- `tracking/` -
- `traffic/` - real-time traffic information.
- `transit/` - experimental GTFS-based public transport support.
## Documentation
The main docs are in the `docs/` directory, however some tools have their own READMEs, etc.

113
docs/STYLES.md Normal file
View file

@ -0,0 +1,113 @@
# Map styling and icons
Here is the basic workflow to update styles:
1. Edit the styles file you want, e.g. [`Roads.mapcss`](../data/styles/default/include/Roads.mapcss)
2. Rebuild the app or run the `tools/unix/generate_drules.sh` script
3. Test how your changes look in the app
4. Commit your edits
5. Send a pull request!
Please prepend `[styles]` to your commit message and add [Developers Certificate of Origin](CONTRIBUTING.md#legal-requirements) to it.
Please check [a list of current styling issues](https://codeberg.org/comaps/comaps/issues?q=&type=all&sort=&labels=410439)
and ["icons" issues](https://codeberg.org/comaps/comaps/issues?q=&type=all&sort=&labels=446883).
An overview of currently used icons can be found in the [Wiki](https://codeberg.org/comaps/comaps/wiki/Icons).
## Requirements
To work with styles first [clone the CoMaps repository](INSTALL.md#getting-sources).
Install a `protobuf` python package with `pip`
```
pip install "protobuf<3.21"
```
or with your OS package manager, e.g for Ubuntu
```
sudo apt install python3-protobuf
```
To run the `generate_symbols.sh` script, you need to install `optipng`, e.g. for Ubuntu
```
sudo apt install optipng
```
If you use WSL on Windows 10 you might need to run [X Server](INSTALL.md#windows-10-wsl) before running `generate_symbols.sh`
## Files
Map styles are defined in text files located in `data/styles/default/include/`:
* Forests, rivers, buildings, etc. [`Basemap.mapcss`](../data/styles/default/include/Basemap.mapcss)
* Their text labels [`Basemap_label.mapcss`](../data/styles/default/include/Basemap_label.mapcss)
* Roads, bridges, foot and bicycle paths, etc. [`Roads.mapcss`](../data/styles/default/include/Roads.mapcss)
* Their text labels [`Roads_label.mapcss`](../data/styles/default/include/Roads_label.mapcss)
* Icons for POIs and other features [`Icons.mapcss`](../data/styles/default/include/Icons.mapcss)
* City-specific subway networks [`Subways.mapcss`](../data/styles/default/include/Subways.mapcss)
* Light (default) theme colors: [`light/colors.mapcss`](../data/styles/default/light/colors.mapcss)
* Dark/night theme colors: [`dark/colors.mapcss`](../data/styles/default/dark/colors.mapcss)
* Priorities of overlays (icons, captions..) [`priorities_4_overlays.prio.txt`](../data/styles/default/include/priorities_4_overlays.prio.txt)
* Priorities of lines and areas [`priorities_3_FG.prio.txt`](../data/styles/default/include/priorities_3_FG.prio.txt), [`priorities_2_BG-top.prio.txt`](../data/styles/default/include/priorities_2_BG-top.prio.txt), [`priorities_1_BG-by-size.prio.txt`](../data/styles/default/include/priorities_1_BG-by-size.prio.txt)
There is a separate set of these style files for the navigation mode in `data/styles/vehicle/`.
Icons are stored in [`data/styles/default/light/symbols/`](../data/styles/default/light/symbols/) and their dark/night counterparts are in [`data/styles/default/dark/symbols/`](../data/styles/default/dark/symbols/).
## How to add a new icon
1. Add an svg icon to `data/styles/default/light/symbols/` (and to `dark` too)
preferably look for icons in [collections CoMaps uses already](../data/copyright.html#icons)
2. Add icon rendering/visibility rules into `data/styles/default/include/Icons.mapcss` and to "navigation style" `data/styles/vehicle/include/Icons.mapcss`
3. Rebuild the app
* Or run `tools/unix/generate_symbols.sh` to add new icons into skin files and `tools/unix/generate_drules.sh` to generate drawing rules for the new icons
5. [Test](#testing-your-changes) your changes
## How to add a new map feature / POI type
1. Add it into `data/mapcss-mapping.csv` (or better replace existing `deprecated` line) to make CoMaps import it from OSM
2. If necessary merge similar tags in via `data/replaced_tags.txt`
3. Define a priority for the new feature type in e.g. [`priorities_4_overlays.prio.txt`](../data/styles/default/include/priorities_4_overlays.prio.txt) and/or other priorities files
4. Add a new icon (see [above](#how-to-add-a-new-icon)) and/or other styling (area, line..)
5. If a new POI should be OSM-addable/editable then add it to `data/editor.config`
6. Add the English string (and optionally translations e.g. for your native language) into iOS and Android type strings
e strings
7. Add search keywords into `data/categories.txt`
8. Add new or fix current classifier tests at `generator/generator_tests/osm_type_tests.cpp` if you can
9. [Test](#testing-your-changes) your changes
10. Relax and wait for the next maps update :)
## Testing your changes
The most convenient way is using [the desktop app](INSTALL.md#desktop-app).
(there is a "Designer" version of it also, which facilitates development
by rebuilding styles and symbols quickly, but it's broken as of now, please help fix it!)
To test on Android or iOS device either re-build the app or put
the compiled style files (e.g. `drules_proto_default_light.bin`) into
a `styles/` subfolder of maps directory on the device
(e.g. `Android/data/app.comaps/files/styles/`).
Changing display zoom level for features (e.g. from z16- to z14-) might
not take effect until map's visibility/scale index is rebuilt:
1. [Build](INSTALL.md#desktop-app) the `generator_tool` binary
2. Put a map file, e.g. `Georgia.mwm` into the `data/` folder in the repository
3. Run
```
../omim-build-release/generator_tool --generate_index=true --output="Georgia"
```
4. The index of `Georgia.mwm` will be updated in place
A whole map needs to be [regenerated](MAPS.md) for the changes to take effect if:
* the visibility change crosses a geometry index boundary
* e.g. `area` style rules are added for a feature that didn't have them before
* a new feature type is added or the mapping of existing one is changed
## Technical details
Map style files syntax is based on [MapCSS/0.2](https://wiki.openstreetmap.org/wiki/MapCSS/0.2),
though the specification is not supported in full and there are CoMaps-specific extensions to it.
The `tools/unix/generate_drules.sh` script uses a customized version of [Kothic](https://codeberg.org/comaps/kothic)
stylesheet processor to compile MapCSS files into binary drawing rules files `data/drules_proto*.bin`.
The processor also produces text versions of these files (`data/drules_proto*.txt`) to ease debugging.
The `tools/unix/generate_symbols.sh` script assembles all icons into skin files in various resolutions (`data/resources-*/symbols.png` and `symbols.sdf`).

62
docs/SUBWAY_GENERATION.md Normal file
View file

@ -0,0 +1,62 @@
# Subway layer generation
For the subway layer to be available in CoMaps, a `SUBWAY_URL`
parameter ought to be provided to the
[map generator](https://codeberg.org/comaps/comaps/src/branch/main/tools/python/maps_generator).
Normally you can specify this link https://cdn.comaps.app/subway.json,
which provides a regularly updated file.
These instructions describe how to manually build a subway layer file.
Japan is used as target country but any other region from one city to the
whole planet is also applicable.
1. Make sure you have an \*.o5m file with the region. As an option, you can
download the region in \*.osm.pbf format and convert it to \*.o5m:
```bash
wget https://download.geofabrik.de/asia/japan-latest.osm.pbf
osmconvert japan-latest.osm.pbf -o=japan.o5m --drop-version
```
If you already have some not too outdated \*.o5m version, it is enough
because the subway generation script will update it with `osmupdate`.
1. With the [CoMaps subways](https://codeberg.org/comaps/subways) repository deployed,
run `scripts/process_subways.sh` bash script or prepare your own script
which launches `process_subways.py` and `validation_to_html.py` scripts
with suitable options.
1. Analyse the HTML output obtained at the previous step. Broken transport
networks won't be included into the map.
1. Run `tools/python/transit/transit_graph_generator.py` from the repository root.
The last three steps may be expressed as the following shell script:
```bash
#!/usr/bin/env bash
set -e
REPO="/path/to/cloned/repo"
export PLANET="/path/to/japan.o5m"
export OSMCTOOLS="/path/to/osmctools/dir"
export HTML_DIR="/generated/html/target/dir"
export PYTHON=python36
export TMPDIR="/tmp"
# Set non-empty string for the script to update validator code from git repository
export GIT_PULL=
export JSON=$TMPDIR/omaps_osm_subways.json
# Set DUMP variable if YAML files needed.
#export DUMP="$HTML_DIR"
# Put city/country name to CITY variable if not all networks needed.
# The default source of available cities/countries you may find at subways repository README.
#export CITY="Germany"
bash -x "$REPO/subways/scripts/process_subways.sh"
TRANSIT_MAPS=${JSON%".json"}.transit.json
cd "$REPO/tools/python/transit"
"$PYTHON" transit_graph_generator.py "$JSON" "$TRANSIT_MAPS"
```
It is the `$TRANSIT_MAPS` file that can be fed to the map generator via `SUBWAY_URL` parameter.

214
docs/SWIFT_STYLE.md Normal file
View file

@ -0,0 +1,214 @@
# Swift Style Guide
## Background
This is the style guide for the Swift programming language. You can find more about the language in the [Swift Language Reference](https://www.swift.org/documentation/tspl/). If you are not clear about how something should be done and it's not especially mentioned here, it's general good practice to follow the style used by Apple.
## Legacy Code
There is some existing legacy code where the style is clearly a bit different. In those files the style already used there should be continued to be used. Don't reorganize or reformat those files according to this style guide. The lack of documentation around it is generally a sign, that something is legacy code.
Of course use this style guide for all new files and methods and existing files and methods, which seem to follow this style guide.
## Language
US English should be used.
```swift
let color = "red"
```
## Documentation
The code should be documented following the [DocC](https://www.swift.org/documentation/docc/) documentation format. See the next point for an example.
When they are needed, comments should be used to explain **why** a particular piece of code does something. Any comments that are used must be kept up-to-date or deleted.
Block comments should generally be avoided, as code should be as self-documenting as possible, with only the need for intermittent, few-line explanations.
## Code Organization
Order imports alphabetically. Leave one free line after the imports.
Use structures instead of classes where possible.
Use extensions for conform to protocols. Leave three free lines between the original and each extension.
Properties and methods should be private by default and only allow more access, if actually necessary.
Use up to one free line inside properties, initalizers and methods to structure the code inside there.
## Sections
Use `// MARK: ` to categorize parts in functional sections and leave one free line below it. To separate extensions use `// MARK: -` without a free line below.
Leave always three free lines between sections.
The order of the sections is always as follows:
- Properties
- Initializers
- Methods
Leave always two lines between the items in a section.
In the properties section the order is always as follows:
- Static properties
- SwiftUI environment properties (`@Environment`)
- SwiftUI binding properties (`@Binding`)
- SwiftUI state properties (`@State`)
- All other properties
Properties other than SwiftUI environment properties should always declare their type.
In the methods section the order is always as follows:
- Static methods
- All other methods
```swift
import A
import B
/// The example for the Swift Style guide
struct Example {
// MARK: Properties
/// The text needed for the example
static let text: String = "Some text"
/// The number needed for the example
let number: Int = 1
// MARK: Initialization
/// Initalize the example with a given text
/// - Parameter text: The text
init(with text: String) {
self.text = text
}
// MARK: Methods
/// This adds an exclamation mark to some text
/// - Parameter text: The text
/// - Returns: The text with an exclamation mark at the end
func addExclamationMark(to text: String) -> String {
// Printing text for some manual debugging
print(text)
return text + "!"
}
}
// MARK: - `SomeProtocol`
extension Example: SomeProtocol {
// MARK: Methods
/// Conform to some protocol
func conform() {
// Actually do something
}
}
```
## Spacing
Indent using 4 spaces. Never indent with tabs.
On empty lines there should be whitespace to the indentation level on which the actual code on the lines before and after starts.
Method braces and other braces (`if`/`else`/`switch`/`while` etc.) always open on the same line as the statement but close on a new line.
```swift
if user.isHappy {
//Do something
} else {
//Do something else
}
```
## Naming
Long, descriptive method and variable names are good.
Variables and methods should be camel-cased. Don't use underscores.
If possible, booleans should be named in a way indicating that they are a boolean like starting with `is`, `has`, `should` etc.
```swift
var descriptionOfThing: String? = nil
var isHappy: Bool = true
```
## Brevity
Don't use semicolons. Don't use parentheses around conditionals.
Other than with properties use type inferred context where it's possible.
Only use `self.` where it is absolutely necessary.
```swift
color = .red
```
## Optionals
Use Optionals to indicate a value is missing. So for example return `nil` instead of `""` in a method, which might return a text, or `nil` instead of `0` in a method, which might return a number.
## Conditionals
Conditional bodies should always use braces even when a conditional body could be written without braces (e.g., it is one line only) to prevent errors.
Combine multiple conditions with a comma when possible.
```swift
if !isError, hasHappened {
return success;
}
```
### Ternary Operator
The Ternary operator, `( ? : )` , should only be used when it increases clarity or code neatness. A single condition is usually all that should be evaluated. Evaluating multiple conditions is usually more understandable as an `if` statement. There might be exceptions in SwiftUI. In general, the best use of the ternary operator is during assignment of a variable and deciding which value to use.
Non-boolean variables should be compared against something, and parentheses are added for improved readability. If the variable being compared is a boolean type, then no parentheses are needed.
```swift
var result = isSmall ? 0 : 10
```
## SwiftUI
Always leave one free line between different objects.
### Modifiers
Modifiers in Swift UI should always be either at the same indentation level as the object they are attached to, if the object has a closure, or one level intended, if the object doesn't have an enclosure.
We would like the behaviour to be consistent in both cases, but the automatic formatter doesn't allow this at the moment.
There should be no free lines between modifiers.
```swift
Button {
someAction()
} label: {
Text("Title")
}
.font(.headline)
Text("Title")
.font(.headline)
```
## Automatic formatting
Xcode includes an automatic formatter, which can help with adhering to most of our rules. It can be invoked in Xcode via the menubar under `Editor`/`Structure`/`Format file with 'swift-format'`.

57
docs/TEAMS.md Normal file
View file

@ -0,0 +1,57 @@
# Teams
CoMaps is led by community contributors, with functional domains occasionally establishing or dissolving their leadership structures, formal or informal. This file outlines the functional project structure that has evolved over time. The current list of teams is available on [Codeberg]https://codeberg.org/org/comaps/teams).
## Members
- [@comaps/members](https://codeberg.org/org/comaps/teams/members)
Active contributors on different projects around CoMaps
## Owners
- [@comaps/owners](https://codeberg.org/org/comaps/teams/owners)
Owners of the CoMaps team and repositories on Codeberg
## Admins
- [@comaps/admins](https://codeberg.org/org/comaps/teams/admins)
- Administrators of different repositories on Codeberg
## Android
- [@comaps/android](https://codeberg.org/org/comaps/teams)
Android experts.
## iOS
- [@comaps/ios](https://codeberg.org/org/comaps/teams/ios)
iOS experts.
## C++
- [@comaps/cpp](https://codeberg.org/org/comaps/teams/cpp)
C++ experts.
## Server
- [@comaps/server](https://codeberg.org/org/comaps/teams/server)
Management of website server, generator server
## Web
- [@comaps/website](https://codeberg.org/org/comaps/teams/website)
Web development experts.
## Translations
- [@comaps/translations](https://codeberg.org/org/comaps/teams/translations)
Internationalization and localization.

25
docs/TESTING.md Normal file
View file

@ -0,0 +1,25 @@
# Testing
User testing is an important part of the pre-release process to make sure no bugs make it into the final release version.
You can install test builds, which are pre-release versions of our app, and try to find new bugs before they make it to more people. You should be aware though that those test builds can be more unstable and prone to errors than the released versions. So don't use those test builds, if you really need to rely on our app working as stable and bug-free as possible.
The main focus of testing those test builds should always be the newly introduced or changed parts.
[Finding and reporting other already existing bugs](https://codeberg.org/comaps/comaps/issues) of course is important too, but it is not the principal purpose of the test builds.
This is the process for the different platforms:
## Android
- A new Issue is created for every Android test build.
- The Issue includes the APK, that needs to be tested, and notes of what changed with this test build.
- Comments and problems found with the specific test build should be noted in the Issue.
- The existing test build Issue will be closed with a link to the new test build Issue, if a new test build becomes available.
- New test builds also usually get announced in the chats.
## iOS
- A new Issue is created for every iOS test build.
- The Issue includes the signup link for the TestFlight and notes of what changed with this test build.
- The available space for beta testers in TestFlight is limited and all spots might be filled already. We regularly remove inactive testers and sometimes add more spots though. So if the beta is full, maybe check again at some point later.
- Comments and problems found with the specific test build should be noted in the Issue.
- The existing test build Issue will be closed with a link to the new test build Issue, if a new test build becomes available.
- TestFlight normally notifies existing testers of a new test build and new test builds also usually get announced in the chats.

161
docs/TRANSLATIONS.md Normal file
View file

@ -0,0 +1,161 @@
# Translations
Translations are managed through [Codeberg Translate][codeberg_translate], which is based on Weblate. Please [contribute][contribute] translations via the [Codeberg Translate][codeberg_translate], and the system and maintainers will handle the rest.
## Components
The project consists of multiple components, each with its own translation files.
| Weblate Component | Description | Translation Files |
| --------------------------------------------------- | ---------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| [Android][android_weblate] | UI strings | [android/app/src/main/res/values\*/strings.xml][android_git] ([en][android_git_en]) |
| [Android feature types][android_typestrings_weblate]| Map feature types | [android/sdk/src/main/res/values\*/type_strings.xml][android_sdkstrings_git] ([en][android_typestrings_git_en])|
| [Android SDK][android_sdkstrings_weblate] | UI strings (system-level) | [android/sdk/src/main/res/values\*/strings.xml][android_sdkstrings_git] ([en][android_sdkstrings_git_en])|
| [iOS][ios_weblate] | UI strings | [iphone/Maps/LocalizedStrings/\*.lproj/Localizable.strings][ios_git] ([en][ios_git_en]) |
| [iOS Type Strings][ios_typestrings_weblate] | OpenStreetMap Types | [iphone/Maps/LocalizedStrings/\*.lproj/LocalizableTypes.strings][ios_git] ([en][ios_typestrings_git_en]) |
| [iOS Plurals][ios_plurals_weblate] | UI strings (plurals) | [iphone/Maps/LocalizedStrings/\*.lproj/Localizable.stringsdict][ios_git] ([en][ios_plurals_git_en]) |
| [iOS Plist][ios_plist_weblate] | UI strings (system-level) | [iphone/Maps/LocalizedStrings/\*.lproj/InfoPlist.strings][ios_git] ([en][ios_plist_git_en]) |
| [TTS][tts_weblate] | Voice announcement strings for navigation directions (TTS) | [data/sound-strings/\*.json][tts_git] ([en][tts_git_en]) |
| [Countries][countries_weblate] | Country names for downloader | [data/countries-strings/\*.json][countries_git] ([en][countries_git_en]) |
| [Search keywords](https://translate.codeberg.org/projects/comaps/search-synonyms-aliases/) | Search keywords/aliases/synonyms | [data/categories-strings/](https://codeberg.org/comaps/comaps/src/branch/main/data/categories-strings) |
| Search keywords (cuisines) | Search keywords for cuisine types | [data/categories_cuisines.txt][categories_cuisines_git] |
| [AppStore Descriptions][appstore_weblate] | AppStore descriptions | [iphone/metadata][appstore_git] ([en][appstore_git_en]) |
| [Android Stores Descriptions][googleplay_weblate] | Google, Huawei store descriptions | [android/app/src/google/play/listings][googleplay_git] ([en][googleplay_git_en]) |
| [F-Droid Descriptions][fdroid_weblate] | F-Droid descriptions | [android/app/src/fdroid/play/listings][fdroid_git] ([en][fdroid_git_en]) |
| [Website][website_weblate] | Website content | [comaps/website][website_git] ([see details][website_guide]) |
Components without links haven't been integrated into Weblate and must be translated directly via [Codeberg Pull Requests](CONTRIBUTING.md).
## Translating
### Workflow
Translations are managed through [Codeberg Translate][codeberg_translate]. Direct submissions to this repository are not recommended but possible in specific cases (like batch-changes). Please prefer using the Weblate for translations whenever possible. Weblate periodically creates pull requests, which [@comaps/mergers][mergers] review and merge as usual.
### Cross-Component Synchronization
Android and iOS share most of the strings. Codeberg Translate automatically syncs translations between components (e.g., from Android to iOS and vice versa), so updating a string in one place is usually sufficient.
### Categories strings
Search categories synonyms/aliases usually shouldn't be just direct translations from English, but rather adaptations - e.g. some specific terms could be used in your language to search for a certain feature and they might not have English equivalents.
Some translations are borrowed from the common category (`@` in the key). Please do not duplicate translations if a category in the key already includes it.
Syntax:
- | - used to separate synonyms.
- 1-9 - digits in front of a synonym indicate the number of symbols that need to be
typed in a search query to make this synonym appear in the list of suggestions.
Located immediately at the start of a synonym. At most one
digit per synonym is allowed.
It's possible to use emoji codes as search synonyms, e.g. U+1F6B0 for potable water.
For all languages with nominative and gentive cases (e.g. Slavic languagues like Russian,
Ukrainian, Belarus, Serbian), state _short_ nouns in nominative and genitive case, e.g. `Вино|вина`,
so that both (e.g. Russian) searches for "вино" and "магазин вина" returns wine shops.
For longer nouns (6 letters or longer) this is not necessary, because error correction
can fix 1 or 2 letters, e.g `Мебель`
Searcing for "магазин мебели" will also match the category name (1 letter difference).
Exact treshold may be different for different languages. For Serbian, error correction
kicks in only for 8-letter or longer words.
## Machine Translation
Codeberg Translate is configured to generate machine translations using the best available tools. Auto-translated entries are added as suggestions.
### Failing checks
Please review any issues flagged by automated checks, such as missing placeholders, inconsistencies, and other potential errors. Use the filter [`has:check AND state:>=translated language:de`][failing_checks], replacing `de` with your target language.
## Developing
### Workflow
Translations are handled by the translation team via [**Codeberg Translate**][codeberg_translate], with no direct developer involvement required. Developers are only responsible for adding English base strings to the source file (see [Components](#components)). Codeberg Translate manages the rest. If you're confident in a language, feel free to contribute translations, but please avoid adding machine translations or translating languages you are not familiar with.
### Tools
Android developers can utilize the built-in features of Android Studio to add and modify strings efficiently. iOS developers are advised to edit `Localizable.strings` as a text file, as Xcodes interface only supports "String Catalog," which is not currently in use. JSON files can be modified using any text editor. To ensure consistency, always follow the established structure and include a comment when adding new strings.
### Cross-Component Synchronization
When adding new strings, first check the base file of the component for existing ones. If no relevant strings are found, look for them on the corresponding platform (e.g., iOS when adding Android strings or vice versa). To maintain consistency across platforms, always reuse the existing string key from the other platform with the same English base string.
## Maintaining
## Under the Hood
Codeberg Translate maintains an internal copy of the Git repository. The repository URL can be found under _Manage → Repository Maintenance → Weblate Repository_. All components, except for the website, share the same internal Weblate repository.
Translations are extracted from the repository and stored in an internal database, which is used by the Weblate UI. Every 24 hours, this internal database is synchronized back to the internal repository. This process can also be triggered manually via _Manage → Repository Maintenance → Commit_.
Codeberg Translate has its own Git repository fork of both the website and the main Git repository for pushing translation commits and then creating pull requests (PRs) on Codeberg. After committing changes from the internal database to the internal repository, Codeberg Translate pushes all updates to the `weblate-comaps-<component>` branch (e.g. `weblate-comaps-android` for Android UI strings) of its forked repository and creates or updates a PR to `main` branch of the main repository. This operation can be manually triggered via _Manage → Repository Maintenance → Push_.
### Reviewing PRs
Translations are intended to be reviewed by the community on Codeberg Translate. However, if it's a user's first contribution or if there is any doubt, a quick scan and comparison with the English source can be useful.
It is recommended to add comments directly on Codeberg Translate, as translators primarily work within that platform. Since Codeberg Translate requires a Codeberg account, you may tag contributors in the pull request, but there is no guarantee that they will respond.
### Resolving Conflicts
The recommended approach for resolving conflicts is as follows:
1. Make sure [the translations on Weblate are actually locked](https://translate.codeberg.org/projects/comaps/#repository), this ensures that no more changes are done on Weblate while the conflict is being fixed. You will need to have the right Weblate permissions to do this.
2. Commit all changes from the _Weblate_ internal database to the Weblate-internal Git repository, the steps in the UI are: _Manage → Repository Maintenance → Commit (button)_. This ensures that all existing translations are in the Weblate-internal _Git_ repo. (this also requires the right Weblate permissions)
3. Now you can add the weblate-internal Git repo as a remote for your local repo: `git remote add weblate https://translate.codeberg.org/git/comaps/android/`. This step only needs to be done the first time you have to resolve a conflict
4. Make sure that your local main branch is at the latest remote state, e.g. by running `git checkout main; git pull`
5. Now you can fetch the current state of the _Weblate_ remote: `git fetch weblate`
6. To be able to rebase the Codeberg `main` into the Weblate one, you need to have an editable branch. You can create it using `git checkout -b resolve_translate weblate/main`. This creates a branch called `resolve_translate` off the Weblate remote, and also switches you to this newly created branch.
7. You can now run `git rebase main`, to rebase the branch and resolve any conflicts that are between the two. (**Note: Make sure to run this command from your `resolve_translate` branch**)
8. Once you have resolved the conflicts, you can push the `resolve_translate` branch to Codeberg: `git push`
9. Make a PR for merging your conflict-resolution-branch into `main` on Codeberg, and get it reviewed as usual
10. Once the PR is merged into `main` on Codeberg and the merge conflict is gone, you can now unlock the translations on Weblate again.
11. **Optionally if necessary**: If the conflict hasn't resolved through the steps, you can optionally reset the Weblate from the admin backend for the `website` component, this forces the current state from the Codeberg git repo into Weblate: _Manage → Repository Maintenance → Reset (button)_.
Using these steps all existing translations can still be kept and rebased into the repo, without losing work. The important bit is that you need to ensure that all translations are in the Weblate-internal git repository before you rebase, so that they get into the _actual_ Codeberg repo.
[codeberg_translate]: https://translate.codeberg.org/projects/comaps/
[contribute]: https://docs.weblate.org/en/latest/workflows.html
[android_weblate]: https://translate.codeberg.org/projects/comaps/android/
[android_git]: https://codeberg.org/comaps/comaps/src/branch/main/android/app/src/main/res
[android_git_en]: https://codeberg.org/comaps/comaps/src/branch/main/android/app/src/main/res/values/strings.xml
[android_typestrings_weblate]: https://translate.codeberg.org/projects/comaps/android-typestrings/
[android_typestrings_git_en]: https://codeberg.org/comaps/comaps/src/branch/main/android/sdk/src/main/res/values/types_strings.xml
[android_sdkstrings_weblate]: https://translate.codeberg.org/projects/comaps/android-ui-strings-sdk/
[android_sdkstrings_git]: https://codeberg.org/comaps/comaps/src/branch/main/android/sdk/src/main/res
[android_sdkstrings_git_en]: https://codeberg.org/comaps/comaps/src/branch/main/android/sdk/src/main/res/values/strings.xml
[countries_weblate]: https://translate.codeberg.org/projects/comaps/countries/
[countries_git]: https://codeberg.org/comaps/comaps/src/branch/main/data/countries-strings
[countries_git_en]: https://codeberg.org/comaps/comaps/src/branch/main/data/countries-strings/en.json/localize.json
[ios_weblate]: https://translate.codeberg.org/projects/comaps/ios/
[ios_git]: https://codeberg.org/comaps/comaps/src/branch/main/iphone/Maps/LocalizedStrings/
[ios_git_en]: https://codeberg.org/comaps/comaps/src/branch/main/iphone/Maps/LocalizedStrings/en.lproj/Localizable.strings
[ios_plist_weblate]: https://translate.codeberg.org/projects/comaps/ios-plist/
[ios_plist_git_en]: https://codeberg.org/comaps/comaps/src/branch/main/iphone/Maps/LocalizedStrings/en.lproj/InfoPlist.strings
[ios_typestrings_weblate]: https://translate.codeberg.org/projects/comaps/ios-typestrings/
[ios_typestrings_git_en]: https://codeberg.org/comaps/comaps/src/branch/main/iphone/Maps/LocalizedStrings/en.lproj/LocalizableTypes.strings
[ios_plurals_weblate]: https://translate.codeberg.org/projects/comaps/ios-plurals/
[ios_plurals_git_en]: https://codeberg.org/comaps/comaps/src/branch/main/iphone/Maps/LocalizedStrings/en.lproj/Localizable.stringsdict
[tts_weblate]: https://translate.codeberg.org/projects/comaps/tts/
[tts_git]: https://codeberg.org/comaps/comaps/src/branch/main/data/sound-strings
[tts_git_en]: https://codeberg.org/comaps/comaps/src/branch/main/data/sound-strings/en.json/localize.json
[categories_git]: https://codeberg.org/comaps/comaps/src/branch/main/data/categories.txt
[categories_cuisines_git]:https://codeberg.org/comaps/comaps/src/branch/main/data/categories_cuisines.txt
[website_weblate]: https://translate.codeberg.org/projects/comaps/website/
[website_git]: https://codeberg.org/comaps/website/
[website_guide]: https://codeberg.org/comaps/website/src/branch/main/TRANSLATIONS.md
[appstore_weblate]: https://translate.codeberg.org/projects/comaps/appstore-description
[appstore_git]: https://codeberg.org/comaps/comaps/src/branch/main/iphone/metadata
[appstore_git_en]: https://codeberg.org/comaps/comaps/src/branch/main/iphone/metadata/en-US
[googleplay_weblate]: https://translate.codeberg.org/projects/comaps/google-play-descriptions
[googleplay_git]: https://codeberg.org/comaps/comaps/src/branch/main/android/app/src/google/play/listings
[googleplay_git_en]: https://codeberg.org/comaps/comaps/src/branch/main/android/app/src/google/play/listings/en-US
[fdroid_weblate]: https://translate.codeberg.org/projects/comaps/fdroid-app-description
[fdroid_git]: https://codeberg.org/comaps/comaps/src/branch/main/android/app/src/fdroid/play/listings
[fdroid_git_en]: https://codeberg.org/comaps/comaps/src/branch/main/android/app/src/fdroid/play/listings/en-US
[mergers]: https://codeberg.org/org/comaps/teams
[failing_checks]: https://translate.codeberg.org/search/comaps/?q=has%3Acheck+AND+state%3A%3E%3Dtranslated+language%3Aru&sort_by=target&checksum=

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
docs/badges/codeberg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
docs/badges/fdroid.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
docs/badges/flathub.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
docs/badges/google-play.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
docs/badges/izzyondroid.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

5
docs/badges/logo.svg Normal file
View file

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1024" height="1024">
<circle fill="#588157" cx="512" cy="512" r="512"/>
<path fill="#ccdfca" d="M793 232.7a20 20 0 0 1 30.8-1.3A416 416 0 0 1 929.5 509a416 416 0 0 1-93.3 263 20 20 0 0 1-31.3-.6l-43-56.6a20 20 0 0 1-.2-24A307 307 0 0 0 821 509c0-74.2-26.2-142.3-69.9-195.6a20 20 0 0 1-.5-24.8zM355.2 548a20 20 0 0 1-7.7-36.7l282-177.4a20 20 0 0 1 29.9 22.7l-97 318.9a20 20 0 0 1-37.5 2.2l-49.2-111.5Z"/>
<path fill="#fefdf6" d="M720.8 844.6a20 20 0 0 1-6.2 29.6A417.7 417.7 0 0 1 94.5 509a417.7 417.7 0 0 1 603.3-373.9 20 20 0 0 1 7 30l-42.4 55.8a20 20 0 0 1-24.2 6.1 309 309 0 1 0 15.4 556.7 20 20 0 0 1 25.1 5.6z"/>
</svg>

After

Width:  |  Height:  |  Size: 672 B

BIN
docs/badges/obtainium.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View file

@ -0,0 +1,114 @@
Some of the project's librariers (traffic, search, kml and others) come
with python bindings, i.e. have some of their functions exposed to be
callable from the python programming language. The version of python
is not enforced, so some libraries may be using python 2 and some may
be using python 3.
This document describes how to build these python bindings.
Preparing source tree
---------------------
The CoMaps project comes with its own version of Boost (https://www.boost.org/)
in a submodule. You have to recursively update submodules before you start
building anything.
Ensure you have ran:
$ git submodule update --init --recursive
Building single pybinding module
--------------------------------
Find a correspoding module's setup.py.
Currently available modules and setup's:
| module | path to setup.py |
|-------------|----------------------------------------|
| pygen | generator/pygen/setup.py |
| pykmlib | kml/pykmlib/setup.py |
| pymvm_diff | generator/mwm_diff/pymwm_diff/setup.py |
| pysearch | search/pysearch/setup.py |
| pytracking | tracking/pytracking/setup.py |
| pytraffic | traffic/pytraffic/setup.py |
Run the chosen setup.py with Python you want to build binding for.
Examples:
$ python kml/pykmlib/setup.py build install --user
$ python3.6 generator/mwm_diff/pymwm_diff/setup.py bdist_wheel
During build, our setup.py will configure and build boost_python library for
needed Python version, configure omim, and build needed binding.
Building all pybindings modules
-------------------------------
Run generic pyhelpers/setup.py with needed Python. This will invoke build (or
other actions) for all pybindings.
Supported actions and options
-----------------------------
Please refer to setuptools/distutils documentation for description of all
available commands.
Main commands are:
build
install
bdist_wheel
Notable option for build command:
--omim-builddir [path to omim builddir]
It should be used to store build dir somewhere outside source tree. If not
specified, everything will be build in directory `build` from current
directory.
Complete wheels generation example:
$ python3.7 pyhelpers/setup.py build --omim-builddir ../omim-build/ bdist_wheel
This will create wheels for all pybindings in `../omim-build/pybindings-dist/`.
Pip installation
----------------
One can install pybinding straight from source:
$ pip install git+https://github.com/organicmaps/organicmaps.git@master#egg=pykmlib&subdirectory=kml/pykmlib
But this can be a long wait, it is better to use already compiled .whl
distribution.
Running and testing a pybinding
-------------------------------
Install your freshly built pybinding either with `setup.py install`, or by
installing .whl with `pip install`.
Run tests:
MWM_RESOURCES_DIR=data \
MWM_WRITABLE_DIR=data \
search/pysearch/run_search_engine.py
Problems and solutions
----------------------
1. Building bindings on MacOS Catalina 10.15.5.
If you try to build one of the bindings on MacOS Catalina with Apple clang
version 11.0.3 you'll see the error that the flag fcoalesce-templates is not
supported. The workaround is to remove this flag from
3party/boost/tools/build/src/tools/darwin.jam and
3party/boost/tools/build/src/tools/darwin.py
2. You may get build errors that standard C++ headers can't be found while
building of Boost.Python. For example, fatal error: 'cstddef' file not found.
In that case the following flags should be set to correct values:
MACOSX_DEPLOYMENT_TARGET, CC, CXX, CFLAGS. For example, instead of launching:
$ python3.7 kml/pykmlib/setup.py build --omim-builddir=kml/pykmlib/cmake-build-release
should be launched:
$ MACOSX_DEPLOYMENT_TARGET=10.9 CC=clang CXX=clang++ CFLAGS='-stdlib=libc++'
python3.7 kml/pykmlib/setup.py build --omim-builddir=kml/pykmlib/cmake-build-release

48
docs/feature_structure.md Normal file
View file

@ -0,0 +1,48 @@
[!NOTE]
This info might be outdated.
First byte:
- 0 - Amount of types (1-8, write as 0-7, 3 bits)
- 3 - Name
- 4 - Layer
- 5, 6 - Geometry type (point = 00, line = 01, area = 10)
- 7 - Bit indicating the presence of additional information:
- Point - rank (1 byte as the logarithm of population base 1.1);
- Line - road number (string);
- Area - house number (string, optimized for storing a two-digit number);
* Write types, name, layer, additional information, and point (for point type)
1 or 2 bytes of the next header (only for line and/or area objects):
* 4 bits for the number of internal points for a line object:
- 0 - geometry is extracted; read the offset mask and offsets;
- 2 - 0 bytes for the simplification mask;
- 3-6 - 1 byte for the simplification mask;
- 7-10 - 2 simplification mask bytes;
- 11-14 - 3 simplification mask bytes;
* 4 bits for the number of internal triangles for an area object:
- 0 - geometry is extracted; read the offset mask and offsets;
- \>0 - number of triangles in one strip (for multiple strips, geometry is extracted);
* 4 bits for the offset mask for line and area objects.
The offset mask determines the presence of extracted geometry for the i-th scale row (out of 4, according to the corresponding bit).
These 2 bytes may be located in one byte when the object is of one type or the geometry is not extracted.
In reality, this will be 2 bytes when the object is both line and area and has extracted geometry.
Following bytes:
* Write geometry ...
- Simplification mask for a line object (1-3 bytes):
The 1-byte simplification mask encodes the visibility of 4 points in 4 scale rows (2 bits per point), i.e.
equal to the scale row value from which the point is already visible.
- Array of geometry points (triangle strip) according to the known amount VarInt64
* ... or write the array of offsets to the extracted geometry (number taken from the offset mask)
Extracted geometry for a scale is representing a block:
- Size of the geometry in bytes
- Serialized VarInt64s by the number of bytes
For a line object, they represent an array of points.
For an area object, they represent the following sequences:
- Number of points on the strip
- The strip itself (array of points)

7
docs/workflows.md Normal file
View file

@ -0,0 +1,7 @@
# How works CI?
CI Codeberg is limited and cannot be used for now to build regularly apps and executes tests.
To limit regressions, we have enabled temporary Github CI on the [Github Mirror](https://github.com/comaps/comaps) to build Android and IOS app and execute linter each time we sync the mirror.
- [Android CI](https://github.com/comaps/comaps/actions/workflows/android-check.yaml)
- [IOS CI](https://github.com/comaps/comaps/actions/workflows/ios-check.yaml)