diff --git a/OsmAnd-api/src/net/osmand/aidlapi/OsmAndCustomizationConstants.java b/OsmAnd-api/src/net/osmand/aidlapi/OsmAndCustomizationConstants.java
index a8c0aebb1e..50a5dfbb41 100644
--- a/OsmAnd-api/src/net/osmand/aidlapi/OsmAndCustomizationConstants.java
+++ b/OsmAnd-api/src/net/osmand/aidlapi/OsmAndCustomizationConstants.java
@@ -45,6 +45,7 @@ public interface OsmAndCustomizationConstants {
String UNDERLAY_MAP = SHOW_ITEMS_ID_SCHEME + "underlay_map";
String CONTOUR_LINES = SHOW_ITEMS_ID_SCHEME + "contour_lines";
String HILLSHADE_LAYER = SHOW_ITEMS_ID_SCHEME + "hillshade_layer";
+ String TERRAIN = SHOW_ITEMS_ID_SCHEME + "terrain";
String MAP_RENDERING_CATEGORY_ID = RENDERING_ITEMS_ID_SCHEME + "category";
String MAP_STYLE_ID = RENDERING_ITEMS_ID_SCHEME + "map_style";
diff --git a/OsmAnd/res/layout/fragment_terrain.xml b/OsmAnd/res/layout/fragment_terrain.xml
new file mode 100644
index 0000000000..8fb1ecc19d
--- /dev/null
+++ b/OsmAnd/res/layout/fragment_terrain.xml
@@ -0,0 +1,303 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml
index 77a52af947..7259b518af 100644
--- a/OsmAnd/res/values/strings.xml
+++ b/OsmAnd/res/values/strings.xml
@@ -11,6 +11,9 @@
Thx - Hardy
-->
+ Legend
+ Zoom levels
+ Transparency
You can read more about Slopes in %1$s.
Additional maps are needed to view Slopes on the map.
Additional maps are needed to view Hillshade on the map.
diff --git a/OsmAnd/src/net/osmand/plus/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/OsmandSettings.java
index 692bc82177..6e59f7dc5a 100644
--- a/OsmAnd/src/net/osmand/plus/OsmandSettings.java
+++ b/OsmAnd/src/net/osmand/plus/OsmandSettings.java
@@ -2096,6 +2096,10 @@ public class OsmandSettings {
public final CommonPreference HILLSHADE = new BooleanPreference("hillshade_layer", true).makeProfile();
+ public final CommonPreference TERRAIN = new BooleanPreference("terrain_layer", true).makeProfile();
+
+ public final CommonPreference TERRAIN_MODE = new EnumIntPreference<>("terrain_mode", TerrainMode.HILLSHADE, TerrainMode.values()).makeProfile();
+
public final CommonPreference CONTOUR_LINES_ZOOM = new StringPreference("contour_lines_zoom", null).makeProfile().cache();
// this value string is synchronized with settings_pref.xml preference name
@@ -3872,6 +3876,11 @@ public class OsmandSettings {
}
}
+ public enum TerrainMode {
+ HILLSHADE,
+ SLOPE
+ }
+
private OsmandPreference[] generalPrefs = new OsmandPreference[]{
EXTERNAL_INPUT_DEVICE,
CENTER_POSITION_ON_MAP,
diff --git a/OsmAnd/src/net/osmand/plus/dashboard/DashboardOnMap.java b/OsmAnd/src/net/osmand/plus/dashboard/DashboardOnMap.java
index 5b3d0d0b83..0da40c9b4b 100644
--- a/OsmAnd/src/net/osmand/plus/dashboard/DashboardOnMap.java
+++ b/OsmAnd/src/net/osmand/plus/dashboard/DashboardOnMap.java
@@ -79,6 +79,7 @@ import net.osmand.plus.routing.RoutingHelper;
import net.osmand.plus.srtmplugin.ContourLinesMenu;
import net.osmand.plus.srtmplugin.HillshadeMenu;
import net.osmand.plus.srtmplugin.SRTMPlugin;
+import net.osmand.plus.srtmplugin.TerrainFragment;
import net.osmand.plus.views.DownloadedRegionsLayer;
import net.osmand.plus.views.MapInfoLayer;
import net.osmand.plus.views.OsmandMapTileView;
@@ -173,7 +174,9 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, IRouteInfo
MAPILLARY,
CONTOUR_LINES,
HILLSHADE,
- OSM_NOTES
+ OSM_NOTES,
+ TERRAIN,
+ SLOPE
}
private Map actionButtons = new HashMap<>();
@@ -320,6 +323,8 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, IRouteInfo
tv.setText(R.string.layer_hillshade);
} else if (visibleType == DashboardType.OSM_NOTES) {
tv.setText(R.string.osm_notes);
+ } else if (visibleType == DashboardType.TERRAIN) {
+ tv.setText(R.string.shared_string_terrain);
}
ImageView edit = (ImageView) dashboardView.findViewById(R.id.toolbar_edit);
edit.setVisibility(View.GONE);
@@ -588,13 +593,19 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, IRouteInfo
updateDownloadBtn();
View listViewLayout = dashboardView.findViewById(R.id.dash_list_view_layout);
ScrollView scrollView = (ScrollView) dashboardView.findViewById(R.id.main_scroll);
- if (visibleType == DashboardType.DASHBOARD || visibleType == DashboardType.MAPILLARY) {
+ if (visibleType == DashboardType.DASHBOARD
+ || visibleType == DashboardType.MAPILLARY
+ || visibleType == DashboardType.TERRAIN) {
if (visibleType == DashboardType.DASHBOARD) {
addOrUpdateDashboardFragments();
- } else {
+ } else if (visibleType == DashboardType.MAPILLARY) {
mapActivity.getSupportFragmentManager().beginTransaction()
.replace(R.id.content, new MapillaryFiltersFragment(), MapillaryFiltersFragment.TAG)
.commit();
+ } else {
+ mapActivity.getSupportFragmentManager().beginTransaction()
+ .replace(R.id.content, new TerrainFragment(), TerrainFragment.TAG)
+ .commit();
}
scrollView.setVisibility(View.VISIBLE);
scrollView.scrollTo(0, 0);
diff --git a/OsmAnd/src/net/osmand/plus/srtmplugin/SRTMPlugin.java b/OsmAnd/src/net/osmand/plus/srtmplugin/SRTMPlugin.java
index b733d3e94f..31c329a74b 100644
--- a/OsmAnd/src/net/osmand/plus/srtmplugin/SRTMPlugin.java
+++ b/OsmAnd/src/net/osmand/plus/srtmplugin/SRTMPlugin.java
@@ -19,6 +19,7 @@ import net.osmand.plus.DialogListItemAdapter;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.OsmandSettings;
+import net.osmand.plus.OsmandSettings.TerrainMode;
import net.osmand.plus.OsmandSettings.CommonPreference;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
@@ -42,6 +43,7 @@ import java.util.List;
import static net.osmand.aidlapi.OsmAndCustomizationConstants.CONTOUR_LINES;
import static net.osmand.aidlapi.OsmAndCustomizationConstants.HILLSHADE_LAYER;
+import static net.osmand.aidlapi.OsmAndCustomizationConstants.TERRAIN;
public class SRTMPlugin extends OsmandPlugin {
@@ -156,6 +158,14 @@ public class SRTMPlugin extends OsmandPlugin {
return settings.HILLSHADE.get();
}
+ public boolean isTerrainLayerEnabled() {
+ return settings.TERRAIN.get();
+ }
+
+ public TerrainMode getTerrainMode() {
+ return settings.TERRAIN_MODE.get();
+ }
+
public static boolean isContourLinesLayerEnabled(OsmandApplication app) {
boolean contourLinesEnabled = false;
@@ -199,6 +209,9 @@ public class SRTMPlugin extends OsmandPlugin {
} 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;
}
return true;
}
@@ -288,6 +301,18 @@ public class SRTMPlugin extends OsmandPlugin {
.setListener(listener)
.setPosition(13)
.createItem());
+ boolean terrainEnabled = settings.TERRAIN.get();
+ adapter.addItem(new ContextMenuItem.ItemBuilder()
+ .setId(TERRAIN)
+ .setTitleId(R.string.shared_string_terrain, mapActivity)
+ .setSelected(terrainEnabled)
+ .setColor(terrainEnabled ? R.color.osmand_orange : ContextMenuItem.INVALID_ID)
+ .setIcon(R.drawable.ic_action_hillshade_dark)
+ .setSecondaryIcon(R.drawable.ic_action_additional_option)
+ .setListener(listener)
+ .setPosition(14)
+ .createItem()
+ );
}
@Override
diff --git a/OsmAnd/src/net/osmand/plus/srtmplugin/TerrainFragment.java b/OsmAnd/src/net/osmand/plus/srtmplugin/TerrainFragment.java
new file mode 100644
index 0000000000..8818b30431
--- /dev/null
+++ b/OsmAnd/src/net/osmand/plus/srtmplugin/TerrainFragment.java
@@ -0,0 +1,176 @@
+package net.osmand.plus.srtmplugin;
+
+import android.content.Intent;
+import android.graphics.Color;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v7.widget.AppCompatSeekBar;
+import android.support.v7.widget.SwitchCompat;
+import android.text.SpannableString;
+import android.text.Spanned;
+import android.text.method.LinkMovementMethod;
+import android.text.style.ClickableSpan;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import net.osmand.plus.OsmandApplication;
+import net.osmand.plus.OsmandPlugin;
+import net.osmand.plus.OsmandSettings;
+import net.osmand.plus.OsmandSettings.TerrainMode;
+import net.osmand.plus.R;
+import net.osmand.plus.UiUtilities;
+import net.osmand.plus.base.BaseOsmAndFragment;
+import net.osmand.plus.inapp.InAppPurchaseHelper;
+import net.osmand.plus.widgets.TextViewEx;
+
+public class TerrainFragment extends BaseOsmAndFragment {
+
+ public static final String TAG = TerrainFragment.class.getSimpleName();
+
+ private static final String SLOPES_WIKI_URL = "";
+ private static final String PLUGIN_URL = "";
+
+ private OsmandApplication app;
+ private UiUtilities uiUtilities;
+ private OsmandSettings settings;
+ private SRTMPlugin srtmPlugin;
+ private boolean nightMode;
+ private boolean srtmEnabled;
+ private boolean terrainEnabled;
+
+ private int colorProfile;
+
+ private TextView downloadDescriptionTv;
+ private TextView emptyStateDescriptionTv;
+ private TextView transparencyValueTv;
+ private TextView slopeReadMoreTv;
+ private TextView descriptionTv;
+ private TextView titleTv;
+ private TextView stateTv;
+ private SwitchCompat switchCompat;
+ private ImageView iconIv;
+ private LinearLayout legendContainer;
+ private LinearLayout emptyState;
+ private LinearLayout contentContainer;
+ private View legendTopDivider;
+ private View legendBottomDivider;
+ private View titleBottomDivider;
+ private AppCompatSeekBar transparencySlider;
+
+ public TerrainFragment() {
+
+ }
+
+ @Override
+ public void onCreate(@Nullable Bundle savedInstanceState) {
+ app = requireMyApplication();
+ settings = app.getSettings();
+ uiUtilities = app.getUIUtilities();
+ nightMode = !settings.isLightContent();
+ srtmPlugin = OsmandPlugin.getPlugin(SRTMPlugin.class);
+ srtmEnabled = OsmandPlugin.getEnabledPlugin(SRTMPlugin.class) != null
+ || InAppPurchaseHelper.isSubscribedToLiveUpdates(app);
+ colorProfile = settings.getApplicationMode().getIconColorInfo().getColor(nightMode);
+ terrainEnabled = srtmPlugin.isTerrainLayerEnabled();
+ super.onCreate(savedInstanceState);
+ }
+
+ @Nullable
+ @Override
+ 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);
+ 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);
+ titleTv = root.findViewById(R.id.title_tv);
+ stateTv = root.findViewById(R.id.state_tv);
+ iconIv = root.findViewById(R.id.icon_iv);
+
+ adjustUi();
+
+ return root;
+ }
+
+ private void adjustUi() {
+ TerrainMode mode = srtmPlugin.getTerrainMode();
+ switch (mode) {
+ case HILLSHADE:
+ descriptionTv.setText(R.string.hillshade_description);
+ downloadDescriptionTv.setText(R.string.hillshade_download_description);
+ break;
+ case SLOPE:
+ descriptionTv.setText(R.string.slope_description);
+ downloadDescriptionTv.setText(R.string.slope_download_description);
+ String wikiString = getString(R.string.shared_string_wikipedia);
+ setupClickableText(slopeReadMoreTv,
+ String.format(getString(R.string.slope_read_more), wikiString),
+ wikiString,
+ SLOPES_WIKI_URL);
+ break;
+ }
+
+ if (!terrainEnabled) {
+ setupClickableText(emptyStateDescriptionTv,
+ String.format(getString(R.string.slope_read_more), PLUGIN_URL),
+ PLUGIN_URL,
+ PLUGIN_URL);
+ }
+ adjustGlobalVisibility();
+ adjustLegendVisibility(mode);
+ }
+
+ private void adjustGlobalVisibility() {
+ emptyStateDescriptionTv.setVisibility(terrainEnabled ? View.GONE : View.VISIBLE);
+ titleBottomDivider.setVisibility(terrainEnabled ? View.GONE : View.VISIBLE);
+ contentContainer.setVisibility(terrainEnabled ? View.VISIBLE : View.GONE);
+ }
+
+ private void adjustLegendVisibility(TerrainMode mode) {
+ int visibility = TerrainMode.SLOPE.equals(mode) ? View.VISIBLE : View.GONE;
+ legendContainer.setVisibility(visibility);
+ legendBottomDivider.setVisibility(visibility);
+ legendTopDivider.setVisibility(visibility);
+ }
+
+ private void setupClickableText(TextView textView,
+ String text,
+ String clickableText,
+ final String url) {
+ SpannableString spannableString = new SpannableString(text);
+ ClickableSpan clickableSpan = new ClickableSpan() {
+ @Override
+ public void onClick(@NonNull View view) {
+ Intent i = new Intent(Intent.ACTION_VIEW);
+ i.setData(Uri.parse(url));
+ startActivity(i);
+ }
+ };
+ try {
+ int startIndex = text.indexOf(clickableText);
+ spannableString.setSpan(clickableSpan, startIndex, startIndex + clickableText.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ textView.setText(spannableString);
+ textView.setMovementMethod(LinkMovementMethod.getInstance());
+ textView.setHighlightColor(nightMode
+ ? getResources().getColor(R.color.active_color_primary_dark)
+ : getResources().getColor(R.color.active_color_primary_light));
+ } catch (RuntimeException e) {
+// LOG.error("Error trying to find index of " + clickableText + " " + e);
+ }
+ }
+}