Organic Maps sources as of 02.04.2025 (fad26bbf22ac3da75e01e62aa01e5c8e11861005)

To expand with full Organic Maps and Maps.ME commits history run:
  git remote add om-historic [om-historic.git repo url]
  git fetch --tags om-historic
  git replace squashed-history historic-commits
This commit is contained in:
Konstantin Pastbin
2025-04-13 16:37:30 +07:00
commit e3e4a1985a
12931 changed files with 13195100 additions and 0 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. OM 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@organicmaps.app>.

75
docs/COMMIT_MESSAGES.md Normal file
View File

@@ -0,0 +1,75 @@
# How to write a commit message
Any commit needs a helpful message. Mind the following guidelines when committing to any of Organic Maps repositories at GitHub.
1. Separate subject from body with a blank line.
2. Limit the subject line to **72 characters**.
3. Prefix the subject line with a **subsystem name** in square brackets:
- [android]
- [ios]
- [qt]
- [search]
- [generator]
- [strings]
- [platform]
- [storage]
- [transit]
- [routing]
- [bookmarks]
- [3party]
- [docs]
- ...
- See `git log --oneline|egrep -o '\[[0-9a-z]*\]'|sort|uniq -c|sort -nr|less` for ideas.
4. Start a sentence with a capital letter.
5. Do not end the subject line with a period.
6. Do not put "gh-xx", "closes #xxx" in the subject line.
7. Use the imperative mood in the subject line.
- A properly formed Git commit subject line should always be able to complete
the following sentence: "If applied, this commit will _/your subject line here/_".
8. Wrap the body to **72 characters** or so.
9. Use the body to explain **what and why** vs. how.
10. Link GitHub issues on the last lines:
- [See tutorial](https://help.github.com/articles/closing-issues-via-commit-messages).
11. Use your real name and real email address.
- See also [Developer's Certificate of Origin](DCO.md)
A template:
```
[subsystem] Summarize in 72 characters or less
More detailed explanatory text, if necessary.
Wrap it to 72 characters or so.
In some contexts, the first line is treated as the subject of the
commit, and the rest of the text as the body.
The blank line separating the summary from the body is critical
(unless you omit the body entirely); various tools like `log`,
`shortlog` and `rebase` can get confused if you run the two together.
Explain the problem that this commit is solving. Focus on why you
are making this change as opposed to how (the code explains that).
Are there side effects or other unintuitive consequences of this
change? Here's the place to explain them.
Further paragraphs come after blank lines.
- Bullet points are okay, too.
- Typically a hyphen or asterisk is used for the bullet, preceded
by a single space, with blank lines in between, but conventions
vary here.
Fixes: #123
Closes: #456
Needed for: #859
See also: #343, #789
```
Based on [Tarantool Guidelines](https://www.tarantool.io/en/doc/latest/dev_guide/developer_guidelines/#how-to-write-a-commit-message).

17
docs/COMMUNICATION.md Normal file
View File

@@ -0,0 +1,17 @@
# Communication
## Telegram Channel
Please subscribe to our [Telegram Channel](https://t.me/OrganicMapsApp) for updates.
## Telegram Group
Please join our [Telegram Group](https://t.me/OrganicMaps) to discuss with other users.
## GitHub Discussions
If you have some ideas or want to request a new feature, please [start a discussion thread](https://github.com/organicmaps/organicmaps/discussions/categories/ideas).
## Code of Conduct
The Organic Maps community abides by the [CNCF code of conduct](CODE_OF_CONDUCT.md).

114
docs/CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,114 @@
# Contributing
Thank you for your interest in contributing to Organic Maps (OM)!
## How Can I Contribute?
- [Donate](https://organicmaps.app/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](#uiux-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](COMMUNICATION.md).
### Bug Reports and Feature Requests
[Submit an issue](https://github.com/organicmaps/organicmaps/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 Organic Maps 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. Your issue will be processed much
faster if you send it to <bugs@organicmaps.app>. Enabling logs in Organic Maps settings on Android
before sending the bug report also helps us a lot with debugging.
If your idea is very broad or raw then instead of a specific feature request consider [starting a discussion thread](https://github.com/organicmaps/organicmaps/discussions/categories/ideas).
### Translations
OM 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
Organic Maps has a strong focus on easy to use UI and smooth user experience. Feel free to join [UI/UX discussions](https://github.com/organicmaps/organicmaps/issues?q=is%3Aopen+is%3Aissue+label%3AUX) in relevant issues. Mockups are very welcome! Check some [existing designs](https://github.com/organicmaps/organicmaps/wiki/Design-Index).
If you're into graphic design then OM needs good, clear and free-to-use icons for hundreds of map features / POIs.
Check OM's [graphic resources and design guidelines](https://github.com/organicmaps/organicmaps/wiki#design) and existing [requests for icons](https://github.com/organicmaps/organicmaps/issues?q=is%3Aopen+is%3Aissue+label%3AIcons). 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 [styles requests](https://github.com/organicmaps/organicmaps/issues?q=is%3Aopen+is%3Aissue+label%3AStyles).
### 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://github.com/organicmaps/organicmaps/labels/Good%20first%20issue) to help you get started with simple tasks. If you want to focus on the most important issues, please check [this label](https://github.com/organicmaps/organicmaps/labels/Frequently%20Reported%20by%20Users) or our [Milestones](https://github.com/organicmaps/organicmaps/milestones).
**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.
While we strive to help onboard new developers we don't have enough time to guide everyone step-by-step and explain in detail how everything works (in many cases we have to study the code ourselves). You'll need to be largely self-sufficient, expect to read a lot of code and documentation.
- [Pull Request Guide](PR_GUIDE.md).
- [How to write a commit message](COMMIT_MESSAGES.md).
- [Directories structure](STRUCTURE.md)
- [C++ Style Guide](CPP_STYLE.md).
- [Java Style Guide](JAVA_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
- keeping [github issues](https://github.com/organicmaps/organicmaps/issues) in order (check for duplicates, organize, assign labels, link related issues, etc.)
- composing nice user-centric release notes and news items
- etc.
## Submitting your changes
All contributions to Organic Maps repositories should be submitted via
[Github pull requests](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork)
and signed-off with the [Developers Certificate of Origin](#legal-requirements).
Each pull request is reviewed by OM 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'
Use your real name or on some rare cases a company email address, but we
disallow pseudonyms or anonymous contributions.
### Code of Conduct
The OM community abides by the [CNCF code of conduct](CODE_OF_CONDUCT.md).

223
docs/CPP_STYLE.md Normal file
View File

@@ -0,0 +1,223 @@
# C++ Style Guide
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++20 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++20 except std::filesystem, std::to_chars & std::from_chars which are not fully supported on all platforms.
- We try to limit the usage of boost libraries which require linking (and prefer C++20 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. If one line `for` or `while` is combined with one line `if`, do use brackets for cycle.
- 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!**
## ClangFormat
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
## 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++20 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@organicmaps.app mailing list to ask all developers and bugs@organicmaps.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`

127
docs/CREDENTIALS.md Normal file
View File

@@ -0,0 +1,127 @@
This file contains a list of all sensitive credentials, access keys, authentication tokens, and security certificates used by CI/CD (Github Actions).
- [PRIVATE\_H](#private_h)
- [RELEASE\_KEYSTORE](#release_keystore)
- [SECURE\_PROPERTIES](#secure_properties)
- [FIREBASE\_APP\_DISTRIBUTION\_JSON](#firebase_app_distribution_json)
- [FIREBASE\_TEST\_LAB\_JSON](#firebase_test_lab_json)
- [GOOGLE\_SERVICES\_JSON](#google_services_json)
- [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)"
```
## FIREBASE_APP_DISTRIBUTION_JSON
Credentials for uploading betas to Google Firebase App Distribution.
```bash
gh secret set FIREBASE_APP_DISTRIBUTION_JSON --env beta --body "$(base64 < android/app/firebase-app-distribution.json)"
```
## FIREBASE_TEST_LAB_JSON
Credentials for using Firebase Test Lab ("Monkey").
```bash
gh secret set FIREBASE_TEST_LAB_JSON --env beta --body "$(base64 < android/app/firebase-test-lab.json)"
```
## GOOGLE_SERVICES_JSON
Credentials for using Firebase Crashlytics.
```bash
gh secret set GOOGLE_SERVICES_JSON --env beta --body "$(base64 < android/app/google-services.json)"
```
## 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://github.com/organicmaps/organicmaps/blob/master/CONTRIBUTORS) in your first PR.

72
docs/DEBUG_COMMANDS.md Normal file
View File

@@ -0,0 +1,72 @@
# Available debug commands
Organic Maps 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 Organic Maps.
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

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 Organic Maps 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 Organic Maps!
## 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

36
docs/GOVERNANCE.md Normal file
View File

@@ -0,0 +1,36 @@
# Governance
Organic Maps Project (organicmaps.app) is an open-source project.
## The Governing Board
The focus of the Governing Board is to assist and guide in the progress and development of Organic Maps, as well as to lead and promote Organic Maps.
The Governing Board is the governing body responsible for the overall oversight of the Organic Maps Project. The Board also has the responsibility to ensure the goals, brands, and marks of Organic Maps and community are protected. The Board serves as the final authority within the Organic Maps Project.
## Governing Board Responsibilities
- Guidance and leadership over the ultimate Project roadmap.
- Community outreach.
- Maintenance of health and viability of the community.
- Maintenance of a healthy and proactive relationship with the Project users and consider those needs and uses in decisions.
- Coordination of Project messaging.
- Overall Project leadership as the final escalation point for decisions.
- Trademark and brand oversight.
- Appointment of Board Chair.
- Appointment of new Board members.
- Re-appointment of Board members after 12 month term of service.
## Chair Responsibilities
- Organize and run the Board meetings.
- Be the coordinating and lead voice for the Project.
- Coordinate the Board to set direction and articulation thereof.
- Focus on helping the Board to reach consensus.
- Guide the Board in transparency and practicing the open source way in leadership and decision making.
## Current Sitting Board
- [Alexander Borsuk](https://github.com/biodranik)
- [Victor Govako](https://github.com/vng)
- [Roman Tsisyk](https://github.com/rtsisyk)

675
docs/INSTALL.md Normal file
View File

@@ -0,0 +1,675 @@
# Building
- [System requirements](#system-requirements)
- [Getting sources](#getting-sources)
- [Desktop](#desktop-app)
- [Android](#android-app)
- [iOS](#ios-app)
- [Map data and styles](#map-data-and-styles)
## System requirements
To build and run Organic Maps 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 5-10Gb of files.
For _Windows_ you need to have [Git for Windows](https://git-scm.com/download/win) installed and Git bash available in the PATH.
## Getting sources
First of all get the source code. The full Organic Maps sources repository is ~10Gb in size, there are various [clone options](#special-cases-options) to reduce the download size to suit your needs.
For _Windows_, 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_
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 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://github.com/organicmaps/organicmaps to fork the repository first and use your fork's URL in the command below)
```bash
git clone --recurse-submodules --shallow-submodules https://github.com/organicmaps/organicmaps.git
```
Go into the cloned repository:
```bash
cd organicmaps
```
Configure the repository (make sure you have a working C++ build environment):
(if you plan to publish the app privately in stores check [special options](#special-cases-options))
```bash
bash ./configure.sh
```
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++`
3. Run `./configure.sh` in WSL.
**Setup 2: Using Visual Studio Developer Command Prompt**
1. 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).
2. Run the following command and follow instructions:
```bash
"C:\Program Files\Git\bin\bash.exe" configure.sh # execute the script by using Developer Command Prompt
```
### 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.
- a `--depth=1` option to make a _shallow copy_ (and possibly a `--no-single-branch` to have all branches not just `master`), i.e. omit history while retaining current commits only (saves ~4.5Gb) - suitable for one-off builds.
If you mistakenly did a `git clone` without checking out submodules, you can run `git submodule update --init --recursive`. If you don't want to clone complete submodules, you can add `--depth=1` to the update command.
To be able to publish the app in stores e.g. in Google Play its necessary to populate some configs with private keys, etc.
Check `./configure.sh --help` to see how to copy the configs automatically from a private repository.
## Desktop app
### Preparing
You need a Linux or a MacOS machine to build a desktop version of Organic Maps. [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 \
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 \
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 \
sqlite-dev
```
#### macOS
```bash
brew install cmake ninja qt@6
```
### Windows
We haven't compiled Organic Maps on Windows *natively* in a long time, though it is possible.
Some files should be updated. There is a work in progress on [windows](https://github.com/organicmaps/organicmaps/tree/windows) branch.
Please contribute if you have time.
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) with `export UNITY_DISABLE=1`
or by passing `-DUNITY_DISABLE=1` option to `cmake` invocation. Or you can reduce Unity build batch size from
the default `50` to a lower value (`2`-`16`) with `export UNITY_BUILD_BATCH_SIZE=8`.
Note that these changes may significantly increase the build time.
### Running
The generated binaries appear in `../omim-build-<buildtype>`.
A desktop app binary is `OMaps`. To run e.g. a release version:
_Linux:_
```bash
../omim-build-release/OMaps
```
_macOS:_
```bash
../omim-build-release/OMaps.app/Contents/MacOS/OMaps
```
### 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](https://github.com/organicmaps/organicmaps/issues?q=is%3Aissue+is%3Aopen+label%3ATests) 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
Organic Maps 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.
To switch themes you can enter this commands:
- `?light` - Day theme
- `?dark` - Night theme
- `?vlight` - Day theme for vehicle navigation
- `?vdark` - Night theme for vehicle navigation
- `?olight` - Outdoors day theme
- `?odark` - Outdoors night theme
There are also other commands for turning on/off isolines, anti-aliasing, etc. Check [DEBUG_COMMANDS.md](DEBUG_COMMANDS.md) to learn about them.
### 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/OMaps -lang ru
```
By default `OMaps` expects a repository's `data` folder to be present in the current working directory, add a `-data_path` option to override it.
Check `OMaps -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>
```
## Android app
### Preparing
Linux, MacOS, or Windows should work to build Organic Maps 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_:
- `Debug` is a debug version with all checks enabled.
- `Beta` is a manual pre-release build for testing.
- `Release` is a fully optimized version for app stores.
- _Flavor_:
- `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 and no Google services).
- ...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!
```
Organic Maps 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 17 (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)
- [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 Organic Maps for iOS requires a Mac.
Ensure that you have at least 20GB of free space.
After [getting all sources](#getting-sources), please make sure that Command Line Tools are installed:
```bash
xcode-select --install
```
Then, install [Xcode](https://apps.apple.com/app/xcode/id497799835?mt=12) from the App Store.
Enroll in the [Apple Developer Program](https://developer.apple.com/programs/) (you can run Organic Maps 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/omim.xcworkspace` in Xcode.
- Click on "Maps" project.
- Open "Signing & Capabilities" tab.
- Choose a unique bundle identifier (not app.organicmaps.debug) and your team.
- Select "Automatically manage signing".
If you want to run Organic Maps on a real device, you have to remove the CarPlay entitlement. Open `iphone/Maps/OMaps-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/omim.xcworkspace` in Xcode.
Select "OMaps" 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").
## Map data and styles
See readme for the [map generator](https://github.com/organicmaps/organicmaps/blob/master/docs/MAPS.md) and [styles](https://github.com/organicmaps/organicmaps/blob/master/docs/STYLES.md) if you need to customize the map files and styles.

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](https://github.com/organicmaps/organicmaps/blob/master/docs/CPP_STYLE.md), even if it contains Objective-C code lines.
C++ can't be used in Objective-C header files.

46
docs/PR_GUIDE.md Normal file
View File

@@ -0,0 +1,46 @@
# Pull Request Guide
## Writing a good Pull Request (PR):
- A PR should be small and reflect only one idea, a feature, a bugfix, or a refactoring. In most cases, a PR of 100 lines or less is considered as a PR of normal size and a PR of 1000 lines as big one
- If a PR implements two different features, refactoring, or bugfixes, it should be split into several PRs
- The description field of every PR should contain a description, links to a ticket or/and links to the confluence
- If a PR implements a complex algorithm, the description should contain a link to the proof of the solution or a link to a trusted source
- All PRs should contain links to the corresponding tickets. The exception is refactoring if there's nothing to test after it. The reason for that is that every feature or bugfix should be tested by testers after it's implemented
- Every commit of all PRs should be compilable under all platforms. All tests should pass. So if changing of code breaks unit or integration tests these tests should be fixed in the same commit
- Every commit should reflect a completed idea and have an understandable comment. Review fixes should be merged into one commit
- New functionality and unit or integration tests for it should be developed in the same PR
- 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, one commit changes strings.txt and another one contains generated files
- Most commits and PRs should have prefixes in square brackets depending on the changed subsystem. For example, [routing], [generator], or [android]. Commits and PRs may have several prefixes
- A PR which should not be merged after review should be marked as a draft.
- All commits and PR captions should be written in English. PR description and PR comments may be written in other languages
- All PRs should be approved by at least two reviewers. There are some exceptions: (1) simple PRs to some tools or tests; (2) situation when it's impossible to find another competent reviewer. In any case a PR should be reviewed by at least one reviewer
- If somebody left a comment in PR the author should wait for their approval
## Doing good code review:
- All comments in PR should be polite and concern the PR
- If a reviewer criticizes a PR they should suggest a better solution
- Reviewer's solution may be rejected by the author if the review did not give arguments why it should be done
- Comments in PR should be not only about things which are worth redeveloping but about good designs as well
- It's better to ask the developer to make code simpler or add comments to the code base than to understand the code through the developer's explanation
- It's worth writing comments in PR which help the PR author to learn something new
- All code base should conform to ./docs/CPP_STYLE.md, ./docs/OBJC_STYLE.md, ./docs/JAVA_STYLE.md or other style in ./docs/ depending on the language
- Code review should be started as quick as possible after a PR is published. A reviewer should answer developer comments as quick as possible
- If a PR looks good to a reviewer they should approve this PR. It means the review is finished
- 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
- A PR may be merged by a reviewer if all the following items are fulfilled: (1) the PR isn't marked as a draft; (2) all reviewers which have started to review the PR, approved it; (3) all reviewers which are added as reviewers of the PR, have approved it
- 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
- All comments about blank lines should be considered as optional
## Recommendations:
- 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
- Source files should not be very long
- If you are solving a big task it's worth splitting it into subtasks and develop one or several PRs for every subtask.
- If it's necessary to make a big change list which should be merged to master at once, it's worth creating a branch and make PRs on it. Then to make PR with all commits of the branch to the master
- In most cases refactoring should be done in a separate PR
- If you want to refactor a significant part of the code base, it's worth discussing it with all developers before starting work
- It's worth using the 'Resolve' conversation button to minimize the list of comments in a PR

View File

@@ -0,0 +1,75 @@
# Release Management
## Apple App Store
### Upload metadata and screenshots to the App Store
Use [GitHub Actions](../.github/workflows/ios-release.yaml).
### Check metadata
Use [GitHub Actions](../.github/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 [GitHub Actions](../.github/workflows/android-release-metadata.yaml).
### Uploading a new version to Google Play
Use [GitHub Actions](../.github/workflows/android-release.yaml).
Promote version to "Production" manually in Google Play Console.
### Uploading a new version to Huawei AppGallery
Use [GitHub Actions](../.github/workflows/android-release.yaml).
### Checking metadata
Use [GitHub Actions](../.github/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
```

8
docs/ROADMAP.md Normal file
View File

@@ -0,0 +1,8 @@
# Roadmap
The Organic Maps project uses [Github Discussions](https://github.com/organicmaps/organicmaps/discussions/categories/ideas) to define its roadmap. ROADMAP.md files are common in open source projects but we find they quickly become out of date. We opt for an issues and milestone approach that our maintainers and community can keep up-to-date as work is added and completed.
## 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://github.com/organicmaps/organicmaps/milestones).

116
docs/STRUCTURE.md Normal file
View File

@@ -0,0 +1,116 @@
# 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 OM 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 OM types.
- `types.txt`
### Styles and icons
- `resources-default/` -
- `resources-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):
- `resources-*/` - icons skin files in various resolutions for `dark` and `clear` (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.

114
docs/STYLES.md Normal file
View File

@@ -0,0 +1,114 @@
# 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. Run the `tools/unix/generate_drules.sh` script
3. Test how your changes look in the app
4. Commit your edits and files changed by the script
5. Send a pull request!
Please prepend `[styles]` to your commit message and add [Developers Certificate of Origin](CONTRIBUTING.md#legal-requirements) to it.
Files changed by the script should be added as a separate `[styles] Regenerated` commit.
Please check [a list of current styling issues](https://github.com/organicmaps/organicmaps/issues?q=is%3Aopen+is%3Aissue+label%3AStyles)
and ["icons wanted" issues](https://github.com/organicmaps/organicmaps/issues?q=is%3Aopen+is%3Aissue+label%3AIcons+label%3A%22Good+first+issue%22).
An overview of currently used icons can be found in the [Wiki](https://github.com/organicmaps/organicmaps/wiki/Icons).
## Requirements
To work with styles first [clone the OM repository](INSTALL.md#getting-sources).
Install a `protobuf` python package with `pip`
```
pip install protobuf
```
or with your OS package manager, e.g for Ubuntu
```
sudo apt install python3-protobuf
```
To run the `generate_symbols.sh` script install `optipng` also, 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 OM 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. Run `tools/unix/generate_symbols.sh` to add new icons into skin files
4. Run `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 OM 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 new type translation into `data/strings/types_strings.txt`
7. Add search keywords into `data/categories.txt`
8. Run `tools/unix/generate_localizations.sh` to validate and distribute translations into iOS and Android
9. Add new or fix current classifier tests at `/generator/generator_tests/osm_type_tests.cpp` if you can
10. [Test](#testing-your-changes) your changes
11. 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.organicmaps/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 OM-specific extensions to it.
The `tools/unix/generate_drules.sh` script uses a customized version of [Kothic](https://github.com/organicmaps/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 Organic Maps, a `SUBWAY_URL`
parameter ought to be provided to the
[map generator](https://github.com/organicmaps/organicmaps/tree/master/tools/python/maps_generator).
Normally you can specify this link https://cdn.organicmaps.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 [Organic Maps subways](https://github.com/organicmaps/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
#!/bin/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.

116
docs/TEAMS.md Normal file
View File

@@ -0,0 +1,116 @@
# Teams
Organic Maps 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 [GitHub](https://github.com/orgs/organicmaps/teams), accessible only to [GitHub Org members](https://github.com/orgs/organicmaps/people) due to the limitations of GitHub.
Teams are typically assigned as code owners for certain sections of the repository. GitHub will automatically request a review from the responsible team when changes are made to the relevant part of the repository in a pull request. See the [CODEOWNERS](../.github/CODEOWNERS) file for more information. Please feel free to tag the relevant team in the comments if you need assistance in a specific area. If you are unsure which team to contact, please tag [@organicmaps/triage](https://github.com/orgs/organicmaps/teams/contributors/triage) for help.
## Triage
- [@organicmaps/triage](https://github.com/orgs/organicmaps/teams/triage/members)
People who help with triaging incoming issues and pull requests. Tag this group if you are unsure which team to tag.
## Mergers
- [@organicmaps/mergers](https://github.com/orgs/organicmaps/teams/mergers/members)
People who can merge pull requests that are ready.
## Android
- [@organicmaps/android](https://github.com/orgs/organicmaps/teams/android/members)
Android experts.
### Android Auto
Android Auto experts (a subteam of Android).
- [@organicmaps/android-auto](https://github.com/orgs/organicmaps/teams/android-auto/members)
## iOS
- [@organicmaps/ios](https://github.com/orgs/organicmaps/teams/ios/members)
iOS experts.
## Qt
- [@organicmaps/qt](https://github.com/orgs/organicmaps/teams/qt/members)
Qt Desktop & Convergent UI experts.
## C++
- [@organicmaps/cpp](https://github.com/orgs/organicmaps/teams/cpp/members)
C++ experts.
## Rendering
- [@organicmaps/rendering](https://github.com/orgs/organicmaps/teams/rendering/members)
Rendering experts.
## Data
- [@organicmaps/map](https://github.com/orgs/organicmaps/teams/data/members)
- [#data](https://organicmaps.zulipchat.com/#narrow/channel/477127-Data)
Map data generation team.
## Styles
- [@organicmaps/styles](https://github.com/orgs/organicmaps/teams/styles/members)
Map styles team.
## DevOps
- [@organicmaps/devops](https://github.com/orgs/organicmaps/teams/devops/members)
DevOps team.
## Design
- [@organicmaps/design](https://github.com/orgs/organicmaps/teams/design/members)
Visual design (icons, graphics, colors, contrast, etc.).
## Web
- [@organicmaps/web](https://github.com/orgs/organicmaps/teams/web/members)
Web development experts.
## Growth
- [@organicmaps/growth](https://github.com/orgs/organicmaps/teams/growth/members)
Marketing, ASO, SEO, and SMM experts.
## Product
- [@organicmaps/product](https://github.com/orgs/organicmaps/teams/product/members)
Product management group.
## Translations
- [@organicmaps/translations](https://github.com/orgs/organicmaps/teams/translations)
Internationalization and localization.
Tag [@organicmaps/translations-langcode](https://github.com/orgs/organicmaps/teams/translations/teams) (e.g. @organicmaps/translations-fr) for specific language.
## Support
- [@organicmaps/support](https://github.com/orgs/organicmaps/teams/support/members)
End-user support: feedback in stores, emails, user-facing docs (FAQs).
## Legal
- [@organicmaps/legal](https://github.com/orgs/organicmaps/teams/legal/members)
Legal team.

121
docs/TRANSLATIONS.md Normal file
View File

@@ -0,0 +1,121 @@
# Translations
Translations are managed through [Weblate][weblate]. Please [contribute][contribute] translations via the [Weblate][weblate], 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/app/src/main/res/values\*/type_strings.xml][android_git] ([en][android_type_strings_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/country-strings/\*.json][countries_git] ([en][countries_git_en]) |
| Search keywords | Search keywords/aliases/synonyms | [data/categories.txt][categories_git] |
| Search keywords (cuisines) | Search keywords for cuisine types | [data/categories_cuisines.txt][categories_cuisines_git] |
| AppStore Descriptions | AppStore descriptions | [iphone/metadata][appstore_git] ([en][appstore_git_en]) |
| Android Stores Descriptions | Google, F-Droid, Huawei store descriptions | [android/app/src/fdroid/play][googleplay_git] ([en][googleplay_git_en]) |
| [Website][website_weblate] | Website content | [organicmaps/website][website_git] ([see details][website_guide]) |
Components without links haven't been integrated into Weblate and must be translated directly via [GitHub Pull Requests](CONTRIBUTING.md).
## Translating
### Workflow
Translations are managed through [Weblate][weblate]. 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 [@organicmaps/mergers][mergers] review and merge as usual.
### Cross-Component Synchronization
Android and iOS share most of the strings. Weblate automatically syncs translations between components (e.g., from Android to iOS and vice versa), so updating a string in one place is usually sufficient.
## Machine Translation
Weblate 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 [**Weblate**][weblate], with no direct developer involvement required. Developers are only responsible for adding English base strings to the source file (see [Components](#components)). Weblate 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
Weblate 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_.
After committing changes from the internal database to the internal repository, Weblate pushes all updates to the `weblate-i18n` branch of the main GitHub repository and creates or updates a pull request (PR) to `master`. This operation can be manually triggered via _Manage → Repository Maintenance → Push_.
### Reviewing PRs
Translations are intended to be reviewed by the community on Weblate. 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 Weblate, as translators primarily work within that platform. If the contributor has a GitHub account, you may tag them 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. Commit all changes from the internal database to the internal Git repository:
_Manage → Repository Maintenance → Commit (button)_.
2. Update the `weblate-i18n` branch on GitHub:
_Manage → Repository Maintenance → Push (button)_.
3. Locally checkout the `weblate-i18n` branch.
4. Rebase it onto `master`, resolving any conflicts during the process.
5. Push the branch to GitHub to update the pull request, then merge the branch or PR into `master`.
6. Reset Weblate to sync changes from GitHub:
_Manage → Repository Maintenance → Reset (button)_.
[weblate]: https://hosted.weblate.org/projects/organicmaps/
[contribute]: https://docs.weblate.org/en/latest/workflows.html
[android_weblate]: https://hosted.weblate.org/projects/organicmaps/android/
[android_git]: https://github.com/organicmaps/organicmaps/blob/master/android/app/src/main/res/
[android_git_en]: https://github.com/organicmaps/organicmaps/blob/master/android/app/src/main/res/values/strings.xml
[android_typestrings_weblate]: https://hosted.weblate.org/projects/organicmaps/android-typestrings/
[android_typestrings_git_en]: https://github.com/organicmaps/organicmaps/blob/master/android/app/src/main/res/values/types_strings.xml
[countries_weblate]: https://hosted.weblate.org/projects/organicmaps/countries/
[countries_git]: https://github.com/organicmaps/organicmaps/tree/master/data/countries-strings
[countries_git_en]: https://github.com/organicmaps/organicmaps/blob/master/data/countries-strings/en.json/localize.json
[ios_weblate]: https://hosted.weblate.org/projects/organicmaps/ios/
[ios_git]: https://github.com/organicmaps/organicmaps/blob/master/iphone/Maps/LocalizedStrings/
[ios_git_en]: https://github.com/organicmaps/organicmaps/blob/master/iphone/Maps/LocalizedStrings/en.lproj/Localizable.strings
[ios_plist_weblate]: https://hosted.weblate.org/projects/organicmaps/ios-plist/
[ios_plist_git_en]: https://github.com/organicmaps/organicmaps/blob/master/iphone/Maps/LocalizedStrings/en.lproj/InfoPlist.strings
[ios_typestrings_weblate]: https://hosted.weblate.org/projects/organicmaps/ios-typestrings/
[ios_typestrings_git_en]: https://github.com/organicmaps/organicmaps/blob/master/iphone/Maps/LocalizedStrings/en.lproj/LocalizableTypes.strings
[ios_plurals_weblate]: https://hosted.weblate.org/projects/organicmaps/ios-plurals/
[ios_plurals_git_en]: https://github.com/organicmaps/organicmaps/blob/master/iphone/Maps/LocalizedStrings/en.lproj/Localizable.stringsdict
[tts_weblate]: https://hosted.weblate.org/projects/organicmaps/tts/
[tts_git]: https://github.com/organicmaps/organicmaps/tree/master/data/sound-strings
[tts_git_en]: https://github.com/organicmaps/organicmaps/blob/master/data/sound-strings/en.json/localize.json
[categories_git]: https://github.com/organicmaps/organicmaps/blob/master/data/categories.txt
[categories_cuisines_git]: https://github.com/organicmaps/organicmaps/blob/master/data/categories_cuisines.txt
[website_weblate]: https://hosted.weblate.org/projects/organicmaps/website/
[website_git]: https://github.com/organicmaps/website/
[website_guide]: https://github.com/organicmaps/website/blob/master/TRANSLATIONS.md
[appstore_git]: https://github.com/organicmaps/organicmaps/tree/master/iphone/metadata
[appstore_git_en]: https://github.com/organicmaps/organicmaps/tree/master/iphone/metadata/en-US
[googleplay_git]: https://github.com/organicmaps/organicmaps/tree/master/android/app/src/fdroid/play
[googleplay_git_en]: https://github.com/organicmaps/organicmaps/tree/master/android/app/src/fdroid/play/listings/en-US
[mergers]: https://github.com/orgs/organicmaps/teams/mergers/members
[failing_checks]: https://hosted.weblate.org/search/organicmaps/?q=has%3Acheck+AND+state%3A%3E%3Dtranslated+language%3Aru&sort_by=target&checksum=

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
docs/badges/fdroid.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 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: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
docs/badges/obtainium.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 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 Organic Maps 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

View File

@@ -0,0 +1,46 @@
1-й байт:
0. кол-во типов (1-8, пишем 0-7, 3 бита)
3. имя
4. слой
5, 6. - тип геометрии (точка = 00, линия = 01, площадной = 10)
7. бит присутствия дополнительной информации:
- точка - ранг (1 байт как логарифм населения по основанию 1.1);
- линейный - № дороги (строка);
- площадной - № дома (строка, оптимизированная для хранения двузначного числа);
* пишем типы, имя, слой, дополнительную информацию, точку (для точечного типа)
1 или 2 байта следующего заголовка (только для линейного и\или площадного объекта):
* 4 бита кол-ва внутренних точек для линейного объекта:
- 0 - геометрия вынесена, идем читать маску смещений и смещения;
- 2 - 0 байт на маску упрощения;
- 3-6 - 1 байт на маску упрощения;
- 7-10 - 2 бму;
- 11-14 - 3 бму;
* 4 бита кол-ва внутренних треугольников для площадного объекта:
- 0 - геометрия вынесена, идем читать маску смещений и смещения;
- >0 - кол-во треугольников одного стрипа (для нескольких стрипов геометрия выносится);
* по 4 бита для маски смещений для линейного и площадного объекта.
Маска смещений опряделяет наличие вынесенной геометрии для i-го масштабного ряда (из 4-х по соотв. биту).
Эти 2 байта актуально могут быть расположены в одном, когда объект одного типа или геометрия не вынесена.
Реально это будет 2 байта когда объект сразу линейный и площадной и у него вынесена геометрия.
Следующие байты:
* пишем геометрию ...
- маска упрощения для линейного объекта (1-3 байта):
Маска упрощения в 1 байт кодирует видимость 4-х точек в 4-х масштабных рядах (по 2 бита), т.е.
равна значению масштабного ряда, с которого точка уже видна.
- массив точек геометрии (треугольников стрипа) по извесному количеству VarInt64
* ... или пишем массив смещений на вынесенную геометрию (количество берем из маски смещений)
Вынесенная геометрия для масштаба представляет собой блок:
- размер геометрии в байтах
- сериализованные VarInt64 по кол-ву байт
Для линейного объекта они представляют собой массив точек.
Для площадного представляют собой следующие последовательности:
- количество точек с стрипе
- сам стрип (массив точек)

BIN
docs/privacy/exodus.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
docs/privacy/mm.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 KiB

BIN
docs/privacy/om.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

3
docs/sponsors/44plus.svg Normal file
View File

@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg width="32" height="32" version="1.1" viewBox="0 0 32 32" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><clipPath id="clip2_10_271"><rect transform="translate(1.4131 -.049927)" width="698.32" height="436.45" fill="#fff"/></clipPath><clipPath id="clip3_10_271"><rect transform="translate(148.79 65.418)" width="403.56" height="305.52" fill="#fff"/></clipPath><clipPath id="clip4_10_271"><rect transform="translate(148.79 65.418)" width="403.56" height="305.52" fill="#fff"/></clipPath><clipPath id="clip5_10_271"><rect transform="translate(148.79 65.418)" width="403.56" height="305.52" fill="#fff"/></clipPath><clipPath id="clip6_10_271"><rect transform="translate(148.79 65.418)" width="403.56" height="305.52" fill="#fff"/></clipPath><clipPath id="clip7_10_271"><rect transform="translate(148.79 65.418)" width="403.56" height="305.52" fill="#fff"/></clipPath><clipPath id="clip8_10_271"><rect transform="translate(148.79 65.418)" width="403.56" height="305.52" fill="#fff"/></clipPath><clipPath id="clip9_10_271"><rect transform="translate(148.79 65.418)" width="403.56" height="305.52" fill="#fff"/></clipPath><clipPath id="clip10_10_271"><rect transform="translate(148.79 65.418)" width="403.56" height="305.52" fill="#fff"/></clipPath><clipPath id="clip11_10_271"><rect transform="translate(148.79 65.418)" width="403.56" height="305.52" fill="#fff"/></clipPath><clipPath id="clip12_10_271"><rect transform="translate(148.79 65.418)" width="403.56" height="305.52" fill="#fff"/></clipPath><clipPath id="clip13_10_271"><rect transform="translate(148.79 65.418)" width="403.56" height="305.52" fill="#fff"/></clipPath><clipPath id="clip14_10_271"><rect transform="translate(148.79 65.418)" width="403.56" height="305.52" fill="#fff"/></clipPath><linearGradient id="linearGradient2" x1="32.239" x2=".24804" y1="16.282" y2="16.282" gradientUnits="userSpaceOnUse"><stop stop-color="#2564ff" offset="0"/><stop stop-color="#54b4fa" offset="1"/></linearGradient></defs><circle cx="16" cy="16" r="16" fill="url(#linearGradient2)" stroke-width="9.6945"/><g transform="matrix(.059032 0 0 .059032 -5.1444 3.1205)" fill="#fff"><g clip-path="url(#clip2_10_271)" fill="#fff"><mask id="mask0_10_271" x="1" y="-1" width="699" height="438" maskUnits="userSpaceOnUse"><path d="m699.74-0.049927h-698.32v436.45h698.32z" fill="#fff"/><g clip-path="url(#clip3_10_271)"><g clip-path="url(#clip4_10_271)"><g clip-path="url(#clip5_10_271)"><g clip-path="url(#clip6_10_271)"><g clip-path="url(#clip7_10_271)"><g clip-path="url(#clip8_10_271)"><path d="m316.35 256.99h33.267v27.913h-33.267v63.092h-34.031v-63.092h-109.36v-25.237l76.857-171.3 29.443 12.236-69.21 156.39h72.651l3.059-68.828h30.59zm123.89-107.45h32.12v57.357h55.826v29.06h-55.826v56.974h-32.12v-56.974h-55.444v-29.06h55.444z" fill="#000" stroke="#000" stroke-linejoin="round" stroke-width="38.237"/></g></g></g></g></g></g></mask><g mask="url(#mask0_10_271)"><path d="m443.14 283.42h55.923v46.923h-55.923v106.06h-57.207v-106.06h-183.84v-42.424l129.2-287.97 49.495 20.569-116.35 262.9h122.13l5.142-115.7h51.423z" fill="#fff"/></g><g clip-path="url(#clip9_10_271)"><g clip-path="url(#clip10_10_271)" fill="#fff"><g clip-path="url(#clip11_10_271)" fill="#fff"><g clip-path="url(#clip12_10_271)" fill="#fff"><g clip-path="url(#clip13_10_271)" fill="#fff"><g clip-path="url(#clip14_10_271)" fill="#fff"><path d="m316.35 256.99h33.267v27.913h-33.267v63.092h-34.031v-63.092h-109.36v-25.237l76.857-171.3 29.443 12.236-69.21 156.39h72.651l3.059-68.828h30.59zm123.89-107.45h32.12v57.357h55.826v29.06h-55.826v56.974h-32.12v-56.974h-55.444v-29.06h55.444z" fill="#fff"/></g></g></g></g></g></g></g></g></svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

1
docs/sponsors/futo.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="92" height="24" viewBox="0 0 92 24" fill="none"><path fill-rule="evenodd" clip-rule="evenodd" d="M91.6364 12C91.6364 18.6274 86.267 24 79.6437 24C73.0203 24 67.651 18.6274 67.651 12C67.651 5.37258 73.0203 0 79.6437 0C86.267 0 91.6364 5.37258 91.6364 12ZM76.1504 14.4215C74.9204 13.1908 74.3054 12.5754 74.3054 11.8107C74.3054 11.046 74.9204 10.4306 76.1504 9.19985L77.1526 8.1968C78.3826 6.96603 78.9979 6.35065 79.7621 6.35065C80.5262 6.35065 81.1412 6.96603 82.3712 8.1968L83.3737 9.19985C84.6037 10.4306 85.2187 11.046 85.2187 11.8107C85.2187 12.5754 84.6037 13.1908 83.3737 14.4215L82.3712 15.4246C81.1412 16.6554 80.5262 17.2707 79.7621 17.2707C78.9979 17.2707 78.3826 16.6554 77.1526 15.4246L76.1504 14.4215ZM16.9128 7.07692C17.2524 7.07692 17.5278 6.80142 17.5278 6.46154V1.84615C17.5278 1.50629 17.2524 1.23077 16.9128 1.23077H0.615009C0.275349 1.23077 0 1.50629 0 1.84615V22.1538C0 22.4937 0.275349 22.7692 0.615009 22.7692H6.15009C6.48976 22.7692 6.7651 22.4937 6.7651 22.1538V16.4923C6.7651 16.1524 7.04044 15.8769 7.38011 15.8769H14.8217C15.1614 15.8769 15.4367 15.6014 15.4367 15.2615V10.6462C15.4367 10.3063 15.1614 10.0308 14.8217 10.0308H7.38011C7.04044 10.0308 6.7651 9.75526 6.7651 9.41539V7.69231C6.7651 7.35243 7.04044 7.07692 7.38011 7.07692H16.9128ZM31.2092 23.1385H31.3015C37.8821 23.1385 41.9104 19.6308 41.9104 12.9538V1.84615C41.9104 1.50629 41.6352 1.23077 41.2954 1.23077H35.7603C35.4208 1.23077 35.1453 1.50629 35.1453 1.84615V12.3385C35.1453 14.6154 34.1613 16.6154 31.3015 16.6154H31.2092C28.3803 16.6154 27.3655 14.6154 27.3655 12.3385V1.84615C27.3655 1.50629 27.0902 1.23077 26.7505 1.23077H21.2154C20.8757 1.23077 20.6004 1.50629 20.6004 1.84615V12.9538C20.6004 19.6308 24.6287 23.1385 31.2092 23.1385ZM44.9845 1.84615C44.9845 1.50629 45.2597 1.23077 45.5995 1.23077H65.4643C65.8041 1.23077 66.0793 1.50629 66.0793 1.84615V6.55385C66.0793 6.89372 65.8041 7.16923 65.4643 7.16923H59.5295C59.1897 7.16923 58.9145 7.44474 58.9145 7.78462V22.1538C58.9145 22.4937 58.6393 22.7692 58.2995 22.7692H52.7644C52.4246 22.7692 52.1494 22.4937 52.1494 22.1538V7.78462C52.1494 7.44474 51.8742 7.16923 51.5344 7.16923H45.5995C45.2597 7.16923 44.9845 6.89372 44.9845 6.55385V1.84615Z" fill="#404040"></path></svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

43
docs/sponsors/gsoc.svg Normal file
View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" id="svg51" version="1.1" viewBox="0 0 281 281" height="281px" width="281px">
<metadata id="metadata55">
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title>logo_lockup_summer_of_code_horizontal_Roboto</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<!-- Generator: Sketch 3.7.2 (28276) - http://www.bohemiancoding.com/sketch -->
<title id="title2">logo_lockup_summer_of_code_horizontal_Roboto</title>
<desc id="desc4">Created with Sketch.</desc>
<defs id="defs6"/>
<g id="Group">
<path style="fill:#fbbc05" d="m 114.7,150.8 25.7,25.7 25.7,-25.7 h 36.4 V 114.4 L 228.2,88.7 202.5,63 V 26.6 H 166.1 L 140.4,0.9 114.7,26.6 H 78.3 V 63 l -25.7,25.7 25.7,25.7 v 36.4 z" id="Shape"/>
<path style="fill:#ffffff" id="path11" d="m 143.2,61.2 -0.1,0.4 -11.9,52.5 -0.4,2 h 7.4 l 0.1,-0.4 11.9,-52.5 0.4,-2 z m -18.9,7.2 -1,0.7 -21.5,16.7 -1.4,1.1 v 3.4 l 1.4,1.1 21.5,16.7 1,0.7 v -9 L 109.8,88.7 124.3,77.4 Z m 32.2,0 v 9 L 171,88.7 156.5,100 v 9 l 1,-0.7 21.5,-16.7 1.4,-1.1 V 87.1 L 179,86 157.4,69.2 Z"/>
<circle id="Oval" cx="140.4" cy="88.7" r="58.7" style="fill:none;stroke:#ffffff;stroke-width:8"/>
</g>
<g style="fill:#757575;font-family:Roboto" id="Roboto">
<path id="path16" d="m 9.77,268.3 c -3.03,-0.87 -5.25,-1.95 -6.63,-3.21 -1.38,-1.26 -2.07,-2.85 -2.07,-4.71 0,-2.13 0.84,-3.87 2.55,-5.25 1.71,-1.38 3.9,-2.07 6.6,-2.07 1.86,0 3.48,0.36 4.95,1.08 1.44,0.72 2.58,1.71 3.36,2.94 0.78,1.23 1.2,2.64 1.2,4.11 H 16.1 c 0,-1.62 -0.51,-2.91 -1.56,-3.84 -1.02,-0.93 -2.49,-1.41 -4.38,-1.41 -1.74,0 -3.12,0.39 -4.08,1.17 -0.96,0.78 -1.47,1.83 -1.47,3.21 0,1.11 0.45,2.04 1.38,2.79 0.93,0.75 2.52,1.44 4.74,2.07 2.22,0.63 3.99,1.32 5.25,2.07 1.26,0.75 2.19,1.65 2.82,2.64 0.6,1.02 0.9,2.19 0.9,3.57 0,2.19 -0.84,3.93 -2.55,5.22 -1.71,1.29 -3.96,1.98 -6.81,1.98 -1.86,0 -3.57,-0.36 -5.16,-1.05 C 3.59,278.92 2.36,277.93 1.49,276.7 0.62,275.47 0.2,274.06 0.2,272.5 h 3.57 c 0,1.62 0.6,2.91 1.8,3.84 1.2,0.93 2.79,1.41 4.8,1.41 1.86,0 3.3,-0.39 4.29,-1.14 0.99,-0.75 1.5,-1.8 1.5,-3.12 0,-1.32 -0.45,-2.34 -1.38,-3.06 -0.93,-0.72 -2.61,-1.41 -5.01,-2.13 z"/>
<path id="path18" d="m 36.05,278.32 c -1.32,1.56 -3.27,2.34 -5.85,2.34 -2.13,0 -3.75,-0.63 -4.86,-1.86 -1.11,-1.23 -1.68,-3.06 -1.68,-5.49 v -12.99 h 3.42 v 12.9 c 0,3.03 1.23,4.53 3.69,4.53 2.61,0 4.35,-0.96 5.19,-2.91 v -14.52 h 3.42 v 19.98 h -3.24 z"/>
<path id="path20" d="m 47.78,260.32 0.09,2.22 c 1.47,-1.71 3.45,-2.58 5.91,-2.58 2.79,0 4.68,1.08 5.7,3.21 0.66,-0.96 1.53,-1.74 2.58,-2.34 1.05,-0.6 2.31,-0.9 3.78,-0.9 4.38,0 6.6,2.31 6.69,6.96 v 13.41 h -3.42 v -13.2 c 0,-1.44 -0.33,-2.49 -0.99,-3.21 -0.66,-0.72 -1.74,-1.05 -3.3,-1.05 -1.26,0 -2.31,0.39 -3.15,1.14 -0.84,0.75 -1.32,1.77 -1.47,3.06 v 13.26 h -3.42 v -13.08 c 0,-2.91 -1.41,-4.35 -4.26,-4.35 -2.25,0 -3.78,0.96 -4.59,2.85 v 14.58 h -3.42 v -19.98 z"/>
<path id="path22" d="m 80.9,260.32 0.09,2.22 c 1.47,-1.71 3.45,-2.58 5.91,-2.58 2.79,0 4.68,1.08 5.7,3.21 0.66,-0.96 1.53,-1.74 2.58,-2.34 1.05,-0.6 2.31,-0.9 3.78,-0.9 4.38,0 6.6,2.31 6.69,6.96 v 13.41 h -3.42 v -13.2 c 0,-1.44 -0.33,-2.49 -0.99,-3.21 -0.66,-0.72 -1.74,-1.05 -3.3,-1.05 -1.26,0 -2.31,0.39 -3.15,1.14 -0.84,0.75 -1.32,1.77 -1.47,3.06 V 280.3 H 89.9 v -13.08 c 0,-2.91 -1.41,-4.35 -4.26,-4.35 -2.25,0 -3.78,0.96 -4.59,2.85 v 14.58 h -3.42 v -19.98 z"/>
<path id="path24" d="m 119.12,280.66 c -2.7,0 -4.92,-0.9 -6.6,-2.67 -1.71,-1.77 -2.55,-4.17 -2.55,-7.14 v -0.63 c 0,-1.98 0.39,-3.75 1.14,-5.31 0.75,-1.56 1.8,-2.76 3.18,-3.66 1.35,-0.87 2.82,-1.32 4.41,-1.32 2.61,0 4.62,0.87 6.06,2.58 1.44,1.71 2.16,4.17 2.16,7.35 v 1.41 h -13.53 c 0.06,1.98 0.63,3.57 1.74,4.77 1.11,1.2 2.49,1.83 4.2,1.83 1.2,0 2.22,-0.24 3.06,-0.75 0.84,-0.48 1.56,-1.14 2.19,-1.95 l 2.1,1.62 c -1.71,2.58 -4.23,3.87 -7.56,3.87 z m -0.42,-17.91 c -1.38,0 -2.52,0.51 -3.48,1.5 -0.93,0.99 -1.5,2.4 -1.74,4.23 h 9.99 v -0.27 c -0.09,-1.74 -0.57,-3.09 -1.41,-4.02 -0.81,-0.96 -1.95,-1.44 -3.36,-1.44 z"/>
<path id="path26" d="m 140.51,263.38 c -0.51,-0.09 -1.08,-0.12 -1.68,-0.12 -2.25,0 -3.75,0.96 -4.56,2.85 v 14.19 h -3.42 v -19.98 h 3.33 l 0.06,2.31 c 1.11,-1.77 2.7,-2.67 4.77,-2.67 0.66,0 1.17,0.09 1.5,0.27 z"/>
<path id="path28" d="m 152.09,270.13 c 0,-1.95 0.39,-3.72 1.14,-5.28 0.78,-1.56 1.83,-2.76 3.21,-3.63 1.38,-0.87 2.94,-1.26 4.71,-1.26 2.73,0 4.92,0.93 6.6,2.82 1.68,1.89 2.52,4.38 2.52,7.5 v 0.24 c 0,1.95 -0.36,3.69 -1.11,5.22 -0.75,1.53 -1.8,2.76 -3.18,3.6 -1.38,0.87 -2.97,1.29 -4.77,1.29 -2.7,0 -4.89,-0.93 -6.57,-2.82 -1.68,-1.89 -2.52,-4.38 -2.52,-7.47 v -0.21 z m 3.45,0.39 c 0,2.22 0.51,3.99 1.53,5.34 1.02,1.35 2.4,2.01 4.14,2.01 1.74,0 3.12,-0.69 4.14,-2.04 1.02,-1.35 1.53,-3.27 1.53,-5.7 0,-2.19 -0.51,-3.96 -1.56,-5.31 -1.05,-1.35 -2.43,-2.04 -4.14,-2.04 -1.68,0 -3.06,0.66 -4.08,2.01 -1.05,1.32 -1.56,3.24 -1.56,5.73 z"/>
<path id="path30" d="m 176.24,280.3 v -17.34 h -3.15 v -2.64 h 3.15 v -2.04 c 0,-2.13 0.57,-3.81 1.71,-4.95 1.14,-1.17 2.76,-1.74 4.86,-1.74 0.78,0 1.56,0.09 2.34,0.3 l -0.18,2.76 c -0.57,-0.12 -1.2,-0.18 -1.86,-0.18 -1.11,0 -1.95,0.33 -2.58,0.96 -0.63,0.63 -0.9,1.59 -0.9,2.79 v 2.1 h 4.26 v 2.64 h -4.26 v 17.34 z"/>
<path id="path32" d="m 217.34,271.75 c -0.33,2.85 -1.38,5.04 -3.15,6.57 -1.77,1.53 -4.11,2.31 -7.05,2.31 -3.18,0 -5.73,-1.14 -7.62,-3.42 -1.92,-2.28 -2.88,-5.31 -2.88,-9.15 v -2.58 c 0,-2.49 0.45,-4.68 1.35,-6.6 0.9,-1.89 2.16,-3.36 3.78,-4.38 1.62,-1.02 3.54,-1.53 5.67,-1.53 2.85,0 5.13,0.81 6.87,2.4 1.71,1.59 2.73,3.81 3,6.63 h -3.57 c -0.3,-2.16 -0.99,-3.69 -2.01,-4.68 -1.02,-0.99 -2.46,-1.44 -4.32,-1.44 -2.25,0 -4.05,0.84 -5.31,2.52 -1.29,1.68 -1.92,4.05 -1.92,7.14 v 2.61 c 0,2.91 0.6,5.25 1.83,6.96 1.23,1.71 2.91,2.58 5.1,2.58 1.98,0 3.48,-0.45 4.53,-1.35 1.05,-0.9 1.74,-2.46 2.1,-4.65 h 3.6 z"/>
<path id="path34" d="m 220.73,270.13 c 0,-1.95 0.39,-3.72 1.14,-5.28 0.78,-1.56 1.83,-2.76 3.21,-3.63 1.38,-0.87 2.94,-1.26 4.71,-1.26 2.73,0 4.92,0.93 6.6,2.82 1.68,1.89 2.52,4.38 2.52,7.5 v 0.24 c 0,1.95 -0.36,3.69 -1.11,5.22 -0.75,1.53 -1.8,2.76 -3.18,3.6 -1.38,0.87 -2.97,1.29 -4.77,1.29 -2.7,0 -4.89,-0.93 -6.57,-2.82 -1.68,-1.89 -2.52,-4.38 -2.52,-7.47 v -0.21 z m 3.45,0.39 c 0,2.22 0.51,3.99 1.53,5.34 1.02,1.35 2.4,2.01 4.14,2.01 1.74,0 3.12,-0.69 4.14,-2.04 1.02,-1.35 1.53,-3.27 1.53,-5.7 0,-2.19 -0.51,-3.96 -1.56,-5.31 -1.05,-1.35 -2.43,-2.04 -4.14,-2.04 -1.68,0 -3.06,0.66 -4.08,2.01 -1.05,1.32 -1.56,3.24 -1.56,5.73 z"/>
<path id="path36" d="m 242.36,270.13 c 0,-3.06 0.72,-5.52 2.19,-7.38 1.47,-1.86 3.36,-2.79 5.7,-2.79 2.34,0 4.2,0.81 5.55,2.4 v -10.41 h 3.42 v 28.35 h -3.15 l -0.18,-2.13 c -1.38,1.68 -3.27,2.52 -5.7,2.52 -2.31,0 -4.2,-0.96 -5.67,-2.85 -1.47,-1.89 -2.19,-4.38 -2.19,-7.41 v -0.3 z m 3.42,0.39 c 0,2.25 0.48,4.05 1.41,5.31 0.93,1.29 2.22,1.92 3.87,1.92 2.16,0 3.75,-0.96 4.74,-2.91 v -9.18 c -1.02,-1.89 -2.58,-2.82 -4.71,-2.82 -1.68,0 -2.97,0.66 -3.9,1.95 -0.93,1.29 -1.41,3.21 -1.41,5.73 z"/>
<path id="path38" d="m 272.81,280.66 c -2.7,0 -4.92,-0.9 -6.6,-2.67 -1.71,-1.77 -2.55,-4.17 -2.55,-7.14 v -0.63 c 0,-1.98 0.39,-3.75 1.14,-5.31 0.75,-1.56 1.8,-2.76 3.18,-3.66 1.35,-0.87 2.82,-1.32 4.41,-1.32 2.61,0 4.62,0.87 6.06,2.58 1.44,1.71 2.16,4.17 2.16,7.35 v 1.41 h -13.53 c 0.06,1.98 0.63,3.57 1.74,4.77 1.11,1.2 2.49,1.83 4.2,1.83 1.2,0 2.22,-0.24 3.06,-0.75 0.84,-0.48 1.56,-1.14 2.19,-1.95 l 2.1,1.62 c -1.71,2.58 -4.23,3.87 -7.56,3.87 z m -0.42,-17.91 c -1.38,0 -2.52,0.51 -3.48,1.5 -0.93,0.99 -1.5,2.4 -1.74,4.23 h 9.99 v -0.27 c -0.09,-1.74 -0.57,-3.09 -1.41,-4.02 -0.81,-0.96 -1.95,-1.44 -3.36,-1.44 z"/>
</g>
<g style="fill:#757575" id="Google">
<path id="path25" d="m 131.2025,217.9746 c 0,6.0019 -4.6953,10.4246 -10.4575,10.4246 -5.7622,0 -10.4575,-4.4227 -10.4575,-10.4246 0,-6.0442 4.6953,-10.4246 10.4575,-10.4246 5.7622,0 10.4575,4.3804 10.4575,10.4246 z m -4.5778,0 c 0,-3.7506 -2.7213,-6.3168 -5.8797,-6.3168 -3.1584,0 -5.8797,2.5662 -5.8797,6.3168 0,3.713 2.7213,6.3168 5.8797,6.3168 3.1584,0 5.8797,-2.6085 5.8797,-6.3168 z"/>
<path id="path27" d="m 153.7625,217.9746 c 0,6.0019 -4.6953,10.4246 -10.4575,10.4246 -5.7622,0 -10.4575,-4.4227 -10.4575,-10.4246 0,-6.0395 4.6953,-10.4246 10.4575,-10.4246 5.7622,0 10.4575,4.3804 10.4575,10.4246 z m -4.5778,0 c 0,-3.7506 -2.7213,-6.3168 -5.8797,-6.3168 -3.1584,0 -5.8797,2.5662 -5.8797,6.3168 0,3.713 2.7213,6.3168 5.8797,6.3168 3.1584,0 5.8797,-2.6085 5.8797,-6.3168 z"/>
<path id="path29" d="m 175.3825,208.1798 v 18.7154 c 0,7.6986 -4.5402,10.8429 -9.9076,10.8429 -5.0525,0 -8.0934,-3.3793 -9.2402,-6.1429 l 3.9856,-1.6591 c 0.7097,1.6967 2.4487,3.6989 5.2499,3.6989 3.4357,0 5.5648,-2.1197 5.5648,-6.11 v -1.4993 h -0.1598 c -1.0246,1.2643 -2.9986,2.3688 -5.4896,2.3688 -5.2123,0 -9.9875,-4.5402 -9.9875,-10.3823 0,-5.8844 4.7752,-10.4622 9.9875,-10.4622 2.4863,0 4.4603,1.1045 5.4896,2.3312 h 0.1598 v -1.6967 h 4.3475 z m -4.0232,9.8324 c 0,-3.6707 -2.4487,-6.3544 -5.5648,-6.3544 -3.1584,0 -5.8045,2.6837 -5.8045,6.3544 0,3.6331 2.6461,6.2792 5.8045,6.2792 3.1161,0 5.5648,-2.6461 5.5648,-6.2792 z"/>
<path id="path31" d="m 182.55,197.21 v 30.55 h -4.465 v -30.55 z"/>
<path id="path33" d="m 199.9494,221.4056 3.5532,2.3688 c -1.1468,1.6967 -3.9104,4.6201 -8.6856,4.6201 -5.922,0 -10.3447,-4.5778 -10.3447,-10.4246 0,-6.1993 4.4603,-10.4246 9.8324,-10.4246 5.4097,0 8.0558,4.3052 8.9206,6.6317 l 0.4747,1.1844 -13.9355,5.7716 c 1.0669,2.0915 2.726,3.1584 5.0525,3.1584 2.3312,0 3.948,-1.1468 5.1324,-2.8858 z m -10.9369,-3.7506 9.3154,-3.8681 c -0.5123,-1.3019 -2.0539,-2.209 -3.8681,-2.209 -2.3265,0 -5.5648,2.0539 -5.4473,6.0771 z"/>
<path id="path35" d="M 93.3863,215.2627 V 210.84 H 108.29 c 0.1457,0.7708 0.2209,1.6826 0.2209,2.6696 0,3.3182 -0.9071,7.4213 -3.8305,10.3447 -2.8435,2.961 -6.4766,4.5402 -11.2894,4.5402 -8.9206,0 -16.4218,-7.2662 -16.4218,-16.1868 0,-8.9206 7.5012,-16.1868 16.4218,-16.1868 4.935,0 8.4506,1.9364 11.092,4.4603 l -3.1208,3.1208 c -1.8941,-1.7766 -4.4603,-3.1584 -7.9759,-3.1584 -6.5142,0 -11.609,5.2499 -11.609,11.7641 0,6.5142 5.0948,11.7641 11.609,11.7641 4.2253,0 6.6317,-1.6967 8.1733,-3.2383 1.2502,-1.2502 2.0727,-3.0362 2.397,-5.4755 z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

3
docs/sponsors/nlnet.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 16 KiB