Issue #3017 Update SatSpatialFactory to have more specific methods.
Former-commit-id: 08555e628c8caa41dc312ed91e3ecc9a39a1b5dc
This commit is contained in:
parent
5bf5bdb6b0
commit
6ea38cfbb2
3 changed files with 297 additions and 272 deletions
|
@ -57,36 +57,41 @@ import com.raytheon.uf.common.util.ArraysUtil;
|
||||||
import com.raytheon.uf.common.util.header.WMOHeaderFinder;
|
import com.raytheon.uf.common.util.header.WMOHeaderFinder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decoder implementation for satellite plugin.
|
* Decodes GINI formatted satelitte data into {@link SatelliteRecord}s.
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
*
|
*
|
||||||
* SOFTWARE HISTORY
|
* SOFTWARE HISTORY
|
||||||
*
|
*
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ----------- ---------- ----------- --------------------------
|
* ------------- -------- ----------- -----------------------------------------
|
||||||
* 006 garmenda Initial Creation
|
* 2006 garmenda Initial Creation
|
||||||
* /14/2007 139 Phillippe Modified to follow refactored plugin pattern
|
* Feb 14, 2007 139 Phillippe Modified to follow refactored plugin
|
||||||
* 8/30/07 njensen Added units, commented out data that
|
* pattern
|
||||||
* is currently decoded but not used.
|
* Aug 30, 2007 njensen Added units, commented out data that is
|
||||||
* 12/01/07 555 garmendariz Modified decompress method.
|
* currently decoded but not used.
|
||||||
* 12/06/07 555 garmendariz Modifed start point to remove satellite header
|
* Dec 01, 2007 555 garmendariz Modified decompress method.
|
||||||
* Dec 17, 2007 600 bphillip Added dao pool usage
|
* DEc 06, 2007 555 garmendariz Modifed start point to remove satellite
|
||||||
* 04Apr2008 1068 MW Fegan Modified decompression routine to prevent
|
* header
|
||||||
* process hang-up.
|
* Dec 17, 2007 600 bphillip Added dao pool usage
|
||||||
* 11/11/2008 chammack Refactored to be thread safe in camel
|
* Apr 04, 2008 1068 MW Fegan Modified decompression routine to prevent
|
||||||
* 02/05/2010 4120 jkorman Modified removeWmoHeader to handle WMOHeader in
|
* process hang-up.
|
||||||
* various start locations.
|
* Nov 11, 2008 chammack Refactored to be thread safe in camel
|
||||||
* 04/17/2012 14724 kshresth This is a temporary workaround - Projection off CONUS
|
* Feb 05, 2010 4120 jkorman Modified removeWmoHeader to handle
|
||||||
* - AWIPS2 Baseline Repository --------
|
* WMOHeader in various start locations.
|
||||||
* 06/27/2012 798 jkorman Using SatelliteMessageData to "carry" the decoded image.
|
* Apr 17, 2012 14724 kshresth This is a temporary workaround -
|
||||||
* 01/03/2013 15294 D. Friedman Start with File instead of byte[] to
|
* Projection off CONUS
|
||||||
* reduce memory usage.
|
* Jun 27, 2012 798 jkorman Using SatelliteMessageData to "carry" the
|
||||||
* Feb 15, 2013 1638 mschenke Moved array based utilities from Util into ArraysUtil
|
* decoded image.
|
||||||
*
|
* Jan 03, 2013 15294 D. Friedman Start with File instead of byte[] to
|
||||||
* Mar 19, 2013 1785 bgonzale Added performance status handler and added status
|
* reduce memory usage.
|
||||||
* to decode.
|
* Feb 15, 2013 1638 mschenke Moved array based utilities from Util
|
||||||
* Jan 20, 2014 njensen Better error handling when fields are not recognized
|
* into ArraysUtil
|
||||||
|
* Mar 19, 2013 1785 bgonzale Added performance status handler and
|
||||||
|
* added status to decode.
|
||||||
|
* Jan 20, 2014 2359 njensen Better error handling when fields are not
|
||||||
|
* recognized
|
||||||
|
* Apr 15, 2014 3017 bsteffen Call new methods in SatSpatialFactory
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -369,7 +374,10 @@ public class SatelliteDecoder {
|
||||||
// get the scanning mode
|
// get the scanning mode
|
||||||
scanMode = byteBuffer.get(37);
|
scanMode = byteBuffer.get(37);
|
||||||
|
|
||||||
float dx = 0.0f, dy = 0.0f, lov = 0.0f, lo2 = 0.0f, la2 = 0.0f;
|
float dx = 0.0f;
|
||||||
|
float dy = 0.0f;
|
||||||
|
|
||||||
|
SatMapCoverage mapCoverage = null;
|
||||||
// Do specialized decoding and retrieve spatial data for Lambert
|
// Do specialized decoding and retrieve spatial data for Lambert
|
||||||
// Conformal and Polar Stereographic projections
|
// Conformal and Polar Stereographic projections
|
||||||
if ((mapProjection == SatSpatialFactory.PROJ_LAMBERT)
|
if ((mapProjection == SatSpatialFactory.PROJ_LAMBERT)
|
||||||
|
@ -384,30 +392,7 @@ public class SatelliteDecoder {
|
||||||
|
|
||||||
byteBuffer.position(27);
|
byteBuffer.position(27);
|
||||||
byteBuffer.get(threeBytesArray, 0, 3);
|
byteBuffer.get(threeBytesArray, 0, 3);
|
||||||
lov = transformLongitude(threeBytesArray);
|
float lov = transformLongitude(threeBytesArray);
|
||||||
}
|
|
||||||
// Do specialized decoding and retrieve spatial data for
|
|
||||||
// Mercator projection
|
|
||||||
else if (mapProjection == SatSpatialFactory.PROJ_MERCATOR) {
|
|
||||||
dx = byteBuffer.getShort(33);
|
|
||||||
dy = byteBuffer.getShort(35);
|
|
||||||
|
|
||||||
byteBuffer.position(27);
|
|
||||||
byteBuffer.get(threeBytesArray, 0, 3);
|
|
||||||
la2 = transformLatitude(threeBytesArray);
|
|
||||||
|
|
||||||
byteBuffer.position(30);
|
|
||||||
byteBuffer.get(threeBytesArray, 0, 3);
|
|
||||||
lo2 = transformLongitude(threeBytesArray);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
throw new DecoderException(
|
|
||||||
"Unable to decode GINI Satellite: Encountered Unknown projection");
|
|
||||||
}
|
|
||||||
|
|
||||||
SatMapCoverage mapCoverage = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
/**
|
/**
|
||||||
* This is a temporary workaround for DR14724, hopefully to
|
* This is a temporary workaround for DR14724, hopefully to
|
||||||
* be removed after NESDIS changes the product header
|
* be removed after NESDIS changes the product header
|
||||||
|
@ -428,35 +413,39 @@ public class SatelliteDecoder {
|
||||||
* End of DR14724
|
* End of DR14724
|
||||||
*/
|
*/
|
||||||
mapCoverage = SatSpatialFactory.getInstance()
|
mapCoverage = SatSpatialFactory.getInstance()
|
||||||
.getMapCoverage(mapProjection, nx, ny, dx, dy, lov,
|
.getCoverageSingleCorner(mapProjection, nx, ny,
|
||||||
|
lov,
|
||||||
|
latin, la1, lo1, dx, dy);
|
||||||
|
}
|
||||||
|
// Do specialized decoding and retrieve spatial data for
|
||||||
|
// Mercator projection
|
||||||
|
else if (mapProjection == SatSpatialFactory.PROJ_MERCATOR) {
|
||||||
|
dx = byteBuffer.getShort(33);
|
||||||
|
dy = byteBuffer.getShort(35);
|
||||||
|
|
||||||
|
byteBuffer.position(27);
|
||||||
|
byteBuffer.get(threeBytesArray, 0, 3);
|
||||||
|
float la2 = transformLatitude(threeBytesArray);
|
||||||
|
|
||||||
|
byteBuffer.position(30);
|
||||||
|
byteBuffer.get(threeBytesArray, 0, 3);
|
||||||
|
float lo2 = transformLongitude(threeBytesArray);
|
||||||
|
mapCoverage = SatSpatialFactory.getInstance()
|
||||||
|
.getCoverageTwoCorners(mapProjection, nx, ny, 0.0f,
|
||||||
latin, la1, lo1, la2, lo2);
|
latin, la1, lo1, la2, lo2);
|
||||||
} catch (Exception e) {
|
|
||||||
StringBuffer buf = new StringBuffer();
|
} else {
|
||||||
buf.append(
|
throw new DecoderException(
|
||||||
"Error getting or constructing SatMapCoverage for values: ")
|
"Unable to decode GINI Satellite: Encountered Unknown projection: "
|
||||||
.append("\n\t");
|
+ mapProjection);
|
||||||
buf.append("mapProjection=" + mapProjection).append("\n\t");
|
|
||||||
buf.append("nx=" + nx).append("\n\t");
|
|
||||||
buf.append("ny=" + ny).append("\n\t");
|
|
||||||
buf.append("dx=" + dx).append("\n\t");
|
|
||||||
buf.append("dy=" + dy).append("\n\t");
|
|
||||||
buf.append("lov=" + lov).append("\n\t");
|
|
||||||
buf.append("latin=" + latin).append("\n\t");
|
|
||||||
buf.append("la1=" + la1).append("\n\t");
|
|
||||||
buf.append("lo1=" + lo1).append("\n\t");
|
|
||||||
buf.append("la2=" + la2).append("\n\t");
|
|
||||||
buf.append("lo2=" + lo2).append("\n");
|
|
||||||
throw new DecoderException(buf.toString(), e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (record != null) {
|
record.setTraceId(traceId);
|
||||||
record.setTraceId(traceId);
|
record.setCoverage(mapCoverage);
|
||||||
record.setCoverage(mapCoverage);
|
// Create the data record.
|
||||||
// Create the data record.
|
IDataRecord dataRec = messageData.getStorageRecord(record,
|
||||||
IDataRecord dataRec = messageData.getStorageRecord(record,
|
SatelliteRecord.SAT_DATASET_NAME);
|
||||||
SatelliteRecord.SAT_DATASET_NAME);
|
record.setMessageData(dataRec);
|
||||||
record.setMessageData(dataRec);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
timer.stop();
|
timer.stop();
|
||||||
perfLog.logDuration("Time to Decode", timer.getElapsedTime());
|
perfLog.logDuration("Time to Decode", timer.getElapsedTime());
|
||||||
|
|
|
@ -20,21 +20,15 @@
|
||||||
|
|
||||||
package com.raytheon.edex.util.satellite;
|
package com.raytheon.edex.util.satellite;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
import org.geotools.geometry.DirectPosition2D;
|
import org.geotools.geometry.DirectPosition2D;
|
||||||
import org.geotools.geometry.jts.JTS;
|
|
||||||
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.exception.DecoderException;
|
||||||
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.raytheon.uf.edex.database.DataAccessLayerException;
|
|
||||||
import com.vividsolutions.jts.geom.Coordinate;
|
|
||||||
import com.vividsolutions.jts.geom.Envelope;
|
import com.vividsolutions.jts.geom.Envelope;
|
||||||
import com.vividsolutions.jts.geom.GeometryFactory;
|
|
||||||
import com.vividsolutions.jts.geom.Polygon;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -42,12 +36,14 @@ import com.vividsolutions.jts.geom.Polygon;
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* SOFTWARE HISTORY
|
* SOFTWARE HISTORY
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------- -------- ----------- --------------------------
|
||||||
* 12/19/07 439 bphillip Initial creation
|
* Dec 19, 2007 439 bphillip Initial creation
|
||||||
* - AWIPS2 Baseline Repository --------
|
* Jul 12, 2012 798 jkorman Changed projection "magic" numbers
|
||||||
* 07/12/2012 798 jkorman Changed projection "magic" numbers
|
* Sep 30, 2013 2333 mschenke Refactored to store points in crs space
|
||||||
* 09/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.
|
||||||
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*/
|
*/
|
||||||
public class SatSpatialFactory {
|
public class SatSpatialFactory {
|
||||||
|
@ -66,9 +62,6 @@ public class SatSpatialFactory {
|
||||||
|
|
||||||
public static final int UNDEFINED = -1;
|
public static final int UNDEFINED = -1;
|
||||||
|
|
||||||
/** The logger */
|
|
||||||
private Log logger = LogFactory.getLog(getClass());
|
|
||||||
|
|
||||||
/** The singleton instance */
|
/** The singleton instance */
|
||||||
private static SatSpatialFactory instance;
|
private static SatSpatialFactory instance;
|
||||||
|
|
||||||
|
@ -87,7 +80,11 @@ public class SatSpatialFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves or generates a satellite map coverage object
|
* @deprecated use either
|
||||||
|
* {@link #getCoverageSingleCorner(int, int, int, double, double, double, double, double, double)}
|
||||||
|
* or
|
||||||
|
* {@link #getCoverageTwoCorners(int, int, int, double, double, double, double, double, double)}
|
||||||
|
* depending on which parameters are considered more accurate.
|
||||||
*
|
*
|
||||||
* @param mapProjection
|
* @param mapProjection
|
||||||
* The projection
|
* The projection
|
||||||
|
@ -117,169 +114,231 @@ public class SatSpatialFactory {
|
||||||
* If errors occur during db interaction or creation of the
|
* If errors occur during db interaction or creation of the
|
||||||
* coverage object
|
* coverage object
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public synchronized SatMapCoverage getMapCoverage(Integer mapProjection,
|
public synchronized SatMapCoverage getMapCoverage(Integer mapProjection,
|
||||||
Integer nx, Integer ny, Float dx, Float dy, Float lov, Float latin,
|
Integer nx, Integer ny, Float dx, Float dy, Float lov, Float latin,
|
||||||
Float la1, Float lo1, Float la2, Float lo2) throws Exception {
|
Float la1, Float lo1, Float la2, Float lo2) throws Exception {
|
||||||
try {
|
if (mapProjection == PROJ_MERCATOR) {
|
||||||
SatMapCoverage mapCoverage = createMapCoverage(mapProjection, nx,
|
return getCoverageTwoCorners(mapProjection, nx, ny, lov, latin,
|
||||||
ny, dx, dy, lov, latin, la1, lo1, la2, lo2);
|
la1, lo1, la2, lo2);
|
||||||
SatMapCoverage persisted = satDao
|
} else {
|
||||||
.queryByMapId(mapCoverage.getGid());
|
return getCoverageSingleCorner(mapProjection, nx, ny, lov, latin,
|
||||||
if (persisted == null) {
|
la1, lo1, dx, dy);
|
||||||
persisted = mapCoverage;
|
|
||||||
satDao.persist(persisted);
|
|
||||||
}
|
|
||||||
return persisted;
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new DataAccessLayerException(
|
|
||||||
"Unable to retrieve or construct valid Satellite Map Coverage",
|
|
||||||
e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new SatMapCoverage object from scratch with the given
|
* Create a {@link SatMapCoverage} with an area defined by only one corner
|
||||||
* parameters
|
* and using dx/dy and nx/by to derive the rest of the area. If dx and dy
|
||||||
|
* are positive than la1 and lo1 are the upper left corner.
|
||||||
*
|
*
|
||||||
* @param mapProjection
|
* @param crsType
|
||||||
* The projection
|
* the type of CRS, must be one of
|
||||||
|
* {@link #PROJ_CYLIN_EQUIDISTANT}, {@link #PROJ_LAMBERT},
|
||||||
|
* {@link #PROJ_MERCATOR}, {@link #PROJ_POLAR}.
|
||||||
* @param nx
|
* @param nx
|
||||||
* The number of columns
|
* the number of columns of data.
|
||||||
* @param ny
|
* @param ny
|
||||||
* The number of rows
|
* the number of rows of data.
|
||||||
* @param dx
|
|
||||||
* The distance between x points
|
|
||||||
* @param dy
|
|
||||||
* The distance between y points
|
|
||||||
* @param lov
|
* @param lov
|
||||||
* The orientation of the grid
|
* the longitude orientatition, used by
|
||||||
|
* {@link #PROJ_CYLIN_EQUIDISTANT}, {@link #PROJ_LAMBERT},
|
||||||
|
* {@link #PROJ_POLAR}.
|
||||||
* @param latin
|
* @param latin
|
||||||
* The latitude at which the Lambert projection cone is tangent
|
* the latitude at which the projection is tangent to the earths
|
||||||
* to the earth
|
* surface, used by {@link #PROJ_CYLIN_EQUIDISTANT},
|
||||||
|
* {@link #PROJ_LAMBERT}, {@link #PROJ_MERCATOR}.
|
||||||
* @param la1
|
* @param la1
|
||||||
* Latitude of first point
|
* the latitude of a corner of the grid, if dy is positive this
|
||||||
|
* is an upper corner.
|
||||||
* @param lo1
|
* @param lo1
|
||||||
* Longitude of first point
|
* the longitide of a corner of the grid, if dx is positive this
|
||||||
* @param la2
|
* is a left corner
|
||||||
* Latitude of last point
|
* @param dx
|
||||||
* @param lo2
|
* the distance between columns measured in CRS meters.
|
||||||
* Longitude of last point
|
* @param dy
|
||||||
* @return A SatMapCoverage object with the given values
|
* the distance between rows measured in CRS meters.
|
||||||
* @throws Exception
|
* @return a {@link SatMapCoverage} matching these parameters that has been
|
||||||
* If errors occur during generation of the coverage object
|
* loaded from or persisted to the database.
|
||||||
|
* @throws DecoderException
|
||||||
*/
|
*/
|
||||||
private synchronized SatMapCoverage createMapCoverage(
|
public SatMapCoverage getCoverageSingleCorner(int crsType, int nx, int ny,
|
||||||
Integer mapProjection, Integer nx, Integer ny, Float dx, Float dy,
|
double lov, double latin, double la1, double lo1, double dx,
|
||||||
Float lov, Float latin, Float la1, Float lo1, Float la2, Float lo2)
|
double dy) throws DecoderException {
|
||||||
throws Exception {
|
try {
|
||||||
|
ProjectedCRS crs = createCRS(crsType, lov, latin, 0.0);
|
||||||
|
DirectPosition2D corner = new DirectPosition2D(lo1, la1);
|
||||||
|
MathTransform fromLatLon = MapUtil.getTransformFromLatLon(crs);
|
||||||
|
fromLatLon.transform(corner, corner);
|
||||||
|
Envelope e = new Envelope(corner.x, corner.x, corner.y, corner.y);
|
||||||
|
e.expandToInclude(corner.x + dx * nx, corner.y + dy * ny);
|
||||||
|
SatMapCoverage coverage = createCoverageFromEnvelope(crsType, crs,
|
||||||
|
e, nx, ny);
|
||||||
|
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("lov=" + lov).append("\n\t");
|
||||||
|
buf.append("latin=" + latin).append("\n\t");
|
||||||
|
buf.append("la1=" + la1).append("\n\t");
|
||||||
|
buf.append("lo1=" + lo1).append("\n\t");
|
||||||
|
buf.append("dx=" + dx).append("\n\t");
|
||||||
|
buf.append("dy=" + dy).append("\n");
|
||||||
|
throw new DecoderException(buf.toString(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
logger.debug("Creating map coverage object");
|
/**
|
||||||
|
*
|
||||||
ProjectedCRS crs = null;
|
* Create a {@link SatMapCoverage} with an area defined by two corners. The
|
||||||
// Get the correct CRS
|
* two corners must be opposite(diagnol) from eachother. They caan be either
|
||||||
if (mapProjection == PROJ_MERCATOR) {
|
* the upper left and lower right or the upper right and lower left corners.
|
||||||
|
*
|
||||||
|
* @param crsType
|
||||||
|
* the type of CRS, must be one of
|
||||||
|
* {@link #PROJ_CYLIN_EQUIDISTANT}, {@link #PROJ_LAMBERT},
|
||||||
|
* {@link #PROJ_MERCATOR}, {@link #PROJ_POLAR}.
|
||||||
|
* @param lov
|
||||||
|
* the longitude orientatition, 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 la1
|
||||||
|
* the latitude of a corner of the grid.
|
||||||
|
* @param lo1
|
||||||
|
* the longitide 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
|
||||||
|
* 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 lo2) throws DecoderException {
|
||||||
|
try {
|
||||||
double cm = 0.0;
|
double cm = 0.0;
|
||||||
if ((lo1 > 0.0) && (lo2 < 0.0)) {
|
if ((lo1 > 0.0) && (lo2 < 0.0)) {
|
||||||
cm = 180.0;
|
cm = 180.0;
|
||||||
}
|
}
|
||||||
crs = MapUtil.constructMercator(MapUtil.AWIPS_EARTH_RADIUS,
|
ProjectedCRS crs = createCRS(crsType, lov, latin, cm);
|
||||||
MapUtil.AWIPS_EARTH_RADIUS, latin, cm);
|
DirectPosition2D corner1 = new DirectPosition2D(lo1, la1);
|
||||||
} else if (mapProjection == PROJ_LAMBERT) {
|
DirectPosition2D corner2 = new DirectPosition2D(lo2, la2);
|
||||||
crs = MapUtil.constructLambertConformal(MapUtil.AWIPS_EARTH_RADIUS,
|
|
||||||
MapUtil.AWIPS_EARTH_RADIUS, latin, latin, lov);
|
|
||||||
} else if (mapProjection == SatSpatialFactory.PROJ_CYLIN_EQUIDISTANT) {
|
|
||||||
crs = MapUtil.constructEquidistantCylindrical(
|
|
||||||
MapUtil.AWIPS_EARTH_RADIUS, MapUtil.AWIPS_EARTH_RADIUS,
|
|
||||||
lov, latin);
|
|
||||||
} else {
|
|
||||||
crs = MapUtil.constructNorthPolarStereo(MapUtil.AWIPS_EARTH_RADIUS,
|
|
||||||
MapUtil.AWIPS_EARTH_RADIUS, 60, lov);
|
|
||||||
}
|
|
||||||
|
|
||||||
DirectPosition2D firstPosition = null;
|
|
||||||
DirectPosition2D secondPosition = null;
|
|
||||||
DirectPosition2D thirdPosition = null;
|
|
||||||
DirectPosition2D fourthPosition = null;
|
|
||||||
DirectPosition2D corner1 = new DirectPosition2D();
|
|
||||||
DirectPosition2D corner2 = new DirectPosition2D();
|
|
||||||
DirectPosition2D corner3 = new DirectPosition2D();
|
|
||||||
DirectPosition2D corner4 = new DirectPosition2D();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Projection is Mercator. Determine corner points from la1,lo1,la2,lo2
|
|
||||||
* provided in the satellite file
|
|
||||||
*/
|
|
||||||
if (mapProjection == PROJ_MERCATOR) {
|
|
||||||
logger.debug("Determining corner points for Mercator projection");
|
|
||||||
corner1.x = lo1;
|
|
||||||
corner1.y = la1;
|
|
||||||
|
|
||||||
corner3.x = lo2;
|
|
||||||
corner3.y = la2;
|
|
||||||
|
|
||||||
corner2.x = lo2;
|
|
||||||
corner2.y = la1;
|
|
||||||
|
|
||||||
corner4.x = lo1;
|
|
||||||
corner4.y = la2;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Projection is Lambert Conformal or Polar Stereographic. Therefore,
|
|
||||||
* the corner points must be calculated
|
|
||||||
*/
|
|
||||||
else {
|
|
||||||
logger.debug("Determining corner points for Lambert Conformal or Polar Stereographic projection");
|
|
||||||
|
|
||||||
// Get the transforms to be used to convert between meters and
|
|
||||||
// lat/lon
|
|
||||||
MathTransform fromLatLon = MapUtil.getTransformFromLatLon(crs);
|
MathTransform fromLatLon = MapUtil.getTransformFromLatLon(crs);
|
||||||
MathTransform toLatLon = fromLatLon.inverse();
|
fromLatLon.transform(corner1, corner1);
|
||||||
|
fromLatLon.transform(corner2, corner2);
|
||||||
// Use la1 and lo1 to specifyt the first point
|
Envelope e = new Envelope(corner1.x, corner2.x, corner1.y,
|
||||||
firstPosition = new DirectPosition2D();
|
corner2.y);
|
||||||
fromLatLon.transform(new DirectPosition2D(lo1, la1), firstPosition);
|
SatMapCoverage coverage = createCoverageFromEnvelope(crsType, crs,
|
||||||
|
e, nx, ny);
|
||||||
// Determine the 3 other corner points using the given dx,dy,nx, and
|
return checkPersisted(coverage);
|
||||||
// ny in meters
|
} catch (Exception e) {
|
||||||
secondPosition = new DirectPosition2D(firstPosition.x + (dx * nx),
|
StringBuilder buf = new StringBuilder();
|
||||||
firstPosition.y);
|
buf.append(
|
||||||
thirdPosition = new DirectPosition2D(secondPosition.x,
|
"Error getting or constructing SatMapCoverage for values: ")
|
||||||
firstPosition.y + (dy * ny));
|
.append("\n\t");
|
||||||
fourthPosition = new DirectPosition2D(firstPosition.x,
|
buf.append("crsType=" + crsType).append("\n\t");
|
||||||
thirdPosition.y);
|
buf.append("nx=" + nx).append("\n\t");
|
||||||
|
buf.append("ny=" + ny).append("\n\t");
|
||||||
// Convert the corner points from meters to lat/lon
|
buf.append("lov=" + lov).append("\n\t");
|
||||||
toLatLon.transform(firstPosition, corner1);
|
buf.append("latin=" + latin).append("\n\t");
|
||||||
toLatLon.transform(secondPosition, corner2);
|
buf.append("la1=" + la1).append("\n\t");
|
||||||
toLatLon.transform(thirdPosition, corner3);
|
buf.append("lo1=" + lo1).append("\n\t");
|
||||||
toLatLon.transform(fourthPosition, corner4);
|
buf.append("la2=" + la2).append("\n\t");
|
||||||
|
buf.append("lo2=" + lo2).append("\n");
|
||||||
|
throw new DecoderException(buf.toString(), e);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
double[] c = corner1.getCoordinate();
|
/** Load or persist a {@link SatMapCoverage} */
|
||||||
Coordinate c1 = new Coordinate(c[0], c[1]);
|
private synchronized SatMapCoverage checkPersisted(
|
||||||
c = corner2.getCoordinate();
|
SatMapCoverage mapCoverage) {
|
||||||
Coordinate c2 = new Coordinate(c[0], c[1]);
|
SatMapCoverage persisted = satDao.queryByMapId(mapCoverage.getGid());
|
||||||
c = corner3.getCoordinate();
|
if (persisted == null) {
|
||||||
Coordinate c3 = new Coordinate(c[0], c[1]);
|
persisted = mapCoverage;
|
||||||
c = corner4.getCoordinate();
|
satDao.persist(persisted);
|
||||||
Coordinate c4 = new Coordinate(c[0], c[1]);
|
|
||||||
|
|
||||||
// Go from lat/lon to crs space to get minX,minY in crs space
|
|
||||||
GeometryFactory gf = new GeometryFactory();
|
|
||||||
Polygon polygon = gf.createPolygon(
|
|
||||||
gf.createLinearRing(new Coordinate[] { c1, c2, c3, c4, c1 }),
|
|
||||||
null);
|
|
||||||
MathTransform fromLatLon = MapUtil.getTransformFromLatLon(crs);
|
|
||||||
|
|
||||||
polygon = (Polygon) JTS.transform(polygon, fromLatLon);
|
|
||||||
Envelope env = polygon.getEnvelopeInternal();
|
|
||||||
if (mapProjection == PROJ_MERCATOR) {
|
|
||||||
// Calculate dx/dy in mercator crs space
|
|
||||||
dx = (float) (env.getWidth() / nx);
|
|
||||||
dy = (float) (env.getHeight() / ny);
|
|
||||||
}
|
}
|
||||||
return new SatMapCoverage(mapProjection, env.getMinX(), env.getMinY(),
|
return persisted;
|
||||||
nx, ny, dx, dy, crs);
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a SatMapCoverage from an envelope and additional metadata. The
|
||||||
|
* minX and minY from the envelope are used and dx/dy are derived useing the
|
||||||
|
* envelope dimensions and nx/ny.
|
||||||
|
*/
|
||||||
|
private static SatMapCoverage createCoverageFromEnvelope(int crsType,
|
||||||
|
ProjectedCRS crs, Envelope envelope, int nx, int ny) {
|
||||||
|
float dx = (float) (envelope.getWidth() / nx);
|
||||||
|
float dy = (float) (envelope.getWidth() / nx);
|
||||||
|
return new SatMapCoverage(crsType, envelope.getMinX(),
|
||||||
|
envelope.getMinY(), nx, ny, dx, dy, crs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a {@link ProjectedCRS} from a crsType and some parameters.
|
||||||
|
*
|
||||||
|
* @param crsType
|
||||||
|
* the type of CRS, must be one of
|
||||||
|
* {@link #PROJ_CYLIN_EQUIDISTANT}, {@link #PROJ_LAMBERT},
|
||||||
|
* {@link #PROJ_MERCATOR}, {@link #PROJ_POLAR}. * @param lov
|
||||||
|
* @param lov
|
||||||
|
* the longitude orientatition, 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 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) {
|
||||||
|
switch (crsType) {
|
||||||
|
case PROJ_MERCATOR:
|
||||||
|
return createMercatorCrs(latin, cm);
|
||||||
|
case PROJ_LAMBERT:
|
||||||
|
return createLambertCrs(latin, lov);
|
||||||
|
case PROJ_CYLIN_EQUIDISTANT:
|
||||||
|
return createEqCylCrs(latin, lov);
|
||||||
|
default:
|
||||||
|
return createNorthPolarStereoCrs(lov);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ProjectedCRS createMercatorCrs(double latin, double cm) {
|
||||||
|
return MapUtil.constructMercator(MapUtil.AWIPS_EARTH_RADIUS,
|
||||||
|
MapUtil.AWIPS_EARTH_RADIUS, latin, cm);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ProjectedCRS createLambertCrs(double latin, double lov) {
|
||||||
|
return MapUtil.constructLambertConformal(MapUtil.AWIPS_EARTH_RADIUS,
|
||||||
|
MapUtil.AWIPS_EARTH_RADIUS, latin, latin, lov);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ProjectedCRS createEqCylCrs(double latin, double lov) {
|
||||||
|
return MapUtil.constructEquidistantCylindrical(
|
||||||
|
MapUtil.AWIPS_EARTH_RADIUS, MapUtil.AWIPS_EARTH_RADIUS, lov,
|
||||||
|
latin);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ProjectedCRS createNorthPolarStereoCrs(double lov) {
|
||||||
|
return MapUtil.constructNorthPolarStereo(MapUtil.AWIPS_EARTH_RADIUS,
|
||||||
|
MapUtil.AWIPS_EARTH_RADIUS, 60, lov);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,7 @@ import com.raytheon.uf.edex.decodertools.time.TimeTools;
|
||||||
* Sep 24, 2012 1210 jkorman Modified the decode method to create the
|
* Sep 24, 2012 1210 jkorman Modified the decode method to create the
|
||||||
* IDataRecord required by the SatelliteDao
|
* IDataRecord required by the SatelliteDao
|
||||||
* Aug 30, 2013 2298 rjpeter Make getPluginName abstract
|
* Aug 30, 2013 2298 rjpeter Make getPluginName abstract
|
||||||
|
* Apr 15, 2014 3017 bsteffen Call new methods in SatSpatialFactory
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author tk
|
* @author tk
|
||||||
|
@ -273,49 +274,25 @@ public class RegionalSatDecoder extends AbstractDecoder {
|
||||||
"Unable to decode Satellite: Encountered Unknown projection");
|
"Unable to decode Satellite: Encountered Unknown projection");
|
||||||
} // end of if map projection block
|
} // end of if map projection block
|
||||||
|
|
||||||
SatMapCoverage mapCoverage = null;
|
SatMapCoverage mapCoverage = SatSpatialFactory.getInstance()
|
||||||
|
.getCoverageTwoCorners(mapProjection, nx, ny, lov, latin,
|
||||||
|
la1, lo1, la2, lo2);
|
||||||
|
|
||||||
try {
|
record.setTraceId(traceId);
|
||||||
mapCoverage = SatSpatialFactory.getInstance()
|
record.setCoverage(mapCoverage);
|
||||||
.getMapCoverage(mapProjection, nx, ny, dx, dy, lov,
|
record.setPersistenceTime(TimeTools.getSystemCalendar().getTime());
|
||||||
latin, la1, lo1, la2, lo2);
|
|
||||||
} catch (Exception e) {
|
|
||||||
StringBuffer buf = new StringBuffer();
|
|
||||||
buf.append(
|
|
||||||
"Error getting or constructing SatMapCoverage for values: ")
|
|
||||||
.append("\n\t");
|
|
||||||
buf.append("mapProjection=" + mapProjection).append("\n\t");
|
|
||||||
buf.append("nx=" + nx).append("\n\t");
|
|
||||||
buf.append("ny=" + ny).append("\n\t");
|
|
||||||
buf.append("dx=" + dx).append("\n\t");
|
|
||||||
buf.append("dy=" + dy).append("\n\t");
|
|
||||||
buf.append("lov=" + lov).append("\n\t");
|
|
||||||
buf.append("latin=" + latin).append("\n\t");
|
|
||||||
buf.append("la1=" + la1).append("\n\t");
|
|
||||||
buf.append("lo1=" + lo1).append("\n\t");
|
|
||||||
buf.append("la2=" + la2).append("\n\t");
|
|
||||||
buf.append("lo2=" + lo2).append("\n");
|
|
||||||
throw new DecoderException(buf.toString(), e);
|
|
||||||
} // end of catch block
|
|
||||||
|
|
||||||
if (record != null) {
|
// Set the data into the IDataRecord
|
||||||
record.setTraceId(traceId);
|
IDataRecord dataRec = SatelliteRecord.getDataRecord(record);
|
||||||
record.setCoverage(mapCoverage);
|
if (dataRec != null) {
|
||||||
record.setPersistenceTime(TimeTools.getSystemCalendar()
|
record.setMessageData(dataRec);
|
||||||
.getTime());
|
} else {
|
||||||
|
handler.error(
|
||||||
|
String.format("Could not create datarecord for %s"),
|
||||||
|
traceId);
|
||||||
|
record = null;
|
||||||
|
}
|
||||||
|
|
||||||
// Set the data into the IDataRecord
|
|
||||||
IDataRecord dataRec = SatelliteRecord.getDataRecord(record);
|
|
||||||
if (dataRec != null) {
|
|
||||||
record.setMessageData(dataRec);
|
|
||||||
} else {
|
|
||||||
handler.error(
|
|
||||||
String.format("Could not create datarecord for %s"),
|
|
||||||
traceId);
|
|
||||||
record = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end of if statement
|
|
||||||
} // end of if data not empty statement
|
} // end of if data not empty statement
|
||||||
|
|
||||||
if (record == null) {
|
if (record == null) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue