~opensatnav-admins/opensatnav/release-1.0

« back to all changes in this revision

Viewing changes to src/org/opensatnav/android/services/NominatimGeoCoder.java

  • Committer: Kieran Fleming
  • Date: 2010-12-13 13:13:48 UTC
  • Revision ID: kieran.fleming@gmail.com-20101213131348-pixo12i0wjf11jk3
Add all the missing stuff from the failed package rename

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package org.opensatnav.android.services;
 
2
 
 
3
import java.net.MalformedURLException;
 
4
import java.net.URL;
 
5
import java.net.URLConnection;
 
6
import java.net.URLEncoder;
 
7
import java.util.ArrayList;
 
8
import java.util.Locale;
 
9
 
 
10
import javax.xml.parsers.DocumentBuilder;
 
11
import javax.xml.parsers.DocumentBuilderFactory;
 
12
 
 
13
import org.andnav.osm.util.GeoPoint;
 
14
import org.andnav.osm.views.util.HttpUserAgentHelper;
 
15
import org.opensatnav.android.OpenSatNavConstants;
 
16
import org.w3c.dom.Document;
 
17
import org.w3c.dom.NamedNodeMap;
 
18
import org.w3c.dom.NodeList;
 
19
 
 
20
import android.content.Context;
 
21
import android.os.Bundle;
 
22
import android.util.Log;
 
23
 
 
24
public class NominatimGeoCoder implements GeoCoder {
 
25
        private String url;
 
26
        private ArrayList<String> locationNames;
 
27
        private ArrayList locationLatitudes;
 
28
        private ArrayList locationLongitudes;
 
29
        private ArrayList<String> locationInfo;
 
30
        URL encodedURL;
 
31
        
 
32
 
 
33
        @Override
 
34
        public Bundle query(String query, GeoPoint userLocation, int mode, int maxResults,
 
35
                        Context context) {
 
36
                locationNames = new ArrayList<String>();
 
37
                locationLatitudes = new ArrayList<int[]>();
 
38
                locationLongitudes = new ArrayList<int[]>();
 
39
                locationInfo = new ArrayList<String>();
 
40
                                        
 
41
                        // see http://wiki.openstreetmap.org/wiki/Nominatim for URL available parameters
 
42
                        
 
43
                        String language = Locale.getDefault().getLanguage();
 
44
                        ReverseGeoCoder revGeoCoder = new NominatimReverseGeoCoder();
 
45
                        Bundle locationData = revGeoCoder.query(userLocation, context);
 
46
                        url = new String("http://nominatim.openstreetmap.org/search?"   
 
47
                                        + "format=xml"
 
48
                                        + "&addressdetails=1"
 
49
                                        + "&accept-language=" + language);
 
50
                        if(mode==FROM_POINT) {
 
51
                                String locationDescription = "";
 
52
                                if(locationData.containsKey("village"))
 
53
                                        locationDescription += locationData.getString("village")+", ";
 
54
                                if(locationData.containsKey("town"))
 
55
                                        locationDescription += locationData.getString("town")+", ";
 
56
                                if(locationData.containsKey("suburb"))
 
57
                                        locationDescription += locationData.getString("suburb")+", ";
 
58
                                if(locationData.containsKey("city"))
 
59
                                        locationDescription += locationData.getString("city")+", ";
 
60
                                if(locationData.containsKey("country"))
 
61
                                        locationDescription += locationData.getString("country");
 
62
                                url += "&q="+URLEncoder.encode(query+" near "+locationDescription);
 
63
                        }
 
64
                        else if (mode == IN_AREA) {
 
65
                                String locationDescription = "";
 
66
                                if(locationData.containsKey("town"))
 
67
                                        locationDescription += locationData.getString("town")+", ";
 
68
                                if(locationData.containsKey("city"))
 
69
                                        locationDescription += locationData.getString("city")+", ";
 
70
                                if(locationData.containsKey("country"))
 
71
                                        locationDescription += locationData.getString("country");
 
72
                                url += "&q="+URLEncoder.encode(query+", "+locationDescription);
 
73
                        }
 
74
                                        
 
75
            try {               
 
76
                encodedURL = new URL(url);
 
77
                } catch (MalformedURLException e) {
 
78
                        Log.e(OpenSatNavConstants.LOG_TAG, e.getMessage(), e);
 
79
                }
 
80
                try {
 
81
                        URLConnection urlConn = encodedURL.openConnection();
 
82
                        String userAgent = HttpUserAgentHelper.getUserAgent(context);
 
83
                        if (userAgent != null)
 
84
                                urlConn.setRequestProperty("User-Agent", userAgent);
 
85
                        urlConn.setReadTimeout(60000);
 
86
                        urlConn.setDoInput(true);
 
87
                        urlConn.setDoOutput(true);
 
88
                        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 
89
                        DocumentBuilder db = dbf.newDocumentBuilder();
 
90
                        Document doc = db.parse(urlConn.getInputStream());
 
91
                        NodeList xml = doc.getChildNodes();
 
92
                        // if we have at least 1 result
 
93
                        //android 2.2 starts at item(0) while previous versions start at item(1) so we deal with both here
 
94
                        if ((xml.item(0).getChildNodes().item(1) != null) || (xml.item(1).getChildNodes().item(1) != null)) {
 
95
                                 NodeList places = xml.item(0).getChildNodes();
 
96
                                 if(places.getLength()==0)
 
97
                                    places = xml.item(1).getChildNodes();
 
98
                                 for (int i = 1; i < places.getLength(); i++) {
 
99
                                        NamedNodeMap attributes = places.item(i).getAttributes();
 
100
                                        Log.d("NOMINATIMGEOCODER", "found location: "
 
101
                                                        + attributes.getNamedItem("display_name").getNodeValue());
 
102
                                        locationNames.add(places.item(i).getChildNodes().item(0).getFirstChild().getNodeValue());
 
103
                                        // convert to integer (E6 format)
 
104
                                        locationLatitudes.add((int) (Float.parseFloat(attributes
 
105
                                                        .getNamedItem("lat").getNodeValue()) * 1000000));
 
106
                                        locationLongitudes.add((int) (Float.parseFloat(attributes
 
107
                                                        .getNamedItem("lon").getNodeValue()) * 1000000));
 
108
                                        //moreInfo is the second line, it displays the type followed by the full address
 
109
                                        String moreInfo = null;
 
110
                                        NodeList locationDetails = places.item(i).getChildNodes();
 
111
                                        if (attributes.getNamedItem("type") != null)
 
112
                                                moreInfo = attributes.getNamedItem("type").getNodeValue();
 
113
                                        StringBuilder sb = new StringBuilder(moreInfo);
 
114
                                        for(int j=1;j<locationDetails.getLength(); j++){
 
115
                                                if(!locationDetails.item(j).getNodeName().equals("country_code")){
 
116
                                                        sb.append(", ");
 
117
                                                        sb.append(locationDetails.item(j).getFirstChild().getNodeValue());
 
118
                                                }
 
119
                                        }
 
120
                                        if (moreInfo != null)
 
121
                                                locationInfo.add(sb.toString());
 
122
                                        else
 
123
                                                locationInfo.add(" ");
 
124
                                }
 
125
                        }
 
126
                        // no results
 
127
                        else
 
128
                                return null;
 
129
                } catch (Exception e) {
 
130
                        e.printStackTrace();
 
131
                        Log.d("OSMGEOCODER", "Network timeout");
 
132
                        return null;
 
133
                }
 
134
                Bundle bundle = new Bundle();
 
135
                // should have done this better - didn't know Java had issues like this!
 
136
                int[] latArray = new int[locationLatitudes.size()];
 
137
                int[] lonArray = new int[locationLatitudes.size()];
 
138
                String[] nameArray = new String[locationNames.size()];
 
139
                String[] infoArray = new String[locationInfo.size()];
 
140
 
 
141
                System.arraycopy(locationNames.toArray(), 0, nameArray, 0,
 
142
                                locationNames.size());
 
143
                System.arraycopy(locationInfo.toArray(), 0, infoArray, 0, locationInfo
 
144
                                .size());
 
145
                for (int i = 0; i < locationLatitudes.size(); i++)
 
146
                        latArray[i] = (Integer) locationLatitudes.get(i);
 
147
                for (int i = 0; i < locationLatitudes.size(); i++)
 
148
                        lonArray[i] = (Integer) locationLongitudes.get(i);
 
149
 
 
150
                bundle.putStringArray("names", nameArray);
 
151
                bundle.putIntArray("latitudes", latArray);
 
152
                bundle.putIntArray("longitudes", lonArray);
 
153
                bundle.putStringArray("info", infoArray);
 
154
                return bundle;
 
155
 
 
156
        }
 
157
 
 
158
}