Position fully implemented in Geocoder

This commit is contained in:
Lennart Hensler committed 2012-01-11 15:33:07 +01:00
1 parent 90755dd8af
commit 8e3699e0e5
5 files changed
+221 -46

No files matched your search

@@ -26,15 +26,51 @@ public interface Placemark {
@Override
public int compare(Placemark p1, Placemark p2) {
return p1.getPopulation() > p2.getPopulation() ? 1 : p1.getPopulation() < p2.getPopulation() ? -1 : 0;
// return new Long(p1.getPopulation()).compareTo(p2.getPopulation());
}
}
/**
* Sorts the Placemarks by distance to a {@link Position} from near to far.<br /><br />
*
* If you use this for {@link ReverseGeocoder#getPlacemarkLast(Position, float, Comparator) getPlacemarkBest(Position position,...)} to
* get the nearest Placemark for <code>position</code> you can use {@link ReverseGeocoder#getPlacemarkNearest(Position) getPlacemark} instead.
* <code>getPlacemark</code> returns per default the nearest Placemark for a Position.
* @author Lennart Hensler (D054527)
*
*/
public class ByDistance implements Comparator<Placemark> {
private Position position;
public ByDistance(Position position) {
this.position = position;
}
@Override
public int compare(Placemark p1, Placemark p2) {
return 0;
Distance d1 = p1.distanceFrom(position);
Distance d2 = p2.distanceFrom(position);
return d1.compareTo(d2);
}
}
public class ByPopulationDistanceRatio implements Comparator<Placemark> {
private Position position;
public ByPopulationDistanceRatio(Position position) {
this.position = position;
}
@Override
public int compare(Placemark p1, Placemark p2) {
double r1 = p1.getPopulation() / p1.distanceFrom(position).getKilometers();
double r2 = p2.getPopulation() / p2.distanceFrom(position).getKilometers();
return r1 > r2 ? 1 : r1 < r2 ? -1 : 0;
}
}
}
@@ -13,12 +13,113 @@ public interface ReverseGeocoder {
final ReverseGeocoder INSTANCE = new ReverseGeocoderImpl();
final String GEONAMES_USER = "sailtracking";
Placemark getPlacemark(double latDeg, double lngDeg) throws IOException, ParseException;
Placemark getPlacemark(Position p) throws IOException, ParseException;
/**
* Returns the nearest {@link Placemark} towards the given coordinates.
*
* @param latDeg Latitude in degrees
* @param lngDeg Longitude in degrees
* @return The nearest {@link Placemark} towards the given coordinates
* @throws IOException
* @throws ParseException
*/
Placemark getPlacemarkNearest(double latDeg, double lngDeg) throws IOException, ParseException;
List<Placemark> getPlacemarkNear(double latDeg, double lngDeg, float radius) throws IOException, ParseException;
List<Placemark> getPlacemarkNear(Position p, float radius) throws IOException, ParseException;
/**
* Returns the nearest {@link Placemark} towards the given {@link Position}.
*
* @param position The position where to search
* @return The nearest {@link Placemark} towards the given {@link Position}
* @throws IOException
* @throws ParseException
*/
Placemark getPlacemarkNearest(Position position) throws IOException, ParseException;
Placemark getPlacemarkBest(double latDeg, double lngDeg, float radius, Comparator<Placemark> comp) throws IOException, ParseException;
Placemark getPlacemarkBest(Position p, float radius, Comparator<Placemark> comp) throws IOException, ParseException;
/**
* Returns a list of {@link Placemark Placemarks} near the given coordinates.
*
* @param latDeg Latitude in degrees
* @param lngDeg Longitude in degrees
* @param radius The search radius
* @return A list of {@link Placemark Placemarks} near the given coordinates.
* @throws IOException
* @throws ParseException
*/
List<Placemark> getPlacemarksNear(double latDeg, double lngDeg, float radius) throws IOException, ParseException;
/**
* Returns a list of {@link Placemark Placemarks} near the given {@link Position}.
*
* @param position The position where to search
* @param radius The search radius
* @return A list of {@link Placemark Placemarks} near the given {@link Position}
* @throws IOException
* @throws ParseException
*/
List<Placemark> getPlacemarksNear(Position position, float radius) throws IOException, ParseException;
/**
* Searches for {@link Placemark Placemarks} near the given coordinates via
* {@link ReverseGeocoder#getPlacemarkNearest(double, double) getPlacemarkNearest} and sorts them with
* <code>comp</code>. Returns the last element in the sorted list.<br /><br />
* The interface {@link Placemark} contains some Comparators for Placemarks.
*
* @param latDeg Latitude in degrees
* @param lngDeg Longitude in degrees
* @param radius The search radius
* @param comp Sorts the list
* @return The last element in the sorted list
* @throws IOException
* @throws ParseException
*/
Placemark getPlacemarkLast(double latDeg, double lngDeg, float radius, Comparator<Placemark> comp)
throws IOException, ParseException;
/**
* Searches for {@link Placemark Placemarks} near the given {@link Position} via
* {@link ReverseGeocoder#getPlacemarkNearest(double, double) getPlacemarkNearest} and sorts them with
* <code>comp</code>. Returns the last element in the sorted list.<br /><br />
* The interface {@link Placemark} contains some Comparators for Placemarks.
*
* @param position The position where to search
* @param radius The search radius
* @param comp Sorts the list
* @return The last element in the sorted list
* @throws IOException
* @throws ParseException
*/
Placemark getPlacemarkLast(Position position, float radius, Comparator<Placemark> comp) throws IOException,
ParseException;
/**
* Searches for {@link Placemark Placemarks} near the given coordinates via
* {@link ReverseGeocoder#getPlacemarkNearest(double, double) getPlacemarkNearest} and sorts them with
* <code>comp</code>. Returns the first element in the sorted list.<br /><br />
* The interface {@link Placemark} contains some Comparators for Placemarks.
*
* @param latDeg Latitude in degrees
* @param lngDeg Longitude in degrees
* @param radius The search radius
* @param comp Sorts the list
* @return The first element in the sorted list
* @throws IOException
* @throws ParseException
*/
Placemark getPlacemarkFirst(double latDeg, double lngDeg, float radius, Comparator<Placemark> comp)
throws IOException, ParseException;
/**
* Searches for {@link Placemark Placemarks} near the given {@link Position} via
* {@link ReverseGeocoder#getPlacemarkNearest(double, double) getPlacemarkNearest} and sorts them with
* <code>comp</code>. Returns the first element in the sorted list.<br /><br />
* The interface {@link Placemark} contains some Comparators for Placemarks.
*
* @param position The position where to search
* @param radius The search radius
* @param comp Sorts the list
* @return The first element in the sorted list
* @throws IOException
* @throws ParseException
*/
Placemark getPlacemarkFirst(Position position, float radius, Comparator<Placemark> comp) throws IOException,
ParseException;
}
@@ -47,8 +47,8 @@ public class PlacemarkImpl implements Placemark {
@Override
public Distance distanceFrom(Position p) {
return position.getDistance(p);
public Distance distanceFrom(Position position) {
return this.position.getDistance(position);
}
@Override
public Distance distanceFrom(double latDeg, double lngDeg) {
@@ -61,6 +61,18 @@ public class PlacemarkImpl implements Placemark {
// TODO Get country name from CountryCodeFactoryImpl with countryCode
return null;
}
@Override
public String toString() {
StringBuilder b = new StringBuilder(Placemark.class.getSimpleName() + "[");
b.append(name + ", ");
b.append(countryCode + ", ");
b.append(position.toString() + ", ");
b.append(type + ", ");
b.append(population + "]");
return b.toString();
}
@Override
public int hashCode() {
@@ -22,12 +22,12 @@ import com.sap.sailing.geocoding.Placemark;
import com.sap.sailing.geocoding.ReverseGeocoder;
public class ReverseGeocoderImpl implements ReverseGeocoder {
private final String NEARBY_PLACE_SERVICE = "http://api.geonames.org/findNearbyPlaceNameJSON?";
private int maxRows = 500;
@Override
public Placemark getPlacemark(double latDeg, double lngDeg) throws IOException, ParseException {
public Placemark getPlacemarkNearest(double latDeg, double lngDeg) throws IOException, ParseException {
Placemark p = null;
StringBuilder url = new StringBuilder(NEARBY_PLACE_SERVICE);
@@ -45,22 +45,24 @@ public class ReverseGeocoderImpl implements ReverseGeocoder {
return p;
}
@Override
public Placemark getPlacemark(Position p) throws IOException, ParseException {
return getPlacemark(p.getLatDeg(), p.getLngDeg());
public Placemark getPlacemarkNearest(Position position) throws IOException, ParseException {
return getPlacemarkNearest(position.getLatDeg(), position.getLngDeg());
}
@Override
public List<Placemark> getPlacemarkNear(double latDeg, double lngDeg, float radius) throws IOException, ParseException {
public List<Placemark> getPlacemarksNear(double latDeg, double lngDeg, float radius) throws IOException,
ParseException {
List<Placemark> placemarks = new ArrayList<Placemark>();
StringBuilder url = new StringBuilder(NEARBY_PLACE_SERVICE);
url.append("&lat=" + Double.toString(latDeg));
url.append("&lng=" + Double.toString(lngDeg));
url.append("&radius=" + Float.toString(radius));
url.append("&maxRows=" + Integer.toString(maxRows));
url.append("&username=" + GEONAMES_USER);
URL request = new URL(url.toString());
URLConnection connection = request.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
@@ -72,33 +74,55 @@ public class ReverseGeocoderImpl implements ReverseGeocoder {
JSONObject object = (JSONObject) iterator.next();
placemarks.add(JSONToPlacemark(object));
}
return placemarks;
}
@Override
public List<Placemark> getPlacemarkNear(Position p, float radius) throws IOException, ParseException {
return getPlacemarkNear(p.getLatDeg(), p.getLngDeg(), radius);
}
@Override
public Placemark getPlacemarkBest(double latDeg, double lngDeg, float radius, Comparator<Placemark> comp) throws IOException, ParseException {
List<Placemark> placemarks = getPlacemarkNear(latDeg, lngDeg, radius);
Collections.sort(placemarks, comp);
public List<Placemark> getPlacemarksNear(Position position, float radius) throws IOException, ParseException {
return getPlacemarksNear(position.getLatDeg(), position.getLngDeg(), radius);
}
@Override
public Placemark getPlacemarkLast(double latDeg, double lngDeg, float radius, Comparator<Placemark> comp)
throws IOException, ParseException {
List<Placemark> placemarks = getPlacemarksNearSorted(latDeg, lngDeg, radius, comp);
return placemarks.get(placemarks.size() - 1);
}
@Override
public Placemark getPlacemarkBest(Position p, float radius, Comparator<Placemark> comp) throws IOException,
public Placemark getPlacemarkLast(Position position, float radius, Comparator<Placemark> comp) throws IOException,
ParseException {
return getPlacemarkBest(p.getLatDeg(), p.getLngDeg(), radius, comp);
return getPlacemarkLast(position.getLatDeg(), position.getLngDeg(), radius, comp);
}
@Override
public Placemark getPlacemarkFirst(double latDeg, double lngDeg, float radius, Comparator<Placemark> comp)
throws IOException, ParseException {
return getPlacemarksNearSorted(latDeg, lngDeg, radius, comp).get(0);
}
@Override
public Placemark getPlacemarkFirst(Position position, float radius, Comparator<Placemark> comp) throws IOException,
ParseException {
return getPlacemarkFirst(position.getLatDeg(), position.getLngDeg(), radius, comp);
}
private List<Placemark> getPlacemarksNearSorted(double latDeg, double lngDeg, float radius,
Comparator<Placemark> comp) throws IOException, ParseException {
List<Placemark> placemarks = getPlacemarksNear(latDeg, lngDeg, radius);
Collections.sort(placemarks, comp);
return placemarks;
}
private Placemark JSONToPlacemark(JSONObject json) {
String name = (String) json.get("toponymName");
String countryCode = (String) json.get("countryCode");
//Tries are necessary, because some latitude or longitude values delivered by Geonames have no decimal places and are interpreted as Long
//Casting a Long to a Double raises a ClassCastException
// Tries are necessary, because some latitude or longitude values delivered by Geonames have no decimal places
// and are interpreted as Long
// Casting a Long to a Double raises a ClassCastException
Double latDeg = null;
try {
latDeg = (Double) json.get("lat");
@@ -112,15 +136,15 @@ public class ReverseGeocoderImpl implements ReverseGeocoder {
lngDeg = ((Long) json.get("lng")).doubleValue();
}
Position p = new DegreePosition(latDeg, lngDeg);
String type = (String) json.get("fcl");
long population = (Long) json.get("population");
if (name != null && lngDeg != null && latDeg != null) {
return new PlacemarkImpl(name, countryCode, p, type, population);
} else {
return null;
}
}
}