package photato.core.metadata.gps;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.google.gson.annotations.SerializedName;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
public class OSMGpsCoordinatesDescriptionGetter implements IGpsCoordinatesDescriptionGetter {
private static class OpenStreetMapResult {
private static class Address {
public String neighbourhood;
public String suburb;
@SerializedName("city_district")
public String cityDistrict;
public String village;
public String town;
public String city;
public String state;
public String country;
}
private Address address;
@SerializedName("display_name")
private String displayName;
public String getDisplayName(int maxElementsCount) {
if (this.address != null) {
List<String> elements = new ArrayList<>();
elements.add(this.address.neighbourhood);
elements.add(this.address.suburb);
elements.add(this.address.cityDistrict);
elements.add(this.address.village);
elements.add(this.address.town);
elements.add(this.address.city);
elements.add(this.address.state);
elements.add(this.address.country);
List<String> l = elements.stream()
.filter((String s) -> (s != null && !s.isEmpty()))
.distinct()
.collect(Collectors.toList());
if (l.size() > maxElementsCount) {
l = l.subList(l.size() - maxElementsCount, l.size());
}
return String.join(", ", l);
} else {
return this.displayName;
}
}
}
private final HttpClient httpClient;
private final int maxElementsCount;
public OSMGpsCoordinatesDescriptionGetter(HttpClient httpClient, int maxElementsCount) {
this.httpClient = httpClient;
this.maxElementsCount = maxElementsCount;
}
@Override
public synchronized String getCoordinatesDescription(Double latitude, Double longitude) {
if (latitude == null || longitude == null) {
return null;
}
try {
HttpGet request = new HttpGet("http://nominatim.openstreetmap.org/reverse?format=json&lat=" + latitude + "&lon=" + longitude);
HttpResponse response = this.httpClient.execute(request);
try (BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()))) {
Gson gson = new Gson();
OpenStreetMapResult result = gson.fromJson(rd, OpenStreetMapResult.class);
return result.getDisplayName(this.maxElementsCount);
}
} catch (IOException | JsonSyntaxException ex) {
System.err.println("Cannot get data from openstreetmap api " + ex);
return null;
}
}
}