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:e3f6b1ea21
[formerlye3f6b1ea21
[formerly 384b8e6a02d4fffa0688993b2a2b53e974ecf493]] Former-commit-id:866c851b47
Former-commit-id:ba25f56dbe
This commit is contained in:
parent
baa1ddd596
commit
80efdbb2b4
37 changed files with 1012 additions and 1167 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
|
@ -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
|
|
@ -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"
|
|
@ -0,0 +1,4 @@
|
|||
source.. = src/
|
||||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
.
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
Binary file not shown.
16
deltaScripts/14.2.1/satellite_spatial_update/update_satellite_spatial.sh
Executable file
16
deltaScripts/14.2.1/satellite_spatial_update/update_satellite_spatial.sh
Executable 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
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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+ "." );
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Reference in a new issue