Issue #2333 Refactored satellite to store table values in CRS space instead of lat/lon for GOES-R readiness

Amend: Accepted ticket.

Change-Id: Ib8171694869f60b46fb38634e71de61eb0e76830

Former-commit-id: fe7051816e [formerly 780ac0129f] [formerly e3f6b1ea21] [formerly 866c851b47 [formerly e3f6b1ea21 [formerly 384b8e6a02d4fffa0688993b2a2b53e974ecf493]]]
Former-commit-id: 866c851b47
Former-commit-id: 00101432c385c23ffd439ab94c020a849e2c2d13 [formerly ba25f56dbe]
Former-commit-id: 43b7cb3107
This commit is contained in:
Max Schenkelberg 2013-10-01 14:36:00 -05:00
parent 075a394152
commit 9e14571020
37 changed files with 1012 additions and 1167 deletions

View file

@ -34,13 +34,15 @@ import javax.measure.unit.SI;
import javax.measure.unit.Unit;
import org.eclipse.swt.graphics.RGB;
import org.opengis.metadata.spatial.PixelOrientation;
import org.geotools.coverage.grid.GridGeometry2D;
import org.opengis.referencing.datum.PixelInCell;
import org.opengis.referencing.operation.MathTransform;
import com.raytheon.uf.common.colormap.prefs.ColorMapParameters;
import com.raytheon.uf.common.dataplugin.grid.GridConstants;
import com.raytheon.uf.common.geospatial.ISpatialObject;
import com.raytheon.uf.common.geospatial.MapUtil;
import com.raytheon.uf.common.geospatial.IGridGeometryProvider;
import com.raytheon.uf.common.geospatial.ReferencedCoordinate;
import com.raytheon.uf.common.geospatial.TransformFactory;
import com.raytheon.uf.common.sounding.VerticalSounding;
import com.raytheon.uf.common.sounding.WxMath;
import com.raytheon.uf.common.sounding.adapter.IVerticalSoundingProvider;
@ -76,7 +78,8 @@ import com.vividsolutions.jts.geom.Coordinate;
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jul 18, 2011 2190 mschenke Initial creation
* Jul 18, 2011 2190 mschenke Initial creation
* Oct 2, 2013 2333 mschenke Converted to use IGridGeometryProvider
*
* </pre>
*
@ -417,12 +420,15 @@ public class CloudHeightResource extends
.interrogate(new ReferencedCoordinate(location));
if (interMap != null
&& interMap.get(SATELLITE_DATA_INTERROGATE_ID) instanceof Measure
&& interMap
.containsKey(ISpatialObject.class.toString())) {
&& interMap.containsKey(IGridGeometryProvider.class
.toString())) {
// Extract temperature values from the resource
float[] rscTemps = extractTemps(location, resource,
(ISpatialObject) interMap.get(ISpatialObject.class
.toString()));
float[] rscTemps = extractTemps(
location,
resource,
((IGridGeometryProvider) interMap
.get(IGridGeometryProvider.class.toString()))
.getGridGeometry());
boolean good = true;
for (int i = 0; i < rscTemps.length; ++i) {
if (Float.isNaN(rscTemps[i])) {
@ -441,14 +447,39 @@ public class CloudHeightResource extends
return temps;
}
private Coordinate convert(MathTransform mt, double[] point) {
try {
double[] out = new double[point.length];
mt.transform(point, 0, out, 0, 1);
return new Coordinate(out[0], out[1]);
} catch (Exception e) {
// Ingore and return null
}
return null;
}
private float[] extractTemps(Coordinate latLon,
AbstractVizResource<?, ?> rsc, ISpatialObject spatialObject) {
AbstractVizResource<?, ?> rsc, GridGeometry2D gridGeometry) {
// Method loosely ported from SatPVImageDepict.C::interogate
float[] temps = new float[] { Float.NaN, Float.NaN, Float.NaN,
Float.NaN };
Coordinate c = MapUtil.latLonToGridCoordinate(latLon,
PixelOrientation.CENTER, spatialObject);
MathTransform gridToLatLon, latLonToGrid;
try {
gridToLatLon = TransformFactory.gridToLatLon(gridGeometry,
PixelInCell.CELL_CENTER);
latLonToGrid = gridToLatLon.inverse();
} catch (Exception e) {
// Ignore and return early
return temps;
}
Coordinate c = convert(latLonToGrid,
new double[] { latLon.x, latLon.y });
if (c == null) {
return temps;
}
int x = (int) c.x;
int y = (int) c.y;
@ -471,8 +502,8 @@ public class CloudHeightResource extends
jj = y + j;
for (i = xStart; i < xEnd; i++) {
ii = x + i;
elements[numElements++] = getTemperature(rsc, spatialObject,
ii, jj);
elements[numElements++] = getTemperature(rsc, gridToLatLon, ii,
jj);
}
}
@ -490,21 +521,20 @@ public class CloudHeightResource extends
}
/**
* Interrogates the resource at the spatial object's gridX,gridY location
* and reads out the temperature value converting to
* Interrogates the resource at the gridToLatLon transform, gridX,gridY
* location and reads out the temperature value converting to
* {@link CloudHeightCalculatorPorted#ALGORITHM_UNIT}
*
* @param resource
* @param spatialObject
* @param gridToLatLon
* @param gridX
* @param gridY
* @return
*/
private double getTemperature(AbstractVizResource<?, ?> resource,
ISpatialObject spatialObject, int gridX, int gridY) {
Coordinate latLon = MapUtil.gridCoordinateToLatLon(new Coordinate(
gridX, gridY), PixelOrientation.CENTER, spatialObject);
return getTemperature(resource, latLon);
MathTransform gridToLatLon, int gridX, int gridY) {
return getTemperature(resource,
convert(gridToLatLon, new double[] { gridX, gridY }));
}
/**
@ -521,16 +551,18 @@ public class CloudHeightResource extends
private double getTemperature(AbstractVizResource<?, ?> resource,
Coordinate latLon) {
double temperature = Double.NaN;
try {
Map<String, Object> dataMap = resource
.interrogate(new ReferencedCoordinate(latLon));
Object obj = dataMap.get(SATELLITE_DATA_INTERROGATE_ID);
if (obj instanceof Measure) {
temperature = getDataValue((Measure<?, ?>) obj,
CloudHeightCalculatorPorted.ALGORITHM_UNIT);
if (latLon != null) {
try {
Map<String, Object> dataMap = resource
.interrogate(new ReferencedCoordinate(latLon));
Object obj = dataMap.get(SATELLITE_DATA_INTERROGATE_ID);
if (obj instanceof Measure) {
temperature = getDataValue((Measure<?, ?>) obj,
CloudHeightCalculatorPorted.ALGORITHM_UNIT);
}
} catch (VizException e) {
// Ignore
}
} catch (VizException e) {
// Ignore
}
return temperature;
}

View file

@ -46,17 +46,17 @@ import com.raytheon.uf.common.dataplugin.npp.viirs.VIIRSDataRecord;
import com.raytheon.uf.common.datastorage.Request;
import com.raytheon.uf.common.datastorage.records.IDataRecord;
import com.raytheon.uf.common.datastorage.records.ShortDataRecord;
import com.raytheon.uf.common.geospatial.ISpatialObject;
import com.raytheon.uf.common.geospatial.IGridGeometryProvider;
import com.raytheon.uf.common.geospatial.ReferencedCoordinate;
import com.raytheon.uf.common.geospatial.util.EnvelopeIntersection;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.common.style.LabelingPreferences;
import com.raytheon.uf.common.style.StyleException;
import com.raytheon.uf.common.style.StyleManager;
import com.raytheon.uf.common.style.StyleManager.StyleType;
import com.raytheon.uf.common.style.StyleRule;
import com.raytheon.uf.common.style.StyleException;
import com.raytheon.uf.common.style.image.DataScale;
import com.raytheon.uf.common.style.image.ImagePreferences;
import com.raytheon.uf.common.time.DataTime;
@ -683,8 +683,7 @@ public class VIIRSResource extends
bestValue);
}
if (bestRecord != null) {
interMap.put(ISpatialObject.class.toString(),
bestRecord.getSpatialObject());
interMap.put(IGridGeometryProvider.class.toString(), bestRecord);
}
}

View file

@ -44,6 +44,7 @@ import org.geotools.coverage.grid.GridCoverageFactory;
import org.geotools.coverage.grid.GridGeometry2D;
import com.raytheon.uf.common.dataplugin.PluginDataObject;
import com.raytheon.uf.common.dataplugin.satellite.SatMapCoverage;
import com.raytheon.uf.common.dataplugin.satellite.SatelliteRecord;
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
import com.raytheon.uf.common.dataquery.requests.RequestConstraint.ConstraintType;
@ -246,16 +247,15 @@ public class SatelliteDataCubeAdapter extends DefaultDataCubeAdapter {
* used in derived parameter
*/
GridGeometry2D geo = null;
if (!records.get(0).getSpatialObject().getNx()
.equals(records.get(1).getSpatialObject().getNx())
|| !records.get(0).getSpatialObject().getNy()
.equals(records.get(1).getSpatialObject().getNy())) {
if (!records.get(0).getCoverage().getNx()
.equals(records.get(1).getCoverage().getNx())
|| !records.get(0).getCoverage().getNy()
.equals(records.get(1).getCoverage().getNy())) {
interpolate = true;
geo = MapUtil.getGridGeometry(records.get(largestRecIdx)
.getSpatialObject());
targetWidth = records.get(largestRecIdx).getSpatialObject().getNx();
targetHeight = records.get(largestRecIdx).getSpatialObject()
.getNy();
SatMapCoverage coverage = records.get(largestRecIdx).getCoverage();
geo = coverage.getGridGeometry();
targetWidth = coverage.getNx();
targetHeight = coverage.getNy();
}
try {

View file

@ -38,11 +38,12 @@ import com.raytheon.uf.common.colormap.prefs.ColorMapParameters;
import com.raytheon.uf.common.colormap.prefs.ColorMapParameters.PersistedParameters;
import com.raytheon.uf.common.colormap.prefs.DataMappingPreferences;
import com.raytheon.uf.common.dataplugin.PluginDataObject;
import com.raytheon.uf.common.dataplugin.satellite.SatMapCoverage;
import com.raytheon.uf.common.dataplugin.satellite.SatelliteRecord;
import com.raytheon.uf.common.dataplugin.satellite.units.SatelliteUnits;
import com.raytheon.uf.common.dataplugin.satellite.units.generic.GenericPixel;
import com.raytheon.uf.common.dataplugin.satellite.units.water.BlendedTPWPixel;
import com.raytheon.uf.common.geospatial.ISpatialObject;
import com.raytheon.uf.common.geospatial.IGridGeometryProvider;
import com.raytheon.uf.common.geospatial.ReferencedCoordinate;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
@ -133,7 +134,7 @@ public class SatResource extends
private class SatRenderable implements IRenderable {
private Map<ISpatialObject, SatTileSetRenderable> tileMap = new HashMap<ISpatialObject, SatTileSetRenderable>();
private Map<SatMapCoverage, SatTileSetRenderable> tileMap = new HashMap<SatMapCoverage, SatTileSetRenderable>();
private DataTime renderableTime;
@ -167,8 +168,8 @@ public class SatResource extends
public void addRecord(SatelliteRecord record) {
synchronized (tileMap) {
SatTileSetRenderable tileSet = tileMap.get(record
.getSpatialObject());
SatTileSetRenderable tileSet = tileMap
.get(record.getCoverage());
if (tileSet != null) {
SatelliteRecord existingRecord = tileSet
.getSatelliteRecord();
@ -192,7 +193,7 @@ public class SatResource extends
if (tileSet == null) {
tileSet = new SatTileSetRenderable(SatResource.this, record);
tileSet.project(descriptor.getGridGeometry());
tileMap.put(record.getSpatialObject(), tileSet);
tileMap.put(record.getCoverage(), tileSet);
}
}
}
@ -394,8 +395,8 @@ public class SatResource extends
.asLatLon());
if (result != null) {
dataValue = result.getValue();
dataMap.put(ISpatialObject.class.toString(), result
.getRecord().getSpatialObject());
dataMap.put(IGridGeometryProvider.class.toString(), result
.getRecord().getCoverage());
}
} catch (Exception e) {
throw new VizException("Error interrogating raw data", e);

View file

@ -58,7 +58,7 @@ public class SatTileSetRenderable extends RecordTileSetRenderable {
public SatTileSetRenderable(AbstractVizResource<?, ?> resource,
SatelliteRecord record) {
// Total levels = Number of interpolation levels + base level
super(resource, record, record.getSpatialObject(), record
super(resource, record, record.getGridGeometry(), record
.getInterpolationLevels() + 1);
this.resource = resource;
}
@ -68,8 +68,6 @@ public class SatTileSetRenderable extends RecordTileSetRenderable {
return new SatDataRetriever((SatelliteRecord) record, tile.tileLevel,
tile.getRectangle()).getColorMapData();
}
@Override
protected void issueRefresh(IGraphicsTarget target) {

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>com.raytheon.uf.edex.upgrade.satellitespatial</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View file

@ -0,0 +1,7 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.6

View file

@ -0,0 +1,10 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Satellite Spatial Upgrade
Bundle-SymbolicName: com.raytheon.uf.edex.upgrade.satellitespatial
Bundle-Version: 1.0.0.qualifier
Bundle-Vendor: RAYTHEON
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Require-Bundle: org.postgres;bundle-version="9.2.0",
com.raytheon.uf.common.geospatial;bundle-version="1.12.1174",
com.raytheon.uf.common.serialization;bundle-version="1.12.1174"

View file

@ -0,0 +1,4 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.

View file

@ -0,0 +1,262 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.edex.upgrade.satellitespatial;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import org.geotools.coverage.grid.GridEnvelope2D;
import org.geotools.coverage.grid.GridGeometry2D;
import org.geotools.geometry.Envelope2D;
import org.geotools.referencing.CRS;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import com.raytheon.uf.common.geospatial.ISpatialObject;
import com.raytheon.uf.common.geospatial.MapUtil;
import com.raytheon.uf.common.geospatial.util.EnvelopeIntersection;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.io.WKBReader;
/**
* Java application to update the satellite spatial table. Converts old spatial
* format into new format using crs space
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Sep 30, 2013 2333 mschenke Initial creation
*
* </pre>
*
* @author mschenke
* @version 1.0
*/
public class UpdateSatSpatial {
private static final String SATELLITE_SPATIAL_TABLE = "satellite_spatial";
private static final String SATELLITE_SPATIAL_GID = "gid";
private static final String SATELLITE_SPATIAL_CRSWKT = "crswkt";
private static final String SATELLITE_SPATIAL_GEOM = "the_geom";
private static final String SATELLITE_SPATIAL_NX = "nx";
private static final String SATELLITE_SPATIAL_NY = "ny";
private static final String SATELLITE_SPATIAL_DX = "dx";
private static final String SATELLITE_SPATIAL_DY = "dy";
private static final String SATELLITE_SPATIAL_MINX = "minx";
private static final String SATELLITE_SPATIAL_MINY = "miny";
private static final String HOST_ARGUMENT = "-host";
private static final String DEFAULT_HOST = "localhost";
private static final String PORT_ARGUMENT = "-port";
private static final String DEFAULT_PORT = "5432";
private static final String USER_ARGUMENT = "-user";
private static final String DEFAULT_USER = "awips";
private static final String PASSWORD_ARGUMENT = "-password";
private static final String DEFAULT_PASSWORD = "awips";
private static final String DATABASE_ARGUMENT = "-database";
private static final String DEFAULT_DATABASE = "metadata";
private static final String JDBC_CONNECTION_FORMAT_STRING = "jdbc:postgresql://%s:%s/%s";
private static final String USER_PROPERTY = "user";
private static final String PASSWORD_PROPERTY = "password";
private static Map<String, Object> argumentMap = new HashMap<String, Object>();
private static class SpatialObject implements ISpatialObject {
private static final long serialVersionUID = 1L;
private final int nx;
private final int ny;
private final Geometry geometry;
private final CoordinateReferenceSystem crs;
public SpatialObject(int nx, int ny, Geometry geometry,
CoordinateReferenceSystem crs) {
this.nx = nx;
this.ny = ny;
this.geometry = geometry;
this.crs = crs;
}
@Override
public Geometry getGeometry() {
return geometry;
}
@Override
public CoordinateReferenceSystem getCrs() {
return crs;
}
@Override
public Integer getNx() {
return nx;
}
@Override
public Integer getNy() {
return ny;
}
}
public static void main(String[] args) throws Exception {
// Parse arguments
parseArguments(args);
Connection conn = openConnection();
Statement query = conn.createStatement();
ResultSet results = query.executeQuery("SELECT "
+ SATELLITE_SPATIAL_GID + ", " + SATELLITE_SPATIAL_CRSWKT
+ ", " + SATELLITE_SPATIAL_NX + ", " + SATELLITE_SPATIAL_NY
+ ", " + SATELLITE_SPATIAL_DX + ", " + SATELLITE_SPATIAL_DY
+ ", AsBinary(" + SATELLITE_SPATIAL_GEOM + ") as "
+ SATELLITE_SPATIAL_GEOM + " FROM " + SATELLITE_SPATIAL_TABLE);
String updateStatement = "UPDATE " + SATELLITE_SPATIAL_TABLE + " SET ("
+ SATELLITE_SPATIAL_MINX + ", " + SATELLITE_SPATIAL_MINY + ", "
+ SATELLITE_SPATIAL_DX + ", " + SATELLITE_SPATIAL_DY + ", "
+ SATELLITE_SPATIAL_GEOM
+ ") = (?, ?, ?, ?, GeomFromText(? , -1)) WHERE "
+ SATELLITE_SPATIAL_GID + " = ?";
while (results.next()) {
int gid = results.getInt(SATELLITE_SPATIAL_GID);
Geometry geometry = new WKBReader().read(results
.getBytes(SATELLITE_SPATIAL_GEOM));
CoordinateReferenceSystem crs = CRS.parseWKT(results
.getString(SATELLITE_SPATIAL_CRSWKT));
int nx = results.getInt(SATELLITE_SPATIAL_NX);
int ny = results.getInt(SATELLITE_SPATIAL_NY);
double dx = results.getDouble(SATELLITE_SPATIAL_DX);
double dy = results.getDouble(SATELLITE_SPATIAL_DY);
ISpatialObject object = new SpatialObject(nx, ny, geometry, crs);
GridGeometry2D resultGeom = MapUtil.getGridGeometry(object);
Envelope2D env = resultGeom.getEnvelope2D();
GridEnvelope2D grid = resultGeom.getGridRange2D();
double minX = env.getMinX();
double minY = env.getMinY();
if (dx == 0.0) {
dx = env.getWidth() / grid.width;
}
if (dy == 0.0) {
dy = env.getHeight() / grid.height;
}
Geometry newGeom = EnvelopeIntersection.createEnvelopeIntersection(
resultGeom.getEnvelope(),
new Envelope2D(DefaultGeographicCRS.WGS84, -180, -90, 360,
180), 1.0, 10, 10).getEnvelope();
PreparedStatement update = conn.prepareStatement(updateStatement);
int index = 1;
update.setDouble(index++, minX);
update.setDouble(index++, minY);
update.setDouble(index++, dx);
update.setDouble(index++, dy);
update.setString(index++, newGeom.toText());
update.setInt(index++, gid);
update.execute();
}
conn.close();
}
private static Connection openConnection() throws SQLException {
String host = getString(HOST_ARGUMENT, DEFAULT_HOST);
String port = getString(PORT_ARGUMENT, DEFAULT_PORT);
String database = getString(DATABASE_ARGUMENT, DEFAULT_DATABASE);
String user = getString(USER_ARGUMENT, DEFAULT_USER);
String password = getString(PASSWORD_ARGUMENT, DEFAULT_PASSWORD);
DriverManager.registerDriver(new org.postgresql.Driver());
String connectionURL = String.format(JDBC_CONNECTION_FORMAT_STRING,
host, port, database);
Properties props = new Properties();
props.setProperty(USER_PROPERTY, user);
props.setProperty(PASSWORD_PROPERTY, password);
return DriverManager.getConnection(connectionURL, props);
}
private static void parseArguments(String[] args) {
for (int i = 0; i < args.length; ++i) {
String arg = args[i];
if (arg.startsWith("-")) {
// we have a key
if (args.length > (i + 1)
&& args[i + 1].startsWith("-") == false) {
argumentMap.put(arg, args[i + 1]);
++i;
} else {
argumentMap.put(arg, true);
}
}
}
}
private static String getString(String key, String defaultValue) {
Object val = argumentMap.get(key);
if (val != null) {
return val.toString();
}
return defaultValue;
}
}

View file

@ -0,0 +1,16 @@
#!/bin/bash
# This script is needed for DR 2333 for GOES-R readiness. The satellite spatial table needed to be refactored to store data to construct
# GridGeometry2D in CRS space instead of lat/lon due to the geostationary projection corner points not being valid in lat/lon space.
DIR=`dirname $0`
PSQL="/awips2/psql/bin/psql"
JAVA="/awips2/java/bin/java"
# Update columns on tables for satellite
${PSQL} -U awips -d metadata -c "ALTER TABLE satellite DROP COLUMN upperrightlat, DROP COLUMN upperrightlon;"
${PSQL} -U awips -d metadata -c "ALTER TABLE satellite_spatial DROP COLUMN la1, DROP COLUMN la2, DROP COLUMN latin, DROP COLUMN lo1, DROP COLUMN lo2, DROP COLUMN lov;"
${PSQL} -U awips -d metadata -c "ALTER TABLE satellite_spatial ADD COLUMN minx double precision, ADD COLUMN miny double precision;"
# Run application to convert sat spatial entries to use crs space
${JAVA} -jar update_satellite_spatial.jar

View file

@ -238,7 +238,7 @@ public class D2DSatParm {
physicalElement, timeRanges);
for (int i = 0; i < satRecords.size(); i++) {
GridLocation satGridLoc = new GridLocation(this.pid.toString(),
satRecords.get(i).getCoverage());
satRecords.get(i));
ByteDataRecord hdf5Record = (ByteDataRecord) satRecords.get(i)
.getMessageData();
Grid2DByte rawData = new Grid2DByte(

View file

@ -22,9 +22,6 @@ Require-Bundle: com.raytheon.uf.common.dataplugin;bundle-version="1.12.1174",
com.raytheon.uf.common.awipstools;bundle-version="1.12.1174",
com.raytheon.uf.edex.core;bundle-version="1.12.1174",
com.raytheon.uf.edex.database;bundle-version="1.0.0",
com.raytheon.uf.edex.menus;bundle-version="1.0.0",
org.springframework;bundle-version="3.1.4",
javax.persistence;bundle-version="1.0.0",
org.hibernate;bundle-version="1.0.0"
com.raytheon.uf.edex.menus;bundle-version="1.0.0"
Import-Package: com.raytheon.edex.exception,
org.apache.commons.logging

View file

@ -345,21 +345,11 @@ public class SatelliteDecoder {
// get the scanning mode
scanMode = byteBuffer.get(37);
// Get latitude of upper right hand corner
byteBuffer.position(55);
byteBuffer.get(threeBytesArray, 0, 3);
record.setUpperRightLat(transformLatitude(threeBytesArray));
// Get longitude of upper right hand corner
byteBuffer.position(58);
byteBuffer.get(threeBytesArray, 0, 3);
record.setUpperRightLon(transformLongitude(threeBytesArray));
float dx = 0.0f, dy = 0.0f, lov = 0.0f, lo2 = 0.0f, la2 = 0.0f;
// Do specialized decoding and retrieve spatial data for Lambert
// Conformal and Polar Stereographic projections
if ((mapProjection == SatMapCoverage.PROJ_LAMBERT)
|| (mapProjection == SatMapCoverage.PROJ_POLAR_STEREO)) {
if ((mapProjection == SatSpatialFactory.PROJ_LAMBERT)
|| (mapProjection == SatSpatialFactory.PROJ_POLAR)) {
byteBuffer.position(30);
byteBuffer.get(threeBytesArray, 0, 3);
dx = byteArrayToFloat(threeBytesArray) / 10;
@ -372,11 +362,9 @@ public class SatelliteDecoder {
byteBuffer.get(threeBytesArray, 0, 3);
lov = transformLongitude(threeBytesArray);
}
// Do specialized decoding and retrieve spatial data for
// Mercator
// projection
else if (mapProjection == SatMapCoverage.PROJ_MERCATOR) {
// Mercator projection
else if (mapProjection == SatSpatialFactory.PROJ_MERCATOR) {
dx = byteBuffer.getShort(33);
dy = byteBuffer.getShort(35);
@ -400,7 +388,7 @@ public class SatelliteDecoder {
* This is a temporary workaround for DR14724, hopefully to
* be removed after NESDIS changes the product header
*/
if ((mapProjection == SatMapCoverage.PROJ_LAMBERT)
if ((mapProjection == SatSpatialFactory.PROJ_LAMBERT)
&& (record.getPhysicalElement()
.equalsIgnoreCase("Imager 13 micron (IR)"))
&& (record.getSectorID()

View file

@ -27,7 +27,6 @@ import com.raytheon.uf.common.dataplugin.satellite.SatMapCoverage;
import com.raytheon.uf.edex.database.DataAccessLayerException;
import com.raytheon.uf.edex.database.dao.CoreDao;
import com.raytheon.uf.edex.database.dao.DaoConfig;
import com.raytheon.uf.edex.database.query.DatabaseQuery;
/**
* The dao implementation associated with the SatelliteMapCoverage class used
@ -41,8 +40,9 @@ import com.raytheon.uf.edex.database.query.DatabaseQuery;
* ------------ ---------- ----------- --------------------------
* 7/24/07 353 bphillip Initial Check in
* - AWIPS2 Baseline Repository --------
* 06/27/2012 798 jkorman Corrected id query type.
*
* 06/27/2012 798 jkorman Corrected id query type.
* 10/02/2013 2333 mschenke Removed unused code
*
* </pre>
*
* @author bphillip
@ -105,81 +105,4 @@ public class SatMapCoverageDao extends CoreDao {
return (List<SatMapCoverage>) queryByCriteria(fields, values);
}
/**
* Retrieves a map projection based on the given criteria
*
* @param mapProjection
* The map projection 1=Mercator 3=Lambert Conformal 5=Polar
* Stereographic
* @param nx
* Number of points along the x-axis
* @param ny
* Number of points along the y-axis
* @param dx
* The horizontal resolution of the grid
* @param dy
* The vertical resolution of the grid
* @param lov
* The orientation of the grid
* @param latin
* The tangent latitude
* @param la1
* The latitude of the first grid point
* @param lo1
* The longitude of the first grid point
* @param la2
* The latitude of the last grid point (only used with Mercator
* projection)
* @param lo2
* The longitude of the last grid opint (only used with Mercaotr
* projection)
* @return The SatMapCoverage object matching the given criteria
*/
@SuppressWarnings("unchecked")
public SatMapCoverage getSatCoverage(Integer mapProjection, Integer nx,
Integer ny, Float dx, Float dy, Float lov, Float latin, Float la1,
Float lo1, Float la2, Float lo2) throws DataAccessLayerException{
List<SatMapCoverage> queryResults = null;
List<String> fields = new ArrayList<String>();
List<Object> values = new ArrayList<Object>();
DatabaseQuery query = new DatabaseQuery(daoClass.getName());
query.addQueryParam("projection", mapProjection);
query.addQueryParam("nx",nx);
query.addQueryParam("ny",ny);
query.addQueryParam("dx",dx);
query.addQueryParam("dy",dy);
query.addQueryParam("lov",lov);
query.addQueryParam("latin",latin);
query.addQueryParam("la1",la1);
query.addQueryParam("lo1",lo1);
if (mapProjection == SatMapCoverage.PROJ_MERCATOR) {
query.addQueryParam("la2",la2);
query.addQueryParam("lo2",lo2);
}
queryResults = (List<SatMapCoverage>) queryByCriteria(query);
if (queryResults != null) {
if (queryResults.size() > 1) {
StringBuffer out = new StringBuffer();
out
.append("Multiple map coverages return using the following criteria: [");
for (int i = 0; i < fields.size(); i++) {
out.append(fields.get(i)).append("=").append(values.get(i))
.append(" ");
}
out.append("] -- Using first result");
logger.debug(out.toString());
}
if (queryResults.size() >= 1) {
return queryResults.get(0);
} else {
return null;
}
} else {
return null;
}
}
}

View file

@ -46,7 +46,6 @@ import com.raytheon.uf.common.datastorage.StorageProperties;
import com.raytheon.uf.common.datastorage.records.ByteDataRecord;
import com.raytheon.uf.common.datastorage.records.IDataRecord;
import com.raytheon.uf.common.datastorage.records.ShortDataRecord;
import com.raytheon.uf.common.geospatial.MapUtil;
import com.raytheon.uf.common.geospatial.interpolation.GridDownscaler;
import com.raytheon.uf.common.geospatial.interpolation.data.AbstractDataWrapper;
import com.raytheon.uf.common.geospatial.interpolation.data.ByteArrayWrapper;
@ -152,7 +151,7 @@ public class SatelliteDao extends PluginDao {
coverage.getNx(), coverage.getNy());
dataSource.setFillValue(fillValue);
GridDownscaler downScaler = new GridDownscaler(
MapUtil.getGridGeometry(coverage));
coverage.getGridGeometry());
// How many interpolation levels do we need for this data?
int levels = downScaler.getNumberOfDownscaleLevels();

View file

@ -23,6 +23,7 @@ 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.jts.JTS;
import org.opengis.referencing.crs.ProjectedCRS;
import org.opengis.referencing.operation.MathTransform;
@ -30,8 +31,10 @@ import com.raytheon.edex.plugin.satellite.dao.SatMapCoverageDao;
import com.raytheon.uf.common.dataplugin.satellite.SatMapCoverage;
import com.raytheon.uf.common.geospatial.MapUtil;
import com.raytheon.uf.edex.database.DataAccessLayerException;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.io.WKTReader;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.Polygon;
/**
*
@ -43,18 +46,34 @@ import com.vividsolutions.jts.io.WKTReader;
* ------------ ---------- ----------- --------------------------
* 12/19/07 439 bphillip Initial creation
* - AWIPS2 Baseline Repository --------
* 07/12/2012 798 jkorman Changed projection "magic" numbers
*
* 07/12/2012 798 jkorman Changed projection "magic" numbers
* 09/30/2013 2333 mschenke Refactored to store points in crs space
* </pre>
*/
public class SatSpatialFactory {
// TODO: These constants should be in the GINI decoder since they are only
// related to the GINI format and should not be stored in SatMapCoverage.
// Can't do this now as ncep has code that checks projection number to
// determine how code should flow.
public static final int PROJ_MERCATOR = 1;
public static final int PROJ_LAMBERT = 3;
public static final int PROJ_POLAR = 5;
public static final int PROJ_CYLIN_EQUIDISTANT = 7;
public static final int UNDEFINED = -1;
/** The logger */
private Log logger = LogFactory.getLog(getClass());
/** The singleton instance */
private static SatSpatialFactory instance;
private SatMapCoverageDao satDao = new SatMapCoverageDao();
/**
* Gets the singleton instance
*
@ -98,39 +117,24 @@ public class SatSpatialFactory {
* If errors occur during db interaction or creation of the
* coverage object
*/
public synchronized SatMapCoverage getMapCoverage(
Integer mapProjection, Integer nx, Integer ny, Float dx, Float dy,
Float lov, Float latin, Float la1, Float lo1, Float la2, Float lo2)
throws Exception {
SatMapCoverage mapCoverage = null;
SatMapCoverageDao satDao = new SatMapCoverageDao();
public synchronized SatMapCoverage getMapCoverage(Integer mapProjection,
Integer nx, Integer ny, Float dx, Float dy, Float lov, Float latin,
Float la1, Float lo1, Float la2, Float lo2) throws Exception {
try {
// Check the database to see if a coverage already exists
mapCoverage = satDao.getSatCoverage(mapProjection, nx, ny, dx, dy,
lov, latin, la1, lo1, la2, lo2);
// If the database does not contain an existing sat map coverage for
// the given values, create one
if (mapCoverage == null) {
mapCoverage = createMapCoverage(mapProjection, nx, ny, dx, dy,
lov, latin, la1, lo1, la2, lo2);
// Persist the new coverage to the database
satDao.persist(mapCoverage);
SatMapCoverage mapCoverage = createMapCoverage(mapProjection, nx,
ny, dx, dy, lov, latin, la1, lo1, la2, lo2);
SatMapCoverage persisted = satDao
.queryByMapId(mapCoverage.getGid());
if (persisted == null) {
persisted = mapCoverage;
satDao.persist(persisted);
}
return persisted;
} catch (Exception e) {
throw new DataAccessLayerException(
"Unable to retrieve or construct valid Satellite Map Coverage",
e);
}
if (mapCoverage == null) {
throw new DataAccessLayerException(
"Unable to retrieve or construct valid Satellite Map Coverage");
}
return mapCoverage;
}
/**
@ -173,16 +177,20 @@ public class SatSpatialFactory {
ProjectedCRS crs = null;
// Get the correct CRS
if (mapProjection == SatMapCoverage.PROJ_MERCATOR) {
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,
MapUtil.AWIPS_EARTH_RADIUS, latin, cm);
} else if (mapProjection == 3) {
} else if (mapProjection == PROJ_LAMBERT) {
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);
@ -201,7 +209,7 @@ public class SatSpatialFactory {
* Projection is Mercator. Determine corner points from la1,lo1,la2,lo2
* provided in the satellite file
*/
if (mapProjection == SatMapCoverage.PROJ_MERCATOR) {
if (mapProjection == PROJ_MERCATOR) {
logger.debug("Determining corner points for Mercator projection");
corner1.x = lo1;
corner1.y = la1;
@ -214,15 +222,13 @@ public class SatSpatialFactory {
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");
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
@ -235,12 +241,12 @@ public class SatSpatialFactory {
// Determine the 3 other corner points using the given dx,dy,nx, and
// ny in meters
secondPosition = new DirectPosition2D(dx * nx + firstPosition.x,
secondPosition = new DirectPosition2D(firstPosition.x + (dx * nx),
firstPosition.y);
thirdPosition = new DirectPosition2D(dx * nx + firstPosition.x, dy
* ny + firstPosition.y);
fourthPosition = new DirectPosition2D(firstPosition.x, dx * ny
+ 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);
@ -249,23 +255,31 @@ public class SatSpatialFactory {
toLatLon.transform(fourthPosition, corner4);
}
// Construct the polygon constructor String
StringBuffer buffer = new StringBuffer();
buffer.append("POLYGON((");
buffer.append(corner1.x + " " + corner1.y + ",");
buffer.append(corner2.x + " " + corner2.y + ",");
buffer.append(corner3.x + " " + corner3.y + ",");
buffer.append(corner4.x + " " + corner4.y + ",");
buffer.append(corner1.x + " " + corner1.y);
buffer.append("))");
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]);
// Create the geometry from the constructed String
Geometry geometry = new WKTReader().read(buffer.toString());
// 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);
SatMapCoverage mapCoverage = new SatMapCoverage(mapProjection,
nx, ny, dx, dy, lov, latin, la1, lo1, la2, lo2, crs, geometry);
return mapCoverage;
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

@ -46,7 +46,9 @@ import jep.INumpyable;
import org.geotools.coverage.grid.GeneralGridEnvelope;
import org.geotools.coverage.grid.GridGeometry2D;
import org.geotools.geometry.Envelope2D;
import org.geotools.geometry.GeneralEnvelope;
import org.geotools.geometry.jts.JTS;
import org.geotools.referencing.GeodeticCalculator;
import org.geotools.referencing.operation.DefaultMathTransformFactory;
import org.geotools.referencing.operation.builder.GridToEnvelopeMapper;
@ -68,6 +70,7 @@ import com.raytheon.uf.common.dataplugin.gfe.reference.ReferenceData.CoordinateT
import com.raytheon.uf.common.dataplugin.gfe.reference.ReferenceID;
import com.raytheon.uf.common.dataplugin.persist.PersistableDataObject;
import com.raytheon.uf.common.geospatial.CRSCache;
import com.raytheon.uf.common.geospatial.IGridGeometryProvider;
import com.raytheon.uf.common.geospatial.ISpatialObject;
import com.raytheon.uf.common.geospatial.MapUtil;
import com.raytheon.uf.common.serialization.ISerializableObject;
@ -102,6 +105,7 @@ import com.vividsolutions.jts.simplify.TopologyPreservingSimplifier;
* spatial
* 08/06/13 #1571 randerso Added hibernate annotations, javadoc cleanup,
* made init method public for use in GFEDao
* 09/30/13 #2333 mschenke Added method to construct from {@link IGridGeometryProvider}
*
*
* </pre>
@ -372,6 +376,36 @@ public class GridLocation extends PersistableDataObject<String> implements
this.ny = coverage.getNy();
}
/**
* @param id
* @param provider
*/
public GridLocation(String id, IGridGeometryProvider provider) {
this.siteId = id;
GridGeometry2D gridGeometry = provider.getGridGeometry();
this.crsObject = gridGeometry.getCoordinateReferenceSystem();
this.crsWKT = this.crsObject.toWKT();
this.nx = gridGeometry.getGridRange().getSpan(0);
this.ny = gridGeometry.getGridRange().getSpan(1);
Envelope2D envelope = gridGeometry.getEnvelope2D();
Coordinate ul = new Coordinate(envelope.getMinX(), envelope.getMinY());
Coordinate ur = new Coordinate(envelope.getMaxX(), envelope.getMinY());
Coordinate lr = new Coordinate(envelope.getMaxX(), envelope.getMaxY());
Coordinate ll = new Coordinate(envelope.getMinX(), envelope.getMaxY());
GeometryFactory gf = new GeometryFactory();
Geometry crsPolygon = gf.createPolygon(
gf.createLinearRing(new Coordinate[] { ul, ur, lr, ll, ul }),
null);
try {
MathTransform crsToLL = MapUtil.getTransformToLatLon(crsObject);
this.geometry = (Polygon) JTS.transform(crsPolygon, crsToLL);
} catch (Exception e) {
throw new IllegalArgumentException(
"GridGeometry provided does not support conversion to lat/lon");
}
}
/**
* @param id
* @param gloc

View file

@ -33,14 +33,14 @@ import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import org.geotools.coverage.grid.GridGeometry2D;
import org.hibernate.annotations.Index;
import com.raytheon.uf.common.dataplugin.IDecoderGettable;
import com.raytheon.uf.common.dataplugin.PluginDataObject;
import com.raytheon.uf.common.dataplugin.annotations.DataURI;
import com.raytheon.uf.common.dataplugin.persist.PersistablePluginDataObject;
import com.raytheon.uf.common.geospatial.ISpatialEnabled;
import com.raytheon.uf.common.geospatial.ISpatialObject;
import com.raytheon.uf.common.geospatial.IGridGeometryProvider;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
@ -77,7 +77,7 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
"refTime", "forecastTime" }) })
@DynamicSerialize
public class VIIRSDataRecord extends PersistablePluginDataObject implements
ISpatialEnabled {
IGridGeometryProvider {
public static final String MISSING_VALUE_ID = "missing_value";
@ -130,11 +130,12 @@ public class VIIRSDataRecord extends PersistablePluginDataObject implements
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.common.geospatial.ISpatialEnabled#getSpatialObject()
* @see
* com.raytheon.uf.common.geospatial.IGridGeometryProvider#getGridGeometry()
*/
@Override
public ISpatialObject getSpatialObject() {
return coverage;
public GridGeometry2D getGridGeometry() {
return coverage != null ? coverage.getGridGeometry() : null;
}
/**

View file

@ -31,13 +31,13 @@ import javax.persistence.Transient;
import org.geotools.coverage.grid.GeneralGridEnvelope;
import org.geotools.coverage.grid.GridGeometry2D;
import org.geotools.geometry.GeneralEnvelope;
import org.hibernate.annotations.Index;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.hibernate.annotations.Index;
import com.raytheon.uf.common.dataplugin.npp.viirs.projection.VIIRSMapProjectionFactory;
import com.raytheon.uf.common.dataplugin.persist.PersistableDataObject;
import com.raytheon.uf.common.geospatial.ISpatialObject;
import com.raytheon.uf.common.geospatial.IGridGeometryProvider;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
import com.raytheon.uf.common.time.DataTime;
@ -67,15 +67,11 @@ import com.vividsolutions.jts.geom.Geometry;
* Both refTime and forecastTime are included in the refTimeIndex since
* forecastTime is unlikely to be used.
*/
@org.hibernate.annotations.Table(
appliesTo = "viirs_spatial",
indexes = {
@Index(name = "viirs_spatial_refTimeIndex", columnNames = { "refTime", "forecastTime" } )
}
)
@org.hibernate.annotations.Table(appliesTo = "viirs_spatial", indexes = { @Index(name = "viirs_spatial_refTimeIndex", columnNames = {
"refTime", "forecastTime" }) })
@DynamicSerialize
public class VIIRSSpatialCoverage extends PersistableDataObject implements
ISpatialObject {
IGridGeometryProvider {
private static final long serialVersionUID = -2532225158997059309L;
@ -127,22 +123,6 @@ public class VIIRSSpatialCoverage extends PersistableDataObject implements
@DynamicSerializeElement
private Geometry envelope;
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.common.geospatial.ISpatialObject#getGeometry()
*/
@Override
public Geometry getGeometry() {
return envelope;
}
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.common.geospatial.ISpatialObject#getCrs()
*/
@Override
public CoordinateReferenceSystem getCrs() {
if (crs == null) {
try {
@ -210,22 +190,16 @@ public class VIIRSSpatialCoverage extends PersistableDataObject implements
this.directions = directions;
}
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.common.geospatial.ISpatialObject#getNx()
/**
* @return the nx
*/
@Override
public Integer getNx() {
return nx;
}
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.common.geospatial.ISpatialObject#getNy()
/**
* @return the ny
*/
@Override
public Integer getNy() {
return ny;
}

View file

@ -4,7 +4,7 @@ Bundle-Name: Satellite Common
Bundle-SymbolicName: com.raytheon.uf.common.dataplugin.satellite
Bundle-Version: 1.0.0.qualifier
Bundle-Vendor: RAYTHEON
Eclipse-RegisterBuddy: com.raytheon.uf.common.serialization, com.raytheon.uf.viz.core
Eclipse-RegisterBuddy: com.raytheon.uf.common.serialization
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Require-Bundle: com.raytheon.uf.common.dataplugin;bundle-version="1.12.1174",
com.raytheon.uf.common.serialization;bundle-version="1.12.1174",

View file

@ -20,8 +20,9 @@
package com.raytheon.uf.common.dataplugin.satellite;
import java.awt.geom.Rectangle2D;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@ -32,18 +33,26 @@ import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.geotools.coverage.grid.GridEnvelope2D;
import org.geotools.coverage.grid.GridGeometry2D;
import org.geotools.geometry.Envelope2D;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.hibernate.annotations.Type;
import org.opengis.coverage.grid.GridEnvelope;
import org.opengis.geometry.Envelope;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import com.raytheon.uf.common.dataplugin.annotations.DataURI;
import com.raytheon.uf.common.dataplugin.persist.PersistableDataObject;
import com.raytheon.uf.common.geospatial.CRSCache;
import com.raytheon.uf.common.geospatial.ISpatialObject;
import com.raytheon.uf.common.geospatial.IGridGeometryProvider;
import com.raytheon.uf.common.geospatial.util.EnvelopeIntersection;
import com.raytheon.uf.common.serialization.adapters.GeometryAdapter;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.Polygon;
/**
@ -62,6 +71,7 @@ import com.vividsolutions.jts.geom.Polygon;
* Jul 12, 2012 798 jkorman Changed projection "magic" numbers
* Jul 16, 2013 2181 bsteffen Convert geometry types to use hibernate-
* spatial
* Sep 30, 2013 2333 mschenke Refactored to store coordinates in CRS space
*
* </pre>
*/
@ -69,321 +79,349 @@ import com.vividsolutions.jts.geom.Polygon;
@Table(name = "satellite_spatial")
@XmlAccessorType(XmlAccessType.NONE)
@DynamicSerialize
@Embeddable
public class SatMapCoverage extends PersistableDataObject implements
ISpatialObject {
public class SatMapCoverage extends PersistableDataObject<Object> implements
IGridGeometryProvider {
private static final long serialVersionUID = 1L;
private static final long serialVersionUID = 1L;
public static final int PROJ_MERCATOR = 1;
public static final int PROJ_LAMBERT = 3;
public static final int PROJ_POLAR_STEREO = 5;
public static final int PROJ_CYLIN_EQUIDISTANT = 7;
@Id
@DynamicSerializeElement
@Id
@DynamicSerializeElement
@DataURI(position = 0)
private int gid;
private int gid;
/**
* The projection of the map coverage 1=Mercator, 3=Lambert Conformal
* 5=Polar Stereographic
*/
@Column
@XmlAttribute
@DynamicSerializeElement
private Integer projection;
/**
* The projection of the map coverage 1=Mercator, 3=Lambert Conformal
* 5=Polar Stereographic
*
* @deprecated This field is only useful for GINI satellite format decoding
* and should not be in the coverage object
*/
@Column
@XmlAttribute
@DynamicSerializeElement
@Deprecated
private Integer projection;
/** Number of points along the x-axis */
@XmlAttribute
@DynamicSerializeElement
@Column
protected Integer nx;
/** Minimum x coordinate in crs space */
@XmlAttribute
@DynamicSerializeElement
@Column
private double minX;
/** Number of points along the y-axis */
@XmlAttribute
@DynamicSerializeElement
@Column
protected Integer ny;
/** Minimum y coordinate in crs space */
@XmlAttribute
@DynamicSerializeElement
@Column
private double minY;
/** The horizontal resolution of the grid */
@Column
@XmlAttribute
@DynamicSerializeElement
private Float dx;
/** Number of points along the x-axis */
@XmlAttribute
@DynamicSerializeElement
@Column
private Integer nx;
/** The vertical resolution of the grid */
@Column
@XmlAttribute
@DynamicSerializeElement
private Float dy;
/** Number of points along the y-axis */
@XmlAttribute
@DynamicSerializeElement
@Column
private Integer ny;
/**
* The orientation of the grid; i.e, the east longitude value of the
* meridian which is parallel to the y-axis (or columns of the grid) along
* which latitude increases as the y-coordinate increases (Note: the
* orientation longitude may or may not appear withing a particular grid.)
*/
@Column
@XmlAttribute
@DynamicSerializeElement
private Float lov;
/** The horizontal resolution of the grid */
@Column
@XmlAttribute
@DynamicSerializeElement
private double dx;
/**
* The latitude at which the Lambert projection cone is tangent to the
* earth. Polar Stereographic this value is set to 0. For Mercator this is
* The latitude at which the Mercator projection cylinder intersects the
* earth.
*/
@Column
@XmlAttribute
@DynamicSerializeElement
private Float latin;
/** The vertical resolution of the grid */
@Column
@XmlAttribute
@DynamicSerializeElement
private double dy;
/** The latitude of the first grid point */
@Column
@XmlAttribute
@DynamicSerializeElement
private Float la1;
@Column(length = 2047)
@XmlAttribute
@DynamicSerializeElement
private String crsWKT;
/** The longitude of the first grid point */
@Column
@XmlAttribute
@DynamicSerializeElement
private Float lo1;
@Transient
private CoordinateReferenceSystem crsObject;
/** The latitude of the last grid point (only used with Mercator projection) */
@Column
@XmlAttribute
@DynamicSerializeElement
private Float la2;
/**
* The longitude of the last grid point (only used with Mercator projection)
*/
@Column
@XmlAttribute
@DynamicSerializeElement
private Float lo2;
@Column(length = 2047)
@XmlAttribute
@DynamicSerializeElement
private String crsWKT;
@Transient
private CoordinateReferenceSystem crsObject;
/** The map coverage */
/** The map coverage */
@Column(name = "the_geom")
@Type(type = "org.hibernatespatial.GeometryUserType")
@XmlJavaTypeAdapter(value = GeometryAdapter.class)
@DynamicSerializeElement
private Polygon location;
@XmlJavaTypeAdapter(value = GeometryAdapter.class)
@DynamicSerializeElement
private Geometry location;
public SatMapCoverage() {
super();
}
public SatMapCoverage() {
super();
}
/**
* Constructs a new SatMapCoverage Object
*
* @param projection
* @param nx
* The number of horizontal scan lines
* @param ny
* The number vertical scan lines
* @param dx
* The horizontal resolution
* @param dy
* The vertical resolution
* @param lov
* The orientation of the grid
* @param latin
* The tangent latitude
* @param la1
* The latitude of the first grid point
* @param lo1
* The longitude of the first grid point
* @param la2
* The latitude of the last grid point (null for Lambert
* Conformal or Polar Stereographic)
* @param lo2
* The longitude of the last grid point (null for Lambert
* Conformal or Polar Stereographic)
* @param crs
* The coordinate reference system
* @param geometry
* The geometry
*/
public SatMapCoverage(Integer projection, Integer nx, Integer ny, Float dx,
Float dy, Float lov, Float latin, Float la1, Float lo1, Float la2,
Float lo2, CoordinateReferenceSystem crs, Geometry geometry) {
/**
* Constructs a new SatMapCoverage Object
*
* @param projection
* the projection id value
* @param minX
* minimum x value in crs space
* @param minY
* minimum y value in crs space
* @param nx
* number of x points in the satellite grid
* @param ny
* number of y points in the satellite grid
* @param dx
* spacing between grid cells in crs x space
* @param dy
* spacing between grid cells in crs y space
* @param crs
* the satellite data crs
*/
public SatMapCoverage(int projection, double minX, double minY, int nx,
int ny, double dx, double dy, CoordinateReferenceSystem crs) {
this(projection, minX, minY, nx, ny, dx, dy, crs, null);
}
this.projection = projection;
this.nx = nx;
this.ny = ny;
this.dx = dx;
this.dy = dy;
this.lov = lov;
this.latin = latin;
this.la1 = la1;
this.lo1 = lo1;
this.la2 = la2;
this.lo2 = lo2;
this.crsObject = crs;
this.crsWKT = crsObject.toWKT();
this.location = (Polygon) geometry;
gid = this.hashCode();
}
/**
* Constructs a new SatMapCoverage Object
*
* @param projection
* the projection id value
* @param minX
* minimum x value in crs space
* @param minY
* minimum y value in crs space
* @param nx
* number of x points in the satellite grid
* @param ny
* number of y points in the satellite grid
* @param dx
* spacing between grid cells in crs x space
* @param dy
* spacing between grid cells in crs y space
* @param crs
* the satellite data crs
* @param latLonGeometry
* A Geometry representing the satellite bounds in lat/lon space
*/
public SatMapCoverage(int projection, double minX, double minY, int nx,
int ny, double dx, double dy, CoordinateReferenceSystem crs,
Geometry latLonGeometry) {
this.projection = projection;
this.minX = minX;
this.minY = minY;
this.nx = nx;
this.ny = ny;
this.dx = dx;
this.dy = dy;
this.crsObject = crs;
this.gid = hashCode();
if (latLonGeometry == null) {
try {
latLonGeometry = EnvelopeIntersection
.createEnvelopeIntersection(
getGridGeometry().getEnvelope(),
new Envelope2D(DefaultGeographicCRS.WGS84,
-180, -90, 360, 180), 1.0, 10, 10)
.getEnvelope();
} catch (Exception e) {
// Ignore exception, null location
}
}
this.location = latLonGeometry;
}
public int hashCode() {
HashCodeBuilder hashBuilder = new HashCodeBuilder();
hashBuilder.append(projection);
hashBuilder.append(nx);
hashBuilder.append(ny);
hashBuilder.append(dx);
hashBuilder.append(dy);
hashBuilder.append(lov);
hashBuilder.append(latin);
hashBuilder.append(la1);
hashBuilder.append(la2);
hashBuilder.append(lo1);
hashBuilder.append(lo2);
return hashBuilder.toHashCode();
}
/**
* @deprecated This field is only useful for GINI satellite format decoding
* and should not be in the coverage object
* @return
*/
@Deprecated
public Integer getProjection() {
return projection;
}
@Override
public Polygon getGeometry() {
return location;
}
/**
* @deprecated This field is only useful for GINI satellite format decoding
* and should not be in the coverage object
* @param projection
*/
@Deprecated
public void setProjection(Integer projection) {
this.projection = projection;
}
@Override
public CoordinateReferenceSystem getCrs() {
if (crsObject == null) {
try {
crsObject = CRSCache.getInstance()
.getCoordinateReferenceSystem(crsWKT);
} catch (FactoryException e) {
crsObject = null;
}
}
return crsObject;
}
public int getGid() {
return gid;
}
public Float getDx() {
return dx;
}
public void setGid(int gid) {
this.gid = gid;
}
public void setDx(Float dx) {
this.dx = dx;
}
public double getMinX() {
return minX;
}
public Float getDy() {
return dy;
}
public void setMinX(double minX) {
this.minX = minX;
}
public void setDy(Float dy) {
this.dy = dy;
}
public double getMinY() {
return minY;
}
public Float getLov() {
return lov;
}
public void setMinY(double minY) {
this.minY = minY;
}
public void setLov(Float lov) {
this.lov = lov;
}
public Integer getNx() {
return nx;
}
public Float getLatin() {
return latin;
}
public void setNx(Integer nx) {
this.nx = nx;
}
public void setLatin(Float latin) {
this.latin = latin;
}
public Integer getNy() {
return ny;
}
public Float getLa1() {
return la1;
}
public void setNy(Integer ny) {
this.ny = ny;
}
public void setLa1(Float la1) {
this.la1 = la1;
}
public double getDx() {
return dx;
}
public Float getLo1() {
return lo1;
}
public void setDx(double dx) {
this.dx = dx;
}
public void setLo1(Float lo1) {
this.lo1 = lo1;
}
public double getDy() {
return dy;
}
public Float getLa2() {
return la2;
}
public void setDy(double dy) {
this.dy = dy;
}
public void setLa2(Float la2) {
this.la2 = la2;
}
public String getCrsWKT() {
if (crsWKT == null && crsObject != null) {
crsWKT = crsObject.toWKT();
}
return crsWKT;
}
public Float getLo2() {
return lo2;
}
public void setCrsWKT(String crsWKT) {
this.crsWKT = crsWKT;
if (crsObject != null) {
crsObject = null;
}
}
public void setLo2(Float lo2) {
this.lo2 = lo2;
}
public Geometry getLocation() {
if (location == null) {
location = generateLocation();
if (location == null) {
// Default to empty MultiPolygon so various Geometry methods
// still work
location = new GeometryFactory()
.createMultiPolygon(new Polygon[0]);
}
}
return location;
}
public Integer getProjection() {
return projection;
}
public void setLocation(Geometry location) {
this.location = location;
}
public void setProjection(Integer projection) {
this.projection = projection;
}
/**
* Generates the lat/lon bounding geometry for the spatial record
*
* @return lat/lon bounding geometry or null if none could be generated
*/
private Geometry generateLocation() {
try {
return EnvelopeIntersection.createEnvelopeIntersection(
getGridGeometry().getEnvelope(),
new Envelope2D(DefaultGeographicCRS.WGS84, -180, -90, 360,
180), 1.0, 10, 10).getEnvelope();
} catch (Exception e) {
// Ignore exception, null location
}
return null;
}
public int getGid() {
return gid;
}
public CoordinateReferenceSystem getCrs() {
if (crsObject == null && crsWKT != null) {
try {
crsObject = CRSCache.getInstance()
.getCoordinateReferenceSystem(crsWKT);
} catch (FactoryException e) {
crsObject = null;
}
}
return crsObject;
}
public void setGid(int gid) {
this.gid = gid;
}
@Override
public GridGeometry2D getGridGeometry() {
GridEnvelope gridRange = new GridEnvelope2D(0, 0, getNx(), getNy());
Envelope crsRange = new Envelope2D(getCrs(), new Rectangle2D.Double(
minX, minY, getNx() * getDx(), getNy() * getDy()));
return new GridGeometry2D(gridRange, crsRange);
}
public Integer getNx() {
return nx;
}
@Override
public int hashCode() {
HashCodeBuilder builder = new HashCodeBuilder();
builder.append(projection);
builder.append(getCrsWKT());
builder.append(minX);
builder.append(minY);
builder.append(dx);
builder.append(dy);
builder.append(nx);
builder.append(ny);
return builder.toHashCode();
}
public void setNx(Integer nx) {
this.nx = nx;
}
public Integer getNy() {
return ny;
}
public void setNy(Integer ny) {
this.ny = ny;
}
public String getCrsWKT() {
return crsWKT;
}
public void setCrsWKT(String crsWKT) {
this.crsWKT = crsWKT;
}
public Polygon getLocation() {
return location;
}
public void setLocation(Polygon location) {
this.location = location;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
SatMapCoverage other = (SatMapCoverage) obj;
if (projection != other.projection)
return false;
String crsWKT = getCrsWKT();
String otherCrsWKT = other.getCrsWKT();
if (crsWKT == null) {
if (otherCrsWKT != null)
return false;
} else if (!crsWKT.equals(otherCrsWKT))
return false;
if (Double.doubleToLongBits(dx) != Double.doubleToLongBits(other.dx))
return false;
if (Double.doubleToLongBits(dy) != Double.doubleToLongBits(other.dy))
return false;
if (Double.doubleToLongBits(minX) != Double
.doubleToLongBits(other.minX))
return false;
if (Double.doubleToLongBits(minY) != Double
.doubleToLongBits(other.minY))
return false;
if (nx != other.nx)
return false;
if (ny != other.ny)
return false;
return true;
}
}

View file

@ -35,6 +35,7 @@ import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import org.geotools.coverage.grid.GridGeometry2D;
import org.hibernate.annotations.Index;
import com.raytheon.uf.common.dataplugin.IDecoderGettable;
@ -43,7 +44,7 @@ import com.raytheon.uf.common.dataplugin.annotations.DataURI;
import com.raytheon.uf.common.dataplugin.persist.PersistablePluginDataObject;
import com.raytheon.uf.common.datastorage.DataStoreFactory;
import com.raytheon.uf.common.datastorage.records.IDataRecord;
import com.raytheon.uf.common.geospatial.ISpatialEnabled;
import com.raytheon.uf.common.geospatial.IGridGeometryProvider;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
@ -91,7 +92,7 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
@XmlAccessorType(XmlAccessType.NONE)
@DynamicSerialize
public class SatelliteRecord extends PersistablePluginDataObject implements
ISpatialEnabled {
IGridGeometryProvider {
public static final String PLUGIN_ID = "satellite";
@ -176,16 +177,6 @@ public class SatelliteRecord extends PersistablePluginDataObject implements
@DynamicSerializeElement
private Float satSubPointLon;
/** The upper right hand latitude */
@Column
@DynamicSerializeElement
private Float upperRightLat;
/** The upper right hand longitude */
@Column
@DynamicSerializeElement
private Float upperRightLon;
/** Height of the satellite in km */
@Column
@DynamicSerializeElement
@ -229,8 +220,8 @@ public class SatelliteRecord extends PersistablePluginDataObject implements
}
@Override
public SatMapCoverage getSpatialObject() {
return coverage;
public GridGeometry2D getGridGeometry() {
return coverage != null ? coverage.getGridGeometry() : null;
}
public SatMapCoverage getCoverage() {
@ -257,22 +248,6 @@ public class SatelliteRecord extends PersistablePluginDataObject implements
this.satSubPointLon = satSubPointLon;
}
public Float getUpperRightLat() {
return upperRightLat;
}
public void setUpperRightLat(Float upperRightLat) {
this.upperRightLat = upperRightLat;
}
public Float getUpperRightLon() {
return upperRightLon;
}
public void setUpperRightLon(Float upperRightLon) {
this.upperRightLon = upperRightLon;
}
public Integer getNumRecords() {
return numRecords;
}

View file

@ -0,0 +1,45 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.geospatial;
import org.geotools.coverage.grid.GridGeometry2D;
/**
* Interface indicating object can provide a {@link GridGeometry2D}
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Sep 25, 2013 2333 mschenke Initial creation
*
* </pre>
*
* @author mschenke
* @version 1.0
*/
public interface IGridGeometryProvider {
public GridGeometry2D getGridGeometry();
}

View file

@ -39,7 +39,9 @@ import org.opengis.referencing.FactoryException;
import org.opengis.referencing.operation.MathTransform;
/**
* Geostationary map projection. Earth as viewed from space.
* Geostationary map projection. Earth as viewed from space. Based on
* Coordination Group for Meteorological Satellites LRIT/HRIT Global
* Specification
*
* TODO Add support latitude of origin != 0.0
*
@ -49,7 +51,8 @@ import org.opengis.referencing.operation.MathTransform;
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 27, 2013 mschenke Initial creation
* Jun 27, 2013 mschenke Initial creation
* Oct 02, 2013 2333 mschenke Converted from libproj to CGMS algorithm
*
* </pre>
*
@ -63,17 +66,25 @@ public class Geostationary extends MapProjection {
public static final String PROJECTION_NAME = "Geostationary";
public static final String PERSPECTIVE_HEIGHT = "perspective_height";
public static final String ORBITAL_HEIGHT = "orbital_height";
public static final String SWEEP_AXIS = "sweep_axis";
static final double DEFAULT_PERSPECTIVE_HEIGHT = 35800000.0;
private double perspectiveHeight = DEFAULT_PERSPECTIVE_HEIGHT;
private double orbitalHeight;
private double perspectiveHeight;
private boolean swapAxis = false;
private double radius_g, radius_g_1, radius_p, radius_p2, radius_p_inv2, C;
private double rEq, rEq2;
private double rPol, rPol2;
private double height_ratio;
private double e2;
/**
* @param values
@ -82,23 +93,18 @@ public class Geostationary extends MapProjection {
protected Geostationary(ParameterValueGroup values)
throws ParameterNotFoundException {
super(values);
this.perspectiveHeight = Provider.getValue(Provider.PERSPECTIVE_HEIGHT,
values);
this.orbitalHeight = Provider.getValue(Provider.ORBITAL_HEIGHT, values);
this.perspectiveHeight = orbitalHeight + semiMajor;
double sweepValue = Provider.getValue(Provider.SWEEP_AXIS, values);
this.swapAxis = sweepValue == 1.0;
double h = perspectiveHeight;
double a = semiMajor;
double b = semiMinor;
double es = 1.0 - (b * b) / (a * a);
double one_es = 1.0 - es;
double rone_es = 1.0 / one_es;
radius_g_1 = h / a;
radius_g = 1 + radius_g_1;
radius_p2 = one_es;
radius_p_inv2 = rone_es;
radius_p = Math.sqrt(radius_p2);
C = radius_g * radius_g - 1.0;
this.rEq = semiMajor;
this.rEq2 = rEq * rEq;
this.rPol = semiMinor;
this.rPol2 = rPol * rPol;
this.e2 = (rEq2 - rPol2) / rEq2;
this.height_ratio = rEq / orbitalHeight;
}
/*
@ -112,6 +118,16 @@ public class Geostationary extends MapProjection {
return Provider.PARAMETERS;
}
@Override
public ParameterValueGroup getParameterValues() {
ParameterValueGroup values = super.getParameterValues();
values.parameter(Provider.ORBITAL_HEIGHT.getName().getCode()).setValue(
orbitalHeight);
values.parameter(Provider.SWEEP_AXIS.getName().getCode()).setValue(
swapAxis ? 1.0 : 0.0);
return values;
}
/*
* (non-Javadoc)
*
@ -121,38 +137,30 @@ public class Geostationary extends MapProjection {
@Override
protected Point2D inverseTransformNormalized(double x, double y,
Point2D ptDst) throws ProjectionException {
double lam, phi;
double Vx, Vy, Vz, a, b, det, k;
double lam = Double.NaN, phi = Double.NaN;
x *= height_ratio;
y *= height_ratio;
/* Setting three components of vector from satellite to position. */
Vx = -1.0;
if (swapAxis) {
Vz = Math.tan(y / radius_g_1);
Vy = Math.tan(x / radius_g_1) * Math.hypot(1.0, Vz);
} else {
Vy = Math.tan(x / radius_g_1);
Vz = Math.tan(y / radius_g_1) * Math.hypot(1.0, Vy);
}
/* Calculation of terms in cubic equation and determinant. */
a = Vz / radius_p;
a = Vy * Vy + a * a + Vx * Vx;
b = 2 * radius_g * Vx;
if ((det = (b * b) - 4 * a * C) < 0.) {
lam = phi = Double.NaN;
} else {
/*
* Calculation of three components of vector from satellite to
* position.
*/
k = (-b - Math.sqrt(det)) / (2. * a);
Vx = radius_g + k * Vx;
Vy *= k;
Vz *= k;
/* Calculation of longitude and latitude. */
lam = Math.atan2(Vy, Vx);
phi = Math.atan(Vz * Math.cos(lam) / Vx);
phi = Math.atan(radius_p_inv2 * Math.tan(phi));
}
double sinX = Math.sin(x);
double cosX = Math.cos(x);
double sinY = Math.sin(y);
double cosY = Math.cos(y);
double a = sinX * sinX + cosX * cosX
* (cosY * cosY + (rEq2 / rPol2) * sinY * sinY);
double b = -2 * perspectiveHeight * cosX * cosY;
double c = perspectiveHeight * perspectiveHeight - rEq2;
double Vl = (-b - Math.sqrt(b * b - 4 * a * c)) / 2 * a;
double Vx = Vl * cosX * cosY;
double Vy = Vl * sinX;
double Vz = Vl * sinY * cosX;
double s1 = perspectiveHeight - Vx;
lam = Math.atan(Vy / s1);
phi = Math.atan((rEq2 / rPol2) * (Vz / Math.sqrt(s1 * s1 + Vy * Vy)));
if (ptDst == null) {
ptDst = new Point2D.Double();
@ -170,38 +178,37 @@ public class Geostationary extends MapProjection {
@Override
protected Point2D transformNormalized(double lam, double phi, Point2D ptDst)
throws ProjectionException {
double x, y;
double r, Vx, Vy, Vz, tmp;
double x = Double.NaN, y = Double.NaN;
/* Calculation of geocentric latitude. */
phi = Math.atan(radius_p2 * Math.tan(phi));
/*
* Calculation of the three components of the vector from satellite to*
* position on earth surface (lon,lat).
*/
r = (radius_p) / Math.hypot(radius_p * Math.cos(phi), Math.sin(phi));
Vx = r * Math.cos(lam) * Math.cos(phi);
Vy = r * Math.sin(lam) * Math.cos(phi);
Vz = r * Math.sin(phi);
/* Check visibility. */
if (((radius_g - Vx) * Vx - Vy * Vy - Vz * Vz * radius_p_inv2) < 0.) {
double cPhi = Math.atan((rPol2 / rEq2) * Math.tan(phi));
double cosPhi = Math.cos(cPhi);
double rs = rPol / Math.sqrt(1 - e2 * cosPhi * cosPhi);
double rPhi = rs * cosPhi;
double Vx = perspectiveHeight - rPhi * Math.cos(lam);
double Vy = rPhi * Math.sin(lam);
double Vz = rs * Math.sin(cPhi);
double Vn = Math.sqrt(Vx * Vx + Vy * Vy + Vz * Vz);
if ((perspectiveHeight * (perspectiveHeight - Vx)) < (Vy * Vy + (rEq2 / rPol2)
* Vz * Vz)) {
x = y = Double.NaN;
} else {
/* Calculation based on view angles from satellite. */
tmp = radius_g - Vx;
// Altered for x sweeping axis
if (swapAxis) {
x = radius_g_1 * Math.atan(Vy / Math.hypot(Vz, tmp));
y = radius_g_1 * Math.atan(Vz / tmp);
x = Math.atan(Vy / Vx);
y = Math.asin(Vz / Vn);
} else {
x = radius_g_1 * Math.atan(Vy / tmp);
y = radius_g_1 * Math.atan(Vz / Math.hypot(Vy, tmp));
x = Math.asin(Vy / Vn);
y = Math.atan(Vz / Vx);
}
}
if (ptDst == null) {
ptDst = new Point2D.Double();
}
ptDst.setLocation(x, y);
ptDst.setLocation(x / height_ratio, y / height_ratio);
return ptDst;
}
@ -209,8 +216,8 @@ public class Geostationary extends MapProjection {
private static final long serialVersionUID = 3868187206568280453L;
static final ParameterDescriptor<Double> PERSPECTIVE_HEIGHT = DefaultParameterDescriptor
.create(Geostationary.PERSPECTIVE_HEIGHT,
static final ParameterDescriptor<Double> ORBITAL_HEIGHT = DefaultParameterDescriptor
.create(Geostationary.ORBITAL_HEIGHT,
DEFAULT_PERSPECTIVE_HEIGHT, 0, Double.MAX_VALUE,
SI.METER);
@ -218,10 +225,10 @@ public class Geostationary extends MapProjection {
.create(Geostationary.SWEEP_AXIS, 0.0, 0.0, 1.0, Unit.ONE);
static final ParameterDescriptorGroup PARAMETERS = new DefaultParameterDescriptorGroup(
PROJECTION_NAME, new ParameterDescriptor[] {
SEMI_MAJOR, SEMI_MINOR, CENTRAL_MERIDIAN,
LATITUDE_OF_ORIGIN, FALSE_EASTING, FALSE_NORTHING,
PERSPECTIVE_HEIGHT, SWEEP_AXIS });
PROJECTION_NAME, new ParameterDescriptor[] { SEMI_MAJOR,
SEMI_MINOR, CENTRAL_MERIDIAN, LATITUDE_OF_ORIGIN,
FALSE_EASTING, FALSE_NORTHING, ORBITAL_HEIGHT,
SWEEP_AXIS });
public Provider() {
super(PARAMETERS);

View file

@ -81,7 +81,6 @@ public class EnvelopeIntersection {
public static Geometry createEnvelopeIntersection(Envelope sourceEnvelope,
Envelope targetEnvelope, double threshold, int maxHorDivisions,
int maxVertDivisions) throws TransformException, FactoryException {
long t0 = System.currentTimeMillis();
ReferencedEnvelope sourceREnvelope = reference(sourceEnvelope);
ReferencedEnvelope targetREnvelope = reference(targetEnvelope);
Geometry border = null;
@ -242,7 +241,6 @@ public class EnvelopeIntersection {
// intersections in collection
Coordinate[] borderCorners = { ul, ur, lr, ll };
// First, world wrap correct the line strings
List<LineString> corrected = new ArrayList<LineString>();
for (LineString ls : lineStrings) {
@ -507,8 +505,6 @@ public class EnvelopeIntersection {
}
}
System.out.println("Time to create EnvelopeIntersection: "
+ (System.currentTimeMillis() - t0) + "ms");
return border;
}

View file

@ -20,8 +20,6 @@
package com.raytheon.uf.edex.plugin.fog;
import org.geotools.coverage.grid.GridGeometry2D;
import org.geotools.geometry.GeneralEnvelope;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import com.raytheon.edex.plugin.satellite.dao.SatelliteDao;
import com.raytheon.uf.common.dataplugin.PluginException;
@ -30,11 +28,7 @@ import com.raytheon.uf.common.datastorage.IDataStore;
import com.raytheon.uf.common.datastorage.Request;
import com.raytheon.uf.common.datastorage.records.ByteDataRecord;
import com.raytheon.uf.common.datastorage.records.IDataRecord;
import com.raytheon.uf.common.geospatial.MapUtil;
import com.raytheon.uf.edex.database.plugin.PluginFactory;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Polygon;
public class FogDbUtils {
@ -94,67 +88,7 @@ public class FogDbUtils {
* @return
*/
public static GridGeometry2D getGridGeometry(SatelliteRecord rec) {
return MapUtil.getGridGeometry(rec.getSpatialObject());
}
/**
* Creates the Grid Geometry for the Fog Display grid
*
* @param geo
* @param crs
* @param nx
* @param ny
* @return
*/
public static GeneralEnvelope getEnvelope(Geometry geo, CoordinateReferenceSystem crs) {
GeneralEnvelope env2 = null;
try {
Point[] points = new Point[((Polygon) geo).getExteriorRing().getNumPoints()];
for (int i = 0; i < points.length; i++) {
points[i] = ((Polygon) geo).getExteriorRing().getPointN(i);
}
env2 = MapUtil.extractProjectedEnvelope(crs, points, MapUtil
.getTransformFromLatLon(crs));
}
catch (Exception e) {
e.printStackTrace();
}
return env2;
}
/**
* Used to re size raster IR sat grids to VIS size
*
* @param inputGrid
* @param outputGridSize
* @param nx
* @param ny
* @return
*/
public static float[] reSizeFloatGrid(float[] inputGrid, int outputGridSize, int nx, int ny) {
float[] outputGrid = new float[outputGridSize];
// decimate
// (SK) i => x j => y
for (int j = 0; j < ny; j++) {
for (int i = 0; i < nx; i++) {
float avValue = 0;
for (int y = 0; y < 4; y++) {
for (int x = 0; x < 4; x++) {
// average the grid values
avValue += inputGrid[nx * (j * 4 + y) + i * 4 + x];
}
}
outputGrid[nx * j + i] = avValue / 16;
}
}
return outputGrid;
return rec.getGridGeometry();
}
/**

View file

@ -292,8 +292,7 @@ public class FogConfig {
* @return
*/
private void setDx(SatelliteRecord rec) {
dx = rec.getCoverage().getDx();
dx = (float) rec.getCoverage().getDx();
}
/**
@ -312,8 +311,7 @@ public class FogConfig {
* @return
*/
private void setDy(SatelliteRecord rec) {
dy = rec.getCoverage().getDy();
dy = (float) rec.getCoverage().getDy();
}
/**

View file

@ -323,7 +323,7 @@ public class McidasSatelliteDecoder {
lo2 = (float) prnlon(lo2);
result = SatSpatialFactory.getInstance().getMapCoverage(
SatMapCoverage.PROJ_MERCATOR, nx, ny, (float) dx,
SatSpatialFactory.PROJ_MERCATOR, nx, ny, (float) dx,
(float) dy, (float) clon, (float) clat, la1, lo1, la2, lo2);
} else {
unimplemented(String.format("navigation type \"%s\"", navType));

View file

@ -61,6 +61,7 @@ import gov.noaa.nws.ncep.common.dataplugin.ncgrib.spatial.projections.PolarStere
* Added getGridNavigationContent, float2File,
* serialize2File, data2File, flipData
* 09/14/2010 284 mgamazaychikov Add addHours method
* 10/02/2013 2333 mschenke Removed unused function getSatHdrContent
* </pre>
*
* @author mgamazaychikov
@ -295,45 +296,6 @@ public class GempakConvert {
return inputStrings;
}
/*
* Construct the satellite header string
*/
public static String getSatHdrContent(ISpatialObject obj) throws JAXBException {
SatMapCoverage mapCoverage = (SatMapCoverage)obj;
StringBuffer resultsBuf = new StringBuffer();
resultsBuf.append(mapCoverage.getProjection());
resultsBuf.append(";");
resultsBuf.append(mapCoverage.getNx());
resultsBuf.append(";");
resultsBuf.append(mapCoverage.getNy());
resultsBuf.append(";");
Float dummy = mapCoverage.getLa1()*10000;
resultsBuf.append(dummy.intValue());
resultsBuf.append(";");
dummy = mapCoverage.getLa2()*10000;
resultsBuf.append(dummy.intValue());
resultsBuf.append(";");
dummy = mapCoverage.getLo1()*10000;
resultsBuf.append(dummy.intValue());
resultsBuf.append(";");
dummy = mapCoverage.getLo2()*10000;
resultsBuf.append(dummy.intValue());
resultsBuf.append(";");
dummy = mapCoverage.getLatin()*10000;
resultsBuf.append(dummy.intValue());
resultsBuf.append(";");
dummy = mapCoverage.getLov()*10000;
resultsBuf.append(dummy.intValue());
resultsBuf.append(";");
resultsBuf.append(mapCoverage.getDx().intValue());
resultsBuf.append(";");
resultsBuf.append(mapCoverage.getDy().intValue());
String content = resultsBuf.toString();
return content;
}
/*
* Converts AWIPS2 date time string into GEMPAK DATTIM string
*/

View file

@ -80,7 +80,7 @@ public class GiniAreaProviderFactory implements INcAreaProviderFactory {
if( proj == 1 || proj == 3 || proj == 5 ) { // MER, LCC or STR
// for remapped projections such as MER, LCC, STR
gridGeom = MapUtil.getGridGeometry( satRec.getSpatialObject() );
gridGeom = satRec.getGridGeometry();
}
else {
System.out.println("Unable to get Coverage for projection "+ proj+ "." );

View file

@ -12,7 +12,6 @@ package gov.noaa.nws.ost.edex.plugin.regionalsat.decoder;
import gov.noaa.nws.ost.edex.plugin.regionalsat.util.RegionalSatLookups;
import gov.noaa.nws.ost.edex.plugin.regionalsat.util.RegionalSatLookups.PhysicalElementValue;
import gov.noaa.nws.ost.edex.plugin.regionalsat.util.RegionalSatSpatialFactory;
import java.util.Calendar;
import java.util.TimeZone;
@ -22,6 +21,7 @@ import ucar.nc2.NetcdfFile;
import com.raytheon.edex.exception.DecoderException;
import com.raytheon.edex.plugin.AbstractDecoder;
import com.raytheon.edex.util.satellite.SatSpatialFactory;
import com.raytheon.uf.common.dataplugin.PluginDataObject;
import com.raytheon.uf.common.dataplugin.satellite.SatMapCoverage;
import com.raytheon.uf.common.dataplugin.satellite.SatelliteRecord;
@ -200,7 +200,7 @@ public class RegionalSatDecoder extends AbstractDecoder {
float lov = netCdfFile.findGlobalAttribute("centralLon")
.getNumericValue().floatValue();
int mapProjection = SatMapCoverage.PROJ_POLAR_STEREO; // STEREOGRAPHIC
int mapProjection = SatSpatialFactory.PROJ_POLAR; // STEREOGRAPHIC
// projection
// default
float latin = 0.0f; // set to zero for Stereographic projections
@ -215,12 +215,12 @@ public class RegionalSatDecoder extends AbstractDecoder {
.getNumericValue().floatValue();
if (projection.equalsIgnoreCase("LAMBERT")
|| projection.equalsIgnoreCase("LAMBERT_CONFORMAL")) {
mapProjection = SatMapCoverage.PROJ_LAMBERT;
mapProjection = SatSpatialFactory.PROJ_LAMBERT;
} else if (projection.equalsIgnoreCase("MERCATOR")) {
mapProjection = SatMapCoverage.PROJ_MERCATOR;
mapProjection = SatSpatialFactory.PROJ_MERCATOR;
} else if (projection
.equalsIgnoreCase("CYLINDRICAL_EQUIDISTANT")) {
mapProjection = SatMapCoverage.PROJ_CYLIN_EQUIDISTANT;
mapProjection = SatSpatialFactory.PROJ_CYLIN_EQUIDISTANT;
}
} else {
@ -237,10 +237,10 @@ public class RegionalSatDecoder extends AbstractDecoder {
int nx = 0, ny = 0;
// Do specialized decoding and retrieve spatial data for projections
if ((mapProjection == SatMapCoverage.PROJ_MERCATOR)
|| (mapProjection == SatMapCoverage.PROJ_LAMBERT)
|| (mapProjection == SatMapCoverage.PROJ_POLAR_STEREO)
|| (mapProjection == SatMapCoverage.PROJ_CYLIN_EQUIDISTANT)) {
if ((mapProjection == SatSpatialFactory.PROJ_MERCATOR)
|| (mapProjection == SatSpatialFactory.PROJ_LAMBERT)
|| (mapProjection == SatSpatialFactory.PROJ_POLAR)
|| (mapProjection == SatSpatialFactory.PROJ_CYLIN_EQUIDISTANT)) {
// set number of points along x-axis
nx = recordSize;
@ -276,20 +276,10 @@ public class RegionalSatDecoder extends AbstractDecoder {
"Unable to decode Satellite: Encountered Unknown projection");
} // end of if map projection block
// Get latitude of upper right hand corner
float urLat = 0; // not used so set to zero, if required get and set
// value
record.setUpperRightLat(urLat);
// Get longitude of upper right hand corner
float urLon = 0; // not used so set to zero, if required get and set
// value
record.setUpperRightLon(urLon);
SatMapCoverage mapCoverage = null;
try {
mapCoverage = RegionalSatSpatialFactory.getInstance()
mapCoverage = SatSpatialFactory.getInstance()
.getMapCoverage(mapProjection, nx, ny, dx, dy, lov,
latin, la1, lo1, la2, lo2);
} catch (Exception e) {
@ -316,7 +306,6 @@ public class RegionalSatDecoder extends AbstractDecoder {
record.setCoverage(mapCoverage);
record.setPersistenceTime(TimeTools.getSystemCalendar()
.getTime());
record.constructDataURI();
// Set the data into the IDataRecord
IDataRecord dataRec = SatelliteRecord.getDataRecord(record);

View file

@ -1,393 +0,0 @@
/**
*
* gov.noaa.nws.ost.edex.plugin.regionalsat.util.RegionalSatSpatialFactory
*
* 12-01-11
*
* This code has been developed by the NWS/OST/SEC for use in the AWIPS2 system.
*
**/
package gov.noaa.nws.ost.edex.plugin.regionalsat.util;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.geotools.geometry.DirectPosition2D;
import org.opengis.referencing.crs.ProjectedCRS;
import org.opengis.referencing.operation.MathTransform;
import com.raytheon.edex.plugin.satellite.dao.SatMapCoverageDao;
import com.raytheon.uf.common.dataplugin.satellite.SatMapCoverage;
import com.raytheon.uf.common.geospatial.MapUtil;
import com.raytheon.uf.edex.database.DataAccessLayerException;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.io.WKTReader;
/**
* The RegionalSatSpatialFactory class is responsible for creating a SatMapCoverage object.
* This class is based on the SatSpatialFactory class. TODO; The class needs to be refactored
* to reduce code duplication. The class should use the Abstract Factory Method design pattern,
* but the code refactor requires changes to the base code. A TTR has been submitted to refactor
* the Satellite spatial factory classes in edex.
*
* <pre>
*
* SOFTWARE HISTORY
*
* date Ticket# Engineer Description
* ----------- ---------- ----------- --------------------------
* 7/15/11 tk Initial Creation
* - AWIPS2 Baseline Repository --------
* 07/12/2012 798 jkorman Changed projection "magic" numbers
* </pre>
*
* @author tk
* @version 1.0
*/
public class RegionalSatSpatialFactory {
/** The logger */
private Log logger = LogFactory.getLog(getClass());
/** The singleton instance */
private static RegionalSatSpatialFactory instance;
/**
* Gets the singleton instance
*
* @return The singleton instance
*/
public static synchronized RegionalSatSpatialFactory getInstance() {
if (instance == null) {
instance = new RegionalSatSpatialFactory();
}
return instance;
}
/**
* make default constructor private to disable
* object creation from outside the class
*
*/
private RegionalSatSpatialFactory() {
}
/**
* Retrieves or generates a satellite map coverage object
*
* @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 db interaction or creation of the
* coverage object
*/
public synchronized SatMapCoverage getMapCoverage(
Integer mapProjection, Integer nx, Integer ny, Float dx, Float dy,
Float lov, Float latin, Float la1, Float lo1, Float la2, Float lo2)
throws Exception {
SatMapCoverage mapCoverage = null;
SatMapCoverageDao satDao = new SatMapCoverageDao();
try {
// Check the database to see if a coverage already exists
mapCoverage = satDao.getSatCoverage(mapProjection, nx, ny, dx, dy,
lov, latin, la1, lo1, la2, lo2);
// If the database does not contain an existing sat map coverage for
// the given values, create one
if (mapCoverage == null) {
mapCoverage = createMapCoverage(mapProjection, nx, ny, dx, dy,
lov, latin, la1, lo1, la2, lo2);
// Persist the new coverage to the database
satDao.persist(mapCoverage);
}
} catch (Exception e) {
throw new DataAccessLayerException(
"Unable to retrieve or construct valid Satellite Map Coverage",
e);
}
if (mapCoverage == null) {
throw new DataAccessLayerException(
"Unable to retrieve or construct valid Satellite Map Coverage");
}
return mapCoverage;
}
/**
* Creates a new SatMapCoverage object from scratch with the given
* parameters
*
* @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(
Integer mapProjection, Integer nx, Integer ny, Float dx, Float dy,
Float lov, Float latin, Float la1, Float lo1, Float la2, Float lo2)
throws Exception {
logger.debug("Creating map coverage object");
ProjectedCRS crs = null;
// Get the correct CRS
if (mapProjection == SatMapCoverage.PROJ_MERCATOR) {
crs = MapUtil.constructMercator(MapUtil.AWIPS_EARTH_RADIUS,
MapUtil.AWIPS_EARTH_RADIUS, latin, lov);
} else if (mapProjection == SatMapCoverage.PROJ_LAMBERT) {
crs = MapUtil.constructLambertConformal(MapUtil.AWIPS_EARTH_RADIUS,
MapUtil.AWIPS_EARTH_RADIUS, latin, latin, lov);
} else if (mapProjection == SatMapCoverage.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. Image starts with ul corner
*/
if (mapProjection == 1) {
logger.debug("Determining corner points for Mercator projection");
corner4.x = lo1;
corner4.y = la1;
corner2.x = lo2;
corner2.y = la2;
corner3.x = lo2;
corner3.y = la1;
corner1.x = lo1;
corner1.y = la2;
}
else {
/*
* Projection is for Polar Stereographic, EquidistantCylindrical or "
* "Lambert Conformal. Therefore,the corner points must be calculated
*/
logger.debug("Determining corner points for Polar Stereographic, " +
"EquidistantCylindrical or Lambert Conformal");
// make lon values positive since -170 is the same as +190 degrees
double lon1 = 0.0f;
if (lo1 < 0.0f) {
lon1 = (180.0 + lo1) + 180.0;
} else {
lon1 = lo1;
}
double lon2 = 0.0f;
if (lo2 < 0.0f) {
lon2 = (180.0 + lo2) + 180.0;
} else {
lon2 = lo1;
}
// Get the transforms to be used to convert between meters and
// lat/lon
MathTransform fromLatLon = MapUtil.getTransformFromLatLon(crs);
MathTransform toLatLon = fromLatLon.inverse();
if (la2 < la1) {
if (lon2 < lon1) {
// Use la2 and lo2 to specify the first point starting with ll corner
logger.debug("Starting with lower left corner Fourth Position");
fourthPosition = new DirectPosition2D();
fromLatLon.transform(new DirectPosition2D(lo2, la2), fourthPosition);
logger.debug("Fourth Position:x,y " + fourthPosition.x + ", " + fourthPosition.y);
secondPosition = new DirectPosition2D();
fromLatLon.transform(new DirectPosition2D(lo1, la1), secondPosition);
logger.debug("Second Position:x,y " + secondPosition.x + ", " + secondPosition.y);
firstPosition = new DirectPosition2D(secondPosition.x, fourthPosition.y);
logger.debug(" First Position:x,y " + firstPosition.x + ", " + firstPosition.y);
thirdPosition = new DirectPosition2D(fourthPosition.x, secondPosition.y);
logger.debug("Third Position:x,y " + thirdPosition.x + ", " + thirdPosition.y);
} else {
// Use la2 and lo2 to specify the fourth point starting with lr corner
logger.debug("Polorsterographic for Alaska start with lower right corner " +
"Third Position");
thirdPosition = new DirectPosition2D();
fromLatLon.transform(new DirectPosition2D(lo2, la2), thirdPosition);
logger.debug("Third Position:x,y " + thirdPosition.x + ", " + thirdPosition.y);
firstPosition = new DirectPosition2D();
fromLatLon.transform(new DirectPosition2D(lo1, la1), firstPosition);
logger.debug("First Position:x,y " + firstPosition.x + ", " + firstPosition.y);
fourthPosition = new DirectPosition2D(thirdPosition.x, firstPosition.y);
logger.debug("Fourth Position:x,y " + fourthPosition.x + ", " + fourthPosition.y);
secondPosition = new DirectPosition2D(firstPosition.x, thirdPosition.y);
logger.debug("Second Position:x,y " + secondPosition.x + ", " + secondPosition.y);
}
} else {
if (lon2 < lon1) {
// Use la2 and lo2 to specify the first point starting with ul corner
logger.debug("Starting with lower upper left Fourth Position");
firstPosition = new DirectPosition2D();
fromLatLon.transform(new DirectPosition2D(lo2, la2), firstPosition);
logger.debug("First Position:x,y " + firstPosition.x + ", " + firstPosition.y);
thirdPosition = new DirectPosition2D();
fromLatLon.transform(new DirectPosition2D(lo1, la1), thirdPosition);
logger.debug("Third Position:x,y " + thirdPosition.x + ", " + thirdPosition.y);
secondPosition = new DirectPosition2D(firstPosition.x, thirdPosition.y);
logger.debug("Second Position:x,y " + secondPosition.x + ", " + secondPosition.y);
fourthPosition = new DirectPosition2D(thirdPosition.x, firstPosition.y);
logger.debug("Fourth Position:x,y " + fourthPosition.x + ", " + fourthPosition.y);
} else {
// Use la2 and lo2 to specify the fourth point starting with ur corner
logger.debug("Starting with lower right corner Fourth Position");
secondPosition = new DirectPosition2D();
fromLatLon.transform(new DirectPosition2D(lo2, la2), secondPosition);
logger.debug("Second Position:x,y " + secondPosition.x + ", " + secondPosition.y);
fourthPosition = new DirectPosition2D();
fromLatLon.transform(new DirectPosition2D(lo1, la1), fourthPosition);
logger.debug("Fourth Position:x,y " + fourthPosition.x + ", " + fourthPosition.y);
firstPosition = new DirectPosition2D(secondPosition.x, fourthPosition.y);
logger.debug("First Position:x,y " + firstPosition.x + ", " + firstPosition.y);
thirdPosition = new DirectPosition2D(fourthPosition.x, secondPosition.y);
logger.debug("Third Position:x,y " + thirdPosition.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);
logger.debug("First Corner:" + corner1.toString());
logger.debug("Second Corner:" + corner2.toString());
logger.debug("Third Corner:" + corner3.toString());
logger.debug("Fourth Corner:" + corner4.toString());
}
/*
* Projection is EquidistantCylindrical or Polar Stereographic. Therefore,
* the corner points must be calculated
*/
// Construct the polygon constructor String
StringBuffer buffer = new StringBuffer();
buffer.append("POLYGON((");
buffer.append(corner4.x + " " + corner4.y + ",");
buffer.append(corner1.x + " " + corner1.y + ",");
buffer.append(corner2.x + " " + corner2.y + ",");
buffer.append(corner3.x + " " + corner3.y + ",");
buffer.append(corner4.x + " " + corner4.y);
buffer.append("))");
logger.debug("Polygon: " + buffer.toString());
// Create the geometry from the constructed String
Geometry geometry = new WKTReader().read(buffer.toString());
la2 = (float)corner2.y;
lo2 = (float)corner2.x;
la1 = (float)corner4.y;
lo1 = (float)corner4.x;
logger.debug("(Lo1, La1),(lo2, La2) (" + lo1 + ", " + la1 + "), (" + lo2 + ", " + la2 +")");
SatMapCoverage mapCoverage = new SatMapCoverage(mapProjection,
nx, ny, dx, dy, lov, latin, la1, lo1, la2, lo2, crs, geometry);
return mapCoverage;
}
}