How to get geocoding information in Java without Google maps API?
For some project, you might want to use geocoding information, which means get the GPS coordinates from an address. If you want to use Google services, you are limited to a certain number of requests but your usage is connected with your account. There is a nice geocoding API available but
You might want to have as many requests as you want but also avoid Google to look at your applications are doing. After all, these requests are sent by the users of your own application, not you.
So, yes, sure, there is a nice geocoding API available with Google. But it seems to be restricted/limited. So, let's not use it. The alternative is to use the open website OpenStreetMap (a.k.a. OSM), which has a webservice to get geocoding information. It does not provide a full Java API but rather the data in a JSON or XML fornat. So, all we have to do is to write a Java API what issue requests to the webservice and retrieve the geocoding information from the JSON/XML.
I chose to get the information with the JSON format, this is pretty easy to use. To parse the JSON data from the service, I use json-simple available on maven.
Getting the geocoding data
Basically, the code issue a request to the geocoding webservice from OpenStreetMap, get the result and convert it into a JSON object. It then get the latitude/longitude information from the JSONObject.
import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.util.HashMap; import java.util.Map; import org.apache.log4j.Logger; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.JSONValue; import org.json.simple.parser.JSONParser; public class OpenStreetMapUtils { public final static Logger log = Logger.getLogger("OpenStreeMapUtils"); private static OpenStreetMapUtils instance = null; private JSONParser jsonParser; public OpenStreetMapUtils() { jsonParser = new JSONParser(); } public static OpenStreetMapUtils getInstance() { if (instance == null) { instance = new OpenStreetMapUtils(); } return instance; } private String getRequest(String url) throws Exception { final URL obj = new URL(url); final HttpURLConnection con = (HttpURLConnection) obj.openConnection(); con.setRequestMethod("GET"); if (con.getResponseCode() != 200) { return null; } BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); String inputLine; StringBuffer response = new StringBuffer(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); } in.close(); return response.toString(); } public Map<String, Double> getCoordinates(String address) { Map<String, Double> res; StringBuffer query; String[] split = address.split(" "); String queryResult = null; query = new StringBuffer(); res = new HashMap<String, Double>(); query.append("http://nominatim.openstreetmap.org/search?q="); if (split.length == 0) { return null; } for (int i = 0; i < split.length; i++) { query.append(split[i]); if (i < (split.length - 1)) { query.append("+"); } } query.append("&format=json&addressdetails=1"); log.debug("Query:" + query); try { queryResult = getRequest(query.toString()); } catch (Exception e) { log.error("Error when trying to get data with the following query " + query); } if (queryResult == null) { return null; } Object obj = JSONValue.parse(queryResult); log.debug("obj=" + obj); if (obj instanceof JSONArray) { JSONArray array = (JSONArray) obj; if (array.size() > 0) { JSONObject jsonObject = (JSONObject) array.get(0); String lon = (String) jsonObject.get("lon"); String lat = (String) jsonObject.get("lat"); log.debug("lon=" + lon); log.debug("lat=" + lat); res.put("lon", Double.parseDouble(lon)); res.put("lat", Double.parseDouble(lat)); } } return res; } }
Testing the service
Then, to use the service, you can just use a main program like the following code.
public class GetCoordinates { static String address = "The White House, Washington DC"; public static void main(String[] args) { Map<String, Double> coords; coords = OpenStreetMapUtils.getInstance().getCoordinates(address); System.out.println("latitude :" + coords.get("lat")); System.out.println("longitude:" + coords.get("lon")); } }
Checking
When running the previous example, the program prints the following information:
- latitude :38.8976989
- longitude:-77.036553192281
Let's then check where are these coordinates! When putting the coordinates on Google Maps, I then got the following map. Sounds like it works!