Skip to content
Snippets Groups Projects
Commit 7d23b46b authored by Hallvard Trætteberg's avatar Hallvard Trætteberg
Browse files

Classes for geo-locations and sets of them, according to issue #3.

parent f4a5bd16
No related branches found
No related tags found
No related merge requests found
package tdt4140.gr1800.app.core;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Optional;
import java.util.stream.Collectors;
public class GeoLocations implements Iterable<LatLong> {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private Collection<LatLong> locations = new ArrayList<LatLong>();
private boolean path = false;
public GeoLocations(LatLong...latLongs) {
for (int i = 0; i < latLongs.length; i++) {
addLocation(latLongs[i]);
}
}
public GeoLocations(String name, LatLong...latLongs) {
this(latLongs);
setName(name);
}
public boolean isPath() {
return path;
}
public void setPath(boolean path) {
this.path = path;
}
public Comparator<? super LatLong> latLongComparator(LatLong latLong) {
return (latLong1, latLong2) -> (int) Math.signum(latLong.distance(latLong1) - latLong.distance(latLong2));
}
public Collection<LatLong> findLocationsNearby(LatLong latLong, double distance) {
return locations.stream()
.filter(latLong2 -> latLong.distance(latLong2) <= distance)
.sorted(latLongComparator(latLong))
.collect(Collectors.toList());
}
public LatLong findNearestLocation(LatLong latLong) {
Optional<LatLong> min = locations.stream()
.min(latLongComparator(latLong));
return min.isPresent() ? min.get() : null;
}
//
public void addLocation(LatLong latLong) {
if (! locations.contains(latLong)) {
locations.add(latLong);
}
}
public void removeLocations(LatLong latLong, double distance) {
Iterator<LatLong> it = locations.iterator();
while (it.hasNext()) {
LatLong latLong2 = it.next();
if (latLong.distance(latLong2) <= distance) {
it.remove();
}
}
}
public int size() {
return locations.size();
}
@Override
public Iterator<LatLong> iterator() {
return locations.iterator();
}
}
package tdt4140.gr1800.app.core;
public class LatLong {
public final double latitude, longitude;
public LatLong(double latitude, double longitude) {
super();
this.latitude = latitude;
this.longitude = longitude;
}
public double distance(LatLong loc) {
return distance(this.latitude, this.longitude, loc.latitude, loc.longitude);
}
public final static String SEPARATOR = ",";
@Override
public String toString() {
return latitude + SEPARATOR + longitude;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
long temp;
temp = Double.doubleToLongBits(latitude);
result = prime * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(longitude);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
LatLong other = (LatLong) obj;
return (Double.doubleToLongBits(latitude) == Double.doubleToLongBits(other.latitude) &&
Double.doubleToLongBits(longitude) == Double.doubleToLongBits(other.longitude));
}
public static LatLong valueOf(String s) {
return valueOf(s, SEPARATOR);
}
public static LatLong valueOf(String s, String sep) {
int pos = s.indexOf(sep);
if (pos < 0) {
throw new IllegalArgumentException("No '" + sep + "' in " + s);
}
double lat = Double.valueOf(s.substring(0, pos).trim());
double lon = Double.valueOf(s.substring(pos + sep.length()).trim());
return new LatLong(lat, lon);
}
/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
/*:: :*/
/*:: This routine calculates the distance between two points (given the :*/
/*:: latitude/longitude of those points). It is being used to calculate :*/
/*:: the distance between two locations using GeoDataSource (TM) products :*/
/*:: :*/
/*:: Definitions: :*/
/*:: South latitudes are negative, east longitudes are positive :*/
/*:: :*/
/*:: Passed to function: :*/
/*:: lat1, lon1 = Latitude and Longitude of point 1 (in decimal degrees) :*/
/*:: lat2, lon2 = Latitude and Longitude of point 2 (in decimal degrees) :*/
/*:: Worldwide cities and other features databases with latitude longitude :*/
/*:: are available at http://www.geodatasource.com :*/
/*:: :*/
/*:: For enquiries, please contact sales@geodatasource.com :*/
/*:: :*/
/*:: Official Web site: http://www.geodatasource.com :*/
/*:: :*/
/*:: GeoDataSource.com (C) All Rights Reserved 2015 :*/
/*:: :*/
/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
public static double distance(double lat1, double lon1, double lat2, double lon2) {
double theta = lon1 - lon2;
double dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2)) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.cos(deg2rad(theta));
dist = Math.acos(dist);
// convert to degrees
dist = rad2deg(dist);
dist = dist * 60 * 1.1515;
// convert to meters
dist = dist * 1609.344;
return dist;
}
public static double distance(LatLong latLong1, LatLong latLong2) {
return distance(latLong1.latitude, latLong1.longitude, latLong2.latitude, latLong2.longitude);
}
/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
/*:: This function converts decimal degrees to radians :*/
/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
private static double deg2rad(double deg) {
return (deg * Math.PI / 180.0);
}
/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
/*:: This function converts radians to decimal degrees :*/
/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
private static double rad2deg(double rad) {
return (rad * 180 / Math.PI);
}
}
package tdt4140.gr1800.app.core;
import java.util.Collection;
import java.util.Iterator;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class GeoLocationsTest {
private GeoLocations geoLocations;
@Before
public void setUp() {
geoLocations = new GeoLocations();
}
@Test
public void testGeoLocations() {
Assert.assertEquals(0, geoLocations.size());
Assert.assertEquals(1, new GeoLocations(new LatLong(0, 0)).size());
Assert.assertEquals(1, new GeoLocations(new LatLong(0, 0), new LatLong(0, 0)).size());
Assert.assertEquals(2, new GeoLocations(new LatLong(0, 0), new LatLong(1, 1)).size());
}
private void assertGeoLocations(LatLong...latLongs) {
assertGeoLocations(geoLocations, latLongs);
}
public static void assertGeoLocations(GeoLocations geoLocations, LatLong...latLongs) {
Iterator<LatLong> it = geoLocations.iterator();
Assert.assertEquals(latLongs.length, geoLocations.size());
int pos = 0;
while (it.hasNext()) {
Assert.assertEquals(latLongs[pos], it.next());
pos++;
}
}
@Test
public void testAddLocation() {
Assert.assertEquals(0, geoLocations.size());
LatLong latLong1 = new LatLong(0, 0);
geoLocations.addLocation(latLong1);
assertGeoLocations(latLong1);
geoLocations.addLocation(new LatLong(0, 0));
assertGeoLocations(latLong1);
LatLong latLong2 = new LatLong(1, 1);
geoLocations.addLocation(latLong2);
assertGeoLocations(latLong1, latLong2);
}
@Test
public void testFindLocationsNearby() {
LatLong latLong = new LatLong(0, 0);
Assert.assertTrue(geoLocations.findLocationsNearby(latLong, 0).isEmpty());
geoLocations.addLocation(latLong);
Collection<LatLong> locationsNearby = geoLocations.findLocationsNearby(latLong, 0);
Assert.assertEquals(1, locationsNearby.size());
Assert.assertEquals(latLong, geoLocations.iterator().next());
}
@Test
public void testFindNearestLocation() {
LatLong latLong = new LatLong(0, 0);
Assert.assertNull(geoLocations.findNearestLocation(latLong));
geoLocations.addLocation(latLong);
LatLong nearestlocations = geoLocations.findNearestLocation(latLong);
Assert.assertEquals(latLong, nearestlocations);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment