Slightly improve poi search activity

This commit is contained in:
Victor Shcherb 2011-09-24 12:34:57 +02:00
parent ade397475a
commit 45d34de01c
11 changed files with 524 additions and 406 deletions

View file

@ -186,10 +186,9 @@ public class BinaryMapIndexReader {
}
public boolean containsPoiData(double latitude, double longitude) {
int x = MapUtils.get31TileNumberX(longitude);
int y = MapUtils.get31TileNumberY(latitude);
for (PoiRegion index : poiIndexes) {
if (index.right31X >= x && index.left31X <= x && index.top31Y <= y && index.bottom31Y >= y) {
if (index.rightLongitude >= longitude && index.leftLongitude <= longitude &&
index.topLatitude >= latitude && index.bottomLatitude <= latitude) {
return true;
}
}
@ -197,12 +196,9 @@ public class BinaryMapIndexReader {
}
public boolean containsPoiData(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude) {
int leftX = MapUtils.get31TileNumberX(leftLongitude);
int rightX = MapUtils.get31TileNumberX(rightLongitude);
int bottomY = MapUtils.get31TileNumberY(bottomLatitude);
int topY = MapUtils.get31TileNumberY(topLatitude);
for (PoiRegion index : poiIndexes) {
if (index.right31X >= leftX && index.left31X <= rightX && index.top31Y <= bottomY && index.bottom31Y >= topY) {
if (index.rightLongitude >= leftLongitude && index.leftLongitude <= rightLongitude &&
index.topLatitude >= bottomLatitude && index.bottomLatitude <= topLatitude) {
return true;
}
}
@ -1219,7 +1215,7 @@ public class BinaryMapIndexReader {
testTransportSearch(reader);
PoiRegion poiRegion = reader.getPoiIndexes().get(0);
System.out.println(poiRegion.left31X + " " + poiRegion.right31X + " " + poiRegion.bottom31Y + " " + poiRegion.top31Y);
System.out.println(poiRegion.leftLongitude + " " + poiRegion.rightLongitude + " " + poiRegion.bottomLatitude + " " + poiRegion.topLatitude);
// for (int i = 0; i < poiRegion.categories.size(); i++) {
// System.out.println(poiRegion.categories.get(i));
// System.out.println(" " + poiRegion.subcategories.get(i));
@ -1228,7 +1224,7 @@ public class BinaryMapIndexReader {
int sright = MapUtils.get31TileNumberX(37.9);
int stop = MapUtils.get31TileNumberY(55.814);
int sbottom = MapUtils.get31TileNumberY(55.81);
SearchRequest<Amenity> req = buildSearchPoiRequest(sleft, sright, stop, sbottom, 15);
SearchRequest<Amenity> req = buildSearchPoiRequest(sleft, sright, stop, sbottom, 15, -1);
req.setPoiTypeFilter(new SearchPoiTypeFilter() {
@Override
public boolean accept(AmenityType type, String subcategory) {

View file

@ -28,25 +28,25 @@ public class BinaryMapPoiReaderAdapter {
List<AmenityType> categoriesType = new ArrayList<AmenityType>();
List<List<String>> subcategories = new ArrayList<List<String>>();
int left31X;
int right31X;
int top31Y;
int bottom31Y;
double leftLongitude;
double rightLongitude;
double topLatitude;
double bottomLatitude;
public int getLeft31X() {
return left31X;
public double getLeftLongitude() {
return leftLongitude;
}
public int getRight31X() {
return right31X;
public double getRightLongitude() {
return rightLongitude;
}
public int getTop31Y() {
return top31Y;
public double getTopLatitude() {
return topLatitude;
}
public int getBottom31Y() {
return bottom31Y;
public double getBottomLatitude() {
return bottomLatitude;
}
}
@ -74,16 +74,16 @@ public class BinaryMapPoiReaderAdapter {
case 0:
return;
case OsmandOdb.OsmAndTileBox.LEFT_FIELD_NUMBER:
region.left31X = codedIS.readUInt32();
region.leftLongitude = MapUtils.get31LongitudeX(codedIS.readUInt32());
break;
case OsmandOdb.OsmAndTileBox.RIGHT_FIELD_NUMBER:
region.right31X = codedIS.readUInt32();
region.rightLongitude = MapUtils.get31LongitudeX(codedIS.readUInt32());
break;
case OsmandOdb.OsmAndTileBox.TOP_FIELD_NUMBER:
region.top31Y = codedIS.readUInt32();
region.topLatitude = MapUtils.get31LatitudeY(codedIS.readUInt32());
break;
case OsmandOdb.OsmAndTileBox.BOTTOM_FIELD_NUMBER:
region.bottom31Y = codedIS.readUInt32();
region.bottomLatitude = MapUtils.get31LatitudeY(codedIS.readUInt32());
break;
default:
skipUnknownField(t);

View file

@ -11,6 +11,7 @@
<Button android:text="@string/search_POI_level_btn"
android:id="@+id/SearchPOILevelButton" android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_weight="1"/>
<TextView android:layout_width="wrap_content" android:text="" android:id="@+id/SearchAreaText" android:layout_height="wrap_content"/>
<ProgressBar android:layout_width="wrap_content" android:text="" android:id="@+id/ProgressBar" android:layout_height="wrap_content" android:visibility="gone"/>
</LinearLayout>
<LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/SearchFilterLayout" android:visibility="gone">

View file

@ -15,7 +15,7 @@ public interface AmenityIndexRepository {
/**
* Search amenities in the specified box doesn't cache results
*/
public List<Amenity> searchAmenities(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int limit,
public List<Amenity> searchAmenities(int stop, int sleft, int sbottom, int sright, int limit,
PoiFilter filter, List<Amenity> amenities);

View file

@ -47,14 +47,9 @@ public class AmenityIndexRepositoryBinary implements AmenityIndexRepository {
}
@Override
public List<Amenity> searchAmenities(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int limit,
public List<Amenity> searchAmenities(int stop, int sleft, int sbottom, int sright, int limit,
final PoiFilter filter, final List<Amenity> amenities) {
long now = System.currentTimeMillis();
int sleft = MapUtils.get31TileNumberX(leftLongitude);
int sright = MapUtils.get31TileNumberX(rightLongitude);
int sbottom = MapUtils.get31TileNumberY(bottomLatitude);
int stop = MapUtils.get31TileNumberY(topLatitude);
SearchRequest<Amenity> req = BinaryMapIndexReader.buildSearchPoiRequest(sleft, sright, stop, sbottom, limit, 16);
req.setPoiTypeFilter(new SearchPoiTypeFilter(){
@Override
@ -75,7 +70,7 @@ public class AmenityIndexRepositoryBinary implements AmenityIndexRepository {
}
if (log.isDebugEnabled()) {
log.debug(String.format("Search for %s done in %s ms found %s.", //$NON-NLS-1$
topLatitude + " " + leftLongitude, System.currentTimeMillis() - now, amenities.size())); //$NON-NLS-1$
MapUtils.get31LatitudeY(stop) + " " + MapUtils.get31LongitudeX(sleft), System.currentTimeMillis() - now, amenities.size())); //$NON-NLS-1$
}
return amenities;
}
@ -132,7 +127,11 @@ public class AmenityIndexRepositoryBinary implements AmenityIndexRepository {
cZoom = zoom;
// first of all put all entities in temp list in order to not freeze other read threads
ArrayList<Amenity> tempList = new ArrayList<Amenity>();
searchAmenities(cTopLatitude, cLeftLongitude, cBottomLatitude, cRightLongitude, limitPoi, filter, tempList);
int sleft = MapUtils.get31TileNumberX(cLeftLongitude);
int sright = MapUtils.get31TileNumberX(cRightLongitude);
int sbottom = MapUtils.get31TileNumberY(cBottomLatitude);
int stop = MapUtils.get31TileNumberY(cTopLatitude);
searchAmenities(stop, sleft, sbottom, sright, limitPoi, filter, tempList);
synchronized (this) {
cachedObjects.clear();
cachedObjects.addAll(tempList);

View file

@ -41,7 +41,7 @@ public class AmenityIndexRepositoryOdb extends BaseLocationIndexRepository<Ameni
private final String[] columns = new String[]{"id", "x", "y", "name", "name_en", "type", "subtype", "opening_hours", "phone", "site"}; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$//$NON-NLS-5$//$NON-NLS-6$//$NON-NLS-7$//$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
public List<Amenity> searchAmenities(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int limit, PoiFilter filter, List<Amenity> amenities){
public List<Amenity> searchAmenities(int stop, int sleft, int sbottom, int sright, int limit, PoiFilter filter, List<Amenity> amenities){
long now = System.currentTimeMillis();
String squery = "? < y AND y < ? AND ? < x AND x < ?"; //$NON-NLS-1$
@ -55,9 +55,9 @@ public class AmenityIndexRepositoryOdb extends BaseLocationIndexRepository<Ameni
squery += " ORDER BY RANDOM() LIMIT " +limit; //$NON-NLS-1$
}
Cursor query = db.query(IndexConstants.POI_TABLE, columns, squery,
new String[]{MapUtils.get31TileNumberY(topLatitude)+"", //$NON-NLS-1$
MapUtils.get31TileNumberY(bottomLatitude)+"", MapUtils.get31TileNumberX(leftLongitude)+"", //$NON-NLS-1$ //$NON-NLS-2$
MapUtils.get31TileNumberX(rightLongitude)+""}, null, null, null); //$NON-NLS-1$
new String[]{stop+"", //$NON-NLS-1$
sbottom+"", sleft+"", //$NON-NLS-1$ //$NON-NLS-2$
sright+""}, null, null, null); //$NON-NLS-1$
if(query.moveToFirst()){
do {
Amenity am = new Amenity();
@ -84,7 +84,7 @@ public class AmenityIndexRepositoryOdb extends BaseLocationIndexRepository<Ameni
if (log.isDebugEnabled()) {
log.debug(String.format("Search for %s done in %s ms found %s.", //$NON-NLS-1$
topLatitude + " " + leftLongitude, System.currentTimeMillis() - now, amenities.size())); //$NON-NLS-1$
MapUtils.get31LatitudeY(stop) + " " + MapUtils.get31LongitudeX(sleft), System.currentTimeMillis() - now, amenities.size())); //$NON-NLS-1$
}
return amenities;
}
@ -135,7 +135,11 @@ public class AmenityIndexRepositoryOdb extends BaseLocationIndexRepository<Ameni
cZoom = zoom;
// first of all put all entities in temp list in order to not freeze other read threads
ArrayList<Amenity> tempList = new ArrayList<Amenity>();
searchAmenities(cTopLatitude, cLeftLongitude, cBottomLatitude, cRightLongitude, limit, filter, tempList);
int sleft = MapUtils.get31TileNumberX(cLeftLongitude);
int sright = MapUtils.get31TileNumberX(cRightLongitude);
int sbottom = MapUtils.get31TileNumberY(cBottomLatitude);
int stop = MapUtils.get31TileNumberY(cTopLatitude);
searchAmenities(stop, sleft, sbottom, sright, limit, filter, tempList);
synchronized (this) {
cachedObjects.clear();
cachedObjects.addAll(tempList);

View file

@ -75,7 +75,7 @@ public class PoiFilter {
public List<Amenity> searchFurther(double latitude, double longitude){
zoom --;
List<Amenity> amenityList = application.getResourceManager().searchAmenities(this, latitude, longitude, zoom, -1);
List<Amenity> amenityList = searchAmenities(this, latitude, longitude, zoom, -1);
MapUtils.sortListOfMapObject(amenityList, latitude, longitude);
return amenityList;
@ -104,17 +104,29 @@ public class PoiFilter {
public List<Amenity> initializeNewSearch(double lat, double lon, int firstTimeLimit){
zoom = getInitialZoom();
List<Amenity> amenityList = application.getResourceManager().searchAmenities(this, lat, lon, zoom, -1);
List<Amenity> amenityList = searchAmenities(this, lat, lon, zoom, -1);
MapUtils.sortListOfMapObject(amenityList, lat, lon);
while (amenityList.size() > firstTimeLimit) {
amenityList.remove(amenityList.size() - 1);
if (firstTimeLimit > 0) {
while (amenityList.size() > firstTimeLimit) {
amenityList.remove(amenityList.size() - 1);
}
}
return amenityList;
}
private List<Amenity> searchAmenities(PoiFilter poiFilter, double lat, double lon, int z, int limit) {
double tileNumberX = MapUtils.getTileNumberX(zoom, lon);
double tileNumberY = MapUtils.getTileNumberY(zoom, lat);
double topLatitude = MapUtils.getLatitudeFromTile(zoom, tileNumberY - 0.5);
double bottomLatitude = MapUtils.getLatitudeFromTile(zoom, tileNumberY + 0.5);
double leftLongitude = MapUtils.getLongitudeFromTile(zoom, tileNumberX - 0.5);
double rightLongitude = MapUtils.getLongitudeFromTile(zoom, tileNumberX + 0.5);
return application.getResourceManager().searchAmenities(poiFilter,
topLatitude, leftLongitude, bottomLatitude, rightLongitude, lat, lon, z, limit);
}
public List<Amenity> searchAgain(double lat, double lon){
List<Amenity> amenityList = application.getResourceManager().searchAmenities(this, lat, lon, zoom, -1);
List<Amenity> amenityList = searchAmenities(this, lat, lon, zoom, -1);
MapUtils.sortListOfMapObject(amenityList, lat, lon);
return amenityList;
}

View file

@ -551,20 +551,15 @@ public class ResourceManager {
return repos;
}
public List<Amenity> searchAmenities(PoiFilter filter, double latitude, double longitude, int zoom, int limit) {
double tileNumberX = MapUtils.getTileNumberX(zoom, longitude);
double tileNumberY = MapUtils.getTileNumberY(zoom, latitude);
double topLatitude = MapUtils.getLatitudeFromTile(zoom, tileNumberY - 0.5);
double bottomLatitude = MapUtils.getLatitudeFromTile(zoom, tileNumberY + 0.5);
double leftLongitude = MapUtils.getLongitudeFromTile(zoom, tileNumberX - 0.5);
double rightLongitude = MapUtils.getLongitudeFromTile(zoom, tileNumberX + 0.5);
public List<Amenity> searchAmenities(PoiFilter filter,
double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude,
double lat, double lon, int zoom, int limit) {
List<Amenity> amenities = new ArrayList<Amenity>();
for (AmenityIndexRepository index : amenityRepositories) {
if (index.checkContains(topLatitude, leftLongitude, bottomLatitude, rightLongitude)) {
if (!index.checkCachedAmenities(topLatitude, leftLongitude, bottomLatitude, rightLongitude, zoom, filter.getFilterId(),
amenities, false)) {
index.searchAmenities(topLatitude, leftLongitude, bottomLatitude, rightLongitude, limit, filter, amenities);
}
index.searchAmenities(MapUtils.get31TileNumberY(topLatitude), MapUtils.get31TileNumberX(leftLongitude),
MapUtils.get31TileNumberY(bottomLatitude), MapUtils.get31TileNumberX(rightLongitude),
limit, filter, amenities);
}
}

View file

@ -336,6 +336,10 @@ public class LocalIndexHelper {
double b = MapUtils.get31LatitudeY(bottom);
return format.format(new Object[] { l, t, r, b });
}
private String formatLatLonBox(double l, double r, double t, double b) {
return format.format(new Object[] { l, t, r, b });
}
private void updateObfFileInformation(LocalIndexInfo info, File mapFile) {
try {
@ -359,7 +363,8 @@ public class LocalIndexHelper {
PoiRegion mi = ((PoiRegion) part);
builder.append(app.getString(R.string.local_index_poi_data)).append(": ").
append(mi.getName()).append("\n");
String box = formatLatLonBox(mi.getLeft31X(), mi.getRight31X(), mi.getTop31Y(), mi.getBottom31Y());
String box = formatLatLonBox(mi.getLeftLongitude(), mi.getRightLongitude(),
mi.getTopLatitude(), mi.getBottomLatitude());
builder.append(box).append("\n");
} else if(part instanceof TransportIndex){
TransportIndex mi = ((TransportIndex) part);

View file

@ -1201,7 +1201,9 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
Message msg = Message.obtain(uiHandler, new Runnable() {
@Override
public void run() {
backToLocationImpl();
if (settings.MAP_ACTIVITY_ENABLED.get()) {
backToLocationImpl();
}
}
});
msg.what = AUTO_FOLLOW_MSG_ID;

View file

@ -6,6 +6,7 @@ package net.osmand.plus.activities.search;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import net.osmand.Algoritms;
@ -40,10 +41,12 @@ import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.AsyncTask.Status;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
@ -88,7 +91,6 @@ public class SearchPOIActivity extends ListActivity implements SensorEventListen
private boolean searchNearBy = false;
private Location location = null;
private Location searchedLocation = null;
private Float heading = null;
private String currentLocationProvider = null;
@ -96,6 +98,8 @@ public class SearchPOIActivity extends ListActivity implements SensorEventListen
private Handler uiHandler;
private OsmandSettings settings;
// never null represents current running task or last finished
private SearchAmenityTask currentSearchTask = new SearchAmenityTask(null);
@Override
@ -103,9 +107,6 @@ public class SearchPOIActivity extends ListActivity implements SensorEventListen
super.onCreate(icicle);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setContentView(R.layout.searchpoi);
Bundle bundle = this.getIntent().getExtras();
String filterId = bundle.getString(AMENITY_FILTER);
filter = ((OsmandApplication)getApplication()).getPoiFilters().getFilterById(filterId);
uiHandler = new Handler();
searchPOILevel = (Button) findViewById(R.id.SearchPOILevelButton);
@ -120,29 +121,15 @@ public class SearchPOIActivity extends ListActivity implements SensorEventListen
searchPOILevel.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(isNameFinderFilter()){
String query = searchFilter.getText().toString();
if(query.length() == 0){
Toast.makeText(SearchPOIActivity.this, R.string.poi_namefinder_query_empty, Toast.LENGTH_LONG).show();
return;
}
String res = ((NameFinderPoiFilter) filter).searchOnline(location.getLatitude(), location.getLongitude(), query);
if(res != null){
Toast.makeText(SearchPOIActivity.this, res, Toast.LENGTH_LONG).show();
}
amenityAdapter.setNewModel(((NameFinderPoiFilter) filter).getSearchedAmenities(), "");
showOnMap.setEnabled(amenityAdapter.getCount() > 0);
} else {
amenityAdapter.setNewModel(filter.searchFurther(location.getLatitude(), location.getLongitude()), searchFilter.getText().toString());
String query = searchFilter.getText().toString();
if (query.length() == 0 && isNameFinderFilter()) {
Toast.makeText(SearchPOIActivity.this, R.string.poi_namefinder_query_empty, Toast.LENGTH_LONG).show();
return;
}
searchedLocation = location;
searchArea.setText(filter.getSearchArea());
searchPOILevel.setEnabled(filter.isSearchFurtherAvailable());
runNewSearchQuery(SearchAmenityRequest.buildRequest(location, SearchAmenityRequest.SEARCH_FURTHER, query));
}
});
showFilter.setVisibility(isNameFinderFilter() ? View.GONE : View.VISIBLE);
showFilter.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
@ -155,18 +142,13 @@ public class SearchPOIActivity extends ListActivity implements SensorEventListen
}
});
if(isNameFinderFilter()){
searchFilterLayout.setVisibility(View.VISIBLE);
}
searchFilter.addTextChangedListener(new TextWatcher(){
@Override
public void afterTextChanged(Editable s) {
if(!isNameFinderFilter()){
amenityAdapter.getFilter().filter(s);
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@ -174,10 +156,39 @@ public class SearchPOIActivity extends ListActivity implements SensorEventListen
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
});
showOnMap.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
settings.setPoiFilterForMap(filter.getFilterId());
settings.SHOW_POI_OVER_MAP.set(true);
if(location != null){
settings.setMapLocationToShow(location.getLatitude(), location.getLongitude(), 15);
}
MapActivity.launchMapActivityMoveToTop(SearchPOIActivity.this);
}
});
amenityAdapter = new AmenityAdapter(new ArrayList<Amenity>());
setListAdapter(amenityAdapter);
// ListActivity has a ListView, which you can get with:
ListView lv = getListView();
lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> av, View v, int pos, long id) {
final Amenity amenity = ((AmenityAdapter) getListAdapter()).getItem(pos);
onLongClick(amenity);
return true;
}
});
}
@Override
protected void onResume() {
super.onResume();
Bundle bundle = this.getIntent().getExtras();
if(bundle.containsKey(SEARCH_LAT) && bundle.containsKey(SEARCH_LON)){
location = new Location("internal"); //$NON-NLS-1$
location.setLatitude(bundle.getDouble(SEARCH_LAT));
@ -188,116 +199,150 @@ public class SearchPOIActivity extends ListActivity implements SensorEventListen
searchNearBy = true;
}
String filterId = bundle.getString(AMENITY_FILTER);
PoiFilter filter = ((OsmandApplication)getApplication()).getPoiFilters().getFilterById(filterId);
if (filter != this.filter) {
this.filter = filter;
if (filter != null) {
filter.clearPreviousZoom();
} else {
amenityAdapter.setNewModel(Collections.<Amenity> emptyList(), "");
searchPOILevel.setText(R.string.search_POI_level_btn);
searchPOILevel.setEnabled(false);
}
// run query again
clearSearchQuery();
}
if(isNameFinderFilter()){
showOnMap.setEnabled(false);
showFilter.setVisibility(View.GONE);
searchFilterLayout.setVisibility(View.VISIBLE);
} else {
showFilter.setVisibility(View.VISIBLE);
showOnMap.setEnabled(filter != null);
}
showOnMap.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
settings.setPoiFilterForMap(filter.getFilterId());
settings.SHOW_POI_OVER_MAP.set(true);
if(/*searchNearBy && */location != null){
settings.setMapLocationToShow(location.getLatitude(), location.getLongitude(), 15);
}
MapActivity.launchMapActivityMoveToTop(SearchPOIActivity.this);
}
});
if (filter != null) {
amenityAdapter = new AmenityAdapter(new ArrayList<Amenity>());
if(location == null){
filter.clearPreviousZoom();
} else if(!isNameFinderFilter()) {
searchedLocation = location;
amenityAdapter.setNewModel(filter.initializeNewSearch(location.getLatitude(), location.getLongitude(), 40), "");
}
setListAdapter(amenityAdapter);
searchPOILevel.setEnabled(filter.isSearchFurtherAvailable());
searchArea.setText(filter.getSearchArea());
} else {
searchPOILevel.setEnabled(false);
}
// ListActivity has a ListView, which you can get with:
ListView lv = getListView();
lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> av, View v, int pos, long id) {
final Amenity amenity = ((AmenityAdapter) getListAdapter()).getItem(pos);
String format = OsmAndFormatter.getPoiSimpleFormat(amenity, SearchPOIActivity.this, settings.USE_ENGLISH_NAMES.get());
if (amenity.getOpeningHours() != null) {
format += " "+getString(R.string.opening_hours) + " : " + amenity.getOpeningHours(); //$NON-NLS-1$ //$NON-NLS-2$
updateSearchPoiTextButton();
setLocation(location);
if (searchNearBy) {
LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE);
service.requestLocationUpdates(LocationManager.GPS_PROVIDER, GPS_TIMEOUT_REQUEST, GPS_DIST_REQUEST, gpsListener);
currentLocationProvider = LocationManager.GPS_PROVIDER;
if (!isRunningOnEmulator()) {
// try to always ask for network provide it is faster way to find location
service.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, GPS_TIMEOUT_REQUEST, GPS_DIST_REQUEST,
networkListener);
currentLocationProvider = LocationManager.NETWORK_PROVIDER;
}
// Toast.makeText(v.getContext(), format, Toast.LENGTH_LONG).show();
AlertDialog.Builder builder = new AlertDialog.Builder(SearchPOIActivity.this);
builder.setTitle(format);
builder.setItems(new String[]{getString(R.string.show_poi_on_map), getString(R.string.navigate_to)}, new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
if(which == 0){
int z = settings.getLastKnownMapZoom();
String poiSimpleFormat = OsmAndFormatter.getPoiSimpleFormat(amenity, SearchPOIActivity.this, settings.usingEnglishNames());
settings.setMapLocationToShow(
amenity.getLocation().getLatitude(), amenity.getLocation().getLongitude(),
Math.max(16, z), getString(R.string.poi)+" : " + poiSimpleFormat); //$NON-NLS-1$
} else if(which == 1){
LatLon l = amenity.getLocation();
String poiSimpleFormat = OsmAndFormatter.getPoiSimpleFormat(amenity, SearchPOIActivity.this, settings.usingEnglishNames());
settings.setPointToNavigate(l.getLatitude(), l.getLongitude(), getString(R.string.poi)+" : " + poiSimpleFormat);
}
if(filter != null){
settings.setPoiFilterForMap(filter.getFilterId());
settings.SHOW_POI_OVER_MAP.set(true);
}
MapActivity.launchMapActivityMoveToTop(SearchPOIActivity.this);
}
});
builder.show();
return true;
}
});
}
}
private void updateSearchPoiTextButton(){
if(location == null){
searchPOILevel.setText(R.string.search_poi_location);
searchPOILevel.setEnabled(false);
} else if (!isNameFinderFilter()) {
searchPOILevel.setText(R.string.search_POI_level_btn);
searchPOILevel.setEnabled(currentSearchTask.getStatus() != Status.RUNNING &&
filter.isSearchFurtherAvailable());
} else {
searchPOILevel.setText(R.string.search_button);
searchPOILevel.setEnabled(currentSearchTask.getStatus() != Status.RUNNING &&
filter.isSearchFurtherAvailable());
}
}
public void setLocation(Location l){
registerUnregisterSensor(l);
boolean handled = false;
if (l != null && filter != null) {
if (location == null) {
searchedLocation = l;
Location searchedLocation = getSearchedLocation();
if (searchedLocation == null) {
searchedLocation = l;
if (!isNameFinderFilter()) {
amenityAdapter.setNewModel(filter.searchAgain(l.getLatitude(), l.getLongitude()), searchFilter.getText().toString());
searchPOILevel.setText(R.string.search_POI_level_btn);
} else {
searchPOILevel.setText(R.string.search_button);
runNewSearchQuery(SearchAmenityRequest.buildRequest(l, SearchAmenityRequest.NEW_SEARCH_INIT,
searchFilter.getText().toString()));
}
searchPOILevel.setEnabled(filter.isSearchFurtherAvailable());
searchArea.setText(filter.getSearchArea());
handled = true;
} else if (searchedLocation != null && l.distanceTo(searchedLocation) > MIN_DISTANCE_TO_RESEARCH) {
amenityAdapter.setNewModel(filter.searchAgain(l.getLatitude(), l.getLongitude()), searchFilter.getText().toString());
} else if (l.distanceTo(searchedLocation) > MIN_DISTANCE_TO_RESEARCH) {
runNewSearchQuery(SearchAmenityRequest.buildRequest(l, SearchAmenityRequest.SEARCH_AGAIN, searchFilter.getText().toString()));
handled = true;
} else if(location.distanceTo(l) > MIN_DISTANCE_TO_UPDATE){
} else if(location == null || location.distanceTo(l) > MIN_DISTANCE_TO_UPDATE){
handled = true;
}
} else {
if(location != null){
searchPOILevel.setText(R.string.search_poi_location);
searchPOILevel.setEnabled(false);
handled = true;
}
}
if(handled) {
updateSearchPoiTextButton();
location = l;
amenityAdapter.notifyDataSetChanged();
amenityAdapter.notifyDataSetInvalidated();
}
}
private Location getSearchedLocation(){
return currentSearchTask.getSearchedLocation();
}
private synchronized void runNewSearchQuery(SearchAmenityRequest request){
if(currentSearchTask.getStatus() == Status.FINISHED ||
currentSearchTask.getSearchedLocation() == null){
currentSearchTask = new SearchAmenityTask(request);
currentSearchTask.execute();
}
}
private synchronized void clearSearchQuery(){
if(currentSearchTask.getStatus() == Status.FINISHED ||
currentSearchTask.getSearchedLocation() == null){
currentSearchTask = new SearchAmenityTask(null);
}
}
private void onLongClick(final Amenity amenity) {
String format = OsmAndFormatter.getPoiSimpleFormat(amenity, SearchPOIActivity.this, settings.USE_ENGLISH_NAMES.get());
if (amenity.getOpeningHours() != null) {
Toast.makeText(this, format + " " + getString(R.string.opening_hours) + " : " + amenity.getOpeningHours(), Toast.LENGTH_LONG)
.show();
}
AlertDialog.Builder builder = new AlertDialog.Builder(SearchPOIActivity.this);
builder.setTitle(format);
builder.setItems(new String[]{getString(R.string.show_poi_on_map), getString(R.string.navigate_to)}, new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
if(which == 0){
int z = settings.getLastKnownMapZoom();
String poiSimpleFormat = OsmAndFormatter.getPoiSimpleFormat(amenity, SearchPOIActivity.this, settings.usingEnglishNames());
settings.setMapLocationToShow(
amenity.getLocation().getLatitude(), amenity.getLocation().getLongitude(),
Math.max(16, z), getString(R.string.poi)+" : " + poiSimpleFormat); //$NON-NLS-1$
} else if(which == 1){
LatLon l = amenity.getLocation();
String poiSimpleFormat = OsmAndFormatter.getPoiSimpleFormat(amenity, SearchPOIActivity.this, settings.usingEnglishNames());
settings.setPointToNavigate(l.getLatitude(), l.getLongitude(), getString(R.string.poi)+" : " + poiSimpleFormat);
}
if(filter != null){
settings.setPoiFilterForMap(filter.getFilterId());
settings.SHOW_POI_OVER_MAP.set(true);
}
MapActivity.launchMapActivityMoveToTop(SearchPOIActivity.this);
}
});
builder.show();
}
private boolean isRunningOnEmulator(){
@ -312,6 +357,298 @@ public class SearchPOIActivity extends ListActivity implements SensorEventListen
}
@Override
public void onSensorChanged(SensorEvent event) {
// Attention : sensor produces a lot of events & can hang the system
if(heading != null && Math.abs(heading - event.values[0]) < 4){
// this is very small variation
return;
}
heading = event.values[0];
if(!uiHandler.hasMessages(5)){
Message msg = Message.obtain(uiHandler, new Runnable(){
@Override
public void run() {
amenityAdapter.notifyDataSetChanged();
}
});
msg.what = 5;
uiHandler.sendMessageDelayed(msg, 100);
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
private void registerUnregisterSensor(Location location){
// show point view only if gps enabled
if(location == null){
if(sensorRegistered) {
Log.d(LogUtil.TAG, "Disable sensor"); //$NON-NLS-1$
((SensorManager) getSystemService(SENSOR_SERVICE)).unregisterListener(this);
sensorRegistered = false;
heading = null;
}
} else {
if(!sensorRegistered){
Log.d(LogUtil.TAG, "Enable sensor"); //$NON-NLS-1$
SensorManager sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);
Sensor s = sensorMgr.getDefaultSensor(Sensor.TYPE_ORIENTATION);
if (s != null) {
sensorMgr.registerListener(this, s, SensorManager.SENSOR_DELAY_UI);
}
sensorRegistered = true;
}
}
}
@Override
protected void onPause() {
super.onPause();
if (searchNearBy) {
LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE);
service.removeUpdates(gpsListener);
service.removeUpdates(networkListener);
SensorManager sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);
sensorMgr.unregisterListener(this);
sensorRegistered = false;
currentLocationProvider = null;
}
}
public void onListItemClick(ListView parent, View v, int position, long id) {
if(filter != null){
settings.setPoiFilterForMap(filter.getFilterId());
settings.SHOW_POI_OVER_MAP.set(true);
}
int z = settings.getLastKnownMapZoom();
Amenity amenity = ((AmenityAdapter) getListAdapter()).getItem(position);
String poiSimpleFormat = OsmAndFormatter.getPoiSimpleFormat(amenity, this, settings.usingEnglishNames());
settings.setMapLocationToShow( amenity.getLocation().getLatitude(), amenity.getLocation().getLongitude(),
Math.max(16, z), getString(R.string.poi)+" : " + poiSimpleFormat); //$NON-NLS-1$
MapActivity.launchMapActivityMoveToTop(SearchPOIActivity.this);
}
static class SearchAmenityRequest {
private static final int SEARCH_AGAIN = 1;
private static final int NEW_SEARCH_INIT = 2;
private static final int SEARCH_FURTHER = 3;
private int type;
private String filter;
private Location location;
public static SearchAmenityRequest buildRequest(Location l, int type, String filter){
SearchAmenityRequest req = new SearchAmenityRequest();
req.type = type;
req.location = l;
req.filter = filter;
return req;
}
}
class SearchAmenityTask extends AsyncTask<Void, String, List<Amenity>> {
private SearchAmenityRequest request;
public SearchAmenityTask(SearchAmenityRequest request){
this.request = request;
}
Location getSearchedLocation(){
return request != null ? request.location : null;
}
@Override
protected void onPreExecute() {
findViewById(R.id.ProgressBar).setVisibility(View.VISIBLE);
findViewById(R.id.SearchAreaText).setVisibility(View.GONE);
searchPOILevel.setEnabled(false);
}
@Override
protected void onPostExecute(List<Amenity> result) {
findViewById(R.id.ProgressBar).setVisibility(View.GONE);
findViewById(R.id.SearchAreaText).setVisibility(View.VISIBLE);
searchPOILevel.setEnabled(filter.isSearchFurtherAvailable());
if(filter instanceof NameFinderPoiFilter){
amenityAdapter.setNewModel(result, "");
showOnMap.setEnabled(amenityAdapter.getCount() > 0);
} else {
amenityAdapter.setNewModel(result, searchFilter.getText().toString());
}
searchArea.setText(filter.getSearchArea());
}
@Override
protected List<Amenity> doInBackground(Void... params) {
if (request.location != null) {
if(filter instanceof NameFinderPoiFilter){
final String message = ((NameFinderPoiFilter) filter).
searchOnline(request.location.getLatitude(), request.location.getLongitude(), request.filter);
if(message != null){
uiHandler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(SearchPOIActivity.this, message, Toast.LENGTH_LONG).show();
}
});
}
return filter.searchAgain(request.location.getLatitude(), request.location.getLongitude());
} else {
if (request.type == SearchAmenityRequest.NEW_SEARCH_INIT) {
return filter.initializeNewSearch(request.location.getLatitude(), request.location.getLongitude(), -1);
} else if (request.type == SearchAmenityRequest.SEARCH_FURTHER) {
return filter.searchFurther(request.location.getLatitude(), request.location.getLongitude());
} else if (request.type == SearchAmenityRequest.SEARCH_AGAIN) {
return filter.searchAgain(request.location.getLatitude(), request.location.getLongitude());
}
}
}
return Collections.emptyList();
}
}
class AmenityAdapter extends ArrayAdapter<Amenity> {
private AmenityFilter listFilter;
private List<Amenity> originalAmenityList;
AmenityAdapter(List<Amenity> list) {
super(SearchPOIActivity.this, R.layout.searchpoi_list, list);
originalAmenityList = new ArrayList<Amenity>(list);
this.setNotifyOnChange(false);
}
public void setNewModel(List<Amenity> amenityList, String filter) {
setNotifyOnChange(false);
originalAmenityList = new ArrayList<Amenity>(amenityList);
clear();
for (Amenity obj : amenityList) {
add(obj);
}
getFilter().filter(filter);
setNotifyOnChange(true);
this.notifyDataSetChanged();
}
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null) {
LayoutInflater inflater = getLayoutInflater();
row = inflater.inflate(R.layout.searchpoi_list, parent, false);
}
float[] mes = null;
TextView label = (TextView) row.findViewById(R.id.poi_label);
TextView distanceLabel = (TextView) row.findViewById(R.id.poidistance_label);
ImageView icon = (ImageView) row.findViewById(R.id.poi_icon);
Amenity amenity = getItem(position);
Location loc = location;
if(loc != null){
mes = new float[2];
LatLon l = amenity.getLocation();
Location.distanceBetween(l.getLatitude(), l.getLongitude(), loc.getLatitude(), loc.getLongitude(), mes);
}
String str = OsmAndFormatter.getPoiStringWithoutType(amenity, settings.usingEnglishNames());
label.setText(str);
int opened = -1;
if (amenity.getOpeningHours() != null) {
List<OpeningHoursRule> rs = OpeningHoursParser.parseOpenedHours(amenity.getOpeningHours());
if (rs != null) {
Calendar inst = Calendar.getInstance();
inst.setTimeInMillis(System.currentTimeMillis());
boolean work = false;
for (OpeningHoursRule p : rs) {
if (p.isOpenedForTime(inst)) {
work = true;
break;
}
}
if (work) {
opened = 0;
} else {
opened = 1;
}
}
}
if(loc != null){
DirectionDrawable draw = new DirectionDrawable();
Float h = heading;
float a = h != null ? h : 0;
draw.setAngle(mes[1] - a + 180);
draw.setOpenedColor(opened);
icon.setImageDrawable(draw);
} else {
if(opened == -1){
icon.setImageResource(R.drawable.poi);
} else if(opened == 0){
icon.setImageResource(R.drawable.opened_poi);
} else {
icon.setImageResource(R.drawable.closed_poi);
}
}
if(mes == null){
distanceLabel.setText(""); //$NON-NLS-1$
} else {
distanceLabel.setText(" " + OsmAndFormatter.getFormattedDistance((int) mes[0], SearchPOIActivity.this)); //$NON-NLS-1$
}
return (row);
}
@Override
public Filter getFilter() {
if (listFilter == null) {
listFilter = new AmenityFilter();
}
return listFilter;
}
private final class AmenityFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (constraint == null || constraint.length() == 0) {
results.values = originalAmenityList;
results.count = originalAmenityList.size();
} else {
String lowerCase = constraint.toString()
.toLowerCase();
List<Amenity> filter = new ArrayList<Amenity>();
for (Amenity item : originalAmenityList) {
String lower = OsmAndFormatter.getPoiStringWithoutType(item, settings.usingEnglishNames()).toLowerCase();
if(lower.indexOf(lowerCase) != -1){
filter.add(item);
}
}
results.values = filter;
results.count = filter.size();
}
return results;
}
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
clear();
for (Amenity item : (Collection<Amenity>) results.values) {
add(item);
}
}
}
}
// Working with location listeners
private LocationListener networkListener = new LocationListener(){
@Override
@ -373,112 +710,7 @@ public class SearchPOIActivity extends ListActivity implements SensorEventListen
}
};
@Override
public void onSensorChanged(SensorEvent event) {
// Attention : sensor produces a lot of events & can hang the system
if(heading != null && Math.abs(heading - event.values[0]) < 4){
// this is very small variation
return;
}
heading = event.values[0];
if(!uiHandler.hasMessages(5)){
Message msg = Message.obtain(uiHandler, new Runnable(){
@Override
public void run() {
amenityAdapter.notifyDataSetChanged();
}
});
msg.what = 5;
uiHandler.sendMessageDelayed(msg, 100);
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
@Override
protected void onResume() {
super.onResume();
if(searchNearBy){
location = null;
amenityAdapter.notifyDataSetChanged();
searchPOILevel.setEnabled(false);
} else {
setLocation(location);
}
if(searchNearBy && location == null){
searchPOILevel.setText(R.string.search_poi_location);
} else if(isNameFinderFilter()){
searchPOILevel.setText(R.string.search_button);
} else {
searchPOILevel.setText(R.string.search_POI_level_btn);
}
if (searchNearBy) {
LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE);
service.requestLocationUpdates(LocationManager.GPS_PROVIDER, GPS_TIMEOUT_REQUEST, GPS_DIST_REQUEST, gpsListener);
currentLocationProvider = LocationManager.GPS_PROVIDER;
if(!isRunningOnEmulator()){
// try to always ask for network provide it is faster way to find location
service.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, GPS_TIMEOUT_REQUEST, GPS_DIST_REQUEST, networkListener);
currentLocationProvider = LocationManager.NETWORK_PROVIDER;
}
}
}
private void registerUnregisterSensor(Location location){
// show point view only if gps enabled
if(location == null){
if(sensorRegistered) {
Log.d(LogUtil.TAG, "Disable sensor"); //$NON-NLS-1$
((SensorManager) getSystemService(SENSOR_SERVICE)).unregisterListener(this);
sensorRegistered = false;
heading = null;
}
} else {
if(!sensorRegistered){
Log.d(LogUtil.TAG, "Enable sensor"); //$NON-NLS-1$
SensorManager sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);
Sensor s = sensorMgr.getDefaultSensor(Sensor.TYPE_ORIENTATION);
if (s != null) {
sensorMgr.registerListener(this, s, SensorManager.SENSOR_DELAY_UI);
}
sensorRegistered = true;
}
}
}
@Override
protected void onPause() {
super.onPause();
if (searchNearBy) {
LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE);
service.removeUpdates(gpsListener);
service.removeUpdates(networkListener);
SensorManager sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);
sensorMgr.unregisterListener(this);
sensorRegistered = false;
currentLocationProvider = null;
}
}
public void onListItemClick(ListView parent, View v, int position, long id) {
if(filter != null){
settings.setPoiFilterForMap(filter.getFilterId());
settings.SHOW_POI_OVER_MAP.set(true);
}
int z = settings.getLastKnownMapZoom();
Amenity amenity = ((AmenityAdapter) getListAdapter()).getItem(position);
String poiSimpleFormat = OsmAndFormatter.getPoiSimpleFormat(amenity, this, settings.usingEnglishNames());
settings.setMapLocationToShow( amenity.getLocation().getLatitude(), amenity.getLocation().getLongitude(),
Math.max(16, z), getString(R.string.poi)+" : " + poiSimpleFormat); //$NON-NLS-1$
MapActivity.launchMapActivityMoveToTop(SearchPOIActivity.this);
}
class DirectionDrawable extends Drawable {
static class DirectionDrawable extends Drawable {
Paint paintRouteDirection;
Path path = new Path();
private float angle;
@ -544,133 +776,5 @@ public class SearchPOIActivity extends ListActivity implements SensorEventListen
public void setColorFilter(ColorFilter cf) {
paintRouteDirection.setColorFilter(cf);
}
}
class AmenityAdapter extends ArrayAdapter<Amenity> {
private AmenityFilter filter;
private List<Amenity> originalAmenityList;
AmenityAdapter(List<Amenity> list) {
super(SearchPOIActivity.this, R.layout.searchpoi_list, list);
originalAmenityList = new ArrayList<Amenity>(list);
this.setNotifyOnChange(false);
}
public void setNewModel(List<Amenity> amenityList, String filter) {
setNotifyOnChange(false);
originalAmenityList = new ArrayList<Amenity>(amenityList);
clear();
for (Amenity obj : amenityList) {
add(obj);
}
getFilter().filter(filter);
setNotifyOnChange(true);
this.notifyDataSetChanged();
}
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null) {
LayoutInflater inflater = getLayoutInflater();
row = inflater.inflate(R.layout.searchpoi_list, parent, false);
}
float[] mes = null;
TextView label = (TextView) row.findViewById(R.id.poi_label);
TextView distanceLabel = (TextView) row.findViewById(R.id.poidistance_label);
ImageView icon = (ImageView) row.findViewById(R.id.poi_icon);
Amenity amenity = getItem(position);
if(location != null){
mes = new float[2];
LatLon l = amenity.getLocation();
Location.distanceBetween(l.getLatitude(), l.getLongitude(), location.getLatitude(), location.getLongitude(), mes);
}
String str = OsmAndFormatter.getPoiStringWithoutType(amenity, settings.usingEnglishNames());
label.setText(str);
int opened = -1;
if (amenity.getOpeningHours() != null) {
List<OpeningHoursRule> rs = OpeningHoursParser.parseOpenedHours(amenity.getOpeningHours());
if (rs != null) {
Calendar inst = Calendar.getInstance();
inst.setTimeInMillis(System.currentTimeMillis());
boolean work = false;
for (OpeningHoursRule p : rs) {
if (p.isOpenedForTime(inst)) {
work = true;
break;
}
}
if (work) {
opened = 0;
} else {
opened = 1;
}
}
}
if(location != null){
DirectionDrawable draw = new DirectionDrawable();
float a = heading != null ? heading : 0;
draw.setAngle(mes[1] - a + 180);
draw.setOpenedColor(opened);
icon.setImageDrawable(draw);
} else {
if(opened == -1){
icon.setImageResource(R.drawable.poi);
} else if(opened == 0){
icon.setImageResource(R.drawable.opened_poi);
} else {
icon.setImageResource(R.drawable.closed_poi);
}
}
if(mes == null){
distanceLabel.setText(""); //$NON-NLS-1$
} else {
distanceLabel.setText(" " + OsmAndFormatter.getFormattedDistance((int) mes[0], SearchPOIActivity.this)); //$NON-NLS-1$
}
return (row);
}
@Override
public Filter getFilter() {
if (filter == null) {
filter = new AmenityFilter();
}
return filter;
}
private final class AmenityFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (constraint == null || constraint.length() == 0) {
results.values = originalAmenityList;
results.count = originalAmenityList.size();
} else {
String lowerCase = constraint.toString()
.toLowerCase();
List<Amenity> filter = new ArrayList<Amenity>();
for (Amenity item : originalAmenityList) {
String lower = OsmAndFormatter.getPoiStringWithoutType(item, settings.usingEnglishNames()).toLowerCase();
if(lower.indexOf(lowerCase) != -1){
filter.add(item);
}
}
results.values = filter;
results.count = filter.size();
}
return results;
}
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
clear();
for (Amenity item : (Collection<Amenity>) results.values) {
add(item);
}
}
}
}
}