terrain ui initial commit

This commit is contained in:
veliymolfar 2020-03-04 19:07:41 +02:00
parent e95da9cb61
commit 24625ca410
7 changed files with 531 additions and 3 deletions

View file

@ -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";

View file

@ -0,0 +1,303 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/activity_background_basic"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/content_padding_half"
android:layout_marginBottom="@dimen/content_padding_half"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:id="@+id/icon_iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/content_padding"
tools:src="@drawable/ic_action_hillshade_dark" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="vertical"
android:paddingStart="@dimen/content_padding"
android:paddingEnd="@dimen/content_padding">
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/title_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/default_list_text_size"
tools:text="Terrain" />
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/state_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_desc_text_size"
tools:text="Enabled" />
</LinearLayout>
<android.support.v7.widget.SwitchCompat
android:id="@+id/switch_compat"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/content_padding" />
</LinearLayout>
<include
android:id="@+id/titleBottomDivider"
layout="@layout/card_bottom_divider"
tools:visibility="gone" />
<LinearLayout
android:id="@+id/content_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/bg_color"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_sheet_list_item_height"
android:layout_marginStart="@dimen/content_padding"
android:layout_marginEnd="@dimen/content_padding"
android:baselineAligned="false"
android:orientation="horizontal">
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="?attr/dlg_btn_primary">
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/hillshade_tv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/selectableItemBackground"
android:gravity="center"
tools:text="Hillshade" />
</FrameLayout>
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="?attr/dlg_btn_primary">
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/slope_tv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/selectableItemBackground"
android:gravity="center"
tools:text="Slope" />
</FrameLayout>
</LinearLayout>
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/content_padding"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_desc_text_size"
tools:text="Hillshade map using dark shades to show slopes, peaks and lowlands." />
</LinearLayout>
<include layout="@layout/card_top_divider" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/bg_color"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingStart="@dimen/content_padding"
android:paddingTop="@dimen/content_padding_small"
android:paddingEnd="@dimen/content_padding">
<net.osmand.plus.widgets.TextViewEx
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/shared_string_transparency"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/default_list_text_size" />
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/transparency_value_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_desc_text_size"
tools:text="25%" />
</LinearLayout>
<android.support.v7.widget.AppCompatSeekBar
android:id="@+id/transparency_slider"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/list_header_settings_top_margin" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginStart="@dimen/content_padding"
android:layout_marginLeft="@dimen/content_padding"
android:layout_marginTop="@dimen/content_padding_half"
android:background="?attr/dashboard_divider"
android:focusable="false" />
<net.osmand.plus.widgets.TextViewEx
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="@dimen/content_padding"
android:paddingTop="@dimen/list_header_settings_top_margin"
android:paddingEnd="@dimen/content_padding"
android:text="@string/shared_string_zoom_levels"
android:textColor="@color/preference_category_title"
android:textSize="@dimen/default_desc_text_size" />
<net.osmand.plus.widgets.TextViewEx
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/content_padding"
android:text="@string/terrain_slider_description"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_desc_text_size" />
</LinearLayout>
<include layout="@layout/card_bottom_divider" />
<include
android:id="@+id/legend_top_divider"
layout="@layout/card_top_divider" />
<LinearLayout
android:id="@+id/legend_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/bg_color"
android:orientation="vertical">
<net.osmand.plus.widgets.TextViewEx
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="@dimen/content_padding"
android:paddingTop="@dimen/list_header_settings_top_margin"
android:paddingEnd="@dimen/content_padding"
android:text="@string/shared_string_legend"
android:textColor="@color/preference_category_title"
android:textSize="@dimen/default_desc_text_size" />
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/slope_read_more_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/content_padding"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_desc_text_size"
tools:text="@string/slope_read_more" />
</LinearLayout>
<include
android:id="@+id/legend_bottom_divider"
layout="@layout/card_bottom_divider" />
<include layout="@layout/card_top_divider" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/bg_color"
android:orientation="vertical">
<net.osmand.plus.widgets.TextViewEx
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="@dimen/content_padding"
android:paddingTop="@dimen/list_header_settings_top_margin"
android:paddingEnd="@dimen/content_padding"
android:text="@string/welmode_download_maps"
android:textColor="@color/preference_category_title"
android:textSize="@dimen/default_desc_text_size" />
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/download_description_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/content_padding"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_desc_text_size"
tools:text="@string/hillshade_download_description" />
</LinearLayout>
<include layout="@layout/card_bottom_divider" />
<View
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_sheet_list_item_height"
android:focusable="false" />
</LinearLayout>
<FrameLayout
android:id="@+id/empty_state"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:visibility="gone">
<ImageView
android:id="@+id/empty_state_image"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/empty_state_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/content_padding"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_desc_text_size"
tools:text="Включите для просмотра слоя с затенениями рельефа или картой уклона склонов. О том зачем нужные такие карты и как они работают, вы можете узнать на нашем сайте: https://osmand.net/features/contour-lines-plugin *" />
</FrameLayout>
</LinearLayout>
</ScrollView>

View file

@ -11,6 +11,9 @@
Thx - Hardy
-->
<string name="shared_string_legend">Legend</string>
<string name="shared_string_zoom_levels">Zoom levels</string>
<string name="shared_string_transparency">Transparency</string>
<string name="slope_read_more">You can read more about Slopes in %1$s.</string>
<string name="slope_download_description">Additional maps are needed to view Slopes on the map.</string>
<string name="hillshade_download_description">Additional maps are needed to view Hillshade on the map.</string>

View file

@ -2096,6 +2096,10 @@ public class OsmandSettings {
public final CommonPreference<Boolean> HILLSHADE = new BooleanPreference("hillshade_layer", true).makeProfile();
public final CommonPreference<Boolean> TERRAIN = new BooleanPreference("terrain_layer", true).makeProfile();
public final CommonPreference<TerrainMode> TERRAIN_MODE = new EnumIntPreference<>("terrain_mode", TerrainMode.HILLSHADE, TerrainMode.values()).makeProfile();
public final CommonPreference<String> 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,

View file

@ -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<DashboardActionButtonType, DashboardActionButton> 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);

View file

@ -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

View file

@ -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);
}
}
}