package net.osmand.plus.activities.search;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import net.osmand.Algoritms;
import net.osmand.LogUtil;
import net.osmand.OsmAndFormatter;
import net.osmand.Version;
import net.osmand.osm.LatLon;
import net.osmand.osm.MapUtils;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import org.apache.commons.logging.Log;
import org.xmlpull.v1.XmlPullParser;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.util.Xml;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class SearchAddressOnlineActivity extends ListActivity {
private LatLon location;
private ProgressDialog progressDlg;
private final static Log log = LogUtil.getLog(SearchAddressOnlineActivity.class);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.search_address_online);
Button searchOffline = (Button) findViewById(R.id.SearchOffline);
if (getParent() instanceof SearchActivity) {
searchOffline.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
((SearchActivity) getParent()).startSearchAddressOffline();
}
});
} else {
searchOffline.setVisibility(View.INVISIBLE);
}
Button searchButton = (Button) findViewById(R.id.SearchButton);
searchButton.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
searchPlaces(((EditText) findViewById(R.id.SearchText)).getText().toString());
}
});
location = OsmandSettings.getLastKnownMapLocation(OsmandSettings.getPrefs(this));
}
protected void searchPlaces(final String search) {
if(Algoritms.isEmpty(search)){
return;
}
progressDlg = ProgressDialog.show(this, getString(R.string.searching), getString(R.string.searching_address));
new Thread(new Runnable(){
@Override
public void run() {
try {
final List<Place> places = new ArrayList<Place>();
StringBuilder b = new StringBuilder();
b.append("http://nominatim.openstreetmap.org/search"); //$NON-NLS-1$
b.append("?format=xml&addressdetails=0&accept-language=").append(Locale.getDefault().getLanguage()); //$NON-NLS-1$
b.append("&q=").append(URLEncoder.encode(search)); //$NON-NLS-1$
log.info("Searching address at : " + b.toString()); //$NON-NLS-1$
URL url = new URL(b.toString());
URLConnection conn = url.openConnection();
conn.setDoInput(true);
conn.setRequestProperty("User-Agent", Version.APP_NAME_VERSION); //$NON-NLS-1$
conn.connect();
InputStream is = conn.getInputStream();
XmlPullParser parser = Xml.newPullParser();
parser.setInput(is, "UTF-8"); //$NON-NLS-1$
int ev;
while ((ev = parser.next()) != XmlPullParser.END_DOCUMENT) {
if(ev == XmlPullParser.START_TAG){
if(parser.getName().equals("place")){ //$NON-NLS-1$
String lat = parser.getAttributeValue("", "lat"); //$NON-NLS-1$ //$NON-NLS-2$
String lon = parser.getAttributeValue("", "lon"); //$NON-NLS-1$//$NON-NLS-2$
String displayName = parser.getAttributeValue("", "display_name"); //$NON-NLS-1$ //$NON-NLS-2$
if(lat != null && lon != null && displayName != null){
Place p = new Place();
p.lat = Double.parseDouble(lat);
p.lon = Double.parseDouble(lon);
p.displayName = displayName;
places.add(p);
}
}
}
}
is.close();
if(places.isEmpty()){
showResult(R.string.search_nothing_found, null);
} else {
showResult(0, places);
}
} catch(Exception e){
log.error("Error searching address", e); //$NON-NLS-1$
showResult(R.string.error_io_error, null);
} finally {
if(progressDlg != null){
progressDlg.dismiss();
progressDlg = null;
}
}
}
}, "SearchingAddress").start(); //$NON-NLS-1$
}
private void showResult(final int warning, final List<Place> places) {
runOnUiThread(new Runnable() {
@Override
public void run() {
if(places == null){
Toast.makeText(SearchAddressOnlineActivity.this, getString(warning), Toast.LENGTH_LONG).show();
} else {
setListAdapter(new PlacesAdapter(places));
}
}
});
}
@Override
protected void onStop() {
if(progressDlg != null){
progressDlg.dismiss();
progressDlg = null;
}
super.onStop();
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
Place item = ((PlacesAdapter) getListAdapter()).getItem(position);
OsmandSettings.setMapLocationToShow(this, item.lat, item.lon, getString(R.string.address)+ " : " + item.displayName); //$NON-NLS-1$
startActivity(new Intent(this, MapActivity.class));
}
private static class Place {
public double lat;
public double lon;
public String displayName;
}
class PlacesAdapter extends ArrayAdapter<Place> {
public PlacesAdapter(List<Place> places) {
super(SearchAddressOnlineActivity.this, R.layout.search_address_online_list_item, places);
}
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null) {
LayoutInflater inflater = getLayoutInflater();
row = inflater.inflate(R.layout.search_address_online_list_item, parent, false);
}
Place model = getItem(position);
TextView label = (TextView) row.findViewById(R.id.label);
TextView distanceLabel = (TextView) row.findViewById(R.id.distance_label);
if(location != null){
int dist = (int) (MapUtils.getDistance(location, model.lat, model.lon));
distanceLabel.setText(OsmAndFormatter.getFormattedDistance(dist, SearchAddressOnlineActivity.this));
} else {
distanceLabel.setText(""); //$NON-NLS-1$
}
label.setText(model.displayName);
return row;
}
}
}