Just follow up to my own past in case helps.
I'm sure I have just committed a terrible hack (knowing little about GIS) - but I only need this function for my unit tests - the production MYSQL database provides the spatial functions needed.
I added the code below to one of my own classes (but I guess it would go in GeoDB more formally?). It includes a haversine implementation (but maybe that should have come out of JTS or Hatbox - did not have time to research that :)
Anyway - it works but I'm pretty sure it's architecturally ugly in terms of reuse etc etc !!!
/**
* Provides an implementation of ST_Distance_Sphere using the Haversine formula
* @param wkb1 the first location
* @param wkb2 the second location
* @return the distance between the two locations
*/
public static double ST_Distance_Sphere( byte[] wkb1, byte[] wkb2 ) {
if ( wkb1 == null || wkb2 == null ) {
return -1;
}
Geometry g1 = GeoDB.gFromWKB(wkb1);
Geometry g2 = GeoDB.gFromWKB(wkb2);
return getHaverSineDistance(g1, g2);
}
/**
* Calculate the Haversine distance between two lat/long geometries
* @param wkb1 the first location
* @param wkb2 the second location
* @return the distance between the two locations
*/
private static double getHaverSineDistance(Geometry g1, Geometry g2)
{
double lat1 = Math.toRadians(g1.getCoordinate().x);
double lng1 = Math.toRadians(g1.getCoordinate().y);
double lat2 = Math.toRadians(g2.getCoordinate().x);
double lng2 = Math.toRadians(g2.getCoordinate().y);
double dlon = lng2 - lng1;
double dlat = lat2 - lat1;
double a = Math.pow((Math.sin(dlat/2)),2) + Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(dlon/2),2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return EARTH_RADIUS_IN_MILES * c;
}
And added the following to my schema:
CREATE ALIAS ST_Distance_Sphere FOR "uk.co.thirdbridge.core.tools.GeoTools.ST_Distance_Sphere";