001: /* uDig - User Friendly Desktop Internet GIS client
002: * http://udig.refractions.net
003: * (C) 2004, Refractions Research Inc.
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation;
008: * version 2.1 of the License.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: */
015: package net.refractions.udig.location;
016:
017: import java.io.IOException;
018: import java.util.ArrayList;
019: import java.util.Hashtable;
020: import java.util.List;
021: import java.util.Vector;
022:
023: import org.apache.xmlrpc.XmlRpcClient;
024: import org.apache.xmlrpc.XmlRpcException;
025: import org.geotools.feature.AttributeType;
026: import org.geotools.feature.AttributeTypeFactory;
027: import org.geotools.feature.Feature;
028: import org.geotools.feature.FeatureType;
029: import org.geotools.feature.FeatureTypeBuilder;
030:
031: import com.vividsolutions.jts.geom.Coordinate;
032: import com.vividsolutions.jts.geom.GeometryFactory;
033: import com.vividsolutions.jts.geom.Point;
034:
035: /**
036: *
037: * @author James
038: */
039: public class AddressSeeker {
040:
041: // protected String host = "http://geocoder.us/service/xmlrpc";
042: protected String username = ""; //$NON-NLS-1$
043: protected String password = ""; //$NON-NLS-1$
044:
045: /** Creates a new instance of AddressSeeker */
046: public AddressSeeker() {
047:
048: }
049:
050: public void setPassword(String pwd) {
051: password = pwd;
052: }
053:
054: static private FeatureType createAddressType(List<String> keys) {
055: AttributeTypeFactory fac = AttributeTypeFactory
056: .defaultInstance();
057: AttributeType[] types = new AttributeType[keys.size() - 1];
058: int index = 0;
059: for (String key : keys) {
060: if ("long".equals(key) || "lat".equals(key))continue; //$NON-NLS-1$ //$NON-NLS-2$
061: types[index] = fac.newAttributeType(key, String.class);
062: index++;
063: }
064: types[index] = fac.newAttributeType("location", Point.class); //$NON-NLS-1$
065:
066: FeatureType type;
067: try {
068: return FeatureTypeBuilder.newFeatureType(types, "Address"); //$NON-NLS-1$
069: } catch (Throwable e) {
070: return null;
071: }
072: }
073:
074: public void setUsername(String uname) {
075: username = uname;
076: }
077:
078: private List<String> keys(Vector<Hashtable<String, Object>> vector) {
079: List<String> keys = new ArrayList<String>();
080: for (Hashtable<String, Object> record : vector)
081: for (String key : record.keySet())
082: if (!keys.contains(key))
083: keys.add(key);
084: return keys;
085: }
086:
087: /** Returns a List<Feature> of ADDRESS */
088: public Point where(String address) throws IOException,
089: XmlRpcException {
090: GeometryFactory fac = new GeometryFactory();
091:
092: XmlRpcClient geocoder;
093: if (username != null && password != null) {
094: geocoder = new XmlRpcClient(
095: "http://" + username + ":" + password + "@geocoder.us/service/xmlrpc"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
096: } else {
097: geocoder = new XmlRpcClient(
098: "http://geocoder.us/service/xmlrpc"); //$NON-NLS-1$
099: }
100:
101: Vector params = new Vector();
102: params.addElement(address);
103: // this method returns a string
104: Vector vec = (Vector) geocoder.execute("geocode", params); //$NON-NLS-1$
105: System.out.println("vec" + vec); //$NON-NLS-1$
106:
107: Hashtable table = (Hashtable) vec.get(0);
108: double lat = ((Number) table.get("lat")).doubleValue(); //$NON-NLS-1$
109: double lon = ((Number) table.get("long")).doubleValue(); //$NON-NLS-1$
110: Coordinate c = new Coordinate(lon, lat);
111: Point p = fac.createPoint(c);
112: return p;
113: }
114:
115: public List<Feature> geocode(String address) throws IOException,
116: XmlRpcException {
117: GeometryFactory fac = new GeometryFactory();
118:
119: XmlRpcClient geocoder;
120: if (username != null && password != null) {
121: geocoder = new XmlRpcClient(
122: "http://" + username + ":" + password + "@geocoder.us/service/xmlrpc"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
123: } else {
124: geocoder = new XmlRpcClient(
125: "http://geocoder.us/service/xmlrpc"); //$NON-NLS-1$
126: }
127: Vector params = new Vector();
128: params.addElement(address);
129:
130: // this method returns a string
131: Vector<Hashtable<String, Object>> vec = (Vector<Hashtable<String, Object>>) geocoder
132: .execute("geocode", params); //$NON-NLS-1$
133: System.out.println("vec" + vec); //$NON-NLS-1$
134:
135: List<String> keys = keys(vec);
136: FeatureType ADDRESS = createAddressType(keys);
137:
138: List<Feature> places = new ArrayList<Feature>(vec.size());
139:
140: int count = 1;
141: for (Hashtable table : vec) {
142: double lat = Double.NaN, lon = Double.NaN;
143: Object values[] = new Object[keys.size() - 1];
144: int index = 0;
145: for (String key : keys) {
146: if (!table.containsKey(key)) {
147: System.out.println("missed key - " + key); //$NON-NLS-1$
148: continue;
149: } else {
150: if ("lat".equals(key)) { //$NON-NLS-1$
151: lat = ((Number) table.get("lat")).doubleValue(); //$NON-NLS-1$
152: continue;
153: } else if ("long".equals(key)) { //$NON-NLS-1$
154: lon = ((Number) table.get("long")).doubleValue(); //$NON-NLS-1$
155: continue;
156: }
157: values[index] = table.get(key);
158: }
159: index++;
160: }
161: if (Double.isNaN(lat) || Double.isNaN(lon)) {
162: System.out.println("missed location - "); //$NON-NLS-1$
163: } else {
164: values[index] = fac
165: .createPoint(new Coordinate(lon, lat));
166: }
167: try {
168: Feature f = ADDRESS.create(values, fid(count++, table));
169: places.add(f);
170: } catch (Exception e) {
171: e.printStackTrace();
172: }
173: }
174: return places;
175: }
176:
177: private void append(StringBuffer fid,
178: Hashtable<String, Object> table, String key) {
179: if (table.containsKey(key) && table.get(key) != null) {
180: fid.append(" "); //$NON-NLS-1$
181: fid.append(table.get(key));
182: }
183: }
184:
185: String fid(int count, Hashtable<String, Object> table) {
186: StringBuffer fid = new StringBuffer();
187: fid.append(count);
188: fid.append("."); //$NON-NLS-1$
189:
190: append(fid, table, "number"); //$NON-NLS-1$
191: append(fid, table, "street"); //$NON-NLS-1$
192: append(fid, table, "type"); //$NON-NLS-1$
193: if (table.containsKey("city")) { //$NON-NLS-1$
194: fid.append(","); //$NON-NLS-1$
195: fid.append(table.get("city")); //$NON-NLS-1$
196: }
197: append(fid, table, "state"); //$NON-NLS-1$
198: return fid.toString();
199: }
200: }
|