From 9331442a2934d899f270722c6caf3a9985bf3e06 Mon Sep 17 00:00:00 2001 From: veliymolfar Date: Thu, 12 Mar 2020 18:59:53 +0200 Subject: [PATCH] Add slope data to Downloads / slopes visualization --- OsmAnd/res/layout/fragment_terrain.xml | 31 +-- OsmAnd/res/values/strings.xml | 1 + .../plus/download/DownloadActivityType.java | 18 +- .../net/osmand/plus/download/IndexItem.java | 6 +- .../plus/download/ui/ItemViewHolder.java | 12 +- .../helpers/FileNameTranslationHelper.java | 12 +- .../controllers/MapDataMenuController.java | 6 +- .../osmand/plus/srtmplugin/SRTMPlugin.java | 70 +++---- .../plus/srtmplugin/TerrainFragment.java | 185 ++++++++++++++++-- ...{HillshadeLayer.java => TerrainLayer.java} | 41 ++-- 10 files changed, 293 insertions(+), 89 deletions(-) rename OsmAnd/src/net/osmand/plus/srtmplugin/{HillshadeLayer.java => TerrainLayer.java} (85%) diff --git a/OsmAnd/res/layout/fragment_terrain.xml b/OsmAnd/res/layout/fragment_terrain.xml index c53bb69604..d3986d4125 100644 --- a/OsmAnd/res/layout/fragment_terrain.xml +++ b/OsmAnd/res/layout/fragment_terrain.xml @@ -325,9 +325,12 @@ android:id="@+id/legend_bottom_divider" layout="@layout/card_bottom_divider" /> - + - + android:divider="@null" + android:fadeScrollbars="true" /> - - - + + + \ No newline at end of file diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 06d7b04741..1cdb6874c5 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -11,6 +11,7 @@ Thx - Hardy --> + Slopes Are you sure you want to clear recorded data? All profile settings will be restored to their original state after creating/importing this profile. Restore all profile settings? diff --git a/OsmAnd/src/net/osmand/plus/download/DownloadActivityType.java b/OsmAnd/src/net/osmand/plus/download/DownloadActivityType.java index e8fbe08c66..ee68eba279 100644 --- a/OsmAnd/src/net/osmand/plus/download/DownloadActivityType.java +++ b/OsmAnd/src/net/osmand/plus/download/DownloadActivityType.java @@ -43,6 +43,8 @@ public class DownloadActivityType { new DownloadActivityType(R.string.download_regular_maps, "depth", 45); public static final DownloadActivityType HILLSHADE_FILE = new DownloadActivityType(R.string.download_hillshade_maps, R.drawable.ic_action_hillshade_dark, "hillshade", 50); + public static final DownloadActivityType SLOPE_FILE = + new DownloadActivityType(R.string.download_slope_maps, R.drawable.ic_action_hillshade_dark, "slope", 55); public static final DownloadActivityType WIKIPEDIA_FILE = new DownloadActivityType(R.string.download_wikipedia_maps, R.drawable.ic_plugin_wikipedia, "wikimap", 60); public static final DownloadActivityType WIKIVOYAGE_FILE = @@ -130,6 +132,8 @@ public class DownloadActivityType { IndexConstants.BINARY_MAP_VERSION)); } else if (HILLSHADE_FILE == this) { return fileName.endsWith(IndexConstants.SQLITE_EXT); + } else if (SLOPE_FILE == this) { + 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)); } @@ -158,6 +162,8 @@ public class DownloadActivityType { return ctx.getAppPath(IndexConstants.LIVE_INDEX_DIR); } else if (HILLSHADE_FILE == this) { return ctx.getAppPath(IndexConstants.TILES_INDEX_DIR); + } else if (SLOPE_FILE == this) { + return ctx.getAppPath(IndexConstants.TILES_INDEX_DIR); } else if (DEPTH_CONTOUR_FILE == this) { return ctx.getAppPath(IndexConstants.MAPS_PATH); } @@ -165,7 +171,7 @@ public class DownloadActivityType { } public boolean isZipStream(OsmandApplication ctx, IndexItem indexItem) { - return HILLSHADE_FILE != this && WIKIVOYAGE_FILE != this; + return HILLSHADE_FILE != this && SLOPE_FILE != this && WIKIVOYAGE_FILE != this; } public boolean isZipFolder(OsmandApplication ctx, IndexItem indexItem) { @@ -205,6 +211,8 @@ public class DownloadActivityType { return BINARY_MAP_INDEX_EXT; } else if (HILLSHADE_FILE == this) { return IndexConstants.SQLITE_EXT; + } else if (SLOPE_FILE == this) { + return IndexConstants.SQLITE_EXT; } else if (DEPTH_CONTOUR_FILE == this) { return BINARY_MAP_INDEX_EXT; } @@ -224,6 +232,8 @@ public class DownloadActivityType { return "&wikivoyage=yes"; } else if (this == HILLSHADE_FILE) { return "&hillshade=yes"; + } else if (this == SLOPE_FILE) { + return "&slope=yes"; } else if (this == FONT_FILE) { return "&fonts=yes"; } else if (this == DEPTH_CONTOUR_FILE) { @@ -358,6 +368,8 @@ public class DownloadActivityType { return fileName.substring(0, l) + IndexConstants.FONT_INDEX_EXT; } else if (this == HILLSHADE_FILE) { return fileName.replace('_', ' '); + } else if (this == SLOPE_FILE) { + return fileName.replace('_', ' '); } else if (this == LIVE_UPDATES_FILE) { int l = fileName.lastIndexOf('.'); if (l == -1) { @@ -405,6 +417,10 @@ public class DownloadActivityType { return fileName.substring(0, fileName.length() - IndexConstants.SQLITE_EXT.length()) .replace(FileNameTranslationHelper.HILL_SHADE, ""); } + if (this == SLOPE_FILE) { + return fileName.substring(0, fileName.length() - IndexConstants.SQLITE_EXT.length()) + .replace(FileNameTranslationHelper.SLOPE, ""); + } if (fileName.endsWith(IndexConstants.SQLITE_EXT)) { return fileName.substring(0, fileName.length() - IndexConstants.SQLITE_EXT.length()); } diff --git a/OsmAnd/src/net/osmand/plus/download/IndexItem.java b/OsmAnd/src/net/osmand/plus/download/IndexItem.java index 9f55404079..48c966832c 100644 --- a/OsmAnd/src/net/osmand/plus/download/IndexItem.java +++ b/OsmAnd/src/net/osmand/plus/download/IndexItem.java @@ -140,6 +140,8 @@ public class IndexItem implements Comparable { 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(); } @@ -181,7 +183,9 @@ public class IndexItem implements Comparable { } public boolean isOutdated() { - return outdated && getType() != DownloadActivityType.HILLSHADE_FILE ; + return outdated + && getType() != DownloadActivityType.HILLSHADE_FILE + && getType() != DownloadActivityType.SLOPE_FILE; } public void setOutdated(boolean outdated) { diff --git a/OsmAnd/src/net/osmand/plus/download/ui/ItemViewHolder.java b/OsmAnd/src/net/osmand/plus/download/ui/ItemViewHolder.java index 9d8dd0510d..0190cfb5e7 100644 --- a/OsmAnd/src/net/osmand/plus/download/ui/ItemViewHolder.java +++ b/OsmAnd/src/net/osmand/plus/download/ui/ItemViewHolder.java @@ -181,8 +181,9 @@ public class ItemViewHolder { descrTextView.setVisibility(View.VISIBLE); if (indexItem.getType() == DownloadActivityType.DEPTH_CONTOUR_FILE && !depthContoursPurchased) { descrTextView.setText(context.getString(R.string.depth_contour_descr)); - } else if ((indexItem.getType() == DownloadActivityType.SRTM_COUNTRY_FILE || - indexItem.getType() == DownloadActivityType.HILLSHADE_FILE) && srtmDisabled) { + } else if ((indexItem.getType() == DownloadActivityType.SRTM_COUNTRY_FILE + || indexItem.getType() == DownloadActivityType.HILLSHADE_FILE + || indexItem.getType() == DownloadActivityType.SLOPE_FILE) && srtmDisabled) { if(showTypeInName) { descrTextView.setText(""); } else { @@ -307,8 +308,9 @@ public class ItemViewHolder { if (indexItem.getBasename().toLowerCase().equals(DownloadResources.WORLD_SEAMARKS_KEY) && nauticalPluginDisabled) { clickAction = RightButtonAction.ASK_FOR_SEAMARKS_PLUGIN; - } else if ((indexItem.getType() == DownloadActivityType.SRTM_COUNTRY_FILE || - indexItem.getType() == DownloadActivityType.HILLSHADE_FILE) && srtmDisabled) { + } else if ((indexItem.getType() == DownloadActivityType.SRTM_COUNTRY_FILE + || indexItem.getType() == DownloadActivityType.HILLSHADE_FILE + || indexItem.getType() == DownloadActivityType.SLOPE_FILE) && srtmDisabled) { if (srtmNeedsInstallation) { clickAction = RightButtonAction.ASK_FOR_SRTM_PLUGIN_PURCHASE; } else { @@ -392,6 +394,8 @@ public class ItemViewHolder { LocalIndexType tp = LocalIndexType.MAP_DATA; if (indexItem.getType() == DownloadActivityType.HILLSHADE_FILE) { tp = LocalIndexType.TILES_DATA; + } else if (indexItem.getType() == DownloadActivityType.SLOPE_FILE) { + tp = LocalIndexType.TILES_DATA; } else if (indexItem.getType() == DownloadActivityType.ROADS_FILE) { tp = LocalIndexType.MAP_DATA; } else if (indexItem.getType() == DownloadActivityType.SRTM_COUNTRY_FILE) { diff --git a/OsmAnd/src/net/osmand/plus/helpers/FileNameTranslationHelper.java b/OsmAnd/src/net/osmand/plus/helpers/FileNameTranslationHelper.java index 30d7b2a730..775b412eac 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/FileNameTranslationHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/FileNameTranslationHelper.java @@ -19,6 +19,7 @@ public class FileNameTranslationHelper { private static final Log LOG = PlatformUtil.getLog(FileNameTranslationHelper.class); public static final String WIKI_NAME = "_wiki"; public static final String HILL_SHADE = "Hillshade_"; + public static final String SLOPE = "Slope_"; public static final String SEA_DEPTH = "Depth_"; public static String getFileName(Context ctx, OsmandRegions regions, String fileName) { @@ -30,7 +31,9 @@ public class FileNameTranslationHelper { } else if (fileName.endsWith(IndexConstants.FONT_INDEX_EXT)) { //otf files return getFontName(ctx, basename); } else if (fileName.startsWith(HILL_SHADE)){ - return getHillShadeName(ctx, regions, basename); + return getTerrainName(ctx, regions, basename, R.string.download_hillshade_maps); + } else if (fileName.startsWith(SLOPE)) { + return getTerrainName(ctx, regions, basename, R.string.download_slope_maps); } else if (fileName.length() == 2) { //voice recorded files try { Field f = R.string.class.getField("lang_"+fileName); @@ -57,10 +60,11 @@ public class FileNameTranslationHelper { return null; } - public static String getHillShadeName(Context ctx, OsmandRegions regions, String basename) { - String hillsh = ctx.getString(R.string.download_hillshade_maps) + " "; + public static String getTerrainName(Context ctx, OsmandRegions regions, String basename, + int terrainNameRes) { + String terrain = ctx.getString(terrainNameRes) + " "; String locName = regions.getLocaleName(basename.trim(), true); - return hillsh + locName; + return terrain + locName; } public static String getWikiName(Context ctx, String basename){ diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/MapDataMenuController.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/MapDataMenuController.java index ecae4fe7f1..8bde5fbe6d 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/MapDataMenuController.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/MapDataMenuController.java @@ -96,7 +96,8 @@ public class MapDataMenuController extends MenuController { restoreFromBackup(); } else if (indexItem != null && activity != null) { if ((indexItem.getType() == DownloadActivityType.SRTM_COUNTRY_FILE - || indexItem.getType() == DownloadActivityType.HILLSHADE_FILE) + || indexItem.getType() == DownloadActivityType.HILLSHADE_FILE + || indexItem.getType() == DownloadActivityType.SLOPE_FILE) && srtmDisabled) { activity.getContextMenu().close(); @@ -400,7 +401,8 @@ public class MapDataMenuController extends MenuController { leftDownloadButtonController.caption = mapActivity.getString(R.string.local_index_mi_restore); } else if (indexItem != null) { if ((indexItem.getType() == DownloadActivityType.SRTM_COUNTRY_FILE - || indexItem.getType() == DownloadActivityType.HILLSHADE_FILE) + || indexItem.getType() == DownloadActivityType.HILLSHADE_FILE + || indexItem.getType() == DownloadActivityType.SLOPE_FILE) && srtmDisabled) { leftDownloadButtonController.caption = mapActivity.getString(R.string.get_plugin); leftDownloadButtonController.clearIcon(true); diff --git a/OsmAnd/src/net/osmand/plus/srtmplugin/SRTMPlugin.java b/OsmAnd/src/net/osmand/plus/srtmplugin/SRTMPlugin.java index ea23d9b10b..84b055f5cd 100644 --- a/OsmAnd/src/net/osmand/plus/srtmplugin/SRTMPlugin.java +++ b/OsmAnd/src/net/osmand/plus/srtmplugin/SRTMPlugin.java @@ -63,7 +63,7 @@ public class SRTMPlugin extends OsmandPlugin { private OsmandSettings settings; private boolean paid; - private HillshadeLayer hillshadeLayer; + private TerrainLayer terrainLayer; @Override public String getId() { @@ -146,12 +146,12 @@ public class SRTMPlugin extends OsmandPlugin { @Override public void registerLayers(MapActivity activity) { - if (hillshadeLayer != null) { - activity.getMapView().removeLayer(hillshadeLayer); + if (terrainLayer != null) { + activity.getMapView().removeLayer(terrainLayer); } - if (settings.HILLSHADE.get()) { - hillshadeLayer = new HillshadeLayer(activity, this); - activity.getMapView().addLayer(hillshadeLayer, 0.6f); + if (settings.TERRAIN.get()) { + terrainLayer = new TerrainLayer(activity, this); + activity.getMapView().addLayer(terrainLayer, 0.6f); } } @@ -213,6 +213,10 @@ public class SRTMPlugin extends OsmandPlugin { return settings.HILLSHADE_TRANSPARENCY.get(); } + public int getSlopeTransparency() { + return settings.SLOPE_TRANSPARENCY.get(); + } + public int getHillshadeMinZoom(){ return settings.HILLSHADE_MIN_ZOOM.get(); } @@ -258,16 +262,19 @@ public class SRTMPlugin extends OsmandPlugin { @Override public void updateLayers(OsmandMapTileView mapView, MapActivity activity) { - if (settings.HILLSHADE.get() && isActive()) { - if (hillshadeLayer == null) { - registerLayers(activity); - } + if (settings.TERRAIN.get() && isActive()) { + removeTerrainLayer(mapView, activity); + registerLayers(activity); } else { - if (hillshadeLayer != null) { - mapView.removeLayer(hillshadeLayer); - hillshadeLayer = null; - activity.refreshMap(); - } + removeTerrainLayer(mapView, activity); + } + } + + private void removeTerrainLayer(OsmandMapTileView mapView, MapActivity activity) { + if (terrainLayer != null) { + mapView.removeLayer(terrainLayer); + terrainLayer = null; + activity.refreshMap(); } } @@ -281,9 +288,6 @@ public class SRTMPlugin extends OsmandPlugin { if (itemId == R.string.srtm_plugin_name) { mapActivity.getDashboard().setDashboardVisibility(true, DashboardOnMap.DashboardType.CONTOUR_LINES, viewCoordinates); return false; - } else if (itemId == R.string.layer_hillshade) { - mapActivity.getDashboard().setDashboardVisibility(true, DashboardOnMap.DashboardType.HILLSHADE, viewCoordinates); - return false; } else if (itemId == R.string.shared_string_terrain) { mapActivity.getDashboard().setDashboardVisibility(true, DashboardOnMap.DashboardType.TERRAIN, viewCoordinates); return false; @@ -324,16 +328,15 @@ public class SRTMPlugin extends OsmandPlugin { } }); - } else if (itemId == R.string.layer_hillshade) { - toggleHillshade(mapActivity, isChecked, new Runnable() { + } else if (itemId == R.string.shared_string_terrain) { + toggleTerrain(mapActivity, isChecked, new Runnable() { @Override public void run() { - boolean selected = settings.HILLSHADE.get(); + boolean selected = settings.TERRAIN.get(); SRTMPlugin plugin = OsmandPlugin.getPlugin(SRTMPlugin.class); if (selected && plugin != null && !plugin.isActive() && !plugin.needsInstallation()) { OsmandPlugin.enablePlugin(mapActivity, mapActivity.getMyApplication(), plugin, true); } - ContextMenuItem item = adapter.getItem(position); if (item != null) { item.setColorRes(selected ? R.color.osmand_orange : ContextMenuItem.INVALID_ID); @@ -365,17 +368,6 @@ public class SRTMPlugin extends OsmandPlugin { .setPosition(12) .setListener(listener).createItem()); } - boolean hillshadeEnabled = settings.HILLSHADE.get(); - adapter.addItem(new ContextMenuItem.ItemBuilder() - .setId(HILLSHADE_LAYER) - .setTitleId(R.string.layer_hillshade, mapActivity) - .setSelected(hillshadeEnabled) - .setColor(hillshadeEnabled ? R.color.osmand_orange : ContextMenuItem.INVALID_ID) - .setIcon(R.drawable.ic_action_hillshade_dark) - .setSecondaryIcon(R.drawable.ic_action_additional_option) - .setListener(listener) - .setPosition(13) - .createItem()); boolean terrainEnabled = settings.TERRAIN.get(); adapter.addItem(new ContextMenuItem.ItemBuilder() .setId(TERRAIN) @@ -385,7 +377,7 @@ public class SRTMPlugin extends OsmandPlugin { .setIcon(R.drawable.ic_action_hillshade_dark) .setSecondaryIcon(R.drawable.ic_action_additional_option) .setListener(listener) - .setPosition(14) + .setPosition(13) .createItem() ); } @@ -407,6 +399,7 @@ public class SRTMPlugin extends OsmandPlugin { LatLon latLon = app.getMapViewTrackingUtilities().getMapLocation(); suggestedMaps.addAll(getMapsForType(latLon, DownloadActivityType.SRTM_COUNTRY_FILE)); suggestedMaps.addAll(getMapsForType(latLon, DownloadActivityType.HILLSHADE_FILE)); + suggestedMaps.addAll(getMapsForType(latLon, DownloadActivityType.SLOPE_FILE)); } return suggestedMaps; @@ -454,6 +447,15 @@ public class SRTMPlugin extends OsmandPlugin { } } + public void toggleTerrain(final MapActivity activity, + final boolean isChecked, + final Runnable callback) { + settings.TERRAIN.set(isChecked); + if (callback != null) { + callback.run(); + } + } + public String getPrefDescription(final Context ctx, final RenderingRuleProperty p, final OsmandSettings.CommonPreference pref) { if (!Algorithms.isEmpty(pref.get())) { return SettingsActivity.getStringPropertyValue(ctx, pref.get()); diff --git a/OsmAnd/src/net/osmand/plus/srtmplugin/TerrainFragment.java b/OsmAnd/src/net/osmand/plus/srtmplugin/TerrainFragment.java index 9e1464cedb..d01338bbba 100644 --- a/OsmAnd/src/net/osmand/plus/srtmplugin/TerrainFragment.java +++ b/OsmAnd/src/net/osmand/plus/srtmplugin/TerrainFragment.java @@ -1,5 +1,6 @@ package net.osmand.plus.srtmplugin; +import android.app.Activity; import android.content.Intent; import android.content.res.ColorStateList; import android.net.Uri; @@ -11,6 +12,8 @@ import android.text.style.ClickableSpan; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; @@ -21,9 +24,12 @@ import androidx.annotation.Nullable; import androidx.appcompat.widget.SwitchCompat; import androidx.core.content.ContextCompat; +import com.github.ksoichiro.android.observablescrollview.ObservableListView; import com.google.android.material.slider.Slider; import net.osmand.PlatformUtil; +import net.osmand.plus.ContextMenuAdapter; +import net.osmand.plus.ContextMenuItem; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; import net.osmand.plus.OsmandSettings; @@ -32,12 +38,22 @@ import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.base.BaseOsmAndFragment; +import net.osmand.plus.download.DownloadIndexesThread; +import net.osmand.plus.download.DownloadResources; +import net.osmand.plus.download.DownloadValidationManager; +import net.osmand.plus.download.IndexItem; import net.osmand.plus.inapp.InAppPurchaseHelper; import org.apache.commons.logging.Log; +import java.io.IOException; import java.util.List; +import static net.osmand.plus.OsmandSettings.TerrainMode.HILLSHADE; +import static net.osmand.plus.OsmandSettings.TerrainMode.SLOPE; +import static net.osmand.plus.download.DownloadActivityType.HILLSHADE_FILE; +import static net.osmand.plus.download.DownloadActivityType.SLOPE_FILE; + public class TerrainFragment extends BaseOsmAndFragment implements View.OnClickListener, Slider.OnSliderTouchListener, Slider.OnChangeListener { @@ -59,16 +75,13 @@ public class TerrainFragment extends BaseOsmAndFragment implements View.OnClickL private ColorStateList colorProfileStateList; private ColorStateList colorProfileInactiveStateList; - private TextView emptyStateDescriptionTv; private TextView downloadDescriptionTv; private TextView transparencyValueTv; - private TextView slopeReadMoreTv; private TextView descriptionTv; private TextView hillshadeBtn; private TextView minZoomTv; private TextView maxZoomTv; private TextView slopeBtn; - private TextView titleTv; private TextView stateTv; private FrameLayout hillshadeBtnContainer; private FrameLayout slopeBtnContainer; @@ -81,8 +94,12 @@ public class TerrainFragment extends BaseOsmAndFragment implements View.OnClickL private View legendBottomDivider; private View titleBottomDivider; private View legendTopDivider; + private View downloadTopDivider; + private View downloadBottomDivider; private Slider transparencySlider; private Slider zoomSlider; + private ObservableListView observableListView; + public TerrainFragment() { @@ -110,20 +127,20 @@ public class TerrainFragment extends BaseOsmAndFragment implements View.OnClickL public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { inflater = UiUtilities.getInflater(app, nightMode); View root = inflater.inflate(R.layout.fragment_terrain, container, false); - emptyStateDescriptionTv = root.findViewById(R.id.empty_state_description); + TextView emptyStateDescriptionTv = root.findViewById(R.id.empty_state_description); + TextView slopeReadMoreTv = root.findViewById(R.id.slope_read_more_tv); + TextView titleTv = root.findViewById(R.id.title_tv); downloadDescriptionTv = root.findViewById(R.id.download_description_tv); transparencyValueTv = root.findViewById(R.id.transparency_value_tv); legendBottomDivider = root.findViewById(R.id.legend_bottom_divider); transparencySlider = root.findViewById(R.id.transparency_slider); titleBottomDivider = root.findViewById(R.id.titleBottomDivider); legendTopDivider = root.findViewById(R.id.legend_top_divider); - slopeReadMoreTv = root.findViewById(R.id.slope_read_more_tv); contentContainer = root.findViewById(R.id.content_container); legendContainer = root.findViewById(R.id.legend_container); switchCompat = root.findViewById(R.id.switch_compat); descriptionTv = root.findViewById(R.id.description); emptyState = root.findViewById(R.id.empty_state); - titleTv = root.findViewById(R.id.title_tv); stateTv = root.findViewById(R.id.state_tv); iconIv = root.findViewById(R.id.icon_iv); slopeBtn = root.findViewById(R.id.slope_btn); @@ -134,6 +151,9 @@ public class TerrainFragment extends BaseOsmAndFragment implements View.OnClickL slopeBtnContainer = root.findViewById(R.id.slope_btn_container); downloadContainer = root.findViewById(R.id.download_container); hillshadeBtnContainer = root.findViewById(R.id.hillshade_btn_container); + downloadTopDivider = root.findViewById(R.id.download_container_top_divider); + downloadBottomDivider = root.findViewById(R.id.download_container_bottom_divider); + observableListView = (ObservableListView) root.findViewById(R.id.list_view); titleTv.setText(R.string.shared_string_terrain); String wikiString = getString(R.string.shared_string_wikipedia); @@ -186,10 +206,10 @@ public class TerrainFragment extends BaseOsmAndFragment implements View.OnClickL onSwitchClick(); break; case R.id.hillshade_btn: - setupTerrainMode(TerrainMode.HILLSHADE); + setupTerrainMode(HILLSHADE); break; case R.id.slope_btn: - setupTerrainMode(TerrainMode.SLOPE); + setupTerrainMode(SLOPE); break; default: break; @@ -212,8 +232,7 @@ public class TerrainFragment extends BaseOsmAndFragment implements View.OnClickL srtmPlugin.setZoomValues(values.get(0).intValue(), values.get(1).intValue()); break; } - MapActivity mapActivity = (MapActivity) getActivity(); - srtmPlugin.updateLayers(mapActivity.getMapView(), mapActivity); + updateLayers(); } @Override @@ -251,14 +270,13 @@ public class TerrainFragment extends BaseOsmAndFragment implements View.OnClickL case HILLSHADE: descriptionTv.setText(R.string.hillshade_description); downloadDescriptionTv.setText(R.string.hillshade_download_description); -// zoomSlider.setValueFrom(); -// zoomSlider.setValueTo(); break; case SLOPE: descriptionTv.setText(R.string.slope_description); downloadDescriptionTv.setText(R.string.slope_download_description); break; } + updateDownloadSection(); } else { iconIv.setImageDrawable(uiUtilities.getIcon( R.drawable.ic_action_hillshade_dark, @@ -279,14 +297,14 @@ public class TerrainFragment extends BaseOsmAndFragment implements View.OnClickL } private void adjustLegendVisibility(TerrainMode mode) { - int visibility = TerrainMode.SLOPE.equals(mode) ? View.VISIBLE : View.GONE; + int visibility = SLOPE.equals(mode) ? View.VISIBLE : View.GONE; legendContainer.setVisibility(visibility); legendBottomDivider.setVisibility(visibility); legendTopDivider.setVisibility(visibility); } private void adjustModeButtons(TerrainMode mode) { - if (TerrainMode.SLOPE.equals(mode)) { + if (SLOPE.equals(mode)) { slopeBtnContainer.setBackgroundResource(R.drawable.btn_border_right_active); slopeBtn.setTextColor(nightMode ? getResources().getColor(R.color.text_color_primary_dark) @@ -338,13 +356,152 @@ public class TerrainFragment extends BaseOsmAndFragment implements View.OnClickL switchCompat.setChecked(terrainEnabled); srtmPlugin.setTerrainLayerEnabled(terrainEnabled); updateUiMode(); + updateLayers(); } + private void setupTerrainMode(TerrainMode mode) { TerrainMode currentMode = srtmPlugin.getTerrainMode(); if (!currentMode.equals(mode)) { srtmPlugin.setTerrainMode(mode); updateUiMode(); + updateLayers(); } } + + private void updateLayers() { + Activity activity = getActivity(); + if (activity instanceof MapActivity) { + srtmPlugin.updateLayers( + ((MapActivity) activity).getMapView(), + (MapActivity) activity + ); + } + } + + private void updateDownloadSection() { + final ContextMenuAdapter adapter = new ContextMenuAdapter(); + adapter.setDefaultLayoutId(R.layout.list_item_icon_and_menu); + adapter.setProfileDependent(true); + adapter.setNightMode(nightMode); + + final MapActivity mapActivity = (MapActivity) getActivity(); + + final DownloadIndexesThread downloadThread = app.getDownloadThread(); + if (!downloadThread.getIndexes().isDownloadedFromInternet) { + if (settings.isInternetConnectionAvailable()) { + downloadThread.runReloadIndexFiles(); + } + } + final boolean downloadIndexes = settings.isInternetConnectionAvailable() + && !downloadThread.getIndexes().isDownloadedFromInternet + && !downloadThread.getIndexes().downloadFromInternetFailed; + + if (downloadIndexes) { + adapter.addItem(new ContextMenuItem.ItemBuilder() + .setLayout(R.layout.list_item_icon_and_download) + .setTitleId(R.string.downloading_list_indexes, mapActivity) + .setLoading(true) + .createItem()); + } else { + try { + TerrainMode mode = srtmPlugin.getTerrainMode(); + IndexItem currentDownloadingItem = downloadThread.getCurrentDownloadingItem(); + int currentDownloadingProgress = downloadThread.getCurrentDownloadingItemProgress(); + List hillshadeItems = DownloadResources.findIndexItemsAt( + app, mapActivity.getMapLocation(), + mode.equals(HILLSHADE) + ? HILLSHADE_FILE + : SLOPE_FILE); + if (hillshadeItems.size() > 0) { + downloadContainer.setVisibility(View.VISIBLE); + downloadTopDivider.setVisibility(View.VISIBLE); + downloadBottomDivider.setVisibility(View.VISIBLE); + for (final IndexItem indexItem : hillshadeItems) { + ContextMenuItem.ItemBuilder itemBuilder = new ContextMenuItem.ItemBuilder() + .setLayout(R.layout.list_item_icon_and_download) + .setTitle(indexItem.getVisibleName(app, app.getRegions(), false)) + .setDescription(mode.equals(HILLSHADE) + ? HILLSHADE_FILE.getString(app) + " • " + indexItem.getSizeDescription(app) + : SLOPE_FILE.getString(app) + " • " + indexItem.getSizeDescription(app)) + .setIcon(mode.equals(HILLSHADE) + ? HILLSHADE_FILE.getIconResource() + : SLOPE_FILE.getIconResource()) + .setListener(new ContextMenuAdapter.ItemClickListener() { + @Override + public boolean onContextMenuClick(ArrayAdapter adapter, int itemId, int position, boolean isChecked, int[] viewCoordinates) { + ContextMenuItem item = adapter.getItem(position); + if (downloadThread.isDownloading(indexItem)) { + downloadThread.cancelDownload(indexItem); + if (item != null) { + item.setProgress(ContextMenuItem.INVALID_ID); + item.setLoading(false); + item.setSecondaryIcon(R.drawable.ic_action_import); + adapter.notifyDataSetChanged(); + } + } else { + new DownloadValidationManager(app).startDownload(mapActivity, indexItem); + if (item != null) { + item.setProgress(ContextMenuItem.INVALID_ID); + item.setLoading(true); + item.setSecondaryIcon(R.drawable.ic_action_remove_dark); + adapter.notifyDataSetChanged(); + } + } + return false; + } + }) + .setProgressListener(new ContextMenuAdapter.ProgressListener() { + @Override + public boolean onProgressChanged(Object progressObject, int progress, + ArrayAdapter adapter, + int itemId, int position) { + if (progressObject instanceof IndexItem) { + IndexItem progressItem = (IndexItem) progressObject; + if (indexItem.compareTo(progressItem) == 0) { + ContextMenuItem item = adapter.getItem(position); + if (item != null) { + item.setProgress(progress); + item.setLoading(true); + item.setSecondaryIcon(R.drawable.ic_action_remove_dark); + adapter.notifyDataSetChanged(); + } + return true; + } + } + return false; + } + }); + + if (indexItem == currentDownloadingItem) { + itemBuilder.setLoading(true) + .setProgress(currentDownloadingProgress) + .setSecondaryIcon(R.drawable.ic_action_remove_dark); + } else { + itemBuilder.setSecondaryIcon(R.drawable.ic_action_import); + } + adapter.addItem(itemBuilder.createItem()); + } + } else { + downloadContainer.setVisibility(View.GONE); + downloadTopDivider.setVisibility(View.GONE); + downloadBottomDivider.setVisibility(View.GONE); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + final ArrayAdapter listAdapter = adapter.createListAdapter(mapActivity, !nightMode); + observableListView.setAdapter(listAdapter); + observableListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + ContextMenuItem item = adapter.getItem(position); + ContextMenuAdapter.ItemClickListener click = item.getItemClickListener(); + if (click != null) { + click.onContextMenuClick(listAdapter, item.getTitleId(), position, false, null); + } + } + }); + } } diff --git a/OsmAnd/src/net/osmand/plus/srtmplugin/HillshadeLayer.java b/OsmAnd/src/net/osmand/plus/srtmplugin/TerrainLayer.java similarity index 85% rename from OsmAnd/src/net/osmand/plus/srtmplugin/HillshadeLayer.java rename to OsmAnd/src/net/osmand/plus/srtmplugin/TerrainLayer.java index 122ba7eaed..67b6d18dd5 100644 --- a/OsmAnd/src/net/osmand/plus/srtmplugin/HillshadeLayer.java +++ b/OsmAnd/src/net/osmand/plus/srtmplugin/TerrainLayer.java @@ -14,14 +14,15 @@ import net.osmand.data.QuadTree; import net.osmand.data.RotatedTileBox; import net.osmand.map.TileSourceManager.TileSourceTemplate; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.OsmandSettings.TerrainMode; import net.osmand.plus.SQLiteTileSource; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.api.SQLiteAPI.SQLiteConnection; import net.osmand.plus.views.MapTileLayer; -import net.osmand.plus.views.OsmandMapLayer; import org.apache.commons.logging.Log; +import android.annotation.SuppressLint; import android.content.ContentValues; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; @@ -29,26 +30,31 @@ import android.graphics.Bitmap; import android.graphics.Canvas; import android.os.AsyncTask; -public class HillshadeLayer extends MapTileLayer { +import static net.osmand.plus.OsmandSettings.TerrainMode.HILLSHADE; - private final static Log log = PlatformUtil.getLog(HillshadeLayer.class); +public class TerrainLayer extends MapTileLayer { + + private final static Log log = PlatformUtil.getLog(TerrainLayer.class); private Map resources = new LinkedHashMap(); private final static String HILLSHADE_CACHE = "hillshade.cache"; + private final static String SLOPE_CACHE = "slope.cache"; private int ZOOM_BOUNDARY = 15; private final static int MAX_TRANSPARENCY_ZOOM = 17; private final static int DEFAULT_ALPHA = 100; private final static int MAX_TRANSPARENCY_ALPHA = 20; private SRTMPlugin srtmPlugin; + private TerrainMode mode; private QuadTree indexedResources = new QuadTree(new QuadRect(0, 0, 1 << (ZOOM_BOUNDARY+1), 1 << (ZOOM_BOUNDARY+1)), 8, 0.55f); - public HillshadeLayer(MapActivity activity, SRTMPlugin srtmPlugin) { + public TerrainLayer(MapActivity activity, SRTMPlugin srtmPlugin) { super(false); final OsmandApplication app = activity.getMyApplication(); - indexHillshadeFiles(app); + this.srtmPlugin = srtmPlugin; + mode = srtmPlugin.getTerrainMode(); + indexTerrainFiles(app); setAlpha(DEFAULT_ALPHA); setMap(createTileSource(activity)); - this.srtmPlugin = srtmPlugin; } @Override @@ -56,21 +62,25 @@ public class HillshadeLayer extends MapTileLayer { if (tileBox.getZoom() >= MAX_TRANSPARENCY_ZOOM) { setAlpha(MAX_TRANSPARENCY_ALPHA); } else { - setAlpha(srtmPlugin.getHillshadeTransparency()); + setAlpha(mode.equals(HILLSHADE) + ? srtmPlugin.getHillshadeTransparency() + : srtmPlugin.getSlopeTransparency()); } super.onPrepareBufferImage(canvas, tileBox, drawSettings); } - private void indexHillshadeFiles(final OsmandApplication app ) { - AsyncTask task = new AsyncTask () { + private void indexTerrainFiles(final OsmandApplication app) { + @SuppressLint("StaticFieldLeak") AsyncTask task = new AsyncTask() { private SQLiteDatabase sqliteDb; + private String type = mode.equals(HILLSHADE) ? "hillshade" : "slope"; @Override protected Void doInBackground(Void... params) { File tilesDir = app.getAppPath(IndexConstants.TILES_INDEX_DIR); File cacheDir = app.getCacheDir(); // fix http://stackoverflow.com/questions/26937152/workaround-for-nexus-9-sqlite-file-write-operations-on-external-dirs - sqliteDb = SQLiteDatabase.openDatabase(new File(cacheDir, HILLSHADE_CACHE).getPath() , + sqliteDb = SQLiteDatabase.openDatabase( + new File(cacheDir, mode.equals(HILLSHADE) ? HILLSHADE_CACHE : SLOPE_CACHE).getPath(), null, SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING | SQLiteDatabase.CREATE_IF_NECESSARY ); if(sqliteDb.getVersion() == 0) { @@ -95,7 +105,7 @@ public class HillshadeLayer extends MapTileLayer { private void indexNonCachedResources(Map fileModified, Map rs) { for(String filename : fileModified.keySet()) { try { - log.info("Indexing hillshade file " + filename); + log.info("Indexing" + type + "file " + filename); ContentValues cv = new ContentValues(); cv.put("filename", filename); cv.put("date_modified", fileModified.get(filename)); @@ -142,8 +152,9 @@ public class HillshadeLayer extends MapTileLayer { File[] files = tilesDir.listFiles(); if(files != null) { for(File f : files) { - if(f != null && f.getName().endsWith(IndexConstants.SQLITE_EXT) && - f.getName().toLowerCase().startsWith("hillshade")) { + if (f != null + && f.getName().endsWith(IndexConstants.SQLITE_EXT) + && f.getName().toLowerCase().startsWith(type)) { SQLiteTileSource ts = new SQLiteTileSource(app, f, new ArrayList()); rs.put(f.getName(), ts); fileModified.put(f.getName(), f.lastModified()); @@ -234,7 +245,7 @@ public class HillshadeLayer extends MapTileLayer { @Override public String getName() { - return "Hillshade"; + return mode.equals(HILLSHADE) ? "Hillshade" : "Slope"; } @Override @@ -243,6 +254,4 @@ public class HillshadeLayer extends MapTileLayer { } }; } - - }