diff --git a/.github/ISSUE_TEMPLATE/1-support-request.md b/.github/ISSUE_TEMPLATE/1-support-request.md
new file mode 100644
index 0000000000..6db5e39f86
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/1-support-request.md
@@ -0,0 +1,16 @@
+---
+name: "❓ Support request"
+about: Questions and requests for support
+---
+
+🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
+
+Please do not file questions or support requests on the GitHub issues tracker.
+
+In case you aren't sure whether to open an issue or not, please send your request to support@osmand.net.
+
+You can get your questions answered using the [Google group](https://groups.google.com/forum/#!forum/osmand) or chat in real-time via our Telegram instances: [English](https://t.me/OsmAndMaps), [German](https://t.me/deosmand), [French](https://t.me/frosmand), [Ukrainian](https://t.me/uaosmand), [Italian](https://t.me/itosmand), [Russian](https://t.me/ruosmand).
+
+Thank you!
+
+🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
diff --git a/.github/ISSUE_TEMPLATE/2-faq-report.md b/.github/ISSUE_TEMPLATE/2-faq-report.md
new file mode 100644
index 0000000000..531d263d7f
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/2-faq-report.md
@@ -0,0 +1,12 @@
+---
+name: "📚 Outdated FAQ"
+about: Report an issue in FAQ
+---
+
+🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
+
+Please do not file FAQ issues on the GitHub issues tracker.
+
+Instead use the [Google group](https://groups.google.com/forum/#!forum/osmand) to fix wrong or outdated FAQ.
+
+🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
diff --git a/.github/ISSUE_TEMPLATE/3-bug-report.md b/.github/ISSUE_TEMPLATE/3-bug-report.md
new file mode 100644
index 0000000000..0fd8c3e5ff
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/3-bug-report.md
@@ -0,0 +1,18 @@
+---
+name: "\U0001F41E Bug report"
+about: Report a bug in OsmAnd
+---
+
+### Description
+
+
+### How to reproduce?
+
+
+### Your Environment
+OsmAnd Version:
+Android/iOS version:
+Device model:
+
+**Maps used (online or offline):**
+If you have an issue related to offline maps, tell us the exact name of the map file where the issue occurs and its edition date.
diff --git a/.github/ISSUE_TEMPLATE/4-routing-report.md b/.github/ISSUE_TEMPLATE/4-routing-report.md
new file mode 100644
index 0000000000..216cd4b402
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/4-routing-report.md
@@ -0,0 +1,72 @@
+---
+name: "\U0001F6A9 Routing report"
+about: Report a routing issue in OsmAnd
+---
+
+
+
+# 🐞 routing report
+
+### Routing engine
+
+
+
+- [ ] OsmAnd's in-app offline routing
+- [ ] Any online routing provider (YOURS, OpenRouteService, OSRM, etc.)
+
+### Routing Profile
+
+
+
+### Start and end points
+
+
+
+### Actual and expected routes
+
+
+
+### Is this a regression?
+
+
+ Yes, the previous version in which this bug was not present was: ....
+
+## 🌍 Your Environment
+
+**OsmAnd Version:**
+
+
+
+
+
+
+
+**Device and Android/iOS version:**
+
+**Maps used (online or offline):**
+
+
+
+- [ ] Offline maps offered within the OsmAnd app for download.
+
+- [ ] Online (tile / raster) maps
+
+**Anything else relevant?**
diff --git a/.github/ISSUE_TEMPLATE/5-feature-request.md b/.github/ISSUE_TEMPLATE/5-feature-request.md
new file mode 100644
index 0000000000..9c46069f8c
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/5-feature-request.md
@@ -0,0 +1,34 @@
+---
+name: "\U0001F680 Feature request"
+about: Suggest a feature for OsmAnd
+---
+
+
+
+# 🚀 feature request
+
+### Description
+
+
+
+### Describe the solution you'd like
+
+ If you have a solution in mind, please describe it.
+
+### Describe alternatives you've considered
+
+ Have you considered any alternative solutions or workarounds?
diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml
new file mode 100644
index 0000000000..405a2b3065
--- /dev/null
+++ b/.github/workflows/gradle-wrapper-validation.yml
@@ -0,0 +1,10 @@
+name: "Validate Gradle Wrapper"
+on: [push, pull_request]
+
+jobs:
+ validation:
+ name: "Validation"
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - uses: gradle/wrapper-validation-action@v1
diff --git a/.gitignore b/.gitignore
index 5798e73f27..33e746a3d6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,6 +19,10 @@ OsmAndCore_*.aar
.project
out/
+# Huawei
+agconnect-services.json
+OsmAndHms.jks
+
# Android Studio
/.idea
*.iml
diff --git a/AUTHORS.md b/AUTHORS.md
index c418f81d10..59f4e936c4 100644
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -1,7 +1,7 @@
-### Credits to all major contributors/developers:
-Major contributors /developers listed here https://github.com/osmandapp/osmandapp.github.io/blob/master/website/help/about.html#L8
+### Credits to all major contributors / developers:
+Major contributors / developers listed here https://github.com/osmandapp/osmandapp.github.io/blob/master/website/help/about.html#L8
### Other Pull requests
-Copyright © All authors of translations and pull requests could be found in commits history:
+Copyright © All authors of translations and pull requests can be found in the commit history:
- Translations are under special “contributor” name ‘weblate’
- - Pull requests have two committers, first is original contributor and second is project maintainer
+ - Pull requests have two committers: first is original contributor, and second is project maintainer
diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md
deleted file mode 100644
index 8f5f620041..0000000000
--- a/ISSUE_TEMPLATE.md
+++ /dev/null
@@ -1,26 +0,0 @@
-Before entering an issue, please read the information below.
-
-```GitHub is a main development tool for developers. There are hundreds requests a month and there are only few developers. So by opening an issue, please know that your issue will be sent out to all developers and acknowledge that it could be closed without explanation or with a brief message. Comments on the closed issues are also sent to all developers, so you will definitely will be heard. However, there is no guarantee that a developer will pick up the issue to work on it.```
-
-In case you are not sure to open issue or not, please send your request to support support@osmand.net. For **general questions** about OsmAnd, please use the [Google group](https://groups.google.com/forum/#!forum/osmand).
-
-Please be sure to have read our [FAQ](http://osmand.net/help-online) before creating an issue here. (Also, tell us in Google Groups when the FAQ is wrong or outdated.)
-
-The best way to get help about an OsmAnd issue is to create a valid and detailed issue content.
-Please give us the following information so that we can try to **reproduce** your issue:
-
-What version of OsmAnd are you using, on what device and Android/iOS version?
-
-Do you use the offline maps offered within the OsmAnd app for download, or online (tile / raster) maps?
-
-If you have an issue related to offline maps, tell us the exact name of the map file where the issue occurs, and its edition date.
-
-__*In case of wrong routing:*__
-
-Tell us whether you have used OsmAnd's in-app offline routing, or any online routing provider like YOURS, OpenRouteService or OSRM.
-
-What routing profile is chosen in OsmAnd app? (car, bike, pedestrian, fastest or shortest)
-
-Please specify as exactly as possible the start and end point of your route by telling us city name and street name so that we can find it via in-app address search easily. Also, a permalink from openstreetmap.org can be helpful.
-
-Tell us your expected routing, and how OsmAnd routes, or add screenshots here.
diff --git a/LICENSE b/LICENSE
index d63b1a7204..5f96ead1b4 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,11 +1,11 @@
OsmAnd – OSM Automated Navigation Directions – navigation software based on OpenStreetMap.
- Copyright © 2010–2018 OsmAnd BV (Amstelveen, Netherlands - KvK 62066714, BTW 854627704B01).
+ Copyright © 2010–2020 OsmAnd BV (Amstelveen, Netherlands - KvK 62066714, BTW 854627704B01).
- The code in this repository is covered by *GPLv3* (for code) and the artwork is covered by [ CC-BY-NC-ND 4.0 ](https://creativecommons.org/licenses/by-nc-nd/4.0/) (for artwork), except some 3rd party libs and resources.
- ATTENTION: please be aware that some artwork has proprietary license.
+ The code in this repository is covered by *GPLv3* (for code) and the artwork is covered by [CC-BY-NC-ND 4.0](https://creativecommons.org/licenses/by-nc-nd/4.0/) (for artwork), except for some third-party libraries and resources.
+ ATTENTION: Please be aware that some artwork uses a proprietary license.
- Main AUTHORS (more detailed list in AUTHORS):
+ Main AUTHORS (more detailed list in AUTHORS.md):
Victor Shcherb – all parts of the project, originator
Alexey Pelykh – rendering and core parts
Hardy Mueller – main parts of the project, mostly rendering, UI interaction design
@@ -30,33 +30,33 @@
* Source code in main repositories is covered by GPLv3 (license exceptions below):
- https://github.com/osmandapp/Osmand/tree/master/OsmAnd
- https://github.com/osmandapp/Osmand/tree/master/OsmAnd-java
- - https://github.com/osmandapp/Osmand-core/tree/legacy_core
- - https://github.com/osmandapp/Osmand-core/
+ - https://github.com/osmandapp/OsmAnd-core/tree/legacy_core
+ - https://github.com/osmandapp/OsmAnd-core
- https://github.com/osmandapp/OsmAnd-misc
- https://github.com/osmandapp/OsmAnd-tools
- https://github.com/osmandapp/OsmAnd-resources
- * UI Design and UX work, such as layout, icons is covered by CC-BY-NC-ND
+ * UI Design and UX work, such as layout and icons, are covered by [CC-BY-NC-ND 4.0](https://creativecommons.org/licenses/by-nc-nd/4.0/)
- https://github.com/osmandapp/Osmand/tree/master/OsmAnd/res and others
Restriction to UI/UX CC-BY-NC-ND:
- * Publishing applications using the OsmAnd UI/UX code to Google Play, Amazon Market or Apple Store must be done with written permission*
+ * Publishing applications using the OsmAnd UI/UX code to Google Play, Amazon Market, or Apple Store must be done with written permission.*
* Map icons are taken from sjjb and some are drawn and distributed under Public Domain (except icons8)
- https://github.com/osmandapp/OsmAnd-resources/tree/master/icons/svg
- some icons are from http://osm-icons.org/wiki/Icons (CC-0 by Markus59, CC BY-SA 2.0)
- * Integration with Qt library in (https://github.com/osmandapp/Osmand-core/) - dynamic linking
- - LGPL (http://www.qt.io/qt-licensing-terms/)
+ * Integration with Qt library in (https://github.com/osmandapp/OsmAnd-core) - dynamic linking
+ - LGPL (https://www.qt.io/terms-conditions/)
- * Map icons and their derived primitives are covered by proprietary license:
+ * Map icons and their derived primitives are covered by a proprietary license:
- © icons8.com (https://github.com/osmandapp/OsmAnd-resources/tree/master/icons/svg/icons8)
- * Generated voice files from TTS files are covered by proprietary license:
+ * Generated voice files from TTS files are covered by a proprietary license:
- Voice files (https://github.com/osmandapp/OsmAnd-resources/tree/master/voice)
* Fonts (https://github.com/osmandapp/OsmAnd-resources/tree/master/rendering_styles/fonts)
- - Google Fonts (Apache License 2)
+ - Google Fonts (Apache License 2.0)
* Map icons (Mapnik):
- Open-SVG-Map-Icons - Public Domain
@@ -65,49 +65,27 @@
- SherlockBar - Apache License - https://github.com/osmandapp/Osmand/tree/master/SherlockBar (https://github.com/JakeWharton/ActionBarSherlock/blob/master/LICENSE.txt)
* Patched libraries:
- - Protobuf - New BSD License (patches - https://github.com/osmandapp/Osmand/tree/master/OsmAnd-java/protobuf-src, https://github.com/osmandapp/OsmAnd-core/tree/legacy_core/externals/protobuf)
- - Expat - (https://github.com/osmandapp/OsmAnd-core/tree/legacy_core/externals/expat)
- - Freetype - (https://github.com/osmandapp/OsmAnd-core/tree/legacy_core/externals/freetype)
- - Giflib - (https://github.com/osmandapp/OsmAnd-core/tree/legacy_core/externals/giflib)
+ - Protobuf - New BSD License (patches - https://github.com/osmandapp/Osmand/tree/master/OsmAnd-java/src/main/java/com/google/protobuf, https://github.com/osmandapp/OsmAnd-core/tree/legacy_core/externals/protobuf)
- Jpeg - (https://github.com/osmandapp/OsmAnd-core/tree/legacy_core/externals/jpeg)
- - Libpng - (https://github.com/osmandapp/OsmAnd-core/tree/legacy_core/externals/libpng)
- Skia - (https://github.com/osmandapp/OsmAnd-core/tree/legacy_core/externals/skia)
- - ZLib - (https://github.com/osmandapp/OsmAnd-core/tree/legacy_core/externals/zlib)
+ - android-openmap-framework - (https://github.com/osmandapp/Osmand/tree/master/OsmAnd-java/src/main/java/com/jwetherell/openmap/common)
+ - mapbox-vector-tile - (https://github.com/osmandapp/Osmand/tree/master/OsmAnd-java/src/main/java/com/wdtinc/mapbox_vector_tile)
* 3rd party libraries present in the libs folder (https://github.com/osmandapp/Osmand/tree/master/OsmAnd-java/libs):
- - bzip2-20090327.jar Bzip2 - Apache License
- - commons-logging-1.1.1.jar - Apache License
- gnu-trove-osmand.jar GNU trove - LGPL
- - icu4j-49_1.jar - ICU license (http://source.icu-project.org/repos/icu/icu/trunk/license.html)
- - json-20090211.jar - BSD alike (http://www.json.org/license.html)
- - junidecode-0.1.jar - BSD-4-Clause-UC (http://sourceforge.net/projects/junidecode/)
- - kxml2-2.3.0.jar - BSD license (http://www.kxml.org/)
- - tuprolog.jar - LGPL (http://apice.unibo.it/xwiki/bin/view/Tuprolog/)
- - OpenMap framework - Apache License (https://code.google.com/p/android-openmap-framework/)
+ - icu4j-49_1_patched.jar - ICU license (https://home.unicode.org/basic-info/projects/#/icu/icu/trunk/license.html)
* Pull-requests and translations:
- - All pull requests are accepted under MIT License (most honorable contributors are mentioned in AUTHORS list)
-
- * Libraries not used in final product (https://github.com/osmandapp/OsmAnd-tools/tree/master/OsmAndMapCreator/libi)
- - Ant libraries - (tools) https://github.com/osmandapp/Osmand/tree/master/OsmAnd/ant-lib
- - jleveldb-v01.jar
- - jsch-20120101.jar
- - junit-4.10.jar
- - mysql-connector-java-5.1.18-bin.jar
- - sqlite-jdbc-3.7.6.3-20110609.081603-3.jar
- - h2-latest.jar
+ - All pull requests are accepted under MIT License (most honorable contributors are mentioned in AUTHORS list).
* Special tools for new rendering (GPLv3)
- - https://github.com/osmandapp/OsmAnd-tools/tree/master/obf-inspector
- - https://github.com/osmandapp/OsmAnd-tools/tree/master/obf-verifier
- - https://github.com/osmandapp/OsmAnd-tools/tree/master/route-tester
+ - https://github.com/osmandapp/OsmAnd-tools
- * OSM data 2014
- - Extracts - https://github.com/osmandapp/OsmAnd-misc/blob/master/osm-planet/osm-data/
+ * OSM data
+ - Extracts - https://github.com/osmandapp/OsmAnd-misc/tree/master/osm-planet/osm-data
* Data files
- - Country boundaries - https://github.com/osmandapp/OsmAnd-misc/tree/master/osm-planet/geo-polygons © by Geofabrik - data free to use
- - Country boundaries - https://github.com/osmandapp/OsmAnd-misc/tree/master/osm-planet/gislab-polygons © by http://be.gis-lab.info - data free to use
+ - Country boundaries - https://github.com/osmandapp/OsmAnd-misc/tree/master/osm-planet/polygons © by Geofabrik - data free to use
* Subway icons
- Moscow: Art Lebedev Studio (http://www.artlebedev.ru/everything/metro/logo/) [Public domain], undefined
@@ -119,7 +97,7 @@
- Kazan: «Kazan-metro-Logo» (Россиянин) - own work. Under Public domain Commons license from the site - https://commons.wikimedia.org/wiki/File:Kazan-metro-Logo.svg#/media/File:Kazan-metro-Logo.svg
- Tbilisi: «Metro Tbilisi logo» (Carnby) - own work. Under CC BY-SA 3.0 license from site - https://commons.wikimedia.org/wiki/File:Metro_Tbilisi_logo.svg#/media/File:Metro_Tbilisi_logo.svg
- Minsk: «Minsk metro logo» (Skip405) - own work. Under Public domain Commons license from the site - https://commons.wikimedia.org/wiki/File:Minsk_metro_logo.svg#/media/File:Minsk_metro_logo.svg
- - Nizhny Novgorod: «NNMetro» (AlexTref871) - own work. This vector image includes elements borrowed from another image: Coat of arms of Nizhny Novgorod Region.svg.. Under Public domain Commons licensefrom the site - https://commons.wikimedia.org/wiki/File:NNMetro.svg#/media/File:NNMetro.svg
+ - Nizhny Novgorod: «NNMetro» (AlexTref871) - own work. This vector image includes elements borrowed from another image: Coat of arms of Nizhny Novgorod Region.svg.. Under Public domain Commons licensefrom the site - https://commons.wikimedia.org/wiki/File:NNMetro.svg#/media/File:NNMetro.svg
- Novosibirsk: «Logo-Nsk-Metro» (AlexTref871) - own work. Under Public domain Commons license from the site - https://commons.wikimedia.org/wiki/File:Logo-Nsk-Metro.svg#/media/File:Logo-Nsk-Metro.svg
- Yekaterinburg: «Ekt-metro-logo-01» (AlexTref871) - own work. Under CC BY-SA 4.0 license from site - https://commons.wikimedia.org/wiki/File:Ekt-metro-logo-01.svg#/media/File:Ekt-metro-logo-01.svg
- New York: «MTA New York City Subway logo» (Metropolitan Transportation Authority) - http://mta.info/. Under Public domain Commons license from the site - https://commons.wikimedia.org/wiki/File:MTA_New_York_City_Subway_logo.svg#/media/File:MTA_New_York_City_Subway_logo.svg
@@ -152,7 +130,7 @@
- Los Angeles: "Lametro" by Los Angeles County Metropolitan Transportation Authority. Original uploader was Cheeselouise at en.wikipedia - Metro materials at http://www.metro.net/riding_metro/pocket_guide_cambodian_printers.pdf. Licensed under Public Domain via Commons - https://commons.wikimedia.org/wiki/File:Lametro.svg#/media/File:Lametro.svg
* Depth maps
- - The GEBCO_2014 Grid, version 20150318, www.gebco.net
+ - The GEBCO_2020 Grid, www.gebco.net
- U.S. Bureau of Ocean Energy Management (24 may 2017,12m per pixel)
- South_Padre_Island_DEM_4133: Grothe, P.G., L.A. Taylor, B.W. Eakins, K.S. Carignan, D.Z. Friday, and M. Love, 2012. Digital Elevation Models of South Padre Island, Texas: Procedures, Data Sources and Analysis, NOAA National Geophysical Data Center technical report, Boulder, CO, 15 pp.
- Corpus_Christi_DEM_1035: Taylor, L.A., B.W. Eakins, K.S. Carignan, R.R. Warnken, T. Sazonova, and D.C. Schoolcraft, 2008. Digital Elevation Model of Corpus Christi, Texas: Procedures, Data Sources and Analysis, NOAA Technical Memorandum NESDIS NGDC-11, National Geophysical Data Center, Boulder, CO, 19 pp.
diff --git a/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlCallback.aidl b/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlCallback.aidl
index 1d7f954815..0598f31854 100644
--- a/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlCallback.aidl
+++ b/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlCallback.aidl
@@ -51,4 +51,9 @@ interface IOsmAndAidlCallback {
* Callback for {@link IOsmAndAidlInterface} registerForVoiceRouterMessages() method.
*/
void onVoiceRouterNotify(in OnVoiceNavigationParams params);
+
+ /**
+ * Callback for {@link IOsmAndAidlInterface} registerForKeyEvents() method.
+ */
+ void onKeyEvent(in KeyEvent params);
}
\ No newline at end of file
diff --git a/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlInterface.aidl b/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlInterface.aidl
index 45bf3907f7..72a3035b60 100644
--- a/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlInterface.aidl
+++ b/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlInterface.aidl
@@ -20,6 +20,8 @@ import net.osmand.aidlapi.mapmarker.UpdateMapMarkerParams;
import net.osmand.aidlapi.calculateroute.CalculateRouteParams;
+import net.osmand.aidlapi.profile.ExportProfileParams;
+
import net.osmand.aidlapi.gpx.ImportGpxParams;
import net.osmand.aidlapi.gpx.ShowGpxParams;
import net.osmand.aidlapi.gpx.StartGpxRecordingParams;
@@ -74,6 +76,7 @@ import net.osmand.aidlapi.customization.OsmandSettingsParams;
import net.osmand.aidlapi.customization.OsmandSettingsInfoParams;
import net.osmand.aidlapi.customization.CustomizationInfoParams;
import net.osmand.aidlapi.customization.ProfileSettingsParams;
+import net.osmand.aidlapi.customization.MapMarginsParams;
import net.osmand.aidlapi.gpx.AGpxFile;
import net.osmand.aidlapi.gpx.AGpxFileDetails;
@@ -96,6 +99,14 @@ import net.osmand.aidlapi.mapmarker.RemoveMapMarkersParams;
import net.osmand.aidlapi.quickaction.QuickActionParams;
import net.osmand.aidlapi.quickaction.QuickActionInfoParams;
+import net.osmand.aidlapi.lock.SetLockStateParams;
+
+import net.osmand.aidlapi.events.AKeyEventsParams;
+
+import net.osmand.aidlapi.info.AppInfoParams;
+
+import net.osmand.aidlapi.profile.ExportProfileParams;
+
// NOTE: Add new methods at the end of file!!!
interface IOsmAndAidlInterface {
@@ -841,4 +852,25 @@ interface IOsmAndAidlInterface {
boolean executeQuickAction(in QuickActionParams params);
boolean getQuickActionsInfo(out List quickActions);
+
+ /**
+ * Toggle Lock/Unlock screen.
+ */
+ boolean setLockState(in SetLockStateParams params);
+
+ /**
+ * Method to register for key events.
+ *
+ * @params subscribeToUpdates (boolean) - boolean flag to subscribe or unsubscribe from key events
+ * @params callbackId (long) - id of callback, needed to unsubscribe key events
+ * @params callback (IOsmAndAidlCallback) - callback to notify user on key event
+ * @params keyEventList (List) - list of requested key events
+ */
+ long registerForKeyEvents(in AKeyEventsParams params, IOsmAndAidlCallback callback);
+
+ AppInfoParams getAppInfo();
+
+ boolean setMapMargins(in MapMarginsParams params);
+
+ boolean exportProfile(in ExportProfileParams params);
}
\ No newline at end of file
diff --git a/OsmAnd-api/src/net/osmand/aidlapi/OsmAndCustomizationConstants.java b/OsmAnd-api/src/net/osmand/aidlapi/OsmAndCustomizationConstants.java
index 2e1543321a..af48552bc4 100644
--- a/OsmAnd-api/src/net/osmand/aidlapi/OsmAndCustomizationConstants.java
+++ b/OsmAnd-api/src/net/osmand/aidlapi/OsmAndCustomizationConstants.java
@@ -4,6 +4,8 @@ public interface OsmAndCustomizationConstants {
// Navigation Drawer:
String DRAWER_ITEM_ID_SCHEME = "drawer.action.";
+ String DRAWER_SWITCH_PROFILE_ID = DRAWER_ITEM_ID_SCHEME + "switch_profile";
+ String DRAWER_CONFIGURE_PROFILE_ID = DRAWER_ITEM_ID_SCHEME + "configure_profile";
String DRAWER_DASHBOARD_ID = DRAWER_ITEM_ID_SCHEME + "dashboard";
String DRAWER_MAP_MARKERS_ID = DRAWER_ITEM_ID_SCHEME + "map_markers";
String DRAWER_MY_PLACES_ID = DRAWER_ITEM_ID_SCHEME + "my_places";
diff --git a/OsmAnd-api/src/net/osmand/aidlapi/copyfile/CopyFileParams.java b/OsmAnd-api/src/net/osmand/aidlapi/copyfile/CopyFileParams.java
index 1118a17f5c..ad122f60c6 100644
--- a/OsmAnd-api/src/net/osmand/aidlapi/copyfile/CopyFileParams.java
+++ b/OsmAnd-api/src/net/osmand/aidlapi/copyfile/CopyFileParams.java
@@ -9,12 +9,21 @@ import net.osmand.aidlapi.AidlParams;
public class CopyFileParams extends AidlParams {
+ public static final String DESTINATION_DIR_KEY = "destinationDir";
+ public static final String FILE_NAME_KEY = "fileName";
+ public static final String FILE_PART_DATA_KEY = "filePartData";
+ public static final String START_TIME_KEY = "startTime";
+ public static final String DONE_KEY = "done";
+ private String destinationDir;
private String fileName;
private byte[] filePartData;
private long startTime;
private boolean done;
- public CopyFileParams(@NonNull String fileName, @NonNull byte[] filePartData, long startTime, boolean done) {
+ public CopyFileParams(@NonNull String destinationDir, @NonNull String fileName, @NonNull byte[] filePartData,
+ long startTime, boolean done) {
+
+ this.destinationDir = destinationDir;
this.fileName = fileName;
this.filePartData = filePartData;
this.startTime = startTime;
@@ -37,6 +46,10 @@ public class CopyFileParams extends AidlParams {
}
};
+ public String getDestinationDir() {
+ return destinationDir;
+ }
+
public String getFileName() {
return fileName;
}
@@ -55,23 +68,26 @@ public class CopyFileParams extends AidlParams {
@Override
public void writeToBundle(Bundle bundle) {
- bundle.putString("fileName", fileName);
- bundle.putByteArray("filePartData", filePartData);
- bundle.putLong("startTime", startTime);
- bundle.putBoolean("done", done);
+ bundle.putString(DESTINATION_DIR_KEY, destinationDir);
+ bundle.putString(FILE_NAME_KEY, fileName);
+ bundle.putByteArray(FILE_PART_DATA_KEY, filePartData);
+ bundle.putLong(START_TIME_KEY, startTime);
+ bundle.putBoolean(DONE_KEY, done);
}
@Override
protected void readFromBundle(Bundle bundle) {
- fileName = bundle.getString("fileName");
- filePartData = bundle.getByteArray("filePartData");
- startTime = bundle.getLong("startTime");
- done = bundle.getBoolean("done");
+ destinationDir = bundle.getString(DESTINATION_DIR_KEY);
+ fileName = bundle.getString(FILE_NAME_KEY);
+ filePartData = bundle.getByteArray(FILE_PART_DATA_KEY);
+ startTime = bundle.getLong(START_TIME_KEY);
+ done = bundle.getBoolean(DONE_KEY);
}
@Override
public String toString() {
return "CopyFileParams {" +
+ " destinationDir=" + destinationDir +
" fileName=" + fileName +
", filePartData size=" + filePartData.length +
", startTime=" + startTime +
diff --git a/OsmAnd-api/src/net/osmand/aidlapi/customization/MapMarginsParams.aidl b/OsmAnd-api/src/net/osmand/aidlapi/customization/MapMarginsParams.aidl
new file mode 100644
index 0000000000..6cba21877e
--- /dev/null
+++ b/OsmAnd-api/src/net/osmand/aidlapi/customization/MapMarginsParams.aidl
@@ -0,0 +1,3 @@
+package net.osmand.aidlapi.customization;
+
+parcelable MapMarginsParams;
\ No newline at end of file
diff --git a/OsmAnd-api/src/net/osmand/aidlapi/customization/MapMarginsParams.java b/OsmAnd-api/src/net/osmand/aidlapi/customization/MapMarginsParams.java
new file mode 100644
index 0000000000..8b810a81b4
--- /dev/null
+++ b/OsmAnd-api/src/net/osmand/aidlapi/customization/MapMarginsParams.java
@@ -0,0 +1,77 @@
+package net.osmand.aidlapi.customization;
+
+import android.os.Bundle;
+import android.os.Parcel;
+
+import net.osmand.aidlapi.AidlParams;
+
+public class MapMarginsParams extends AidlParams {
+
+ private String appModeKey;
+ private int leftMargin;
+ private int topMargin;
+ private int rightMargin;
+ private int bottomMargin;
+
+ public MapMarginsParams(String appModeKey, int leftMargin, int topMargin, int rightMargin, int bottomMargin) {
+ this.appModeKey = appModeKey;
+ this.leftMargin = leftMargin;
+ this.topMargin = topMargin;
+ this.rightMargin = rightMargin;
+ this.bottomMargin = bottomMargin;
+ }
+
+ public MapMarginsParams(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public static final Creator CREATOR = new Creator() {
+ @Override
+ public MapMarginsParams createFromParcel(Parcel in) {
+ return new MapMarginsParams(in);
+ }
+
+ @Override
+ public MapMarginsParams[] newArray(int size) {
+ return new MapMarginsParams[size];
+ }
+ };
+
+ public String getAppModeKey() {
+ return appModeKey;
+ }
+
+ public int getLeftMargin() {
+ return leftMargin;
+ }
+
+ public int getTopMargin() {
+ return topMargin;
+ }
+
+ public int getRightMargin() {
+ return rightMargin;
+ }
+
+ public int getBottomMargin() {
+ return bottomMargin;
+ }
+
+ @Override
+ public void writeToBundle(Bundle bundle) {
+ bundle.putString("appModeKey", appModeKey);
+ bundle.putInt("leftMargin", leftMargin);
+ bundle.putInt("topMargin", topMargin);
+ bundle.putInt("rightMargin", rightMargin);
+ bundle.putInt("bottomMargin", bottomMargin);
+ }
+
+ @Override
+ protected void readFromBundle(Bundle bundle) {
+ appModeKey = bundle.getString("appModeKey");
+ leftMargin = bundle.getInt("leftMargin");
+ topMargin = bundle.getInt("topMargin");
+ rightMargin = bundle.getInt("rightMargin");
+ bottomMargin = bundle.getInt("bottomMargin");
+ }
+}
\ No newline at end of file
diff --git a/OsmAnd-api/src/net/osmand/aidlapi/customization/ProfileSettingsParams.java b/OsmAnd-api/src/net/osmand/aidlapi/customization/ProfileSettingsParams.java
index 36959ef776..00c68851e7 100644
--- a/OsmAnd-api/src/net/osmand/aidlapi/customization/ProfileSettingsParams.java
+++ b/OsmAnd-api/src/net/osmand/aidlapi/customization/ProfileSettingsParams.java
@@ -5,15 +5,31 @@ import android.os.Bundle;
import android.os.Parcel;
import net.osmand.aidlapi.AidlParams;
+import net.osmand.aidlapi.profile.AExportSettingsType;
+
+import java.util.ArrayList;
+
+import static net.osmand.aidlapi.profile.ExportProfileParams.SETTINGS_TYPE_KEY;
public class ProfileSettingsParams extends AidlParams {
+ public static final String VERSION_KEY = "version";
+ public static final String REPLACE_KEY = "replace";
+ public static final String LATEST_CHANGES_KEY = "latestChanges";
+ public static final String PROFILE_SETTINGS_URI_KEY = "profileSettingsUri";
private Uri profileSettingsUri;
private String latestChanges;
private int version;
+ private ArrayList settingsTypeKeyList = new ArrayList<>();
+ boolean replace;
- public ProfileSettingsParams(Uri profileSettingsUri, String latestChanges, int version) {
+ public ProfileSettingsParams(Uri profileSettingsUri, ArrayList settingsTypeList, boolean replace,
+ String latestChanges, int version) {
this.profileSettingsUri = profileSettingsUri;
+ for (AExportSettingsType settingsType : settingsTypeList) {
+ settingsTypeKeyList.add(settingsType.name());
+ }
+ this.replace = replace;
this.latestChanges = latestChanges;
this.version = version;
}
@@ -46,17 +62,29 @@ public class ProfileSettingsParams extends AidlParams {
return profileSettingsUri;
}
+ public ArrayList getSettingsTypeKeys() {
+ return settingsTypeKeyList;
+ }
+
+ public boolean isReplace() {
+ return replace;
+ }
+
@Override
public void writeToBundle(Bundle bundle) {
- bundle.putInt("version", version);
- bundle.putString("latestChanges", latestChanges);
- bundle.putParcelable("profileSettingsUri", profileSettingsUri);
+ bundle.putInt(VERSION_KEY, version);
+ bundle.putString(LATEST_CHANGES_KEY, latestChanges);
+ bundle.putParcelable(PROFILE_SETTINGS_URI_KEY, profileSettingsUri);
+ bundle.putStringArrayList(SETTINGS_TYPE_KEY, settingsTypeKeyList);
+ bundle.putBoolean(REPLACE_KEY, replace);
}
@Override
protected void readFromBundle(Bundle bundle) {
- version = bundle.getInt("version");
- latestChanges = bundle.getString("latestChanges");
- profileSettingsUri = bundle.getParcelable("profileSettingsUri");
+ version = bundle.getInt(VERSION_KEY);
+ latestChanges = bundle.getString(LATEST_CHANGES_KEY);
+ profileSettingsUri = bundle.getParcelable(PROFILE_SETTINGS_URI_KEY);
+ settingsTypeKeyList = bundle.getStringArrayList(SETTINGS_TYPE_KEY);
+ replace = bundle.getBoolean(REPLACE_KEY);
}
}
\ No newline at end of file
diff --git a/OsmAnd-api/src/net/osmand/aidlapi/events/AKeyEventsParams.aidl b/OsmAnd-api/src/net/osmand/aidlapi/events/AKeyEventsParams.aidl
new file mode 100644
index 0000000000..972b2cb218
--- /dev/null
+++ b/OsmAnd-api/src/net/osmand/aidlapi/events/AKeyEventsParams.aidl
@@ -0,0 +1,2 @@
+package net.osmand.aidlapi.events;
+parcelable AKeyEventsParams;
\ No newline at end of file
diff --git a/OsmAnd-api/src/net/osmand/aidlapi/events/AKeyEventsParams.java b/OsmAnd-api/src/net/osmand/aidlapi/events/AKeyEventsParams.java
new file mode 100644
index 0000000000..83c4d4368e
--- /dev/null
+++ b/OsmAnd-api/src/net/osmand/aidlapi/events/AKeyEventsParams.java
@@ -0,0 +1,73 @@
+package net.osmand.aidlapi.events;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import net.osmand.aidlapi.AidlParams;
+
+import java.util.ArrayList;
+
+public class AKeyEventsParams extends AidlParams {
+
+ private long callbackId = -1L;
+ private boolean subscribeToUpdates = true;
+ private ArrayList keyEventList;
+
+ public AKeyEventsParams() {
+ }
+
+ protected AKeyEventsParams(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
+ @Override
+ public AKeyEventsParams createFromParcel(Parcel in) {
+ return new AKeyEventsParams(in);
+ }
+
+ @Override
+ public AKeyEventsParams[] newArray(int size) {
+ return new AKeyEventsParams[size];
+ }
+ };
+
+ public long getCallbackId() {
+ return callbackId;
+ }
+
+ public void setCallbackId(long callbackId) {
+ this.callbackId = callbackId;
+ }
+
+ public void setSubscribeToUpdates(boolean subscribeToUpdates) {
+ this.subscribeToUpdates = subscribeToUpdates;
+ }
+
+ public boolean isSubscribeToUpdates() {
+ return subscribeToUpdates;
+ }
+
+ public void setKeyEventList(ArrayList keyEventList) {
+ this.keyEventList = keyEventList;
+ }
+
+ public ArrayList getKeyEventList() {
+ return keyEventList;
+ }
+
+ @Override
+ protected void readFromBundle(Bundle bundle) {
+ callbackId = bundle.getLong("callbackId");
+ subscribeToUpdates = bundle.getBoolean("subscribeToUpdates");
+ keyEventList = bundle.getIntegerArrayList("keyEventList");
+ }
+
+ @Override
+ public void writeToBundle(Bundle bundle) {
+ bundle.putLong("callbackId", callbackId);
+ bundle.putBoolean("subscribeToUpdates", subscribeToUpdates);
+ bundle.putIntegerArrayList("keyEventList", keyEventList);
+ }
+}
\ No newline at end of file
diff --git a/OsmAnd-api/src/net/osmand/aidlapi/favorite/AFavorite.java b/OsmAnd-api/src/net/osmand/aidlapi/favorite/AFavorite.java
index 1e645d2fae..39daf1d2a2 100644
--- a/OsmAnd-api/src/net/osmand/aidlapi/favorite/AFavorite.java
+++ b/OsmAnd-api/src/net/osmand/aidlapi/favorite/AFavorite.java
@@ -11,16 +11,18 @@ public class AFavorite extends AidlParams {
private double lon;
private String name;
private String description;
+ private String address;
private String category;
private String color;
private boolean visible;
- public AFavorite(double lat, double lon, String name, String description,
+ public AFavorite(double lat, double lon, String name, String description, String address,
String category, String color, boolean visible) {
this.lat = lat;
this.lon = lon;
this.name = name;
this.description = description;
+ this.address = address;
this.category = category;
this.color = color;
this.visible = visible;
@@ -58,6 +60,8 @@ public class AFavorite extends AidlParams {
return description;
}
+ public String getAddress() { return address; }
+
public String getCategory() {
return category;
}
@@ -76,6 +80,7 @@ public class AFavorite extends AidlParams {
bundle.putDouble("lon", lon);
bundle.putString("name", name);
bundle.putString("description", description);
+ bundle.putString("address", address);
bundle.putString("category", category);
bundle.putString("color", color);
bundle.putBoolean("visible", visible);
@@ -87,6 +92,7 @@ public class AFavorite extends AidlParams {
lon = bundle.getDouble("lon");
name = bundle.getString("name");
description = bundle.getString("description");
+ address = bundle.getString("address");
category = bundle.getString("category");
color = bundle.getString("color");
visible = bundle.getBoolean("visible");
diff --git a/OsmAnd-api/src/net/osmand/aidlapi/info/AppInfoParams.aidl b/OsmAnd-api/src/net/osmand/aidlapi/info/AppInfoParams.aidl
new file mode 100644
index 0000000000..0030d5376c
--- /dev/null
+++ b/OsmAnd-api/src/net/osmand/aidlapi/info/AppInfoParams.aidl
@@ -0,0 +1,3 @@
+package net.osmand.aidlapi.info;
+
+parcelable AppInfoParams;
\ No newline at end of file
diff --git a/OsmAnd-api/src/net/osmand/aidlapi/info/AppInfoParams.java b/OsmAnd-api/src/net/osmand/aidlapi/info/AppInfoParams.java
new file mode 100644
index 0000000000..8b6b2c236a
--- /dev/null
+++ b/OsmAnd-api/src/net/osmand/aidlapi/info/AppInfoParams.java
@@ -0,0 +1,95 @@
+package net.osmand.aidlapi.info;
+
+import android.os.Bundle;
+import android.os.Parcel;
+
+import net.osmand.aidlapi.AidlParams;
+import net.osmand.aidlapi.map.ALatLon;
+
+public class AppInfoParams extends AidlParams {
+
+ private ALatLon lastKnownLocation;
+ private ALatLon mapLocation;
+
+ private Bundle turnInfo;
+ private int leftTime;
+ private int leftDistance;
+ private long arrivalTime;
+ private boolean mapVisible;
+
+ public AppInfoParams(ALatLon lastKnownLocation, ALatLon mapLocation, Bundle turnInfo, int leftTime, int leftDistance, long arrivalTime, boolean mapVisible) {
+ this.lastKnownLocation = lastKnownLocation;
+ this.mapLocation = mapLocation;
+ this.leftTime = leftTime;
+ this.leftDistance = leftDistance;
+ this.arrivalTime = arrivalTime;
+ this.turnInfo = turnInfo;
+ this.mapVisible = mapVisible;
+ }
+
+ public AppInfoParams(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public static final Creator CREATOR = new Creator() {
+ @Override
+ public AppInfoParams createFromParcel(Parcel in) {
+ return new AppInfoParams(in);
+ }
+
+ @Override
+ public AppInfoParams[] newArray(int size) {
+ return new AppInfoParams[size];
+ }
+ };
+
+ public ALatLon getLastKnownLocation() {
+ return lastKnownLocation;
+ }
+
+ public ALatLon getMapLocation() {
+ return mapLocation;
+ }
+
+ public int getLeftTime() {
+ return leftTime;
+ }
+
+ public long getArrivalTime() {
+ return arrivalTime;
+ }
+
+ public int getLeftDistance() {
+ return leftDistance;
+ }
+
+ public boolean isMapVisible() {
+ return mapVisible;
+ }
+
+ public Bundle getTurnInfo() {
+ return turnInfo;
+ }
+
+ @Override
+ public void writeToBundle(Bundle bundle) {
+ bundle.putParcelable("lastKnownLocation", lastKnownLocation);
+ bundle.putParcelable("mapLocation", mapLocation);
+ bundle.putInt("leftTime", leftTime);
+ bundle.putLong("arrivalTime", arrivalTime);
+ bundle.putInt("leftDistance", leftDistance);
+ bundle.putBundle("turnInfo", turnInfo);
+ bundle.putBoolean("mapVisible", mapVisible);
+ }
+
+ @Override
+ protected void readFromBundle(Bundle bundle) {
+ lastKnownLocation = bundle.getParcelable("lastKnownLocation");
+ mapLocation = bundle.getParcelable("mapLocation");
+ leftTime = bundle.getInt("leftTime");
+ arrivalTime = bundle.getLong("arrivalTime");
+ leftDistance = bundle.getInt("leftDistance");
+ turnInfo = bundle.getBundle("turnInfo");
+ mapVisible = bundle.getBoolean("mapVisible");
+ }
+}
\ No newline at end of file
diff --git a/OsmAnd-api/src/net/osmand/aidlapi/lock/SetLockStateParams.aidl b/OsmAnd-api/src/net/osmand/aidlapi/lock/SetLockStateParams.aidl
new file mode 100644
index 0000000000..332f768344
--- /dev/null
+++ b/OsmAnd-api/src/net/osmand/aidlapi/lock/SetLockStateParams.aidl
@@ -0,0 +1,3 @@
+package net.osmand.aidlapi.lock;
+
+parcelable SetLockStateParams;
\ No newline at end of file
diff --git a/OsmAnd-api/src/net/osmand/aidlapi/lock/SetLockStateParams.java b/OsmAnd-api/src/net/osmand/aidlapi/lock/SetLockStateParams.java
new file mode 100644
index 0000000000..0b71c750df
--- /dev/null
+++ b/OsmAnd-api/src/net/osmand/aidlapi/lock/SetLockStateParams.java
@@ -0,0 +1,45 @@
+package net.osmand.aidlapi.lock;
+
+import android.os.Bundle;
+import android.os.Parcel;
+
+import net.osmand.aidlapi.AidlParams;
+
+public class SetLockStateParams extends AidlParams {
+
+ private boolean lock;
+
+ public SetLockStateParams(boolean lock) {
+ this.lock = lock;
+ }
+
+ public SetLockStateParams(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public static final Creator CREATOR = new Creator() {
+ @Override
+ public SetLockStateParams createFromParcel(Parcel in) {
+ return new SetLockStateParams(in);
+ }
+
+ @Override
+ public SetLockStateParams[] newArray(int size) {
+ return new SetLockStateParams[size];
+ }
+ };
+
+ public boolean getLockState() {
+ return lock;
+ }
+
+ @Override
+ public void writeToBundle(Bundle bundle) {
+ bundle.putBoolean("lock", this.lock);
+ }
+
+ @Override
+ protected void readFromBundle(Bundle bundle) {
+ lock = bundle.getBoolean("lock");
+ }
+}
\ No newline at end of file
diff --git a/OsmAnd-api/src/net/osmand/aidlapi/map/SetMapLocationParams.java b/OsmAnd-api/src/net/osmand/aidlapi/map/SetMapLocationParams.java
index 9da5ee83f0..d441682da5 100644
--- a/OsmAnd-api/src/net/osmand/aidlapi/map/SetMapLocationParams.java
+++ b/OsmAnd-api/src/net/osmand/aidlapi/map/SetMapLocationParams.java
@@ -10,12 +10,14 @@ public class SetMapLocationParams extends AidlParams {
private double latitude;
private double longitude;
private int zoom;
+ private float rotation;
private boolean animated;
- public SetMapLocationParams(double latitude, double longitude, int zoom, boolean animated) {
+ public SetMapLocationParams(double latitude, double longitude, int zoom, float rotation, boolean animated) {
this.latitude = latitude;
this.longitude = longitude;
this.zoom = zoom;
+ this.rotation = rotation;
this.animated = animated;
}
@@ -47,6 +49,10 @@ public class SetMapLocationParams extends AidlParams {
return zoom;
}
+ public float getRotation() {
+ return rotation;
+ }
+
public boolean isAnimated() {
return animated;
}
@@ -56,6 +62,7 @@ public class SetMapLocationParams extends AidlParams {
bundle.putDouble("latitude", latitude);
bundle.putDouble("longitude", longitude);
bundle.putInt("zoom", zoom);
+ bundle.putFloat("rotation", rotation);
bundle.putBoolean("animated", animated);
}
@@ -64,6 +71,7 @@ public class SetMapLocationParams extends AidlParams {
latitude = bundle.getDouble("latitude");
longitude = bundle.getDouble("longitude");
zoom = bundle.getInt("zoom");
+ rotation = bundle.getFloat("rotation");
animated = bundle.getBoolean("animated");
}
}
\ No newline at end of file
diff --git a/OsmAnd-api/src/net/osmand/aidlapi/profile/AExportSettingsType.aidl b/OsmAnd-api/src/net/osmand/aidlapi/profile/AExportSettingsType.aidl
new file mode 100644
index 0000000000..99c59bba2a
--- /dev/null
+++ b/OsmAnd-api/src/net/osmand/aidlapi/profile/AExportSettingsType.aidl
@@ -0,0 +1,3 @@
+package net.osmand.aidlapi.profile;
+
+parcelable AExportSettingsType;
\ No newline at end of file
diff --git a/OsmAnd-api/src/net/osmand/aidlapi/profile/AExportSettingsType.java b/OsmAnd-api/src/net/osmand/aidlapi/profile/AExportSettingsType.java
new file mode 100644
index 0000000000..23c0189615
--- /dev/null
+++ b/OsmAnd-api/src/net/osmand/aidlapi/profile/AExportSettingsType.java
@@ -0,0 +1,11 @@
+package net.osmand.aidlapi.profile;
+
+public enum AExportSettingsType {
+ PROFILE,
+ QUICK_ACTIONS,
+ POI_TYPES,
+ MAP_SOURCES,
+ CUSTOM_RENDER_STYLE,
+ CUSTOM_ROUTING,
+ AVOID_ROADS;
+}
diff --git a/OsmAnd-api/src/net/osmand/aidlapi/profile/ExportProfileParams.aidl b/OsmAnd-api/src/net/osmand/aidlapi/profile/ExportProfileParams.aidl
new file mode 100644
index 0000000000..0dfefce6be
--- /dev/null
+++ b/OsmAnd-api/src/net/osmand/aidlapi/profile/ExportProfileParams.aidl
@@ -0,0 +1,3 @@
+package net.osmand.aidlapi.profile;
+
+parcelable ExportProfileParams;
\ No newline at end of file
diff --git a/OsmAnd-api/src/net/osmand/aidlapi/profile/ExportProfileParams.java b/OsmAnd-api/src/net/osmand/aidlapi/profile/ExportProfileParams.java
new file mode 100644
index 0000000000..931f52eeb8
--- /dev/null
+++ b/OsmAnd-api/src/net/osmand/aidlapi/profile/ExportProfileParams.java
@@ -0,0 +1,61 @@
+package net.osmand.aidlapi.profile;
+
+import android.os.Bundle;
+import android.os.Parcel;
+
+import net.osmand.aidlapi.AidlParams;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ExportProfileParams extends AidlParams {
+
+ public static final String PROFILE_KEY = "profile";
+ public static final String SETTINGS_TYPE_KEY = "settings_type";
+ private String profile;
+ private ArrayList settingsTypeKeyList = new ArrayList<>();
+
+ public ExportProfileParams(String profile, ArrayList settingsTypeList) {
+
+ this.profile = profile;
+ for (AExportSettingsType settingsType : settingsTypeList) {
+ settingsTypeKeyList.add(settingsType.name());
+ }
+ }
+
+ public ExportProfileParams(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public static final Creator CREATOR = new Creator() {
+ @Override
+ public ExportProfileParams createFromParcel(Parcel in) {
+ return new ExportProfileParams(in);
+ }
+
+ @Override
+ public ExportProfileParams[] newArray(int size) {
+ return new ExportProfileParams[size];
+ }
+ };
+
+ public String getProfile() {
+ return profile;
+ }
+
+ public List getSettingsTypeKeys() {
+ return settingsTypeKeyList;
+ }
+
+ @Override
+ public void writeToBundle(Bundle bundle) {
+ bundle.putString(PROFILE_KEY, profile);
+ bundle.putStringArrayList(SETTINGS_TYPE_KEY, settingsTypeKeyList);
+ }
+
+ @Override
+ protected void readFromBundle(Bundle bundle) {
+ profile = bundle.getString(PROFILE_KEY);
+ settingsTypeKeyList = bundle.getStringArrayList(SETTINGS_TYPE_KEY);
+ }
+}
\ No newline at end of file
diff --git a/OsmAnd-java/build.gradle b/OsmAnd-java/build.gradle
index ce0fc99dd1..4385f9d0b0 100644
--- a/OsmAnd-java/build.gradle
+++ b/OsmAnd-java/build.gradle
@@ -43,6 +43,7 @@ task collectTestResources(type: Copy) {
into "src/test/resources/"
from("../../resources/test-resources") {
include "*"
+ include "/search/*"
}
from("../../resources/poi") {
include "poi_types.xml"
diff --git a/OsmAnd-java/src/main/java/net/osmand/CollatorStringMatcher.java b/OsmAnd-java/src/main/java/net/osmand/CollatorStringMatcher.java
index 693be4bd82..8048595615 100644
--- a/OsmAnd-java/src/main/java/net/osmand/CollatorStringMatcher.java
+++ b/OsmAnd-java/src/main/java/net/osmand/CollatorStringMatcher.java
@@ -17,19 +17,34 @@ public class CollatorStringMatcher implements StringMatcher {
private final String part;
public static enum StringMatcherMode {
+ // tests only first word as base starts with part
CHECK_ONLY_STARTS_WITH,
+ // tests all words (split by space) and one of word should start with a given part
CHECK_STARTS_FROM_SPACE,
+ // tests all words except first (split by space) and one of word should start with a given part
CHECK_STARTS_FROM_SPACE_NOT_BEGINNING,
+ // tests all words (split by space) and one of word should be equal to part
CHECK_EQUALS_FROM_SPACE,
+ // simple collator contains in any part of the base
CHECK_CONTAINS,
- CHECK_ONLY_STARTS_WITH_TRIM,
+ // simple collator equals
CHECK_EQUALS,
}
public CollatorStringMatcher(String part, StringMatcherMode mode) {
this.collator = OsmAndCollator.primaryCollator();
- this.part = part.toLowerCase(Locale.getDefault());
+ part = simplifyStringAndAlignChars(part);
+ if (part.length() > 0 && part.charAt(part.length() - 1) == '.') {
+ part = part.substring(0, part.length() - 1);
+ if (mode == StringMatcherMode.CHECK_EQUALS_FROM_SPACE) {
+ mode = StringMatcherMode.CHECK_STARTS_FROM_SPACE;
+ } else if (mode == StringMatcherMode.CHECK_EQUALS) {
+ mode = StringMatcherMode.CHECK_ONLY_STARTS_WITH;
+ }
+ }
+ this.part = part;
this.mode = mode;
+
}
public Collator getCollator() {
@@ -42,22 +57,20 @@ public class CollatorStringMatcher implements StringMatcher {
}
- public static boolean cmatches(Collator collator, String base, String part, StringMatcherMode mode){
+ public static boolean cmatches(Collator collator, String fullName, String part, StringMatcherMode mode){
switch (mode) {
case CHECK_CONTAINS:
- return ccontains(collator, base, part);
+ return ccontains(collator, fullName, part);
case CHECK_EQUALS_FROM_SPACE:
- return cstartsWith(collator, base, part, true, true, true, false);
+ return cstartsWith(collator, fullName, part, true, true, true);
case CHECK_STARTS_FROM_SPACE:
- return cstartsWith(collator, base, part, true, true, false, false);
+ return cstartsWith(collator, fullName, part, true, true, false);
case CHECK_STARTS_FROM_SPACE_NOT_BEGINNING:
- return cstartsWith(collator, base, part, false, true, false, false);
+ return cstartsWith(collator, fullName, part, false, true, false);
case CHECK_ONLY_STARTS_WITH:
- return cstartsWith(collator, base, part, true, false, false, false);
- case CHECK_ONLY_STARTS_WITH_TRIM:
- return cstartsWith(collator, base, part, true, false, false, true);
+ return cstartsWith(collator, fullName, part, true, false, false);
case CHECK_EQUALS:
- return cstartsWith(collator, base, part, false, false, true, false);
+ return cstartsWith(collator, fullName, part, false, false, true);
}
return false;
}
@@ -116,25 +129,19 @@ public class CollatorStringMatcher implements StringMatcher {
* Special check try to find as well in the middle of name
*
* @param collator
- * @param searchInParam
+ * @param fullText
* @param theStart
- * @param trim - trim theStart to searchInParam length if searchInParam non empty
* @return true if searchIn starts with token
*/
- public static boolean cstartsWith(Collator collator, String searchInParam, String theStart,
- boolean checkBeginning, boolean checkSpaces, boolean equals, boolean trim) {
- String searchIn = searchInParam.toLowerCase(Locale.getDefault());
- if (trim && searchIn.length() > 0) {
- searchIn += " ";
- }
+ public static boolean cstartsWith(Collator collator, String fullTextP, String theStart,
+ boolean checkBeginning, boolean checkSpaces, boolean equals) {
+ String searchIn = simplifyStringAndAlignChars(fullTextP);
int searchInLength = searchIn.length();
- if (trim && searchInLength > 0 && theStart.length() > searchInLength) {
- theStart = theStart.substring(0, searchInLength);
- }
int startLength = theStart.length();
if (startLength == 0) {
return true;
}
+ // this is not correct because of Auhofstrasse != Auhofstraße
if (startLength > searchInLength) {
return false;
}
@@ -156,7 +163,8 @@ public class CollatorStringMatcher implements StringMatcher {
if (isSpace(searchIn.charAt(i - 1)) && !isSpace(searchIn.charAt(i))) {
if (collator.equals(searchIn.substring(i, i + startLength), theStart)) {
if(equals) {
- if(i + startLength == searchInLength || isSpace(searchIn.charAt(i + startLength))) {
+ if(i + startLength == searchInLength ||
+ isSpace(searchIn.charAt(i + startLength))) {
return true;
}
} else {
@@ -172,7 +180,17 @@ public class CollatorStringMatcher implements StringMatcher {
return false;
}
+ private static String simplifyStringAndAlignChars(String fullText) {
+ int i;
+ fullText = fullText.toLowerCase(Locale.getDefault());
+ while( (i = fullText.indexOf('ß') ) != -1 ) {
+ fullText = fullText.substring(0, i) + "ss" + fullText.substring(i+1);
+ }
+ return fullText;
+ }
+
private static boolean isSpace(char c){
return !Character.isLetter(c) && !Character.isDigit(c);
}
+
}
diff --git a/OsmAnd-java/src/main/java/net/osmand/GPXUtilities.java b/OsmAnd-java/src/main/java/net/osmand/GPXUtilities.java
index f3cb0f8b84..23afd7dd2a 100644
--- a/OsmAnd-java/src/main/java/net/osmand/GPXUtilities.java
+++ b/OsmAnd-java/src/main/java/net/osmand/GPXUtilities.java
@@ -1,6 +1,10 @@
package net.osmand;
+
+import net.osmand.binary.StringBundle;
+import net.osmand.binary.StringBundleWriter;
+import net.osmand.binary.StringBundleXmlWriter;
import net.osmand.data.QuadRect;
import net.osmand.util.Algorithms;
@@ -12,7 +16,6 @@ import org.xmlpull.v1.XmlSerializer;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
-import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -42,10 +45,14 @@ import java.util.Stack;
import java.util.TimeZone;
public class GPXUtilities {
+
public final static Log log = PlatformUtil.getLog(GPXUtilities.class);
+
private static final String ICON_NAME_EXTENSION = "icon";
private static final String DEFAULT_ICON_NAME = "special_star";
private static final String BACKGROUND_TYPE_EXTENSION = "background";
+ private static final String PROFILE_TYPE_EXTENSION = "profile";
+ private static final String TRKPT_INDEX_EXTENSION = "trkpt_idx";
private final static String GPX_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'"; //$NON-NLS-1$
private final static String GPX_TIME_FORMAT_MILLIS = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"; //$NON-NLS-1$
@@ -115,6 +122,20 @@ public class GPXUtilities {
return extensions;
}
+ public Map getExtensionsToWrite() {
+ if (extensions == null) {
+ extensions = new LinkedHashMap<>();
+ }
+ return extensions;
+ }
+
+ public void copyExtensions(GPXExtensions e) {
+ Map extensionsToRead = e.getExtensionsToRead();
+ if (!extensionsToRead.isEmpty()) {
+ getExtensionsToWrite().putAll(extensionsToRead);
+ }
+ }
+
public GPXExtensionsWriter getExtensionsWriter() {
return extensionsWriter;
}
@@ -148,14 +169,7 @@ public class GPXUtilities {
getExtensionsToWrite().remove("color");
}
- public Map getExtensionsToWrite() {
- if (extensions == null) {
- extensions = new LinkedHashMap<>();
- }
- return extensions;
- }
-
- private int parseColor(String colorString, int defColor) {
+ protected int parseColor(String colorString, int defColor) {
if (!Algorithms.isEmpty(colorString)) {
if (colorString.charAt(0) == '#') {
long color = Long.parseLong(colorString.substring(1), 16);
@@ -302,6 +316,30 @@ public class GPXUtilities {
getExtensionsToWrite().put(BACKGROUND_TYPE_EXTENSION, backType);
}
+ public String getProfileType() {
+ return getExtensionsToRead().get(PROFILE_TYPE_EXTENSION);
+ }
+
+ public void setProfileType(String profileType) {
+ getExtensionsToWrite().put(PROFILE_TYPE_EXTENSION, profileType);
+ }
+
+ public void removeProfileType() {
+ getExtensionsToWrite().remove(PROFILE_TYPE_EXTENSION);
+ }
+
+ public int getTrkPtIndex() {
+ try {
+ return Integer.parseInt(getExtensionsToRead().get(TRKPT_INDEX_EXTENSION));
+ } catch (NumberFormatException e) {
+ return -1;
+ }
+ }
+
+ public void setTrkPtIndex(int index) {
+ getExtensionsToWrite().put(TRKPT_INDEX_EXTENSION, String.valueOf(index));
+ }
+
@Override
public int hashCode() {
final int prime = 31;
@@ -412,6 +450,65 @@ public class GPXUtilities {
public double maxlon;
}
+ public static class RouteSegment {
+ public String id;
+ public String length;
+ public String segmentTime;
+ public String speed;
+ public String turnType;
+ public String turnAngle;
+ public String types;
+ public String pointTypes;
+ public String names;
+
+ public static RouteSegment fromStringBundle(StringBundle bundle) {
+ RouteSegment s = new RouteSegment();
+ s.id = bundle.getString("id", null);
+ s.length = bundle.getString("length", null);
+ s.segmentTime = bundle.getString("segmentTime", null);
+ s.speed = bundle.getString("speed", null);
+ s.turnType = bundle.getString("turnType", null);
+ s.turnAngle = bundle.getString("turnAngle", null);
+ s.types = bundle.getString("types", null);
+ s.pointTypes = bundle.getString("pointTypes", null);
+ s.names = bundle.getString("names", null);
+ return s;
+ }
+
+ public StringBundle toStringBundle() {
+ StringBundle bundle = new StringBundle();
+ bundle.putString("id", id);
+ bundle.putString("length", length);
+ bundle.putString("segmentTime", segmentTime);
+ bundle.putString("speed", speed);
+ bundle.putString("turnType", turnType);
+ bundle.putString("turnAngle", turnAngle);
+ bundle.putString("types", types);
+ bundle.putString("pointTypes", pointTypes);
+ bundle.putString("names", names);
+ return bundle;
+ }
+ }
+
+ public static class RouteType {
+ public String tag;
+ public String value;
+
+ public static RouteType fromStringBundle(StringBundle bundle) {
+ RouteType t = new RouteType();
+ t.tag = bundle.getString("t", null);
+ t.value = bundle.getString("v", null);
+ return t;
+ }
+
+ public StringBundle toStringBundle() {
+ StringBundle bundle = new StringBundle();
+ bundle.putString("t", tag);
+ bundle.putString("v", value);
+ return bundle;
+ }
+ }
+
public static class GPXTrackAnalysis {
public float totalDistance = 0;
public float totalDistanceWithoutGaps = 0;
@@ -932,7 +1029,6 @@ public class GPXUtilities {
sp = new SplitSegment(segment, k - 1, cf);
currentMetricEnd += metricLimit;
- prev = sp.get(0);
}
total += currentSegment;
}
@@ -957,6 +1053,24 @@ public class GPXUtilities {
return ls;
}
+ public static QuadRect calculateBounds(List pts) {
+ QuadRect trackBounds = new QuadRect(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY,
+ Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
+ updateBounds(trackBounds, pts, 0);
+
+ return trackBounds;
+ }
+
+ public static void updateBounds(QuadRect trackBounds, List pts, int startIndex) {
+ for (int i = startIndex; i < pts.size(); i++) {
+ WptPt pt = pts.get(i);
+ trackBounds.right = Math.max(trackBounds.right, pt.lon);
+ trackBounds.left = Math.min(trackBounds.left, pt.lon);
+ trackBounds.top = Math.max(trackBounds.top, pt.lat);
+ trackBounds.bottom = Math.min(trackBounds.bottom, pt.lat);
+ }
+ }
+
public static class GPXFile extends GPXExtensions {
public String author;
public Metadata metadata;
@@ -964,6 +1078,9 @@ public class GPXUtilities {
private List points = new ArrayList<>();
public List routes = new ArrayList<>();
+ public List routeSegments = new ArrayList<>();
+ public List routeTypes = new ArrayList<>();
+
public Exception error = null;
public String path = "";
public boolean showCurrentTrack;
@@ -990,6 +1107,10 @@ public class GPXUtilities {
}
}
+ public boolean hasRoute() {
+ return !routeSegments.isEmpty() && !routeTypes.isEmpty();
+ }
+
public List getPoints() {
return Collections.unmodifiableList(points);
}
@@ -1197,6 +1318,17 @@ public class GPXUtilities {
return pt;
}
+ public TrkSegment getNonEmptyTrkSegment() {
+ for (GPXUtilities.Track t : tracks) {
+ for (TrkSegment s : t.segments) {
+ if (s.points.size() > 0) {
+ return s;
+ }
+ }
+ }
+ return null;
+ }
+
public void addTrkSegment(List points) {
removeGeneralTrackIfExists();
@@ -1493,6 +1625,97 @@ public class GPXUtilities {
}
return new QuadRect(left, top, right, bottom);
}
+
+ public int getGradientScaleColor(String gradientScaleType, int defColor) {
+ String clrValue = null;
+ if (extensions != null) {
+ clrValue = extensions.get(gradientScaleType);
+ }
+ return parseColor(clrValue, defColor);
+ }
+
+ public void setGradientScaleColor(String gradientScaleType, int gradientScaleColor) {
+ getExtensionsToWrite().put(gradientScaleType, Algorithms.colorToString(gradientScaleColor));
+ }
+
+ public String getGradientScaleType() {
+ if (extensions != null) {
+ return extensions.get("gradient_scale_type");
+ }
+ return null;
+ }
+
+ public void setGradientScaleType(String gradientScaleType) {
+ getExtensionsToWrite().put("gradient_scale_type", gradientScaleType);
+ }
+
+ public void removeGradientScaleType() {
+ getExtensionsToWrite().remove("gradient_scale_type");
+ }
+
+ public String getSplitType() {
+ if (extensions != null) {
+ return extensions.get("split_type");
+ }
+ return null;
+ }
+
+ public void setSplitType(String gpxSplitType) {
+ getExtensionsToWrite().put("split_type", gpxSplitType);
+ }
+
+ public double getSplitInterval() {
+ if (extensions != null) {
+ String splitIntervalStr = extensions.get("split_interval");
+ if (!Algorithms.isEmpty(splitIntervalStr)) {
+ try {
+ return Double.parseDouble(splitIntervalStr);
+ } catch (NumberFormatException e) {
+ log.error("Error reading split_interval", e);
+ }
+ }
+ }
+ return 0;
+ }
+
+ public void setSplitInterval(double splitInterval) {
+ getExtensionsToWrite().put("split_interval", String.valueOf(splitInterval));
+ }
+
+ public String getWidth(String defWidth) {
+ String widthValue = null;
+ if (extensions != null) {
+ widthValue = extensions.get("width");
+ }
+ return widthValue != null ? widthValue : defWidth;
+ }
+
+ public void setWidth(String width) {
+ getExtensionsToWrite().put("width", width);
+ }
+
+ public boolean isShowArrows() {
+ String showArrows = null;
+ if (extensions != null) {
+ showArrows = extensions.get("show_arrows");
+ }
+ return Boolean.parseBoolean(showArrows);
+ }
+
+ public void setShowArrows(boolean showArrows) {
+ getExtensionsToWrite().put("show_arrows", String.valueOf(showArrows));
+ }
+
+ public boolean isShowStartFinish() {
+ if (extensions != null && extensions.containsKey("show_start_finish")) {
+ return Boolean.parseBoolean(extensions.get("show_start_finish"));
+ }
+ return true;
+ }
+
+ public void setShowStartFinish(boolean showStartFinish) {
+ getExtensionsToWrite().put("show_start_finish", String.valueOf(showStartFinish));
+ }
}
public static String asString(GPXFile file) {
@@ -1611,6 +1834,7 @@ public class GPXUtilities {
serializer.endTag(null, "wpt"); //$NON-NLS-1$
}
+ assignRouteExtensionWriter(file);
writeExtensions(serializer, file);
serializer.endTag(null, "gpx"); //$NON-NLS-1$
@@ -1623,6 +1847,29 @@ public class GPXUtilities {
return null;
}
+ private static void assignRouteExtensionWriter(final GPXFile gpxFile) {
+ if (gpxFile.hasRoute() && gpxFile.getExtensionsWriter() == null) {
+ gpxFile.setExtensionsWriter(new GPXExtensionsWriter() {
+ @Override
+ public void writeExtensions(XmlSerializer serializer) {
+ StringBundle bundle = new StringBundle();
+ List segmentsBundle = new ArrayList<>();
+ for (RouteSegment segment : gpxFile.routeSegments) {
+ segmentsBundle.add(segment.toStringBundle());
+ }
+ bundle.putBundleList("route", "segment", segmentsBundle);
+ List typesBundle = new ArrayList<>();
+ for (RouteType routeType : gpxFile.routeTypes) {
+ typesBundle.add(routeType.toStringBundle());
+ }
+ bundle.putBundleList("types", "type", typesBundle);
+ StringBundleWriter bundleWriter = new StringBundleXmlWriter(bundle, serializer);
+ bundleWriter.writeBundle();
+ }
+ });
+ }
+ }
+
private static String getFilename(String path) {
if(path != null) {
int i = path.lastIndexOf('/');
@@ -1840,23 +2087,7 @@ public class GPXUtilities {
}
public static GPXFile loadGPXFile(InputStream f) {
- return loadGPXFile(f, null, null);
- }
-
- public static GPXFile loadGPXFile(InputStream f, GPXFile gpxFile, GPXExtensionsReader extensionsReader) {
- boolean readExtensionsOnly = false;
- if (gpxFile == null) {
- gpxFile = new GPXFile(null);
- } else {
- if (f == null) {
- try {
- f = new FileInputStream(new File(gpxFile.path));
- } catch (FileNotFoundException e) {
- return gpxFile;
- }
- }
- readExtensionsOnly = extensionsReader != null;
- }
+ GPXFile gpxFile = new GPXFile(null);
SimpleDateFormat format = new SimpleDateFormat(GPX_TIME_FORMAT, Locale.US);
format.setTimeZone(TimeZone.getTimeZone("UTC"));
SimpleDateFormat formatMillis = new SimpleDateFormat(GPX_TIME_FORMAT_MILLIS, Locale.US);
@@ -1870,6 +2101,10 @@ public class GPXUtilities {
Stack parserState = new Stack<>();
boolean extensionReadMode = false;
boolean routePointExtension = false;
+ List routeSegments = gpxFile.routeSegments;
+ List routeTypes = gpxFile.routeTypes;
+ boolean routeExtension = false;
+ boolean typesExtension = false;
parserState.push(gpxFile);
int tok;
while ((tok = parser.next()) != XmlPullParser.END_DOCUMENT) {
@@ -1878,37 +2113,50 @@ public class GPXUtilities {
String tag = parser.getName();
if (extensionReadMode && parse != null && !routePointExtension) {
String tagName = tag.toLowerCase();
- boolean extensionsRead = false;
- if (extensionsReader != null) {
- extensionsRead = extensionsReader.readExtensions(gpxFile, parser);
+ if (routeExtension) {
+ if (tagName.equals("segment")) {
+ RouteSegment segment = parseRouteSegmentAttributes(parser);
+ routeSegments.add(segment);
+ }
+ } else if (typesExtension) {
+ if (tagName.equals("type")) {
+ RouteType type = parseRouteTypeAttributes(parser);
+ routeTypes.add(type);
+ }
}
- if (!readExtensionsOnly && !extensionsRead) {
- switch (tagName) {
- case "routepointextension":
- routePointExtension = true;
- if (parse instanceof WptPt) {
- parse.getExtensionsToWrite().put("offset", routeTrackSegment.points.size() + "");
- }
- break;
+ switch (tagName) {
+ case "routepointextension":
+ routePointExtension = true;
+ if (parse instanceof WptPt) {
+ parse.getExtensionsToWrite().put("offset", routeTrackSegment.points.size() + "");
+ }
+ break;
- default:
- Map values = readTextMap(parser, tag);
- if (values.size() > 0) {
- for (Entry entry : values.entrySet()) {
- String t = entry.getKey().toLowerCase();
- String value = entry.getValue();
- parse.getExtensionsToWrite().put(t, value);
- if (tag.equals("speed") && parse instanceof WptPt) {
- try {
- ((WptPt) parse).speed = Float.parseFloat(value);
- } catch (NumberFormatException e) {
- log.debug(e.getMessage(), e);
- }
+ case "route":
+ routeExtension = true;
+ break;
+
+ case "types":
+ typesExtension = true;
+ break;
+
+ default:
+ Map values = readTextMap(parser, tag);
+ if (values.size() > 0) {
+ for (Entry entry : values.entrySet()) {
+ String t = entry.getKey().toLowerCase();
+ String value = entry.getValue();
+ parse.getExtensionsToWrite().put(t, value);
+ if (tag.equals("speed") && parse instanceof WptPt) {
+ try {
+ ((WptPt) parse).speed = Float.parseFloat(value);
+ } catch (NumberFormatException e) {
+ log.debug(e.getMessage(), e);
}
}
}
- break;
- }
+ }
+ break;
}
} else if (parse != null && tag.equals("extensions")) {
extensionReadMode = true;
@@ -1918,7 +2166,7 @@ public class GPXUtilities {
routeTrackSegment.points.add(wptPt);
parserState.push(wptPt);
}
- } else if (!readExtensionsOnly) {
+ } else {
if (parse instanceof GPXFile) {
if (tag.equals("gpx")) {
((GPXFile) parse).author = parser.getAttributeValue("", "creator");
@@ -2114,7 +2362,12 @@ public class GPXUtilities {
if (parse != null && tag.equals("extensions")) {
extensionReadMode = false;
}
- if (readExtensionsOnly) {
+ if (extensionReadMode && tag.equals("route")) {
+ routeExtension = false;
+ continue;
+ }
+ if (extensionReadMode && tag.equals("types")) {
+ typesExtension = false;
continue;
}
@@ -2194,6 +2447,27 @@ public class GPXUtilities {
return wpt;
}
+ private static RouteSegment parseRouteSegmentAttributes(XmlPullParser parser) {
+ RouteSegment segment = new RouteSegment();
+ segment.id = parser.getAttributeValue("", "id");
+ segment.length = parser.getAttributeValue("", "length");
+ segment.segmentTime = parser.getAttributeValue("", "segmentTime");
+ segment.speed = parser.getAttributeValue("", "speed");
+ segment.turnType = parser.getAttributeValue("", "turnType");
+ segment.turnAngle = parser.getAttributeValue("", "turnAngle");
+ segment.types = parser.getAttributeValue("", "types");
+ segment.pointTypes = parser.getAttributeValue("", "pointTypes");
+ segment.names = parser.getAttributeValue("", "names");
+ return segment;
+ }
+
+ private static RouteType parseRouteTypeAttributes(XmlPullParser parser) {
+ RouteType type = new RouteType();
+ type.tag = parser.getAttributeValue("", "t");
+ type.value = parser.getAttributeValue("", "v");
+ return type;
+ }
+
private static Bounds parseBoundsAttributes(XmlPullParser parser) {
Bounds bounds = new Bounds();
try {
diff --git a/OsmAnd-java/src/main/java/net/osmand/IndexConstants.java b/OsmAnd-java/src/main/java/net/osmand/IndexConstants.java
index 14401c4a04..93569dfddd 100644
--- a/OsmAnd-java/src/main/java/net/osmand/IndexConstants.java
+++ b/OsmAnd-java/src/main/java/net/osmand/IndexConstants.java
@@ -28,9 +28,6 @@ public class IndexConstants {
public static final String EXTRA_EXT = ".extra";
public static final String EXTRA_ZIP_EXT = ".extra.zip";
- public static final String TOUR_INDEX_EXT = ".tour"; //$NON-NLS-1$
- public static final String TOUR_INDEX_EXT_ZIP = ".tour.zip"; //$NON-NLS-1$
-
public static final String GEN_LOG_EXT = ".gen.log"; //$NON-NLS-1$
public static final String VOICE_INDEX_EXT_ZIP = ".voice.zip"; //$NON-NLS-1$
@@ -48,6 +45,9 @@ public class IndexConstants {
public static final String GPX_FILE_EXT = ".gpx"; //$NON-NLS-1$
+ public static final String WPT_CHART_FILE_EXT = ".wpt.chart";
+ public static final String SQLITE_CHART_FILE_EXT = ".3d.chart";
+
public final static String POI_TABLE = "poi"; //$NON-NLS-1$
public static final String INDEX_DOWNLOAD_DOMAIN = "download.osmand.net";
diff --git a/OsmAnd-java/src/main/java/net/osmand/LocationsHolder.java b/OsmAnd-java/src/main/java/net/osmand/LocationsHolder.java
new file mode 100644
index 0000000000..5cecf9b8e6
--- /dev/null
+++ b/OsmAnd-java/src/main/java/net/osmand/LocationsHolder.java
@@ -0,0 +1,159 @@
+package net.osmand;
+
+import net.osmand.GPXUtilities.WptPt;
+import net.osmand.data.LatLon;
+import net.osmand.util.Algorithms;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class LocationsHolder {
+
+ private static final int LOCATION_TYPE_UNKNOWN = -1;
+ private static final int LOCATION_TYPE_LATLON = 0;
+ private static final int LOCATION_TYPE_LOCATION = 1;
+ private static final int LOCATION_TYPE_WPTPT = 2;
+
+ private List latLonList;
+ private List locationList;
+ private List wptPtList;
+ private int locationType;
+ private int size;
+
+ @SuppressWarnings("unchecked")
+ public LocationsHolder(List> locations) {
+ this.locationType = resolveLocationType(locations);
+ switch (locationType) {
+ case LOCATION_TYPE_LATLON:
+ latLonList = new ArrayList<>((List) locations);
+ size = locations.size();
+ break;
+ case LOCATION_TYPE_LOCATION:
+ locationList = new ArrayList<>((List) locations);
+ size = locations.size();
+ break;
+ case LOCATION_TYPE_WPTPT:
+ wptPtList = new ArrayList<>((List) locations);
+ size = locations.size();
+ break;
+ }
+ }
+
+ private int resolveLocationType(List> locations) {
+ if (!Algorithms.isEmpty(locations)) {
+ Object locationObj = locations.get(0);
+ if (locationObj instanceof LatLon) {
+ return LOCATION_TYPE_LATLON;
+ } else if (locationObj instanceof WptPt) {
+ return LOCATION_TYPE_WPTPT;
+ } else if (locationObj instanceof Location) {
+ return LOCATION_TYPE_LOCATION;
+ } else {
+ throw new IllegalArgumentException("Unsupported location type: " + locationObj.getClass().getSimpleName());
+ }
+ }
+ return LOCATION_TYPE_UNKNOWN;
+ }
+
+ public double getLatitude(int index) {
+ switch (locationType) {
+ case LOCATION_TYPE_LATLON:
+ return latLonList.get(index).getLatitude();
+ case LOCATION_TYPE_LOCATION:
+ return locationList.get(index).getLatitude();
+ case LOCATION_TYPE_WPTPT:
+ return wptPtList.get(index).getLatitude();
+ default:
+ return 0;
+ }
+ }
+
+ public double getLongitude(int index) {
+ switch (locationType) {
+ case LOCATION_TYPE_LATLON:
+ return latLonList.get(index).getLongitude();
+ case LOCATION_TYPE_LOCATION:
+ return locationList.get(index).getLongitude();
+ case LOCATION_TYPE_WPTPT:
+ return wptPtList.get(index).getLongitude();
+ default:
+ return 0;
+ }
+ }
+
+ public int getSize() {
+ return size;
+ }
+
+ @SuppressWarnings("unchecked")
+ private List getList(int locationType) {
+ List res = new ArrayList<>();
+ if (size > 0) {
+ for (int i = 0; i < size; i++) {
+ switch (locationType) {
+ case LOCATION_TYPE_LATLON:
+ res.add((T) getLatLon(i));
+ break;
+ case LOCATION_TYPE_LOCATION:
+ res.add((T) getLocation(i));
+ break;
+ case LOCATION_TYPE_WPTPT:
+ res.add((T) getWptPt(i));
+ break;
+ }
+ }
+ }
+ return res;
+ }
+
+ public List getLatLonList() {
+ if (this.locationType == LOCATION_TYPE_LATLON) {
+ return latLonList;
+ } else {
+ return getList(LOCATION_TYPE_LATLON);
+ }
+ }
+
+ public List getWptPtList() {
+ if (this.locationType == LOCATION_TYPE_WPTPT) {
+ return wptPtList;
+ } else {
+ return getList(LOCATION_TYPE_WPTPT);
+ }
+ }
+
+ public List getLocationsList() {
+ if (this.locationType == LOCATION_TYPE_LOCATION) {
+ return locationList;
+ } else {
+ return getList(LOCATION_TYPE_LOCATION);
+ }
+ }
+
+ public LatLon getLatLon(int index) {
+ if (this.locationType == LOCATION_TYPE_LATLON) {
+ return latLonList.get(index);
+ } else {
+ return new LatLon(getLatitude(index), getLongitude(index));
+ }
+ }
+
+ public WptPt getWptPt(int index) {
+ if (this.locationType == LOCATION_TYPE_WPTPT) {
+ return wptPtList.get(index);
+ } else {
+ WptPt wptPt = new WptPt();
+ wptPt.lat = getLatitude(index);
+ wptPt.lon = getLongitude(index);
+ return wptPt;
+ }
+ }
+
+ public Location getLocation(int index) {
+ if (this.locationType == LOCATION_TYPE_LOCATION) {
+ return locationList.get(index);
+ } else {
+ return new Location("", getLatitude(index), getLongitude(index));
+ }
+ }
+}
diff --git a/OsmAnd-java/src/main/java/net/osmand/NativeLibrary.java b/OsmAnd-java/src/main/java/net/osmand/NativeLibrary.java
index 8893c01286..0189d38378 100644
--- a/OsmAnd-java/src/main/java/net/osmand/NativeLibrary.java
+++ b/OsmAnd-java/src/main/java/net/osmand/NativeLibrary.java
@@ -26,10 +26,9 @@ import net.osmand.data.QuadRect;
import net.osmand.render.RenderingRuleSearchRequest;
import net.osmand.render.RenderingRulesStorage;
import net.osmand.router.NativeTransportRoutingResult;
-import net.osmand.router.PrecalculatedRouteDirection;
import net.osmand.router.RouteCalculationProgress;
import net.osmand.router.RouteSegmentResult;
-import net.osmand.router.RoutingConfiguration;
+import net.osmand.router.RoutingContext;
import net.osmand.router.TransportRoutingConfiguration;
import net.osmand.util.Algorithms;
@@ -135,12 +134,10 @@ public class NativeLibrary {
return nativeTransportRouting(new int[] { sx31, sy31, ex31, ey31 }, cfg, progress);
}
- public RouteSegmentResult[] runNativeRouting(int sx31, int sy31, int ex31, int ey31, RoutingConfiguration config,
- RouteRegion[] regions, RouteCalculationProgress progress, PrecalculatedRouteDirection precalculatedRouteDirection,
- boolean basemap, boolean publicTransport, boolean startTransportStop, boolean targetTransportStop) {
+ public RouteSegmentResult[] runNativeRouting(RoutingContext c, RouteRegion[] regions, boolean basemap) {
// config.router.printRules(System.out);
- return nativeRouting(new int[] { sx31, sy31, ex31, ey31 }, config, config.initialDirection == null ? -360 : config.initialDirection.floatValue(),
- regions, progress, precalculatedRouteDirection, basemap, publicTransport, startTransportStop, targetTransportStop);
+ return nativeRouting(c, c.config.initialDirection == null ? -360 : c.config.initialDirection.floatValue(),
+ regions, basemap);
}
@@ -156,16 +153,15 @@ public class NativeLibrary {
protected static native NativeRouteSearchResult loadRoutingData(RouteRegion reg, String regName, int regfp, RouteSubregion subreg,
boolean loadObjects);
+ public static native void deleteNativeRoutingContext(long handle);
+
protected static native void deleteRenderingContextHandle(long handle);
protected static native void deleteRouteSearchResult(long searchResultHandle);
protected static native RouteDataObject[] getRouteDataObjects(RouteRegion reg, long rs, int x31, int y31);
- protected static native RouteSegmentResult[] nativeRouting(int[] coordinates, RoutingConfiguration r,
- float initDirection, RouteRegion[] regions, RouteCalculationProgress progress,
- PrecalculatedRouteDirection precalculatedRouteDirection, boolean basemap,
- boolean publicTransport, boolean startTransportStop, boolean targetTransportStop);
+ protected static native RouteSegmentResult[] nativeRouting(RoutingContext c, float initDirection, RouteRegion[] regions, boolean basemap);
protected static native NativeTransportRoutingResult[] nativeTransportRouting(int[] coordinates, TransportRoutingConfiguration cfg,
RouteCalculationProgress progress);
@@ -354,6 +350,7 @@ public class NativeLibrary {
FileInputStream fis = new FileInputStream(f);
Algorithms.streamCopy(fis, ous);
fis.close();
+ System.out.println("FONT " + name);
initFontType(ous.toByteArray(), name.substring(0, name.length() - 4), name.toLowerCase().contains("bold"),
name.toLowerCase().contains("italic"));
} catch (IOException e) {
diff --git a/OsmAnd-java/src/main/java/net/osmand/OsmAndCollator.java b/OsmAnd-java/src/main/java/net/osmand/OsmAndCollator.java
index bf8338f73a..21d0a5d231 100644
--- a/OsmAnd-java/src/main/java/net/osmand/OsmAndCollator.java
+++ b/OsmAnd-java/src/main/java/net/osmand/OsmAndCollator.java
@@ -38,4 +38,5 @@ public class OsmAndCollator {
}
};
}
+
}
diff --git a/OsmAnd-java/src/main/java/net/osmand/Reshaper.java b/OsmAnd-java/src/main/java/net/osmand/Reshaper.java
index 6efd414062..8a55a6f77f 100644
--- a/OsmAnd-java/src/main/java/net/osmand/Reshaper.java
+++ b/OsmAnd-java/src/main/java/net/osmand/Reshaper.java
@@ -1,6 +1,7 @@
package net.osmand;
import java.io.UnsupportedEncodingException;
+import java.util.Arrays;
import org.apache.commons.logging.Log;
@@ -19,61 +20,67 @@ public class Reshaper {
return "";
}
}
+
public static String reshape(String s) {
-// if(true) {
-// return s;
-// }
try {
- ArabicShaping as = new ArabicShaping(ArabicShaping.LETTERS_SHAPE | ArabicShaping.LENGTH_GROW_SHRINK);
+ ArabicShaping as = new ArabicShaping(ArabicShaping.LETTERS_SHAPE |
+ ArabicShaping.LENGTH_GROW_SHRINK);
+ //printSplit("B", s);
try {
s = as.shape(s);
} catch (ArabicShapingException e) {
LOG.error(e.getMessage(), e);
}
+ //printSplit("A", s);
Bidi line = new Bidi(s.length(), s.length());
- line.setPara(s, Bidi.LEVEL_DEFAULT_LTR, null);
+ line.setPara(s, Bidi.LEVEL_DEFAULT_LTR, null);
+// line.setPara(s, Bidi.LEVEL_DEFAULT_LTR, null);
+// s = line.writeReordered(Bidi.DO_MIRRORING);
+// s = reordered;
byte direction = line.getDirection();
if (direction != Bidi.MIXED) {
// unidirectional
- if(line.isLeftToRight()) {
- return s;
- } else {
+ if (line.isLeftToRight()) {
+ return s;
+ } else {
char[] chs = new char[s.length()];
for(int i = 0; i< chs.length ; i++) {
- chs[i] = s.charAt(chs.length - i - 1);
+// chs[i] = s.charAt(chs.length - i - 1);
+ chs[i] = mirror(s.charAt(chs.length - i - 1));
}
return new String(chs);
}
} else {
- // // mixed-directional
+ // mixed-directional
+// System.out.println(s);
+// printSplit("Split", s);
int count = line.countRuns();
- // if (styleRunCount <= 1) {
- // int style = styleRuns[0].style;
- // // iterate over directional runs
- // for (i = 0; i < count; ++i) {
- // run = line.getVisualRun(i);
- // renderRun(text, run.getStart(), run.getLimit(),
- // run.getDirection(), style);
- // }
- // }
StringBuilder res = new StringBuilder();
// iterate over both directional and style runs
for (int i = 0; i < count; ++i) {
+ StringBuilder runs = new StringBuilder();
BidiRun run = line.getVisualRun(i);
-
- int st = run.getStart();
- int e = run.getLimit();
- int j = run.getDirection() == Bidi.LTR ? st : e - 1;
- int l = run.getDirection() == Bidi.LTR ? e : st - 1;
- boolean plus = run.getDirection() == Bidi.LTR;
- while (j != l) {
- res.append(s.charAt(j));
- if (plus) {
- j++;
- } else {
- j--;
+ boolean ltr = run.getDirection() == Bidi.LTR;
+ int start = run.getStart();
+ int limit = run.getLimit();
+ int begin = ltr ? start : limit - 1;
+ int end = ltr ? limit : start - 1;
+ int ind = begin;
+ while (ind != end) {
+ char ch = s.charAt(ind);
+ if (!ltr) {
+ ch = mirror(ch);
}
+ res.append(ch);
+ runs.append(ch);
+ if (ltr) {
+ ind++;
+ } else {
+ ind--;
+ }
+
}
+ printSplit(run.getDirection() + " " + run.getEmbeddingLevel(), runs.toString());
}
return res.toString();
}
@@ -83,24 +90,77 @@ public class Reshaper {
}
}
- public static void main(String[] args) {
-// char[] c = new char[] {'א', 'ד','ם', ' ', '1', '2'} ;
-// String reshape = "אדם";
- char[] c = new char[] {'א', 'ד','ם'} ;
- String reshape = reshape(new String(c));
- for(int i=0; i < reshape.length(); i++) {
- System.out.println(reshape.charAt(i));
+ private static char mirror(char ch) {
+ switch (ch) {
+ case '(': ch = ')'; break;
+ case ')': ch = '('; break;
+ case '[': ch = ']'; break;
+ case ']': ch = '['; break;
}
+ return ch;
+ }
+ public static void main(String[] args) {
test2();
+ test3();
+ test4();
+ test5();
+ }
+
+ public static void test3() {
+ String s = "מרכז מסחרי/השלום (40050)";
+ String reshape = reshape(s);
+ String expected = "(40050) םולשה/ירחסמ זכרמ";
+ check(s, reshape, expected);
+ }
+
+ public static void test5() {
+ String s = "מרכז מסחרי/השלום (מרז)";
+ String reshape = reshape(s);
+ String expected = "(זרמ) םולשה/ירחסמ זכרמ";
+ check(s, reshape, expected);
+ }
+
+ public static void check(String source, String reshape, String expected) {
+ printSplit("Source ", source);
+ printSplit("Expected", expected);
+ printSplit("Reshaped", reshape);
+ System.out.println(reshape);
+ if (!reshape.equals(expected)) {
+ throw new IllegalArgumentException(String.format("Bug: expected '%s', reshaped '%s'", expected, reshape));
+ }
+ }
+
+ static void printSplit(String p, String source) {
+ printSplit(p, source, true);
+ printSplit(p, source, false);
+ }
+ static void printSplit(String p, String source, boolean f) {
+ System.out.print(p);
+ System.out.print(": \u2066");
+ for (int i = 0; i < source.length(); i++) {
+ if (f) {
+ System.out.print(source.charAt(i));
+ System.out.print(" \u200e");
+ } else {
+ System.out.print(String.format("%04x ", (int) source.charAt(i)));
+ }
+ }
+// System.out.println(Arrays.toString(source.toCharArray()));
+ System.out.println();
+ System.out.flush();
}
- private static void test2() {
+ public static void test2() {
String s = "گچ پژ نمکی باللغة العربي";
String reshape = reshape(s);
-
- if (!reshape.equals("ﻲﺑﺮﻌﻟﺍ ﺔﻐﻠﻟﺎﺑ ﯽﮑﻤﻧ ﮋﭘ ﭻﮔ")) {
- throw new IllegalArgumentException("BUG!!!");
- }
+ String expected1 = "ﻲﺑﺮﻌﻟﺍ ﺔﻐﻠﻟﺎﺑ ﯽﮑﻤﻧ ﮋﭘ ﭻﮔ";
+ String expected2 = "ﻲﺑﺮﻌﻟﺍ ﺔﻐﻠﻟﺎﺑ یکﻤﻧ ژپ چگ";
+ check(s, reshape, expected1);
+ }
+
+ public static void test4() {
+ String s = "Abc (123)";
+ check(s, reshape(s), s);
}
-}
+}
\ No newline at end of file
diff --git a/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapAddressReaderAdapter.java b/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapAddressReaderAdapter.java
index 2060c8c23a..18f7b2549e 100644
--- a/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapAddressReaderAdapter.java
+++ b/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapAddressReaderAdapter.java
@@ -221,7 +221,7 @@ public class BinaryMapAddressReaderAdapter {
int fp = codedIS.getTotalBytesRead();
int length = codedIS.readRawVarint32();
int oldLimit = codedIS.pushLimit(length);
- City c = readCityHeader(new DefaultCityMatcher(matcher), fp, additionalTagsTable);
+ City c = readCityHeader(resultMatcher, new DefaultCityMatcher(matcher), fp, additionalTagsTable);
if (c != null) {
if (resultMatcher == null || resultMatcher.publish(c)) {
cities.add(c);
@@ -256,6 +256,7 @@ public class BinaryMapAddressReaderAdapter {
int oldLimit = codedIS.pushLimit(length);
readStreet(s, null, false, x >> 7, y >> 7, city.isPostcode() ? city.getName() : null,
attributeTagsTable);
+ publishRawData(resultMatcher, s);
if (resultMatcher == null || resultMatcher.publish(s)) {
city.registerStreet(s);
}
@@ -303,7 +304,7 @@ public class BinaryMapAddressReaderAdapter {
}
}
- protected City readCityHeader(CityMatcher matcher, int filePointer, List additionalTagsTable) throws IOException {
+ protected City readCityHeader(SearchRequest super City> resultMatcher, CityMatcher matcher, int filePointer, List additionalTagsTable) throws IOException {
int x = 0;
int y = 0;
City c = null;
@@ -313,6 +314,7 @@ public class BinaryMapAddressReaderAdapter {
int tag = WireFormat.getTagFieldNumber(t);
switch (tag) {
case 0:
+ publishRawData(resultMatcher, c);
return (matcher == null || matcher.matches(c)) ? c : null;
case OsmandOdb.CityIndex.CITY_TYPE_FIELD_NUMBER:
int type = codedIS.readUInt32();
@@ -445,6 +447,7 @@ public class BinaryMapAddressReaderAdapter {
if (loadBuildingsAndIntersected) {
int oldLimit = codedIS.pushLimit(length);
Building b = readBuilding(offset, x, y, additionalTagsTable);
+ publishRawData(buildingsMatcher, b);
if (postcodeFilter == null || postcodeFilter.equalsIgnoreCase(b.getPostcode())) {
if (buildingsMatcher == null || buildingsMatcher.publish(b)) {
s.addBuilding(b);
@@ -688,7 +691,7 @@ public class BinaryMapAddressReaderAdapter {
codedIS.seek(contOffset);
int len = codedIS.readRawVarint32();
int old = codedIS.pushLimit(len);
- obj = readCityHeader(null, contOffset, reg.attributeTagsTable);
+ obj = readCityHeader(req, null, contOffset, reg.attributeTagsTable);
codedIS.popLimit(old);
}
if (obj != null) {
@@ -701,6 +704,7 @@ public class BinaryMapAddressReaderAdapter {
readStreet(s, null, false, MapUtils.get31TileNumberX(l.getLongitude()) >> 7,
MapUtils.get31TileNumberY(l.getLatitude()) >> 7, obj.isPostcode() ? obj.getName() : null,
reg.attributeTagsTable);
+ publishRawData(req, s);
boolean matches = stringMatcher.matches(s.getName());
if (!matches) {
for (String n : s.getAllNames()) {
@@ -727,7 +731,8 @@ public class BinaryMapAddressReaderAdapter {
codedIS.seek(offset);
int len = codedIS.readRawVarint32();
int old = codedIS.pushLimit(len);
- City obj = readCityHeader(cityPostcodeMatcher, list.get(j), reg.attributeTagsTable);
+ City obj = readCityHeader(req, cityPostcodeMatcher, list.get(j), reg.attributeTagsTable);
+ publishRawData(req, obj);
if (obj != null && !published.contains(offset)) {
req.publish(obj);
published.add(offset);
@@ -805,4 +810,9 @@ public class BinaryMapAddressReaderAdapter {
}
}
+ private void publishRawData(SearchRequest resultMatcher, T obj) {
+ if (resultMatcher != null && obj != null) {
+ resultMatcher.collectRawData(obj);
+ }
+ }
}
diff --git a/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapIndexReader.java b/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapIndexReader.java
index e2b5432c6e..f9015ec48d 100644
--- a/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapIndexReader.java
+++ b/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapIndexReader.java
@@ -496,7 +496,7 @@ public class BinaryMapIndexReader {
}
}
Iterator> it = groupPoints.entrySet().iterator();
- if (it.hasNext()) {
+ while (it.hasNext()) {
Entry e = it.next();
TransportIndex ind = e.getKey();
TIntArrayList pointers = e.getValue();
@@ -696,6 +696,7 @@ public class BinaryMapIndexReader {
private void readMapIndex(MapIndex index, boolean onlyInitEncodingRules) throws IOException {
int defaultId = 1;
int oldLimit;
+ int encodingRulesSize = 0;
while (true) {
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);
@@ -712,10 +713,14 @@ public class BinaryMapIndexReader {
break;
case OsmandOdb.OsmAndMapIndex.RULES_FIELD_NUMBER :
if (onlyInitEncodingRules) {
+ if(encodingRulesSize == 0) {
+ encodingRulesSize = codedIS.getTotalBytesRead();
+ }
int len = codedIS.readInt32();
oldLimit = codedIS.pushLimit(len);
readMapEncodingRule(index, defaultId++);
codedIS.popLimit(oldLimit);
+ index.encodingRulesSizeBytes = (codedIS.getTotalBytesRead() - encodingRulesSize);
} else {
skipUnknownField(t);
}
@@ -1457,8 +1462,14 @@ public class BinaryMapIndexReader {
public static SearchRequest buildAddressByNameRequest(ResultMatcher resultMatcher, String nameRequest,
StringMatcherMode matcherMode) {
+ return buildAddressByNameRequest(resultMatcher, null, nameRequest, matcherMode);
+ }
+
+ public static SearchRequest buildAddressByNameRequest(ResultMatcher resultMatcher, ResultMatcher rawDataCollector, String nameRequest,
+ StringMatcherMode matcherMode) {
SearchRequest request = new SearchRequest();
request.resultMatcher = resultMatcher;
+ request.rawDataCollector = rawDataCollector;
request.nameQuery = nameRequest.trim();
request.matcherMode = matcherMode;
return request;
@@ -1542,6 +1553,10 @@ public class BinaryMapIndexReader {
public static SearchRequest buildSearchPoiRequest(int x, int y, String nameFilter, int sleft, int sright, int stop, int sbottom, ResultMatcher resultMatcher) {
+ return buildSearchPoiRequest(x, y, nameFilter, sleft, sright, stop, sbottom, resultMatcher, null);
+ }
+
+ public static SearchRequest buildSearchPoiRequest(int x, int y, String nameFilter, int sleft, int sright, int stop, int sbottom, ResultMatcher resultMatcher, ResultMatcher rawDataCollector) {
SearchRequest request = new SearchRequest();
request.x = x;
request.y = y;
@@ -1550,6 +1565,7 @@ public class BinaryMapIndexReader {
request.top = stop;
request.bottom = sbottom;
request.resultMatcher = resultMatcher;
+ request.rawDataCollector = rawDataCollector;
request.nameQuery = nameFilter.trim();
return request;
}
@@ -1634,6 +1650,7 @@ public class BinaryMapIndexReader {
private boolean ocean = false;
private ResultMatcher resultMatcher;
+ private ResultMatcher rawDataCollector;
// 31 zoom tiles
// common variables
@@ -1711,6 +1728,12 @@ public class BinaryMapIndexReader {
return false;
}
+ public void collectRawData(T obj) {
+ if (rawDataCollector != null) {
+ rawDataCollector.publish(obj);
+ }
+ }
+
protected void publishOceanTile(boolean ocean) {
if (ocean) {
this.ocean = true;
@@ -1811,10 +1834,13 @@ public class BinaryMapIndexReader {
public int onewayReverseAttribute = -1;
public TIntHashSet positiveLayers = new TIntHashSet(2);
public TIntHashSet negativeLayers = new TIntHashSet(2);
+ public int encodingRulesSizeBytes;
// to speed up comparision
private MapIndex referenceMapIndex;
+
+
public Integer getRule(String t, String v) {
Map m = encodingRules.get(t);
if (m != null) {
@@ -2637,18 +2663,20 @@ public class BinaryMapIndexReader {
}
}
+
public TLongObjectHashMap getIncompleteTransportRoutes() throws InvalidProtocolBufferException, IOException {
if (incompleteTransportRoutes == null) {
incompleteTransportRoutes = new TLongObjectHashMap<>();
for (TransportIndex ti : transportIndexes) {
if (ti.incompleteRoutesLength > 0) {
- transportAdapter.readIncompleteRoutesList(incompleteTransportRoutes, ti.incompleteRoutesLength,
- ti.incompleteRoutesOffset);
+ codedIS.seek(ti.incompleteRoutesOffset);
+ int oldLimit = codedIS.pushLimit(ti.incompleteRoutesLength);
+ transportAdapter.readIncompleteRoutesList(incompleteTransportRoutes, ti.filePointer);
+ codedIS.popLimit(oldLimit);
}
}
}
return incompleteTransportRoutes;
}
-
}
diff --git a/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapPoiReaderAdapter.java b/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapPoiReaderAdapter.java
index aa51de0c4b..857eb4f4d3 100644
--- a/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapPoiReaderAdapter.java
+++ b/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapPoiReaderAdapter.java
@@ -26,7 +26,6 @@ import net.osmand.data.Amenity.AmenityRoutePoint;
import net.osmand.data.LatLon;
import net.osmand.osm.MapPoiTypes;
import net.osmand.osm.PoiCategory;
-import net.osmand.osm.PoiType;
import net.osmand.util.MapUtils;
import org.apache.commons.logging.Log;
@@ -591,6 +590,7 @@ public class BinaryMapPoiReaderAdapter {
}
}
if (matches) {
+ req.collectRawData(am);
req.publish(am);
}
}
@@ -637,6 +637,7 @@ public class BinaryMapPoiReaderAdapter {
int yp = (int) MapUtils.getTileNumberY(zSkip, am.getLocation().getLatitude());
long valSkip = (((long) xp) << zSkip) | yp;
if (!toSkip.contains(valSkip)) {
+ req.collectRawData(am);
boolean publish = req.publish(am);
if (publish) {
read = true;
@@ -647,6 +648,7 @@ public class BinaryMapPoiReaderAdapter {
return read;
}
} else {
+ req.collectRawData(am);
if (req.publish(am)) {
read = true;
}
@@ -770,7 +772,8 @@ public class BinaryMapPoiReaderAdapter {
}
}
subtype = poiTypes.replaceDeprecatedSubtype(type, subtype);
- if (req.poiTypeFilter == null || req.poiTypeFilter.accept(type, subtype)) {
+ boolean isForbidden = poiTypes.isTypeForbidden(subtype);
+ if (!isForbidden && (req.poiTypeFilter == null || req.poiTypeFilter.accept(type, subtype))) {
if (amenityType == null) {
amenityType = type;
am.setSubType(subtype);
diff --git a/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapRouteReaderAdapter.java b/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapRouteReaderAdapter.java
index 048eb706fb..8431df7244 100644
--- a/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapRouteReaderAdapter.java
+++ b/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapRouteReaderAdapter.java
@@ -1,9 +1,25 @@
package net.osmand.binary;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+
import com.google.protobuf.CodedInputStream;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.WireFormat;
+import gnu.trove.iterator.TLongObjectIterator;
+import gnu.trove.list.array.TIntArrayList;
+import gnu.trove.list.array.TLongArrayList;
+import gnu.trove.map.hash.TIntObjectHashMap;
+import gnu.trove.map.hash.TLongObjectHashMap;
import net.osmand.PlatformUtil;
import net.osmand.ResultMatcher;
import net.osmand.binary.BinaryMapIndexReader.SearchRequest;
@@ -18,23 +34,6 @@ import net.osmand.util.Algorithms;
import net.osmand.util.MapUtils;
import net.osmand.util.OpeningHoursParser;
-import org.apache.commons.logging.Log;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-import gnu.trove.iterator.TLongObjectIterator;
-import gnu.trove.list.array.TIntArrayList;
-import gnu.trove.list.array.TLongArrayList;
-import gnu.trove.map.hash.TIntObjectHashMap;
-import gnu.trove.map.hash.TLongObjectHashMap;
-
public class BinaryMapRouteReaderAdapter {
protected static final Log LOG = PlatformUtil.getLog(BinaryMapRouteReaderAdapter.class);
private static final int SHIFT_COORDINATES = 4;
@@ -172,7 +171,7 @@ public class BinaryMapRouteReaderAdapter {
}
return tag;
}
-
+
public int onewayDirection(){
if(type == ONEWAY){
return intValue;
@@ -293,10 +292,19 @@ public class BinaryMapRouteReaderAdapter {
public static class RouteRegion extends BinaryIndexPart {
public int regionsRead;
public List routeEncodingRules = new ArrayList();
+ public int routeEncodingRulesBytes = 0;
public Map decodingRules = null;
List subregions = new ArrayList();
List basesubregions = new ArrayList();
+ public int directionForward = -1;
+ public int directionBackward = -1;
+ public int directionTrafficSignalsForward = -1;
+ public int directionTrafficSignalsBackward = -1;
+ public int trafficSignals = -1;
+ public int stopSign = -1;
+ public int giveWaySign = -1;
+
int nameTypeRule = -1;
int refTypeRule = -1;
int destinationTypeRule = -1;
@@ -353,9 +361,28 @@ public class BinaryMapRouteReaderAdapter {
destinationTypeRule = id;
} else if (tags.equals("destination:ref") || tags.equals("destination:ref:forward") || tags.equals("destination:ref:backward")) {
destinationRefTypeRule = id;
+ } else if (tags.equals("highway") && val.equals("traffic_signals")){
+ trafficSignals = id;
+ } else if (tags.equals("highway") && val.equals("stop")){
+ stopSign = id;
+ } else if (tags.equals("highway") && val.equals("give_way")){
+ giveWaySign = id;
+ } else if (tags.equals("traffic_signals:direction") && val != null){
+ if (val.equals("forward")) {
+ directionTrafficSignalsForward = id;
+ } else if (val.equals("backward")) {
+ directionTrafficSignalsBackward = id;
+ }
+ } else if (tags.equals("direction") && val != null) {
+ if (val.equals("forward")) {
+ directionForward = id;
+ } else if (val.equals("backward")) {
+ directionBackward = id;
+ }
}
}
+
public void completeRouteEncodingRules() {
for(int i = 0; i < routeEncodingRules.size(); i++) {
RouteTypeRule rtr = routeEncodingRules.get(i);
@@ -588,6 +615,7 @@ public class BinaryMapRouteReaderAdapter {
protected void readRouteIndex(RouteRegion region) throws IOException {
int routeEncodingRule = 1;
+ int routeEncodingRulesSize = 0;
while(true){
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);
@@ -600,10 +628,13 @@ public class BinaryMapRouteReaderAdapter {
break;
case OsmandOdb.OsmAndRoutingIndex.RULES_FIELD_NUMBER: {
int len = codedIS.readInt32();
+ if(routeEncodingRulesSize == 0) {
+ routeEncodingRulesSize = codedIS.getTotalBytesRead();
+ }
int oldLimit = codedIS.pushLimit(len);
readRouteEncodingRule(region, routeEncodingRule++);
- codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
codedIS.popLimit(oldLimit);
+ region.routeEncodingRulesBytes = codedIS.getTotalBytesRead() - routeEncodingRulesSize;
} break;
case OsmandOdb.OsmAndRoutingIndex.ROOTBOXES_FIELD_NUMBER :
case OsmandOdb.OsmAndRoutingIndex.BASEMAPBOXES_FIELD_NUMBER :{
diff --git a/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapTransportReaderAdapter.java b/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapTransportReaderAdapter.java
index 049fc161eb..1e733e50f6 100644
--- a/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapTransportReaderAdapter.java
+++ b/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapTransportReaderAdapter.java
@@ -11,6 +11,7 @@ import com.google.protobuf.WireFormat;
import gnu.trove.map.hash.TIntObjectHashMap;
import gnu.trove.map.hash.TLongObjectHashMap;
import net.osmand.binary.BinaryMapIndexReader.SearchRequest;
+import net.osmand.data.IncompleteTransportRoute;
import net.osmand.data.TransportSchedule;
import net.osmand.data.TransportStop;
import net.osmand.data.TransportStopExit;
@@ -71,7 +72,6 @@ public class BinaryMapTransportReaderAdapter {
return bottom;
}
-
IndexStringTable stringTable = null;
}
@@ -251,9 +251,7 @@ public class BinaryMapTransportReaderAdapter {
return ((char) i)+"";
}
- public void readIncompleteRoutesList(TLongObjectHashMap incompleteRoutes,
- int length, int offset) throws IOException {
- codedIS.seek(offset);
+ public void readIncompleteRoutesList(TLongObjectHashMap incompleteRoutes, int transportIndexStart) throws IOException {
boolean end = false;
while (!end) {
int t = codedIS.readTag();
@@ -265,7 +263,7 @@ public class BinaryMapTransportReaderAdapter {
case OsmandOdb.IncompleteTransportRoutes.ROUTES_FIELD_NUMBER:
int l = codedIS.readRawVarint32();
int olds = codedIS.pushLimit(l);
- net.osmand.data.IncompleteTransportRoute ir = readIncompleteRoute();
+ net.osmand.data.IncompleteTransportRoute ir = readIncompleteRoute(transportIndexStart);
net.osmand.data.IncompleteTransportRoute itr = incompleteRoutes.get(ir.getRouteId());
if(itr != null) {
itr.setNextLinkedRoute(ir);
@@ -283,7 +281,7 @@ public class BinaryMapTransportReaderAdapter {
}
- public net.osmand.data.IncompleteTransportRoute readIncompleteRoute() throws IOException {
+ public net.osmand.data.IncompleteTransportRoute readIncompleteRoute(int transportIndexStart) throws IOException {
net.osmand.data.IncompleteTransportRoute dataObject = new net.osmand.data.IncompleteTransportRoute();
boolean end = false;
while(!end){
@@ -297,7 +295,12 @@ public class BinaryMapTransportReaderAdapter {
dataObject.setRouteId(codedIS.readUInt64());
break;
case OsmandOdb.IncompleteTransportRoute.ROUTEREF_FIELD_NUMBER :
- dataObject.setRouteOffset(codedIS.readRawVarint32());
+ int delta = codedIS.readRawVarint32();
+ if (delta > transportIndexStart) {
+ dataObject.setRouteOffset(delta);
+ } else {
+ dataObject.setRouteOffset(transportIndexStart + delta);
+ }
break;
case OsmandOdb.IncompleteTransportRoute.OPERATOR_FIELD_NUMBER :
skipUnknownField(t);
@@ -320,7 +323,6 @@ public class BinaryMapTransportReaderAdapter {
break;
}
}
-
return dataObject;
}
diff --git a/OsmAnd-java/src/main/java/net/osmand/binary/CommonWords.java b/OsmAnd-java/src/main/java/net/osmand/binary/CommonWords.java
index 55d7461573..5c4c24ee68 100644
--- a/OsmAnd-java/src/main/java/net/osmand/binary/CommonWords.java
+++ b/OsmAnd-java/src/main/java/net/osmand/binary/CommonWords.java
@@ -13,10 +13,6 @@ public class CommonWords {
frequentlyUsedWordsDictionary.put(string, frequentlyUsedWordsDictionary.size());
}
public static int getCommon(String name) {
-// if(true) {
-// // not ready for old versions yet
-// return -1;
-// }
Integer i = commonWordsDictionary.get(name);
return i == null ? -1 : i.intValue();
}
@@ -28,7 +24,15 @@ public class CommonWords {
public static int getCommonSearch(String name) {
Integer i = commonWordsDictionary.get(name);
- return i == null ? getFrequentlyUsed(name) : i.intValue() + frequentlyUsedWordsDictionary.size();
+ // higher means better for search
+ if (i == null) {
+ int fq = getFrequentlyUsed(name);
+ if (fq != -1) {
+ return commonWordsDictionary.size() + fq;
+ }
+ return -1;
+ }
+ return i.intValue();
}
public static int getCommonGeocoding(String name) {
@@ -839,6 +843,7 @@ public class CommonWords {
addCommon("van");
addCommon("road");
addCommon("street");
+ addCommon("sector");
addCommon("drive");
addCommon("avenue");
addCommon("rue");
diff --git a/OsmAnd-java/src/main/java/net/osmand/binary/GeocodingUtilities.java b/OsmAnd-java/src/main/java/net/osmand/binary/GeocodingUtilities.java
index 1699d749d9..a372f12aa1 100644
--- a/OsmAnd-java/src/main/java/net/osmand/binary/GeocodingUtilities.java
+++ b/OsmAnd-java/src/main/java/net/osmand/binary/GeocodingUtilities.java
@@ -4,6 +4,7 @@ import net.osmand.PlatformUtil;
import net.osmand.ResultMatcher;
import net.osmand.CollatorStringMatcher.StringMatcherMode;
import net.osmand.binary.BinaryMapIndexReader.SearchRequest;
+import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
import net.osmand.data.Building;
import net.osmand.data.City;
import net.osmand.data.LatLon;
@@ -23,9 +24,11 @@ import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import gnu.trove.set.hash.TLongHashSet;
@@ -40,7 +43,7 @@ public class GeocodingUtilities {
public static final float STOP_SEARCHING_STREET_WITH_MULTIPLIER_RADIUS = 250;
public static final float STOP_SEARCHING_STREET_WITHOUT_MULTIPLIER_RADIUS = 400;
- public static final int DISTANCE_STREET_NAME_PROXIMITY_BY_NAME = 15000;
+ public static final int DISTANCE_STREET_NAME_PROXIMITY_BY_NAME = 45000;
public static final float DISTANCE_STREET_FROM_CLOSEST_WITH_SAME_NAME = 1000;
public static final float THRESHOLD_MULTIPLIER_SKIP_BUILDINGS_AFTER = 1.5f;
@@ -142,15 +145,12 @@ public class GeocodingUtilities {
RoutePlannerFrontEnd rp = new RoutePlannerFrontEnd();
List lst = new ArrayList();
List listR = new ArrayList();
- rp.findRouteSegment(lat, lon, ctx, listR);
+ // we allow duplications to search in both files for boundary regions
+ rp.findRouteSegment(lat, lon, ctx, listR, false, true);
double distSquare = 0;
- TLongHashSet set = new TLongHashSet();
- Set streetNames = new HashSet();
+ Map> streetNames = new HashMap<>();
for (RouteSegmentPoint p : listR) {
RouteDataObject road = p.getRoad();
- if (!set.add(road.getId())) {
- continue;
- }
// System.out.println(road.toString() + " " + Math.sqrt(p.distSquare));
String name = Algorithms.isEmpty(road.getName()) ? road.getRef("", false, true) : road.getName();
if (allowEmptyNames || !Algorithms.isEmpty(name)) {
@@ -164,7 +164,13 @@ public class GeocodingUtilities {
sr.connectionPoint = new LatLon(MapUtils.get31LatitudeY(p.preciseY), MapUtils.get31LongitudeX(p.preciseX));
sr.regionFP = road.region.getFilePointer();
sr.regionLen = road.region.getLength();
- if (streetNames.add(sr.streetName)) {
+ List plst = streetNames.get(sr.streetName);
+ if (plst == null) {
+ plst = new ArrayList();
+ streetNames.put(sr.streetName, plst);
+ }
+ if (!plst.contains(road.region)) {
+ plst.add(road.region);
lst.add(sr);
}
}
@@ -308,6 +314,50 @@ public class GeocodingUtilities {
return res;
}
+ public void filterDuplicateRegionResults(final List res) {
+ Collections.sort(res, DISTANCE_COMPARATOR);
+ // filter duplicate city results (when building is in both regions on boundary)
+ for (int i = 0; i < res.size() - 1;) {
+ int cmp = cmpResult(res.get(i), res.get(i + 1));
+ if (cmp > 0) {
+ res.remove(i);
+ } else if (cmp < 0) {
+ res.remove(i + 1);
+ } else {
+ // nothing to delete
+ i++;
+ }
+ }
+ }
+
+ private int cmpResult(GeocodingResult gr1, GeocodingResult gr2) {
+ boolean eqStreet = Algorithms.stringsEqual(gr1.streetName, gr2.streetName);
+ if (eqStreet) {
+ boolean sameObj = false;
+ if (gr1.city != null && gr2.city != null) {
+ if (gr1.building != null && gr2.building != null) {
+ if (Algorithms.stringsEqual(gr1.building.getName(), gr2.building.getName())) {
+ // same building
+ sameObj = true;
+ }
+ } else if (gr1.building == null && gr2.building == null) {
+ // same street
+ sameObj = true;
+ }
+ }
+ if (sameObj) {
+ double cityDist1 = MapUtils.getDistance(gr1.searchPoint, gr1.city.getLocation());
+ double cityDist2 = MapUtils.getDistance(gr2.searchPoint, gr2.city.getLocation());
+ if (cityDist1 < cityDist2) {
+ return -1;
+ } else {
+ return 1;
+ }
+ }
+ }
+ return 0;
+ }
+
private List loadStreetBuildings(final GeocodingResult road, BinaryMapIndexReader reader,
GeocodingResult street) throws IOException {
final List streetBuildings = new ArrayList();
diff --git a/OsmAnd-java/src/main/java/net/osmand/binary/RouteDataObject.java b/OsmAnd-java/src/main/java/net/osmand/binary/RouteDataObject.java
index 807561e66d..bfe638d394 100644
--- a/OsmAnd-java/src/main/java/net/osmand/binary/RouteDataObject.java
+++ b/OsmAnd-java/src/main/java/net/osmand/binary/RouteDataObject.java
@@ -1,12 +1,15 @@
package net.osmand.binary;
import net.osmand.Location;
+import net.osmand.PlatformUtil;
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteTypeRule;
import net.osmand.util.Algorithms;
import net.osmand.util.MapUtils;
import net.osmand.util.TransliterationHelper;
+import org.apache.commons.logging.Log;
+
import java.text.MessageFormat;
import java.util.Arrays;
@@ -34,7 +37,7 @@ public class RouteDataObject {
public int[] nameIds;
// mixed array [0, height, cumulative_distance height, cumulative_distance, height, ...] - length is length(points)*2
public float[] heightDistanceArray = null;
-
+ private static final Log LOG = PlatformUtil.getLog(RouteDataObject.class);
public RouteDataObject(RouteRegion region) {
this.region = region;
}
@@ -56,6 +59,7 @@ public class RouteDataObject {
this.pointsY = copy.pointsY;
this.types = copy.types;
this.names = copy.names;
+ this.nameIds = copy.nameIds;
this.restrictions = copy.restrictions;
this.restrictionsVia = copy.restrictionsVia;
this.pointTypes = copy.pointTypes;
@@ -426,12 +430,19 @@ public class RouteDataObject {
int[] opointsX = pointsX;
int[] opointsY = pointsY;
int[][] opointTypes = pointTypes;
+ String[][] opointNames = pointNames;
+ int[][] opointNameTypes = pointNameTypes;
pointsX = new int[pointsX.length + 1];
pointsY = new int[pointsY.length + 1];
boolean insTypes = this.pointTypes != null && this.pointTypes.length > pos;
+ boolean insNames = this.pointNames != null && this.pointNames.length > pos;
if (insTypes) {
pointTypes = new int[opointTypes.length + 1][];
}
+ if (insNames) {
+ pointNames = new String[opointNames.length + 1][];
+ pointNameTypes = new int[opointNameTypes.length +1][];
+ }
int i = 0;
for (; i < pos; i++) {
pointsX[i] = opointsX[i];
@@ -439,18 +450,32 @@ public class RouteDataObject {
if (insTypes) {
pointTypes[i] = opointTypes[i];
}
+ if (insNames) {
+ pointNames[i] = opointNames[i];
+ pointNameTypes[i] = opointNameTypes[i];
+ }
}
pointsX[i] = x31;
pointsY[i] = y31;
if (insTypes) {
pointTypes[i] = null;
}
+ if (insNames) {
+ pointNames[i] = null;
+ pointNameTypes[i] = null;
+ }
for (i = i + 1; i < pointsX.length; i++) {
pointsX[i] = opointsX[i - 1];
pointsY[i] = opointsY[i - 1];
if (insTypes && i < pointTypes.length) {
pointTypes[i] = opointTypes[i - 1];
}
+ if (insNames && i < pointNames.length) {
+ pointNames[i] = opointNames[i - 1];
+ }
+ if (insNames && i < pointNameTypes.length) {
+ pointNameTypes[i] = opointNameTypes[i - 1];
+ }
}
}
@@ -1054,6 +1079,4 @@ public class RouteDataObject {
}
restrictionsVia[k] = viaWay;
}
-
-
}
diff --git a/OsmAnd-java/src/main/java/net/osmand/binary/StringBundle.java b/OsmAnd-java/src/main/java/net/osmand/binary/StringBundle.java
index dd66cfc969..ad54015c07 100644
--- a/OsmAnd-java/src/main/java/net/osmand/binary/StringBundle.java
+++ b/OsmAnd-java/src/main/java/net/osmand/binary/StringBundle.java
@@ -21,7 +21,7 @@ public class StringBundle {
private static final DecimalFormat FIVE_DIGITS_FORMATTER = new DecimalFormat("#.#####");
private static final DecimalFormat SIX_DIGITS_FORMATTER = new DecimalFormat("#.######");
- private Map map = new LinkedHashMap<>();
+ private Map> map = new LinkedHashMap<>();
public enum ItemType {
STRING,
@@ -32,7 +32,7 @@ public class StringBundle {
public StringBundle() {
}
- protected StringBundle(Map map) {
+ protected StringBundle(Map> map) {
this.map = map;
}
@@ -156,16 +156,16 @@ public class StringBundle {
}
}
- public static class StringListItem extends Item> {
+ public static class StringListItem extends Item>> {
- private StringListItem(String name, List- list) {
+ private StringListItem(String name, List
- > list) {
super(name, ItemType.LIST, list);
}
}
- public static class StringMapItem extends Item