Merge branch 'master' into bug5715

This commit is contained in:
Axel Uhl
2022-09-30 13:13:12 +02:00
@@ -14,6 +14,8 @@ import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
@@ -44,10 +46,12 @@ public class ReverseGeocoderImpl implements ReverseGeocoder {
private final int XKM_RADIUS = 5;
private final int ROWS_PER_XKM_RADIUS = 15;
private final int MAX_ROW_NUMBER = 1000;
private final int MAX_ROW_NUMBER = 500;
private final int MAX_RADIUS = 300;
private QuadTree<Util.Triple<Position, Double, List<Placemark>>> cache = new QuadTree<Util.Triple<Position,Double,List<Placemark>>>();;
private static final Logger logger = Logger.getLogger(ReverseGeocoderImpl.class.getName());
@Override
public Placemark getPlacemarkNearest(Position position) throws IOException, ParseException {
@@ -71,14 +75,13 @@ public class ReverseGeocoderImpl implements ReverseGeocoder {
@Override
public List<Placemark> getPlacemarksNear(Position position, double radius) throws IOException, ParseException {
List<Placemark> placemarks = null;
Util.Triple<Position, Double, List<Placemark>> cachedPlacemarks = checkCache(position);
final List<Placemark> placemarks;
final Util.Triple<Position, Double, List<Placemark>> cachedPlacemarks = checkCache(position);
// Calculating the search radius and the maximum number of returning Placemarks
double limitedRadius = Math.min(radius, MAX_RADIUS);
int radiusInt = (int) limitedRadius;
int xKmRadius = radiusInt / XKM_RADIUS;
int maxRows = (int) (ROWS_PER_XKM_RADIUS * Math.pow(2, xKmRadius));
maxRows = Math.min(maxRows, MAX_ROW_NUMBER);
final int radiusInt = (int) limitedRadius;
final int xKmRadius = radiusInt / XKM_RADIUS;
final int maxRows = (int) Math.min(ROWS_PER_XKM_RADIUS * Math.pow(2, xKmRadius), MAX_ROW_NUMBER);
if (cachedPlacemarks != null && cachedPlacemarks.getB() >= limitedRadius) {
if (cachedPlacemarks.getC().size() > maxRows) {
placemarks = cachedPlacemarks.getC().subList(0, maxRows);
@@ -95,23 +98,29 @@ public class ReverseGeocoderImpl implements ReverseGeocoder {
} else {
searchPosition = position;
}
JSONArray geonames = callNearbyService(searchPosition, limitedRadius, maxRows);
final JSONArray geonames = callNearbyService(searchPosition, limitedRadius, maxRows);
if (geonames != null) {
Iterator<Object> iterator = geonames.iterator();
placemarks = iterator.hasNext() ? new ArrayList<Placemark>() : null;
while (iterator.hasNext()) {
JSONObject object = (JSONObject) iterator.next();
Placemark place = jsonToPlacemark(object);
if (place != null) {
placemarks.add(jsonToPlacemark(object));
if (iterator.hasNext()) {
placemarks = new ArrayList<Placemark>();
while (iterator.hasNext()) {
JSONObject object = (JSONObject) iterator.next();
Placemark place = jsonToPlacemark(object);
if (place != null) {
placemarks.add(jsonToPlacemark(object));
}
}
// If there are no cached placemarks for the requested Position just cache them, otherwise update the cache
if (cachedPlacemarks == null) {
cachePlacemarks(searchPosition, limitedRadius, placemarks);
} else {
updateCachedPlacemarks(searchPosition, limitedRadius, placemarks);
}
} else {
placemarks = null;
}
}
// If there are no cached placemarks for the requested Position just cache them, otherwise update the cache
if (cachedPlacemarks == null && placemarks != null) {
cachePlacemarks(searchPosition, limitedRadius, placemarks);
} else if (placemarks != null) {
updateCachedPlacemarks(searchPosition, limitedRadius, placemarks);
} else {
placemarks = null;
}
}
return placemarks;
@@ -135,11 +144,7 @@ public class ReverseGeocoderImpl implements ReverseGeocoder {
public Placemark getPlacemark(String name, Comparator<Placemark> comp) throws IOException, ParseException {
StringBuilder url = new StringBuilder(SEARCH_BY_NAME_SERVICE);
url.append("name=" + URLEncoder.encode(name, "UTF-8"));
URLConnection connection = addUsernameParameterAndConnect(url);
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream(), Charset.forName("UTF-8")));
final JSONParser parser = new JSONParser();
final JSONObject obj = (JSONObject) parser.parse(in);
final JSONArray geonames = (JSONArray) obj.get("geonames");
final JSONArray geonames = submitGeonamesRequestForJSONArrayResult(url);
return geonames.stream().map(o->jsonToPlacemark((JSONObject) o)).sorted(comp).findFirst().orElse(null);
}
@@ -242,14 +247,8 @@ public class ReverseGeocoderImpl implements ReverseGeocoder {
}
private JSONArray callNearestService(Position position) throws MalformedURLException, IOException, ParseException {
StringBuilder url = new StringBuilder(NEARBY_PLACE_SERVICE);
url.append("lat=" + Double.toString(position.getLatDeg()));
url.append("&lng=" + Double.toString(position.getLngDeg()));
URLConnection connection = addUsernameParameterAndConnect(url);
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream(), Charset.forName("UTF-8")));
JSONParser parser = new JSONParser();
JSONObject obj = (JSONObject) parser.parse(in);
JSONArray geonames = (JSONArray) obj.get("geonames");
StringBuilder url = generateRequestUrlNearbyPlaceService(position);
JSONArray geonames = submitGeonamesRequestForJSONArrayResult(url);
return geonames;
}
@@ -261,16 +260,34 @@ public class ReverseGeocoderImpl implements ReverseGeocoder {
private JSONArray callNearbyService(Position position, double radius, int maxRows) throws MalformedURLException,
IOException, ParseException {
StringBuilder url = generateRequestUrlNearbyPlaceService(position, radius, maxRows);
JSONArray geonames = submitGeonamesRequestForJSONArrayResult(url);
return geonames;
}
private StringBuilder generateRequestUrlNearbyPlaceService(Position position) {
StringBuilder url = new StringBuilder(NEARBY_PLACE_SERVICE);
url.append("lat=" + Double.toString(position.getLatDeg()));
url.append("&lng=" + Double.toString(position.getLngDeg()));
return url;
}
private StringBuilder generateRequestUrlNearbyPlaceService(Position position, double radius, int maxRows) {
StringBuilder url = generateRequestUrlNearbyPlaceService(position);
url.append("&radius=" + Double.toString(radius));
url.append("&maxRows=" + Integer.toString(maxRows));
return url;
}
private JSONArray submitGeonamesRequestForJSONArrayResult(StringBuilder url) throws MalformedURLException, IOException, ParseException {
URLConnection connection = addUsernameParameterAndConnect(url);
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream(), Charset.forName("UTF-8")));
JSONParser parser = new JSONParser();
JSONObject obj = (JSONObject) parser.parse(in);
JSONArray geonames = (JSONArray) obj.get("geonames");
if (geonames == null) {
logger.log(Level.WARNING, "Returning null value for geonames object: " + obj.toJSONString());
}
return geonames;
}