I have had reason to pursue a similar goal in the past where accuracy is not of huge importance. We can start by getting the Earth's radius according to the WGS84 Well-Known Text definition.
GEOGCS["WGS 84",
DATUM["WGS_1984",
SPHEROID["WGS 84",6378137,298.257223563,
AUTHORITY["EPSG","7030"]],
AUTHORITY["EPSG","6326"]],
PRIMEM["Greenwich",0,
AUTHORITY["EPSG","8901"]],
UNIT["degree",0.01745329251994328,
AUTHORITY["EPSG","9122"]],
AUTHORITY["EPSG","4326"]]
To make sense of the angular distance units, you can use the following formula to convert angular units to meters:
angular_units * (PI/180) * 6378137
That should give you a reasonably accurate short-distance measurements in meters. The calculation is based on a perfect sphere (non-ellipsoidal).
GDAL is your best bet here. My code sample is in C++, however the Java bindings have the same essential API, so the concept will carry over.
This is code chopped from another project. The key is to create two SpatialReference objects, then set their datums. For the output, since it is in UTM, you set the UTM zone there. Normally, you pick the best utm grid zone based on the longitude, but since you need it in another, you can just manually set it to what you want.
/**
* Compute the best utm zone. (Just don't go to Svalbard)
*/
int compute_utm_zone( CoordinateLatLon const& coord, bool& isNorth ){
// check the isNorth flag
if( coord.lat >= 0 ) isNorth = true;
else isNorth = false;
// compute the appropriate UTM Zone
int zone = std::floor(( coord.lon + 180 )/6.0) + 1;
return zone;
}
CoordinateUTM convert_coordinate( CoordinateLatLon const& coord ){
// create the spatial reference objects
OGRSpatialReference sourceSRS, targetSRS;
// set the required datim
sourceSRS.SetWellKnownGeogCS( coord.datum.c_str() ); // "WGS84"
targetSRS.SetWellKnownGeogCS( coord.datum.c_str() ); // "WGS84"
// specify the target as UTM and compute proper zone and hemisphere
bool isNorth;
int zone = compute_utm_zone( coord, isNorth );
targetSRS.SetUTM( zone, isNorth );
// create the coordinate transform
OGRCoordinateTransformation *poTransform = OGRCreateCoordinateTransformation( &sourceSRS, &targetSRS );
if( poTransform == NULL ){
throw string("ERROR: call failed");
}
double x = coord.lon;
double y = coord.lat;
double z = coord.elevation;
if( !poTransform->Transform( 1, &x, &y, &z ) )
throw string("ERROR: transform failed");
OCTDestroyCoordinateTransformation( poTransform );
return CoordinateUTM( zone, isNorth, x, y, z, coord.datum );
}
Link to OSR Bindings
http://gdal.org/java/org/gdal/osr/package-summary.html
Best Answer
I have found, combined and translate to Java something like that. But i dont know about how precise it is. It returns northing(XXXXXXX.XXXXXm) and easting(NXXXXXX.XXXXXm) in meters. N-zone number