/*
* Copyright (C) 2014 Alec Dhuse
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package co.foldingmap.imaging;
/*
* Copyright 2013 Alec Dhuse
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import java.text.SimpleDateFormat;
import java.util.*;
/**
* Represents a four dimensional point where/when an photo was taken.
*/
public final class GeoTag {
private double altitude, latitude, longitude;
private GregorianCalendar calendar;
private String latitudeRef, longitudeRef;
/**
* Default constructor with no parameters. Information is added through
* the set methods.
*
*/
public GeoTag() {
calendar = new GregorianCalendar();
latitudeRef = "";
longitudeRef = "";
calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
}
/**
*
* @return the latitude in decimal degrees.
*/
public double getLatitude() {
return this.latitude;
}
/**
* @return the Altitude of this location, in meters above sea level.
*/
public double getAltitude() {
return this.altitude;
}
/**
*
* @return the date as UTC milliseconds from the epoch.
*/
public long getDateInMillis() {
return calendar.getTimeInMillis();
}
/**
* @return the longitude in decimal degrees.
*/
public double getLongitude() {
return this.longitude;
}
/**
*
* @return If the Latitude is (N)orth or (S)outh.
*/
public String getLatitudeReference() {
return this.latitudeRef;
}
/**
*
* @return If the Longitude is (E)ast or (W)est.
*/
public String getLongitudeReference() {
return this.longitudeRef;
}
/**
*
* @return the timestamp as a string in the format yyyy-MM-dd'T'hh:mm:ssZ
*/
public String getTimestamp() {
SimpleDateFormat timestampDateFormat;
timestampDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'kk:mm:ss");
timestampDateFormat.setTimeZone(new SimpleTimeZone(0, "Z"));
return timestampDateFormat.format(calendar.getTimeInMillis()) + "Z";
}
/**
* Converts degrees-minutes-seconds into a single value in decimal degrees.
*
* @param degs
* @param mins
* @param secs
* @return Decimal degrees value from the degrees, minutes and seconds vals.
*/
public static double degreesToDecimal(double degs, double mins, double secs) {
double decimal = Math.abs(degs) + (mins / 60) + (secs / 3600);
return decimal;
}
/**
* Sets the altitude value.
*
* @param altitude In meters above sea level.
*/
public void setAltitude(double altitude) {
this.altitude = altitude;
}
/**
* Sets the date from a String value.
*
* @param date Must be in year:mm:dd format.
*/
public void setDate(String date) {
StringTokenizer st = new StringTokenizer(date, ":");
if (st.countTokens() == 3) {
calendar.set(Calendar.YEAR, Integer.parseInt(st.nextToken()));
calendar.set(Calendar.MONTH, Integer.parseInt(st.nextToken()) - 1);
calendar.set(Calendar.DAY_OF_MONTH, Integer.parseInt(st.nextToken()));
}
}
/**
* Sets the latitude value.
*
* @param latitude double value between -90 and 90.
*/
public void setLatitude(double latitude) {
this.latitude = latitude;
if (latitudeRef.equalsIgnoreCase("N")) {
if (this.latitude < 0)
this.latitude *= -1;
} else if (latitudeRef.equalsIgnoreCase("S")) {
if (this.latitude > 0)
this.latitude *= -1;
}
}
/**
* Sets the hemisphere or reference for the latitude.
*
* @param latitudeRef String value either "N" or "S".
*/
public void setLatitudeReference(String latitudeRef) {
this.latitudeRef = latitudeRef;
if (latitudeRef.equalsIgnoreCase("N")) {
if (latitude < 0)
latitude *= -1;
} else if (latitudeRef.equalsIgnoreCase("S")) {
if (latitude > 0)
latitude *= -1;
}
}
/**
* Sets the longitude value.
*
* @param longitude double value between -180 and 180.
*/
public void setLongitude(double longitude) {
this.longitude = longitude;
if (longitudeRef.equalsIgnoreCase("E")) {
if (this.longitude < 0)
this.longitude *= -1;
} else if (longitudeRef.equalsIgnoreCase("W")) {
if (this.longitude > 0)
this.longitude *= -1;
}
}
/**
* Sets the hemisphere or reference for the longitude.
*
* @param longitudeRef String value either "E" or "W".
*/
public void setLongitudeReference(String longitudeRef) {
this.longitudeRef = longitudeRef;
if (longitudeRef.equalsIgnoreCase("E")) {
if (longitude < 0)
longitude *= -1;
} else if (longitudeRef.equalsIgnoreCase("W")) {
if (longitude > 0)
longitude *= -1;
}
}
/**
* Sets the time for this GeoInfo Object.
*
* @param hour The hour in 24 hour format.
* @param min The minute.
* @param sec The second.
*/
public void setTime(double hour, double min, double sec) {
calendar.set(Calendar.HOUR_OF_DAY, (int) hour);
calendar.set(Calendar.MINUTE, (int) min);
calendar.set(Calendar.SECOND, (int) sec);
}
/**
* @return a string representation of this GeoInfo object.
*/
@Override
public String toString() {
return latitude + ", " + longitude + ", " + altitude + " " + getTimestamp();
}
}