package service;
import api.v1.*;
import com.ibm.util.CoordinateConversion;
import exceptions.PoseidonException;
import play.mvc.Http;
public class CoordinateConversionService extends PoseidonService {
public CoordinateConversionService(String USER) {
super(USER);
}
public Position convertCoordinates(Position apiPosition) {
CoordinateConversion coordinateConversion = new CoordinateConversion();
Position result = clonePosition(apiPosition);
checkPositionParams(apiPosition);
switch (apiPosition.coordinateFormat) {
case DECIMAL_DEGREES:
result.dms = dec2dms(apiPosition, coordinateConversion);
result.utm = dec2utm(apiPosition, coordinateConversion);
break;
case DEGREES_MINUTES_SECONDS:
result.dec = dms2latlon(apiPosition, coordinateConversion);
result.utm = dms2utm(apiPosition, coordinateConversion);
break;
case UTM:
result.dec = utm2latlon(apiPosition, coordinateConversion);
result.dms = utm2dms(apiPosition, coordinateConversion);
break;
}
return result;
}
private void checkPositionParams(Position apiPosition) {
switch (apiPosition.coordinateFormat){
case DECIMAL_DEGREES:
if ( apiPosition.dec.getLatitude() == null ){
throw new PoseidonException(Http.Status.BAD_REQUEST,"Breddegrad ikke angitt");
}
if ( apiPosition.dec.getLongitude() == null ){
throw new PoseidonException(Http.Status.BAD_REQUEST,"Lengdegrad ikke angitt");
}
break;
case DEGREES_MINUTES_SECONDS:
if ( apiPosition.dms.latDeg == null){
throw new PoseidonException(Http.Status.BAD_REQUEST,"Breddegrad ikke angitt");
}
if ( apiPosition.dms.latMin == null){
throw new PoseidonException(Http.Status.BAD_REQUEST,"Breddegrad minutter ikke angitt");
}
if ( apiPosition.dms.latSec == null){
throw new PoseidonException(Http.Status.BAD_REQUEST,"Breddegrad sekunder ikke angitt");
}
if ( apiPosition.dms.longDeg == null){
throw new PoseidonException(Http.Status.BAD_REQUEST,"Lengdegrad ikke angitt");
}
if ( apiPosition.dms.longMin == null){
throw new PoseidonException(Http.Status.BAD_REQUEST,"Lengdegrad minutter ikke angitt");
}
if ( apiPosition.dms.longSec == null){
throw new PoseidonException(Http.Status.BAD_REQUEST,"Lengdegrad sekunder ikke angitt");
}
break;
case UTM:
if ( apiPosition.utm.zone == null ){
throw new PoseidonException(Http.Status.BAD_REQUEST,"UTM Zone ikke angitt");
}
if ( apiPosition.utm.band == null ){
throw new PoseidonException(Http.Status.BAD_REQUEST,"UTM Bånd ikke angitt");
}
if ( apiPosition.utm.easting== null ){
throw new PoseidonException(Http.Status.BAD_REQUEST,"UTM Øst ikke angitt");
}
if ( apiPosition.utm.northing == null ){
throw new PoseidonException(Http.Status.BAD_REQUEST,"UTM Nord ikke angitt");
}
break;
}
}
public PositionDMS utm2dms(Position apiPosition, CoordinateConversion coordinateConversion) {
PositionDMS dms = new PositionDMS();
CoordinateConversion.UTM utm = new CoordinateConversion.UTM();
PositionUTM apiUtm = apiPosition.utm;
utm.zone = apiUtm.zone;
utm.band = apiUtm.band;
utm.northing = apiUtm.northing;
utm.easting = apiUtm.easting;
double[] latLong = coordinateConversion.utm2LatLon(utm);
double[] coord = coordinateConversion.latLon2dms(latLong[0], latLong[1]);
dms.latDirection = coord[0]>=0.0?"N":"S";
dms.longDirection = coord[3]>=0.0?"E":"W";
dms.latDeg = (int) Math.abs(coord[0]);
dms.latMin = (int) coord[1];
dms.latSec = (int) coord[2];
dms.longDeg = (int) Math.abs(coord[3]);
dms.longMin = (int) coord[4];
dms.longSec = (int) coord[5];
return dms;
}
public PositionDecimalDegrees utm2latlon(Position apiPosition, CoordinateConversion coordinateConversion) {
PositionDecimalDegrees dec = new PositionDecimalDegrees();
CoordinateConversion.UTM utm = new CoordinateConversion.UTM();
PositionUTM apiUtm = apiPosition.utm;
utm.zone = apiUtm.zone;
utm.band = apiUtm.band;
utm.northing = apiUtm.northing;
utm.easting = apiUtm.easting;
double[] latLong = coordinateConversion.utm2LatLon(utm);
dec.setLatitude(latLong[0]);
dec.setLongitude(latLong[1]);
return dec;
}
public PositionUTM dms2utm(Position apiPosition, CoordinateConversion coordinateConversion) {
PositionUTM utm = new PositionUTM();
{
PositionDMS dms = apiPosition.dms;
Integer latDeg = dms.latDeg;
Integer longDeg = dms.longDeg;
if ( dms.latDirection != null) {
if (dms.latDirection.equals("S")) latDeg = -Math.abs(latDeg);
} else {
dms.latDirection = dms.latDeg < 0 ? "S":"N";
}
if ( dms.longDirection != null) {
if (dms.longDirection.equals("W")) longDeg = -Math.abs(longDeg);
} else {
dms.longDirection = dms.longDeg < 0 ? "W":"E";
}
double[] latLong = coordinateConversion.dms2LatLon(latDeg, dms.latMin, dms.latSec, longDeg, dms.longMin, dms.longSec);
CoordinateConversion.UTM coord = coordinateConversion.latLon2UTM(latLong[0], latLong[1]);
utm.zone = coord.zone;
utm.band = coord.band;
utm.easting = coord.easting;
utm.northing = coord.northing;
}
return utm;
}
public PositionDecimalDegrees dms2latlon(Position apiPosition, CoordinateConversion coordinateConversion) {
PositionDecimalDegrees dec = new PositionDecimalDegrees();
{
PositionDMS dms = apiPosition.dms;
int latDeg = dms.latDeg!=null?dms.latDeg:0;
latDeg = "N".equals(dms.latDirection)?Math.abs(latDeg):-Math.abs(latDeg);
if ( dms.latDirection.equals("S")) latDeg = -latDeg;
int latMin = dms.latMin!=null?dms.latMin:0;
int latSec = dms.latSec!=null?dms.latSec:0;
int lonDeg = dms.longDeg!=null?dms.longDeg:0;
lonDeg = "E".equals(dms.longDirection)?Math.abs(lonDeg):-Math.abs(lonDeg);
int lonMin = dms.longMin!=null?dms.longMin:0;
int lonSec = dms.longSec!=null?dms.longSec:0;
double[] latLong = coordinateConversion.dms2LatLon(latDeg, latMin, latSec, lonDeg, lonMin, lonSec);
dec.setLatitude(latLong[0]);
dec.setLongitude(latLong[1]);
}
return dec;
}
public PositionUTM dec2utm(Position apiPosition, CoordinateConversion coordinateConversion) {
CoordinateConversion.UTM coord = coordinateConversion.latLon2UTM(apiPosition.dec.getLatitude(), apiPosition.dec.getLongitude());
PositionUTM utm = new PositionUTM();
utm.zone = coord.zone;
utm.band = coord.band;
utm.easting = coord.easting;
utm.northing = coord.northing;
return utm;
}
public PositionDMS dec2dms(Position apiPosition, CoordinateConversion coordinateConversion) {
double[] coord = coordinateConversion.latLon2dms(apiPosition.dec.getLatitude(), apiPosition.dec.getLongitude());
PositionDMS dms = new PositionDMS();
dms.latDirection = coord[0] > 0 ? "N":"S";
dms.longDirection = coord[3] > 0 ? "E":"W";
dms.latDeg = (int)(Math.abs(coord[0]));
dms.latMin = (int) coord[1];
dms.latSec = (int) coord[2];
dms.longDeg = (int)(Math.abs(coord[3]));
dms.longMin = (int) coord[4];
dms.longSec = (int) coord[5];
return dms;
}
private Position clonePosition(Position apiPosition) {
Position p = new Position();
p.id = apiPosition.id;
p.name = apiPosition.name;
p.alias = apiPosition.alias;
p.coordinateFormat = apiPosition.coordinateFormat;
p.isDeletable = apiPosition.isDeletable;
if (apiPosition.dec != null) {
p.dec = new PositionDecimalDegrees();
p.dec.setLatitude(apiPosition.dec.getLatitude());
p.dec.setLongitude(apiPosition.dec.getLongitude());
}
if (apiPosition.dms != null) {
p.dms = new PositionDMS();
p.dms.latDeg = apiPosition.dms.latDeg;
p.dms.latMin = apiPosition.dms.latMin;
p.dms.latSec = apiPosition.dms.latSec;
p.dms.latDirection = apiPosition.dms.latDirection;
p.dms.longDeg = apiPosition.dms.longDeg;
p.dms.longMin = apiPosition.dms.longMin;
p.dms.longSec = apiPosition.dms.longSec;
p.dms.longDirection = apiPosition.dms.longDirection;
}
if ( apiPosition.utm != null ) {
p.utm = new PositionUTM();
p.utm.zone = apiPosition.utm.zone;
p.utm.band = apiPosition.utm.band;
p.utm.easting = apiPosition.utm.easting;
p.utm.northing = apiPosition.utm.northing;
}
if ( apiPosition.tags != null ) {
p.tags = new PositionTag[apiPosition.tags.length];
for(int i=0;i<apiPosition.tags.length;i++){
PositionTag tag = apiPosition.tags[i];
p.tags[i] = new PositionTag(tag.id,tag.name);
}
}
return p;
}
}