package org.opensatnav.services;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.ArrayList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.andnav.osm.util.GeoPoint;
import org.andnav.osm.views.util.HttpUserAgentHelper;
import org.opensatnav.OpenSatNavConstants;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.NodeList;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
public class NominatimGeoCoder implements GeoCoder {
private URL url;
private GeoPoint location;
private ArrayList<String> locationNames;
private ArrayList locationLatitudes;
private ArrayList locationLongitudes;
private ArrayList<String> locationInfo;
@Override
public Bundle getFromLocationName(String locationName, int maxResults,
Context context) {
locationNames = new ArrayList<String>();
locationLatitudes = new ArrayList<int[]>();
locationLongitudes = new ArrayList<int[]>();
locationInfo = new ArrayList<String>();
try {
// see http://wiki.openstreetmap.org/wiki/Nominatim for URL available parameters
//String language = Locale.getDefault().getLanguage();
// "&accept-language=" + language
url = new URL("http://nominatim.openstreetmap.org/search?q="
+ URLEncoder.encode(locationName) + "&format=xml");
} catch (MalformedURLException e) {
Log.e(OpenSatNavConstants.LOG_TAG, e.getMessage(), e);
}
try {
URLConnection urlConn = url.openConnection();
String userAgent = HttpUserAgentHelper.getUserAgent(context);
if (userAgent != null)
urlConn.setRequestProperty("User-Agent", userAgent);
urlConn.setReadTimeout(60000);
urlConn.setDoInput(true);
urlConn.setDoOutput(true);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(urlConn.getInputStream());
NodeList xml = doc.getChildNodes();
// if we have at least 1 result
if (xml.item(1).getChildNodes().item(1) != null) {
NodeList places = xml.item(1).getChildNodes();
for (int i = 1; i < places.getLength(); i++) {
NamedNodeMap attributes = places.item(i).getAttributes();
Log.d("NOMINATIMGEOCODER", "found location: "
+ attributes.getNamedItem("display_name").getNodeValue());
locationNames.add(attributes.getNamedItem("display_name")
.getNodeValue());
// convert to integer (E6 format)
locationLatitudes.add((int) (Float.parseFloat(attributes
.getNamedItem("lat").getNodeValue()) * 1000000));
locationLongitudes.add((int) (Float.parseFloat(attributes
.getNamedItem("lon").getNodeValue()) * 1000000));
if (attributes.getNamedItem("type") != null)
locationInfo.add(attributes.getNamedItem("type")
.getNodeValue());
else
locationInfo.add(" ");
}
}
// no results
else
return null;
} catch (Exception e) {
e.printStackTrace();
Log.d("OSMGEOCODER", "Network timeout");
return null;
}
Bundle bundle = new Bundle();
// should have done this better - didn't know Java had issues like this!
int[] latArray = new int[locationLatitudes.size()];
int[] lonArray = new int[locationLatitudes.size()];
String[] nameArray = new String[locationNames.size()];
String[] infoArray = new String[locationInfo.size()];
System.arraycopy(locationNames.toArray(), 0, nameArray, 0,
locationNames.size());
System.arraycopy(locationInfo.toArray(), 0, infoArray, 0, locationInfo
.size());
for (int i = 0; i < locationLatitudes.size(); i++)
latArray[i] = (Integer) locationLatitudes.get(i);
for (int i = 0; i < locationLatitudes.size(); i++)
lonArray[i] = (Integer) locationLongitudes.get(i);
bundle.putStringArray("names", nameArray);
bundle.putIntArray("latitudes", latArray);
bundle.putIntArray("longitudes", lonArray);
bundle.putStringArray("info", infoArray);
return bundle;
}
}