diff --git a/OsmAnd/res/values/no_translate.xml b/OsmAnd/res/values/no_translate.xml index d90e3fd680..c6e2561f78 100644 --- a/OsmAnd/res/values/no_translate.xml +++ b/OsmAnd/res/values/no_translate.xml @@ -8,10 +8,10 @@ true +play_market +gps_status -parking_plugin -blackberry -free_version -amazon + * Order waypoints in optimal way to visit all (Travelling salesman, door-to-door) * New downlad screen * Planning mode * Delete SRTM files * GPX subfolders structure - * Order waypoints in optimal way (Travel salesman) diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 3f9077884f..46313c1660 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -9,6 +9,7 @@ 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 --> + Search street in neighborhood cities Positions ordered to form optimal way from map position to the target location Sort (door-to-door) OSM change file succesfully generated %1$s diff --git a/OsmAnd/src/net/osmand/plus/activities/IntermediatePointsDialog.java b/OsmAnd/src/net/osmand/plus/activities/IntermediatePointsDialog.java index 2f735dff78..f1f7f699eb 100644 --- a/OsmAnd/src/net/osmand/plus/activities/IntermediatePointsDialog.java +++ b/OsmAnd/src/net/osmand/plus/activities/IntermediatePointsDialog.java @@ -1,5 +1,7 @@ package net.osmand.plus.activities; +import gnu.trove.list.array.TIntArrayList; + import java.util.ArrayList; import java.util.List; @@ -12,26 +14,25 @@ import net.osmand.plus.R; import net.osmand.plus.TargetPointsHelper; import net.osmand.util.MapUtils; import android.app.Activity; +import android.app.AlertDialog; import android.app.AlertDialog.Builder; +import android.app.Dialog; import android.content.DialogInterface; +import android.content.DialogInterface.OnShowListener; import android.graphics.Color; import android.os.AsyncTask; import android.view.View; -import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ArrayAdapter; -import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.ImageButton; import android.widget.LinearLayout; -import android.widget.LinearLayout.LayoutParams; import android.widget.ListView; import android.widget.ProgressBar; -import android.widget.ScrollView; import android.widget.TextView; public class IntermediatePointsDialog { @@ -45,57 +46,31 @@ public class IntermediatePointsDialog { final OsmandApplication app, final boolean changeOrder){ TargetPointsHelper targets = app.getTargetPointsHelper(); final List intermediates = targets.getIntermediatePointsWithTarget(); + final TIntArrayList originalPositions = new TIntArrayList(intermediates.size()); + for(int j = 1; j <= intermediates.size(); j++) { + originalPositions.add(j); + } final List names = targets.getIntermediatePointNamesWithTarget(); final boolean[] checkedIntermediates = new boolean[intermediates.size()]; - final ArrayAdapter listadapter = getListAdapter(app, activity, changeOrder, intermediates, names, checkedIntermediates); + final ArrayAdapter listadapter = getListAdapter(app, activity, changeOrder, intermediates, originalPositions, names, checkedIntermediates); ListView lv = new ListView(activity); + View contentView = lv; final ProgressBar pb = new ProgressBar(activity); pb.setVisibility(View.GONE); final TextView textInfo = new TextView(activity); textInfo.setText(R.string.intermediate_items_sort_return); textInfo.setVisibility(View.GONE); + if (changeOrder) { - Button btn = new Button(activity); - btn.setText(R.string.intermediate_items_sort_by_distance); - btn.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - new AsyncTask() { - - protected void onPreExecute() { - pb.setVisibility(View.VISIBLE); - textInfo.setVisibility(View.VISIBLE); - }; - - protected int[] doInBackground(Void[] params) { - ArrayList lt = new ArrayList(intermediates); - LatLon start = new LatLon(activity.getMapView().getLatitude(), activity.getMapView().getLongitude()); - LatLon end = lt.remove(lt.size() - 1); - return new TspAnt().readGraph(lt, start, end).solve(); - }; - - protected void onPostExecute(int[] result) { - pb.setVisibility(View.GONE); - List alocs = new ArrayList(); - List anames = new ArrayList(); - for (int i = 0; i < result.length; i++) { - if(result[i] > 0) { - alocs.add(intermediates.get(result[i] - 1)); - anames.add(names.get(result[i] - 1)); - } - } - intermediates.clear(); - intermediates.addAll(alocs); - names.clear(); - names.addAll(anames); - listadapter.notifyDataSetChanged(); - }; - }.execute(new Void[0]); - } - }); - lv.addFooterView(pb); - lv.addFooterView(textInfo); - lv.addFooterView(btn); + LinearLayout ll = new LinearLayout(activity); + ll.setOrientation(LinearLayout.VERTICAL); + ll.addView(lv); + ll.addView(pb); + ll.addView(textInfo); + contentView = ll; + +// lv.addFooterView(pb); +// lv.addFooterView(textInfo); } lv.setAdapter(listadapter); lv.setOnItemClickListener(new OnItemClickListener() { @@ -114,7 +89,7 @@ public class IntermediatePointsDialog { }); Builder builder = new AccessibleAlertBuilder(activity); - builder.setView(lv); + builder.setView(contentView); builder.setInverseBackgroundForced(true); lv.setBackgroundColor(Color.WHITE); builder.setPositiveButton(R.string.default_buttons_ok, new DialogInterface.OnClickListener() { @@ -135,13 +110,79 @@ public class IntermediatePointsDialog { openIntermediatePointsDialog(activity, app, true); } }); + } else { + builder.setNeutralButton(R.string.intermediate_items_sort_by_distance, new Dialog.OnClickListener() { + @Override + public void onClick(DialogInterface d, int which) { + //Do nothing here. We override the onclick + } + }); } - builder.show(); + AlertDialog dlg = builder.create(); + if (changeOrder) { + applySortTargets(dlg, activity, intermediates, originalPositions, names, listadapter, pb, textInfo); + } + dlg.show(); } + + private static void applySortTargets(AlertDialog dlg, final MapActivity activity, final List intermediates, + final TIntArrayList originalPositions, + final List names, final ArrayAdapter listadapter, final ProgressBar pb, final TextView textInfo) { + dlg.setOnShowListener(new OnShowListener() { + @Override + public void onShow(DialogInterface dialog) { + ((AlertDialog) dialog).getButton(AlertDialog.BUTTON_NEUTRAL).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + new AsyncTask() { + + protected void onPreExecute() { + pb.setVisibility(View.VISIBLE); + textInfo.setVisibility(View.VISIBLE); + }; + + protected int[] doInBackground(Void[] params) { + ArrayList lt = new ArrayList(intermediates); + LatLon start = new LatLon(activity.getMapView().getLatitude(), activity.getMapView().getLongitude()); + LatLon end = lt.remove(lt.size() - 1); + return new TspAnt().readGraph(lt, start, end).solve(); + }; + + protected void onPostExecute(int[] result) { + pb.setVisibility(View.GONE); + List alocs = new ArrayList(); + List anames = new ArrayList(); + TIntArrayList newOriginalPositions = new TIntArrayList(); + for (int i = 0; i < result.length; i++) { + if (result[i] > 0) { + LatLon loc = intermediates.get(result[i] - 1); + alocs.add(loc); + newOriginalPositions.add(originalPositions.get(intermediates.indexOf(loc))); + anames.add(names.get(result[i] - 1)); + } + } + intermediates.clear(); + intermediates.addAll(alocs); + names.clear(); + names.addAll(anames); + originalPositions.clear(); + originalPositions.addAll(newOriginalPositions); + listadapter.notifyDataSetChanged(); + }; + }.execute(new Void[0]); + + } + }); + + } + }); + } + private static ArrayAdapter getListAdapter(final OsmandApplication app, final Activity activity, final boolean changeOrder, - final List intermediates, final List names, final boolean[] checkedIntermediates) { + final List intermediates, final TIntArrayList originalPositions, final List names, final boolean[] checkedIntermediates) { final int padding = (int) (12 * activity.getResources().getDisplayMetrics().density + 0.5f); final ArrayAdapter listadapter = new ArrayAdapter(app, changeOrder? R.layout.change_order_item : R.layout.list_menu_item, R.id.title, @@ -152,7 +193,7 @@ public class IntermediatePointsDialog { // User super class to create the View View v = super.getView(position, convertView, parent); TextView tv = (TextView) v.findViewById(R.id.title); - String nm = (position + 1) + ". "; + String nm = originalPositions.get(position) + ". "; String distString = ""; if(activity instanceof MapActivity) { double lat = ((MapActivity) activity).getMapView().getLatitude(); @@ -175,8 +216,10 @@ public class IntermediatePointsDialog { if(position > 0) { LatLon old = intermediates.remove(position - 1); String oldN = names.remove(position - 1); + int oldI = originalPositions.removeAt(position -1 ); names.add(position, oldN); intermediates.add(position, old); + originalPositions.insert(position, oldI); notifyDataSetInvalidated(); } } @@ -187,8 +230,10 @@ public class IntermediatePointsDialog { if(position < intermediates.size() - 1) { LatLon old = intermediates.remove(position + 1); String oldN = names.remove(position + 1); + int oldI = originalPositions.removeAt(position + 1 ); names.add(position, oldN); intermediates.add(position, old); + originalPositions.insert(position, oldI); notifyDataSetInvalidated(); } } diff --git a/OsmAnd/src/net/osmand/plus/activities/search/SearchByNameAbstractActivity.java b/OsmAnd/src/net/osmand/plus/activities/search/SearchByNameAbstractActivity.java index d1b96ca395..87de060ae1 100644 --- a/OsmAnd/src/net/osmand/plus/activities/search/SearchByNameAbstractActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/search/SearchByNameAbstractActivity.java @@ -32,6 +32,7 @@ import android.os.Message; import android.text.Editable; import android.text.Spannable; import android.text.TextWatcher; +import android.text.style.ForegroundColorSpan; import android.text.style.StyleSpan; import android.view.KeyEvent; import android.view.LayoutInflater; @@ -45,6 +46,7 @@ import android.widget.Filter; import android.widget.ListView; import android.widget.ProgressBar; import android.widget.TextView; +import android.widget.TextView.BufferType; import android.widget.TextView.OnEditorActionListener; @@ -137,8 +139,9 @@ public abstract class SearchByNameAbstractActivity extends OsmandListActivity findViewById(R.id.ResetButton).setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v) { - searchText.setText(""); + reset(); } + }); getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); if(initializeTask != null){ @@ -146,6 +149,10 @@ public abstract class SearchByNameAbstractActivity extends OsmandListActivity } } + protected void reset() { + searchText.setText(""); + } + protected void addFooterViews() { } @@ -189,6 +196,10 @@ public abstract class SearchByNameAbstractActivity extends OsmandListActivity querySearch(currentFilter); } + protected View getFooterView() { + return null; + } + private void querySearch(final String filter) { if (!currentFilter.equals(filter) || !initFilter) { currentFilter = filter; @@ -241,6 +252,10 @@ public abstract class SearchByNameAbstractActivity extends OsmandListActivity } protected abstract Comparator createComparator(); + + public String getDistanceText(T obj) { + return null; + } public abstract String getText(T obj); @@ -413,7 +428,15 @@ public abstract class SearchByNameAbstractActivity extends OsmandListActivity row = inflater.inflate(R.layout.searchbyname_list, parent, false); } TextView label = (TextView) row.findViewById(R.id.NameLabel); - label.setText(getText(getItem(position))); + String distanceText = getDistanceText(getItem(position)); + String text = getText(getItem(position)); + if(distanceText == null) { + label.setText(text); + } else { + label.setText(distanceText + " " + text, BufferType.SPANNABLE); + ((Spannable) label.getText()).setSpan(new ForegroundColorSpan(getResources().getColor(R.color.color_distance)), 0, + distanceText.length(), 0); + } return row; } } diff --git a/OsmAnd/src/net/osmand/plus/activities/search/SearchStreetByNameActivity.java b/OsmAnd/src/net/osmand/plus/activities/search/SearchStreetByNameActivity.java index 7513304696..0566ead681 100644 --- a/OsmAnd/src/net/osmand/plus/activities/search/SearchStreetByNameActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/search/SearchStreetByNameActivity.java @@ -10,22 +10,69 @@ import net.osmand.CollatorStringMatcher; import net.osmand.CollatorStringMatcher.StringMatcherMode; import net.osmand.ResultMatcher; import net.osmand.data.City; +import net.osmand.data.MapObject; import net.osmand.data.MapObject.MapObjectComparator; import net.osmand.data.Street; +import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.resources.RegionAddressRepository; +import net.osmand.util.Algorithms; +import net.osmand.util.MapUtils; import android.os.AsyncTask; import android.os.Message; +import android.view.Gravity; import android.view.View; +import android.view.ViewGroup.LayoutParams; +import android.widget.Button; +import android.widget.FrameLayout; public class SearchStreetByNameActivity extends SearchByNameAbstractActivity { private RegionAddressRepository region; private City city; + private Button searchAllStrets; + private int searchWithCity = -1; // -1 - default, 0 - filter city, 1 - deep search @Override protected Comparator createComparator() { - return new MapObjectComparator(getMyApplication().getSettings().usingEnglishNames()); + return new MapObjectComparator(getMyApplication().getSettings().usingEnglishNames()) { + @Override + public int compare(MapObject o1, MapObject o2) { + if(searchWithCity >= 0 && city != null) { + double d1 = MapUtils.getDistance(city.getLocation(), o1.getLocation()); + double d2 = MapUtils.getDistance(city.getLocation(), o2.getLocation()); + return Double.compare(d1, d2); + } + return super.compare(o1, o2); + } + }; + } + + @Override + protected void reset() { + searchWithCity = -1; + super.reset(); + } + + + @Override + protected void addFooterViews() { + final FrameLayout ll = new FrameLayout(this); + searchAllStrets = new Button(this); + android.widget.FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); + lp.gravity = Gravity.CENTER_HORIZONTAL; + searchAllStrets.setLayoutParams(lp); + searchAllStrets.setText(R.string.search_street_in_neighborhood_cities); + ll.addView(searchAllStrets); + searchAllStrets.setOnClickListener(new View.OnClickListener() { + + @Override + public void onClick(View v) { + searchWithCity = 1; + research(); + } + }); + getListView().addFooterView(ll); } @Override @@ -50,7 +97,7 @@ public class SearchStreetByNameActivity extends SearchByNameAbstractActivity(); } region.preloadStreets(city, new ResultMatcher() { @Override @@ -73,6 +120,53 @@ public class SearchStreetByNameActivity extends SearchByNameAbstractActivity list) { + if(searchWithCity == -1){ + filter(query, list); + } else if(searchWithCity == 0){ + for (Street obj : list) { + if(namesFilter.isCancelled){ + break; + } + if(filterObject(obj, query)){ + Message msg = uiHandler.obtainMessage(MESSAGE_ADD_ENTITY, obj); + msg.sendToTarget(); + } + } + } else { + searchWithCity = 0; + final List res = region.searchMapObjectsByName(query, new ResultMatcher() { + @Override + public boolean publish(MapObject object) { + if (object instanceof Street) { + if(city == null || + MapUtils.getDistance(city.getLocation(), object.getLocation()) < 100*1000) { + Message msg = uiHandler.obtainMessage(MESSAGE_ADD_ENTITY, object); + msg.sendToTarget(); + return true; + } + } + return false; + } + + @Override + public boolean isCancelled() { + return namesFilter.isCancelled; + } + }); + runOnUiThread(new Runnable() { + + @Override + public void run() { + finishInitializing(res); + } + }); + } + + + } + + + private void filter(String query, Collection list) { boolean emptyQuery = query == null || query.length() == 0; for (Street obj : list) { if (namesFilter.isCancelled) { @@ -99,12 +193,28 @@ public class SearchStreetByNameActivity extends SearchByNameAbstractActivity= 0 || city == null) { + String nameWithCity = obj.getName(region.useEnglishNames()) + " - " + obj.getCity().getName(region.useEnglishNames()); + return nameWithCity ; + } return obj.getName(region.useEnglishNames()); } + @Override + public String getDistanceText(Street obj) { + if(searchWithCity >= 0 && city != null) { + return OsmAndFormatter.getFormattedDistance((float) MapUtils.getDistance(obj.getLocation(), city.getLocation()), + getMyApplication()); + } + return null; + } + @Override public void itemSelected(Street obj) { + if(!Algorithms.objectEquals(settings.getLastSearchedCity(), obj.getCity().getId())) { + settings.setLastSearchedCity(obj.getCity().getId(), obj.getCity().getName(), obj.getLocation()); + } settings.setLastSearchedStreet(obj.getName(region.useEnglishNames()), obj.getLocation()); finish();