18Apr 12
openstreetmap json geolocation using java
A viable free alternative to google’s geolocation api is openstreetmap’s nominatim functionality. The service recommends restricting the frequency of requests to 1 per second, so if nothing else, this is a viable failover alternative to google’s geolocation api.
The code below may be used to query openstreetmap’s nominatim database for latitude/longitude information. It uses the jackson library for json parsing.
If you are using maven, add:
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-jaxrs</artifactId>
<version>1.9.4</version>
</dependency>
to your pom.xml file’s dependencies to satisfy the import statements in the class below.
import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.net.URLEncoder; import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import org.codehaus.jackson.map.ObjectMapper; public class OpenStreetMapGeoCodeJacksonParser { private static final String LATITUDE = "lat"; private static final String LONGITUDE = "lon"; public LatLng parse(final InputStream jsonStream) { LatLng coordinate = null; final ObjectMapper mapper = new ObjectMapper(); try { final List<Object> dealData = mapper.readValue(jsonStream, List.class); if (dealData != null && dealData.size() == 1) { final Map< String, Object > locationMap = (Map< String, Object >) dealData.get(0); if (locationMap != null && locationMap.containsKey(LATITUDE) && locationMap.containsKey(LONGITUDE)) { final double lat = Double.parseDouble(locationMap.get(LATITUDE).toString()); final double lng = Double.parseDouble(locationMap.get(LONGITUDE).toString()); coordinate = new LatLng(lat, lng); } } else { Logger.getLogger(OpenStreetMapGeoCodeJacksonParser.class.getName()).log(Level.SEVERE, "NO RESULTS", "NO RESULTS"); } } catch (Exception ex) { Logger.getLogger(OpenStreetMapGeoCodeJacksonParser.class.getName()).log(Level.SEVERE, ex.getMessage(), ex); } return coordinate; } public LatLng parse(String rawAddress) { InputStream is = null; LatLng coords = null; if (rawAddress != null && rawAddress.length() > 0 ) { try { String address = URLEncoder.encode(rawAddress, "utf-8"); String geocodeURL = "http://nominatim.openstreetmap.org/search?format=json&limit=1&polygon=0&addressdetails=0&email=contact@EMAIL.ME&countrycodes=us&q="; //query google geocode api String formattedUrl = geocodeURL + address; URL geocodeUrl = new URL(formattedUrl); is = geocodeUrl.openStream(); coords = parse(is); } catch (IOException ex) { Logger.getLogger(OpenStreetMapGeoCodeJacksonParser.class.getName()).log(Level.SEVERE, null, ex); } finally { try { is.close(); } catch (IOException ex) { Logger.getLogger(OpenStreetMapGeoCodeJacksonParser.class.getName()).log(Level.SEVERE, null, ex); } } } return coords; } public static void main(final String[] args) { final String rawAddress = "Los Angeles, CA"; System.out.println(new OpenStreetMapGeoCodeJacksonParser().parse(rawAddress)); } }
Please make sure to substitute a valid email address into the geocodeURL’s email GET parameter.
Finally, the LatLng.java class holds the latitude-longitude information.
import java.io.Serializable; /** * * @author mdanter */ public class LatLng implements Serializable{ private static final long serialVersionUID = 16549987563L; private double lat; private double lng; public LatLng(final double lat, final double lng) { this.lat = lat; this.lng = lng; } public double getLat() { return lat; } public void setLat(final double lat) { this.lat = lat; } public double getLng() { return lng; } public void setLng(final double lng) { this.lng = lng; } @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final LatLng other = (LatLng) obj; if (Double.doubleToLongBits(this.lat) != Double.doubleToLongBits(other.lat)) { return false; } if (Double.doubleToLongBits(this.lng) != Double.doubleToLongBits(other.lng)) { return false; } return true; } @Override public int hashCode() { int hash = 3; hash = 53 * hash + (int) (Double.doubleToLongBits(this.lat) ^ (Double.doubleToLongBits(this.lat) >>> 32)); hash = 53 * hash + (int) (Double.doubleToLongBits(this.lng) ^ (Double.doubleToLongBits(this.lng) >>> 32)); return hash; } }
Posted in JEE, geolocation, javaNo Comments »