Issue #3017 Update SatSpatialFactory to have more specific methods.

Former-commit-id: 08555e628c8caa41dc312ed91e3ecc9a39a1b5dc
This commit is contained in:
Ben Steffensmeier 2014-04-15 11:51:53 -05:00 committed by Gerrit Code Review
parent 5bf5bdb6b0
commit 6ea38cfbb2
3 changed files with 297 additions and 272 deletions

View file

@ -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 06, 2007 555 garmendariz Modifed start point to remove satellite
* header
* Dec 17, 2007 600 bphillip Added dao pool usage * Dec 17, 2007 600 bphillip Added dao pool usage
* 04Apr2008 1068 MW Fegan Modified decompression routine to prevent * Apr 04, 2008 1068 MW Fegan Modified decompression routine to prevent
* process hang-up. * process hang-up.
* 11/11/2008 chammack Refactored to be thread safe in camel * Nov 11, 2008 chammack Refactored to be thread safe in camel
* 02/05/2010 4120 jkorman Modified removeWmoHeader to handle WMOHeader in * Feb 05, 2010 4120 jkorman Modified removeWmoHeader to handle
* various start locations. * WMOHeader in various start locations.
* 04/17/2012 14724 kshresth This is a temporary workaround - Projection off CONUS * Apr 17, 2012 14724 kshresth This is a temporary workaround -
* - AWIPS2 Baseline Repository -------- * Projection off CONUS
* 06/27/2012 798 jkorman Using SatelliteMessageData to "carry" the decoded image. * Jun 27, 2012 798 jkorman Using SatelliteMessageData to "carry" the
* 01/03/2013 15294 D. Friedman Start with File instead of byte[] to * decoded image.
* Jan 03, 2013 15294 D. Friedman Start with File instead of byte[] to
* reduce memory usage. * reduce memory usage.
* Feb 15, 2013 1638 mschenke Moved array based utilities from Util into ArraysUtil * Feb 15, 2013 1638 mschenke Moved array based utilities from Util
* * into ArraysUtil
* Mar 19, 2013 1785 bgonzale Added performance status handler and added status * Mar 19, 2013 1785 bgonzale Added performance status handler and
* to decode. * added status to decode.
* Jan 20, 2014 njensen Better error handling when fields are not recognized * 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,28 +413,33 @@ 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.
@ -457,7 +447,6 @@ public class SatelliteDecoder {
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());
} catch (Throwable e) { } catch (Throwable e) {

View file

@ -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;
/** /**
* *
@ -43,11 +37,13 @@ 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 {
if (mapProjection == PROJ_MERCATOR) {
return getCoverageTwoCorners(mapProjection, nx, ny, lov, latin,
la1, lo1, la2, lo2);
} else {
return getCoverageSingleCorner(mapProjection, nx, ny, lov, latin,
la1, lo1, dx, dy);
}
}
/**
* Create a {@link SatMapCoverage} with an area defined by only one corner
* 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 crsType
* the type of CRS, must be one of
* {@link #PROJ_CYLIN_EQUIDISTANT}, {@link #PROJ_LAMBERT},
* {@link #PROJ_MERCATOR}, {@link #PROJ_POLAR}.
* @param nx
* the number of columns of data.
* @param ny
* the number of rows of data.
* @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, if dy is positive this
* is an upper corner.
* @param lo1
* the longitide 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.
* @param dy
* the distance between rows measured in CRS meters.
* @return a {@link SatMapCoverage} matching these parameters that has been
* loaded from or persisted to the database.
* @throws DecoderException
*/
public SatMapCoverage getCoverageSingleCorner(int crsType, int nx, int ny,
double lov, double latin, double la1, double lo1, double dx,
double dy) throws DecoderException {
try { try {
SatMapCoverage mapCoverage = createMapCoverage(mapProjection, nx, ProjectedCRS crs = createCRS(crsType, lov, latin, 0.0);
ny, dx, dy, lov, latin, la1, lo1, la2, lo2); DirectPosition2D corner = new DirectPosition2D(lo1, la1);
SatMapCoverage persisted = satDao MathTransform fromLatLon = MapUtil.getTransformFromLatLon(crs);
.queryByMapId(mapCoverage.getGid()); 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);
}
}
/**
*
* Create a {@link SatMapCoverage} with an area defined by two corners. The
* two corners must be opposite(diagnol) from eachother. They caan be either
* 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;
if ((lo1 > 0.0) && (lo2 < 0.0)) {
cm = 180.0;
}
ProjectedCRS crs = createCRS(crsType, lov, latin, cm);
DirectPosition2D corner1 = new DirectPosition2D(lo1, la1);
DirectPosition2D corner2 = new DirectPosition2D(lo2, la2);
MathTransform fromLatLon = MapUtil.getTransformFromLatLon(crs);
fromLatLon.transform(corner1, corner1);
fromLatLon.transform(corner2, corner2);
Envelope e = new Envelope(corner1.x, corner2.x, corner1.y,
corner2.y);
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("la2=" + la2).append("\n\t");
buf.append("lo2=" + lo2).append("\n");
throw new DecoderException(buf.toString(), e);
}
}
/** Load or persist a {@link SatMapCoverage} */
private synchronized SatMapCoverage checkPersisted(
SatMapCoverage mapCoverage) {
SatMapCoverage persisted = satDao.queryByMapId(mapCoverage.getGid());
if (persisted == null) { if (persisted == null) {
persisted = mapCoverage; persisted = mapCoverage;
satDao.persist(persisted); satDao.persist(persisted);
} }
return 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 SatMapCoverage from an envelope and additional metadata. The
* parameters * minX and minY from the envelope are used and dx/dy are derived useing the
* * envelope dimensions and nx/ny.
* @param mapProjection
* The projection
* @param nx
* The number of columns
* @param ny
* The number of rows
* @param dx
* The distance between x points
* @param dy
* The distance between y points
* @param lov
* The orientation of the grid
* @param latin
* The latitude at which the Lambert projection cone is tangent
* to the earth
* @param la1
* Latitude of first point
* @param lo1
* Longitude of first point
* @param la2
* Latitude of last point
* @param lo2
* Longitude of last point
* @return A SatMapCoverage object with the given values
* @throws Exception
* If errors occur during generation of the coverage object
*/ */
private synchronized SatMapCoverage createMapCoverage( private static SatMapCoverage createCoverageFromEnvelope(int crsType,
Integer mapProjection, Integer nx, Integer ny, Float dx, Float dy, ProjectedCRS crs, Envelope envelope, int nx, int ny) {
Float lov, Float latin, Float la1, Float lo1, Float la2, Float lo2) float dx = (float) (envelope.getWidth() / nx);
throws Exception { float dy = (float) (envelope.getWidth() / nx);
return new SatMapCoverage(crsType, envelope.getMinX(),
logger.debug("Creating map coverage object"); envelope.getMinY(), nx, ny, dx, dy, crs);
ProjectedCRS crs = null;
// Get the correct CRS
if (mapProjection == PROJ_MERCATOR) {
double cm = 0.0;
if ((lo1 > 0.0) && (lo2 < 0.0)) {
cm = 180.0;
} }
crs = MapUtil.constructMercator(MapUtil.AWIPS_EARTH_RADIUS,
/**
* 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); MapUtil.AWIPS_EARTH_RADIUS, latin, cm);
} else if (mapProjection == PROJ_LAMBERT) { }
crs = MapUtil.constructLambertConformal(MapUtil.AWIPS_EARTH_RADIUS,
private static ProjectedCRS createLambertCrs(double latin, double lov) {
return MapUtil.constructLambertConformal(MapUtil.AWIPS_EARTH_RADIUS,
MapUtil.AWIPS_EARTH_RADIUS, latin, latin, lov); 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, private static ProjectedCRS createEqCylCrs(double latin, double lov) {
lov, latin); return MapUtil.constructEquidistantCylindrical(
} else { MapUtil.AWIPS_EARTH_RADIUS, MapUtil.AWIPS_EARTH_RADIUS, lov,
crs = MapUtil.constructNorthPolarStereo(MapUtil.AWIPS_EARTH_RADIUS, latin);
}
private static ProjectedCRS createNorthPolarStereoCrs(double lov) {
return MapUtil.constructNorthPolarStereo(MapUtil.AWIPS_EARTH_RADIUS,
MapUtil.AWIPS_EARTH_RADIUS, 60, lov); 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 toLatLon = fromLatLon.inverse();
// Use la1 and lo1 to specifyt the first point
firstPosition = new DirectPosition2D();
fromLatLon.transform(new DirectPosition2D(lo1, la1), firstPosition);
// Determine the 3 other corner points using the given dx,dy,nx, and
// ny in meters
secondPosition = new DirectPosition2D(firstPosition.x + (dx * nx),
firstPosition.y);
thirdPosition = new DirectPosition2D(secondPosition.x,
firstPosition.y + (dy * ny));
fourthPosition = new DirectPosition2D(firstPosition.x,
thirdPosition.y);
// Convert the corner points from meters to lat/lon
toLatLon.transform(firstPosition, corner1);
toLatLon.transform(secondPosition, corner2);
toLatLon.transform(thirdPosition, corner3);
toLatLon.transform(fourthPosition, corner4);
}
double[] c = corner1.getCoordinate();
Coordinate c1 = new Coordinate(c[0], c[1]);
c = corner2.getCoordinate();
Coordinate c2 = new Coordinate(c[0], c[1]);
c = corner3.getCoordinate();
Coordinate c3 = new Coordinate(c[0], c[1]);
c = corner4.getCoordinate();
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(),
nx, ny, dx, dy, crs);
}
} }

View file

@ -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,36 +274,13 @@ 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 {
mapCoverage = SatSpatialFactory.getInstance()
.getMapCoverage(mapProjection, nx, ny, dx, dy, lov,
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) {
record.setTraceId(traceId); record.setTraceId(traceId);
record.setCoverage(mapCoverage); record.setCoverage(mapCoverage);
record.setPersistenceTime(TimeTools.getSystemCalendar() record.setPersistenceTime(TimeTools.getSystemCalendar().getTime());
.getTime());
// Set the data into the IDataRecord // Set the data into the IDataRecord
IDataRecord dataRec = SatelliteRecord.getDataRecord(record); IDataRecord dataRec = SatelliteRecord.getDataRecord(record);
@ -315,7 +293,6 @@ public class RegionalSatDecoder extends AbstractDecoder {
record = null; 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) {