diff --git a/OsmAnd/res/values-fr/strings.xml b/OsmAnd/res/values-fr/strings.xml index 62aa70c0de..71b61ef4dc 100644 --- a/OsmAnd/res/values-fr/strings.xml +++ b/OsmAnd/res/values-fr/strings.xml @@ -559,7 +559,7 @@ Rue :\n{0}\n{1} Intersection :\n{0} x {1} dans {2} Bâtiment :\n{0} {1}\n{2} - Favori + Favori Effacer tout Historique Envoi des données… @@ -601,7 +601,7 @@ Ouverture des modifications… Fermeture des modifications… Envoi des nœuds… - Chargement des Points d\'Intérêts… + Chargement des Points d\'intérêts… Autorisation refusée Échec Convertir les noms en anglais… @@ -909,14 +909,14 @@ Privé Récupérer votre véhicule du parking Avertissement - Une notification pour récupérer votre véhicule a été ajoutée dans votre agenda. Elle y restera jusqu\'à ce que vous le supprimiez manuellement. + Une notification pour récupérer votre véhicule a été ajoutée dans votre agenda. Elle y restera jusqu\'à ce que vous la supprimiez manuellement. Donner un temps limite de stationnement Voulez-vous supprimer l\'emplacement de stationnement du véhicule ? Supprimer un emplacement de stationnement Choisir le type de stationnement Temps limité Temps illimité - Ajouter une notification dans l\'Agenda + Ajouter une notification dans l\'agenda Stationnement avec limite de temps Stationnement sans limite de temps La position de votre véhicule. %1$s @@ -1093,7 +1093,7 @@ Aucun numéro de bâtiment trouvé Rechercher les villages et les codes postaux Lat %1$.3f lon %2$.3f - la position actuelle + La position actuelle Limite de vitesse @@ -1281,7 +1281,7 @@ Effacer la destination Autre Il reste %1$d fichiers - Reste %1$d fichiers à télécharger + Vous pouvez encore télécharger %1$d fichier(s). Version complète Utiliser le magnétomètre pour déterminer l\'orientation de la boussole au lieu du capteur d\'orientation Utiliser le magnétomètre (boussole) @@ -1472,10 +1472,10 @@ Éviter les autoroutes Poids Spécifier la limite de poids - Sélectionner GPX … + Sélectionner GPX… Définir la destination - Définir sur la carte … - Favori … + Définir sur la carte… + Favori… Préférences d\'itinéraire Informations sur l\'itinéraire Ajouter comme destination @@ -1551,18 +1551,22 @@ Interrompre la musique lors des annonces Interrompre la musique Partager l\'itinéraire au format GPX - Itinéraire partagé via OsmAnd +Itinéraire partagé via OsmAnd Identifiant unique de l\'appareil - Voir la clé unique d\'enregistrement de l\'appareil et les autres paramètres spécifiques de suivi - OpenStreetMap-Monitoring - Suivi en temps réel avec de nombreuses fonctionnalités de contrôle à distance http://osmo.mobi - OSMo (suivi en temps réel) - OSMo - Jamais - Annoncer les instructions de navigation à intervalles réguliers - Répéter les instructions de navigation - Format invalide : %s + Voir la clé unique d\'enregistrement de l\'appareil et les autres paramètres spécifiques de suivi + OpenStreetMap-Monitoring - Suivi en temps réel avec de nombreuses fonctionnalités de contrôle à distance http://osmo.mobi + OSMo (suivi en temps réel) + OSMo + Enregistrement de l\'appareil… + Problème de connection OSMo : + Arrêter\nOSMo + Démarrer\nOSMo +Jamais +Annoncer les instructions de navigation à intervalles réguliers +Répéter les instructions de navigation +Format invalide : %s Annonce de l\'arrivée - Choisir à quel moment est annoncée l\'arrivée à destination +Choisir à quel moment est annoncée l\'arrivée à destination Précoce Normale diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 347b324f54..e2753608c9 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -9,15 +9,31 @@ 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 --> - OSMo connection problem : - Stop OSMo - Start OSMo + Automatically start tracker session and send locations after application startup + Automatically start tracker session + Personal tracker id + Click to view or share tracker id. + Using tracker id connected devices will be able to monitor all movements of this device! To disconnect select Regenerate option. + Session token : %1$s + Waiting for authorization... + Locations sent %1$d (in buffer %2$d) + Connection established : %1$s + OsMo connection problem : Unique device id - View unique device registration key and other monitoring specific settings - OSMo (OpenStreetMap-Monitoring) + Changes in 1.8: + * Calculate route between route points of GPX track + * Changed layout of countries for downloads (support local names search) + + Calculate route between points + Restart OsMo session + Stop OsMo session + Start OsMo session + Debug information + Configure monitoring settings and setup personal monitoring channel + OsMo (OpenStreetMap-Monitoring) OpenStreetMap-Monitoring - Advanced Live Monitoring with lots of features for remote control http://osmo.mobi - OSMo (Advanced Live Monitoring) - OSMo + OsMo (Advanced Live Monitoring) + OsMo Display position always in center Voice Miscallenious @@ -1441,6 +1457,8 @@ Afghanistan, Albania, Algeria, Andorra, Angola, Anguilla, Antigua and Barbuda, A No favorite points to save Import Export + Share + Favourites shared via OsmAnd Error occurred while loading GPX Send report No offline data for regions found on SD card. Download regions from the Internet. diff --git a/OsmAnd/res/xml/general_settings.xml b/OsmAnd/res/xml/general_settings.xml index 021f043585..a504808729 100644 --- a/OsmAnd/res/xml/general_settings.xml +++ b/OsmAnd/res/xml/general_settings.xml @@ -8,9 +8,9 @@ - + + + diff --git a/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java b/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java index a0ce8ab24b..7f8ed4af28 100644 --- a/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java +++ b/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java @@ -89,6 +89,11 @@ public class FavouritesDbHelper { public String exportFavorites(String fileName) { File f = new File(context.getAppPath(null), fileName); + GPXFile gpx = asGpxFile(); + return GPXUtilities.writeGpxFile(f, gpx, context); + } + + public GPXFile asGpxFile() { GPXFile gpx = new GPXFile(); for (FavouritePoint p : getFavouritePoints()) { if (p.isStored()) { @@ -101,9 +106,9 @@ public class FavouritesDbHelper { gpx.points.add(pt); } } - return GPXUtilities.writeGpxFile(f, gpx, context); + return gpx; } - + private void createCategories(SQLiteConnection db){ addCategoryQuery(context.getString(R.string.favorite_home_category), db); addCategoryQuery(context.getString(R.string.favorite_friends_category), db); diff --git a/OsmAnd/src/net/osmand/plus/GPXUtilities.java b/OsmAnd/src/net/osmand/plus/GPXUtilities.java index 03eb594513..81bbc3822a 100644 --- a/OsmAnd/src/net/osmand/plus/GPXUtilities.java +++ b/OsmAnd/src/net/osmand/plus/GPXUtilities.java @@ -123,6 +123,26 @@ public class GPXUtilities { public boolean isCloudmadeRouteFile() { return "cloudmade".equalsIgnoreCase(author); } + + public boolean hasRtePt() { + for(Route r : routes) { + if(r.points.size() > 0) { + return true; + } + } + return false; + } + + public boolean hasTrkpt() { + for(Track t : tracks) { + for (TrkSegment ts : t.segments) { + if (ts.points.size() > 0) { + return true; + } + } + } + return false; + } public void proccessPoints() { List> tpoints = new ArrayList>(); diff --git a/OsmAnd/src/net/osmand/plus/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/OsmandSettings.java index 3766b5154a..84cc9deeca 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/OsmandSettings.java @@ -632,7 +632,8 @@ public class OsmandSettings { public final OsmandPreference DRIVING_REGION = new EnumIntPreference( "default_driving_region", DrivingRegion.EUROPE_ASIA, DrivingRegion.values()) { protected boolean setValue(Object prefs, DrivingRegion val) { - ((CommonPreference)METRIC_SYSTEM).cachedValue = null; + //((CommonPreference)METRIC_SYSTEM).cachedValue = null; + ((CommonPreference)METRIC_SYSTEM).set(DRIVING_REGION.get().defMetrics); return super.setValue(prefs, val); }; }.makeGlobal().cache(); @@ -640,7 +641,7 @@ public class OsmandSettings { // this value string is synchronized with settings_pref.xml preference name // cache of metrics constants as they are used very often public final OsmandPreference METRIC_SYSTEM = new EnumIntPreference( - "default_metric_system_2", MetricsConstants.KILOMETERS_AND_METERS, MetricsConstants.values()){ + "default_metric_system", MetricsConstants.KILOMETERS_AND_METERS, MetricsConstants.values()){ protected MetricsConstants getDefaultValue() { return DRIVING_REGION.get().defMetrics; }; @@ -786,9 +787,10 @@ public class OsmandSettings { public final OsmandPreference SPEAK_SPEED_CAMERA = new BooleanPreference("speak_cameras", true).makeProfile().cache(); public final OsmandPreference SPEAK_SPEED_LIMIT = new BooleanPreference("speak_speed_limit", true).makeProfile().cache(); - public final OsmandPreference ROUTE_CALC_OSMAND_PARTS = new BooleanPreference("gpx_routing_calculate_osmand_route", true).makeGlobal().cache(); - public final OsmandPreference SPEAK_GPX_WPT = new BooleanPreference("speak_gpx_wpt", true).makeGlobal().cache(); - public final OsmandPreference CALC_GPX_ROUTE = new BooleanPreference("calc_gpx_route", false).makeGlobal().cache(); + public final OsmandPreference GPX_ROUTE_CALC_OSMAND_PARTS = new BooleanPreference("gpx_routing_calculate_osmand_route", true).makeGlobal().cache(); + public final OsmandPreference GPX_CALCULATE_RTEPT = new BooleanPreference("gpx_routing_calculate_rtept", true).makeGlobal().cache(); + public final OsmandPreference GPX_SPEAK_WPT = new BooleanPreference("speak_gpx_wpt", true).makeGlobal().cache(); + public final OsmandPreference GPX_ROUTE_CALC = new BooleanPreference("calc_gpx_route", false).makeGlobal().cache(); @@ -824,6 +826,12 @@ public class OsmandSettings { public final OsmandPreference MAP_INFO_CONTROLS = new StringPreference("map_info_controls", "").makeProfile(); + public final OsmandPreference OSMO_DEVICE_KEY = new StringPreference("osmo_device_token", "").makeGlobal(); + + public final OsmandPreference OSMO_AUTO_SEND_LOCATIONS = new BooleanPreference("osmo_automatically_send_locations", false).makeGlobal(); + + public final OsmandPreference OSMO_GROUPS = new StringPreference("osmo_groups", "{}").makeGlobal(); + // this value string is synchronized with settings_pref.xml preference name public final OsmandPreference DEBUG_RENDERING_INFO = new BooleanPreference("debug_rendering", false).makeGlobal(); @@ -1659,6 +1667,10 @@ public class OsmandSettings { public static final int OSMAND_DARK_THEME = 0; public static final int OSMAND_LIGHT_THEME = 1; public static final int OSMAND_LIGHT_DARK_ACTIONBAR_THEME = 2; + + public final CommonPreference SEARCH_TAB = + new IntPreference("SEARCH_TAB", 0).makeGlobal().cache(); + public final CommonPreference OSMAND_THEME = new IntPreference("osmand_theme", OSMAND_DARK_THEME).makeGlobal().cache(); diff --git a/OsmAnd/src/net/osmand/plus/activities/FavouritesActivity.java b/OsmAnd/src/net/osmand/plus/activities/FavouritesActivity.java index 25f85ecc44..a01357d70a 100644 --- a/OsmAnd/src/net/osmand/plus/activities/FavouritesActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/FavouritesActivity.java @@ -1,5 +1,5 @@ /** - * + * */ package net.osmand.plus.activities; @@ -15,6 +15,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import android.content.Intent; import net.londatiga.android.ActionItem; import net.londatiga.android.QuickAction; import net.osmand.access.AccessibleToast; @@ -57,30 +58,26 @@ import com.actionbarsherlock.view.MenuItem; import com.actionbarsherlock.view.Window; /** - * + * */ public class FavouritesActivity extends OsmandExpandableListActivity { - public static final int SHOW_ON_MAP = 0; - public static final int NAVIGATE_TO = 1; - public static final int DELETE_ITEM = 2; - public static final int EDIT_ITEM = 3; - public static final int EXPORT_ID = 0; public static final int IMPORT_ID = 1; public static final int DELETE_ID = 2; public static final int DELETE_ACTION_ID = 3; - + public static final int SHARE_ID = 4; + private FavouritesAdapter favouritesAdapter; private FavouritesDbHelper helper; - + private boolean selectionMode = false; private Set favoritesToDelete = new LinkedHashSet(); private Set groupsToDelete = new LinkedHashSet(); private Comparator favoritesComparator; private ActionMode actionMode; - + @Override public void onCreate(Bundle icicle) { @@ -100,18 +97,18 @@ public class FavouritesActivity extends OsmandExpandableListActivity { }; - + setContentView(R.layout.favourites_list); getSupportActionBar().setTitle(R.string.favourites_activity); setSupportProgressBarIndeterminateVisibility(false); // getSupportActionBar().setIcon(R.drawable.tab_search_favorites_icon); - - + + helper = getMyApplication().getFavorites(); favouritesAdapter = new FavouritesAdapter(); favouritesAdapter.setFavoriteGroups(helper.getFavoriteGroups()); getExpandableListView().setAdapter(favouritesAdapter); - + } private void deleteFavorites() { @@ -126,8 +123,8 @@ public class FavouritesActivity extends OsmandExpandableListActivity { hideProgressBar(); favouritesAdapter.synchronizeGroups(); favouritesAdapter.sort(favoritesComparator); - }; - + } + @Override protected void onProgressUpdate(Object... values) { for(Object o : values){ @@ -137,8 +134,8 @@ public class FavouritesActivity extends OsmandExpandableListActivity { favouritesAdapter.deleteCategory((String) o); } } - }; - + } + @Override protected String doInBackground(Void... params) { for (FavouritePoint fp : favoritesToDelete) { @@ -153,20 +150,20 @@ public class FavouritesActivity extends OsmandExpandableListActivity { groupsToDelete.clear(); return getString(R.string.favourites_delete_multiple_succesful); } - + }.execute(); - + } - + @Override protected void onResume() { super.onResume(); // final LatLon mapLocation = getMyApplication().getSettings().getLastKnownMapLocation(); favouritesAdapter.synchronizeGroups(); - + // Sort Favs by distance on Search tab, but sort alphabetically here favouritesAdapter.sort(favoritesComparator); - + } @Override @@ -189,10 +186,10 @@ public class FavouritesActivity extends OsmandExpandableListActivity { OnClickListener onshow = new OnClickListener() { @Override public void onClick(View v) { - settings.SHOW_FAVORITES.set(true); + settings.SHOW_FAVORITES.set(true); } }; - MapActivityActions.createDirectionsActions(qa, location, point, name, settings.getLastKnownMapZoom(), this, + MapActivityActions.createDirectionsActions(qa, location, point, name, settings.getLastKnownMapZoom(), this, true, onshow, false); if (point.isStored()) { ActionItem edit = new ActionItem(); @@ -219,12 +216,12 @@ public class FavouritesActivity extends OsmandExpandableListActivity { }); qa.addActionItem(delete); } - + qa.show(); } return true; } - + private boolean editPoint(final FavouritePoint point) { Builder builder = new AlertDialog.Builder(this); @@ -276,7 +273,7 @@ public class FavouritesActivity extends OsmandExpandableListActivity { builder.create().show(); return true; } - + @Override public boolean onOptionsItemSelected(com.actionbarsherlock.view.MenuItem item) { if (item.getItemId() == EXPORT_ID) { @@ -285,6 +282,9 @@ public class FavouritesActivity extends OsmandExpandableListActivity { } else if (item.getItemId() == IMPORT_ID) { importFile(); return true; + } else if (item.getItemId() == SHARE_ID) { + shareFavourites(); + return true; } else if (item.getItemId() == DELETE_ID) { enterDeleteMode(); return true; @@ -295,31 +295,33 @@ public class FavouritesActivity extends OsmandExpandableListActivity { return super.onOptionsItemSelected(item); } } - - + + @Override public boolean onCreateOptionsMenu(com.actionbarsherlock.view.Menu menu) { createMenuItem(menu, EXPORT_ID, R.string.export_fav, R.drawable.ic_action_gsave_light, R.drawable.ic_action_gsave_dark, MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT); + createMenuItem(menu, SHARE_ID, R.string.share_fav, R.drawable.ic_action_gshare_light, R.drawable.ic_action_gshare_dark, + MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT); createMenuItem(menu, IMPORT_ID, R.string.import_fav, R.drawable.ic_action_grefresh_light, R.drawable.ic_action_grefresh_dark, MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT); createMenuItem(menu, DELETE_ID, R.string.default_buttons_delete, R.drawable.ic_action_delete_light, R.drawable.ic_action_delete_dark, MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT) ; return super.onCreateOptionsMenu(menu); } - + public void showProgressBar(){ setSupportProgressBarIndeterminateVisibility(true); } - + public void hideProgressBar(){ setSupportProgressBarIndeterminateVisibility(false); } - + private void enterDeleteMode() { actionMode = startActionMode(new Callback() { - + @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { selectionMode = true; @@ -330,18 +332,18 @@ public class FavouritesActivity extends OsmandExpandableListActivity { favouritesAdapter.notifyDataSetInvalidated(); return true; } - + @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { return false; } - + @Override public void onDestroyActionMode(ActionMode mode) { selectionMode = false; favouritesAdapter.notifyDataSetInvalidated(); } - + @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { if(item.getItemId() == DELETE_ACTION_ID) { @@ -350,11 +352,11 @@ public class FavouritesActivity extends OsmandExpandableListActivity { return true; } - + }); - + } - + private void deleteFavoritesAction() { if (groupsToDelete.size() + favoritesToDelete.size() > 0) { @@ -444,6 +446,37 @@ public class FavouritesActivity extends OsmandExpandableListActivity { } } + private void shareFavourites() { + if (favouritesAdapter.isEmpty()) { + AccessibleToast.makeText(this, R.string.no_fav_to_save, Toast.LENGTH_LONG).show(); + } else { + final AsyncTask exportTask = new AsyncTask() { + @Override + protected GPXFile doInBackground(Void... params) { + return helper.asGpxFile(); + } + + @Override + protected void onPreExecute() { + showProgressBar(); + } + + @Override + protected void onPostExecute(GPXFile gpxFile) { + hideProgressBar(); + final Intent sendIntent = new Intent(); + sendIntent.setAction(Intent.ACTION_SEND); + sendIntent.putExtra(Intent.EXTRA_TEXT, GPXUtilities.asString(gpxFile, getMyApplication())); + sendIntent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.share_fav_subject)); + sendIntent.setType("application/gpx+xml"); + startActivity(sendIntent); + } + }; + + exportTask.execute(); + } + } + private void export() { final File tosave = getMyApplication().getAppPath(FavouritesDbHelper.FILE_TO_SAVE); if (favouritesAdapter.isEmpty()) { @@ -491,19 +524,19 @@ public class FavouritesActivity extends OsmandExpandableListActivity { } } } - + class FavouritesAdapter extends OsmandBaseExpandableListAdapter { Map> sourceFavoriteGroups; Map> favoriteGroups = new LinkedHashMap>(); List groups = new ArrayList(); - + public void setFavoriteGroups(Map> favoriteGroups) { this.sourceFavoriteGroups = favoriteGroups; synchronizeGroups(); } - + public void sort(Comparator comparator) { for(List ps : favoriteGroups.values()) { Collections.sort(ps, comparator); @@ -518,14 +551,14 @@ public class FavouritesActivity extends OsmandExpandableListActivity { favoriteGroups.get(p.getCategory()).add(p); notifyDataSetChanged(); } - + public void deleteFavoritePoint(FavouritePoint p) { if(favoriteGroups.containsKey(p.getCategory())){ favoriteGroups.get(p.getCategory()).remove(p); } notifyDataSetChanged(); } - + public void deleteCategory(String p) { favoriteGroups.remove(p); groups.remove(p); @@ -582,7 +615,7 @@ public class FavouritesActivity extends OsmandExpandableListActivity { public boolean isChildSelectable(int groupPosition, int childPosition) { return true; } - + @Override public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { View row = convertView; @@ -596,11 +629,11 @@ public class FavouritesActivity extends OsmandExpandableListActivity { final String model = getGroup(groupPosition); label.setText(model); final CheckBox ch = (CheckBox) row.findViewById(R.id.check_item); - + if(selectionMode){ ch.setVisibility(View.VISIBLE); ch.setChecked(groupsToDelete.contains(model)); - + ch.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -629,7 +662,7 @@ public class FavouritesActivity extends OsmandExpandableListActivity { LayoutInflater inflater = getLayoutInflater(); row = inflater.inflate(R.layout.favourites_list_item, parent, false); } - + TextView label = (TextView) row.findViewById(R.id.favourite_label); ImageView icon = (ImageView) row.findViewById(R.id.favourite_icon); final FavouritePoint model = (FavouritePoint) getChild(groupPosition, childPosition); @@ -640,7 +673,7 @@ public class FavouritesActivity extends OsmandExpandableListActivity { icon.setImageResource(R.drawable.opened_poi); } LatLon lastKnownMapLocation = getMyApplication().getSettings().getLastKnownMapLocation(); - int dist = (int) (MapUtils.getDistance(model.getLatitude(), model.getLongitude(), + int dist = (int) (MapUtils.getDistance(model.getLatitude(), model.getLongitude(), lastKnownMapLocation.getLatitude(), lastKnownMapLocation.getLongitude())); String distance = OsmAndFormatter.getFormattedDistance(dist, getMyApplication()) + " "; label.setText(distance + model.getName(), TextView.BufferType.SPANNABLE); @@ -651,7 +684,7 @@ public class FavouritesActivity extends OsmandExpandableListActivity { ch.setChecked(favoritesToDelete.contains(model)); row.findViewById(R.id.favourite_icon).setVisibility(View.GONE); ch.setOnClickListener(new View.OnClickListener() { - + @Override public void onClick(View v) { if(ch.isChecked()){ diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java index 029449caea..18a36c7402 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java @@ -473,9 +473,15 @@ public class MapActivityActions implements DialogProvider { } else { GPXRouteParamsBuilder params = new GPXRouteParamsBuilder(result, mapActivity.getMyApplication() .getSettings()); - params.setCalculateOsmAndRouteParts(settings.ROUTE_CALC_OSMAND_PARTS.get()); - params.setAnnounceWaypoints(settings.SPEAK_GPX_WPT.get()); - params.setCalculateOsmAndRoute(settings.CALC_GPX_ROUTE.get()); + if (result.hasRtePt() && !result.hasTrkpt()) { + settings.GPX_CALCULATE_RTEPT.set(true); + } else { + settings.GPX_CALCULATE_RTEPT.set(false); + } + params.setCalculateOsmAndRouteParts(settings.GPX_ROUTE_CALC_OSMAND_PARTS.get()); + params.setAnnounceWaypoints(settings.GPX_SPEAK_WPT.get()); + params.setUseIntermediatePointsRTE(settings.GPX_CALCULATE_RTEPT.get()); + params.setCalculateOsmAndRoute(settings.GPX_ROUTE_CALC.get()); List ps = params.getPoints(); mapActivity.getRoutingHelper().setGpxParams(params); settings.FOLLOW_THE_GPX_ROUTE.set(result.path); diff --git a/OsmAnd/src/net/osmand/plus/activities/SettingsGeneralActivity.java b/OsmAnd/src/net/osmand/plus/activities/SettingsGeneralActivity.java index 6f518c4709..c70c293b6a 100644 --- a/OsmAnd/src/net/osmand/plus/activities/SettingsGeneralActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/SettingsGeneralActivity.java @@ -17,6 +17,7 @@ import net.osmand.plus.ApplicationMode; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandSettings; import net.osmand.plus.OsmandSettings.DrivingRegion; +import net.osmand.plus.OsmandSettings.MetricsConstants; import net.osmand.plus.ProgressDialogImplementation; import net.osmand.plus.R; import net.osmand.plus.Version; @@ -138,16 +139,16 @@ public class SettingsGeneralActivity extends SettingsBaseActivity { 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) +")" ; + 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 mTabs = new ArrayList(); private TextView tabInfo; + private OsmandSettings osmSettings; static final class TabInfo { private final String tag; @@ -411,12 +402,13 @@ public class SearchActivity extends SherlockFragmentActivity implements OsmAndLo } } - public TabsAdapter(FragmentActivity activity, TabHost tabHost, TextView tabinfo, ViewPager pager) { + public TabsAdapter(FragmentActivity activity, TabHost tabHost, TextView tabinfo, ViewPager pager, OsmandSettings settings) { super(activity.getSupportFragmentManager()); mContext = activity; mTabHost = tabHost; tabInfo = tabinfo; mViewPager = pager; + osmSettings = settings; mTabHost.setOnTabChangedListener(this); mViewPager.setAdapter(this); mViewPager.setOnPageChangeListener(this); @@ -447,6 +439,7 @@ public class SearchActivity extends SherlockFragmentActivity implements OsmAndLo @Override public void onTabChanged(String tabId) { int position = mTabHost.getCurrentTab(); + osmSettings.SEARCH_TAB.set(position); mViewPager.setCurrentItem(position); if (SEARCH_POI.equals(tabId)) { tabInfo.setText(R.string.poi_search_desc); diff --git a/OsmAnd/src/net/osmand/plus/base/FailSafeFuntions.java b/OsmAnd/src/net/osmand/plus/base/FailSafeFuntions.java index 9411e42af0..09b0796b43 100644 --- a/OsmAnd/src/net/osmand/plus/base/FailSafeFuntions.java +++ b/OsmAnd/src/net/osmand/plus/base/FailSafeFuntions.java @@ -128,13 +128,16 @@ public class FailSafeFuntions { final GPXRouteParamsBuilder gpxRoute; if (result != null) { gpxRoute = new GPXRouteParamsBuilder(result, settings); - if (settings.SPEAK_GPX_WPT.get()) { + if (settings.GPX_SPEAK_WPT.get()) { gpxRoute.setAnnounceWaypoints(true); } - if (settings.ROUTE_CALC_OSMAND_PARTS.get()) { + if (settings.GPX_ROUTE_CALC_OSMAND_PARTS.get()) { gpxRoute.setCalculateOsmAndRouteParts(true); } - if(settings.CALC_GPX_ROUTE.get()) { + if (settings.GPX_CALCULATE_RTEPT.get()) { + gpxRoute.setUseIntermediatePointsRTE(true); + } + if(settings.GPX_ROUTE_CALC.get()) { gpxRoute.setCalculateOsmAndRoute(true); } } else { diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoGroups.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoGroups.java new file mode 100644 index 0000000000..34737c7709 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoGroups.java @@ -0,0 +1,283 @@ +package net.osmand.plus.osmo; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import net.osmand.data.LatLon; +import net.osmand.plus.OsmandSettings; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +public class OsMoGroups implements OsMoReactor { + + private static final String TRACKER_ID = "trackerId"; + private static final String GROUP_TRACKERS = "group_trackers"; + private static final String GROUP_ID = "group_id"; + private static final String NAME = "name"; + private static final String USER_NAME = "userName"; + private static final String GROUP_NAME = "group_name"; + private static final String MY_GROUP_TRACKER_ID = "my_group_tracker_id"; + private OsMoTracker tracker; + private ConcurrentHashMap groups = new ConcurrentHashMap(); + private OsMoGroup mainGroup; + private OsmandSettings settings; + private OsMoService service; + + public static class OsMoGroup { + public String name; + public String userName; + public String groupId; + public String myGroupTrackerId; + public boolean active; + + public Map users = new ConcurrentHashMap(); + + public boolean isMainGroup() { + return groupId == null; + } + + public String getVisibleName(){ + if(userName != null && userName.length() > 0) { + return userName; + } + return name; + } + } + + public static class OsMoMessage { + public long timestamp; + public LatLon location; + public String text; + } + + public static class OsMoUser { + public String serverName; + public String userName; + public String trackerId; + public List messages = new ArrayList(); + + public String getVisibleName(){ + if(userName != null && userName.length() > 0) { + return userName; + } + return serverName; + } + } + + public OsMoGroups(OsMoService service, OsMoTracker tracker, OsmandSettings settings) { + this.service = service; + this.tracker = tracker; + this.settings = settings; +// service.registerSender(this); + service.registerReactor(this); + mainGroup = new OsMoGroup(); + groups.put("", mainGroup); + + parseGroups(); + } + + private void parseGroups() { + String grp = settings.OSMO_GROUPS.get(); + try { + JSONObject obj = new JSONObject(grp); + parseGroupUsers(mainGroup, obj); + if(!obj.has("groups")) { + return; + } + JSONArray groups = obj.getJSONArray("groups"); + for (int i = 0; i < groups.length(); i++) { + JSONObject o = (JSONObject) groups.get(i); + OsMoGroup group = new OsMoGroup(); + group.groupId = o.getString(GROUP_ID); + if(o.has(MY_GROUP_TRACKER_ID)) { + group.myGroupTrackerId = o.getString(MY_GROUP_TRACKER_ID); + } + if(o.has(NAME)) { + group.name = o.getString(NAME); + } + if(o.has(USER_NAME)) { + group.userName = o.getString(USER_NAME); + } + parseGroupUsers(group, o); + this.groups.put(group.groupId, group); + } + } catch (JSONException e) { + e.printStackTrace(); + service.showErrorMessage(e.getMessage()); + } + } + + public void saveGroups() { + JSONObject mainObj = new JSONObject(); + try { + saveGroupUsers(mainGroup, mainObj); + JSONArray ar = new JSONArray(); + for(OsMoGroup gr : groups.values()) { + if(gr.isMainGroup()) { + continue; + } + JSONObject obj = new JSONObject(); + if (gr.userName != null) { + obj.put(USER_NAME, gr.userName); + } + if (gr.name != null) { + obj.put(NAME, gr.name); + } + obj.put(GROUP_ID, gr.groupId); + ar.put(obj); + } + } catch (JSONException e) { + e.printStackTrace(); + service.showErrorMessage(e.getMessage()); + } + settings.OSMO_GROUPS.set(mainObj.toString()); + } + + private void saveGroupUsers(OsMoGroup gr, JSONObject grObj) throws JSONException { + JSONArray ar = new JSONArray(); + for(OsMoUser u : gr.users.values()) { + JSONObject obj = new JSONObject(); + if (u.userName != null) { + obj.put(USER_NAME, u.userName); + } + if (u.serverName != null) { + obj.put("serverName", u.serverName); + } + obj.put(TRACKER_ID, u.trackerId); + + ar.put(obj); + } + grObj.put("users", ar); + } + + private void parseGroupUsers(OsMoGroup gr, JSONObject obj) throws JSONException { + if(!obj.has("users")) { + return; + } + JSONArray users = obj.getJSONArray("users"); + for (int i = 0; i < users.length(); i++) { + JSONObject o = (JSONObject) users.get(i); + OsMoUser user = new OsMoUser(); + if(o.has("serverName")) { + user.serverName = o.getString("serverName"); + } + if(o.has(USER_NAME)) { + user.userName = o.getString(USER_NAME); + } + user.trackerId = o.getString(TRACKER_ID); + } + } + + @Override + public boolean acceptCommand(String command, String data, JSONObject obj, OsMoThread thread) { + if(command.startsWith("ON_GROUP_CHANGE:")) { + String gid = command.substring(command.indexOf(':') + 1); + OsMoGroup gr = groups.get(gid); + if(gr != null) { + mergeGroup(gr, obj, false); + } + return true; + } else if(command.startsWith("CREATE_GROUP:")) { + String gid = command.substring(command.indexOf(':') + 1); + OsMoGroup gr = new OsMoGroup(); + gr.groupId = gid; + try { + gr.name = obj.getString(GROUP_NAME); + } catch (JSONException e) { + e.printStackTrace(); + service.showErrorMessage(e.getMessage()); + } + joinGroup(gid); + } else if(command.startsWith("JOIN_GROUP:")) { + String gid = command.substring(command.indexOf(':') + 1); + OsMoGroup gr = groups.get(gid); + if(gr != null) { + mergeGroup(gr, obj, true); + gr.active = true; + for(String key : gr.users.keySet()) { + if (!key.equals(gr.myGroupTrackerId)) { + tracker.startTrackingId(key); + } + } + } + return true; + } else if(command.startsWith("LEAVE_GROUP:")) { + String gid = command.substring(command.indexOf(':') + 1); + OsMoGroup gr = groups.get(gid); + if(gr != null) { + gr.active = false; + for(String key : gr.users.keySet()) { + if (!key.equals(gr.myGroupTrackerId)) { + tracker.stopTrackingId(key); + } + } + } + return true; + } + return false; + } + + + private void mergeGroup(OsMoGroup gr, JSONObject obj, boolean deleteUsers) { + try { + if(obj.has(GROUP_NAME)) { + gr.name = obj.getString(GROUP_NAME); + } + if(obj.has(MY_GROUP_TRACKER_ID)) { + gr.myGroupTrackerId = obj.getString(MY_GROUP_TRACKER_ID); + } + JSONArray arr = obj.getJSONArray(GROUP_TRACKERS); + Set toDelete = new HashSet(gr.users.keySet()); + for (int i = 0; i < arr.length(); i++) { + JSONObject o = (JSONObject) arr.get(i); + String tid = o.getString(TRACKER_ID); + toDelete.remove(tid); + OsMoUser us = gr.users.get(tid); + if (us == null) { + us = new OsMoUser(); + us.trackerId = tid; + gr.users.put(tid, us); + if(gr.active) { + if (!tid.equals(gr.myGroupTrackerId)) { + tracker.startTrackingId(tid); + } + } + } + if (o.has(NAME)) { + us.serverName = o.getString(NAME); + } + } + if(deleteUsers) { + for(String s : toDelete) { + gr.users.remove(s); + if(gr.active) { + tracker.stopTrackingId(s); + } + } + } + } catch (JSONException e) { + e.printStackTrace(); + service.showErrorMessage(e.getMessage()); + } + } + + public void joinGroup(String groupId) { + service.pushCommand("JOIN_GROUP|"+groupId); + } + + public void createGroup(String groupName) { + service.pushCommand("CREATE_GROUP|{\"group_name\":\"" + groupName + "\"}"); + } + + + public void leaveGroup(OsMoGroup group) { + service.pushCommand("LEAVE_GROUP|"+group.groupId); + } + +} diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java index 1adf4cd150..8e31f2eb5e 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java @@ -1,7 +1,6 @@ package net.osmand.plus.osmo; import net.osmand.Location; -import net.osmand.PlatformUtil; import net.osmand.plus.ContextMenuAdapter; import net.osmand.plus.ContextMenuAdapter.OnContextMenuClick; import net.osmand.plus.OsmandApplication; @@ -12,36 +11,42 @@ import net.osmand.plus.activities.SettingsActivity; import net.osmand.plus.views.MonitoringInfoControl; import net.osmand.plus.views.MonitoringInfoControl.MonitoringInfoControlServices; import net.osmand.plus.views.OsmandMapTileView; - -import org.apache.commons.logging.Log; - -import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.preference.Preference; import android.preference.Preference.OnPreferenceClickListener; import android.preference.PreferenceScreen; -import android.provider.Settings; public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlServices { private OsmandApplication app; public static final String ID = "osmand.osmo"; - //private static final Log log = PlatformUtil.getLog(OsMoPlugin.class); private OsMoService service; private OsMoTracker tracker; + private OsMoGroups groups; public OsMoPlugin(final OsmandApplication app) { - service = new OsMoService(); + service = new OsMoService(app); tracker = new OsMoTracker(service); + if(app.getSettings().OSMO_AUTO_SEND_LOCATIONS.get()) { + tracker.enableTracker(); + } + groups = new OsMoGroups(service, tracker, app.getSettings()); this.app = app; } @Override public boolean init(final OsmandApplication app) { + service.connect(true); return true; } + @Override + public void disable(OsmandApplication app) { + super.disable(app); + service.disconnect(); + } + @Override public void updateLocation(Location location) { if (service.isConnected()) { @@ -49,10 +54,6 @@ public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlSer } } - public static String getUUID(Context ctx) { - return Settings.Secure.getString(ctx.getContentResolver(), Settings.Secure.ANDROID_ID); - } - @Override public String getDescription() { return app.getString(R.string.osmo_plugin_description); @@ -72,27 +73,28 @@ public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlSer lock.addMonitorActions(this); } } - - @Override public void addMonitorActions(ContextMenuAdapter qa, MonitoringInfoControl li, final OsmandMapTileView view) { - final boolean off = !service.isConnected(); - qa.item(off ? R.string.osmo_mode_off : R.string.osmo_mode_on) - .icon(off ? R.drawable.monitoring_rec_inactive : R.drawable.monitoring_rec_big) + //final boolean off = !service.isConnected(); + final boolean autosend = app.getSettings().OSMO_AUTO_SEND_LOCATIONS.get(); + final boolean offTracker = tracker.isEnabledTracker(); + qa.item(autosend ? R.string.osmo_mode_restart : + ( offTracker ? R.string.osmo_mode_off : R.string.osmo_mode_on)) + .icon(offTracker ? R.drawable.monitoring_rec_inactive : R.drawable.monitoring_rec_big) .listen(new OnContextMenuClick() { @Override public void onContextMenuClick(int itemId, int pos, boolean isChecked, DialogInterface dialog) { - if(off) { - service.connect(true); + if(autosend) { + tracker.disableTracker(); + tracker.enableTracker(); + } else if (offTracker) { + tracker.enableTracker(); } else { - service.disconnect(); + tracker.disableTracker(); } } - - - }).reg(); qa.item("Test (send)").icons(R.drawable.ic_action_grefresh_dark, R.drawable.ic_action_grefresh_light) .listen(new OnContextMenuClick() { @@ -127,4 +129,16 @@ public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlSer public String getId() { return ID; } + + public OsMoGroups getGroups() { + return groups; + } + + public OsMoTracker getTracker() { + return tracker; + } + + public OsMoService getService() { + return service; + } } diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoReactor.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoReactor.java new file mode 100644 index 0000000000..4869b5c03d --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoReactor.java @@ -0,0 +1,9 @@ +package net.osmand.plus.osmo; + +import org.json.JSONObject; + +public interface OsMoReactor { + + public boolean acceptCommand(String command, String data, JSONObject obj, OsMoThread tread); + +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoSender.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoSender.java new file mode 100644 index 0000000000..3252289c2e --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoSender.java @@ -0,0 +1,6 @@ +package net.osmand.plus.osmo; + +public interface OsMoSender { + + public String nextSendCommand(OsMoThread tracker); +} diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoService.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoService.java index 65a6fdbe13..68bf90b1c4 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/OsMoService.java +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoService.java @@ -1,32 +1,62 @@ package net.osmand.plus.osmo; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; import java.util.List; +import java.util.concurrent.ConcurrentLinkedQueue; -public class OsMoService { - //public static int NUMBER_OF_TRIES_TO_RECONNECT = 20; - +import net.osmand.PlatformUtil; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; +import net.osmand.plus.Version; + +import org.apache.commons.logging.Log; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.HttpClient; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.message.BasicNameValuePair; +import org.json.JSONException; +import org.json.JSONObject; + +import android.os.Build; +import android.provider.Settings.Secure; + +public class OsMoService implements OsMoSender { private OsMoThread thread; private List listSenders = new java.util.concurrent.CopyOnWriteArrayList(); private List listReactors = new java.util.concurrent.CopyOnWriteArrayList(); + private ConcurrentLinkedQueue commands = new ConcurrentLinkedQueue(); + private OsmandApplication app; + private static final Log log = PlatformUtil.getLog(OsMoService.class); + private String lastRegistrationError = null; - public interface OsMoSender { - - public String nextSendCommand(); - } - public interface OsMoReactor { - - public boolean acceptCommand(String command); - - } - public OsMoService() { + public OsMoService(OsmandApplication app) { + this.app = app; + listSenders.add(this); } public boolean isConnected() { return thread != null && thread.isConnected(); } + public long getConnectionTime() { + return thread == null || !thread.isConnected() ? System.currentTimeMillis() : thread.getConnectionTime(); + } + + + public String getLastRegistrationError() { + return lastRegistrationError; + } + public boolean connect(boolean forceReconnect) { if(thread != null) { if(!forceReconnect ) { @@ -34,7 +64,7 @@ public class OsMoService { } thread.stopConnection(); } - thread = new OsMoThread(listSenders, listReactors); + thread = new OsMoThread(this, listSenders, listReactors); return true; } @@ -65,4 +95,124 @@ public class OsMoService { } + public String registerOsmoDeviceKey() throws IOException { + HttpClient httpclient = new DefaultHttpClient(); + HttpPost httppost = new HttpPost("http://api.osmo.mobi/auth"); + try { + // Add your data + List nameValuePairs = new ArrayList(2); + nameValuePairs.add(new BasicNameValuePair("android_id", Secure.ANDROID_ID)); + nameValuePairs.add(new BasicNameValuePair("android_model", Build.MODEL)); + nameValuePairs.add(new BasicNameValuePair("imei", "0")); + nameValuePairs.add(new BasicNameValuePair("android_product", Build.PRODUCT)); + nameValuePairs.add(new BasicNameValuePair("osmand", Version.getFullVersion(app))); + httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); + + // Execute HTTP Post Request + HttpResponse response = httpclient.execute(httppost); + InputStream cm = response.getEntity().getContent(); + BufferedReader reader = new BufferedReader(new InputStreamReader(cm)); + String r = reader.readLine(); + reader.close(); + log.info("Authorization key : " + r); + final JSONObject obj = new JSONObject(r); + if(obj.has("error")) { + lastRegistrationError = obj.getString("error"); + throw new RuntimeException(obj.getString("error")); + } + app.getSettings().OSMO_DEVICE_KEY.set(obj.getString("key")); + return obj.getString("key"); + } catch (JSONException e) { + throw new IOException(e); + } + } + + public static class SessionInfo { + public String hostName; + public String port; + public String token; + // after auth + public String protocol = ""; + public String groupTrackerId; + public String trackerId; + public String username; + public long serverTimeDelta; + public long motdTimestamp; + } + + public SessionInfo getCurrentSessionInfo() { + if(thread == null) { + return null; + } + return thread.getSessionInfo(); + } + + + public SessionInfo prepareSessionToken() throws IOException { + String deviceKey = app.getSettings().OSMO_DEVICE_KEY.get(); + if(deviceKey.length() == 0) { + deviceKey = registerOsmoDeviceKey(); + } + HttpClient httpclient = new DefaultHttpClient(); + HttpPost httppost = new HttpPost("http://api.osmo.mobi/prepare"); + try { + // Add your data + List nameValuePairs = new ArrayList(2); + nameValuePairs.add(new BasicNameValuePair("key", deviceKey)); + nameValuePairs.add(new BasicNameValuePair("protocol", "1")); + httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); + + // Execute HTTP Post Request + HttpResponse response = httpclient.execute(httppost); + InputStream cm = response.getEntity().getContent(); + BufferedReader reader = new BufferedReader(new InputStreamReader(cm)); + String r = reader.readLine(); + reader.close(); + log.info("Authorization key : " + r); + final JSONObject obj = new JSONObject(r); + if(obj.has("error")) { + lastRegistrationError = obj.getString("error"); + throw new RuntimeException(obj.getString("error")); + } + if(!obj.has("address")) { + lastRegistrationError = "Host name not specified"; + throw new RuntimeException("Host name not specified"); + } + if(!obj.has("token")) { + lastRegistrationError = "Token not specified by server"; + throw new RuntimeException("Token not specified by server"); + } + + SessionInfo si = new SessionInfo(); + String a = obj.getString("address"); + int i = a.indexOf(':'); + si.hostName = a.substring(0, i); + si.port = a.substring(i + 1); + si.token = obj.getString("token"); + return si; + } catch (ClientProtocolException e) { + throw new IOException(e); + } catch (IOException e) { + throw e; + } catch (JSONException e) { + throw new IOException(e); + } + } + + public void showErrorMessage(String string) { + app.showToastMessage(app.getString(R.string.osmo_io_error) + string); + } + + public void pushCommand(String cmd) { + commands.add(cmd); + } + + @Override + public String nextSendCommand(OsMoThread tracker) { + if(!commands.isEmpty()) { + return commands.poll(); + } + return null; + } + } diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java index f4d36cefd1..cb79345c64 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java @@ -10,65 +10,63 @@ import java.nio.channels.SocketChannel; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import net.osmand.PlatformUtil; -import net.osmand.plus.osmo.OsMoService.OsMoReactor; -import net.osmand.plus.osmo.OsMoService.OsMoSender; +import net.osmand.plus.osmo.OsMoService.SessionInfo; import org.apache.commons.logging.Log; +import org.json.JSONException; +import org.json.JSONObject; import android.os.Handler; import android.os.HandlerThread; import android.os.Message; public class OsMoThread { - private static String TRACKER_SERVER = "srv.osmo.mobi"; - private static int TRACKER_PORT = 4242; +// private static String TRACKER_SERVER = "srv.osmo.mobi"; +// private static int TRACKER_PORT = 3245; protected final static Log log = PlatformUtil.getLog(OsMoThread.class); private static final long HEARTBEAT_DELAY = 100; private static final long HEARTBEAT_FAILED_DELAY = 10000; private static final long LIMIT_OF_FAILURES_RECONNECT = 10; - private static final long CONNECTION_DELAY = 25000; private static final long SELECT_TIMEOUT = 500; private static int HEARTBEAT_MSG = 3; private Handler serviceThread; private int failures = 0; private int activeConnectionId = 0; - // -1 means connected, 0 needs to reconnect, > 0 when connection initiated - private long connectionStarted = 0; private boolean stopThread; + private boolean reconnect; private Selector selector; private List listSenders; private List listReactors; + private int authorized = 0; // 1 - send, 2 - authorized + private OsMoService service; + private SessionInfo sessionInfo = null; private SocketChannel activeChannel; + private long connectionTime; private ByteBuffer pendingSendCommand; private String readCommand = ""; private ByteBuffer pendingReadCommand = ByteBuffer.allocate(2048); private LinkedList queueOfMessages = new LinkedList(); + + + - public OsMoThread(List listSenders, List listReactors) { + public OsMoThread(OsMoService service, List listSenders, List listReactors) { + this.service = service; this.listSenders = listSenders; this.listReactors = listReactors; // start thread to receive events from OSMO HandlerThread h = new HandlerThread("OSMo Service"); h.start(); serviceThread = new Handler(h.getLooper()); - serviceThread.post(new Runnable() { - - @Override - public void run() { - try { - initConnection(); - } catch (IOException e) { - e.printStackTrace(); - } - } - }); scheduleHeartbeat(HEARTBEAT_DELAY); } @@ -77,16 +75,38 @@ public class OsMoThread { } protected void initConnection() throws IOException { + if (sessionInfo == null) { + sessionInfo = service.prepareSessionToken(); + } + authorized = 0; + reconnect = false; + selector = Selector.open(); + SocketChannel activeChannel = SocketChannel.open(); + activeChannel.configureBlocking(true); + activeChannel.connect(new InetSocketAddress(sessionInfo.hostName, Integer.parseInt(sessionInfo.port))); + activeChannel.configureBlocking(false); + SelectionKey key = activeChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE); + connectionTime = System.currentTimeMillis(); + if (this.activeChannel != null) { + stopChannel(); + } + this.activeChannel = activeChannel; + key.attach(new Integer(++activeConnectionId)); + + } + + public String format(String cmd, Map params) { + JSONObject json; try { - selector = Selector.open(); - connectionStarted = System.currentTimeMillis(); - activeChannel = SocketChannel.open(); - activeChannel.configureBlocking(false); - SelectionKey key = activeChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE); - key.attach(new Integer(++activeConnectionId)); - activeChannel.connect(new InetSocketAddress(TRACKER_SERVER, TRACKER_PORT)); - } catch (IOException e) { - throw e; + json = new JSONObject(); + Iterator> it = params.entrySet().iterator(); + while(it.hasNext()) { + Entry e = it.next(); + json.put(e.getKey(), e.getValue()); + } + return cmd + "|"+json.toString(); + } catch (JSONException e) { + throw new RuntimeException(e); } } @@ -102,25 +122,18 @@ public class OsMoThread { } public boolean isConnected() { - return connectionStarted == -1; + return activeChannel != null; } protected void checkAsyncSocket() { long delay = HEARTBEAT_DELAY; try { - if (selector == null) { - stopThread = true; +// if (selector == null) { +// stopThread = true; + if(activeChannel == null || reconnect) { + initConnection(); } else { - if (activeChannel != null && connectionStarted != -1 && !activeChannel.isConnectionPending()) { - // connection ready - connectionStarted = -1; - } - if ((connectionStarted != -1 && System.currentTimeMillis() - connectionStarted > CONNECTION_DELAY) - || activeChannel == null) { - initConnection(); - } else { - checkSelectedKeys(); - } + checkSelectedKeys(); } } catch (Exception e) { log.info("Exception selecting socket", e); @@ -130,7 +143,7 @@ public class OsMoThread { activeChannel = null; } if (failures++ > LIMIT_OF_FAILURES_RECONNECT) { - stopChannel(); + reconnect = true; } } if (stopThread) { @@ -186,12 +199,14 @@ public class OsMoThread { while (hasSomethingToRead) { pendingReadCommand.clear(); int read = activeChannel.read(pendingReadCommand); - if (pendingReadCommand.hasRemaining()) { + if (!pendingReadCommand.hasRemaining()) { hasSomethingToRead = true; } else { hasSomethingToRead = false; } - if (read > 0) { + if(read == -1) { + reconnect = true; + } else if (read > 0) { byte[] ar = pendingReadCommand.array(); String res = new String(ar, 0, read); readCommand += res; @@ -205,46 +220,130 @@ public class OsMoThread { } if (queueOfMessages.size() > 0) { - while(!queueOfMessages.isEmpty()){ - String cmd = queueOfMessages.poll(); - boolean processed = false; - for (OsMoReactor o : listReactors) { - if (o.acceptCommand(cmd)) { - processed = true; - break; - } - } - if (!processed) { - log.warn("Command not processed '" + cmd + "'"); - } - } + processReadMessages(); } } + private void processReadMessages() { + while(!queueOfMessages.isEmpty()){ + String cmd = queueOfMessages.poll(); + log.info("OSMO get:"+cmd); + int k = cmd.indexOf('|'); + String header = cmd; + String data = ""; + if(k >= 0) { + header = cmd.substring(0, k); + data = cmd.substring(k + 1); + } + JSONObject obj = null; + if(data.startsWith("{")) { + try { + obj = new JSONObject(data); + } catch (JSONException e) { + e.printStackTrace(); + } + } + boolean error = false; + if(obj != null && obj.has("error")) { + error = true; + try { + service.showErrorMessage(obj.getString("error")); + } catch (JSONException e) { + e.printStackTrace(); + } + } + if(header.equalsIgnoreCase("TOKEN")) { + if(!error){ + authorized = 2; + try { + parseAuthCommand(data, obj); + } catch (JSONException e) { + service.showErrorMessage(e.getMessage()); + } + } + continue; + } + boolean processed = false; + for (OsMoReactor o : listReactors) { + if (o.acceptCommand(header, data, obj, this)) { + processed = true; + break; + } + } + if (!processed) { + log.warn("Command not processed '" + cmd + "'"); + } + } + } + + private void parseAuthCommand(String data, JSONObject obj) throws JSONException { + if(sessionInfo != null) { + if(obj.has("protocol")) { + sessionInfo.protocol = obj.getString("protocol"); + } + if(obj.has("now")) { + sessionInfo.serverTimeDelta = obj.getLong("now") - System.currentTimeMillis(); + } + if(obj.has("name")) { + sessionInfo.username = obj.getString("name"); + } + if (obj.has("motd")) { + sessionInfo.motdTimestamp = obj.getLong("motd"); + } + if(obj.has("tracker_id")) { + sessionInfo.trackerId= obj.getString("tracker_id"); + } + if(obj.has("group_tracker_id")) { + sessionInfo.groupTrackerId= obj.getString("group_tracker_id"); + } + } + } + + public long getConnectionTime() { + return connectionTime; + } + private void writeCommands() throws UnsupportedEncodingException, IOException { if (pendingSendCommand == null) { - getNewPendingSendCommand(); + pendingSendCommand = getNewPendingSendCommand(); } while (pendingSendCommand != null) { activeChannel.write(pendingSendCommand); if (!pendingSendCommand.hasRemaining()) { - pendingSendCommand = null; - getNewPendingSendCommand(); - } - } - } - - private void getNewPendingSendCommand() throws UnsupportedEncodingException { - for (OsMoSender s : listSenders) { - String l = s.nextSendCommand(); - if (l != null) { - StringBuilder res = prepareCommand(l); - pendingSendCommand = ByteBuffer.wrap(res.toString().getBytes("UTF-8")); + pendingSendCommand = getNewPendingSendCommand(); + } else { break; } } } + + + + private ByteBuffer getNewPendingSendCommand() throws UnsupportedEncodingException { + if(authorized == 0) { + String auth = "TOKEN|"+ sessionInfo.token; + log.info("OSMO send:" + auth); + authorized = 1; + return ByteBuffer.wrap(prepareCommand(auth).toString().getBytes("UTF-8")); + } + if(authorized == 1) { + return null; + } + for (OsMoSender s : listSenders) { + String l = s.nextSendCommand(this); + if (l != null) { + StringBuilder res = prepareCommand(l); + log.info("OSMO send " + res); + return ByteBuffer.wrap(res.toString().getBytes("UTF-8")); + } + } + return null; + } + + public SessionInfo getSessionInfo() { + return sessionInfo; + } private StringBuilder prepareCommand(String l) { boolean addNL = true; @@ -270,4 +369,4 @@ public class OsMoThread { } return res; } -} \ No newline at end of file +} diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoTracker.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoTracker.java index ce16b4f0a8..4d7005d299 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/OsMoTracker.java +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoTracker.java @@ -1,19 +1,58 @@ package net.osmand.plus.osmo; -import java.util.LinkedList; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; import net.osmand.Location; -import net.osmand.plus.osmo.OsMoService.OsMoSender; +import net.osmand.plus.views.OsmandMapTileView; -public class OsMoTracker implements OsMoSender { - private LinkedList bufferOfLocations = new LinkedList(); +import org.json.JSONObject; + +public class OsMoTracker implements OsMoSender, OsMoReactor { + private ConcurrentLinkedQueue bufferOfLocations = new ConcurrentLinkedQueue(); + private Map otherLocations = new ConcurrentHashMap(); + private boolean startSendingLocations; + private OsmandMapTileView view; + private OsMoService service; + private int locationsSent = 0; public OsMoTracker(OsMoService service) { + this.service = service; service.registerSender(this); + service.registerReactor(this); + } + + public boolean isEnabledTracker() { + return startSendingLocations; + } + + public void enableTracker() { + if(!startSendingLocations) { + startSendingLocations = true; + service.pushCommand("TRACKER_SESSION_OPEN"); + } + } + + public void disableTracker() { + if(startSendingLocations) { + startSendingLocations = false; + service.pushCommand("TRACKER_SESSION_CLOSE"); + } + } + + public void startTrackingId(String id) { + service.pushCommand("LISTEN|"+id); + otherLocations.put(id, null); + } + + public void stopTrackingId(String id) { + service.pushCommand("UNLISTEN|"+id); + otherLocations.remove(id); } @Override - public String nextSendCommand() { + public String nextSendCommand(OsMoThread thread) { if(!bufferOfLocations.isEmpty()){ Location loc = bufferOfLocations.poll(); StringBuilder cmd = new StringBuilder("T|"); @@ -27,13 +66,30 @@ public class OsMoTracker implements OsMoSender { if(loc.hasSpeed()) { cmd.append("S").append((float)loc.getSpeed()); } + if(loc.hasBearing()) { + cmd.append("C").append((float)loc.getBearing()); + } + if((System.currentTimeMillis() - loc.getTime()) > 30000 && loc.getTime() != 0) { + cmd.append("T").append(loc.getTime()); + } + locationsSent ++; return cmd.toString(); } return null; } public void sendCoordinate(Location location) { - bufferOfLocations.add(location); + if(startSendingLocations) { + bufferOfLocations.add(location); + } + } + + public int getLocationsSent() { + return locationsSent; + } + + public int getBufferLocationsSize() { + return bufferOfLocations.size(); } public void sendCoordinate(double lat, double lon) { @@ -43,5 +99,56 @@ public class OsMoTracker implements OsMoSender { bufferOfLocations.add(l); } + public void setView(OsmandMapTileView view) { + this.view = view; + } + + public OsmandMapTileView getView() { + return view; + } + + @Override + public boolean acceptCommand(String command, String data, JSONObject obj, OsMoThread thread) { + if(command.startsWith("LT:")) { + String tid = command.substring(command.indexOf(':') + 1); + float lat = 0; + float lon = 0; + float speed = 0; + int k = 0; + for (int i = 0; i <= data.length(); i++) { + boolean separator = i == data.length() || Character.isDigit(data.charAt(i)) || data.charAt(i) == ':' + || data.charAt(i) == '.'; + if (separator) { + char ch = data.charAt(k); + String vl = data.substring(k + 1, i); + if (ch == 'L') { + int l = vl.indexOf(":"); + lat = Float.parseFloat(vl.substring(0, l)); + lon = Float.parseFloat(vl.substring(l + 1)); + } else if (ch == 'S') { + speed = Float.parseFloat(vl); + } + k = i; + } + } + if(lat != 0 || lon != 0) { + Location loc = new Location("osmo"); + loc.setTime(System.currentTimeMillis()); + loc.setLatitude(lat); + loc.setLongitude(lon); + if(speed > 0) { + loc.setSpeed(speed); + } + otherLocations.put(tid, loc); + OsmandMapTileView v = view; + if(v != null){ + v.refreshMap(); + } + } + return true; + } + return false; + } + } diff --git a/OsmAnd/src/net/osmand/plus/osmo/SettingsOsMoActivity.java b/OsmAnd/src/net/osmand/plus/osmo/SettingsOsMoActivity.java index bc0060a2b8..718eb7dc4f 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/SettingsOsMoActivity.java +++ b/OsmAnd/src/net/osmand/plus/osmo/SettingsOsMoActivity.java @@ -1,34 +1,123 @@ package net.osmand.plus.osmo; +import net.osmand.access.AccessibleToast; +import net.osmand.plus.OsmandPlugin; import net.osmand.plus.R; import net.osmand.plus.activities.SettingsBaseActivity; +import net.osmand.plus.osmo.OsMoService.SessionInfo; +import net.osmand.util.Algorithms; +import android.app.AlertDialog; +import android.app.AlertDialog.Builder; +import android.app.ProgressDialog; +import android.os.AsyncTask; import android.os.Bundle; +import android.preference.CheckBoxPreference; import android.preference.Preference; import android.preference.PreferenceScreen; -import android.provider.Settings; +import android.text.format.DateFormat; +import android.util.TimeUtils; +import android.widget.ProgressBar; +import android.widget.Toast; public class SettingsOsMoActivity extends SettingsBaseActivity { public static final String MORE_VALUE = "MORE_VALUE"; public static final String DEFINE_EDIT = "DEFINE_EDIT"; + private Preference debugPref; + private Preference trackerId; + private CheckBoxPreference sendLocationsref; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - getSupportActionBar().setTitle(R.string.online_map_settings); + getSupportActionBar().setTitle(R.string.osmo_settings); PreferenceScreen grp = getPreferenceScreen(); - Preference pref = new Preference(this); - pref.setTitle(R.string.osmo_settings_uuid); - pref.setSummary(OsMoPlugin.getUUID(this)); - - grp.addPreference(pref); + trackerId = new Preference(this); + trackerId.setTitle(R.string.osmo_tracker_id); + trackerId.setSummary(R.string.osmo_tracker_id_descr); + trackerId.setOnPreferenceClickListener(this); + grp.addPreference(trackerId); + + sendLocationsref = createCheckBoxPreference(settings.OSMO_AUTO_SEND_LOCATIONS); + sendLocationsref.setTitle(R.string.osmo_auto_send_locations); + sendLocationsref.setSummary(R.string.osmo_auto_send_locations_descr); + grp.addPreference(sendLocationsref); + + debugPref = new Preference(this); + debugPref.setTitle(R.string.osmo_settings_debug); + debugPref.setOnPreferenceClickListener(this); + updateDebugPref(); + grp.addPreference(debugPref); } + private void updateDebugPref() { + final OsMoPlugin plugin = OsMoPlugin.getEnabledPlugin(OsMoPlugin.class); + OsMoService service = plugin.getService(); + OsMoTracker tracker = plugin.getTracker(); + StringBuilder s = new StringBuilder(); + if(service.isConnected()) { + int seconds = (int) ((System.currentTimeMillis() - service.getConnectionTime()) / 1000); + s.append(getString(R.string.osmo_conn_successfull, Algorithms.formatDuration(seconds))).append("\n"); + SessionInfo si = service.getCurrentSessionInfo(); + if(si == null) { + s.append(getString(R.string.osmo_auth_pending)).append("\n"); + } else { + s.append(getString(R.string.osmo_session_token, si.token)).append("\n"); + } + } else { + String err = service.getLastRegistrationError(); + if(err == null) { + err = "..."; + } + s.append(getString(R.string.osmo_io_error) + err).append("\n"); + } + s.append(getString(R.string.osmo_locations_sent, + tracker.getLocationsSent(), + tracker.getBufferLocationsSize())).append("\n"); + s.append(getString(R.string.osmo_settings_uuid)).append(" : ") + .append(getMyApplication().getSettings().OSMO_DEVICE_KEY.get().toUpperCase()).append("\n"); + debugPref.setSummary(s.toString().trim()); + } + + @Override + public boolean onPreferenceClick(Preference preference) { + if (preference == debugPref) { + updateDebugPref(); + return true; + } else if(preference == trackerId) { + final OsMoPlugin plugin = OsMoPlugin.getEnabledPlugin(OsMoPlugin.class); + OsMoService service = plugin.getService(); + SessionInfo ci = service.getCurrentSessionInfo(); + if(ci == null || ci.trackerId == null) { + AccessibleToast.makeText(this, R.string.osmo_auth_pending, Toast.LENGTH_SHORT).show(); + } else { + Builder bld = new AlertDialog.Builder(this); + bld.setTitle(R.string.osmo_tracker_id); + bld.setMessage(ci.trackerId); + bld.show(); + } + } + return super.onPreferenceClick(preference); + } + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + boolean p = super.onPreferenceChange(preference, newValue); + String id = preference.getKey(); + if (id.equals(settings.OSMO_AUTO_SEND_LOCATIONS.getId())) { + if ((Boolean) newValue) { + final OsMoPlugin plugin = OsMoPlugin.getEnabledPlugin(OsMoPlugin.class); + plugin.getTracker().enableTracker(); + } + } + return p; + } + public void updateAllSettings() { super.updateAllSettings(); diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java index d9d7b92828..20899dfc47 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java +++ b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java @@ -119,7 +119,8 @@ public class RouteProvider { private boolean reverse; private boolean leftSide; private boolean passWholeRoute; - public boolean calculateOsmAndRouteParts; + private boolean calculateOsmAndRouteParts; + private boolean useIntermediatePointsRTE; public GPXRouteParamsBuilder(GPXFile file, OsmandSettings settings){ leftSide = settings.DRIVING_REGION.get().leftHandDriving; @@ -142,6 +143,14 @@ public class RouteProvider { this.calculateOsmAndRouteParts = calculateOsmAndRouteParts; } + public void setUseIntermediatePointsRTE(boolean useIntermediatePointsRTE) { + this.useIntermediatePointsRTE = useIntermediatePointsRTE; + } + + public boolean isUseIntermediatePointsRTE() { + return useIntermediatePointsRTE; + } + public boolean isCalculateOsmAndRoute() { return calculateOsmAndRoute; } @@ -196,6 +205,7 @@ public class RouteProvider { boolean calculateOsmAndRoute; boolean passWholeRoute; boolean calculateOsmAndRouteParts; + boolean useIntermediatePointsRTE; public List getPoints() { return points; @@ -229,8 +239,9 @@ public class RouteProvider { boolean reverse = builder.reverse; passWholeRoute = builder.passWholeRoute; calculateOsmAndRouteParts = builder.calculateOsmAndRouteParts; + useIntermediatePointsRTE = builder.useIntermediatePointsRTE; boolean announceWaypoints = builder.announceWaypoints; - calculateOsmAndRoute = false; // Disabled temporary builder.calculateOsmAndRoute; + builder.calculateOsmAndRoute = false; // Disabled temporary builder.calculateOsmAndRoute; if(file.isCloudmadeRouteFile() || OSMAND_ROUTER.equals(file.author)){ directions = parseOsmAndGPXRoute(points, file, OSMAND_ROUTER.equals(file.author), builder.leftSide, 10); if(reverse){ @@ -240,10 +251,12 @@ public class RouteProvider { } } else { // first of all check tracks - for (Track tr : file.tracks) { - for (TrkSegment tkSeg : tr.segments) { - for (WptPt pt : tkSeg.points) { - points.add(createLocation(pt)); + if (!useIntermediatePointsRTE) { + for (Track tr : file.tracks) { + for (TrkSegment tkSeg : tr.segments) { + for (WptPt pt : tkSeg.points) { + points.add(createLocation(pt)); + } } } } @@ -348,9 +361,13 @@ public class RouteProvider { return res; } - private RouteCalculationResult calculateGpxRoute(RouteCalculationParams routeParams) { + private RouteCalculationResult calculateGpxRoute(RouteCalculationParams routeParams) throws IOException { // get the closest point to start and to end GPXRouteParams gpxParams = routeParams.gpxRoute; + if(routeParams.gpxRoute.useIntermediatePointsRTE){ + final List intermediates = gpxParams.points; + return calculateOsmAndRouteWithIntermediatePoints(routeParams, intermediates); + } List gpxRoute ; int[] startI = new int[]{0}; int[] endI = new int[]{gpxParams.points.size()}; @@ -378,6 +395,28 @@ public class RouteProvider { + private RouteCalculationResult calculateOsmAndRouteWithIntermediatePoints(RouteCalculationParams routeParams, + final List intermediates) throws IOException { + RouteCalculationParams rp = new RouteCalculationParams(); + rp.calculationProgress = routeParams.calculationProgress; + rp.ctx = routeParams.ctx; + rp.mode = routeParams.mode; + rp.start = routeParams.start; + rp.end = routeParams.end; + rp.leftSide = routeParams.leftSide; + rp.type = routeParams.type; + rp.fast = routeParams.fast; + rp.previousToRecalculate = routeParams.previousToRecalculate; + rp.intermediates = new ArrayList(); + for(Location w : intermediates) { + rp.intermediates.add(new LatLon(w.getLatitude(), w.getLongitude())); + } + return findVectorMapsRoute(rp, false); + } + + + + private List calcDirections(int[] startI, int[] endI, final List inputDirections) { List directions = new ArrayList(); diff --git a/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java b/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java index 2dadb2178a..45b4d2674e 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java +++ b/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java @@ -757,7 +757,7 @@ public class RoutingHelper { return; } final boolean onlineSourceWithoutInternet = !res.isCalculated() && params.type.isOnline() && !settings.isInternetConnectionAvailable(); - if (onlineSourceWithoutInternet && settings.ROUTE_CALC_OSMAND_PARTS.get()) { + if (onlineSourceWithoutInternet && settings.GPX_ROUTE_CALC_OSMAND_PARTS.get()) { if (params.previousToRecalculate != null && params.previousToRecalculate.isCalculated()) { res = provider.recalculatePartOfflineRoute(res, params); } diff --git a/OsmAnd/src/net/osmand/plus/views/controls/MapRoutePreferencesControl.java b/OsmAnd/src/net/osmand/plus/views/controls/MapRoutePreferencesControl.java index b462050ddc..8e11c831a2 100644 --- a/OsmAnd/src/net/osmand/plus/views/controls/MapRoutePreferencesControl.java +++ b/OsmAnd/src/net/osmand/plus/views/controls/MapRoutePreferencesControl.java @@ -188,20 +188,23 @@ public class MapRoutePreferencesControl extends MapControls { } } else if (gpxParam.id == R.string.gpx_option_calculate_first_last_segment) { rp.setCalculateOsmAndRouteParts(selected); - settings.ROUTE_CALC_OSMAND_PARTS.set(selected); + settings.GPX_ROUTE_CALC_OSMAND_PARTS.set(selected); } else if (gpxParam.id == R.string.gpx_option_from_start_point) { rp.setPassWholeRoute(selected); } else if (gpxParam.id == R.string.announce_gpx_waypoints) { - settings.SPEAK_GPX_WPT.set(selected); + settings.GPX_SPEAK_WPT.set(selected); rp.setAnnounceWaypoints(selected); + } else if (gpxParam.id == R.string.use_points_as_intermediates) { + settings.GPX_CALCULATE_RTEPT.set(selected); + rp.setUseIntermediatePointsRTE(selected); } else if (gpxParam.id == R.string.calculate_osmand_route_gpx) { - settings.CALC_GPX_ROUTE.set(selected); + settings.GPX_ROUTE_CALC.set(selected); rp.setCalculateOsmAndRoute(selected); updateParameters(); } } if (gpxParam.id == R.string.calculate_osmand_route_without_internet) { - settings.ROUTE_CALC_OSMAND_PARTS.set(selected); + settings.GPX_ROUTE_CALC_OSMAND_PARTS.set(selected); } if (gpxParam.id == R.string.fast_route_mode) { settings.FAST_ROUTE_MODE.set(selected); @@ -215,18 +218,25 @@ public class MapRoutePreferencesControl extends MapControls { boolean osmandRouter = settings.ROUTER_SERVICE.get() == RouteService.OSMAND ; if(!osmandRouter) { list.add(new OtherLocalRoutingParameter(R.string.calculate_osmand_route_without_internet, - getString(R.string.calculate_osmand_route_without_internet), settings.ROUTE_CALC_OSMAND_PARTS.get())); + getString(R.string.calculate_osmand_route_without_internet), settings.GPX_ROUTE_CALC_OSMAND_PARTS.get())); list.add(new OtherLocalRoutingParameter(R.string.fast_route_mode, getString(R.string.fast_route_mode), settings.FAST_ROUTE_MODE.get())); return list; } if(rparams != null) { + GPXFile fl = rparams.getFile(); + if (fl.hasRtePt()) { + list.add(new OtherLocalRoutingParameter(R.string.use_points_as_intermediates, + getString(R.string.use_points_as_intermediates), rparams.isUseIntermediatePointsRTE())); + } list.add(new OtherLocalRoutingParameter(R.string.gpx_option_reverse_route, getString(R.string.gpx_option_reverse_route), rparams.isReverse())); - list.add(new OtherLocalRoutingParameter(R.string.gpx_option_from_start_point, + if (!rparams.isUseIntermediatePointsRTE()) { + list.add(new OtherLocalRoutingParameter(R.string.gpx_option_from_start_point, getString(R.string.gpx_option_from_start_point), rparams.isPassWholeRoute())); - list.add(new OtherLocalRoutingParameter(R.string.gpx_option_calculate_first_last_segment, - getString(R.string.gpx_option_calculate_first_last_segment), rparams.isCalculateOsmAndRouteParts())); + list.add(new OtherLocalRoutingParameter(R.string.gpx_option_calculate_first_last_segment, + getString(R.string.gpx_option_calculate_first_last_segment), rparams.isCalculateOsmAndRouteParts())); + } list.add(new OtherLocalRoutingParameter(R.string.announce_gpx_waypoints, getString(R.string.announce_gpx_waypoints), rparams.isAnnounceWaypoints())); // Temporary disabled