/*
Copyright (C) 2001, 2006 United States Government as represented by
the Administrator of the National Aeronautics and Space Administration.
All Rights Reserved.
*/
package gov.nasa.worldwind.formats.rpf;
import gov.nasa.worldwind.util.Logging;
/**
* @author dcollins
* @version $Id: RPFPolarFrameStructure.java 4852 2008-03-28 19:14:52Z dcollins $
*/
class RPFPolarFrameStructure extends RPFFrameStructure
{
private final int polarPixelConstant;
private final double polewardExtent;
private final double equatorwardExtent;
private final int polarFrames;
private RPFPolarFrameStructure(
int polarPixelConstant,
double polewardExtent, double equatorwardExtent,
int polarFrames)
{
this.polarPixelConstant = polarPixelConstant;
this.polewardExtent = polewardExtent;
this.equatorwardExtent = equatorwardExtent;
this.polarFrames = polarFrames;
}
public static RPFPolarFrameStructure computeStructure(char zoneCode, String rpfDataType, double resolution)
{
if (!RPFZone.isZoneCode(zoneCode))
{
String message = Logging.getMessage("RPFZone.UnknownZoneCode", zoneCode);
Logging.logger().fine(message);
throw new IllegalArgumentException(message);
}
if (rpfDataType == null || !RPFDataSeries.isRPFDataType(rpfDataType))
{
String message = Logging.getMessage("RPFDataSeries.UnkownDataType", rpfDataType);
Logging.logger().fine(message);
throw new IllegalArgumentException(message);
}
if (resolution < 0)
{
String message = Logging.getMessage("generic.ArgumentOutOfRange", rpfDataType);
Logging.logger().fine(message);
throw new IllegalArgumentException(message);
}
int nsPixelSpacingConst = northSouthPixelSpacingConstant();
int polarPixelConst, polarFrames;
if (RPFDataSeries.isCADRGDataType(rpfDataType))
{
polarPixelConst = polarPixelConstant_CADRG(nsPixelSpacingConst, resolution);
polarFrames = polarFrames_CADRG(polarPixelConst);
}
else if (RPFDataSeries.isCIBDataType(rpfDataType))
{
int nsPixelConst = northSouthPixelConstant_CIB(nsPixelSpacingConst, resolution);
polarPixelConst = polarPixelConstant_CIB(nsPixelConst);
polarFrames = polarFrames_CIB(polarPixelConst);
}
else
{
polarPixelConst = -1;
polarFrames = -1;
}
double polewardExtent = polewardExtent(polewardNominalBoundary(zoneCode));
double equatorwardExtent = equatorwardExtent(equatorwardNominalBoundary(zoneCode));
return new RPFPolarFrameStructure(
polarPixelConst,
polewardExtent, equatorwardExtent,
polarFrames);
}
public final int getPolarPixelConstant()
{
return this.polarPixelConstant;
}
public final double getPolewardExtent()
{
return this.polewardExtent;
}
public final double getEquatorwardExtent()
{
return this.equatorwardExtent;
}
public final int getPolarFrames()
{
return this.polarFrames;
}
// TODO: include supporting sources for CADRG in docs
/* [Section A.5.1.1, MIL-PRF-89041A] */
private static int northSouthPixelConstant_CIB(double northSouthPixelSpacingConstant, double groundSampleDistance)
{
double S = 100d / groundSampleDistance;
double tmp = northSouthPixelSpacingConstant * S;
tmp = 512d * (int) Math.ceil(tmp / 512d);
tmp /= 4d;
return 256 * (int) Math.round(tmp / 256d);
}
/* [Section 60.2.1, MIL-C-89038] */
private static int polarPixelConstant_CADRG(double northSouthPixelSpacingConstant, double scale)
{
double S = 1000000d / scale;
double tmp = northSouthPixelSpacingConstant * S;
tmp = 512d * (int) Math.ceil(tmp / 512d);
tmp *= (20d / 360d);
tmp /= (150d / 100d);
tmp = 512d * (int) Math.round(tmp / 512d);
return (int) (tmp * 360d / 20d);
}
/* [Section A.5.2.1, MIL-PRF-89041A */
private static int polarPixelConstant_CIB(double northSouthPixelConstant)
{
double tmp = northSouthPixelConstant * 20d / 90d;
tmp = 512d * (int) Math.round(tmp / 512d);
return (int) (tmp * 90d / 20d);
}
/* [Section 60.2.3, MIL-C-89038] */
private static int polarFrames_CADRG(double polarPixelConstant)
{
double tmp = polarPixelConstant * 20d / 360d;
tmp /= 256d;
tmp /= 6d;
tmp = Math.ceil(tmp);
if (((int) tmp) % 2 == 0)
tmp = tmp + 1;
return (int) tmp;
}
/* [Section A.5.2.2, MIL-PRF-89041A] */
private static int polarFrames_CIB(double polarPixelConstant)
{
double tmp = polarPixelConstant * 20d / 90d;
tmp /= 256d;
tmp += 4d;
tmp /= 6d;
tmp = Math.ceil(tmp);
if (((int) tmp) % 2 == 0)
tmp = tmp + 1;
return (int) tmp;
}
/* [Section A.5.2.3, MIL-PRF-89041A] */
private static double polewardExtent(double polewardNominalBoundary)
{
return polewardNominalBoundary;
}
/* [Section A.5.2.3, MIL-PRF-89041A] */
private static double equatorwardExtent(double equatorwardNominalBoundary)
{
return equatorwardNominalBoundary;
}
}