/* 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.geom.LatLon; import gov.nasa.worldwind.geom.Sector; import gov.nasa.worldwind.util.Logging; /** * @author dcollins * @version $Id: RPFNonpolarFrameTransform.java 4852 2008-03-28 19:14:52Z dcollins $ */ @SuppressWarnings({"UnusedDeclaration"}) class RPFNonpolarFrameTransform extends RPFFrameTransform { private final char zoneCode; private final String rpfDataType; private final double resolution; private final RPFNonpolarFrameStructure frameStructure; private RPFNonpolarFrameTransform(char zoneCode, String rpfDataType, double resolution, RPFNonpolarFrameStructure frameStructure) { this.zoneCode = zoneCode; this.rpfDataType = rpfDataType; this.resolution = resolution; this.frameStructure = frameStructure; } static RPFNonpolarFrameTransform createNonpolarFrameTransform(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); } RPFNonpolarFrameStructure frameStructure = RPFNonpolarFrameStructure.computeStructure( zoneCode, rpfDataType, resolution); return new RPFNonpolarFrameTransform(zoneCode, rpfDataType, resolution, frameStructure); } public final char getZoneCode() { return this.zoneCode; } public final String getRpfDataType() { return this.rpfDataType; } public final double getResolution() { return this.resolution; } public final RPFFrameStructure getFrameStructure() { return this.frameStructure; } public int getFrameNumber(int row, int column) { return frameNumber(row, column, this.frameStructure.getLongitudinalFrames()); } public int getMaximumFrameNumber() { return maxFrameNumber(this.frameStructure.getLatitudinalFrames(), this.frameStructure.getLongitudinalFrames()); } public int getRows() { return this.frameStructure.getLatitudinalFrames(); } public int getColumns() { return this.frameStructure.getLongitudinalFrames(); } public LatLon computeFrameOrigin(int frameNumber) { if (frameNumber < 0 || frameNumber > getMaximumFrameNumber()) { String message = Logging.getMessage("generic.ArgumentOutOfRange", frameNumber); Logging.logger().severe(message); throw new IllegalArgumentException(message); } int row = frameRow(frameNumber, this.frameStructure.getLongitudinalFrames()); int col = frameColumn(frameNumber, row, this.frameStructure.getLongitudinalFrames()); double zoneLat = RPFZone.isZoneInUpperHemisphere(this.zoneCode) ? this.frameStructure.getEquatorwardExtent() : this.frameStructure.getPolewardExtent(); double n = frameOriginLatitude(row, this.frameStructure.getNorthSouthPixelConstant(), this.frameStructure.getPixelRowsPerFrame(), zoneLat); double w = frameOriginLongitude(col, this.frameStructure.getEastWestPixelConstant(), this.frameStructure.getPixelRowsPerFrame()); return LatLon.fromDegrees(n, w); } public Sector computeFrameCoverage(int frameNumber) { int maxFrameNumber = maxFrameNumber(this.frameStructure.getLatitudinalFrames(), this.frameStructure.getLongitudinalFrames()); if (frameNumber < 0 || frameNumber > maxFrameNumber) { String message = Logging.getMessage("generic.ArgumentOutOfRange", frameNumber); Logging.logger().severe(message); throw new IllegalArgumentException(message); } int row = frameRow(frameNumber, this.frameStructure.getLongitudinalFrames()); int col = frameColumn(frameNumber, row, this.frameStructure.getLongitudinalFrames()); double zoneLat = RPFZone.isZoneInUpperHemisphere(this.zoneCode) ? this.frameStructure.getEquatorwardExtent() : this.frameStructure.getPolewardExtent(); double n = frameOriginLatitude(row, this.frameStructure.getNorthSouthPixelConstant(), this.frameStructure.getPixelRowsPerFrame(), zoneLat); double s = n - frameDeltaLatitude(this.frameStructure.getNorthSouthPixelConstant(), this.frameStructure.getPixelRowsPerFrame()); double w = frameOriginLongitude(col, this.frameStructure.getEastWestPixelConstant(), this.frameStructure.getPixelRowsPerFrame()); double e = w + frameDeltaLongitude(this.frameStructure.getEastWestPixelConstant(), this.frameStructure.getPixelRowsPerFrame()); //e = normalizedDegreesLongitude(e); return Sector.fromDegrees(s, n, w, e); } //public int[] computeFramesInSector(Sector sector) //{ // if (sector == null) // { // String message = Logging.getMessage("nullValue.SectorIsNull"); // Logging.logger().fine(message); // throw new IllegalArgumentException(message); // } // // double minLat, maxLat; // if (this.frameStructure.getPolewardExtent() < this.frameStructure.getEquatorwardExtent()) // { // minLat = this.frameStructure.getPolewardExtent(); // maxLat = this.frameStructure.getEquatorwardExtent(); // } // else // { // minLat = this.frameStructure.getEquatorwardExtent(); // maxLat = this.frameStructure.getPolewardExtent(); // } // // Sector intersection = Sector.fromDegrees(minLat, maxLat, -180, 180).intersection(sector); // if (intersection == null) // return null; // // double zoneLat = RPFZone.isZoneInUpperHemisphere(this.zoneCode) ? // this.frameStructure.getEquatorwardExtent() : this.frameStructure.getPolewardExtent(); // int startRow = frameRow(intersection.getMinLatitude().degrees, // this.frameStructure.getNorthSouthPixelConstant(), this.frameStructure.getPixelRowsPerFrame(), // zoneLat); // int startCol = frameColumn(intersection.getMinLongitude().degrees, // this.frameStructure.getEastWestPixelConstant(), this.frameStructure.getPixelRowsPerFrame()); // int endRow = frameRow(intersection.getMaxLatitude().degrees, // this.frameStructure.getNorthSouthPixelConstant(), this.frameStructure.getPixelRowsPerFrame(), // zoneLat); // int endCol = frameColumn(intersection.getMaxLongitude().degrees, // this.frameStructure.getEastWestPixelConstant(), this.frameStructure.getPixelRowsPerFrame()); // // int numFrames = (endRow - startRow + 1) * (endCol - startCol + 1); // int[] frames = new int[numFrames]; // int index = 0; // for (int row = startRow; row <= endRow; row++) // { // for (int col = startCol; col <= endCol; col++) // { // frames[index++] = frameNumber(row, col, this.frameStructure.getLongitudinalFrames()); // } // } // // return frames; //} /* [Section 30.2.1 MIL-C-89038 ] */ private static double pixelLatitude_CADRG(double latFrameOrigin, int row, double northSouthPixelConstant) { return latFrameOrigin - (90d / northSouthPixelConstant) * row; } /* [Section 30.2.2 MIL-C-89038] */ private static double pixelLongitude_CADRG(double lonFrameOrigin, int col, double eastWestPixelConstant) { return lonFrameOrigin + (360d / eastWestPixelConstant) * col; } /* [Section A.3.2.1 MIL-PRF-89041A] */ private static double pixelLatitude_CIB(double latFrameOrigin, int row, double northSouthPixelConstant) { return latFrameOrigin - (90d / northSouthPixelConstant) * (row + 0.5); } /* [Section A.3.2.2 MIL-PRF-89041A] */ private static double pixelLongitude_CIB(double lonFrameOrigin, int col, double eastWestPixelConstant) { return lonFrameOrigin + (360d / eastWestPixelConstant) * (col + 0.5); } /* [Section 30.3.1, MIL-C-89038] */ /* [Section A.3.3.1, MIL-PRF-89041A] */ private static int frameRow(double latitude, double northSouthPixelConstant, double pixelRowsPerFrame, double zoneOriginLatitude) { return (int) (((latitude - zoneOriginLatitude) / 90d) * (northSouthPixelConstant / pixelRowsPerFrame)); } /* [Section 30.3.1, MIL-C-89038] */ /* [Section A.3.3.1, MIL-PRF-89041A] */ private static double frameOriginLatitude(int row, double northSouthPixelConstant, double pixelRowsPerFrame, double zoneOriginLatitude) { return (90d / northSouthPixelConstant) * pixelRowsPerFrame * (row + 1) + zoneOriginLatitude; } /* [Section 30.3.2, MIL-C-89038] */ /* [Section A.3.3.2, MIL-PRF-89041A] */ private static int frameColumn(double longitude, double eastWestPixelConstant, double pixelRowsPerFrame) { return (int) (((longitude + 180d) / 360d) * (eastWestPixelConstant / pixelRowsPerFrame)); } /* [Section 30.3.2, MIL-C-89038] */ /* [Section A.3.3.2, MIL-PRF-89041A] */ private static double frameOriginLongitude(int column, double eastWestPixelConstant, double pixelRowsPerFrame) { return (360d / eastWestPixelConstant) * pixelRowsPerFrame * column - 180d; } private static double frameDeltaLatitude(double northSouthPixelConstant, double pixelRowsPerFrame) { return (90d / northSouthPixelConstant) * pixelRowsPerFrame; } private static double frameDeltaLongitude(double eastWestPixelConstant, double pixelRowsPerFrame) { return (360d / eastWestPixelConstant) * pixelRowsPerFrame; } private static double normalizedDegreesLongitude(double degrees) { double lon = degrees % 360; return lon > 180 ? lon - 360 : lon < -180 ? 360 + lon : lon; } }