Merge "VLab Issue #4723 - Ingest LambertConformal projection with two standard parallels using RegionalSat; fixes #4723" into field_14.3.1

Former-commit-id: d4cf990bb3 [formerly ae6d0f5d64] [formerly 2e66ced748] [formerly 536140f021 [formerly 2e66ced748 [formerly c7c530f99f8585817544db2d7be5b13d47c3e62e]]]
Former-commit-id: 536140f021
Former-commit-id: 26b13374598275c0292d8e5bd4d8ce0636344ce2 [formerly e259a36575]
Former-commit-id: 7b84e88b83
This commit is contained in:
Ana Rivera 2014-09-16 08:05:51 -04:00 committed by Gerrit Code Review
commit e7a707af00
2 changed files with 70 additions and 36 deletions

View file

@ -43,7 +43,7 @@ import com.vividsolutions.jts.geom.Envelope;
* Sep 30, 2013 2333 mschenke Refactored to store points in crs space
* Apr 15, 2014 3017 bsteffen Add new getCoverage methods to support
* either one corner + dx/dy or two corners.
*
* Sep 15, 2014 DR 17303 jgerth Support for second standard latitude
* </pre>
*/
public class SatSpatialFactory {
@ -141,18 +141,20 @@ public class SatSpatialFactory {
* @param ny
* the number of rows of data.
* @param lov
* the longitude orientatition, used by
* the longitude orientation, used by
* {@link #PROJ_CYLIN_EQUIDISTANT}, {@link #PROJ_LAMBERT},
* {@link #PROJ_POLAR}.
* @param latin
* the latitude at which the projection is tangent to the earths
* surface, used by {@link #PROJ_CYLIN_EQUIDISTANT},
* {@link #PROJ_LAMBERT}, {@link #PROJ_MERCATOR}.
* @param latin2
* the second standard latitude, used by {@link #PROJ_LAMBERT}.
* @param la1
* the latitude of a corner of the grid, if dy is positive this
* is an upper corner.
* @param lo1
* the longitide of a corner of the grid, if dx is positive this
* the longitude of a corner of the grid, if dx is positive this
* is a left corner
* @param dx
* the distance between columns measured in CRS meters.
@ -163,10 +165,10 @@ public class SatSpatialFactory {
* @throws DecoderException
*/
public SatMapCoverage getCoverageSingleCorner(int crsType, int nx, int ny,
double lov, double latin, double la1, double lo1, double dx,
double lov, double latin, double latin2, double la1, double lo1, double dx,
double dy) throws DecoderException {
try {
ProjectedCRS crs = createCRS(crsType, lov, latin, 0.0);
ProjectedCRS crs = createCRS(crsType, lov, latin, latin2, 0.0);
DirectPosition2D corner = new DirectPosition2D(lo1, la1);
MathTransform fromLatLon = MapUtil.getTransformFromLatLon(crs);
fromLatLon.transform(corner, corner);
@ -193,10 +195,19 @@ public class SatSpatialFactory {
}
}
/**
* @see {@link #getCoverageSingleCorner(int, int, int, double, double, double, double, double, double, double)}
*/
public SatMapCoverage getCoverageSingleCorner(int crsType, int nx, int ny,
double lov, double latin, double la1, double lo1, double dx,
double dy) throws DecoderException {
return getCoverageSingleCorner(crsType, nx, ny, lov, latin, latin, la1, lo1, dx, dy);
}
/**
*
* Create a {@link SatMapCoverage} with an area defined by two corners. The
* two corners must be opposite(diagnol) from eachother. They caan be either
* two corners must be opposite (diagonal) from each other. They can be either
* the upper left and lower right or the upper right and lower left corners.
*
* @param crsType
@ -204,36 +215,38 @@ public class SatSpatialFactory {
* {@link #PROJ_CYLIN_EQUIDISTANT}, {@link #PROJ_LAMBERT},
* {@link #PROJ_MERCATOR}, {@link #PROJ_POLAR}.
* @param lov
* the longitude orientatition, used by
* the longitude orientation, used by
* {@link #PROJ_CYLIN_EQUIDISTANT}, {@link #PROJ_LAMBERT},
* {@link #PROJ_POLAR}.
* @param latin
* the latitude at which the projection is tangent to the earths
* surface, used by {@link #PROJ_CYLIN_EQUIDISTANT},
* {@link #PROJ_LAMBERT}, {@link #PROJ_MERCATOR}.
* @param latin2
* the second standard latitude, used by {@link #PROJ_LAMBERT}.
* @param la1
* the latitude of a corner of the grid.
* @param lo1
* the longitide of a corner of the grid.
* the longitude of a corner of the grid.
* @param la2
* the latitude of a corner of the grid., should be opposite
* corner from la1.
* @param lo2
* the longitide of a corner of the grid, should be opposite
* the longitude of a corner of the grid, should be opposite
* corner from lo1
* @return a {@link SatMapCoverage} matching these parameters that has been
* loaded from or persisted to the database.
* @throws DecoderException
*/
public SatMapCoverage getCoverageTwoCorners(int crsType, int nx, int ny,
double lov, double latin, double la1, double lo1, double la2,
double lov, double latin, double latin2, double la1, double lo1, double la2,
double lo2) throws DecoderException {
try {
double cm = 0.0;
if ((lo1 > 0.0) && (lo2 < 0.0)) {
cm = 180.0;
}
ProjectedCRS crs = createCRS(crsType, lov, latin, cm);
ProjectedCRS crs = createCRS(crsType, lov, latin, latin2, cm);
DirectPosition2D corner1 = new DirectPosition2D(lo1, la1);
DirectPosition2D corner2 = new DirectPosition2D(lo2, la2);
MathTransform fromLatLon = MapUtil.getTransformFromLatLon(crs);
@ -262,6 +275,15 @@ public class SatSpatialFactory {
}
}
/**
* @see {@link #getCoverageTwoCorners(int, int, int, double, double, double, double, double, double, double)}
*/
public SatMapCoverage getCoverageTwoCorners(int crsType, int nx, int ny,
double lov, double latin, double la1, double lo1, double la2,
double lo2) throws DecoderException {
return getCoverageTwoCorners(crsType, nx, ny, lov, latin, latin, la1, lo1, la2, lo2);
}
/** Load or persist a {@link SatMapCoverage} */
private synchronized SatMapCoverage checkPersisted(
SatMapCoverage mapCoverage) {
@ -294,25 +316,27 @@ public class SatSpatialFactory {
* {@link #PROJ_CYLIN_EQUIDISTANT}, {@link #PROJ_LAMBERT},
* {@link #PROJ_MERCATOR}, {@link #PROJ_POLAR}. * @param lov
* @param lov
* the longitude orientatition, used by
* the longitude orientation, used by
* {@link #PROJ_CYLIN_EQUIDISTANT}, {@link #PROJ_LAMBERT},
* {@link #PROJ_POLAR}.
* @param latin
* the latitude at which the projection is tangent to the earths
* surface, used by {@link #PROJ_CYLIN_EQUIDISTANT},
* {@link #PROJ_LAMBERT}, {@link #PROJ_MERCATOR}.
* @param latin2
* the second standard latitude, used by {@link #PROJ_LAMBERT}.
* @param cm
* the central meridian of the projection, only used by
* {@link #PROJ_MERCATOR}.
* @return
*/
private static ProjectedCRS createCRS(int crsType, double lov,
double latin, double cm) {
double latin, double latin2, double cm) {
switch (crsType) {
case PROJ_MERCATOR:
return createMercatorCrs(latin, cm);
case PROJ_LAMBERT:
return createLambertCrs(latin, lov);
return createLambertCrs(latin, latin2, lov);
case PROJ_CYLIN_EQUIDISTANT:
return createEqCylCrs(latin, lov);
default:
@ -325,9 +349,9 @@ public class SatSpatialFactory {
MapUtil.AWIPS_EARTH_RADIUS, latin, cm);
}
private static ProjectedCRS createLambertCrs(double latin, double lov) {
private static ProjectedCRS createLambertCrs(double latin, double latin2, double lov) {
return MapUtil.constructLambertConformal(MapUtil.AWIPS_EARTH_RADIUS,
MapUtil.AWIPS_EARTH_RADIUS, latin, latin, lov);
MapUtil.AWIPS_EARTH_RADIUS, latin, latin2, lov);
}
private static ProjectedCRS createEqCylCrs(double latin, double lov) {

View file

@ -61,6 +61,7 @@ import com.raytheon.uf.edex.decodertools.time.TimeTools;
* IDataRecord required by the SatelliteDao
* Aug 30, 2013 2298 rjpeter Make getPluginName abstract
* Apr 15, 2014 3017 bsteffen Call new methods in SatSpatialFactory
* Sep 11, 2014 DR 17303 jgerth Support for second standard latitude
* </pre>
*
* @author tk
@ -116,26 +117,26 @@ public class RegionalSatDecoder extends AbstractDecoder {
netCdfFile = NetcdfFile.openInMemory(filename, data);
// set the source; Alaska Region
if (source == null) {
source = "Source"; // use to look up source value; default of
// Source
String gaSourceStr = "Unknown";
Attribute gaSource = netCdfFile.findGlobalAttribute("source");
if (gaSource != null) {
gaSourceStr = gaSource.getStringValue().trim();
}
record.setSource(getSource(source)); // lookup source value
record.setSource(getSource(gaSourceStr).replace("/", " ")); // lookup source value
// set the creating entity
Attribute satName = netCdfFile.findGlobalAttribute("satelliteName");
String entity = null; // "HRPT"; "GOESR-PG"; "Blended2";
if (satName != null) {
entity = satName.getStringValue();
entity = satName.getStringValue().trim();
}
if (entity != null) {
String parsed = getCreatingEntity(entity);
if ((parsed != null) && (parsed.length() > 0)) {
record.setCreatingEntity(parsed);
record.setCreatingEntity(parsed.replace("/", " "));
} else {
record.setCreatingEntity(entity);
record.setCreatingEntity(entity.replace("/", " "));
}
} else {
record.setCreatingEntity("Unknown");
@ -156,9 +157,9 @@ public class RegionalSatDecoder extends AbstractDecoder {
pev = getPhysicalElement(entity, channel);
String element = pev.name;
if (pev.name != null) {
record.setPhysicalElement(element);
record.setPhysicalElement(element.replace("/", " "));
} else {
record.setPhysicalElement(channel);
record.setPhysicalElement(channel.replace("/", " "));
}
} else {
record.setPhysicalElement("Imager Visible");
@ -181,10 +182,10 @@ public class RegionalSatDecoder extends AbstractDecoder {
// read the valid time in seconds and store the time in milliseconds
long time = netCdfFile.findVariable("validTime").readScalarLong(); // time
// in
// seconds
// in
// seconds
calendar.setTimeInMillis(time * 1000); // need to convert seconds to
// milliseconds
// milliseconds
/*
* Date date = new Date(); // used for setting the test data time
@ -199,9 +200,10 @@ public class RegionalSatDecoder extends AbstractDecoder {
.getNumericValue().floatValue();
int mapProjection = SatSpatialFactory.PROJ_POLAR; // STEREOGRAPHIC
// projection
// default
// projection
// default
float latin = 0.0f; // set to zero for Stereographic projections
Attribute rot = netCdfFile.findGlobalAttribute("rotation");
float rotation = 0.0f;
// read the projection
@ -214,6 +216,9 @@ public class RegionalSatDecoder extends AbstractDecoder {
if (projection.equalsIgnoreCase("LAMBERT")
|| projection.equalsIgnoreCase("LAMBERT_CONFORMAL")) {
mapProjection = SatSpatialFactory.PROJ_LAMBERT;
if (rot != null) {
rotation = rot.getNumericValue().floatValue();
}
} else if (projection.equalsIgnoreCase("MERCATOR")) {
mapProjection = SatSpatialFactory.PROJ_MERCATOR;
} else if (projection
@ -222,7 +227,6 @@ public class RegionalSatDecoder extends AbstractDecoder {
}
} else {
Attribute rot = netCdfFile.findGlobalAttribute("rotation");
if (rot != null) {
rotation = rot.getNumericValue().floatValue();
// STEREOGRAPHIC projection add rotation to lov
@ -274,9 +278,15 @@ public class RegionalSatDecoder extends AbstractDecoder {
"Unable to decode Satellite: Encountered Unknown projection");
} // end of if map projection block
SatMapCoverage mapCoverage = SatSpatialFactory.getInstance()
.getCoverageTwoCorners(mapProjection, nx, ny, lov, latin,
la1, lo1, la2, lo2);
SatMapCoverage mapCoverage;
if (mapProjection == SatSpatialFactory.PROJ_LAMBERT && rot != null && rotation != latin)
mapCoverage = SatSpatialFactory.getInstance()
.getCoverageTwoCorners(mapProjection, nx, ny, lov, latin, rotation,
la1, lo1, la2, lo2);
else
mapCoverage = SatSpatialFactory.getInstance()
.getCoverageTwoCorners(mapProjection, nx, ny, lov, latin,
la1, lo1, la2, lo2);
record.setTraceId(traceId);
record.setCoverage(mapCoverage);
@ -357,4 +367,4 @@ public class RegionalSatDecoder extends AbstractDecoder {
this.filename = file;
}
}
}