GVAR McIDAS native projection support added for Raytheon satellite.mcidas decoder.
Former-commit-id:17f3681bd0
[formerlybf979e7040
] Former-commit-id:b9f2552744
This commit is contained in:
parent
e6e79a8599
commit
659fac2925
5 changed files with 210 additions and 42 deletions
|
@ -23,3 +23,6 @@ Require-Bundle: com.raytheon.uf.common.dataplugin;bundle-version="1.12.1174",
|
||||||
com.raytheon.uf.edex.database;bundle-version="1.0.0",
|
com.raytheon.uf.edex.database;bundle-version="1.0.0",
|
||||||
com.raytheon.uf.edex.menus;bundle-version="1.0.0",
|
com.raytheon.uf.edex.menus;bundle-version="1.0.0",
|
||||||
com.raytheon.uf.common.numeric;bundle-version="1.14.0"
|
com.raytheon.uf.common.numeric;bundle-version="1.14.0"
|
||||||
|
Import-Package: gov.noaa.nws.ncep.common.tools,
|
||||||
|
gov.noaa.nws.ncep.edex.util,
|
||||||
|
org.apache.commons.codec.binary
|
||||||
|
|
|
@ -20,15 +20,19 @@
|
||||||
|
|
||||||
package com.raytheon.edex.util.satellite;
|
package com.raytheon.edex.util.satellite;
|
||||||
|
|
||||||
|
import java.awt.geom.Rectangle2D;
|
||||||
|
import gov.noaa.nws.ncep.common.tools.IDecoderConstantsN;
|
||||||
|
|
||||||
import org.geotools.geometry.DirectPosition2D;
|
import org.geotools.geometry.DirectPosition2D;
|
||||||
import org.opengis.referencing.crs.ProjectedCRS;
|
import org.opengis.referencing.crs.ProjectedCRS;
|
||||||
import org.opengis.referencing.operation.MathTransform;
|
import org.opengis.referencing.operation.MathTransform;
|
||||||
|
|
||||||
import com.raytheon.edex.plugin.satellite.SatelliteDecoderException;
|
import com.raytheon.edex.plugin.satellite.SatelliteDecoderException;
|
||||||
import com.raytheon.edex.plugin.satellite.dao.SatMapCoverageDao;
|
import com.raytheon.edex.plugin.satellite.dao.SatMapCoverageDao;
|
||||||
import com.raytheon.uf.common.dataplugin.satellite.SatMapCoverage;
|
import com.raytheon.uf.common.dataplugin.satellite.SatMapCoverage;
|
||||||
import com.raytheon.uf.common.geospatial.MapUtil;
|
import com.raytheon.uf.common.geospatial.MapUtil;
|
||||||
import com.vividsolutions.jts.geom.Envelope;
|
import com.vividsolutions.jts.geom.Envelope;
|
||||||
|
import com.vividsolutions.jts.geom.Geometry;
|
||||||
|
import com.vividsolutions.jts.io.WKTReader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -48,7 +52,7 @@ import com.vividsolutions.jts.geom.Envelope;
|
||||||
* Nov 05, 2014 2714 bclement replaced DecoderException with SatelliteDecoderException
|
* Nov 05, 2014 2714 bclement replaced DecoderException with SatelliteDecoderException
|
||||||
* Nov 05, 2014 3788 bsteffen use getOrCreateCoverage in place of queryByMapId
|
* Nov 05, 2014 3788 bsteffen use getOrCreateCoverage in place of queryByMapId
|
||||||
* May 11, 2015 mjames South polar stereogrpahic support added.
|
* May 11, 2015 mjames South polar stereogrpahic support added.
|
||||||
*
|
* 05/19/2015 mjames@ucar Added decoding of GVAR native projection products
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*/
|
*/
|
||||||
|
@ -68,6 +72,8 @@ public class SatSpatialFactory {
|
||||||
|
|
||||||
public static final int UNDEFINED = -1;
|
public static final int UNDEFINED = -1;
|
||||||
|
|
||||||
|
public static final int PROJ_GVAR = 7585;
|
||||||
|
|
||||||
/** The singleton instance */
|
/** The singleton instance */
|
||||||
private static SatSpatialFactory instance;
|
private static SatSpatialFactory instance;
|
||||||
|
|
||||||
|
@ -210,6 +216,58 @@ public class SatSpatialFactory {
|
||||||
return getCoverageSingleCorner(crsType, nx, ny, lov, latin, latin, la1, lo1, dx, dy);
|
return getCoverageSingleCorner(crsType, nx, ny, lov, latin, latin, la1, lo1, dx, dy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public SatMapCoverage getCoverageNative(int crsType, int nx, int ny,
|
||||||
|
double reflon, int upperLeftElement, int upperLeftLine,
|
||||||
|
int xres, int yres, ProjectedCRS crs)
|
||||||
|
throws SatelliteDecoderException {
|
||||||
|
try {
|
||||||
|
|
||||||
|
// Construct the polygon constructor String
|
||||||
|
StringBuffer buffer = new StringBuffer();
|
||||||
|
buffer.append("POLYGON((");
|
||||||
|
buffer.append(reflon - 90. + " -90.0,");
|
||||||
|
buffer.append(reflon + 90. + " -90.0,");
|
||||||
|
buffer.append(reflon + 90. + " 90.0,");
|
||||||
|
buffer.append(reflon - 90. + " 90.0,");
|
||||||
|
buffer.append(reflon - 90. + " -90.0");
|
||||||
|
buffer.append("))");
|
||||||
|
// Create the geometry from the constructed String
|
||||||
|
Geometry geometry = new WKTReader().read(buffer.toString());
|
||||||
|
|
||||||
|
// Construct rectangle
|
||||||
|
double minX = upperLeftElement;
|
||||||
|
int maxX = upperLeftElement + (nx * xres);
|
||||||
|
double minY = upperLeftLine + (ny * yres);
|
||||||
|
minY = -minY;
|
||||||
|
int maxY = -1 * upperLeftLine;
|
||||||
|
Rectangle2D rect = new Rectangle2D.Double(minX,
|
||||||
|
minY, maxX, maxY);
|
||||||
|
|
||||||
|
SatMapCoverage coverage = createCoverageFromNative(crsType, nx, ny,
|
||||||
|
reflon, upperLeftElement, upperLeftLine,
|
||||||
|
xres, yres, crs, geometry );
|
||||||
|
|
||||||
|
return checkPersisted(coverage);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
buf.append(
|
||||||
|
"Error getting or constructing SatMapCoverage for values: ")
|
||||||
|
.append("\n\t");
|
||||||
|
buf.append("crsType=" + crsType).append("\n\t");
|
||||||
|
buf.append("nx=" + nx).append("\n\t");
|
||||||
|
buf.append("ny=" + ny).append("\n\t");
|
||||||
|
buf.append("reflon=" + reflon).append("\n\t");
|
||||||
|
buf.append("upperLeftElement=" + upperLeftElement).append("\n\t");
|
||||||
|
buf.append("upperLeftLine=" + upperLeftLine).append("\n\t");
|
||||||
|
buf.append("xres=" + xres).append("\n\t");
|
||||||
|
buf.append("yres=" + yres).append("\n\t");
|
||||||
|
throw new SatelliteDecoderException(buf.toString(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Create a {@link SatMapCoverage} with an area defined by two corners. The
|
* Create a {@link SatMapCoverage} with an area defined by two corners. The
|
||||||
|
@ -310,6 +368,29 @@ public class SatSpatialFactory {
|
||||||
envelope.getMinY(), nx, ny, dx, dy, crs);
|
envelope.getMinY(), nx, ny, dx, dy, crs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a SatMapCoverage from native projection
|
||||||
|
*/
|
||||||
|
private static SatMapCoverage createCoverageFromNative(Integer crsType,
|
||||||
|
Integer nx, Integer ny, double reflon, int upperLeftElement,
|
||||||
|
int upperLeftLine, int xres, int yres, ProjectedCRS crs,
|
||||||
|
Geometry geometry) {
|
||||||
|
|
||||||
|
// do your shit here.
|
||||||
|
float dx = IDecoderConstantsN.FLOAT_MISSING;
|
||||||
|
float dy = IDecoderConstantsN.FLOAT_MISSING;
|
||||||
|
|
||||||
|
double minX, minY;
|
||||||
|
//if (crsType == PROJ_GVAR) { // for native projection
|
||||||
|
minX = upperLeftElement;
|
||||||
|
minY = upperLeftLine + (ny * yres);
|
||||||
|
minY = -minY;
|
||||||
|
|
||||||
|
return new SatMapCoverage(crsType, minX, minY, nx, ny,
|
||||||
|
dx, dy, crs, geometry);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a {@link ProjectedCRS} from a crsType and some parameters.
|
* Create a {@link ProjectedCRS} from a crsType and some parameters.
|
||||||
*
|
*
|
||||||
|
@ -377,4 +458,7 @@ public class SatSpatialFactory {
|
||||||
MapUtil.AWIPS_EARTH_RADIUS, latin, lov);
|
MapUtil.AWIPS_EARTH_RADIUS, latin, lov);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,8 @@ import com.vividsolutions.jts.geom.Polygon;
|
||||||
* Apr 11, 2014 2947 bsteffen Fix equals
|
* Apr 11, 2014 2947 bsteffen Fix equals
|
||||||
* Oct 16, 2014 3454 bphillip Upgrading to Hibernate 4
|
* Oct 16, 2014 3454 bphillip Upgrading to Hibernate 4
|
||||||
* Nov 05, 2014 3788 bsteffen Make gid a sequence instead of a hash.
|
* Nov 05, 2014 3788 bsteffen Make gid a sequence instead of a hash.
|
||||||
*
|
* May 19, 2015 mjames@ucar Added decoding of GVAR native projection products,
|
||||||
|
* increased crsWKT to 5120 for GVAR the_geom
|
||||||
* </pre>
|
* </pre>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
|
@ -92,6 +93,8 @@ import com.vividsolutions.jts.geom.Polygon;
|
||||||
public class SatMapCoverage extends PersistableDataObject<Object> implements
|
public class SatMapCoverage extends PersistableDataObject<Object> implements
|
||||||
IGridGeometryProvider {
|
IGridGeometryProvider {
|
||||||
|
|
||||||
|
public static final int PROJ_GVAR = 7585;
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
|
@ -102,7 +105,8 @@ public class SatMapCoverage extends PersistableDataObject<Object> implements
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The projection of the map coverage 1=Mercator, 3=Lambert Conformal
|
* The projection of the map coverage 1=Mercator, 3=Lambert Conformal
|
||||||
* 5=Polar Stereographic
|
* 5=Polar Stereographic, 7585 = native satellite navigation e.g.
|
||||||
|
* GVAR, ...
|
||||||
*
|
*
|
||||||
* @deprecated This field is only useful for GINI satellite format decoding
|
* @deprecated This field is only useful for GINI satellite format decoding
|
||||||
* and should not be in the coverage object
|
* and should not be in the coverage object
|
||||||
|
@ -110,7 +114,6 @@ public class SatMapCoverage extends PersistableDataObject<Object> implements
|
||||||
@Column
|
@Column
|
||||||
@XmlAttribute
|
@XmlAttribute
|
||||||
@DynamicSerializeElement
|
@DynamicSerializeElement
|
||||||
@Deprecated
|
|
||||||
private Integer projection;
|
private Integer projection;
|
||||||
|
|
||||||
/** Minimum x coordinate in crs space */
|
/** Minimum x coordinate in crs space */
|
||||||
|
@ -149,7 +152,7 @@ public class SatMapCoverage extends PersistableDataObject<Object> implements
|
||||||
@DynamicSerializeElement
|
@DynamicSerializeElement
|
||||||
private double dy;
|
private double dy;
|
||||||
|
|
||||||
@Column(length = 2047)
|
@Column(length = 5120)
|
||||||
@XmlAttribute
|
@XmlAttribute
|
||||||
@DynamicSerializeElement
|
@DynamicSerializeElement
|
||||||
private String crsWKT;
|
private String crsWKT;
|
||||||
|
@ -379,9 +382,16 @@ public class SatMapCoverage extends PersistableDataObject<Object> implements
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GridGeometry2D getGridGeometry() {
|
public GridGeometry2D getGridGeometry() {
|
||||||
GridEnvelope gridRange = new GridEnvelope2D(0, 0, getNx(), getNy());
|
GridEnvelope gridRange;
|
||||||
Envelope crsRange = new Envelope2D(getCrs(), new Rectangle2D.Double(
|
Envelope crsRange;
|
||||||
|
|
||||||
|
int nx = getNx();
|
||||||
|
int ny = getNy();
|
||||||
|
gridRange = new GridEnvelope2D(0, 0, getNx(), getNy());
|
||||||
|
crsRange = new Envelope2D(getCrs(), new Rectangle2D.Double(
|
||||||
minX, minY, getNx() * getDx(), getNy() * getDy()));
|
minX, minY, getNx() * getDx(), getNy() * getDy()));
|
||||||
|
|
||||||
|
|
||||||
return new GridGeometry2D(gridRange, crsRange);
|
return new GridGeometry2D(gridRange, crsRange);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,5 +16,6 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||||
Import-Package: com.raytheon.uf.common.localization,
|
Import-Package: com.raytheon.uf.common.localization,
|
||||||
com.raytheon.uf.common.menus,
|
com.raytheon.uf.common.menus,
|
||||||
com.raytheon.uf.common.menus.xml,
|
com.raytheon.uf.common.menus.xml,
|
||||||
com.raytheon.uf.common.status
|
com.raytheon.uf.common.status,
|
||||||
|
org.apache.commons.codec.binary
|
||||||
Export-Package: com.raytheon.uf.edex.plugin.satellite.mcidas
|
Export-Package: com.raytheon.uf.edex.plugin.satellite.mcidas
|
||||||
|
|
|
@ -26,6 +26,9 @@ import java.util.Calendar;
|
||||||
import java.util.GregorianCalendar;
|
import java.util.GregorianCalendar;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
import org.opengis.referencing.crs.ProjectedCRS;
|
||||||
|
|
||||||
import com.raytheon.edex.esb.Headers;
|
import com.raytheon.edex.esb.Headers;
|
||||||
import com.raytheon.edex.exception.DecoderException;
|
import com.raytheon.edex.exception.DecoderException;
|
||||||
import com.raytheon.edex.util.satellite.SatSpatialFactory;
|
import com.raytheon.edex.util.satellite.SatSpatialFactory;
|
||||||
|
@ -33,6 +36,7 @@ import com.raytheon.uf.common.dataplugin.PluginDataObject;
|
||||||
import com.raytheon.uf.common.dataplugin.satellite.SatMapCoverage;
|
import com.raytheon.uf.common.dataplugin.satellite.SatMapCoverage;
|
||||||
import com.raytheon.uf.common.dataplugin.satellite.SatelliteRecord;
|
import com.raytheon.uf.common.dataplugin.satellite.SatelliteRecord;
|
||||||
import com.raytheon.uf.common.datastorage.records.IDataRecord;
|
import com.raytheon.uf.common.datastorage.records.IDataRecord;
|
||||||
|
import com.raytheon.uf.common.geospatial.MapUtil;
|
||||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||||
import com.raytheon.uf.common.status.UFStatus;
|
import com.raytheon.uf.common.status.UFStatus;
|
||||||
import com.raytheon.uf.common.time.DataTime;
|
import com.raytheon.uf.common.time.DataTime;
|
||||||
|
@ -71,7 +75,8 @@ import com.raytheon.uf.edex.plugin.satellite.mcidas.util.McidasSatelliteLookups.
|
||||||
* IDataRecord required by the SatelliteDao
|
* IDataRecord required by the SatelliteDao
|
||||||
* 12/03/2013 DR 16841 D. Friedman Allow record overwrites
|
* 12/03/2013 DR 16841 D. Friedman Allow record overwrites
|
||||||
* 09/18/2014 3627 mapeters Updated deprecated method calls.
|
* 09/18/2014 3627 mapeters Updated deprecated method calls.
|
||||||
* 05/11/2015 mjames PS (south and north) stereogrpahic support added.
|
* 05/11/2015 mjames@ucar PS (south and north) stereogrpahic support added.
|
||||||
|
* 05/19/2015 mjames@ucar Added decoding of GVAR native projection products
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author
|
* @author
|
||||||
|
@ -90,6 +95,8 @@ public class McidasSatelliteDecoder {
|
||||||
|
|
||||||
private static final int RADIUS = 6371200;
|
private static final int RADIUS = 6371200;
|
||||||
|
|
||||||
|
final int SIZE_OF_AREA = 256;
|
||||||
|
|
||||||
private static final double HALFPI = Math.PI / 2.;
|
private static final double HALFPI = Math.PI / 2.;
|
||||||
|
|
||||||
private static final double RTD = 180. / Math.PI;
|
private static final double RTD = 180. / Math.PI;
|
||||||
|
@ -134,9 +141,17 @@ public class McidasSatelliteDecoder {
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
private PluginDataObject[] decodeMcidasArea(byte[] data) throws Exception {
|
private PluginDataObject[] decodeMcidasArea(byte[] data) throws Exception {
|
||||||
|
|
||||||
|
|
||||||
|
byte[] area = null;
|
||||||
|
byte[] nonAreaBlock = new byte[data.length - SIZE_OF_AREA];
|
||||||
|
area = new byte[SIZE_OF_AREA];
|
||||||
|
System.arraycopy(data, 0, area, 0, SIZE_OF_AREA);
|
||||||
|
System.arraycopy(data, SIZE_OF_AREA, nonAreaBlock, 0,
|
||||||
|
nonAreaBlock.length);
|
||||||
|
|
||||||
ByteBuffer buf = ByteBuffer.wrap(data);
|
ByteBuffer buf = ByteBuffer.wrap(data);
|
||||||
buf.order(ByteOrder.LITTLE_ENDIAN);
|
buf.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
|
||||||
// Decode the directory block
|
// Decode the directory block
|
||||||
if (buf.getInt() != 0) {
|
if (buf.getInt() != 0) {
|
||||||
formatError(UNEXPECTED_HEADER_VALUE);
|
formatError(UNEXPECTED_HEADER_VALUE);
|
||||||
|
@ -148,24 +163,37 @@ public class McidasSatelliteDecoder {
|
||||||
formatError(UNEXPECTED_HEADER_VALUE);
|
formatError(UNEXPECTED_HEADER_VALUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int sensorSourceNumber = buf.getInt();
|
|
||||||
int yyyddd = buf.getInt();
|
int sensorSourceNumber = buf.getInt(); // W3
|
||||||
int hhmmss = buf.getInt();
|
int yyyddd = buf.getInt(); // W4
|
||||||
int ulImageLine = buf.getInt();
|
int hhmmss = buf.getInt(); // W5
|
||||||
int ulImageElement = buf.getInt();
|
int ulImageLine = buf.getInt(); // W6
|
||||||
buf.getInt(); // reserved
|
int ulImageElement = buf.getInt(); // W7
|
||||||
int nLines = buf.getInt();
|
buf.getInt(); // reserved // W8
|
||||||
int nElementsPerLine = buf.getInt();
|
int nLines = buf.getInt(); // W9
|
||||||
int nBytesPerElement = buf.getInt();
|
int nElementsPerLine = buf.getInt(); // W10
|
||||||
int lineResolution = buf.getInt();
|
int nBytesPerElement = buf.getInt(); // W11
|
||||||
int elementResolution = buf.getInt();
|
int lineResolution = buf.getInt(); // W12
|
||||||
int nBands = buf.getInt();
|
int elementResolution = buf.getInt(); // W13
|
||||||
int linePrefixLength = buf.getInt();
|
int nBands = buf.getInt(); // W14
|
||||||
/* int projectNumber = */buf.getInt();
|
int linePrefixLength = buf.getInt(); // W15
|
||||||
/* int creationYyyddd = */buf.getInt();
|
/* int projectNumber = */buf.getInt(); // W16
|
||||||
/* int creationHhmmss = */buf.getInt();
|
/* int creationYyyddd = */buf.getInt(); // W17
|
||||||
int bandMap1to32 = buf.getInt();
|
/* int creationHhmmss = */buf.getInt(); // W18
|
||||||
int bandMap33to64 = buf.getInt();
|
|
||||||
|
/*
|
||||||
|
* W19
|
||||||
|
32-bit filter band map for multichannel
|
||||||
|
images; if a bit is set, data exists for the band;
|
||||||
|
band 1 is the least significant byte (rightmost)
|
||||||
|
*/
|
||||||
|
int bandMap1to32 = buf.getInt(); // W19
|
||||||
|
/*
|
||||||
|
* W20-24
|
||||||
|
satellite specific information
|
||||||
|
*/
|
||||||
|
int bandMap33to64 = buf.getInt(); // W20
|
||||||
|
|
||||||
buf.position(buf.position() + (4 * 4)); // sensor specific
|
buf.position(buf.position() + (4 * 4)); // sensor specific
|
||||||
buf.position(buf.position() + (4 * 8)); // memo
|
buf.position(buf.position() + (4 * 8)); // memo
|
||||||
int areaNumber = buf.getInt();
|
int areaNumber = buf.getInt();
|
||||||
|
@ -188,12 +216,35 @@ public class McidasSatelliteDecoder {
|
||||||
/* int scaling = */buf.getInt();
|
/* int scaling = */buf.getInt();
|
||||||
/* int supplementalBlockOffset = */buf.getInt();
|
/* int supplementalBlockOffset = */buf.getInt();
|
||||||
buf.getInt(); // reserved
|
buf.getInt(); // reserved
|
||||||
/* int calibrationOffset = */buf.getInt();
|
int calibrationOffset = buf.getInt();
|
||||||
buf.getInt(); // comment cards
|
buf.getInt(); // comment cards
|
||||||
|
|
||||||
|
|
||||||
|
int navsize;
|
||||||
|
if (calibrationOffset == 0){
|
||||||
|
navsize = dataBlockOffset - navBlockOffset;
|
||||||
|
} else {
|
||||||
|
navsize = calibrationOffset - navBlockOffset;
|
||||||
|
}
|
||||||
|
byte[] navigation = new byte[navsize];
|
||||||
|
System.arraycopy(nonAreaBlock, 0, navigation, 0, navsize);
|
||||||
|
|
||||||
|
/* mjames@ucar
|
||||||
|
* bandMap1to32 is a 32-bit filter band map for multichannel images.
|
||||||
|
* if a bit is set, data exists for the band; band 1 is the least
|
||||||
|
* significant byte (rightmost)
|
||||||
|
*
|
||||||
|
* Example: for GVAR GEWCOMP UNIWISC image,
|
||||||
|
* bandMap1to32 = 4
|
||||||
|
* bandMap33to64 = -1, so
|
||||||
|
* nBands = 1
|
||||||
|
* bandBitsCount = 33
|
||||||
|
*
|
||||||
|
* this is a problem...
|
||||||
|
*/
|
||||||
long bandBits = ((long) bandMap33to64 << 32) | bandMap1to32;
|
long bandBits = ((long) bandMap33to64 << 32) | bandMap1to32;
|
||||||
long bandBitsCount = Long.bitCount(bandBits);
|
long bandBitsCount = Long.bitCount(bandBits);
|
||||||
if (nBands != bandBitsCount) {
|
if (nBands != bandBitsCount && nBands > 1) {
|
||||||
formatError("Specified number of bands does not match number of bits in band map");
|
formatError("Specified number of bands does not match number of bits in band map");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,7 +252,7 @@ public class McidasSatelliteDecoder {
|
||||||
buf.position(navBlockOffset);
|
buf.position(navBlockOffset);
|
||||||
SatMapCoverage coverage = decodeNavigation(elementResolution,
|
SatMapCoverage coverage = decodeNavigation(elementResolution,
|
||||||
lineResolution, ulImageElement, ulImageLine, nElementsPerLine,
|
lineResolution, ulImageElement, ulImageLine, nElementsPerLine,
|
||||||
nLines, buf);
|
nLines, buf, navigation);
|
||||||
|
|
||||||
// Decode the data block, creating a SatelliteRecord for each band.
|
// Decode the data block, creating a SatelliteRecord for each band.
|
||||||
PluginDataObject[] result = new PluginDataObject[nBands];
|
PluginDataObject[] result = new PluginDataObject[nBands];
|
||||||
|
@ -280,7 +331,8 @@ public class McidasSatelliteDecoder {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private SatMapCoverage decodeNavigation(int xImgRes, int yImgRes, int ulX,
|
private SatMapCoverage decodeNavigation(int xImgRes, int yImgRes, int ulX,
|
||||||
int ulY, int nx, int ny, ByteBuffer buf) throws Exception {
|
int ulY, int nx, int ny, ByteBuffer buf, byte[] navigation)
|
||||||
|
throws Exception {
|
||||||
SatMapCoverage result = new SatMapCoverage();
|
SatMapCoverage result = new SatMapCoverage();
|
||||||
String navType = get4cc(buf);
|
String navType = get4cc(buf);
|
||||||
int lineOfEquator = buf.getInt();
|
int lineOfEquator = buf.getInt();
|
||||||
|
@ -289,6 +341,7 @@ public class McidasSatelliteDecoder {
|
||||||
int spacingAtStdLatInMeters = buf.getInt();
|
int spacingAtStdLatInMeters = buf.getInt();
|
||||||
int nrmlLonDDMMSS = buf.getInt();
|
int nrmlLonDDMMSS = buf.getInt();
|
||||||
|
|
||||||
|
|
||||||
// NOTE: We do not check the following for compatibility with WGS84.
|
// NOTE: We do not check the following for compatibility with WGS84.
|
||||||
int radiusInMeters = buf.getInt();
|
int radiusInMeters = buf.getInt();
|
||||||
/* int eccentricity = */buf.getInt();
|
/* int eccentricity = */buf.getInt();
|
||||||
|
@ -375,7 +428,18 @@ public class McidasSatelliteDecoder {
|
||||||
(float) clat, la1, lo1, la2, lo2);
|
(float) clat, la1, lo1, la2, lo2);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
unimplemented(String.format("navigation type \"%s\"", navType));
|
/*
|
||||||
|
* Native projection
|
||||||
|
*/
|
||||||
|
//unimplemented(String.format("navigation type \"%s\"", navType));
|
||||||
|
clon = nrmlLonDDMMSS / 10000000.f;
|
||||||
|
clon = (float) Math.toDegrees(clon);
|
||||||
|
ProjectedCRS crs = MapUtil.constructNative(navType, encodeNavBlock(navigation));
|
||||||
|
|
||||||
|
result = SatSpatialFactory.getInstance().getCoverageNative(
|
||||||
|
SatSpatialFactory.PROJ_GVAR, nx, ny, (float) clon,
|
||||||
|
ulX, ulY, xImgRes, yImgRes, crs);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -451,5 +515,11 @@ public class McidasSatelliteDecoder {
|
||||||
throw new DecoderException(String.format("%s: unimplemented: %s",
|
throw new DecoderException(String.format("%s: unimplemented: %s",
|
||||||
traceId, feature));
|
traceId, feature));
|
||||||
}
|
}
|
||||||
|
private String encodeNavBlock(byte[] navigation) {
|
||||||
|
|
||||||
|
Base64 b64 = new Base64();
|
||||||
|
byte[] coded = b64.encode(navigation);
|
||||||
|
|
||||||
|
return new String(coded);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue