private static Wpt wptFromGpsTag(IFD gps) throws MetadataException, ParseException{
if(gps == null){
return null;
}
Wpt result = new Wpt();
Rational[] r3 = new Rational[3];
/* map datum */
Entry e = gps.getEntry(Exif.GPSMapDatum, 0);
if(e == null){
warn("GPS datum missing. Assuming WGS84.");
} else {
Object value = e.getValue(0);
String svalue = String.valueOf(value);
if(value == null || svalue.equals("")){
System.err.println("Warning: GPS datum missing. Assuming WGS84.");
} else if(!svalue.toUpperCase().replaceAll("[^0-9A-Z]", "").equals("WGS84")){
throw new MetadataException("GPS datum is " + value.toString() +
". Currently only coordinates in the WGS84 "+
"map datum can be handled.");
}
}
/* latitude */
e = gps.getEntry(Exif.GPSLatitude, 0);
if(e == null){
throw new MetadataException("GPS latitude missing.");
}
r3 = getRationalTripleValue(e, r3);
e = gps.getEntry(Exif.GPSLatitudeRef, 0);
if(e == null){
String sysprop = System.getProperty("DefaultGPSLatitudeRef");
char s0 = (sysprop == null || sysprop.length() == 0)
? 'X'
: sysprop.toUpperCase().charAt(0);
if(s0 != 'N' && s0 != 'S'){
throw new MetadataException("GPS latitude found but GPS latitude reference missing or invalid.\n"+
" To use the GPS latitude information set the DefaultGPSLatitudeRef system property to N or S, e. g.\n"+
" java -DDefaultGPSLatitudeRef=N -jar gpsdings.jar ...");
}
result.setLat(asBigDecimalDegrees(r3, String.valueOf(s0)));
} else {
result.setLat(asBigDecimalDegrees(r3, String.valueOf(e.getValue(0))));
}
/* longitude */
e = gps.getEntry(Exif.GPSLongitude, 0);
if(e == null){
throw new MetadataException("GPS longtude missing.");
}
r3 = getRationalTripleValue(e, r3);
e = gps.getEntry(Exif.GPSLongitudeRef, 0);
if(e == null){
String sysprop = System.getProperty("DefaultGPSLongitudeRef");
final char s0 = (sysprop == null || sysprop.length() == 0)
? 'X'
: sysprop.toUpperCase().charAt(0);
if(s0 != 'E' && s0 != 'W'){
throw new MetadataException("GPS longitude found but GPS longitude reference missing or invalid.\n"+
" To use the GPS longitude information set the DefaultGPSLongitudeRef system property to W or E, e. g.\n"+
" java -DDefaultGPSLongitudeRef=E -jar gpsdings.jar ...");
}
result.setLon(asBigDecimalDegrees(r3, String.valueOf(s0)));
} else {
result.setLon(asBigDecimalDegrees(r3, String.valueOf(e.getValue(0))));
}
/* elevation */
if(gps.getEntry(Exif.GPSAltitude, 0) != null){
double alti = 1;
if (gps.getEntry(Exif.GPSAltitudeRef, 0) == null){
warn("GPSAltitudeRef missing. Assuming above sea level.");
} else {
e = gps.getEntry(Exif.GPSAltitudeRef, 0);
alti *= ((Integer) e.getValue(0)).intValue() * (-2) + 1; // 0 -> 1 && 1 -> -1
if (Math.abs(alti) != 1 ){
alti = 1;
System.err.printf("WARNING: illegal GPSAltitudeRef %d. Assuming above sea level.\n",
((Integer) e.getValue(0)).intValue());
}
}
e = gps.getEntry(Exif.GPSAltitude, 0);
alti *= ((Rational) e.getValue(0)).floatValue();
result.setEle(new BigDecimal(alti));
}
/* dateTime */
if(gps.getEntry(Exif.GPSTimeStamp, 0) != null &&
gps.getEntry(Exif.GPSDateStamp, 0) != null){
e = gps.getEntry(Exif.GPSTimeStamp, 0);
r3 = getRationalTripleValue(e, r3);
long millis = Math.round(asDouble(r3, 3.6e6));
e = gps.getEntry(Exif.GPSDateStamp, 0);
Date d = null;
if(e.getType() == Exif.ASCII){
try{
d = AbstractExecExifWriter.parseExifDate(String.valueOf(e.getValue(0)));
d = new Date(d.getTime() + millis);
result.setTime(d);
} catch (ParseException ex){
System.err.println(ex);
}
}
if(d == null) {