'Can't access the OpenStreetMap to get coordinates for address

I'm trying to retrieve coordinates for a given address using an API I found for OpenStreetMap

The API is as follows:

package com.sges.commons.utils.coordenada;

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.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import org.json.simple.parser.JSONParser;

import com.sges.commons.generic.entities.GenConcelho;

public class OpenStreetMapUtils {

    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 static  String getRequest(String url) throws Exception {

        final URL obj = new URL(url);
        final HttpURLConnection con = (HttpURLConnection) obj.openConnection();

        con.setRequestMethod("GET");
        
        int a = con.getResponseCode();

        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 static Map<String, Double> getCoordinates(String address, String concelho) {
        Map<String, Double> res;
        StringBuffer query;
        String join_morada_concelho = address + " " + concelho;
        String[] split = join_morada_concelho.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");

       

        try {
            queryResult = getRequest(query.toString());
        } catch (Exception e) {
            
        }

        if (queryResult == null) {
            return null;
        }
        
        Object obj = JSONValue.parse(queryResult);
        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");
                res.put("lon", Double.parseDouble(lon));
                res.put("lat", Double.parseDouble(lat));

            }
        }
        return res;
    }
    
}

The problem is that when it gets to the getRequest() method, it shows me that I don't have a response code 200: variable "con"

And yes, it generates a valid URL because I pasted it on chrome and it showed me coordinates for my address. The problem seems to be the connection between my project and OpenStreetMap.

Any ideas?



Solution 1:[1]

You've got to do some better error handling. You're quietly throwing away all the error information that you get back.

It's rarely a good idea to squash exceptions entirely like this:

} catch (Exception e) {
        
}

So change it to this:

} catch (Exception e) {
    System.err.println(e);
}

And then you can throw an exception with more information in your getRequest method.

You need to check for response codes other than 200. I think for 500 errors you also ideally read from errorStream, although [correcting earlier version of this answer] maybe it's not strictly necessary. Hopefully useful error content is in the main response stream so you need something like this:

StringBuffer response = new StringBuffer();
try {
    BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
    String inputLine;
    while ((inputLine = in.readLine()) != null) {
        response.append(inputLine);
    }
    in.close();
} catch (Exception e) {
    System.err.println("Error reading input stream");
    e.printStackTrace();
}

if (con.getResponseCode() != 200) {
    throw new RuntimeException("Response " + con.getResponseCode() + " : " + response.toString());
}
return response.toString();

That should at least blurt out something to System.err

It might not be very exciting error information. Maybe just a "403 forbidden" coming back from OpenStreetMap's nominatim server (due to violating the usage policy) but start by setting it up so you can see what you're getting back.

Solution 2:[2]

In your case you receive 301 status code because you try to use non-secure version of nominatim API. Try to change http to https and you wil get a result. Btw as mentioned @HarryWood you should work with exceptions properly and just ignoring them; and you should use loggers for this.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Alex