From 61b47f538c7c9d8e2b065ec4b32040070648943d Mon Sep 17 00:00:00 2001 From: Alexey Kulish Date: Wed, 15 Mar 2017 17:04:39 +0300 Subject: [PATCH] Added automatic detection of driving region --- .../src/net/osmand/map/OsmandRegions.java | 8 +- .../layout/single_choice_description_item.xml | 48 ++++++++++ OsmAnd/res/values/strings.xml | 2 + OsmAnd/res/xml/general_settings.xml | 2 +- .../net/osmand/plus/OsmandApplication.java | 22 +++++ .../src/net/osmand/plus/OsmandSettings.java | 6 ++ .../activities/SettingsGeneralActivity.java | 94 ++++++++++++++++--- .../plus/base/MapViewTrackingUtilities.java | 28 ++++++ .../plus/download/DownloadIndexesThread.java | 23 +---- .../download/ui/SearchDialogFragment.java | 7 +- 10 files changed, 206 insertions(+), 34 deletions(-) create mode 100644 OsmAnd/res/layout/single_choice_description_item.xml diff --git a/OsmAnd-java/src/net/osmand/map/OsmandRegions.java b/OsmAnd-java/src/net/osmand/map/OsmandRegions.java index 40ded13a8d..3b3d6efe49 100644 --- a/OsmAnd-java/src/net/osmand/map/OsmandRegions.java +++ b/OsmAnd-java/src/net/osmand/map/OsmandRegions.java @@ -370,6 +370,8 @@ public class OsmandRegions { sr.log = false; if (reader != null) { reader.searchMapIndex(sr); + } else { + throw new IOException("Reader == null"); } return result; } @@ -689,16 +691,16 @@ public class OsmandRegions { } } - public BinaryMapDataObject findBinaryMapDataObject(LatLon latLon) { + public BinaryMapDataObject findBinaryMapDataObject(LatLon latLon) throws IOException { int point31x = MapUtils.get31TileNumberX(latLon.getLongitude()); int point31y = MapUtils.get31TileNumberY(latLon.getLatitude()); BinaryMapDataObject res = null; - List mapDataObjects = null; + List mapDataObjects; try { mapDataObjects = queryBbox(point31x, point31x, point31y, point31y); } catch (IOException e) { - e.printStackTrace(); + throw new IOException("Error while calling queryBbox"); } if (mapDataObjects != null) { diff --git a/OsmAnd/res/layout/single_choice_description_item.xml b/OsmAnd/res/layout/single_choice_description_item.xml new file mode 100644 index 0000000000..ea8db8ecf1 --- /dev/null +++ b/OsmAnd/res/layout/single_choice_description_item.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index b13e7367f2..63a60d532a 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -9,6 +9,8 @@ 3. All your modified/created strings are in the top of the file (to make easier find what\'s translated). PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy --> + Right-hand driving + Automatic Do not send anonymous app usage It sends general information about screen used during session. We do not collect any geolocation or user input related data. Do not show messages at startup diff --git a/OsmAnd/res/xml/general_settings.xml b/OsmAnd/res/xml/general_settings.xml index 800cfff28e..4cd0d2465b 100644 --- a/OsmAnd/res/xml/general_settings.xml +++ b/OsmAnd/res/xml/general_settings.xml @@ -5,7 +5,7 @@ - + diff --git a/OsmAnd/src/net/osmand/plus/OsmandApplication.java b/OsmAnd/src/net/osmand/plus/OsmandApplication.java index e22a3895d1..5606640dd7 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandApplication.java +++ b/OsmAnd/src/net/osmand/plus/OsmandApplication.java @@ -29,6 +29,7 @@ import net.osmand.PlatformUtil; import net.osmand.access.AccessibilityPlugin; import net.osmand.data.LatLon; import net.osmand.map.OsmandRegions; +import net.osmand.map.WorldRegion; import net.osmand.osm.MapPoiTypes; import net.osmand.plus.AppInitializer.AppInitializeListener; import net.osmand.plus.access.AccessibilityMode; @@ -790,6 +791,27 @@ public class OsmandApplication extends MultiDexApplication { } return l; } + + public void setupDrivingRegion(WorldRegion reg) { + OsmandSettings.DrivingRegion drg = null; + WorldRegion.RegionParams params = reg.getParams(); + boolean americanSigns = "american".equals(params.getRegionRoadSigns()); + boolean leftHand = "yes".equals(params.getRegionLeftHandDriving()); + OsmandSettings.MetricsConstants mc1 = "miles".equals(params.getRegionMetric()) ? + OsmandSettings.MetricsConstants.MILES_AND_FEET : OsmandSettings.MetricsConstants.KILOMETERS_AND_METERS; + OsmandSettings.MetricsConstants mc2 = "miles".equals(params.getRegionMetric()) ? + OsmandSettings.MetricsConstants.MILES_AND_METERS : OsmandSettings.MetricsConstants.KILOMETERS_AND_METERS; + for (OsmandSettings.DrivingRegion r : OsmandSettings.DrivingRegion.values()) { + if (r.americanSigns == americanSigns && r.leftHandDriving == leftHand && + (r.defMetrics == mc1 || r.defMetrics == mc2)) { + drg = r; + break; + } + } + if (drg != null) { + osmandSettings.DRIVING_REGION.set(drg); + } + } public void logEvent(Activity ctx, String event) { try { diff --git a/OsmAnd/src/net/osmand/plus/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/OsmandSettings.java index bfaf9512c8..53b52518c4 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/OsmandSettings.java @@ -738,6 +738,7 @@ public class OsmandSettings { public final OsmandPreference FIRST_MAP_IS_DOWNLOADED = new BooleanPreference( "first_map_is_downloaded", false); + public final CommonPreference DRIVING_REGION_AUTOMATIC = new BooleanPreference("driving_region_automatic", true).makeGlobal().cache(); public final OsmandPreference DRIVING_REGION = new EnumIntPreference( "default_driving_region", DrivingRegion.EUROPE_ASIA, DrivingRegion.values()) { protected boolean setValue(Object prefs, DrivingRegion val) { @@ -3049,6 +3050,11 @@ public class OsmandSettings { this.americanSigns = americanSigns; } + public String getDescription(Context ctx) { + return ctx.getString(leftHandDriving ? R.string.left_side_navigation : R.string.right_side_navigation) + + ", " + + defMetrics.toHumanString(ctx).toLowerCase(); + } } } diff --git a/OsmAnd/src/net/osmand/plus/activities/SettingsGeneralActivity.java b/OsmAnd/src/net/osmand/plus/activities/SettingsGeneralActivity.java index 27bc33cd86..41a0cbb0ea 100644 --- a/OsmAnd/src/net/osmand/plus/activities/SettingsGeneralActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/SettingsGeneralActivity.java @@ -20,10 +20,17 @@ import android.preference.Preference.OnPreferenceChangeListener; import android.preference.Preference.OnPreferenceClickListener; import android.preference.PreferenceGroup; import android.preference.PreferenceScreen; +import android.support.annotation.NonNull; import android.support.v4.app.ActivityCompat.OnRequestPermissionsResultCallback; import android.support.v7.app.AlertDialog; +import android.support.v7.widget.AppCompatCheckedTextView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; import android.widget.EditText; import android.widget.LinearLayout; +import android.widget.TextView; import android.widget.Toast; import net.osmand.IProgress; @@ -50,6 +57,7 @@ import net.osmand.render.RenderingRulesStorage; import java.io.File; import java.util.ArrayList; +import java.util.Arrays; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; @@ -60,7 +68,7 @@ public class SettingsGeneralActivity extends SettingsBaseActivity implements OnR public static final String MORE_VALUE = "MORE_VALUE"; private Preference applicationDir; private ListPreference applicationModePreference; - private ListPreference drivingRegionPreference; + private Preference drivingRegionPreference; private ChooseAppDirFragment chooseAppDirFragment; private boolean permissionRequested; private boolean permissionGranted; @@ -93,15 +101,15 @@ public class SettingsGeneralActivity extends SettingsBaseActivity implements OnR new String[]{getString(R.string.map_orientation_portrait), getString(R.string.map_orientation_landscape), getString(R.string.map_orientation_default)}, new Integer[]{ActivityInfo.SCREEN_ORIENTATION_PORTRAIT, ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE, ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED}); + drivingRegionPreference = screen.findPreference(settings.DRIVING_REGION.getId()); + addLocalPrefs((PreferenceGroup) screen.findPreference("localization")); addVoicePrefs((PreferenceGroup) screen.findPreference("voice")); addProxyPrefs((PreferenceGroup) screen.findPreference("proxy")); addMiscPreferences((PreferenceGroup) screen.findPreference("misc")); - applicationModePreference = (ListPreference) screen.findPreference(settings.APPLICATION_MODE.getId()); applicationModePreference.setOnPreferenceChangeListener(this); - drivingRegionPreference = (ListPreference) screen.findPreference(settings.DRIVING_REGION.getId()); } @@ -134,16 +142,80 @@ public class SettingsGeneralActivity extends SettingsBaseActivity implements OnR private void addLocalPrefs(PreferenceGroup screen) { + drivingRegionPreference.setTitle(R.string.driving_region); + drivingRegionPreference.setSummary(R.string.driving_region_descr); + drivingRegionPreference.setOnPreferenceClickListener(new OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + final AlertDialog.Builder b = new AlertDialog.Builder(SettingsGeneralActivity.this); + + b.setTitle(getString(R.string.driving_region)); + + final List drs = new ArrayList<>(); + drs.add(null); + drs.addAll(Arrays.asList(DrivingRegion.values())); + int sel = -1; + DrivingRegion selectedDrivingRegion = settings.DRIVING_REGION.get(); + if (settings.DRIVING_REGION_AUTOMATIC.get()) { + sel = 0; + } + for (int i = 1; i < drs.size(); i++) { + if (sel == -1 && drs.get(i) == selectedDrivingRegion) { + sel = i; + break; + } + } + + final int selected = sel; + final ArrayAdapter singleChoiceAdapter = + new ArrayAdapter(SettingsGeneralActivity.this, R.layout.single_choice_description_item, R.id.text1, drs) { + @NonNull + @Override + public View getView(int position, View convertView, @NonNull ViewGroup parent) { + View v = convertView; + if (v == null) { + LayoutInflater inflater = SettingsGeneralActivity.this.getLayoutInflater(); + v = inflater.inflate(R.layout.single_choice_description_item, parent, false); + } + DrivingRegion item = getItem(position); + AppCompatCheckedTextView title = (AppCompatCheckedTextView) v.findViewById(R.id.text1); + TextView desc = (TextView) v.findViewById(R.id.description); + if (item != null) { + title.setText(getString(item.name)); + desc.setVisibility(View.VISIBLE); + desc.setText(item.getDescription(v.getContext())); + } else { + title.setText(getString(R.string.driving_region_automatic)); + desc.setVisibility(View.GONE); + } + title.setChecked(position == selected); + return v; + } + }; + + b.setAdapter(singleChoiceAdapter, new OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + if (drs.get(which) == null) { + settings.DRIVING_REGION_AUTOMATIC.set(true); + MapActivity.getSingleMapViewTrackingUtilities().resetDrivingRegionUpdate(); + } else { + settings.DRIVING_REGION_AUTOMATIC.set(false); + settings.DRIVING_REGION.set(drs.get(which)); + } + updateAllSettings(); + } + }); + + b.setNegativeButton(R.string.shared_string_cancel, null); + b.show(); + return true; + } + }); + String[] entries; String[] entrieValues; - DrivingRegion[] drs = DrivingRegion.values(); - entries = new String[drs.length]; - for (int i = 0; i < entries.length; i++) { - entries[i] = getString(drs[i].name); // + " (" + drs[i].defMetrics.toHumanString(this) +")" ; - } - registerListPreference(settings.DRIVING_REGION, screen, entries, drs); - MetricsConstants[] mvls = MetricsConstants.values(); entries = new String[mvls.length]; for (int i = 0; i < entries.length; i++) { @@ -458,7 +530,7 @@ public class SettingsGeneralActivity extends SettingsBaseActivity implements OnR applicationModePreference.setTitle(getString(R.string.settings_preset) + " [" + settings.APPLICATION_MODE.get().toHumanString(getMyApplication()) + "]"); drivingRegionPreference.setTitle(getString(R.string.driving_region) + " [" - + getString(settings.DRIVING_REGION.get().name) + "]"); + + getString(settings.DRIVING_REGION_AUTOMATIC.get() ? R.string.driving_region_automatic : settings.DRIVING_REGION.get().name) + "]"); } @Override diff --git a/OsmAnd/src/net/osmand/plus/base/MapViewTrackingUtilities.java b/OsmAnd/src/net/osmand/plus/base/MapViewTrackingUtilities.java index 5f49d4fee2..949d5a9fbb 100644 --- a/OsmAnd/src/net/osmand/plus/base/MapViewTrackingUtilities.java +++ b/OsmAnd/src/net/osmand/plus/base/MapViewTrackingUtilities.java @@ -6,8 +6,11 @@ import android.view.WindowManager; import net.osmand.Location; import net.osmand.StateChangedListener; import net.osmand.ValueHolder; +import net.osmand.binary.BinaryMapDataObject; +import net.osmand.data.LatLon; import net.osmand.data.RotatedTileBox; import net.osmand.map.IMapLocationListener; +import net.osmand.map.WorldRegion; import net.osmand.plus.MapMarkersHelper; import net.osmand.plus.MapMarkersHelper.MapMarkerChangedListener; import net.osmand.plus.OsmAndConstants; @@ -17,6 +20,7 @@ import net.osmand.plus.OsmAndLocationProvider.OsmAndLocationListener; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandSettings; import net.osmand.plus.OsmandSettings.AutoZoomMap; +import net.osmand.plus.OsmandSettings.DrivingRegion; import net.osmand.plus.R; import net.osmand.plus.dashboard.DashboardOnMap; import net.osmand.plus.mapcontextmenu.MapContextMenu; @@ -26,6 +30,8 @@ import net.osmand.plus.views.AnimateDraggingMapThread; import net.osmand.plus.views.OsmandMapTileView; import net.osmand.util.MapUtils; +import java.io.IOException; + public class MapViewTrackingUtilities implements OsmAndLocationListener, IMapLocationListener, OsmAndCompassListener, IRouteInformationListener, MapMarkerChangedListener { private static final int AUTO_FOLLOW_MSG_ID = OsmAndConstants.UI_HANDLER_LOCATION_SERVICE + 4; @@ -46,6 +52,7 @@ public class MapViewTrackingUtilities implements OsmAndLocationListener, IMapLoc private boolean showRouteFinishDialog = false; private Location myLocation; private Float heading; + private boolean drivingRegionUpdated = false; public MapViewTrackingUtilities(OsmandApplication app){ this.app = app; @@ -58,6 +65,10 @@ public class MapViewTrackingUtilities implements OsmAndLocationListener, IMapLoc app.getRoutingHelper().addListener(this); } + public void resetDrivingRegionUpdate() { + drivingRegionUpdated = false; + } + private void addTargetPointListener(OsmandApplication app) { app.getTargetPointsHelper().addListener(new StateChangedListener() { @@ -141,6 +152,23 @@ public class MapViewTrackingUtilities implements OsmAndLocationListener, IMapLoc showViewAngle = false; if (location != null) { locationProvider = location.getProvider(); + if (settings.DRIVING_REGION_AUTOMATIC.get() && !drivingRegionUpdated) { + try { + BinaryMapDataObject o = app.getRegions().findBinaryMapDataObject( + new LatLon(location.getLatitude(), location.getLongitude())); + if (o != null) { + String fullName = app.getRegions().getFullName(o); + WorldRegion worldRegion = app.getRegions().getRegionData(fullName); + if (worldRegion != null) { + app.setupDrivingRegion(worldRegion); + } + } + drivingRegionUpdated = true; + + } catch (IOException e) { + // ignore + } + } } if (mapView != null) { RotatedTileBox tb = mapView.getCurrentRotatedTileBox(); diff --git a/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java b/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java index f516fcfd55..3d07372e06 100644 --- a/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java +++ b/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java @@ -20,15 +20,14 @@ import android.support.v7.app.NotificationCompat; import android.support.v7.app.NotificationCompat.Builder; import android.view.View; import android.widget.Toast; + import net.osmand.IndexConstants; import net.osmand.PlatformUtil; import net.osmand.map.WorldRegion; import net.osmand.map.WorldRegion.RegionParams; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.OsmandSettings.DrivingRegion; -import net.osmand.plus.OsmandSettings.MetricsConstants; -import net.osmand.plus.OsmandSettings.OsmandPreference; import net.osmand.plus.OsmandSettings; +import net.osmand.plus.OsmandSettings.OsmandPreference; import net.osmand.plus.R; import net.osmand.plus.Version; import net.osmand.plus.base.BasicProgressAsyncTask; @@ -154,27 +153,15 @@ public class DownloadIndexesThread { } updateNotification(); } - + public void initSettingsFirstMap(WorldRegion reg) { if(app.getSettings().FIRST_MAP_IS_DOWNLOADED.get() || reg == null) { return; } app.getSettings().FIRST_MAP_IS_DOWNLOADED.set(true); - DrivingRegion drg = null; RegionParams params = reg.getParams(); - boolean americanSigns = "american".equals(params.getRegionRoadSigns()); - boolean leftHand = "yes".equals(params.getRegionLeftHandDriving()); - MetricsConstants mc = "miles".equals(params.getRegionMetric()) ? - MetricsConstants.MILES_AND_FEET : MetricsConstants.KILOMETERS_AND_METERS; - for (DrivingRegion r : DrivingRegion.values()) { - if (r.americanSigns == americanSigns && r.leftHandDriving == leftHand && - r.defMetrics == mc) { - drg = r; - break; - } - } - if (drg != null) { - app.getSettings().DRIVING_REGION.set(drg); + if (!app.getSettings().DRIVING_REGION_AUTOMATIC.get()) { + app.setupDrivingRegion(reg); } String lang = params.getRegionLang(); if (lang != null) { diff --git a/OsmAnd/src/net/osmand/plus/download/ui/SearchDialogFragment.java b/OsmAnd/src/net/osmand/plus/download/ui/SearchDialogFragment.java index 6d9d6ffaee..acf3e9e205 100644 --- a/OsmAnd/src/net/osmand/plus/download/ui/SearchDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/download/ui/SearchDialogFragment.java @@ -394,7 +394,12 @@ public class SearchDialogFragment extends DialogFragment implements DownloadEven @Override protected IndexItem doInBackground(Void... params) { Amenity amenity = cityItem.getAmenity(); - BinaryMapDataObject o = osmandRegions.findBinaryMapDataObject(amenity.getLocation()); + BinaryMapDataObject o = null; + try { + o = osmandRegions.findBinaryMapDataObject(amenity.getLocation()); + } catch (IOException e) { + // ignore + } if (o != null) { String selectedFullName = osmandRegions.getFullName(o); WorldRegion downloadRegion = osmandRegions.getRegionData(selectedFullName);