VLab Issue #4723 - Ingest LambertConformal projection with two standard parallels using RegionalSat; fixes #4723
Change-Id: I20b309f4e994259a54e6bdb2276bc09a6b60a885 Former-commit-id: baf75c177b595dcfb545436586c31d28080b8281
This commit is contained in:
parent
088ebd2ca2
commit
0b425f94eb
2 changed files with 70 additions and 36 deletions
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue