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!

coordinates