Merge pull request #8798 from osmandapp/custom_downloads
Custom downloads
This commit is contained in:
commit
7273372040
38 changed files with 1382 additions and 267 deletions
|
@ -45,7 +45,9 @@ public class IndexConstants {
|
|||
public static final String ROUTING_FILE_EXT = ".xml";
|
||||
|
||||
public static final String RENDERER_INDEX_EXT = ".render.xml"; //$NON-NLS-1$
|
||||
|
||||
|
||||
public static final String GPX_FILE_EXT = ".gpx"; //$NON-NLS-1$
|
||||
|
||||
public final static String POI_TABLE = "poi"; //$NON-NLS-1$
|
||||
|
||||
public static final String INDEX_DOWNLOAD_DOMAIN = "download.osmand.net";
|
||||
|
|
85
OsmAnd/res/layout/item_info_fragment.xml
Normal file
85
OsmAnd/res/layout/item_info_fragment.xml
Normal file
|
@ -0,0 +1,85 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/pstsTabBackground"
|
||||
android:minHeight="@dimen/dashboard_map_toolbar"
|
||||
android:theme="?attr/toolbar_theme"
|
||||
app:contentInsetLeft="72dp"
|
||||
app:contentInsetStart="72dp" />
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/activity_background_basic">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="@dimen/dialog_button_ex_height">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/item_image"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:adjustViewBounds="true"
|
||||
android:background="?attr/bg_color"
|
||||
android:maxHeight="132dp"
|
||||
android:scaleType="fitCenter"
|
||||
tools:src="@drawable/extension_stub" />
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/item_description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/bg_color"
|
||||
android:letterSpacing="@dimen/text_button_letter_spacing"
|
||||
android:paddingStart="@dimen/content_padding"
|
||||
android:paddingLeft="@dimen/content_padding"
|
||||
android:paddingTop="@dimen/content_padding_small"
|
||||
android:paddingEnd="@dimen/content_padding"
|
||||
android:paddingRight="@dimen/content_padding"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="@dimen/default_list_text_size"
|
||||
app:typeface="@string/font_roboto_regular"
|
||||
tools:text="@string/lorem_ipsum" />
|
||||
|
||||
<include layout="@layout/card_bottom_divider" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:background="?attr/list_background_color">
|
||||
|
||||
<include layout="@layout/bottom_buttons" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</LinearLayout>
|
|
@ -11,6 +11,7 @@
|
|||
Thx - Hardy
|
||||
|
||||
-->
|
||||
<string name="extra_maps_menu_group">Extra maps</string>
|
||||
<string name="custom_color">Custom color</string>
|
||||
<string name="lang_lmo">Lombard</string>
|
||||
<string name="lang_an">Aragonese</string>
|
||||
|
|
78
OsmAnd/src/net/osmand/JsonUtils.java
Normal file
78
OsmAnd/src/net/osmand/JsonUtils.java
Normal file
|
@ -0,0 +1,78 @@
|
|||
package net.osmand;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class JsonUtils {
|
||||
|
||||
public static String getLocalizedResFromMap(Context ctx, Map<String, String> localizedMap, String defVal) {
|
||||
if (!Algorithms.isEmpty(localizedMap)) {
|
||||
Configuration config = ctx.getResources().getConfiguration();
|
||||
String lang = config.locale.getLanguage();
|
||||
String name = localizedMap.get(lang);
|
||||
if (Algorithms.isEmpty(name)) {
|
||||
name = localizedMap.get("");
|
||||
}
|
||||
if (!Algorithms.isEmpty(name)) {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
return defVal;
|
||||
}
|
||||
|
||||
public static List<String> jsonArrayToList(String key, JSONObject json) throws JSONException {
|
||||
List<String> items = new ArrayList<>();
|
||||
JSONArray jsonArray = json.optJSONArray(key);
|
||||
if (jsonArray != null) {
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
items.add(jsonArray.getString(i));
|
||||
}
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
public static Map<String, String> getLocalizedMapFromJson(String key, JSONObject json) throws JSONException {
|
||||
Map<String, String> localizedMap = new HashMap<>();
|
||||
JSONObject jsonObject = json.optJSONObject(key);
|
||||
if (jsonObject != null) {
|
||||
for (Iterator<String> it = jsonObject.keys(); it.hasNext(); ) {
|
||||
String localeKey = it.next();
|
||||
String name = jsonObject.getString(localeKey);
|
||||
localizedMap.put(localeKey, name);
|
||||
}
|
||||
}
|
||||
return localizedMap;
|
||||
}
|
||||
|
||||
public static void writeStringListToJson(String key, JSONObject json, List<String> items) throws JSONException {
|
||||
if (!Algorithms.isEmpty(items)) {
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
for (String render : items) {
|
||||
jsonArray.put(render);
|
||||
}
|
||||
json.put(key, jsonArray);
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeLocalizedMapToJson(String jsonKey, JSONObject json, Map<String, String> map) throws JSONException {
|
||||
if (!Algorithms.isEmpty(map)) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
for (Map.Entry<String, String> entry : map.entrySet()) {
|
||||
jsonObject.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
json.put(jsonKey, jsonObject);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
package net.osmand.plus;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
|
@ -9,9 +8,12 @@ import androidx.annotation.NonNull;
|
|||
import androidx.annotation.Nullable;
|
||||
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.JsonUtils;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.map.ITileSource;
|
||||
import net.osmand.map.TileSourceManager;
|
||||
import net.osmand.map.WorldRegion;
|
||||
import net.osmand.plus.SettingsHelper.AvoidRoadsSettingsItem;
|
||||
import net.osmand.plus.SettingsHelper.MapSourcesSettingsItem;
|
||||
import net.osmand.plus.SettingsHelper.PluginSettingsItem;
|
||||
|
@ -20,6 +22,10 @@ import net.osmand.plus.SettingsHelper.ProfileSettingsItem;
|
|||
import net.osmand.plus.SettingsHelper.QuickActionsSettingsItem;
|
||||
import net.osmand.plus.SettingsHelper.SettingsCollectListener;
|
||||
import net.osmand.plus.SettingsHelper.SettingsItem;
|
||||
import net.osmand.plus.download.DownloadActivityType;
|
||||
import net.osmand.plus.download.DownloadIndexesThread;
|
||||
import net.osmand.plus.download.DownloadResources;
|
||||
import net.osmand.plus.download.IndexItem;
|
||||
import net.osmand.plus.helpers.AvoidSpecificRoads;
|
||||
import net.osmand.plus.poi.PoiUIFilter;
|
||||
import net.osmand.plus.quickaction.QuickAction;
|
||||
|
@ -32,7 +38,9 @@ import org.json.JSONException;
|
|||
import org.json.JSONObject;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
@ -56,6 +64,8 @@ public class CustomOsmandPlugin extends OsmandPlugin {
|
|||
|
||||
private List<String> rendererNames = new ArrayList<>();
|
||||
private List<String> routerNames = new ArrayList<>();
|
||||
private List<SuggestedDownloadItem> suggestedDownloadItems = new ArrayList<>();
|
||||
private List<WorldRegion> customRegions = new ArrayList<>();
|
||||
|
||||
public CustomOsmandPlugin(@NonNull OsmandApplication app, @NonNull JSONObject json) throws JSONException {
|
||||
super(app);
|
||||
|
@ -65,6 +75,25 @@ public class CustomOsmandPlugin extends OsmandPlugin {
|
|||
loadResources();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return pluginId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return JsonUtils.getLocalizedResFromMap(app, names, app.getString(R.string.custom_osmand_plugin));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return JsonUtils.getLocalizedResFromMap(app, descriptions, null);
|
||||
}
|
||||
|
||||
public String getResourceDirName() {
|
||||
return resourceDirName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean init(@NonNull OsmandApplication app, @Nullable Activity activity) {
|
||||
super.init(app, activity);
|
||||
|
@ -78,6 +107,108 @@ public class CustomOsmandPlugin extends OsmandPlugin {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disable(OsmandApplication app) {
|
||||
super.disable(app);
|
||||
removePluginItems(null);
|
||||
}
|
||||
|
||||
public File getPluginDir() {
|
||||
return app.getAppPath(IndexConstants.PLUGINS_DIR + pluginId);
|
||||
}
|
||||
|
||||
public File getPluginItemsFile() {
|
||||
return new File(getPluginDir(), "items" + IndexConstants.OSMAND_SETTINGS_FILE_EXT);
|
||||
}
|
||||
|
||||
public File getPluginResDir() {
|
||||
File pluginDir = getPluginDir();
|
||||
if (!Algorithms.isEmpty(resourceDirName)) {
|
||||
return new File(pluginDir, resourceDirName);
|
||||
}
|
||||
return pluginDir;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getRendererNames() {
|
||||
return rendererNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getRouterNames() {
|
||||
return routerNames;
|
||||
}
|
||||
|
||||
private Drawable getIconForFile(String path, Map<String, String> fileNames) {
|
||||
for (Map.Entry<String, String> entry : fileNames.entrySet()) {
|
||||
String value = entry.getValue();
|
||||
if (value.startsWith("@")) {
|
||||
value = value.substring(1);
|
||||
}
|
||||
if (path.endsWith(value)) {
|
||||
return BitmapDrawable.createFromPath(path);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Drawable getLogoResource() {
|
||||
return icon != null ? icon : super.getLogoResource();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable getAssetResourceImage() {
|
||||
return image;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WorldRegion> getDownloadMaps() {
|
||||
return customRegions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IndexItem> getSuggestedMaps() {
|
||||
List<IndexItem> suggestedMaps = new ArrayList<>();
|
||||
|
||||
DownloadIndexesThread downloadThread = app.getDownloadThread();
|
||||
if (!downloadThread.getIndexes().isDownloadedFromInternet && app.getSettings().isInternetConnectionAvailable()) {
|
||||
downloadThread.runReloadIndexFiles();
|
||||
}
|
||||
|
||||
boolean downloadIndexes = app.getSettings().isInternetConnectionAvailable()
|
||||
&& !downloadThread.getIndexes().isDownloadedFromInternet
|
||||
&& !downloadThread.getIndexes().downloadFromInternetFailed;
|
||||
|
||||
if (!downloadIndexes) {
|
||||
for (SuggestedDownloadItem item : suggestedDownloadItems) {
|
||||
DownloadActivityType type = DownloadActivityType.getIndexType(item.scopeId);
|
||||
if (type != null) {
|
||||
List<IndexItem> foundMaps = new ArrayList<>();
|
||||
String searchType = item.getSearchType();
|
||||
if ("latlon".equalsIgnoreCase(searchType)) {
|
||||
LatLon latLon = app.getMapViewTrackingUtilities().getMapLocation();
|
||||
foundMaps.addAll(getMapsForType(latLon, type));
|
||||
} else if ("worldregion".equalsIgnoreCase(searchType)) {
|
||||
LatLon latLon = app.getMapViewTrackingUtilities().getMapLocation();
|
||||
foundMaps.addAll(getMapsForType(latLon, type));
|
||||
}
|
||||
if (!Algorithms.isEmpty(item.getNames())) {
|
||||
foundMaps.addAll(getMapsForType(item.getNames(), type, item.getLimit()));
|
||||
}
|
||||
suggestedMaps.addAll(foundMaps);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return suggestedMaps;
|
||||
}
|
||||
|
||||
public void setResourceDirName(String resourceDirName) {
|
||||
this.resourceDirName = resourceDirName;
|
||||
}
|
||||
|
||||
private void addPluginItemsFromFile(final File file) {
|
||||
app.getSettingsHelper().collectSettings(file, "", 1, new SettingsCollectListener() {
|
||||
@Override
|
||||
|
@ -93,9 +224,7 @@ public class CustomOsmandPlugin extends OsmandPlugin {
|
|||
ApplicationMode.changeProfileAvailability(savedMode, true, app);
|
||||
}
|
||||
iterator.remove();
|
||||
} else if (item instanceof PluginSettingsItem) {
|
||||
iterator.remove();
|
||||
} else {
|
||||
} else if (!(item instanceof PluginSettingsItem)) {
|
||||
item.setShouldReplace(true);
|
||||
}
|
||||
}
|
||||
|
@ -179,207 +308,94 @@ public class CustomOsmandPlugin extends OsmandPlugin {
|
|||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disable(OsmandApplication app) {
|
||||
super.disable(app);
|
||||
removePluginItems(null);
|
||||
}
|
||||
|
||||
public File getPluginDir() {
|
||||
return app.getAppPath(IndexConstants.PLUGINS_DIR + pluginId);
|
||||
}
|
||||
|
||||
public File getPluginItemsFile() {
|
||||
return new File(getPluginDir(), "items" + IndexConstants.OSMAND_SETTINGS_FILE_EXT);
|
||||
}
|
||||
|
||||
public File getPluginResDir() {
|
||||
File pluginDir = getPluginDir();
|
||||
if (!Algorithms.isEmpty(resourceDirName)) {
|
||||
return new File(pluginDir, resourceDirName);
|
||||
}
|
||||
return pluginDir;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return pluginId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
Configuration config = app.getResources().getConfiguration();
|
||||
String lang = config.locale.getLanguage();
|
||||
String name = names.get(lang);
|
||||
if (Algorithms.isEmpty(name)) {
|
||||
name = names.get("");
|
||||
}
|
||||
if (Algorithms.isEmpty(name)) {
|
||||
name = app.getString(R.string.custom_osmand_plugin);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
Configuration config = app.getResources().getConfiguration();
|
||||
String lang = config.locale.getLanguage();
|
||||
String description = descriptions.get(lang);
|
||||
if (Algorithms.isEmpty(description)) {
|
||||
description = descriptions.get("");
|
||||
}
|
||||
return description;
|
||||
}
|
||||
|
||||
public String getResourceDirName() {
|
||||
return resourceDirName;
|
||||
}
|
||||
|
||||
public void setResourceDirName(String resourceDirName) {
|
||||
this.resourceDirName = resourceDirName;
|
||||
}
|
||||
|
||||
public void readAdditionalDataFromJson(JSONObject json) throws JSONException {
|
||||
JSONObject iconJson = json.has("icon") ? json.getJSONObject("icon") : null;
|
||||
if (iconJson != null) {
|
||||
for (Iterator<String> it = iconJson.keys(); it.hasNext(); ) {
|
||||
String iconKey = it.next();
|
||||
String name = iconJson.getString(iconKey);
|
||||
iconNames.put(iconKey, name);
|
||||
}
|
||||
}
|
||||
JSONObject imageJson = json.has("image") ? json.getJSONObject("image") : null;
|
||||
if (imageJson != null) {
|
||||
for (Iterator<String> it = imageJson.keys(); it.hasNext(); ) {
|
||||
String imageKey = it.next();
|
||||
String name = imageJson.getString(imageKey);
|
||||
imageNames.put(imageKey, name);
|
||||
}
|
||||
}
|
||||
JSONObject nameJson = json.has("name") ? json.getJSONObject("name") : null;
|
||||
if (nameJson != null) {
|
||||
for (Iterator<String> it = nameJson.keys(); it.hasNext(); ) {
|
||||
String localeKey = it.next();
|
||||
String name = nameJson.getString(localeKey);
|
||||
names.put(localeKey, name);
|
||||
}
|
||||
}
|
||||
JSONObject descriptionJson = json.has("description") ? json.getJSONObject("description") : null;
|
||||
if (descriptionJson != null) {
|
||||
for (Iterator<String> it = descriptionJson.keys(); it.hasNext(); ) {
|
||||
String localeKey = it.next();
|
||||
String name = descriptionJson.getString(localeKey);
|
||||
descriptions.put(localeKey, name);
|
||||
}
|
||||
iconNames = JsonUtils.getLocalizedMapFromJson("icon", json);
|
||||
imageNames = JsonUtils.getLocalizedMapFromJson("image", json);
|
||||
names = JsonUtils.getLocalizedMapFromJson("name", json);
|
||||
descriptions = JsonUtils.getLocalizedMapFromJson("description", json);
|
||||
|
||||
JSONArray regionsJson = json.optJSONArray("regionsJson");
|
||||
if (regionsJson != null) {
|
||||
customRegions.addAll(collectRegionsFromJson(regionsJson));
|
||||
}
|
||||
}
|
||||
|
||||
public void writeAdditionalDataToJson(JSONObject json) throws JSONException {
|
||||
JSONObject iconJson = new JSONObject();
|
||||
for (Map.Entry<String, String> entry : iconNames.entrySet()) {
|
||||
iconJson.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
json.put("icon", iconJson);
|
||||
JsonUtils.writeLocalizedMapToJson("icon", json, iconNames);
|
||||
JsonUtils.writeLocalizedMapToJson("image", json, imageNames);
|
||||
JsonUtils.writeLocalizedMapToJson("name", json, names);
|
||||
JsonUtils.writeLocalizedMapToJson("description", json, descriptions);
|
||||
|
||||
JSONObject imageJson = new JSONObject();
|
||||
for (Map.Entry<String, String> entry : imageNames.entrySet()) {
|
||||
imageJson.put(entry.getKey(), entry.getValue());
|
||||
JSONArray regionsJson = new JSONArray();
|
||||
for (WorldRegion region : getFlatCustomRegions()) {
|
||||
if (region instanceof CustomRegion) {
|
||||
regionsJson.put(((CustomRegion) region).toJson());
|
||||
}
|
||||
}
|
||||
json.put("image", imageJson);
|
||||
json.put("regionsJson", regionsJson);
|
||||
}
|
||||
|
||||
JSONObject nameJson = new JSONObject();
|
||||
for (Map.Entry<String, String> entry : names.entrySet()) {
|
||||
nameJson.put(entry.getKey(), entry.getValue());
|
||||
private List<WorldRegion> getFlatCustomRegions() {
|
||||
List<WorldRegion> l = new ArrayList<>(customRegions);
|
||||
for (WorldRegion region : customRegions) {
|
||||
collectCustomSubregionsFromRegion(region, l);
|
||||
}
|
||||
json.put("name", nameJson);
|
||||
return l;
|
||||
}
|
||||
|
||||
JSONObject descriptionJson = new JSONObject();
|
||||
for (Map.Entry<String, String> entry : descriptions.entrySet()) {
|
||||
descriptionJson.put(entry.getKey(), entry.getValue());
|
||||
private void collectCustomSubregionsFromRegion(WorldRegion region, List<WorldRegion> items) {
|
||||
items.addAll(region.getSubregions());
|
||||
for (WorldRegion subregion : region.getSubregions()) {
|
||||
collectCustomSubregionsFromRegion(subregion, items);
|
||||
}
|
||||
json.put("description", descriptionJson);
|
||||
}
|
||||
|
||||
public void readDependentFilesFromJson(JSONObject json) throws JSONException {
|
||||
JSONArray rendererNamesJson = json.has("rendererNames") ? json.getJSONArray("rendererNames") : null;
|
||||
if (rendererNamesJson != null) {
|
||||
for (int i = 0; i < rendererNamesJson.length(); i++) {
|
||||
String renderer = rendererNamesJson.getString(i);
|
||||
rendererNames.add(renderer);
|
||||
}
|
||||
}
|
||||
JSONArray routerNamesJson = json.has("routerNames") ? json.getJSONArray("routerNames") : null;
|
||||
if (routerNamesJson != null) {
|
||||
for (int i = 0; i < routerNamesJson.length(); i++) {
|
||||
String renderer = routerNamesJson.getString(i);
|
||||
routerNames.add(renderer);
|
||||
}
|
||||
}
|
||||
JSONObject iconNamesJson = json.has("iconNames") ? json.getJSONObject("iconNames") : null;
|
||||
if (iconNamesJson != null) {
|
||||
for (Iterator<String> it = iconNamesJson.keys(); it.hasNext(); ) {
|
||||
String localeKey = it.next();
|
||||
String name = iconNamesJson.getString(localeKey);
|
||||
iconNames.put(localeKey, name);
|
||||
}
|
||||
}
|
||||
JSONObject imageNamesJson = json.has("imageNames") ? json.getJSONObject("imageNames") : null;
|
||||
if (imageNamesJson != null) {
|
||||
for (Iterator<String> it = imageNamesJson.keys(); it.hasNext(); ) {
|
||||
String localeKey = it.next();
|
||||
String name = imageNamesJson.getString(localeKey);
|
||||
imageNames.put(localeKey, name);
|
||||
}
|
||||
}
|
||||
resourceDirName = json.has("pluginResDir") ? json.getString("pluginResDir") : null;
|
||||
rendererNames = JsonUtils.jsonArrayToList("rendererNames", json);
|
||||
routerNames = JsonUtils.jsonArrayToList("routerNames", json);
|
||||
resourceDirName = json.optString("pluginResDir");
|
||||
}
|
||||
|
||||
public void writeDependentFilesJson(JSONObject json) throws JSONException {
|
||||
JSONArray rendererNamesJson = new JSONArray();
|
||||
for (String render : rendererNames) {
|
||||
rendererNamesJson.put(render);
|
||||
}
|
||||
json.put("rendererNames", rendererNamesJson);
|
||||
|
||||
JSONArray routerNamesJson = new JSONArray();
|
||||
for (String render : routerNames) {
|
||||
routerNamesJson.put(render);
|
||||
}
|
||||
json.put("routerNames", routerNamesJson);
|
||||
|
||||
JSONObject iconNamesJson = new JSONObject();
|
||||
for (Map.Entry<String, String> entry : iconNames.entrySet()) {
|
||||
iconNamesJson.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
json.put("iconNames", iconNamesJson);
|
||||
|
||||
JSONObject imageNamesJson = new JSONObject();
|
||||
for (Map.Entry<String, String> entry : imageNames.entrySet()) {
|
||||
imageNamesJson.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
json.put("imageNames", imageNamesJson);
|
||||
JsonUtils.writeStringListToJson("rendererNames", json, rendererNames);
|
||||
JsonUtils.writeStringListToJson("routerNames", json, routerNames);
|
||||
|
||||
json.put("pluginResDir", resourceDirName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getRendererNames() {
|
||||
return rendererNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getRouterNames() {
|
||||
return routerNames;
|
||||
public static List<CustomRegion> collectRegionsFromJson(JSONArray jsonArray) throws JSONException {
|
||||
List<CustomRegion> customRegions = new ArrayList<>();
|
||||
Map<String, CustomRegion> flatRegions = new HashMap<>();
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
JSONObject regionJson = jsonArray.getJSONObject(i);
|
||||
CustomRegion region = CustomRegion.fromJson(regionJson);
|
||||
flatRegions.put(region.getPath(), region);
|
||||
}
|
||||
for (CustomRegion region : flatRegions.values()) {
|
||||
if (!Algorithms.isEmpty(region.getParentPath())) {
|
||||
CustomRegion parentReg = flatRegions.get(region.getParentPath());
|
||||
if (parentReg != null) {
|
||||
parentReg.addSubregion(region);
|
||||
}
|
||||
} else {
|
||||
customRegions.add(region);
|
||||
}
|
||||
}
|
||||
return customRegions;
|
||||
}
|
||||
|
||||
public void addRouter(String fileName) {
|
||||
String routerName = Algorithms.getFileWithoutDirs(fileName);
|
||||
routerNames.add(routerName);
|
||||
if (!routerNames.contains(routerName)) {
|
||||
routerNames.add(routerName);
|
||||
}
|
||||
}
|
||||
|
||||
public void addRenderer(String fileName) {
|
||||
String rendererName = Algorithms.getFileWithoutDirs(fileName);
|
||||
rendererNames.add(rendererName);
|
||||
if (!rendererNames.contains(rendererName)) {
|
||||
rendererNames.add(rendererName);
|
||||
}
|
||||
}
|
||||
|
||||
public void loadResources() {
|
||||
|
@ -398,28 +414,25 @@ public class CustomOsmandPlugin extends OsmandPlugin {
|
|||
}
|
||||
}
|
||||
|
||||
private Drawable getIconForFile(String path, Map<String, String> fileNames) {
|
||||
for (Map.Entry<String, String> entry : fileNames.entrySet()) {
|
||||
String value = entry.getValue();
|
||||
if (value.startsWith("@")) {
|
||||
value = value.substring(1);
|
||||
}
|
||||
if (path.endsWith(value)) {
|
||||
return BitmapDrawable.createFromPath(path);
|
||||
}
|
||||
public void updateSuggestedDownloads(List<SuggestedDownloadItem> items) {
|
||||
suggestedDownloadItems = new ArrayList<>(items);
|
||||
}
|
||||
|
||||
public void updateDownloadItems(List<WorldRegion> items) {
|
||||
customRegions = new ArrayList<>(items);
|
||||
}
|
||||
|
||||
private List<IndexItem> getMapsForType(LatLon latLon, DownloadActivityType type) {
|
||||
try {
|
||||
return DownloadResources.findIndexItemsAt(app, latLon, type);
|
||||
} catch (IOException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
return null;
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Drawable getLogoResource() {
|
||||
return icon != null ? icon : super.getLogoResource();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable getAssetResourceImage() {
|
||||
return image;
|
||||
private List<IndexItem> getMapsForType(List<String> names, DownloadActivityType type, int limit) {
|
||||
return DownloadResources.findIndexItemsAt(app, names, type, false, limit);
|
||||
}
|
||||
|
||||
public interface PluginItemsListener {
|
||||
|
@ -427,4 +440,35 @@ public class CustomOsmandPlugin extends OsmandPlugin {
|
|||
void onItemsRemoved();
|
||||
|
||||
}
|
||||
|
||||
public static class SuggestedDownloadItem {
|
||||
|
||||
private String scopeId;
|
||||
private String searchType;
|
||||
private List<String> names;
|
||||
private int limit;
|
||||
|
||||
public SuggestedDownloadItem(String scopeId, String searchType, List<String> names, int limit) {
|
||||
this.scopeId = scopeId;
|
||||
this.limit = limit;
|
||||
this.searchType = searchType;
|
||||
this.names = names;
|
||||
}
|
||||
|
||||
public String getScopeId() {
|
||||
return scopeId;
|
||||
}
|
||||
|
||||
public String getSearchType() {
|
||||
return searchType;
|
||||
}
|
||||
|
||||
public List<String> getNames() {
|
||||
return names;
|
||||
}
|
||||
|
||||
public int getLimit() {
|
||||
return limit;
|
||||
}
|
||||
}
|
||||
}
|
173
OsmAnd/src/net/osmand/plus/CustomRegion.java
Normal file
173
OsmAnd/src/net/osmand/plus/CustomRegion.java
Normal file
|
@ -0,0 +1,173 @@
|
|||
package net.osmand.plus;
|
||||
|
||||
import androidx.annotation.ColorInt;
|
||||
|
||||
import net.osmand.JsonUtils;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.map.WorldRegion;
|
||||
import net.osmand.plus.download.CustomIndexItem;
|
||||
import net.osmand.plus.download.DownloadActivityType;
|
||||
import net.osmand.plus.download.IndexItem;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class CustomRegion extends WorldRegion {
|
||||
|
||||
private static final Log LOG = PlatformUtil.getLog(CustomRegion.class);
|
||||
|
||||
private String scopeId;
|
||||
private String path;
|
||||
private String parentPath;
|
||||
private String type;
|
||||
private String subfolder;
|
||||
private String headerButton;
|
||||
|
||||
private JSONArray downloadItemsJson;
|
||||
|
||||
private Map<String, String> names = new HashMap<>();
|
||||
private Map<String, String> icons = new HashMap<>();
|
||||
private Map<String, String> headers = new HashMap<>();
|
||||
|
||||
private int headerColor = -1;
|
||||
|
||||
|
||||
private CustomRegion(String scopeId, String path, String type) {
|
||||
super(path, null);
|
||||
this.scopeId = scopeId;
|
||||
this.path = path;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getScopeId() {
|
||||
return scopeId;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public String getParentPath() {
|
||||
return parentPath;
|
||||
}
|
||||
|
||||
@ColorInt
|
||||
public int getHeaderColor() {
|
||||
return headerColor;
|
||||
}
|
||||
|
||||
public static CustomRegion fromJson(JSONObject object) throws JSONException {
|
||||
String scopeId = object.optString("scope-id", null);
|
||||
String path = object.optString("path", null);
|
||||
String type = object.optString("type", null);
|
||||
|
||||
CustomRegion region = new CustomRegion(scopeId, path, type);
|
||||
region.subfolder = object.optString("subfolder", null);
|
||||
|
||||
int index = path.lastIndexOf(File.separator);
|
||||
if (index != -1) {
|
||||
region.parentPath = path.substring(0, index);
|
||||
}
|
||||
|
||||
region.names = JsonUtils.getLocalizedMapFromJson("name", object);
|
||||
if (!Algorithms.isEmpty(region.names)) {
|
||||
region.regionName = region.names.get("");
|
||||
region.regionNameEn = region.names.get("");
|
||||
region.regionFullName = region.names.get("");
|
||||
region.regionNameLocale = region.names.get("");
|
||||
}
|
||||
|
||||
region.icons = JsonUtils.getLocalizedMapFromJson("icon", object);
|
||||
region.headers = JsonUtils.getLocalizedMapFromJson("header", object);
|
||||
|
||||
region.headerButton = object.optString("header-button", null);
|
||||
region.downloadItemsJson = object.optJSONArray("items");
|
||||
|
||||
String headerColor = object.optString("header-color", null);
|
||||
try {
|
||||
region.headerColor = Algorithms.isEmpty(headerColor) ? 0 : Algorithms.parseColor(headerColor);
|
||||
} catch (IllegalArgumentException e) {
|
||||
region.headerColor = 0;
|
||||
}
|
||||
|
||||
return region;
|
||||
}
|
||||
|
||||
public List<IndexItem> loadIndexItems() {
|
||||
List<IndexItem> items = new ArrayList<>();
|
||||
if (downloadItemsJson != null) {
|
||||
try {
|
||||
for (int i = 0; i < downloadItemsJson.length(); i++) {
|
||||
JSONObject itemJson = downloadItemsJson.getJSONObject(i);
|
||||
|
||||
long timestamp = itemJson.optLong("timestamp") * 1000;
|
||||
long contentSize = itemJson.optLong("contentSize");
|
||||
long containerSize = itemJson.optLong("containerSize");
|
||||
|
||||
String indexType = itemJson.optString("type", type);
|
||||
String webUrl = itemJson.optString("weburl");
|
||||
String fileName = itemJson.optString("filename");
|
||||
String downloadUrl = itemJson.optString("downloadurl");
|
||||
String size = new DecimalFormat("#.#").format(containerSize / (1024f * 1024f));
|
||||
|
||||
List<String> descrImageUrl = JsonUtils.jsonArrayToList("image-description-url", itemJson);
|
||||
Map<String, String> indexNames = JsonUtils.getLocalizedMapFromJson("name", itemJson);
|
||||
Map<String, String> descriptions = JsonUtils.getLocalizedMapFromJson("description", itemJson);
|
||||
Map<String, String> webButtonText = JsonUtils.getLocalizedMapFromJson("web-button-text", itemJson);
|
||||
|
||||
DownloadActivityType type = DownloadActivityType.getIndexType(indexType);
|
||||
if (type != null) {
|
||||
IndexItem indexItem = new CustomIndexItem.CustomIndexItemBuilder()
|
||||
.setFileName(fileName)
|
||||
.setSubfolder(subfolder)
|
||||
.setDownloadUrl(downloadUrl)
|
||||
.setNames(indexNames)
|
||||
.setDescriptions(descriptions)
|
||||
.setImageDescrUrl(descrImageUrl)
|
||||
.setWebUrl(webUrl)
|
||||
.setWebButtonText(webButtonText)
|
||||
.setTimestamp(timestamp)
|
||||
.setSize(size)
|
||||
.setContentSize(contentSize)
|
||||
.setContainerSize(containerSize)
|
||||
.setType(type)
|
||||
.create();
|
||||
|
||||
items.add(indexItem);
|
||||
}
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
public JSONObject toJson() throws JSONException {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
|
||||
jsonObject.putOpt("scope-id", scopeId);
|
||||
jsonObject.putOpt("path", path);
|
||||
jsonObject.putOpt("type", type);
|
||||
jsonObject.putOpt("subfolder", subfolder);
|
||||
jsonObject.putOpt("header-button", headerButton);
|
||||
|
||||
JsonUtils.writeLocalizedMapToJson("name", jsonObject, names);
|
||||
JsonUtils.writeLocalizedMapToJson("icon", jsonObject, icons);
|
||||
JsonUtils.writeLocalizedMapToJson("header", jsonObject, headers);
|
||||
|
||||
jsonObject.putOpt("items", downloadItemsJson);
|
||||
|
||||
return jsonObject;
|
||||
}
|
||||
}
|
|
@ -17,6 +17,7 @@ import net.osmand.GPXUtilities.Track;
|
|||
import net.osmand.GPXUtilities.TrkSegment;
|
||||
import net.osmand.GPXUtilities.WptPt;
|
||||
import net.osmand.IProgress;
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.plus.GPXDatabase.GpxDataItem;
|
||||
|
@ -241,7 +242,7 @@ public class GpxSelectionHelper {
|
|||
if (i >= 0) {
|
||||
name = name.substring(i + 1);
|
||||
}
|
||||
if (name.toLowerCase().endsWith(".gpx")) {
|
||||
if (name.toLowerCase().endsWith(IndexConstants.GPX_FILE_EXT)) {
|
||||
name = name.substring(0, name.length() - 4);
|
||||
}
|
||||
name = name.replace('_', ' ');
|
||||
|
|
|
@ -1009,10 +1009,10 @@ public class MapMarkersHelper {
|
|||
if (!dir.exists()) {
|
||||
dir.mkdirs();
|
||||
}
|
||||
File fout = new File(dir, fileName + ".gpx");
|
||||
File fout = new File(dir, fileName + IndexConstants.GPX_FILE_EXT);
|
||||
int ind = 1;
|
||||
while (fout.exists()) {
|
||||
fout = new File(dir, fileName + "_" + (++ind) + ".gpx");
|
||||
fout = new File(dir, fileName + "_" + (++ind) + IndexConstants.GPX_FILE_EXT);
|
||||
}
|
||||
GPXFile file = new GPXFile(Version.getFullVersion(ctx));
|
||||
for (MapMarker marker : mapMarkers) {
|
||||
|
|
|
@ -21,6 +21,7 @@ import net.osmand.IProgress;
|
|||
import net.osmand.Location;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.access.AccessibilityPlugin;
|
||||
import net.osmand.map.WorldRegion;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.activities.TabActivity.TabItem;
|
||||
import net.osmand.plus.api.SettingsAPI;
|
||||
|
@ -182,6 +183,10 @@ public abstract class OsmandPlugin {
|
|||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
public List<WorldRegion> getDownloadMaps() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
public List<String> getRendererNames() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
@ -645,6 +650,31 @@ public abstract class OsmandPlugin {
|
|||
return null;
|
||||
}
|
||||
|
||||
public static List<WorldRegion> getCustomDownloadRegions() {
|
||||
List<WorldRegion> l = new ArrayList<>();
|
||||
for (OsmandPlugin plugin : getEnabledPlugins()) {
|
||||
l.addAll(plugin.getDownloadMaps());
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
public static List<IndexItem> getCustomDownloadItems() {
|
||||
List<IndexItem> l = new ArrayList<>();
|
||||
for (WorldRegion region : getCustomDownloadRegions()) {
|
||||
collectIndexItemsFromSubregion(region, l);
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
public static void collectIndexItemsFromSubregion(WorldRegion region, List<IndexItem> items) {
|
||||
if (region instanceof CustomRegion) {
|
||||
items.addAll(((CustomRegion) region).loadIndexItems());
|
||||
}
|
||||
for (WorldRegion subregion : region.getSubregions()) {
|
||||
collectIndexItemsFromSubregion(subregion, items);
|
||||
}
|
||||
}
|
||||
|
||||
public static List<String> getDisabledRendererNames() {
|
||||
List<String> l = new ArrayList<String>();
|
||||
for (OsmandPlugin plugin : getNotEnabledPlugins()) {
|
||||
|
|
|
@ -16,10 +16,12 @@ import net.osmand.PlatformUtil;
|
|||
import net.osmand.data.LatLon;
|
||||
import net.osmand.map.ITileSource;
|
||||
import net.osmand.map.TileSourceManager;
|
||||
import net.osmand.map.WorldRegion;
|
||||
import net.osmand.osm.MapPoiTypes;
|
||||
import net.osmand.osm.PoiCategory;
|
||||
import net.osmand.plus.ApplicationMode.ApplicationModeBean;
|
||||
import net.osmand.plus.ApplicationMode.ApplicationModeBuilder;
|
||||
import net.osmand.plus.CustomOsmandPlugin.SuggestedDownloadItem;
|
||||
import net.osmand.plus.OsmandSettings.OsmandPreference;
|
||||
import net.osmand.plus.helpers.AvoidSpecificRoads;
|
||||
import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo;
|
||||
|
@ -131,7 +133,9 @@ public class SettingsHelper {
|
|||
QUICK_ACTIONS,
|
||||
POI_UI_FILTERS,
|
||||
MAP_SOURCES,
|
||||
AVOID_ROADS
|
||||
AVOID_ROADS,
|
||||
SUGGESTED_DOWNLOADS,
|
||||
DOWNLOADS
|
||||
}
|
||||
|
||||
public abstract static class SettingsItem {
|
||||
|
@ -410,6 +414,10 @@ public class SettingsHelper {
|
|||
} else if (fileItem.getSubtype() == FileSettingsItem.FileSubtype.OTHER) {
|
||||
plugin.setResourceDirName(item.getFileName());
|
||||
}
|
||||
} else if (item instanceof SuggestedDownloadsItem) {
|
||||
plugin.updateSuggestedDownloads(((SuggestedDownloadsItem) item).getItems());
|
||||
} else if (item instanceof DownloadsItem) {
|
||||
plugin.updateDownloadItems(((DownloadsItem) item).getItems());
|
||||
}
|
||||
}
|
||||
OsmandPlugin.addCustomPlugin(app, plugin);
|
||||
|
@ -441,6 +449,199 @@ public class SettingsHelper {
|
|||
}
|
||||
}
|
||||
|
||||
public static class SuggestedDownloadsItem extends SettingsItem {
|
||||
|
||||
private List<SuggestedDownloadItem> items;
|
||||
|
||||
SuggestedDownloadsItem(@NonNull OsmandApplication app, @NonNull JSONObject json) throws JSONException {
|
||||
super(app, json);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
super.init();
|
||||
items = new ArrayList<>();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public SettingsItemType getType() {
|
||||
return SettingsItemType.SUGGESTED_DOWNLOADS;
|
||||
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return "suggested_downloads";
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String getPublicName(@NonNull Context ctx) {
|
||||
return "suggested_downloads";
|
||||
}
|
||||
|
||||
public List<SuggestedDownloadItem> getItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
@Override
|
||||
void readItemsFromJson(@NonNull JSONObject json) throws IllegalArgumentException {
|
||||
try {
|
||||
if (!json.has("items")) {
|
||||
return;
|
||||
}
|
||||
JSONArray jsonArray = json.getJSONArray("items");
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
JSONObject object = jsonArray.getJSONObject(i);
|
||||
String scopeId = object.optString("scope-id");
|
||||
String searchType = object.optString("search-type");
|
||||
int limit = object.optInt("limit", -1);
|
||||
|
||||
List<String> names = new ArrayList<>();
|
||||
if (object.has("names")) {
|
||||
JSONArray namesArray = object.getJSONArray("names");
|
||||
for (int j = 0; j < namesArray.length(); j++) {
|
||||
names.add(namesArray.getString(j));
|
||||
}
|
||||
}
|
||||
SuggestedDownloadItem suggestedDownload = new SuggestedDownloadItem(scopeId, searchType, names, limit);
|
||||
items.add(suggestedDownload);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
warnings.add(app.getString(R.string.settings_item_read_error, String.valueOf(getType())));
|
||||
throw new IllegalArgumentException("Json parse error", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void writeItemsToJson(@NonNull JSONObject json) {
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
if (!items.isEmpty()) {
|
||||
try {
|
||||
for (SuggestedDownloadItem downloadItem : items) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("scope-id", downloadItem.getScopeId());
|
||||
if (downloadItem.getLimit() != -1) {
|
||||
jsonObject.put("limit", downloadItem.getLimit());
|
||||
}
|
||||
if (!Algorithms.isEmpty(downloadItem.getSearchType())) {
|
||||
jsonObject.put("search-type", downloadItem.getSearchType());
|
||||
}
|
||||
if (!Algorithms.isEmpty(downloadItem.getNames())) {
|
||||
JSONArray namesArray = new JSONArray();
|
||||
for (String downloadName : downloadItem.getNames()) {
|
||||
namesArray.put(downloadName);
|
||||
}
|
||||
jsonObject.put("names", namesArray);
|
||||
}
|
||||
jsonArray.put(jsonObject);
|
||||
}
|
||||
json.put("items", jsonArray);
|
||||
} catch (JSONException e) {
|
||||
warnings.add(app.getString(R.string.settings_item_write_error, String.valueOf(getType())));
|
||||
LOG.error("Failed write to json", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
SettingsItemReader getReader() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
SettingsItemWriter getWriter() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class DownloadsItem extends SettingsItem {
|
||||
|
||||
private List<WorldRegion> items;
|
||||
|
||||
DownloadsItem(@NonNull OsmandApplication app, @NonNull JSONObject json) throws JSONException {
|
||||
super(app, json);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
super.init();
|
||||
items = new ArrayList<>();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public SettingsItemType getType() {
|
||||
return SettingsItemType.DOWNLOADS;
|
||||
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return "downloads";
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String getPublicName(@NonNull Context ctx) {
|
||||
return "downloads";
|
||||
}
|
||||
|
||||
public List<WorldRegion> getItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
@Override
|
||||
void readItemsFromJson(@NonNull JSONObject json) throws IllegalArgumentException {
|
||||
try {
|
||||
if (!json.has("items")) {
|
||||
return;
|
||||
}
|
||||
JSONArray jsonArray = json.getJSONArray("items");
|
||||
items.addAll(CustomOsmandPlugin.collectRegionsFromJson(jsonArray));
|
||||
} catch (JSONException e) {
|
||||
warnings.add(app.getString(R.string.settings_item_read_error, String.valueOf(getType())));
|
||||
throw new IllegalArgumentException("Json parse error", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void writeItemsToJson(@NonNull JSONObject json) {
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
if (!items.isEmpty()) {
|
||||
try {
|
||||
for (WorldRegion region : items) {
|
||||
if (region instanceof CustomRegion) {
|
||||
JSONObject regionJson = ((CustomRegion) region).toJson();
|
||||
jsonArray.put(regionJson);
|
||||
}
|
||||
}
|
||||
json.put("items", jsonArray);
|
||||
} catch (JSONException e) {
|
||||
warnings.add(app.getString(R.string.settings_item_write_error, String.valueOf(getType())));
|
||||
LOG.error("Failed write to json", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
SettingsItemReader getReader() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
SettingsItemWriter getWriter() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class CollectionSettingsItem<T> extends SettingsItem {
|
||||
|
||||
protected List<T> items;
|
||||
|
@ -2095,6 +2296,12 @@ public class SettingsHelper {
|
|||
case AVOID_ROADS:
|
||||
item = new AvoidRoadsSettingsItem(app, json);
|
||||
break;
|
||||
case SUGGESTED_DOWNLOADS:
|
||||
item = new SuggestedDownloadsItem(app, json);
|
||||
break;
|
||||
case DOWNLOADS:
|
||||
item = new DownloadsItem(app, json);
|
||||
break;
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
|
|
@ -83,6 +83,7 @@ import java.util.ArrayList;
|
|||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import static net.osmand.IndexConstants.GPX_FILE_EXT;
|
||||
import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_CONFIGURE_MAP_ID;
|
||||
import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_CONFIGURE_SCREEN_ID;
|
||||
import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_DASHBOARD_ID;
|
||||
|
@ -111,7 +112,6 @@ import static net.osmand.aidlapi.OsmAndCustomizationConstants.MAP_CONTEXT_MENU_S
|
|||
import static net.osmand.plus.ContextMenuAdapter.PROFILES_CHOSEN_PROFILE_TAG;
|
||||
import static net.osmand.plus.ContextMenuAdapter.PROFILES_CONTROL_BUTTON_TAG;
|
||||
import static net.osmand.plus.ContextMenuAdapter.PROFILES_NORMAL_PROFILE_TAG;
|
||||
import static net.osmand.plus.helpers.ImportHelper.GPX_SUFFIX;
|
||||
|
||||
|
||||
public class MapActivityActions implements DialogProvider {
|
||||
|
@ -282,8 +282,8 @@ public class MapActivityActions implements DialogProvider {
|
|||
fileDir.mkdirs();
|
||||
File toSave = fileDir;
|
||||
if (name.length() > 0) {
|
||||
if (!name.endsWith(GPX_SUFFIX)) {
|
||||
name += GPX_SUFFIX;
|
||||
if (!name.endsWith(GPX_FILE_EXT)) {
|
||||
name += GPX_FILE_EXT;
|
||||
}
|
||||
toSave = new File(fileDir, name);
|
||||
}
|
||||
|
@ -320,7 +320,7 @@ public class MapActivityActions implements DialogProvider {
|
|||
if (params.length > 0) {
|
||||
File file = params[0];
|
||||
String fileName = file.getName();
|
||||
GPXFile gpx = app.getRoutingHelper().generateGPXFileWithRoute(fileName.substring(0,fileName.length()-GPX_SUFFIX.length()));
|
||||
GPXFile gpx = app.getRoutingHelper().generateGPXFileWithRoute(fileName.substring(0,fileName.length()-GPX_FILE_EXT.length()));
|
||||
GPXUtilities.writeGpxFile(file, gpx);
|
||||
return app.getString(R.string.route_successfully_saved_at, file.getName());
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import android.database.sqlite.SQLiteDatabase;
|
|||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.text.format.DateFormat;
|
||||
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.plus.GPXDatabase.GpxDataItem;
|
||||
|
@ -209,7 +210,7 @@ public class SavingTrackHelper extends SQLiteOpenHelper {
|
|||
// save file
|
||||
for (final String f : data.keySet()) {
|
||||
log.debug("Filename: " + f);
|
||||
File fout = new File(dir, f + ".gpx"); //$NON-NLS-1$
|
||||
File fout = new File(dir, f + IndexConstants.GPX_FILE_EXT);
|
||||
if (!data.get(f).isEmpty()) {
|
||||
WptPt pt = data.get(f).findPointToShow();
|
||||
String fileName = f + "_" + new SimpleDateFormat("HH-mm_EEE", Locale.US).format(new Date(pt.time)); //$NON-NLS-1$
|
||||
|
@ -227,10 +228,10 @@ public class SavingTrackHelper extends SQLiteOpenHelper {
|
|||
}
|
||||
}
|
||||
filenames.add(fileName);
|
||||
fout = new File(dir, fileName + ".gpx"); //$NON-NLS-1$
|
||||
fout = new File(dir, fileName + IndexConstants.GPX_FILE_EXT);
|
||||
int ind = 1;
|
||||
while (fout.exists()) {
|
||||
fout = new File(dir, fileName + "_" + (++ind) + ".gpx"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
fout = new File(dir, fileName + "_" + (++ind) + IndexConstants.GPX_FILE_EXT); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ import net.osmand.GPXUtilities;
|
|||
import net.osmand.GPXUtilities.GPXFile;
|
||||
import net.osmand.GPXUtilities.TrkSegment;
|
||||
import net.osmand.GPXUtilities.WptPt;
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.data.PointDescription;
|
||||
import net.osmand.data.QuadRect;
|
||||
|
@ -92,7 +93,7 @@ public class TrackActivity extends TabActivity {
|
|||
ActionBar actionBar = getSupportActionBar();
|
||||
if (actionBar != null) {
|
||||
if (file != null) {
|
||||
String fn = file.getName().replace(".gpx", "").replace("/", " ").replace("_", " ");
|
||||
String fn = file.getName().replace(IndexConstants.GPX_FILE_EXT, "").replace("/", " ").replace("_", " ");
|
||||
actionBar.setTitle(fn);
|
||||
} else {
|
||||
actionBar.setTitle(getString(R.string.shared_string_currently_recording_track));
|
||||
|
|
196
OsmAnd/src/net/osmand/plus/download/CustomIndexItem.java
Normal file
196
OsmAnd/src/net/osmand/plus/download/CustomIndexItem.java
Normal file
|
@ -0,0 +1,196 @@
|
|||
package net.osmand.plus.download;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import net.osmand.JsonUtils;
|
||||
import net.osmand.map.OsmandRegions;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class CustomIndexItem extends IndexItem {
|
||||
|
||||
private String subfolder;
|
||||
private String downloadUrl;
|
||||
private String webUrl;
|
||||
|
||||
private List<String> imageDescrUrl;
|
||||
private Map<String, String> names;
|
||||
private Map<String, String> descriptions;
|
||||
private Map<String, String> webButtonTexts;
|
||||
|
||||
public CustomIndexItem(String fileName,
|
||||
String subfolder,
|
||||
String downloadUrl,
|
||||
String webUrl,
|
||||
String size,
|
||||
long timestamp,
|
||||
long contentSize,
|
||||
long containerSize,
|
||||
List<String> imageDescrUrl,
|
||||
Map<String, String> names,
|
||||
Map<String, String> descriptions,
|
||||
Map<String, String> webButtonTexts,
|
||||
@NonNull DownloadActivityType type) {
|
||||
super(fileName, null, timestamp, size, contentSize, containerSize, type);
|
||||
this.subfolder = subfolder;
|
||||
this.downloadUrl = downloadUrl;
|
||||
this.webUrl = webUrl;
|
||||
this.imageDescrUrl = imageDescrUrl;
|
||||
this.names = names;
|
||||
this.descriptions = descriptions;
|
||||
this.webButtonTexts = webButtonTexts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DownloadEntry createDownloadEntry(OsmandApplication ctx) {
|
||||
DownloadEntry entry = super.createDownloadEntry(ctx);
|
||||
if (entry != null) {
|
||||
entry.urlToDownload = downloadUrl;
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getTargetFile(OsmandApplication ctx) {
|
||||
String basename = getTranslatedBasename();
|
||||
if (!Algorithms.isEmpty(subfolder)) {
|
||||
basename = subfolder + "/" + basename;
|
||||
}
|
||||
return new File(type.getDownloadFolder(ctx, this), basename + type.getUnzipExtension(ctx, this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVisibleName(Context ctx, OsmandRegions osmandRegions) {
|
||||
return getVisibleName(ctx, osmandRegions, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVisibleName(Context ctx, OsmandRegions osmandRegions, boolean includingParent) {
|
||||
String name = super.getVisibleName(ctx, osmandRegions, includingParent);
|
||||
return JsonUtils.getLocalizedResFromMap(ctx, names, name);
|
||||
}
|
||||
|
||||
public List<String> getDescriptionImageUrl() {
|
||||
return imageDescrUrl;
|
||||
}
|
||||
|
||||
public String getLocalizedDescription(Context ctx) {
|
||||
String description = super.getDescription();
|
||||
return JsonUtils.getLocalizedResFromMap(ctx, descriptions, description);
|
||||
}
|
||||
|
||||
public String getWebUrl() {
|
||||
return webUrl;
|
||||
}
|
||||
|
||||
public String getWebButtonText(Context ctx) {
|
||||
return JsonUtils.getLocalizedResFromMap(ctx, webButtonTexts, null);
|
||||
}
|
||||
|
||||
public static class CustomIndexItemBuilder {
|
||||
|
||||
private String fileName;
|
||||
private String subfolder;
|
||||
private String downloadUrl;
|
||||
private String webUrl;
|
||||
private String size;
|
||||
|
||||
private long timestamp;
|
||||
private long contentSize;
|
||||
private long containerSize;
|
||||
|
||||
private List<String> imageDescrUrl;
|
||||
private Map<String, String> names;
|
||||
private Map<String, String> descriptions;
|
||||
private Map<String, String> webButtonText;
|
||||
private DownloadActivityType type;
|
||||
|
||||
|
||||
public CustomIndexItemBuilder setFileName(String fileName) {
|
||||
this.fileName = fileName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CustomIndexItemBuilder setSubfolder(String subfolder) {
|
||||
this.subfolder = subfolder;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CustomIndexItemBuilder setDownloadUrl(String downloadUrl) {
|
||||
this.downloadUrl = downloadUrl;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CustomIndexItemBuilder setWebUrl(String webUrl) {
|
||||
this.webUrl = webUrl;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CustomIndexItemBuilder setSize(String size) {
|
||||
this.size = size;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CustomIndexItemBuilder setTimestamp(long timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CustomIndexItemBuilder setContentSize(long contentSize) {
|
||||
this.contentSize = contentSize;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CustomIndexItemBuilder setContainerSize(long containerSize) {
|
||||
this.containerSize = containerSize;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CustomIndexItemBuilder setImageDescrUrl(List<String> imageDescrUrl) {
|
||||
this.imageDescrUrl = imageDescrUrl;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CustomIndexItemBuilder setNames(Map<String, String> names) {
|
||||
this.names = names;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CustomIndexItemBuilder setDescriptions(Map<String, String> descriptions) {
|
||||
this.descriptions = descriptions;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CustomIndexItemBuilder setWebButtonText(Map<String, String> webButtonText) {
|
||||
this.webButtonText = webButtonText;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CustomIndexItemBuilder setType(@NonNull DownloadActivityType type) {
|
||||
this.type = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CustomIndexItem create() {
|
||||
return new CustomIndexItem(fileName,
|
||||
subfolder,
|
||||
downloadUrl,
|
||||
webUrl,
|
||||
size,
|
||||
timestamp,
|
||||
contentSize,
|
||||
containerSize,
|
||||
imageDescrUrl,
|
||||
names,
|
||||
descriptions,
|
||||
webButtonText,
|
||||
type);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -51,6 +51,11 @@ public class DownloadActivityType {
|
|||
new DownloadActivityType(R.string.shared_string_wikivoyage, R.drawable.ic_plugin_wikipedia, "wikivoyage", 65);
|
||||
public static final DownloadActivityType LIVE_UPDATES_FILE =
|
||||
new DownloadActivityType(R.string.download_live_updates, "live_updates", 70);
|
||||
public static final DownloadActivityType GPX_FILE =
|
||||
new DownloadActivityType(R.string.shared_string_gpx_tracks, R.drawable.ic_action_polygom_dark, "gpx", 75);
|
||||
public static final DownloadActivityType SQLITE_FILE =
|
||||
new DownloadActivityType(R.string.shared_string_online_maps, "sqlite", 80);
|
||||
|
||||
private final int stringResource;
|
||||
private final int iconResource;
|
||||
|
||||
|
@ -136,6 +141,10 @@ public class DownloadActivityType {
|
|||
return fileName.endsWith(IndexConstants.SQLITE_EXT);
|
||||
} else if (DEPTH_CONTOUR_FILE == this) {
|
||||
return fileName.endsWith(addVersionToExt(IndexConstants.BINARY_MAP_INDEX_EXT_ZIP, IndexConstants.BINARY_MAP_VERSION));
|
||||
} else if (GPX_FILE == this) {
|
||||
return fileName.endsWith(IndexConstants.GPX_FILE_EXT);
|
||||
} else if (SQLITE_FILE == this) {
|
||||
return fileName.endsWith(IndexConstants.SQLITE_EXT);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -166,14 +175,18 @@ public class DownloadActivityType {
|
|||
return ctx.getAppPath(IndexConstants.TILES_INDEX_DIR);
|
||||
} else if (DEPTH_CONTOUR_FILE == this) {
|
||||
return ctx.getAppPath(IndexConstants.MAPS_PATH);
|
||||
} else if (GPX_FILE == this) {
|
||||
return ctx.getAppPath(IndexConstants.GPX_INDEX_DIR);
|
||||
} else if (SQLITE_FILE == this) {
|
||||
return ctx.getAppPath(IndexConstants.TILES_INDEX_DIR);
|
||||
}
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
public boolean isZipStream(OsmandApplication ctx, IndexItem indexItem) {
|
||||
return HILLSHADE_FILE != this && SLOPE_FILE != this && WIKIVOYAGE_FILE != this;
|
||||
return HILLSHADE_FILE != this && SLOPE_FILE != this && SQLITE_FILE != this && WIKIVOYAGE_FILE != this && GPX_FILE != this;
|
||||
}
|
||||
|
||||
|
||||
public boolean isZipFolder(OsmandApplication ctx, IndexItem indexItem) {
|
||||
return this == VOICE_FILE;
|
||||
}
|
||||
|
@ -213,8 +226,12 @@ public class DownloadActivityType {
|
|||
return IndexConstants.SQLITE_EXT;
|
||||
} else if (SLOPE_FILE == this) {
|
||||
return IndexConstants.SQLITE_EXT;
|
||||
} else if (SQLITE_FILE == this) {
|
||||
return IndexConstants.SQLITE_EXT;
|
||||
} else if (DEPTH_CONTOUR_FILE == this) {
|
||||
return BINARY_MAP_INDEX_EXT;
|
||||
} else if (GPX_FILE == this) {
|
||||
return IndexConstants.GPX_FILE_EXT;
|
||||
}
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
@ -238,6 +255,8 @@ public class DownloadActivityType {
|
|||
return "&fonts=yes";
|
||||
} else if (this == DEPTH_CONTOUR_FILE) {
|
||||
return "&inapp=depth";
|
||||
} else if (this == GPX_FILE) {
|
||||
return "&gpx=yes";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
@ -303,6 +322,8 @@ public class DownloadActivityType {
|
|||
return ctx.getString(R.string.download_depth_countours);
|
||||
} else if (this == FONT_FILE) {
|
||||
return ctx.getString(R.string.fonts_header);
|
||||
} else if (this == GPX_FILE) {
|
||||
return ctx.getString(R.string.shared_string_gpx_tracks);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
@ -370,6 +391,8 @@ public class DownloadActivityType {
|
|||
return fileName.replace('_', ' ');
|
||||
} else if (this == SLOPE_FILE) {
|
||||
return fileName.replace('_', ' ');
|
||||
} else if (this == SQLITE_FILE) {
|
||||
return fileName.replace('_', ' ');
|
||||
} else if (this == LIVE_UPDATES_FILE) {
|
||||
int l = fileName.lastIndexOf('.');
|
||||
if (l == -1) {
|
||||
|
|
|
@ -349,6 +349,7 @@ public class DownloadIndexesThread {
|
|||
app.getSettings().LAST_CHECKED_UPDATES.set(System.currentTimeMillis());
|
||||
result.prepareData(indexFileList.getIndexFiles());
|
||||
} catch (Exception e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
return result == null ? new DownloadResources(app) : result;
|
||||
|
|
|
@ -55,6 +55,7 @@ public class DownloadResourceGroup {
|
|||
FONTS(R.string.fonts_header),
|
||||
VOICE_REC(R.string.index_name_voice),
|
||||
OTHER_MAPS(R.string.download_select_map_types),
|
||||
EXTRA_MAPS(R.string.extra_maps_menu_group),
|
||||
WORLD(-1),
|
||||
REGION(-1);
|
||||
|
||||
|
@ -79,7 +80,7 @@ public class DownloadResourceGroup {
|
|||
|
||||
public boolean containsIndexItem() {
|
||||
return isHeader() && this != SUBREGIONS && this != OTHER_GROUP && this != OTHER_MAPS_GROUP
|
||||
&& this != NAUTICAL_MAPS_GROUP && this != TRAVEL_GROUP;
|
||||
&& this != NAUTICAL_MAPS_GROUP && this != TRAVEL_GROUP && this != EXTRA_MAPS;
|
||||
}
|
||||
|
||||
public boolean isHeader() {
|
||||
|
@ -90,7 +91,8 @@ public class DownloadResourceGroup {
|
|||
|| this == OTHER_MAPS_HEADER || this == OTHER_MAPS_GROUP
|
||||
|| this == FONTS_HEADER
|
||||
|| this == NAUTICAL_MAPS_HEADER || this == NAUTICAL_MAPS_GROUP
|
||||
|| this == WIKIVOYAGE_HEADER || this == TRAVEL_GROUP;
|
||||
|| this == WIKIVOYAGE_HEADER || this == TRAVEL_GROUP
|
||||
|| this == EXTRA_MAPS;
|
||||
}
|
||||
|
||||
public static String getVoiceTTSId() {
|
||||
|
@ -274,7 +276,7 @@ public class DownloadResourceGroup {
|
|||
}
|
||||
|
||||
public IndexItem getItemByIndex(int ind) {
|
||||
if(individualResources != null && ind < individualResources.size()) {
|
||||
if (individualResources != null && ind >= 0 && ind < individualResources.size()) {
|
||||
return individualResources.get(ind);
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -9,8 +9,11 @@ import net.osmand.data.LatLon;
|
|||
import net.osmand.map.OsmandRegions;
|
||||
import net.osmand.map.WorldRegion;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.OsmandPlugin;
|
||||
import net.osmand.plus.CustomRegion;
|
||||
import net.osmand.plus.download.DownloadOsmandIndexesHelper.AssetIndexItem;
|
||||
import net.osmand.plus.inapp.InAppPurchaseHelper;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
|
@ -290,6 +293,8 @@ public class DownloadResources extends DownloadResourceGroup {
|
|||
protected boolean prepareData(List<IndexItem> resources) {
|
||||
this.rawResources = resources;
|
||||
|
||||
DownloadResourceGroup extraMapsGroup = new DownloadResourceGroup(this, DownloadResourceGroupType.EXTRA_MAPS);
|
||||
|
||||
DownloadResourceGroup otherMapsGroup = new DownloadResourceGroup(this, DownloadResourceGroupType.OTHER_MAPS_GROUP);
|
||||
DownloadResourceGroup otherMapsScreen = new DownloadResourceGroup(otherMapsGroup, DownloadResourceGroupType.OTHER_MAPS);
|
||||
DownloadResourceGroup otherMaps = new DownloadResourceGroup(otherMapsGroup, DownloadResourceGroupType.OTHER_MAPS_HEADER);
|
||||
|
@ -363,6 +368,14 @@ public class DownloadResources extends DownloadResourceGroup {
|
|||
}
|
||||
this.groupByRegion = groupByRegion;
|
||||
|
||||
List<WorldRegion> customRegions = OsmandPlugin.getCustomDownloadRegions();
|
||||
if (!Algorithms.isEmpty(customRegions)) {
|
||||
addGroup(extraMapsGroup);
|
||||
for (WorldRegion region : customRegions) {
|
||||
buildRegionsGroups(region, extraMapsGroup);
|
||||
}
|
||||
}
|
||||
|
||||
LinkedList<WorldRegion> queue = new LinkedList<WorldRegion>();
|
||||
LinkedList<DownloadResourceGroup> parent = new LinkedList<DownloadResourceGroup>();
|
||||
DownloadResourceGroup worldSubregions = new DownloadResourceGroup(this, DownloadResourceGroupType.SUBREGIONS);
|
||||
|
@ -433,6 +446,40 @@ public class DownloadResources extends DownloadResourceGroup {
|
|||
return true;
|
||||
}
|
||||
|
||||
private void buildRegionsGroups(WorldRegion region, DownloadResourceGroup group) {
|
||||
LinkedList<WorldRegion> queue = new LinkedList<WorldRegion>();
|
||||
LinkedList<DownloadResourceGroup> parent = new LinkedList<DownloadResourceGroup>();
|
||||
queue.add(region);
|
||||
parent.add(group);
|
||||
while (!queue.isEmpty()) {
|
||||
WorldRegion reg = queue.pollFirst();
|
||||
DownloadResourceGroup parentGroup = parent.pollFirst();
|
||||
List<WorldRegion> subregions = reg.getSubregions();
|
||||
DownloadResourceGroup mainGrp = new DownloadResourceGroup(parentGroup, DownloadResourceGroupType.REGION, reg.getRegionId());
|
||||
mainGrp.region = reg;
|
||||
parentGroup.addGroup(mainGrp);
|
||||
|
||||
if (reg instanceof CustomRegion) {
|
||||
CustomRegion customRegion = (CustomRegion) reg;
|
||||
List<IndexItem> indexItems = customRegion.loadIndexItems();
|
||||
if (!Algorithms.isEmpty(indexItems)) {
|
||||
DownloadResourceGroup flatFiles = new DownloadResourceGroup(mainGrp, DownloadResourceGroupType.REGION_MAPS);
|
||||
for (IndexItem ii : indexItems) {
|
||||
flatFiles.addItem(ii);
|
||||
}
|
||||
mainGrp.addGroup(flatFiles);
|
||||
}
|
||||
}
|
||||
DownloadResourceGroup subRegions = new DownloadResourceGroup(mainGrp, DownloadResourceGroupType.SUBREGIONS);
|
||||
mainGrp.addGroup(subRegions);
|
||||
// add to processing queue
|
||||
for (WorldRegion rg : subregions) {
|
||||
queue.add(rg);
|
||||
parent.add(subRegions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return smallest index item, if there are no downloaded index items; Downloaded item otherwise.
|
||||
*/
|
||||
|
@ -465,6 +512,10 @@ public class DownloadResources extends DownloadResourceGroup {
|
|||
}
|
||||
|
||||
public static List<IndexItem> findIndexItemsAt(OsmandApplication app, LatLon latLon, DownloadActivityType type, boolean includeDownloaded) throws IOException {
|
||||
return findIndexItemsAt(app, latLon, type, includeDownloaded, -1);
|
||||
}
|
||||
|
||||
public static List<IndexItem> findIndexItemsAt(OsmandApplication app, LatLon latLon, DownloadActivityType type, boolean includeDownloaded, int limit) throws IOException {
|
||||
List<IndexItem> res = new ArrayList<>();
|
||||
OsmandRegions regions = app.getRegions();
|
||||
DownloadIndexesThread downloadThread = app.getDownloadThread();
|
||||
|
@ -473,6 +524,25 @@ public class DownloadResources extends DownloadResourceGroup {
|
|||
if (includeDownloaded || !isIndexItemDownloaded(downloadThread, type, downloadRegion, res)) {
|
||||
addIndexItem(downloadThread, type, downloadRegion, res);
|
||||
}
|
||||
if (limit != -1 && res.size() == limit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public static List<IndexItem> findIndexItemsAt(OsmandApplication app, List<String> names, DownloadActivityType type, boolean includeDownloaded, int limit) {
|
||||
List<IndexItem> res = new ArrayList<>();
|
||||
OsmandRegions regions = app.getRegions();
|
||||
DownloadIndexesThread downloadThread = app.getDownloadThread();
|
||||
for (String name : names) {
|
||||
WorldRegion downloadRegion = regions.getRegionDataByDownloadName(name);
|
||||
if (downloadRegion != null && (includeDownloaded || !isIndexItemDownloaded(downloadThread, type, downloadRegion, res))) {
|
||||
addIndexItem(downloadThread, type, downloadRegion, res);
|
||||
}
|
||||
if (limit != -1 && res.size() == limit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -135,19 +135,22 @@ public class IndexItem implements Comparable<IndexItem> {
|
|||
public String getBasename() {
|
||||
return type.getBasename(this);
|
||||
}
|
||||
|
||||
|
||||
public File getTargetFile(OsmandApplication ctx) {
|
||||
String basename;
|
||||
if (type == DownloadActivityType.HILLSHADE_FILE) {
|
||||
basename = (FileNameTranslationHelper.HILL_SHADE + getBasename()).replace("_", " ");
|
||||
} else if (type == DownloadActivityType.SLOPE_FILE) {
|
||||
basename = (FileNameTranslationHelper.SLOPE + getBasename()).replace('_', ' ');
|
||||
} else {
|
||||
basename = getBasename();
|
||||
}
|
||||
String basename = getTranslatedBasename();
|
||||
return new File(type.getDownloadFolder(ctx, this), basename + type.getUnzipExtension(ctx, this));
|
||||
}
|
||||
|
||||
public String getTranslatedBasename() {
|
||||
if (type == DownloadActivityType.HILLSHADE_FILE) {
|
||||
return (FileNameTranslationHelper.HILL_SHADE + getBasename()).replace("_", " ");
|
||||
} else if (type == DownloadActivityType.SLOPE_FILE) {
|
||||
return (FileNameTranslationHelper.SLOPE + getBasename()).replace('_', ' ');
|
||||
} else {
|
||||
return getBasename();
|
||||
}
|
||||
}
|
||||
|
||||
public File getBackupFile(OsmandApplication ctx) {
|
||||
File backup = new File(ctx.getAppPath(IndexConstants.BACKUP_INDEX_DIR), getTargetFile(ctx).getName());
|
||||
return backup;
|
||||
|
|
178
OsmAnd/src/net/osmand/plus/download/ui/DownloadItemFragment.java
Normal file
178
OsmAnd/src/net/osmand/plus/download/ui/DownloadItemFragment.java
Normal file
|
@ -0,0 +1,178 @@
|
|||
package net.osmand.plus.download.ui;
|
||||
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
|
||||
import com.squareup.picasso.Callback;
|
||||
import com.squareup.picasso.Picasso;
|
||||
import com.squareup.picasso.RequestCreator;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.PicassoUtils;
|
||||
import net.osmand.map.WorldRegion;
|
||||
import net.osmand.plus.CustomRegion;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
import net.osmand.plus.download.CustomIndexItem;
|
||||
import net.osmand.plus.download.DownloadActivity;
|
||||
import net.osmand.plus.download.DownloadResourceGroup;
|
||||
import net.osmand.plus.download.DownloadResources;
|
||||
import net.osmand.plus.wikipedia.WikipediaDialogFragment;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import static net.osmand.plus.download.ui.DownloadResourceGroupFragment.REGION_ID_DLG_KEY;
|
||||
|
||||
public class DownloadItemFragment extends DialogFragment {
|
||||
|
||||
public static final String ITEM_ID_DLG_KEY = "index_item_dialog_key";
|
||||
|
||||
public static final String TAG = DownloadItemFragment.class.getSimpleName();
|
||||
|
||||
private String regionId = "";
|
||||
private int itemIndex = -1;
|
||||
|
||||
private DownloadResourceGroup group;
|
||||
private CustomIndexItem indexItem;
|
||||
|
||||
private View view;
|
||||
private Toolbar toolbar;
|
||||
private ImageView image;
|
||||
private TextView description;
|
||||
private TextView buttonTextView;
|
||||
|
||||
private boolean nightMode;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
nightMode = !getMyApplication().getSettings().isLightContent();
|
||||
int themeId = nightMode ? R.style.OsmandDarkTheme : R.style.OsmandLightTheme;
|
||||
setStyle(STYLE_NO_FRAME, themeId);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
view = inflater.inflate(R.layout.item_info_fragment, container, false);
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
regionId = savedInstanceState.getString(REGION_ID_DLG_KEY);
|
||||
itemIndex = savedInstanceState.getInt(ITEM_ID_DLG_KEY, -1);
|
||||
}
|
||||
if ((itemIndex == -1 || group == null) && getArguments() != null) {
|
||||
regionId = getArguments().getString(REGION_ID_DLG_KEY);
|
||||
itemIndex = getArguments().getInt(ITEM_ID_DLG_KEY, -1);
|
||||
}
|
||||
|
||||
toolbar = view.findViewById(R.id.toolbar);
|
||||
Drawable icBack = getMyApplication().getUIUtilities().getIcon(AndroidUtils.getNavigationIconResId(requireContext()));
|
||||
toolbar.setNavigationIcon(icBack);
|
||||
toolbar.setNavigationContentDescription(R.string.access_shared_string_navigate_up);
|
||||
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
|
||||
description = view.findViewById(R.id.item_description);
|
||||
image = view.findViewById(R.id.item_image);
|
||||
|
||||
View dismissButton = view.findViewById(R.id.dismiss_button);
|
||||
dismissButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (indexItem != null && !Algorithms.isEmpty(indexItem.getWebUrl())) {
|
||||
WikipediaDialogFragment.showFullArticle(v.getContext(), Uri.parse(indexItem.getWebUrl()), nightMode);
|
||||
}
|
||||
}
|
||||
});
|
||||
UiUtilities.setupDialogButton(nightMode, dismissButton, UiUtilities.DialogButtonType.PRIMARY, "");
|
||||
buttonTextView = (TextView) dismissButton.findViewById(R.id.button_text);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
reloadData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putString(REGION_ID_DLG_KEY, regionId);
|
||||
outState.putInt(ITEM_ID_DLG_KEY, itemIndex);
|
||||
}
|
||||
|
||||
private void reloadData() {
|
||||
DownloadActivity downloadActivity = getDownloadActivity();
|
||||
if (downloadActivity != null) {
|
||||
OsmandApplication app = downloadActivity.getMyApplication();
|
||||
DownloadResources indexes = getDownloadActivity().getDownloadThread().getIndexes();
|
||||
group = indexes.getGroupById(regionId);
|
||||
indexItem = (CustomIndexItem) group.getItemByIndex(itemIndex);
|
||||
if (indexItem != null) {
|
||||
toolbar.setTitle(indexItem.getVisibleName(app, app.getRegions()));
|
||||
WorldRegion region = group.getRegion();
|
||||
if (region instanceof CustomRegion) {
|
||||
CustomRegion customRegion = (CustomRegion) region;
|
||||
int color = customRegion.getHeaderColor();
|
||||
if (color != -1) {
|
||||
toolbar.setBackgroundColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
description.setText(indexItem.getLocalizedDescription(app));
|
||||
buttonTextView.setText(indexItem.getWebButtonText(app));
|
||||
|
||||
final PicassoUtils picassoUtils = PicassoUtils.getPicasso(app);
|
||||
Picasso picasso = Picasso.get();
|
||||
for (final String imageUrl : indexItem.getDescriptionImageUrl()) {
|
||||
RequestCreator rc = picasso.load(imageUrl);
|
||||
rc.into(image, new Callback() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
image.setVisibility(View.VISIBLE);
|
||||
picassoUtils.setResultLoaded(imageUrl, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Exception e) {
|
||||
image.setVisibility(View.GONE);
|
||||
picassoUtils.setResultLoaded(imageUrl, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private OsmandApplication getMyApplication() {
|
||||
return (OsmandApplication) getActivity().getApplication();
|
||||
}
|
||||
|
||||
private DownloadActivity getDownloadActivity() {
|
||||
return (DownloadActivity) getActivity();
|
||||
}
|
||||
|
||||
public static DownloadItemFragment createInstance(String regionId, int itemIndex) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString(REGION_ID_DLG_KEY, regionId);
|
||||
bundle.putInt(ITEM_ID_DLG_KEY, itemIndex);
|
||||
DownloadItemFragment fragment = new DownloadItemFragment();
|
||||
fragment.setArguments(bundle);
|
||||
return fragment;
|
||||
}
|
||||
}
|
|
@ -33,6 +33,7 @@ import net.osmand.plus.OsmandSettings;
|
|||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
import net.osmand.plus.activities.OsmandBaseExpandableListAdapter;
|
||||
import net.osmand.plus.download.CustomIndexItem;
|
||||
import net.osmand.plus.download.DownloadActivity;
|
||||
import net.osmand.plus.download.DownloadActivity.BannerAndDownloadFreeVersion;
|
||||
import net.osmand.plus.download.DownloadActivityType;
|
||||
|
@ -60,8 +61,10 @@ public class DownloadResourceGroupFragment extends DialogFragment implements Dow
|
|||
InAppPurchaseListener, OnChildClickListener {
|
||||
public static final int RELOAD_ID = 0;
|
||||
public static final int SEARCH_ID = 1;
|
||||
|
||||
public static final String TAG = "RegionDialogFragment";
|
||||
private static final String REGION_ID_DLG_KEY = "world_region_dialog_key";
|
||||
public static final String REGION_ID_DLG_KEY = "world_region_dialog_key";
|
||||
|
||||
private String groupId;
|
||||
private View view;
|
||||
private BannerAndDownloadFreeVersion banner;
|
||||
|
@ -451,6 +454,11 @@ public class DownloadResourceGroupFragment extends DialogFragment implements Dow
|
|||
.createInstance(uniqueId);
|
||||
((DownloadActivity) getActivity()).showDialog(getActivity(), regionDialogFragment);
|
||||
return true;
|
||||
} else if (child instanceof CustomIndexItem) {
|
||||
String regionId = group.getGroupByIndex(groupPosition).getUniqueId();
|
||||
|
||||
DownloadItemFragment downloadItemFragment = DownloadItemFragment.createInstance(regionId, childPosition);
|
||||
((DownloadActivity) getActivity()).showDialog(getActivity(), downloadItemFragment);
|
||||
} else if (child instanceof IndexItem) {
|
||||
IndexItem indexItem = (IndexItem) child;
|
||||
ItemViewHolder vh = (ItemViewHolder) v.getTag();
|
||||
|
@ -631,11 +639,12 @@ public class DownloadResourceGroupFragment extends DialogFragment implements Dow
|
|||
viewHolder.setShowRemoteDate(true);
|
||||
convertView.setTag(viewHolder);
|
||||
}
|
||||
if(mainGroup.getType() == DownloadResourceGroupType.REGION &&
|
||||
group != null && group.getType() == DownloadResourceGroupType.REGION_MAPS) {
|
||||
if (mainGroup.getType() == DownloadResourceGroupType.REGION &&
|
||||
group != null && group.getType() == DownloadResourceGroupType.REGION_MAPS
|
||||
&& !(item instanceof CustomIndexItem)) {
|
||||
viewHolder.setShowTypeInName(true);
|
||||
viewHolder.setShowTypeInDesc(false);
|
||||
} else if(group != null && (group.getType() == DownloadResourceGroupType.SRTM_HEADER
|
||||
} else if (group != null && (group.getType() == DownloadResourceGroupType.SRTM_HEADER
|
||||
|| group.getType() == DownloadResourceGroupType.HILLSHADE_HEADER)) {
|
||||
viewHolder.setShowTypeInName(false);
|
||||
viewHolder.setShowTypeInDesc(false);
|
||||
|
|
|
@ -115,6 +115,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
|
||||
import static com.github.mikephil.charting.components.XAxis.XAxisPosition.BOTTOM;
|
||||
import static net.osmand.IndexConstants.GPX_FILE_EXT;
|
||||
import static net.osmand.binary.RouteDataObject.HEIGHT_UNDEFINED;
|
||||
import static net.osmand.plus.OsmAndFormatter.FEET_IN_ONE_METER;
|
||||
import static net.osmand.plus.OsmAndFormatter.METERS_IN_KILOMETER;
|
||||
|
@ -307,8 +308,8 @@ public class GpxUiHelper {
|
|||
|
||||
public static String getGpxTitle(String fileName) {
|
||||
String s = fileName;
|
||||
if (s.toLowerCase().endsWith(".gpx")) {
|
||||
s = s.substring(0, s.length() - ".gpx".length());
|
||||
if (s.toLowerCase().endsWith(GPX_FILE_EXT)) {
|
||||
s = s.substring(0, s.length() - GPX_FILE_EXT.length());
|
||||
}
|
||||
s = s.replace('_', ' ');
|
||||
return s;
|
||||
|
@ -901,7 +902,7 @@ public class GpxUiHelper {
|
|||
File[] files = dir.listFiles();
|
||||
if (files != null) {
|
||||
for (File f : files) {
|
||||
if (f.getName().toLowerCase().endsWith(".gpx")) { //$NON-NLS-1$
|
||||
if (f.getName().toLowerCase().endsWith(GPX_FILE_EXT)) {
|
||||
list.add(new GPXInfo(absolutePath ? f.getAbsolutePath() :
|
||||
parent + f.getName(), f.lastModified(), f.length()));
|
||||
} else if (f.isDirectory()) {
|
||||
|
|
|
@ -84,6 +84,7 @@ import java.util.Map;
|
|||
import java.util.zip.ZipInputStream;
|
||||
|
||||
import static android.app.Activity.RESULT_OK;
|
||||
import static net.osmand.IndexConstants.GPX_FILE_EXT;
|
||||
import static net.osmand.IndexConstants.OSMAND_SETTINGS_FILE_EXT;
|
||||
import static net.osmand.IndexConstants.RENDERER_INDEX_EXT;
|
||||
import static net.osmand.IndexConstants.ROUTING_FILE_EXT;
|
||||
|
@ -99,7 +100,7 @@ public class ImportHelper {
|
|||
public final static Log log = PlatformUtil.getLog(ImportHelper.class);
|
||||
public static final String KML_SUFFIX = ".kml";
|
||||
public static final String KMZ_SUFFIX = ".kmz";
|
||||
public static final String GPX_SUFFIX = ".gpx";
|
||||
|
||||
private final AppCompatActivity activity;
|
||||
private final OsmandApplication app;
|
||||
private final OsmandMapTileView mapView;
|
||||
|
@ -146,8 +147,8 @@ public class ImportHelper {
|
|||
boolean isOsmandSubdir = isSubDirectory(app.getAppPath(IndexConstants.GPX_INDEX_DIR), new File(contentUri.getPath()));
|
||||
if (!isOsmandSubdir && name != null) {
|
||||
String nameLC = name.toLowerCase();
|
||||
if (nameLC.endsWith(GPX_SUFFIX)) {
|
||||
name = name.substring(0, name.length() - 4) + GPX_SUFFIX;
|
||||
if (nameLC.endsWith(GPX_FILE_EXT)) {
|
||||
name = name.substring(0, name.length() - 4) + GPX_FILE_EXT;
|
||||
handleGpxImport(contentUri, name, true, useImportDir);
|
||||
return true;
|
||||
} else if (nameLC.endsWith(KML_SUFFIX)) {
|
||||
|
@ -1046,14 +1047,14 @@ public class ImportHelper {
|
|||
private File getFileToSave(final String fileName, final File importDir, final WptPt pt) {
|
||||
final StringBuilder builder = new StringBuilder(fileName);
|
||||
if ("".equals(fileName)) {
|
||||
builder.append("import_").append(new SimpleDateFormat("HH-mm_EEE", Locale.US).format(new Date(pt.time))).append(GPX_SUFFIX); //$NON-NLS-1$
|
||||
builder.append("import_").append(new SimpleDateFormat("HH-mm_EEE", Locale.US).format(new Date(pt.time))).append(GPX_FILE_EXT); //$NON-NLS-1$
|
||||
}
|
||||
if (fileName.endsWith(KML_SUFFIX)) {
|
||||
builder.replace(builder.length() - KML_SUFFIX.length(), builder.length(), GPX_SUFFIX);
|
||||
builder.replace(builder.length() - KML_SUFFIX.length(), builder.length(), GPX_FILE_EXT);
|
||||
} else if (fileName.endsWith(KMZ_SUFFIX)) {
|
||||
builder.replace(builder.length() - KMZ_SUFFIX.length(), builder.length(), GPX_SUFFIX);
|
||||
} else if (!fileName.endsWith(GPX_SUFFIX)) {
|
||||
builder.append(GPX_SUFFIX);
|
||||
builder.replace(builder.length() - KMZ_SUFFIX.length(), builder.length(), GPX_FILE_EXT);
|
||||
} else if (!fileName.endsWith(GPX_FILE_EXT)) {
|
||||
builder.append(GPX_FILE_EXT);
|
||||
}
|
||||
return new File(importDir, builder.toString());
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import androidx.core.content.ContextCompat;
|
|||
|
||||
import net.osmand.GPXUtilities;
|
||||
import net.osmand.GPXUtilities.WptPt;
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.data.PointDescription;
|
||||
import net.osmand.plus.GpxSelectionHelper;
|
||||
|
@ -113,7 +114,7 @@ public class WptPtMenuBuilder extends MenuBuilder {
|
|||
if (points.size() > 0) {
|
||||
String title = view.getContext().getString(R.string.context_menu_points_of_group);
|
||||
File file = new File(gpx.path);
|
||||
String gpxName = file.getName().replace(".gpx", "").replace("/", " ").replace("_", " ");
|
||||
String gpxName = file.getName().replace(IndexConstants.GPX_FILE_EXT, "").replace("/", " ").replace("_", " ");
|
||||
int color = getPointColor(wpt, getFileColor(selectedGpxFile));
|
||||
buildRow(view, app.getUIUtilities().getPaintedIcon(R.drawable.ic_type_waypoints_group, color), null, title, 0, gpxName,
|
||||
true, getCollapsableWaypointsView(view.getContext(), true, gpx, wpt),
|
||||
|
|
|
@ -6,6 +6,7 @@ import androidx.annotation.NonNull;
|
|||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import net.osmand.GPXUtilities.WptPt;
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.data.PointDescription;
|
||||
import net.osmand.plus.GpxSelectionHelper;
|
||||
|
@ -115,7 +116,7 @@ public class WptPtMenuController extends MenuController {
|
|||
sb.append(", ");
|
||||
if (selectedGpxFile != null) {
|
||||
File file = new File(selectedGpxFile.getGpxFile().path);
|
||||
String gpxName = file.getName().replace(".gpx", "").replace("/", " ").replace("_", " ");
|
||||
String gpxName = file.getName().replace(IndexConstants.GPX_FILE_EXT, "").replace("/", " ").replace("_", " ");
|
||||
sb.append(gpxName);
|
||||
}
|
||||
return sb.toString();
|
||||
|
|
|
@ -172,7 +172,7 @@ public class AddTracksGroupBottomSheetDialogFragment extends AddGroupBottomSheet
|
|||
String sub = gpxSubfolder.length() == 0 ?
|
||||
gpxFile.getName() : gpxSubfolder + "/" + gpxFile.getName();
|
||||
processGPXFolder(gpxFile, sub);
|
||||
} else if (gpxFile.isFile() && gpxFile.getName().toLowerCase().endsWith(".gpx")) {
|
||||
} else if (gpxFile.isFile() && gpxFile.getName().toLowerCase().endsWith(IndexConstants.GPX_FILE_EXT)) {
|
||||
GpxDataItem item = dbHelper.getItem(gpxFile, gpxDataItemCallback);
|
||||
publishProgress(item);
|
||||
}
|
||||
|
|
|
@ -1494,10 +1494,10 @@ public class CoordinateInputDialogFragment extends DialogFragment implements Osm
|
|||
if (!dir.exists()) {
|
||||
dir.mkdirs();
|
||||
}
|
||||
File fout = new File(dir, fileName + ".gpx");
|
||||
File fout = new File(dir, fileName + IndexConstants.GPX_FILE_EXT);
|
||||
int ind = 1;
|
||||
while (fout.exists()) {
|
||||
fout = new File(dir, fileName + "_" + (++ind) + ".gpx");
|
||||
fout = new File(dir, fileName + "_" + (++ind) + IndexConstants.GPX_FILE_EXT);
|
||||
}
|
||||
GPXUtilities.writeGpxFile(fout, gpx);
|
||||
}
|
||||
|
|
|
@ -32,7 +32,6 @@ import net.osmand.plus.widgets.OsmandTextFieldBoxes;
|
|||
import java.io.File;
|
||||
import java.util.Date;
|
||||
|
||||
import static net.osmand.plus.helpers.ImportHelper.GPX_SUFFIX;
|
||||
import static net.osmand.plus.mapmarkers.CoordinateInputDialogFragment.ADDED_POINTS_NUMBER_KEY;
|
||||
|
||||
public class SaveAsTrackBottomSheetDialogFragment extends BottomSheetDialogFragment {
|
||||
|
@ -98,11 +97,11 @@ public class SaveAsTrackBottomSheetDialogFragment extends BottomSheetDialogFragm
|
|||
Date date = new Date();
|
||||
final String suggestedName = app.getString(R.string.markers) + "_" + DateFormat.format("yyyy-MM-dd", date).toString();
|
||||
String displayedName = suggestedName;
|
||||
File fout = new File(dir, suggestedName + GPX_SUFFIX);
|
||||
File fout = new File(dir, suggestedName + IndexConstants.GPX_FILE_EXT);
|
||||
int ind = 1;
|
||||
while (fout.exists()) {
|
||||
displayedName = suggestedName + "_" + (++ind);
|
||||
fout = new File(dir, displayedName + GPX_SUFFIX);
|
||||
fout = new File(dir, displayedName + IndexConstants.GPX_FILE_EXT);
|
||||
}
|
||||
final EditText nameEditText = (EditText) mainView.findViewById(R.id.name_edit_text);
|
||||
nameEditText.setText(displayedName);
|
||||
|
|
|
@ -10,6 +10,7 @@ import androidx.annotation.Nullable;
|
|||
import net.osmand.GPXUtilities;
|
||||
import net.osmand.GPXUtilities.GPXFile;
|
||||
import net.osmand.GPXUtilities.WptPt;
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.plus.GpxSelectionHelper;
|
||||
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
|
||||
import net.osmand.plus.MapMarkersHelper;
|
||||
|
@ -161,7 +162,7 @@ public class SelectWptCategoriesBottomSheetDialogFragment extends MenuBottomShee
|
|||
|
||||
private String getGpxName(GPXFile gpxFile) {
|
||||
return new File(gpxFile.path).getName()
|
||||
.replace(".gpx", "")
|
||||
.replace(IndexConstants.GPX_FILE_EXT, "")
|
||||
.replace("/", " ")
|
||||
.replace("_", " ");
|
||||
}
|
||||
|
|
|
@ -404,7 +404,7 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter<RecyclerView.V
|
|||
if (groupName.equals("")) {
|
||||
groupName = app.getString(R.string.shared_string_favorites);
|
||||
} else if (group.getType() == MapMarkersGroup.GPX_TYPE) {
|
||||
groupName = groupName.replace(".gpx", "").replace("/", " ").replace("_", " ");
|
||||
groupName = groupName.replace(IndexConstants.GPX_FILE_EXT, "").replace("/", " ").replace("_", " ");
|
||||
}
|
||||
if (group.isDisabled()) {
|
||||
headerString = groupName;
|
||||
|
|
|
@ -7,6 +7,7 @@ import androidx.annotation.Nullable;
|
|||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import net.osmand.GPXUtilities.GPXTrackAnalysis;
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.plus.GPXDatabase.GpxDataItem;
|
||||
import net.osmand.plus.R;
|
||||
|
||||
|
@ -33,7 +34,7 @@ public class TracksGroupsAdapter extends GroupsAdapter {
|
|||
GpxDataItem gpx = getItem(position);
|
||||
MapMarkersGroupViewHolder markersGroupViewHolder = (MapMarkersGroupViewHolder) holder;
|
||||
markersGroupViewHolder.icon.setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_polygom_dark));
|
||||
markersGroupViewHolder.name.setText(gpx.getFile().getName().replace(".gpx", "").replace("/", " ").replace("_", " "));
|
||||
markersGroupViewHolder.name.setText(gpx.getFile().getName().replace(IndexConstants.GPX_FILE_EXT, "").replace("/", " ").replace("_", " "));
|
||||
GPXTrackAnalysis analysis = gpx.getAnalysis();
|
||||
markersGroupViewHolder.numberCount.setText(analysis != null ? String.valueOf(analysis.wptPoints) : "");
|
||||
String description = getDescription(gpx);
|
||||
|
|
|
@ -81,7 +81,8 @@ import java.util.Date;
|
|||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import static net.osmand.plus.helpers.ImportHelper.GPX_SUFFIX;
|
||||
import static net.osmand.IndexConstants.GPX_FILE_EXT;
|
||||
|
||||
|
||||
public class MeasurementToolFragment extends BaseOsmAndFragment {
|
||||
|
||||
|
@ -1171,11 +1172,11 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
|||
|
||||
final String suggestedName = new SimpleDateFormat("yyyy-MM-dd_HH-mm_EEE", Locale.US).format(new Date());
|
||||
String displayedName = suggestedName;
|
||||
File fout = new File(dir, suggestedName + GPX_SUFFIX);
|
||||
File fout = new File(dir, suggestedName + GPX_FILE_EXT);
|
||||
int ind = 1;
|
||||
while (fout.exists()) {
|
||||
displayedName = suggestedName + "_" + (++ind);
|
||||
fout = new File(dir, displayedName + GPX_SUFFIX);
|
||||
fout = new File(dir, displayedName + GPX_FILE_EXT);
|
||||
}
|
||||
nameEt.setText(displayedName);
|
||||
nameEt.setSelection(displayedName.length());
|
||||
|
@ -1188,12 +1189,12 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
|||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
final String name = nameEt.getText().toString();
|
||||
String fileName = name + GPX_SUFFIX;
|
||||
String fileName = name + GPX_FILE_EXT;
|
||||
if (textChanged[0]) {
|
||||
File fout = new File(dir, fileName);
|
||||
int ind = 1;
|
||||
while (fout.exists()) {
|
||||
fileName = name + "_" + (++ind) + GPX_SUFFIX;
|
||||
fileName = name + "_" + (++ind) + GPX_FILE_EXT;
|
||||
fout = new File(dir, fileName);
|
||||
}
|
||||
}
|
||||
|
@ -1217,7 +1218,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
|||
|
||||
@Override
|
||||
public void afterTextChanged(Editable editable) {
|
||||
if (new File(dir, editable.toString() + GPX_SUFFIX).exists()) {
|
||||
if (new File(dir, editable.toString() + GPX_FILE_EXT).exists()) {
|
||||
warningTextView.setVisibility(View.VISIBLE);
|
||||
warningTextView.setText(R.string.file_with_name_already_exists);
|
||||
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(true);
|
||||
|
@ -1277,7 +1278,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
|||
TrkSegment after = editingCtx.getAfterTrkSegmentLine();
|
||||
if (gpx == null) {
|
||||
toSave = new File(dir, fileName);
|
||||
String trackName = fileName.substring(0, fileName.length() - GPX_SUFFIX.length());
|
||||
String trackName = fileName.substring(0, fileName.length() - GPX_FILE_EXT.length());
|
||||
GPXFile gpx = new GPXFile(Version.getFullVersion(activity.getMyApplication()));
|
||||
if (measurementLayer != null) {
|
||||
if (saveType == SaveType.LINE) {
|
||||
|
@ -1534,11 +1535,11 @@ public class MeasurementToolFragment extends BaseOsmAndFragment {
|
|||
public void onClick(DialogInterface dialog, int which) {
|
||||
if (showOnMapToggle.isChecked()) {
|
||||
final String name = new SimpleDateFormat("yyyy-MM-dd_HH-mm_EEE", Locale.US).format(new Date());
|
||||
String fileName = name + GPX_SUFFIX;
|
||||
String fileName = name + GPX_FILE_EXT;
|
||||
File fout = new File(dir, fileName);
|
||||
int ind = 1;
|
||||
while (fout.exists()) {
|
||||
fileName = name + "_" + (++ind) + GPX_SUFFIX;
|
||||
fileName = name + "_" + (++ind) + GPX_FILE_EXT;
|
||||
fout = new File(dir, fileName);
|
||||
}
|
||||
saveNewGpx(dir, fileName, true, SaveType.LINE, true);
|
||||
|
|
|
@ -25,6 +25,7 @@ import androidx.fragment.app.FragmentManager;
|
|||
|
||||
import net.osmand.GPXUtilities;
|
||||
import net.osmand.GPXUtilities.WptPt;
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
|
@ -74,7 +75,7 @@ public class OnSaveCurrentTrackFragment extends BottomSheetDialogFragment {
|
|||
}
|
||||
|
||||
Context ctx = requireContext();
|
||||
file = new File(app.getAppCustomization().getTracksDir(), savedGpxName + ".gpx");
|
||||
file = new File(app.getAppCustomization().getTracksDir(), savedGpxName + IndexConstants.GPX_FILE_EXT);
|
||||
final boolean nightMode = app.getDaynightHelper().isNightModeForMapControls();
|
||||
final int textPrimaryColor = nightMode ? R.color.text_color_primary_dark : R.color.text_color_primary_light;
|
||||
View mainView = UiUtilities.getInflater(ctx, nightMode).inflate(R.layout.fragment_on_save_current_track, container);
|
||||
|
@ -175,7 +176,7 @@ public class OnSaveCurrentTrackFragment extends BottomSheetDialogFragment {
|
|||
return null;
|
||||
}
|
||||
OsmandApplication app = (OsmandApplication) activity.getApplication();
|
||||
File savedFile = new File(app.getAppCustomization().getTracksDir(), new File(savedGpxDir, savedGpxName + ".gpx").getPath());
|
||||
File savedFile = new File(app.getAppCustomization().getTracksDir(), new File(savedGpxDir, savedGpxName + IndexConstants.GPX_FILE_EXT).getPath());
|
||||
if (savedGpxName.equalsIgnoreCase(newGpxName)) {
|
||||
return savedFile;
|
||||
}
|
||||
|
@ -183,7 +184,7 @@ public class OnSaveCurrentTrackFragment extends BottomSheetDialogFragment {
|
|||
Toast.makeText(app, R.string.empty_filename, Toast.LENGTH_LONG).show();
|
||||
return null;
|
||||
}
|
||||
return LocalIndexesFragment.renameGpxFile(app, savedFile, newGpxName + ".gpx", true, null);
|
||||
return LocalIndexesFragment.renameGpxFile(app, savedFile, newGpxName + IndexConstants.GPX_FILE_EXT, true, null);
|
||||
}
|
||||
|
||||
private void showOnMap(File f, boolean animated) {
|
||||
|
|
|
@ -978,7 +978,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
|
|||
String sub = gpxSubfolder.length() == 0 ? gpxFile.getName() : gpxSubfolder + "/"
|
||||
+ gpxFile.getName();
|
||||
loadGPXFolder(gpxFile, result, loadTask, progress, sub);
|
||||
} else if (gpxFile.isFile() && gpxFile.getName().toLowerCase().endsWith(".gpx")) {
|
||||
} else if (gpxFile.isFile() && gpxFile.getName().toLowerCase().endsWith(IndexConstants.GPX_FILE_EXT)) {
|
||||
GpxInfo info = new GpxInfo();
|
||||
info.subfolder = gpxSubfolder;
|
||||
info.file = gpxFile;
|
||||
|
@ -1233,7 +1233,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
|
|||
v.findViewById(R.id.group_divider).setVisibility(View.VISIBLE);
|
||||
|
||||
StringBuilder t = new StringBuilder();
|
||||
String groupName = group.replaceAll("_", " ").replace(".gpx", "");
|
||||
String groupName = group.replaceAll("_", " ").replace(IndexConstants.GPX_FILE_EXT, "");
|
||||
if (groupName.length() == 0) {
|
||||
groupName = getString(R.string.shared_string_tracks);
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ import net.osmand.Collator;
|
|||
import net.osmand.GPXUtilities;
|
||||
import net.osmand.GPXUtilities.GPXFile;
|
||||
import net.osmand.GPXUtilities.WptPt;
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.OsmAndCollator;
|
||||
import net.osmand.data.FavouritePoint;
|
||||
import net.osmand.data.LatLon;
|
||||
|
@ -1269,7 +1270,7 @@ public class TrackPointFragment extends OsmandExpandableListFragment implements
|
|||
dir.mkdir();
|
||||
}
|
||||
for (final String f : files.keySet()) {
|
||||
File fout = new File(dir, f + ".gpx");
|
||||
File fout = new File(dir, f + IndexConstants.GPX_FILE_EXT);
|
||||
GPXUtilities.writeGpxFile(fout, gpx);
|
||||
}
|
||||
return shouldClearPath;
|
||||
|
|
|
@ -34,6 +34,7 @@ import net.osmand.AndroidUtils;
|
|||
import net.osmand.GPXUtilities;
|
||||
import net.osmand.GPXUtilities.GPXFile;
|
||||
import net.osmand.GPXUtilities.WptPt;
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.data.PointDescription;
|
||||
import net.osmand.osm.edit.Entity;
|
||||
import net.osmand.osm.edit.Node;
|
||||
|
@ -800,7 +801,7 @@ public class OsmEditsFragment extends OsmAndListFragment implements SendPoiDialo
|
|||
} else {
|
||||
sb.append("osm_modification");
|
||||
}
|
||||
sb.append(oscFile ? ".osc" : ".gpx");
|
||||
sb.append(oscFile ? ".osc" : IndexConstants.GPX_FILE_EXT);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
|
|
@ -193,7 +193,7 @@ public class DataStorageHelper {
|
|||
|
||||
tracksMemory = DataStorageMemoryItem.builder()
|
||||
.setKey(TRACKS_MEMORY)
|
||||
// .setExtensions(".gpx", ".gpx.bz2")
|
||||
// .setExtensions(IndexConstants.GPX_FILE_EXT, ".gpx.bz2")
|
||||
.setDirectories(
|
||||
new Directory(app.getAppPath(IndexConstants.GPX_INDEX_DIR).getAbsolutePath(), true, EXTENSIONS, false))
|
||||
.createItem();
|
||||
|
|
|
@ -633,7 +633,8 @@ public class TravelDbHelper {
|
|||
}
|
||||
|
||||
public String getGPXName(TravelArticle article) {
|
||||
return article.getTitle().replace('/', '_').replace('\'', '_').replace('\"', '_') + ".gpx";
|
||||
return article.getTitle().replace('/', '_').replace('\'', '_')
|
||||
.replace('\"', '_') + IndexConstants.GPX_FILE_EXT;
|
||||
}
|
||||
|
||||
public File createGpxFile(TravelArticle article) {
|
||||
|
|
Loading…
Reference in a new issue