package eirb.pg203; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URI; import java.net.URL; import java.util.Locale; import eirb.pg203.utils.JSONFetcher; import org.json.JSONArray; import org.json.JSONObject; import eirb.pg203.utils.Coords; /** * Representation of a city * Possibility to get city coordinates based on the name */ public class City { private String cityName; private Coords cityCoords; /** * Fetch data from adresse.data.gouv.fr * @throws IOException if the request fails */ private static JSONObject getDataFromName(String cityName) throws IOException { StringBuilder result = new StringBuilder(); URL url = URI.create( String.format(Locale.ENGLISH, "https://api-adresse.data.gouv.fr/search/?q=%s&autocomplete=0&limit=1", cityName ) ).toURL(); return JSONFetcher.fetch(url); } private static Coords getCoordsFromName(String cityName) throws IOException { JSONObject data = getDataFromName(cityName); JSONArray rawCoords = data.getJSONArray("features") .getJSONObject(0) .getJSONObject("geometry") .getJSONArray("coordinates"); final float lon = rawCoords.getFloat(0); final float lat = rawCoords.getFloat(1); return new Coords(lat, lon); } City (String cityName) { this.cityName = cityName; } /** * Get city name * @return city name string */ public String getCityName() { return cityName; } /** * Returns the city coords using adresse.data.gouv.fr, cache the result * @return the city Coords * @throws IOException if the request to adresse.data.gouv.fr fails * */ public Coords getCityCoords() throws IOException { if (this.cityCoords == null) { this.cityCoords = getCoordsFromName(cityName); } return cityCoords; } @Override public String toString() { try { Coords coords = this.getCityCoords(); return String.format(Locale.ENGLISH, "City(%s, lat: %f, lon: %f)", this.cityName, coords.getLat(), coords.getLon() ); } catch (IOException e) { return String.format(Locale.ENGLISH, "City(%s, lat: Request failed, lon: Request Failed)", this.cityName ); } } }