Added quick search
BIN
OsmAnd/res/drawable-hdpi/map_search_dark.png
Executable file
After Width: | Height: | Size: 1.5 KiB |
BIN
OsmAnd/res/drawable-hdpi/map_search_night.png
Executable file
After Width: | Height: | Size: 1.5 KiB |
BIN
OsmAnd/res/drawable-mdpi/map_search_dark.png
Executable file
After Width: | Height: | Size: 1.3 KiB |
BIN
OsmAnd/res/drawable-mdpi/map_search_night.png
Executable file
After Width: | Height: | Size: 1.3 KiB |
BIN
OsmAnd/res/drawable-xhdpi/map_search_dark.png
Executable file
After Width: | Height: | Size: 1.7 KiB |
BIN
OsmAnd/res/drawable-xhdpi/map_search_night.png
Executable file
After Width: | Height: | Size: 1.7 KiB |
BIN
OsmAnd/res/drawable-xxhdpi/map_search_dark.png
Executable file
After Width: | Height: | Size: 2.1 KiB |
BIN
OsmAnd/res/drawable-xxhdpi/map_search_night.png
Executable file
After Width: | Height: | Size: 2.1 KiB |
|
@ -361,22 +361,39 @@
|
|||
android:layout_marginTop="@dimen/map_button_margin"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/map_layers_button"
|
||||
android:contentDescription="@string/configure_map"
|
||||
android:layout_width="@dimen/map_small_button_size"
|
||||
android:layout_height="@dimen/map_small_button_size"
|
||||
android:background="@drawable/btn_inset_circle_trans"
|
||||
android:contentDescription="@string/configure_map"
|
||||
android:src="@drawable/ic_action_test_light"/>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/map_compass_button"
|
||||
android:contentDescription="@string/map_widget_compass"
|
||||
android:layout_width="@dimen/map_small_button_size"
|
||||
android:layout_height="@dimen/map_small_button_size"
|
||||
android:layout_marginLeft="@dimen/map_small_button_margin"
|
||||
android:layout_marginTop="@dimen/map_small_button_margin"
|
||||
android:background="@drawable/btn_inset_circle_trans"
|
||||
android:contentDescription="@string/map_widget_compass"
|
||||
android:src="@drawable/ic_action_test_light"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/map_search_button"
|
||||
android:layout_width="@dimen/map_small_button_size"
|
||||
android:layout_height="@dimen/map_small_button_size"
|
||||
android:layout_marginLeft="@dimen/map_small_button_margin"
|
||||
android:background="@drawable/btn_inset_circle_trans"
|
||||
android:contentDescription="@string/map_widget_search"
|
||||
tools:src="@drawable/ic_action_test_light"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
|
|
|
@ -360,17 +360,33 @@
|
|||
android:layout_marginTop="@dimen/map_button_margin"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/map_layers_button"
|
||||
android:contentDescription="@string/configure_map"
|
||||
android:layout_width="@dimen/map_small_button_size"
|
||||
android:layout_height="@dimen/map_small_button_size"
|
||||
android:background="@drawable/btn_inset_circle_trans"
|
||||
tools:src="@drawable/ic_action_test_light"/>
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/map_layers_button"
|
||||
android:layout_width="@dimen/map_small_button_size"
|
||||
android:layout_height="@dimen/map_small_button_size"
|
||||
android:background="@drawable/btn_inset_circle_trans"
|
||||
android:contentDescription="@string/configure_map"
|
||||
tools:src="@drawable/ic_action_test_light"/>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/map_compass_button"
|
||||
android:layout_width="@dimen/map_small_button_size"
|
||||
android:layout_height="@dimen/map_small_button_size"
|
||||
android:layout_marginTop="@dimen/map_small_button_margin"
|
||||
android:background="@drawable/btn_inset_circle_trans"
|
||||
android:contentDescription="@string/map_widget_compass"
|
||||
tools:src="@drawable/ic_action_test_light"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/map_compass_button"
|
||||
android:contentDescription="@string/map_widget_compass"
|
||||
android:id="@+id/map_search_button"
|
||||
android:contentDescription="@string/map_widget_search"
|
||||
android:layout_width="@dimen/map_small_button_size"
|
||||
android:layout_height="@dimen/map_small_button_size"
|
||||
android:layout_marginLeft="@dimen/map_small_button_margin"
|
||||
|
|
74
OsmAnd/res/layout/search_dialog_fragment.xml
Normal file
|
@ -0,0 +1,74 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<android.support.design.widget.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="@dimen/dashboard_map_toolbar"
|
||||
android:background="?attr/pstsTabBackground"
|
||||
android:minHeight="@dimen/dashboard_map_toolbar"
|
||||
android:theme="?attr/toolbar_theme"
|
||||
app:contentInsetLeft="54dp"
|
||||
app:contentInsetStart="54dp">
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="56dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/searchEditText"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:background="@null"
|
||||
android:gravity="center_vertical"
|
||||
android:hint="@string/search_poi_category_hint"
|
||||
android:lines="1"
|
||||
android:singleLine="true"/>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/searchProgressBar"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:indeterminate="true"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/clearButton"
|
||||
style="@style/Widget.AppCompat.ActionButton"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:contentDescription="@string/shared_string_close"
|
||||
android:src="@drawable/ic_action_remove_dark"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</android.support.v7.widget.Toolbar>
|
||||
|
||||
|
||||
</android.support.design.widget.AppBarLayout>
|
||||
|
||||
<ListView
|
||||
android:id="@android:id/list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginLeft="0dp"
|
||||
android:layout_marginRight="0dp"
|
||||
android:layout_marginTop="0dp"
|
||||
android:layout_weight="1"
|
||||
android:drawSelectorOnTop="true"
|
||||
android:groupIndicator="@android:color/transparent"/>
|
||||
|
||||
</LinearLayout>
|
60
OsmAnd/res/layout/search_list_item.xml
Normal file
|
@ -0,0 +1,60 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="?attr/listPreferredItemHeight"
|
||||
android:orientation="horizontal"
|
||||
android:paddingBottom="12dp"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingTop="8dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imageView"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_gravity="top"
|
||||
android:scaleType="centerInside"
|
||||
android:visibility="visible"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:paddingRight="16dp"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Subhead"
|
||||
tools:text="Amsterdam"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/distance"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="right"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
tools:text="100 km"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/subtitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
tools:text="City"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
|
@ -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
|
||||
-->
|
||||
<string name="map_widget_search">Search</string>
|
||||
<string name="shared_string_is_open_24_7">Open 24/7</string>
|
||||
<string name="storage_directory_card">Memory card</string>
|
||||
<string name="coords_format">Coordinate format</string>
|
||||
|
|
409
OsmAnd/src/net/osmand/plus/search/QuickSearchDialogFragment.java
Normal file
|
@ -0,0 +1,409 @@
|
|||
package net.osmand.plus.search;
|
||||
|
||||
import android.app.ProgressDialog;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ListView;
|
||||
import android.widget.ProgressBar;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.binary.BinaryMapIndexReader;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.data.PointDescription;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.OsmandSettings;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.resources.RegionAddressRepository;
|
||||
import net.osmand.search.SearchUICore;
|
||||
import net.osmand.search.core.ObjectType;
|
||||
import net.osmand.search.core.SearchResult;
|
||||
import net.osmand.search.core.SearchSettings;
|
||||
import net.osmand.util.Algorithms;
|
||||
import net.osmand.util.MapUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class QuickSearchDialogFragment extends DialogFragment {
|
||||
|
||||
public static final String TAG = "QuickSearchDialogFragment";
|
||||
private static final String QUICK_SEARCH_QUERY_KEY = "quick_search_query_key";
|
||||
private ListView listView;
|
||||
private SearchListAdapter listAdapter;
|
||||
private EditText searchEditText;
|
||||
private ProgressBar progressBar;
|
||||
private ImageButton clearButton;
|
||||
|
||||
private SearchUICore searchUICore;
|
||||
private String searchQuery = "";
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
boolean isLightTheme = getMyApplication().getSettings().OSMAND_THEME.get() == OsmandSettings.OSMAND_LIGHT_THEME;
|
||||
int themeId = isLightTheme ? R.style.OsmandLightTheme : R.style.OsmandDarkTheme;
|
||||
setStyle(STYLE_NO_FRAME, themeId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
final OsmandApplication app = getMyApplication();
|
||||
final MapActivity mapActivity = getMapActivity();
|
||||
final View view = inflater.inflate(R.layout.search_dialog_fragment, container, false);
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
searchQuery = savedInstanceState.getString(QUICK_SEARCH_QUERY_KEY);
|
||||
}
|
||||
if (searchQuery == null) {
|
||||
searchQuery = getArguments().getString(QUICK_SEARCH_QUERY_KEY);
|
||||
}
|
||||
if (searchQuery == null)
|
||||
searchQuery = "";
|
||||
|
||||
Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar);
|
||||
toolbar.setNavigationIcon(R.drawable.abc_ic_ab_back_mtrl_am_alpha);
|
||||
toolbar.setNavigationContentDescription(R.string.access_shared_string_navigate_up);
|
||||
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
|
||||
// Setup search
|
||||
String locale = app.getSettings().MAP_PREFERRED_LOCALE.get();
|
||||
/*
|
||||
List<BinaryMapIndexReader> files = new ArrayList<>();
|
||||
File file = new File(Environment.getExternalStorageDirectory() + "/osmand");
|
||||
if (file.exists() && file.listFiles() != null) {
|
||||
for (File obf : file.listFiles()) {
|
||||
if (!obf.isDirectory() && obf.getName().endsWith(".obf")) {
|
||||
try {
|
||||
BinaryMapIndexReader bmir = new BinaryMapIndexReader(new RandomAccessFile(obf, "r"), obf);
|
||||
files.add(bmir);
|
||||
} catch (Exception e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
searchUICore = new SearchUICore(app.getPoiTypes(), locale, files.toArray(new BinaryMapIndexReader[files.size()]));
|
||||
*/
|
||||
|
||||
Collection<RegionAddressRepository> regionAddressRepositories = app.getResourceManager().getAddressRepositories();
|
||||
BinaryMapIndexReader[] binaryMapIndexReaderArray = new BinaryMapIndexReader[regionAddressRepositories.size()];
|
||||
int i = 0;
|
||||
for (RegionAddressRepository rep : regionAddressRepositories) {
|
||||
binaryMapIndexReaderArray[i++] = rep.getFile();
|
||||
}
|
||||
searchUICore = new SearchUICore(app.getPoiTypes(), locale, binaryMapIndexReaderArray);
|
||||
|
||||
LatLon centerLatLon = mapActivity.getMapView().getCurrentRotatedTileBox().getCenterLatLon();
|
||||
SearchSettings settings = searchUICore.getPhrase().getSettings().setOriginalLocation(
|
||||
new LatLon(centerLatLon.getLatitude(), centerLatLon.getLongitude()));
|
||||
settings = settings.setLang(locale);
|
||||
searchUICore.updateSettings(settings);
|
||||
searchUICore.setOnResultsComplete(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
app.runInUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
hideProgressBar();
|
||||
updateSearchResult(searchUICore.getCurrentSearchResult(), true);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
listView = (ListView) view.findViewById(android.R.id.list);
|
||||
listAdapter = new SearchListAdapter(getMyApplication());
|
||||
listView.setAdapter(listAdapter);
|
||||
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
SearchListItem item = listAdapter.getItem(position);
|
||||
SearchResult sr = item.getSearchResult();
|
||||
|
||||
boolean updateEditText = true;
|
||||
if (sr.objectType == ObjectType.POI
|
||||
|| sr.objectType == ObjectType.LOCATION
|
||||
|| sr.objectType == ObjectType.HOUSE
|
||||
|| sr.objectType == ObjectType.FAVORITE
|
||||
|| sr.objectType == ObjectType.RECENT_OBJ
|
||||
|| sr.objectType == ObjectType.WPT
|
||||
|| sr.objectType == ObjectType.STREET_INTERSECTION) {
|
||||
|
||||
updateEditText = false;
|
||||
dismiss();
|
||||
if (sr.location != null) {
|
||||
showOnMap(sr);
|
||||
}
|
||||
}
|
||||
completeQueryWithObject(item.getSearchResult(), updateEditText);
|
||||
}
|
||||
});
|
||||
|
||||
searchEditText = (EditText) view.findViewById(R.id.searchEditText);
|
||||
searchEditText.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
String newQueryText = s.toString();
|
||||
if (!searchQuery.equalsIgnoreCase(newQueryText)) {
|
||||
searchQuery = newQueryText;
|
||||
showProgressBar();
|
||||
runSearch();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
progressBar = (ProgressBar) view.findViewById(R.id.searchProgressBar);
|
||||
clearButton = (ImageButton) view.findViewById(R.id.clearButton);
|
||||
clearButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (searchEditText.getText().length() == 0) {
|
||||
dismiss();
|
||||
} else {
|
||||
searchEditText.setText("");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
searchEditText.requestFocus();
|
||||
AndroidUtils.softKeyboardDelayed(searchEditText);
|
||||
runSearch();
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
setShowsDialog(true);
|
||||
final boolean isLightContent = getMyApplication().getSettings().isLightContent();
|
||||
final int colorId = isLightContent ? R.color.bg_color_light : R.color.bg_color_dark;
|
||||
listView.setBackgroundColor(ContextCompat.getColor(getActivity(), colorId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
outState.putString(QUICK_SEARCH_QUERY_KEY, searchQuery);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
if (!Algorithms.isEmpty(searchQuery)) {
|
||||
searchEditText.setText(searchQuery);
|
||||
searchEditText.setSelection(searchQuery.length());
|
||||
}
|
||||
}
|
||||
|
||||
private void showProgressBar() {
|
||||
clearButton.setVisibility(View.GONE);
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
private void hideProgressBar() {
|
||||
clearButton.setVisibility(View.VISIBLE);
|
||||
progressBar.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
private void runSearch() {
|
||||
runSearch(searchQuery);
|
||||
}
|
||||
|
||||
private void runSearch(String text) {
|
||||
|
||||
SearchSettings settings = searchUICore.getPhrase().getSettings();
|
||||
if(settings.getRadiusLevel() != 1){
|
||||
searchUICore.updateSettings(settings.setRadiusLevel(1));
|
||||
}
|
||||
SearchUICore.SearchResultCollection c = searchUICore.search(text, null);
|
||||
updateSearchResult(c, false);
|
||||
}
|
||||
|
||||
private void completeQueryWithObject(SearchResult sr, boolean updateEditText) {
|
||||
|
||||
searchUICore.selectSearchResult(sr);
|
||||
String txt = searchUICore.getPhrase().getText(true);
|
||||
if (updateEditText) {
|
||||
searchQuery = txt;
|
||||
searchEditText.setText(txt);
|
||||
searchEditText.setSelection(txt.length());
|
||||
}
|
||||
|
||||
searchUICore.search(txt, null);
|
||||
}
|
||||
|
||||
private void updateSearchResult(SearchUICore.SearchResultCollection res, boolean addMore) {
|
||||
|
||||
OsmandApplication app = getMyApplication();
|
||||
|
||||
List<SearchListItem> rows = new ArrayList<>();
|
||||
if (res.getCurrentSearchResults().size() > 0) {
|
||||
for (final SearchResult sr : res.getCurrentSearchResults()) {
|
||||
|
||||
int count = 30;
|
||||
/*
|
||||
if(addMore) {
|
||||
JMenuItem mi = new JMenuItem();
|
||||
mi.setText("Results " + res.getCurrentSearchResults().size() + ", radius " + res.getPhrase().getRadiusLevel()+
|
||||
" (show more...)");
|
||||
mi.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
SearchSettings settings = searchUICore.getPhrase().getSettings();
|
||||
searchUICore.updateSettings(settings.setRadiusLevel(settings.getRadiusLevel() + 1));
|
||||
searchUICore.search(statusField.getText(), null);
|
||||
updateSearchResult(statusField, new SearchResultCollection(), false);
|
||||
}
|
||||
});
|
||||
popup.add(mi);
|
||||
}
|
||||
*/
|
||||
|
||||
count--;
|
||||
if (count == 0) {
|
||||
// break;
|
||||
}
|
||||
//LatLon location = res.getPhrase().getLastTokenLocation();
|
||||
//String locationString = "";
|
||||
//if (sr.location != null) {
|
||||
// locationString = ((int) MapUtils.getDistance(location, sr.location)) + " m";
|
||||
//}
|
||||
//mi.setText(sr.localeName + " [" + sr.objectType + "] " + locationString);
|
||||
|
||||
SearchListItem listItem = new SearchListItem(app, sr);
|
||||
if (sr.location != null) {
|
||||
LatLon location = res.getPhrase().getLastTokenLocation();
|
||||
listItem.setDistance(MapUtils.getDistance(location, sr.location));
|
||||
}
|
||||
rows.add(listItem);
|
||||
}
|
||||
}
|
||||
updateListAdapter(rows);
|
||||
}
|
||||
|
||||
private void updateListAdapter(List<SearchListItem> listItems) {
|
||||
listAdapter.setListItems(listItems);
|
||||
if (listAdapter.getCount() > 0) {
|
||||
listView.setSelection(0);
|
||||
}
|
||||
}
|
||||
|
||||
private void showOnMap(SearchResult searchResult) {
|
||||
if (searchResult.location != null) {
|
||||
PointDescription pointDescription = null;
|
||||
Object object = null;
|
||||
switch (searchResult.objectType) {
|
||||
case POI:
|
||||
object = searchResult.object;
|
||||
pointDescription = getMapActivity().getMapLayers().getPoiMapLayer().getObjectName(object);
|
||||
break;
|
||||
}
|
||||
getMyApplication().getSettings().setMapLocationToShow(
|
||||
searchResult.location.getLatitude(), searchResult.location.getLongitude(),
|
||||
searchResult.preferredZoom, pointDescription, true, object);
|
||||
|
||||
MapActivity.launchMapActivityMoveToTop(getActivity());
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean showInstance(final MapActivity mapActivity, final String searchQuery) {
|
||||
try {
|
||||
|
||||
if (mapActivity.isActivityDestroyed()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final OsmandApplication app = mapActivity.getMyApplication();
|
||||
if (app.isApplicationInitializing()) {
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
|
||||
private ProgressDialog dlg;
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
dlg = new ProgressDialog(mapActivity);
|
||||
dlg.setTitle("");
|
||||
dlg.setMessage(mapActivity.getString(R.string.wait_current_task_finished));
|
||||
dlg.setCanceledOnTouchOutside(false);
|
||||
dlg.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
while (app.isApplicationInitializing()) {
|
||||
try {
|
||||
Thread.sleep(50);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void aVoid) {
|
||||
dlg.hide();
|
||||
showInternal(mapActivity, searchQuery);
|
||||
}
|
||||
}.execute();
|
||||
|
||||
} else {
|
||||
showInternal(mapActivity, searchQuery);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
} catch (RuntimeException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static void showInternal(MapActivity mapActivity, String searchQuery) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString(QUICK_SEARCH_QUERY_KEY, searchQuery);
|
||||
QuickSearchDialogFragment fragment = new QuickSearchDialogFragment();
|
||||
fragment.setArguments(bundle);
|
||||
mapActivity.getSupportFragmentManager().beginTransaction()
|
||||
//.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_left, R.anim.slide_in_left, R.anim.slide_out_left)
|
||||
.add(R.id.fragmentContainer, fragment, TAG)
|
||||
.addToBackStack(TAG).commitAllowingStateLoss();
|
||||
}
|
||||
|
||||
private MapActivity getMapActivity() {
|
||||
return (MapActivity) getActivity();
|
||||
}
|
||||
|
||||
private OsmandApplication getMyApplication() {
|
||||
return (OsmandApplication) getActivity().getApplication();
|
||||
}
|
||||
|
||||
}
|
101
OsmAnd/src/net/osmand/plus/search/SearchListAdapter.java
Normal file
|
@ -0,0 +1,101 @@
|
|||
package net.osmand.plus.search;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.plus.OsmAndFormatter;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.List;
|
||||
|
||||
public class SearchListAdapter extends ArrayAdapter<SearchListItem> {
|
||||
|
||||
private OsmandApplication ctx;
|
||||
|
||||
public SearchListAdapter(OsmandApplication ctx) {
|
||||
super(ctx, R.layout.search_list_item);
|
||||
this.ctx = ctx;
|
||||
}
|
||||
|
||||
public void setListItems(List<SearchListItem> items) {
|
||||
setNotifyOnChange(false);
|
||||
clear();
|
||||
addAll(items);
|
||||
setNotifyOnChange(true);
|
||||
notifyDataSetInvalidated();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchListItem getItem(int position) {
|
||||
return super.getItem(position);
|
||||
}
|
||||
|
||||
public void updateDistance(double latitude, double longitude) {
|
||||
/*
|
||||
for (int i = 0; i < getCount(); i++) {
|
||||
SearchListItem item = getItem(i);
|
||||
if (item instanceof SearchListPositionItem) {
|
||||
SearchListPositionItem positionItem = (SearchListPositionItem) item;
|
||||
positionItem.setDistance(Utilities.distance(
|
||||
longitude, latitude, positionItem.getLongitude(), positionItem.getLatitude()));
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
SearchListItem listItem = getItem(position);
|
||||
|
||||
LinearLayout view;
|
||||
if (convertView == null) {
|
||||
LayoutInflater inflater = (LayoutInflater) ctx
|
||||
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
view = (LinearLayout) inflater.inflate(
|
||||
R.layout.search_list_item, null);
|
||||
} else {
|
||||
view = (LinearLayout) convertView;
|
||||
}
|
||||
|
||||
ImageView imageView = (ImageView) view.findViewById(R.id.imageView);
|
||||
TextView title = (TextView) view.findViewById(R.id.title);
|
||||
TextView subtitle = (TextView) view.findViewById(R.id.subtitle);
|
||||
TextView distance = (TextView) view.findViewById(R.id.distance);
|
||||
|
||||
imageView.setImageDrawable(listItem.getIcon());
|
||||
title.setText(listItem.getName());
|
||||
subtitle.setText(listItem.getTypeName());
|
||||
float dist = (float) listItem.getDistance();
|
||||
if (dist == 0) {
|
||||
distance.setText("");
|
||||
distance.setVisibility(View.INVISIBLE);
|
||||
} else {
|
||||
distance.setText(OsmAndFormatter.getFormattedDistance(dist, ctx));
|
||||
distance.setVisibility(View.VISIBLE);
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
public static String getFormattedDistance(double meters) {
|
||||
double mainUnitInMeters = 1000;
|
||||
String mainUnitStr = "km";
|
||||
if (meters >= 100 * mainUnitInMeters) {
|
||||
return (int) (meters / mainUnitInMeters + 0.5) + " " + mainUnitStr;
|
||||
} else if (meters > 9.99f * mainUnitInMeters) {
|
||||
return MessageFormat.format("{0,number,#.#} " + mainUnitStr, ((float) meters) / mainUnitInMeters).replace('\n', ' ');
|
||||
} else if (meters > 0.999f * mainUnitInMeters) {
|
||||
return MessageFormat.format("{0,number,#.##} " + mainUnitStr, ((float) meters) / mainUnitInMeters).replace('\n', ' ');
|
||||
} else {
|
||||
return ((int) (meters + 0.5)) + " m";
|
||||
}
|
||||
}
|
||||
}
|
152
OsmAnd/src/net/osmand/plus/search/SearchListItem.java
Normal file
|
@ -0,0 +1,152 @@
|
|||
package net.osmand.plus.search;
|
||||
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import net.osmand.data.Amenity;
|
||||
import net.osmand.data.City;
|
||||
import net.osmand.data.Street;
|
||||
import net.osmand.osm.AbstractPoiType;
|
||||
import net.osmand.osm.PoiCategory;
|
||||
import net.osmand.osm.PoiFilter;
|
||||
import net.osmand.osm.PoiType;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.search.core.SearchResult;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
public class SearchListItem {
|
||||
|
||||
protected OsmandApplication app;
|
||||
private SearchResult searchResult;
|
||||
private double distance;
|
||||
|
||||
public SearchListItem(OsmandApplication app, SearchResult searchResult) {
|
||||
this.app = app;
|
||||
this.searchResult = searchResult;
|
||||
}
|
||||
|
||||
public SearchResult getSearchResult() {
|
||||
return searchResult;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return searchResult.localeName;
|
||||
}
|
||||
|
||||
public String getTypeName() {
|
||||
switch (searchResult.objectType) {
|
||||
case CITY:
|
||||
case POSTCODE:
|
||||
City city = (City) searchResult.object;
|
||||
return Algorithms.capitalizeFirstLetterAndLowercase(city.getType().toString());
|
||||
case VILLAGE:
|
||||
city = (City) searchResult.object;
|
||||
if (!Algorithms.isEmpty(searchResult.localeRelatedObjectName)) {
|
||||
return Algorithms.capitalizeFirstLetterAndLowercase(city.getType().toString())
|
||||
+ " near "
|
||||
+ searchResult.localeRelatedObjectName
|
||||
+ (searchResult.distRelatedObjectName > 0 ? " (" + SearchListAdapter.getFormattedDistance(searchResult.distRelatedObjectName) + ")" : "");
|
||||
} else {
|
||||
return Algorithms.capitalizeFirstLetterAndLowercase(city.getType().toString());
|
||||
}
|
||||
case STREET:
|
||||
Street street = (Street) searchResult.object;
|
||||
City streetCity = street.getCity();
|
||||
if (!Algorithms.isEmpty(searchResult.localeRelatedObjectName)) {
|
||||
return searchResult.localeRelatedObjectName
|
||||
+ (searchResult.distRelatedObjectName > 0 ? "(" + SearchListAdapter.getFormattedDistance(searchResult.distRelatedObjectName) + ")" : "");
|
||||
} else {
|
||||
return streetCity.getName() + " - " + Algorithms.capitalizeFirstLetterAndLowercase(streetCity.getType().name());
|
||||
}
|
||||
case HOUSE:
|
||||
return "House";
|
||||
case STREET_INTERSECTION:
|
||||
return "Street intersection";
|
||||
case POI_TYPE:
|
||||
AbstractPoiType abstractPoiType = (AbstractPoiType) searchResult.object;
|
||||
String res;
|
||||
if (abstractPoiType instanceof PoiCategory) {
|
||||
res = "POI category";
|
||||
} else if (abstractPoiType instanceof PoiFilter) {
|
||||
PoiFilter poiFilter = (PoiFilter) abstractPoiType;
|
||||
res = poiFilter.getPoiCategory() != null ? poiFilter.getPoiCategory().getTranslation() : "POI filter";
|
||||
|
||||
} else if (abstractPoiType instanceof PoiType) {
|
||||
PoiType poiType = (PoiType) abstractPoiType;
|
||||
res = poiType.getParentType() != null ? poiType.getParentType().getTranslation() : null;
|
||||
if (res == null) {
|
||||
res = poiType.getCategory() != null ? poiType.getCategory().getTranslation() : null;
|
||||
}
|
||||
if (res == null) {
|
||||
res = "POI type";
|
||||
}
|
||||
} else {
|
||||
res = "POI type";
|
||||
}
|
||||
return res;
|
||||
case POI:
|
||||
Amenity amenity = (Amenity) searchResult.object;
|
||||
return amenity.getType().toString();
|
||||
case LOCATION:
|
||||
break;
|
||||
case FAVORITE:
|
||||
break;
|
||||
case REGION:
|
||||
break;
|
||||
case RECENT_OBJ:
|
||||
break;
|
||||
case WPT:
|
||||
break;
|
||||
case UNKNOWN_NAME_FILTER:
|
||||
break;
|
||||
}
|
||||
return searchResult.objectType.name();
|
||||
}
|
||||
|
||||
public Drawable getIcon() {
|
||||
switch (searchResult.objectType) {
|
||||
case CITY:
|
||||
break;
|
||||
case VILLAGE:
|
||||
break;
|
||||
case POSTCODE:
|
||||
break;
|
||||
case STREET:
|
||||
break;
|
||||
case HOUSE:
|
||||
break;
|
||||
case STREET_INTERSECTION:
|
||||
break;
|
||||
case POI_TYPE:
|
||||
break;
|
||||
case POI:
|
||||
Amenity amenity = (Amenity) searchResult.object;
|
||||
Drawable drawable = null;
|
||||
PoiType st = amenity.getType().getPoiTypeByKeyName(amenity.getSubType());
|
||||
if (st != null) {
|
||||
//drawable = app.getIconsCache().getMapIcon(st.getOsmTag() + "_" + st.getOsmValue());
|
||||
}
|
||||
return drawable;
|
||||
case LOCATION:
|
||||
break;
|
||||
case FAVORITE:
|
||||
break;
|
||||
case REGION:
|
||||
break;
|
||||
case RECENT_OBJ:
|
||||
break;
|
||||
case WPT:
|
||||
break;
|
||||
case UNKNOWN_NAME_FILTER:
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public double getDistance() {
|
||||
return distance;
|
||||
}
|
||||
|
||||
public void setDistance(double distance) {
|
||||
this.distance = distance;
|
||||
}
|
||||
}
|
|
@ -41,6 +41,7 @@ import net.osmand.plus.activities.search.SearchAddressFragment;
|
|||
import net.osmand.plus.dashboard.DashboardOnMap.DashboardType;
|
||||
import net.osmand.plus.mapcontextmenu.other.MapRouteInfoMenu;
|
||||
import net.osmand.plus.routing.RoutingHelper;
|
||||
import net.osmand.plus.search.QuickSearchDialogFragment;
|
||||
import net.osmand.plus.views.corenative.NativeCoreContext;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -77,6 +78,7 @@ public class MapControlsLayer extends OsmandMapLayer {
|
|||
private MapHudButton backToLocationControl;
|
||||
private MapHudButton menuControl;
|
||||
private MapHudButton compassHud;
|
||||
private MapHudButton quickSearch;
|
||||
private float cachedRotate = 0;
|
||||
private ImageView appModeIcon;
|
||||
private TextView zoomText;
|
||||
|
@ -212,6 +214,19 @@ public class MapControlsLayer extends OsmandMapLayer {
|
|||
}
|
||||
});
|
||||
|
||||
View search = mapActivity.findViewById(R.id.map_search_button);
|
||||
quickSearch = createHudButton(search, R.drawable.map_search_dark)
|
||||
.setIconsId(R.drawable.map_search_dark, R.drawable.map_search_night)
|
||||
.setIconColorId(0)
|
||||
.setBg(R.drawable.btn_inset_circle_trans, R.drawable.btn_inset_circle_night);
|
||||
controls.add(quickSearch);
|
||||
search.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
QuickSearchDialogFragment.showInstance(mapActivity, "");
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void initRouteControls() {
|
||||
|
@ -525,6 +540,7 @@ public class MapControlsLayer extends OsmandMapLayer {
|
|||
mapZoomOut.updateVisibility(!dialogOpened);
|
||||
compassHud.updateVisibility(!dialogOpened);
|
||||
layersHud.updateVisibility(!dialogOpened);
|
||||
quickSearch.updateVisibility(!dialogOpened);
|
||||
|
||||
if (!routePlanningMode && !routeFollowingMode) {
|
||||
if (mapView.isZooming()) {
|
||||
|
|
|
@ -54,11 +54,11 @@ import net.osmand.core.samples.android.sample1.MultiTouchSupport.MultiTouchZoomL
|
|||
import net.osmand.core.samples.android.sample1.adapters.SearchListAdapter;
|
||||
import net.osmand.core.samples.android.sample1.adapters.SearchListItem;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.search.example.SearchUICore;
|
||||
import net.osmand.search.example.SearchUICore.SearchResultCollection;
|
||||
import net.osmand.search.example.core.ObjectType;
|
||||
import net.osmand.search.example.core.SearchResult;
|
||||
import net.osmand.search.example.core.SearchSettings;
|
||||
import net.osmand.search.SearchUICore;
|
||||
import net.osmand.search.SearchUICore.SearchResultCollection;
|
||||
import net.osmand.search.core.ObjectType;
|
||||
import net.osmand.search.core.SearchResult;
|
||||
import net.osmand.search.core.SearchSettings;
|
||||
import net.osmand.util.MapUtils;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -99,7 +99,6 @@ public class MainActivity extends Activity {
|
|||
private SearchUICore searchUICore;
|
||||
|
||||
private EditText searchEditText;
|
||||
private TextView searchDetailsText;
|
||||
private ImageView searchIcon;
|
||||
private ProgressBar progressBar;
|
||||
|
||||
|
@ -282,7 +281,6 @@ public class MainActivity extends Activity {
|
|||
}
|
||||
});
|
||||
|
||||
searchDetailsText = (TextView) findViewById(R.id.searchDetailsText);
|
||||
searchIcon = (ImageView) findViewById(R.id.searchIcon);
|
||||
progressBar = (ProgressBar) findViewById(R.id.searchProgressBar);
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import android.widget.TextView;
|
|||
|
||||
import net.osmand.core.samples.android.sample1.R;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.search.example.core.SearchResult;
|
||||
import net.osmand.search.core.SearchResult;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.List;
|
||||
|
|
|
@ -5,13 +5,12 @@ import android.graphics.drawable.Drawable;
|
|||
import net.osmand.core.samples.android.sample1.SampleApplication;
|
||||
import net.osmand.data.Amenity;
|
||||
import net.osmand.data.City;
|
||||
import net.osmand.data.City.CityType;
|
||||
import net.osmand.data.Street;
|
||||
import net.osmand.osm.AbstractPoiType;
|
||||
import net.osmand.osm.PoiCategory;
|
||||
import net.osmand.osm.PoiFilter;
|
||||
import net.osmand.osm.PoiType;
|
||||
import net.osmand.search.example.core.SearchResult;
|
||||
import net.osmand.search.core.SearchResult;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
public class SearchListItem {
|
||||
|
@ -36,18 +35,25 @@ public class SearchListItem {
|
|||
public String getTypeName() {
|
||||
switch (searchResult.objectType) {
|
||||
case CITY:
|
||||
case VILLAGE:
|
||||
case POSTCODE:
|
||||
City city = (City) searchResult.object;
|
||||
return Algorithms.capitalizeFirstLetterAndLowercase(city.getType().toString());
|
||||
case VILLAGE:
|
||||
city = (City) searchResult.object;
|
||||
if (!Algorithms.isEmpty(searchResult.localeRelatedObjectName)) {
|
||||
return Algorithms.capitalizeFirstLetterAndLowercase(city.getType().toString())
|
||||
+ " near "
|
||||
+ searchResult.localeRelatedObjectName
|
||||
+ (searchResult.distRelatedObjectName > 0 ? " (" + SearchListAdapter.getFormattedDistance(searchResult.distRelatedObjectName) + ")" : "");
|
||||
} else {
|
||||
return Algorithms.capitalizeFirstLetterAndLowercase(city.getType().toString());
|
||||
}
|
||||
case STREET:
|
||||
Street street = (Street) searchResult.object;
|
||||
City streetCity = street.getCity();
|
||||
if (streetCity.getType() != CityType.CITY
|
||||
&& streetCity.getType() != CityType.TOWN
|
||||
&& streetCity.getType() != CityType.VILLAGE
|
||||
&& streetCity.getClosestCity() != null) {
|
||||
return streetCity.getName() + " - " + streetCity.getClosestCity().getName();
|
||||
if (!Algorithms.isEmpty(searchResult.localeRelatedObjectName)) {
|
||||
return searchResult.localeRelatedObjectName
|
||||
+ (searchResult.distRelatedObjectName > 0 ? "(" + SearchListAdapter.getFormattedDistance(searchResult.distRelatedObjectName) + ")" : "");
|
||||
} else {
|
||||
return streetCity.getName() + " - " + Algorithms.capitalizeFirstLetterAndLowercase(streetCity.getType().name());
|
||||
}
|
||||
|
|