如何通过OpenStreetMap API从地址获取坐标?Java遇301错误求助
Hey there! Let's work through your problem step by step—you're really close to getting this working.
Why You're Seeing the 301 "Moved Permanently" Error
The core issue here is that Nominatim now requires HTTPS instead of HTTP for all API requests. When you send a request to http://nominatim.openstreetmap.org, the server immediately sends a 301 redirect to the HTTPS version of the URL. If your makeRequest method doesn't automatically follow redirects (many basic HTTP clients don't do this by default), it'll throw that error instead of fetching the actual JSON data.
Step-by-Step Fixes
1. Switch to HTTPS in Your API URL
First, update your request URL to use https:// instead of http://. Also, note that in Java string literals, you don't need to use &—that's an HTML escape code. Just use regular & characters:
String url = "https://nominatim.openstreetmap.org/search?q=" + address + "&format=json&polygon=1&addressdetails=1"; // Adjust based on what your makeRequest method expects (string or direct call) Object response = makeRequest(url, "get");
2. Fix the JSON Parsing Logic
Another hidden problem: Nominatim returns a JSON array (even if there's only one matching address), not a single JSONObject. Your current code tries to call getString("lon") directly on the root object, which will throw an error once you fix the 301. Here's how to adjust it:
public static String getLongLat(String address) { String url = "https://nominatim.openstreetmap.org/search?q=" + address + "&format=json&polygon=1&addressdetails=1"; // Assuming makeRequest returns the raw JSON string—adjust if it returns a JSON object directly String jsonResponse = makeRequest(url, "get"); JSONArray results = new JSONArray(jsonResponse); if (results.length() == 0) { System.out.println("No matching address found."); return ""; } JSONObject firstResult = results.getJSONObject(0); String lon = firstResult.getString("lon"); String lat = firstResult.getString("lat"); System.out.println("Longitude: " + lon); System.out.println("Latitude: " + lat); // Return a usable format, e.g., "lat,lon" for later distance calculations return lat + "," + lon; }
3. Ensure Your HTTP Client Follows Redirects (Optional)
If you still run into redirect issues after switching to HTTPS, check your makeRequest method. If it uses HttpURLConnection, add this line to enable automatic redirect following:
connection.setInstanceFollowRedirects(true);
A Quick Usage Tip for Nominatim
Don't forget to follow Nominatim's usage rules: avoid sending too many requests in a short time, and add a clear User-Agent header to your requests (this helps them identify your app and avoid rate limiting). You can add this to your makeRequest method like so:
connection.setRequestProperty("User-Agent", "YourDesktopAppName/1.0 (your-contact-email@example.com)");
内容的提问来源于stack exchange,提问作者Sep Bauknecht

