package eu.hgross.blaubot.geobeacon;
import com.google.gson.Gson;
import eu.hgross.blaubot.core.BlaubotConstants;
import eu.hgross.blaubot.messaging.BlaubotMessage;
/**
* Contains helper methods for the geo beacon.
*/
public class GeoBeaconUtil {
private static final Gson gson = new Gson();
/**
* Wraps a geo beacon message into a blaubot message
*
* @param message the message
* @return the blaubot message
*/
public static BlaubotMessage geoBeaconMessageToBlaubotMessage(GeoBeaconMessage message) {
GeoBeaconMessageDTO dto = new GeoBeaconMessageDTO(message);
byte[] jsonBytes = gson.toJson(dto).getBytes(BlaubotConstants.STRING_CHARSET);
// wrap it and send
BlaubotMessage msg = new BlaubotMessage();
msg.setPayload(jsonBytes);
return msg;
}
public static GeoBeaconMessage blaubotMessageToGeoBeaconMessage(BlaubotMessage msg) {
final byte[] payload = msg.getPayload();
final String jsonData = new String(payload, BlaubotConstants.STRING_CHARSET);
final GeoBeaconMessageDTO geoBeaconMessageDTO = gson.fromJson(jsonData, GeoBeaconMessageDTO.class);
final GeoBeaconMessage geoBeaconMessage = new GeoBeaconMessage(geoBeaconMessageDTO);
return geoBeaconMessage;
}
/**
* Calculates the distance between two coordinates in KM using the harvesine formula.
*
* @param geoData1 containing lat and lon
* @param geoData2 containing lat and lon
* @return the distance in km
*/
public static double distanceBetweenGeoBeaconMessages(GeoData geoData1, GeoData geoData2) {
// conver to radian values
double lat1 = geoData1.getLatitude() * Math.PI / 180d;
double lon1 = geoData1.getLongitude() * Math.PI / 180d;
double lat2 = geoData2.getLatitude() * Math.PI / 180d;
double lon2 = geoData2.getLongitude() * Math.PI / 180d;
// diffs in x and y
double latDiff = lat2 - lat1;
double lonDiff = lon2 - lon1;
// harversine
double a = Math.sin(latDiff / 2d) * Math.sin(latDiff / 2d) + Math.cos(lat1)
* Math.cos(lat2) * Math.sin(lonDiff / 2d) * Math.sin(lonDiff / 2d);
double c = 2d * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
double distance = R * c;
return distance;
}
/**
* Earth's diameter in KM
*/
private static final double R = 6371d;
public static void main(String[] args) {
GeoData dortmund = new GeoData(51.512054, 7.463573, 1);
GeoData berlin = new GeoData(52.523403, 13.411400, 1);
System.out.println("Dortmund -> Berlin (should be 422,11 KM): " + distanceBetweenGeoBeaconMessages(dortmund, berlin));
}
}