Issue #3069 Fix contour tool issues caused by GeoTools 10.5 update

Change-Id: I4d1bedc67059f0c9fdec3f7a5d2938869c12c465

Former-commit-id: 809548b283 [formerly 3b404f4083 [formerly b10be8ae235c4528c4ce83088daeccf8a0928933]]
Former-commit-id: 3b404f4083
Former-commit-id: b794dd04e1
This commit is contained in:
Ron Anderson 2014-05-20 10:40:34 -05:00
parent 27f56c3f36
commit 0e02e83629
13 changed files with 748 additions and 641 deletions

View file

@ -362,6 +362,12 @@
id="com.raytheon.viz.gfe.SiteActivation"
name="GFE Site Activation">
</command>
<command
categoryId="com.raytheon.viz.gfe.GFECategory"
description="Coordinate Conversion"
id="com.raytheon.viz.gfe.CoordinateConversion"
name="GFE Coordinate Conversion">
</command>
<category
description="GFE Edit Tools"
id="com.raytheon.viz.ui.modalTool.gfe"
@ -975,6 +981,10 @@
</reference>
</activeWhen>
</handler>
<handler
class="com.raytheon.viz.gfe.actions.CoordinateConversionHandler"
commandId="com.raytheon.viz.gfe.CoordinateConversion">
</handler>
<handler
class="com.raytheon.viz.gfe.export.image.GfeExportImageHandler"
commandId="com.raytheon.uf.viz.image.export.save">
@ -1143,6 +1153,13 @@
label="Site Activation..."
style="push">
</command>
<!-- Commented out for now. May re-enable when DR #15463 is worked
<command
commandId="com.raytheon.viz.gfe.CoordinateConversion"
label="Coordinate Conversion..."
style="push">
</command>
-->
</menu>
<menu label="WeatherElement" mnemonic="W">
<visibleWhen>

View file

@ -0,0 +1,83 @@
/**
* 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.viz.gfe.actions;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
import com.raytheon.viz.gfe.core.DataManager;
import com.raytheon.viz.gfe.core.DataManagerUIFactory;
import com.raytheon.viz.gfe.dialogs.CoordinateConversionDialog;
/**
* Handler to display the Coordinate Conversion Dialog
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* May 13, 2014 #3069 randerso Added to help debug GeoTools 10.5 issues.
* May partially address Dimensions DR 15463
* plugin.xml menu entry commented out so can't be activated
*
* </pre>
*
* @author randerso
* @version 1.0
*/
public class CoordinateConversionHandler extends AbstractHandler {
private CoordinateConversionDialog dialog;
/*
* (non-Javadoc)
*
* @see
* org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands.
* ExecutionEvent)
*/
@Override
public Object execute(ExecutionEvent event) throws ExecutionException {
DataManager dm = DataManagerUIFactory.getCurrentInstance();
if (dm == null) {
return null;
}
if ((dialog == null) || (dialog.getShell() == null)
|| dialog.isDisposed()) {
Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow()
.getShell();
dialog = new CoordinateConversionDialog(shell, dm);
dialog.setBlockOnOpen(false);
dialog.open();
} else {
dialog.bringToTop();
}
return null;
}
}

View file

@ -0,0 +1,307 @@
/**
* 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.viz.gfe.dialogs;
import java.text.DecimalFormat;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.opengis.metadata.spatial.PixelOrientation;
import com.raytheon.uf.common.dataplugin.gfe.config.ProjectionData;
import com.raytheon.uf.common.dataplugin.gfe.db.objects.GridLocation;
import com.raytheon.uf.common.geospatial.MapUtil;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.viz.gfe.core.DataManager;
import com.raytheon.viz.ui.dialogs.CaveJFACEDialog;
import com.vividsolutions.jts.geom.Coordinate;
/**
* Coordinate Conversion Dialog
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* May 13, 2014 #3069 randerso Added to help debug GeoTools 10.5 issues.
* May partially address Dimensions DR 15463.
* plugin.xml menu entry comnmented out so can't be activated
*
* </pre>
*
* @author randerso
* @version 1.0
*/
public class CoordinateConversionDialog extends CaveJFACEDialog {
private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(CoordinateConversionDialog.class);
private DataManager dataMgr;
private GridLocation gloc;
private ProjectionData awipsProj;
private DecimalFormat df;
private Text lonText;
private Text latText;
private Text awipsXText;
private Text awipsYText;
private Text gfeXText;
private Text gfeYText;
/**
* @param parentShell
* @param dataMgr
*/
public CoordinateConversionDialog(Shell parentShell, DataManager dataMgr) {
super(parentShell);
this.dataMgr = dataMgr;
gloc = this.dataMgr.getParmManager().compositeGridLocation();
awipsProj = gloc.getProjection();
df = new DecimalFormat("###0.####;-###0.####");
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets
* .Shell)
*/
@Override
protected void configureShell(Shell newShell) {
super.configureShell(newShell);
newShell.setText("Coordinate Conversion");
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.viz.ui.dialogs.CaveJFACEDialog#createDialogArea(org.eclipse
* .swt.widgets.Composite)
*/
@Override
protected Control createDialogArea(Composite parent) {
Composite comp = (Composite) super.createDialogArea(parent);
((GridLayout) comp.getLayout()).numColumns = 3;
// listener to validate numeric entry and update computed fields
KeyListener keyListener = new KeyListener() {
@Override
public void keyReleased(KeyEvent e) {
if (e.character != '.') {
Object source = e.getSource();
if ((source == lonText) || (source == latText)) {
updateLonLat();
} else if ((source == awipsXText) || (source == awipsYText)) {
updateAwips();
} else if ((source == gfeXText) || (source == gfeYText)) {
updateGfe();
}
}
}
@Override
public void keyPressed(KeyEvent e) {
if (!Character.isISOControl(e.character)) {
Text source = (Text) e.getSource();
String text = source.getText();
Point selection = source.getSelection();
text = text.substring(0, selection.x) + e.character
+ text.substring(selection.y);
try {
Double.parseDouble(text);
} catch (NumberFormatException e1) {
e.doit = false;
getShell().getDisplay().beep();
}
}
}
};
Label label = new Label(comp, SWT.RIGHT);
GridData layoutData = new GridData(SWT.FILL, SWT.CENTER, true, false);
label.setLayoutData(layoutData);
label.setText("Lon/Lat");
lonText = new Text(comp, SWT.RIGHT | SWT.SINGLE | SWT.BORDER);
layoutData = new GridData(SWT.FILL, SWT.CENTER, true, false);
lonText.setLayoutData(layoutData);
lonText.addKeyListener(keyListener);
latText = new Text(comp, SWT.RIGHT | SWT.SINGLE | SWT.BORDER);
layoutData = new GridData(SWT.FILL, SWT.CENTER, true, false);
latText.setLayoutData(layoutData);
latText.addKeyListener(keyListener);
label = new Label(comp, SWT.RIGHT);
layoutData = new GridData(SWT.FILL, SWT.CENTER, true, false);
label.setLayoutData(layoutData);
label.setText(gloc.getProjection().getProjectionID());
awipsXText = new Text(comp, SWT.RIGHT | SWT.SINGLE | SWT.BORDER);
layoutData = new GridData(SWT.FILL, SWT.CENTER, true, false);
awipsXText.setLayoutData(layoutData);
awipsXText.addKeyListener(keyListener);
awipsYText = new Text(comp, SWT.RIGHT | SWT.SINGLE | SWT.BORDER);
layoutData = new GridData(SWT.FILL, SWT.CENTER, true, false);
awipsYText.setLayoutData(layoutData);
awipsYText.addKeyListener(keyListener);
label = new Label(comp, SWT.RIGHT);
layoutData = new GridData(SWT.FILL, SWT.CENTER, true, false);
label.setLayoutData(layoutData);
label.setText(gloc.getSiteId());
gfeXText = new Text(comp, SWT.RIGHT | SWT.SINGLE | SWT.BORDER);
layoutData = new GridData(SWT.FILL, SWT.CENTER, true, false);
gfeXText.setLayoutData(layoutData);
gfeXText.addKeyListener(keyListener);
gfeYText = new Text(comp, SWT.RIGHT | SWT.SINGLE | SWT.BORDER);
layoutData = new GridData(SWT.FILL, SWT.CENTER, true, false);
gfeYText.setLayoutData(layoutData);
gfeYText.addKeyListener(keyListener);
gfeXText.setText("0");
gfeYText.setText("0");
updateGfe();
return comp;
}
private double getDoubleValue(Text text) {
String s = text.getText();
if (s.isEmpty()) {
return 0;
} else {
return Double.parseDouble(s);
}
}
private void updateLonLat() {
double lon = getDoubleValue(lonText);
double lat = getDoubleValue(latText);
Coordinate lonLat = new Coordinate(lon, lat);
// lonText.setText(df.format(lon));
// latText.setText(df.format(lat));
try {
Coordinate gridCell = MapUtil.latLonToGridCoordinate(lonLat,
PixelOrientation.CENTER, gloc);
gfeXText.setText(df.format(gridCell.x));
gfeYText.setText(df.format(gloc.getNy() - gridCell.y - 1));
} catch (Exception e) {
statusHandler.error(e.getLocalizedMessage(), e);
gfeXText.setText("");
gfeYText.setText("");
}
try {
Coordinate awips = awipsProj.latLonToGridCoordinate(lonLat);
awipsXText.setText(df.format(awips.x));
awipsYText.setText(df.format(awips.y));
} catch (Exception e) {
statusHandler.error(e.getLocalizedMessage(), e);
awipsXText.setText("");
awipsYText.setText("");
}
}
private void updateAwips() {
double x = getDoubleValue(awipsXText);
double y = getDoubleValue(awipsYText);
// awipsXText.setText(df.format(x));
// awipsYText.setText(df.format(y));
Coordinate awips = new Coordinate(x, y);
Coordinate lonLat;
try {
lonLat = awipsProj.gridCoordinateToLatLon(awips);
lonText.setText(df.format(lonLat.x));
latText.setText(df.format(lonLat.y));
try {
Coordinate gridCell = MapUtil.latLonToGridCoordinate(lonLat,
PixelOrientation.CENTER, gloc);
gfeXText.setText(df.format(gridCell.x));
gfeYText.setText(df.format(gloc.getNy() - gridCell.y - 1));
} catch (Exception e) {
statusHandler.error(e.getLocalizedMessage(), e);
gfeXText.setText("");
gfeYText.setText("");
}
} catch (Exception e) {
statusHandler.error(e.getLocalizedMessage(), e);
lonText.setText("");
latText.setText("");
gfeXText.setText("");
gfeYText.setText("");
}
}
private void updateGfe() {
double x = getDoubleValue(gfeXText);
double y = getDoubleValue(gfeYText);
Coordinate gridCell = new Coordinate(x, gloc.getNy() - y - 1);
// gfeXText.setText(df.format(x));
// gfeYText.setText(df.format(y));
Coordinate lonLat = gloc.latLonCenter(gridCell);
lonText.setText(df.format(lonLat.x));
latText.setText(df.format(lonLat.y));
try {
Coordinate awips = awipsProj.latLonToGridCoordinate(lonLat);
awipsXText.setText(df.format(awips.x));
awipsYText.setText(df.format(awips.y));
} catch (Exception e) {
statusHandler.error(e.getLocalizedMessage(), e);
awipsXText.setText("");
awipsYText.setText("");
}
}
}

View file

@ -25,6 +25,7 @@ import org.eclipse.swt.graphics.RGB;
import com.raytheon.uf.viz.core.IGraphicsTarget;
import com.raytheon.uf.viz.core.IGraphicsTarget.LineStyle;
import com.raytheon.uf.viz.core.drawables.IDescriptor;
import com.raytheon.uf.viz.core.drawables.IFont;
import com.raytheon.uf.viz.core.drawables.IRenderable;
import com.raytheon.uf.viz.core.drawables.IWireframeShape;
@ -46,6 +47,9 @@ import com.vividsolutions.jts.geom.Geometry;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* May 5, 2008 chammack Initial creation
* May 15, 2014 #3069 randerso Made labelSpacing settable.
* Fixed label coordinates after ReferencedGeometry
* was made non-destructive.
*
* </pre>
*
@ -63,6 +67,8 @@ public class JTSRenderable implements IRenderable {
private RGB color = ColorUtil.WHITE;
private int labelSpacing = 50;
/**
* @return the color
*/
@ -93,6 +99,10 @@ public class JTSRenderable implements IRenderable {
this.lineWidth = lineWidth;
}
public void setLabelSpacing(int labelSpacing) {
this.labelSpacing = labelSpacing;
}
private float lineWidth = 1.0f;
public JTSRenderable() {
@ -127,17 +137,17 @@ public class JTSRenderable implements IRenderable {
@Override
public void paint(IGraphicsTarget target, PaintProperties paintProps)
throws VizException {
EditToolPaintProperties etpp = (EditToolPaintProperties) paintProps;
IDescriptor descriptor = ((EditToolPaintProperties) paintProps)
.getDescriptor();
if (this.wireframeShape == null) {
this.wireframeShape = target.createWireframeShape(true,
etpp.getDescriptor());
this.wireframeShape = target.createWireframeShape(true, descriptor);
}
if (!this.pendingGeometies.isEmpty()) {
JTSCompiler jtsCompiler = new JTSCompiler(null, wireframeShape,
etpp.getDescriptor());
descriptor);
while (!this.pendingGeometies.isEmpty()) {
Geometry geom = this.pendingGeometies.remove();
jtsCompiler.handle(geom);
@ -146,10 +156,11 @@ public class JTSRenderable implements IRenderable {
String label = (String) geom.getUserData();
double[] coord = new double[2];
int numCoords = geom.getNumPoints();
for (int j = 0; j < numCoords; j += 50) {
for (int j = 0; j < numCoords; j += this.labelSpacing) {
Coordinate c = geom.getCoordinates()[j];
coord[0] = c.x;
coord[1] = c.y;
coord = descriptor.worldToPixel(coord);
this.wireframeShape.addLabel(label, coord);
}
}

View file

@ -117,6 +117,8 @@ import com.vividsolutions.jts.geom.LineString;
* drawing and calculating new grid.
* Aug 08, 2012 #621 dgilling Fix ConcurrentModificationException
* in handling of renderables field.
* May 15, 2014 #3069 randerso Changed to compute contour label spacing variable
* based on subsample setting
*
* </pre>
*
@ -212,7 +214,7 @@ public class ContourTool extends AbstractFreeformTool implements
Point gridSize = gloc.gridSize();
int newX = ((gridSize.x - 1) / subFactor) + 1;
int newY = ((gridSize.y - 1) / subFactor) + 1;
if (newX <= 5 || newY <= 5) {
if ((newX <= 5) || (newY <= 5)) {
int tmpX = gridSize.x / 5;
int tmpY = gridSize.y / 5;
subFactor = Math.min(tmpX, tmpY);
@ -228,14 +230,14 @@ public class ContourTool extends AbstractFreeformTool implements
}
private RemapGrid getToLowRes() {
if (toLowRes == null && currentGrid != null) {
if ((toLowRes == null) && (currentGrid != null)) {
computeRemaps();
}
return toLowRes;
}
private RemapGrid getToHiRes() {
if (toHiRes == null && currentGrid != null) {
if ((toHiRes == null) && (currentGrid != null)) {
computeRemaps();
}
return toHiRes;
@ -319,9 +321,6 @@ public class ContourTool extends AbstractFreeformTool implements
refresh();
}
/**
*
*/
private void replaceCLines(List<CLine> contours) {
clearRenderables();
@ -335,6 +334,7 @@ public class ContourTool extends AbstractFreeformTool implements
JTSRenderable renderable = new JTSRenderable();
renderable.setLineWidth(2.0f);
renderable.setColor(contourColor);
renderable.setLabelSpacing(200 / subSample);
for (CLine contour : contours) {
LineString ls = contour.getLineString();
if (ls == null) {
@ -1141,8 +1141,8 @@ public class ContourTool extends AbstractFreeformTool implements
sumLoc.x += coords.get(i).x;
sumLoc.y += coords.get(i).y;
}
sumLoc.x = sumLoc.x / (end - start + 1);
sumLoc.y = sumLoc.y / (end - start + 1);
sumLoc.x = sumLoc.x / ((end - start) + 1);
sumLoc.y = sumLoc.y / ((end - start) + 1);
return sumLoc;
} else {
int i;
@ -1154,8 +1154,8 @@ public class ContourTool extends AbstractFreeformTool implements
sumLoc.x += coords.get(i).x;
sumLoc.y += coords.get(i).y;
}
sumLoc.x = sumLoc.x / (start - end + 1);
sumLoc.y = sumLoc.y / (start - end + 1);
sumLoc.x = sumLoc.x / ((start - end) + 1);
sumLoc.y = sumLoc.y / ((start - end) + 1);
return sumLoc;
}
}
@ -1182,7 +1182,7 @@ public class ContourTool extends AbstractFreeformTool implements
double distance = line.getCoordinateN(0).distance(
line.getCoordinateN(line.getNumPoints() - 1));
if (distance < 3 * (cellSize.x + cellSize.y) / 2) {
if (distance < ((3 * (cellSize.x + cellSize.y)) / 2)) {
return true;
}
@ -1260,7 +1260,7 @@ public class ContourTool extends AbstractFreeformTool implements
public void addContextMenuItems(IMenuManager menuManager, int x, int y) {
Parm activeParm = dataManager.getSpatialDisplayManager()
.getActivatedParm();
if (activeParm != null
if ((activeParm != null)
&& activeParm.getGridInfo().getGridType()
.equals(GridType.SCALAR)) {
@ -1668,7 +1668,7 @@ public class ContourTool extends AbstractFreeformTool implements
@Override
public void gridDataChanged(ParmID parmId, TimeRange validTime) {
if (currentGrid != null
if ((currentGrid != null)
&& currentGrid.getParm().getParmID().equals(parmId)
&& currentGrid.getGridTime().equals(validTime)) {
initializeContourData(getGrid());
@ -1681,7 +1681,7 @@ public class ContourTool extends AbstractFreeformTool implements
@Override
public void parmInventoryChanged(Parm parm, TimeRange affectedTimeRange) {
if (currentGrid != null
if ((currentGrid != null)
&& parm.getParmID().equals(currentGrid.getParm().getParmID())
&& affectedTimeRange.contains(currentGrid.getGridTime())) {
initializeContourData(getGrid());

View file

@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Common Plug-in
Bundle-SymbolicName: com.raytheon.edex.common
Bundle-Version: 1.12.1174.qualifier
Bundle-Version: 1.14.0
Bundle-Vendor: RAYTHEON
Eclipse-BuddyPolicy: registered, ext, global
Eclipse-RegisterBuddy: com.raytheon.uf.common.serialization
@ -18,7 +18,6 @@ Export-Package: com.raytheon.edex.colormap,
com.raytheon.edex.plugin.factory,
com.raytheon.edex.site,
com.raytheon.edex.subscription,
com.raytheon.edex.topo,
com.raytheon.edex.urifilter,
com.raytheon.edex.util,
com.raytheon.edex.utility

View file

@ -1,178 +0,0 @@
/**
* 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.edex.topo;
import org.geotools.coverage.grid.GeneralGridEnvelope;
import org.geotools.coverage.grid.GridGeometry2D;
import org.geotools.geometry.GeneralEnvelope;
import org.geotools.referencing.CRS;
import org.geotools.referencing.operation.DefaultMathTransformFactory;
import org.opengis.metadata.spatial.PixelOrientation;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
import com.raytheon.uf.common.geospatial.CRSCache;
import com.raytheon.uf.common.geospatial.ISpatialObject;
import com.raytheon.uf.common.geospatial.MapUtil;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Polygon;
public class GridLocation implements ISpatialObject {
private CoordinateReferenceSystem crsObject;
private Polygon geometry;
private Integer nx;
private Integer ny;
private String crsWKT;
private Coordinate extent;
private Coordinate origin;
private ProjectionData projection;
/**
* @param data
* @param gridSize
* @param domainOrigin
* @param domainExtent
*/
public GridLocation(ProjectionData proj, java.awt.Point gridSize,
Coordinate domainOrigin, Coordinate domainExtent) {
try {
this.nx = gridSize.x;
this.ny = gridSize.y;
this.projection = proj;
this.origin = domainOrigin;
this.extent = domainExtent;
this.crsObject = proj.getCRS();
this.crsWKT = this.crsObject.toWKT();
// transform the projection corner points to CRS units
MathTransform mt = MapUtil.getTransformFromLatLon(this.crsObject);
double[] output = new double[4];
mt.transform(
new double[] { proj.getLatLonLL().x, proj.getLatLonLL().y,
proj.getLatLonUR().x, proj.getLatLonUR().y }, 0,
output, 0, 2);
// create a grid geometry for the projection
GeneralEnvelope ge = new GeneralEnvelope(2);
ge.setCoordinateReferenceSystem(this.crsObject);
ge.setRange(0, Math.min(output[0], output[2]),
Math.max(output[0], output[2]));
ge.setRange(1, Math.min(output[1], output[3]),
Math.max(output[1], output[3]));
GeneralGridEnvelope gr = new GeneralGridEnvelope(new int[] {
proj.getGridPointLL().x, proj.getGridPointLL().y },
new int[] { proj.getGridPointUR().x + 1,
proj.getGridPointUR().y + 1 }, false);
GridGeometry2D projGeom = new GridGeometry2D(gr, ge);
DefaultMathTransformFactory dmtf = new DefaultMathTransformFactory();
double[] latLon = new double[8];
// transform the grid corners from grid coordinates to CRS units
// need to adjust for the fact that AWIPS considers 1,1 to be in
// lower left and GeoTools considers 1,1 to be in upper left
Coordinate ll = new Coordinate(domainOrigin.x,
proj.getGridPointUR().y - domainOrigin.y
+ proj.getGridPointLL().y);
Coordinate ur = new Coordinate(domainOrigin.x + domainExtent.x,
ll.y - domainExtent.y);
mt.transform(new double[] { ll.x, ll.y, ur.x, ur.y }, 0, output, 0,
2);
mt = projGeom.getGridToCRS(PixelOrientation.UPPER_LEFT);
output = new double[4];
mt.transform(new double[] { ll.x, ll.y, ur.x, ur.y }, 0, output, 0,
2);
// construct the grid geometry that covers the GFE grid
ge.setRange(0, Math.min(output[0], output[2]),
Math.max(output[0], output[2]));
ge.setRange(1, Math.min(output[1], output[3]),
Math.max(output[1], output[3]));
GridGeometry2D gridGeom = new GridGeometry2D(
new GeneralGridEnvelope(new int[] { 0, 0 }, new int[] {
this.nx, this.ny }, false), ge);
// set up the transform from grid coordinates to lon/lat
mt = dmtf.createConcatenatedTransform(
gridGeom.getGridToCRS(PixelOrientation.CENTER),
MapUtil.getTransformToLatLon(crsObject));
// transform grid corner points to Lat/Lon
mt.transform(new double[] { -1.0, this.ny - 1, -1.0, -1.0,
this.nx - 1, -1.0, this.nx - 1, this.ny - 1 }, 0, latLon,
0, 4);
Coordinate[] corners = new Coordinate[] {
MapUtil.getCoordinate(latLon[0], latLon[1]),
MapUtil.getCoordinate(latLon[2], latLon[3]),
MapUtil.getCoordinate(latLon[4], latLon[5]),
MapUtil.getCoordinate(latLon[6], latLon[7]),
MapUtil.getCoordinate(latLon[0], latLon[1]) };
this.geometry = MapUtil.getPolygon(corners);
// this.geometry = new Polygon(new LinearRing[] { shell });
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public CoordinateReferenceSystem getCrs() {
if (crsObject == null) {
try {
crsObject = CRSCache.getInstance()
.getCoordinateReferenceSystem(crsWKT);
} catch (FactoryException e) {
crsObject = null;
}
}
return crsObject;
}
@Override
public Polygon getGeometry() {
return geometry;
}
@Override
public Integer getNx() {
return nx;
}
@Override
public Integer getNy() {
return ny;
}
}

View file

@ -1,282 +0,0 @@
/**
* 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.edex.topo;
import java.awt.Point;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import com.raytheon.uf.common.geospatial.MapUtil;
import com.vividsolutions.jts.geom.Coordinate;
public class ProjectionData {
private static float COMPARISON_THRESHOLD = 0.005f;
public static enum ProjectionType {
NONE, LAMBERT_CONFORMAL, MERCATOR, POLAR_STEREOGRAPHIC, LATLON
};
private String projectionID;
private ProjectionType projectionType;
private Coordinate latLonLL;
private Coordinate latLonUR;
private Coordinate latLonOrigin;
private double stdParallelOne;
private double stdParallelTwo;
private Point gridPointLL;
private Point gridPointUR;
private double latIntersect;
private double lonCenter;
private double lonOrigin;
public ProjectionData() {
latLonLL = new Coordinate();
latLonUR = new Coordinate();
latLonOrigin = new Coordinate();
gridPointLL = new Point();
gridPointUR = new Point();
}
public ProjectionData(String projID, int projType, Coordinate latLonLL,
Coordinate latLonUR, Coordinate latLonOrig, float stdPar1,
float stdPar2, Point gridLL, Point gridUR, float latInt,
float lonCenter, float lonOrig) {
this();
this.projectionID = projID;
this.projectionType = ProjectionType.values()[projType];
this.latLonLL = latLonLL;
this.latLonUR = latLonUR;
this.latLonOrigin = latLonOrig;
this.stdParallelOne = stdPar1;
this.stdParallelTwo = stdPar2;
this.gridPointLL = gridLL;
this.gridPointUR = gridUR;
this.latIntersect = latInt;
this.lonCenter = lonCenter;
this.lonOrigin = lonOrig;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
String result = "{";
result += projectionType + ", ";
result += latLonLL + ", ";
result += latLonUR + ", ";
result += latLonOrigin + ", ";
result += stdParallelOne + ", ";
result += stdParallelTwo + ", ";
result += gridPointLL + ", ";
result += gridPointUR + ", ";
result += latIntersect + ", ";
result += lonCenter + ", ";
result += lonOrigin;
result += "}";
return result;
}
/**
* @return
*/
public CoordinateReferenceSystem getCRS() {
// construct the appropriate CRS based on the projection type
CoordinateReferenceSystem crs = null;
switch (this.projectionType) {
case LAMBERT_CONFORMAL:
crs = MapUtil.constructLambertConformal(MapUtil.AWIPS_EARTH_RADIUS,
MapUtil.AWIPS_EARTH_RADIUS, this.stdParallelOne,
this.stdParallelTwo, this.latLonOrigin.x);
break;
case MERCATOR:
crs = MapUtil.constructMercator(MapUtil.AWIPS_EARTH_RADIUS,
MapUtil.AWIPS_EARTH_RADIUS, this.stdParallelOne,
this.lonCenter);
break;
case POLAR_STEREOGRAPHIC:
crs = MapUtil.constructNorthPolarStereo(MapUtil.AWIPS_EARTH_RADIUS,
MapUtil.AWIPS_EARTH_RADIUS, 60.0, this.lonOrigin);
break;
case LATLON:
crs = MapUtil.LATLON_PROJECTION;
break;
case NONE:
default:
System.out.println("ERROR: unknown projection type: "
+ this.projectionType);
}
return crs;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof ProjectionData)) {
return false;
}
ProjectionData rhs = (ProjectionData) obj;
if (!this.getProjectionType().equals(rhs.getProjectionType())) {
return false;
}
if (Math.abs(this.latLonLL.y - rhs.latLonLL.y) > COMPARISON_THRESHOLD
|| Math.abs(this.latLonLL.x - rhs.latLonLL.x) > COMPARISON_THRESHOLD
|| Math.abs(this.latLonUR.y - rhs.latLonUR.y) > COMPARISON_THRESHOLD
|| Math.abs(this.latLonLL.x - rhs.latLonLL.x) > COMPARISON_THRESHOLD) {
return false;
}
// specific projection comparisons
switch (this.projectionType) {
case LAMBERT_CONFORMAL:
return (Math.abs(this.latLonOrigin.y - rhs.latLonOrigin.y) < COMPARISON_THRESHOLD
|| Math.abs(this.latLonOrigin.x - rhs.latLonOrigin.x) < COMPARISON_THRESHOLD
|| Math.abs(this.stdParallelOne - rhs.stdParallelOne) < COMPARISON_THRESHOLD || Math
.abs(this.stdParallelTwo - rhs.stdParallelTwo) < COMPARISON_THRESHOLD);
case POLAR_STEREOGRAPHIC:
return (Math.abs(this.lonOrigin - rhs.lonOrigin) < COMPARISON_THRESHOLD);
case MERCATOR:
return (Math.abs(this.lonCenter - rhs.lonCenter) < COMPARISON_THRESHOLD);
case LATLON:
return true;
default:
return false;
}
}
public String getProjectionID() {
return projectionID;
}
public ProjectionType getProjectionType() {
return projectionType;
}
public Coordinate getLatLonLL() {
return latLonLL;
}
public Coordinate getLatLonUR() {
return latLonUR;
}
public Coordinate getLatLonOrigin() {
return latLonOrigin;
}
public double getStdParallelOne() {
return stdParallelOne;
}
public double getStdParallelTwo() {
return stdParallelTwo;
}
public Point getGridPointLL() {
return gridPointLL;
}
public Point getGridPointUR() {
return gridPointUR;
}
public double getLatIntersect() {
return latIntersect;
}
public double getLonCenter() {
return lonCenter;
}
public double getLonOrigin() {
return lonOrigin;
}
public void setProjectionID(String projectionID) {
this.projectionID = projectionID;
}
public void setProjectionType(ProjectionType projectionType) {
this.projectionType = projectionType;
}
public void setLatLonLL(Coordinate latLonLL) {
this.latLonLL = latLonLL;
}
public void setLatLonUR(Coordinate latLonUR) {
this.latLonUR = latLonUR;
}
public void setLatLonOrigin(Coordinate latLonOrigin) {
this.latLonOrigin = latLonOrigin;
}
public void setStdParallelOne(double stdParallelOne) {
this.stdParallelOne = stdParallelOne;
}
public void setStdParallelTwo(double stdParallelTwo) {
this.stdParallelTwo = stdParallelTwo;
}
public void setGridPointLL(Point gridPointLL) {
this.gridPointLL = gridPointLL;
}
public void setGridPointUR(Point gridPointUR) {
this.gridPointUR = gridPointUR;
}
public void setLatIntersect(double latIntersect) {
this.latIntersect = latIntersect;
}
public void setLonCenter(double lonCenter) {
this.lonCenter = lonCenter;
}
public void setLonOrigin(double lonOrigin) {
this.lonOrigin = lonOrigin;
}
}

View file

@ -37,13 +37,13 @@ import org.hibernate.criterion.Restrictions;
import com.raytheon.edex.plugin.gfe.smartinit.SmartInitRecordPK.State;
import com.raytheon.uf.edex.database.cluster.ClusterLockUtils;
import com.raytheon.uf.edex.database.cluster.ClusterTask;
import com.raytheon.uf.edex.database.cluster.ClusterLockUtils.LockState;
import com.raytheon.uf.edex.database.cluster.ClusterTask;
import com.raytheon.uf.edex.database.dao.CoreDao;
import com.raytheon.uf.edex.database.dao.DaoConfig;
/**
* TODO Add Description
* SmartInit Transactions
*
* <pre>
*
@ -51,6 +51,8 @@ import com.raytheon.uf.edex.database.dao.DaoConfig;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Apr 12, 2010 njensen Initial creation
* May 20, 2014 #3069 randerso Added validTime to sort order when
* choosing next smartInit to run
*
* </pre>
*
@ -104,8 +106,8 @@ public class SmartInitTransactions {
LockOptions.UPGRADE);
// double check to make sure another process hasn't
// already grabbed it and the run didn't finish
if (record != null
&& record.getInsertTime().getTime() < timeOutCheck) {
if ((record != null)
&& (record.getInsertTime().getTime() < timeOutCheck)) {
logger.info("Running smartInit " + record.getId()
+ " timed out. Rerunning smartInit.");
record.setInsertTime(new Date(System
@ -120,8 +122,9 @@ public class SmartInitTransactions {
// query the pending table for available inits
Criteria pendingCrit = sess.createCriteria(SmartInitRecord.class);
pendingCrit.addOrder(Order.asc("priority")).addOrder(
Order.asc("insertTime"));
pendingCrit.addOrder(Order.asc("priority"))
.addOrder(Order.asc("insertTime"))
.addOrder(Order.asc("id.validTime"));
long pendingTimeRest = System.currentTimeMillis()
- pendingInitMinTimeMillis;
@ -151,8 +154,8 @@ public class SmartInitTransactions {
record.getId(), LockOptions.UPGRADE);
// double check its still valid
if (record != null
&& record.getInsertTime().getTime() <= pendingTimeRest) {
if ((record != null)
&& (record.getInsertTime().getTime() <= pendingTimeRest)) {
sess.delete(record);
// can we update primary key in place?? or do we need to
// delete then add

View file

@ -20,7 +20,6 @@
package com.raytheon.uf.common.dataplugin.gfe.config;
import java.awt.Point;
import java.util.HashMap;
import javax.persistence.Column;
import javax.persistence.Embeddable;
@ -29,14 +28,15 @@ import javax.persistence.Enumerated;
import javax.persistence.Transient;
import org.geotools.coverage.grid.GeneralGridEnvelope;
import org.geotools.coverage.grid.GridGeometry2D;
import org.geotools.geometry.GeneralEnvelope;
import org.geotools.referencing.operation.DefaultMathTransformFactory;
import org.geotools.referencing.operation.builder.GridToEnvelopeMapper;
import org.opengis.metadata.spatial.PixelOrientation;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.datum.PixelInCell;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.NoninvertibleTransformException;
import org.opengis.referencing.operation.TransformException;
import com.raytheon.uf.common.geospatial.MapUtil;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
@ -58,6 +58,9 @@ import com.vividsolutions.jts.geom.Coordinate;
* 08/06/13 #1571 randerso Added hibernate annotations
* Removed constructor with int for ProjectionType
* 10/22/13 #2361 njensen Remove XML annotations
* 05/14/2014 #3069 randerso Changed to store math transforms and CRS instead of
* GridGeometry2D since GeoTools now changes the supplied
* math transform when creating GridGeometry2D
*
* </pre>
*
@ -145,22 +148,13 @@ public class ProjectionData {
private CoordinateReferenceSystem crs;
@Transient
private GridGeometry2D gridGeometry;
private MathTransform gridToLatLon;
@Transient
private MathTransform crsToLatLon;
private MathTransform latLonToGrid;
@Transient
private MathTransform latLonToCrs;
@Transient
private HashMap<PixelOrientation, MathTransform> gridToLatLon;
@Transient
private HashMap<PixelOrientation, MathTransform> latLonToGrid;
@Transient
private HashMap<PixelOrientation, MathTransform> gridToCrs;
private MathTransform gridToCrs;
@Transient
private boolean initialized;
@ -175,10 +169,6 @@ public class ProjectionData {
gridPointLL = new Point();
gridPointUR = new Point();
gridToLatLon = new HashMap<PixelOrientation, MathTransform>();
latLonToGrid = new HashMap<PixelOrientation, MathTransform>();
gridToCrs = new HashMap<PixelOrientation, MathTransform>();
initialized = false;
}
@ -255,24 +245,25 @@ public class ProjectionData {
ge.setRange(1, Math.min(output[1], output[3]),
Math.max(output[1], output[3]));
// NOTE: the LL + 1 is a kludge to work around an apparent geotools
// issue
// GeoTools 10.5 kludge to say upper right is non-inclusive
GeneralGridEnvelope gr = new GeneralGridEnvelope(new int[] {
getGridPointLL().x + 1, getGridPointLL().y + 1 },
new int[] { getGridPointUR().x, getGridPointUR().y }, true);
getGridPointLL().x, getGridPointLL().y }, new int[] {
getGridPointUR().x, getGridPointUR().y }, false);
// GeoTools 10.5 kludge to use CELL_CORNER instead of CELL_CENTER
GridToEnvelopeMapper mapper = new GridToEnvelopeMapper();
mapper.setEnvelope(ge);
mapper.setGridRange(gr);
mapper.setPixelAnchor(PixelInCell.CELL_CENTER);
mapper.setPixelAnchor(PixelInCell.CELL_CORNER);
mapper.setReverseAxis(new boolean[] { false, false });
mt = mapper.createTransform();
gridToCrs = mapper.createTransform();
gridGeometry = new GridGeometry2D(PixelInCell.CELL_CORNER, mt, ge,
null);
MathTransform crsToLatLon = MapUtil.getTransformToLatLon(getCrs());
crsToLatLon = MapUtil.getTransformToLatLon(getCrs());
latLonToCrs = MapUtil.getTransformFromLatLon(getCrs());
DefaultMathTransformFactory dmtf = new DefaultMathTransformFactory();
gridToLatLon = dmtf.createConcatenatedTransform(gridToCrs,
crsToLatLon);
latLonToGrid = getGridToLatLon().inverse();
initialized = true;
@ -388,71 +379,96 @@ public class ProjectionData {
}
/**
* Return the lat/lon of the specified corner or center of a grid cell
* Return the lat/lon of the specified grid cell
*
* @param gridCoord
* coordinates of the grid cell
* @param orientation
* desired corner or center
* @return the lat/lon
* @throws FactoryException
* @throws TransformException
*/
public Coordinate gridCoordinateToLatLon(Coordinate gridCoord,
PixelOrientation orientation) {
public Coordinate gridCoordinateToLatLon(Coordinate gridCoord)
throws FactoryException, TransformException {
Coordinate latLon = new Coordinate();
MathTransform mt = gridToLatLon.get(orientation);
try {
if (mt == null) {
init();
DefaultMathTransformFactory dmtf = new DefaultMathTransformFactory();
mt = dmtf.createConcatenatedTransform(
gridGeometry.getGridToCRS(orientation), crsToLatLon);
gridToLatLon.put(orientation, mt);
}
double[] output = new double[2];
mt.transform(new double[] { gridCoord.x, gridCoord.y }, 0, output,
0, 1);
latLon.x = output[0];
latLon.y = output[1];
} catch (Exception e) {
statusHandler.error(
"Error computing grid coordinate to lat/lon transform", e);
}
MathTransform mt = getGridToLatLon();
double[] output = new double[2];
mt.transform(new double[] { gridCoord.x, gridCoord.y }, 0, output, 0, 1);
latLon.x = output[0];
latLon.y = output[1];
return latLon;
}
/**
* Return the math transform from grid coordinate to the specified corner or
* center lat/lon
* Return the grid coordinate of the specified lat/lon
*
* @param orientation
* desired corner or center
* @return the transform
* @param latLon
* lat/lon to be converted
* @return the grid coordinate
* @throws FactoryException
* @throws TransformException
*/
public MathTransform getGridToCrs(PixelOrientation orientation) {
MathTransform mt = gridToCrs.get(orientation);
if (mt == null) {
init();
mt = gridGeometry.getGridToCRS(orientation);
gridToCrs.put(orientation, mt);
}
return mt;
public Coordinate latLonToGridCoordinate(Coordinate latLon)
throws FactoryException, TransformException {
Coordinate gridCoord = new Coordinate();
MathTransform mt = getLatLonToGrid();
double[] output = new double[2];
mt.transform(new double[] { latLon.x, latLon.y }, 0, output, 0, 1);
gridCoord.x = output[0];
gridCoord.y = output[1];
return gridCoord;
}
/**
* Convert a grid cell coordinate to the native CRS coordinate of this
* projection
* Return the math transform from grid coordinate to lat/lon
*
* @return the transform
* @throws FactoryException
*/
public MathTransform getGridToLatLon() throws FactoryException {
if (gridToLatLon == null) {
init();
}
return gridToLatLon;
}
/**
* Return the math transform from lat/lon to grid coordinate
*
* @return the transform
* @throws FactoryException
* @throws NoninvertibleTransformException
*/
public MathTransform getLatLonToGrid() throws FactoryException,
NoninvertibleTransformException {
if (latLonToGrid == null) {
init();
}
return latLonToGrid;
}
/**
* Return the math transform from grid coordinate to the native CRS
*
* @return the transform
*/
public MathTransform getGridToCrs() {
if (gridToCrs == null) {
init();
}
return gridToCrs;
}
/**
* Convert a grid cell coordinate to the native CRS of this projection
*
* @param gridCoord
* grid cell coordinate
* @param orientation
* desired corner or center of the grid cell
* @return native CRS coordinate
*/
public Coordinate gridCoordinateToCrs(Coordinate gridCoord,
PixelOrientation orientation) {
public Coordinate gridCoordinateToCrs(Coordinate gridCoord) {
Coordinate crsCoordinate = new Coordinate();
MathTransform mt = getGridToCrs(orientation);
MathTransform mt = getGridToCrs();
try {
double[] output = new double[2];
mt.transform(new double[] { gridCoord.x, gridCoord.y }, 0, output,

View file

@ -100,6 +100,9 @@ import com.vividsolutions.jts.simplify.TopologyPreservingSimplifier;
* 09/30/13 #2333 mschenke Added method to construct from {@link IGridGeometryProvider}
* 10/22/13 #2361 njensen Remove XML annotations
* 04/11/14 #2947 bsteffen Remove ISpatialObject constructor.
* 05/14/2014 #3069 randerso Changed to store math transforms and CRS instead of
* GridGeometry2D since GeoTools now changes the supplied
* math transform when creating GridGeometry2D
*
*
*
@ -121,7 +124,7 @@ public class GridLocation extends PersistableDataObject<String> implements
* reshaped using numpy for performance
*
*/
private static class PythonNumpyLatLonGrid implements INumpyable {
static class PythonNumpyLatLonGrid implements INumpyable {
private float[] data;
public PythonNumpyLatLonGrid(int nx, int ny, float[] data) {
@ -276,10 +279,8 @@ public class GridLocation extends PersistableDataObject<String> implements
Coordinate ur = new Coordinate(this.origin.x + this.extent.x,
this.origin.y + this.extent.y);
Coordinate llCrs = this.projection.gridCoordinateToCrs(ll,
PixelOrientation.CENTER);
Coordinate urCrs = this.projection.gridCoordinateToCrs(ur,
PixelOrientation.CENTER);
Coordinate llCrs = this.projection.gridCoordinateToCrs(ll);
Coordinate urCrs = this.projection.gridCoordinateToCrs(ur);
// construct the grid geometry that covers the GFE grid
GeneralEnvelope ge = new GeneralEnvelope(2);
@ -289,29 +290,29 @@ public class GridLocation extends PersistableDataObject<String> implements
ge.setRange(1, Math.min(llCrs.y, urCrs.y),
Math.max(llCrs.y, urCrs.y));
// GeoTools 10.5 kludge to use nx-1, ny-1 non-inclusive
GeneralGridEnvelope gr = new GeneralGridEnvelope(
new int[] { 1, 1 }, new int[] { this.nx, this.ny }, false);
new int[] { 0, 0 }, new int[] { this.nx - 1, this.ny - 1 },
false);
// GeoTools 10.5 kludge to use CELL_CORNER instead of CELL_CENTER
GridToEnvelopeMapper mapper = new GridToEnvelopeMapper();
mapper.setEnvelope(ge);
mapper.setGridRange(gr);
mapper.setPixelAnchor(PixelInCell.CELL_CENTER);
mapper.setReverseAxis(new boolean[] { false, false });
MathTransform mt = mapper.createTransform();
GridGeometry2D gridGeom = new GridGeometry2D(
PixelInCell.CELL_CORNER, mt, ge, null);
mapper.setPixelAnchor(PixelInCell.CELL_CORNER);
mapper.setReverseAxis(new boolean[] { false, true });
MathTransform gridToCrs = mapper.createTransform();
// set up the transform from grid coordinates to lon/lat
DefaultMathTransformFactory dmtf = new DefaultMathTransformFactory();
mt = dmtf.createConcatenatedTransform(
gridGeom.getGridToCRS(PixelOrientation.UPPER_LEFT),
MapUtil.getTransformToLatLon(crsObject));
MathTransform gridToLatLon = dmtf.createConcatenatedTransform(
gridToCrs, MapUtil.getTransformToLatLon(crsObject));
// transform grid corner points to Lat/Lon
double[] latLon = new double[8];
mt.transform(new double[] { 0, this.ny, 0, 0, this.nx, 0, this.nx,
this.ny }, 0, latLon, 0, 4);
double[] gridCells = new double[] { -0.5, -0.5, -0.5,
this.ny - 0.5, this.nx - 0.5, this.ny - 0.5, this.nx - 0.5,
-0.5 };
gridToLatLon.transform(gridCells, 0, latLon, 0, 4);
Coordinate[] corners = new Coordinate[] {
MapUtil.getCoordinate(latLon[0], latLon[1]),
@ -700,9 +701,7 @@ public class GridLocation extends PersistableDataObject<String> implements
public String toString() {
String s = "[SiteID =" + siteId + ",ProjID="
+ getCrs().getName().getCode() + ",gridSize=(" + nx + ',' + ny
+ "),loc=" + this.geometry.getGeometryType();
// if (proj())
// s += "," + proj()->pdata();
+ "), loc=[o=" + this.origin + ", e=" + this.extent + "]";
s += ']';
return s;
}
@ -1008,43 +1007,56 @@ public class GridLocation extends PersistableDataObject<String> implements
// new Coordinate(9, 9), "CST6CDT");
GridLocation gloc = new GridLocation("OAX", grid211,
new Point(145, 145), new Coordinate(45.0, 30.0),
new Coordinate(9, 9), "CST6CDT");
new Point(417, 289), new Coordinate(41.0, 29.0),
new Coordinate(13, 9), "CST6CDT");
System.out.println(gloc.getSiteId());
Coordinate gridCoord = new Coordinate();
Coordinate latLon = new Coordinate();
PixelOrientation orientation = PixelOrientation.CENTER;
gridCoord.x = 0;
gridCoord.y = 0;
latLon = MapUtil.gridCoordinateToLatLon(gridCoord, orientation, gloc);
System.out.println(gridCoord.x + "," + gridCoord.y + " " + latLon);
System.out.println("geometry: " + gloc.getGeometry());
gridCoord.x = 0;
gridCoord.y = gloc.getNy() - 1;
latLon = MapUtil.gridCoordinateToLatLon(gridCoord, orientation, gloc);
System.out.println(gridCoord.x + "," + gridCoord.y + " " + latLon);
try {
gridCoord.x = 0;
gridCoord.y = 0;
latLon = MapUtil.gridCoordinateToLatLon(gridCoord,
PixelOrientation.CENTER, gloc);
System.out.println(gridCoord.x + "," + gridCoord.y + " " + latLon);
gridCoord.x = gloc.getNx() - 1;
gridCoord.y = gloc.getNy() - 1;
latLon = MapUtil.gridCoordinateToLatLon(gridCoord, orientation, gloc);
System.out.println(gridCoord.x + "," + gridCoord.y + " " + latLon);
gridCoord.x = 0;
gridCoord.y = gloc.getNy() - 1;
latLon = MapUtil.gridCoordinateToLatLon(gridCoord,
PixelOrientation.CENTER, gloc);
System.out.println(gridCoord.x + "," + gridCoord.y + " " + latLon);
gridCoord.x = gloc.getNx() - 1;
gridCoord.y = 0;
latLon = MapUtil.gridCoordinateToLatLon(gridCoord, orientation, gloc);
System.out.println(gridCoord.x + "," + gridCoord.y + " " + latLon);
gridCoord.x = gloc.getNx() - 1;
gridCoord.y = gloc.getNy() - 1;
latLon = MapUtil.gridCoordinateToLatLon(gridCoord,
PixelOrientation.CENTER, gloc);
System.out.println(gridCoord.x + "," + gridCoord.y + " " + latLon);
PythonNumpyLatLonGrid latLonGrid = gloc.getLatLonGrid();
float[] data = (float[]) latLonGrid.getNumpy()[0];
for (int x = 0; x < gloc.getNx(); x++) {
for (int y = 0; y < gloc.getNy(); y++) {
int idx = 2 * ((x * gloc.ny) + y);
float lon = data[idx];
float lat = data[idx + 1];
System.out.println(x + "," + y + " " + lon + ", " + lat);
gridCoord.x = gloc.getNx() - 1;
gridCoord.y = 0;
latLon = MapUtil.gridCoordinateToLatLon(gridCoord,
PixelOrientation.CENTER, gloc);
System.out.println(gridCoord.x + "," + gridCoord.y + " " + latLon);
GridGeometry2D gridGeometry = MapUtil.getGridGeometry(gloc);
System.out.println(gridGeometry.getEnvelope2D().toString());
System.out.println(gridGeometry.toString());
PythonNumpyLatLonGrid latLonGrid = gloc.getLatLonGrid();
float[] data = (float[]) latLonGrid.getNumpy()[0];
for (int x = 0; x < gloc.getNx(); x++) {
for (int y = 0; y < gloc.getNy(); y++) {
int idx = 2 * ((x * gloc.ny) + y);
float lon = data[idx];
float lat = data[idx + 1];
System.out.println(x + "," + y + " " + lon + ", " + lat);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}

View file

@ -0,0 +1,120 @@
/**
* 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.dataplugin.gfe.db.objects;
import java.awt.Point;
import org.geotools.coverage.grid.GridGeometry2D;
import org.opengis.metadata.spatial.PixelOrientation;
import com.raytheon.uf.common.dataplugin.gfe.config.ProjectionData;
import com.raytheon.uf.common.dataplugin.gfe.config.ProjectionData.ProjectionType;
import com.raytheon.uf.common.dataplugin.gfe.db.objects.GridLocation.PythonNumpyLatLonGrid;
import com.raytheon.uf.common.geospatial.MapUtil;
import com.vividsolutions.jts.geom.Coordinate;
/**
* GridLocation unit test
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* May 20, 2014 #3069 randerso Initial creation
*
* </pre>
*
* @author randerso
* @version 1.0
*/
public class GridLocationTest {
/**
* @param args
*/
public static void main(String[] args) {
ProjectionData grid211 = new ProjectionData("Grid211",
ProjectionType.LAMBERT_CONFORMAL, new Coordinate(-133.459,
12.190), new Coordinate(-49.385, 57.290),
new Coordinate(-95.0, 25.0), 25.0f, 25.0f, new Point(1, 1),
new Point(93, 65), 0.0f, 0.0f, 0.0f);
// GridLocation gloc = new GridLocation("ABR", grid211,
// new Point(145, 145), new Coordinate(45.0, 35.0),
// new Coordinate(9, 9), "CST6CDT");
GridLocation gloc = new GridLocation("OAX", grid211,
new Point(417, 289), new Coordinate(41.0, 29.0),
new Coordinate(13, 9), "CST6CDT");
System.out.println(gloc.getSiteId());
Coordinate gridCoord = new Coordinate();
Coordinate latLon = new Coordinate();
System.out.println("geometry: " + gloc.getGeometry());
try {
gridCoord.x = 0;
gridCoord.y = 0;
latLon = MapUtil.gridCoordinateToLatLon(gridCoord,
PixelOrientation.CENTER, gloc);
System.out.println(gridCoord.x + "," + gridCoord.y + " " + latLon);
gridCoord.x = 0;
gridCoord.y = gloc.getNy() - 1;
latLon = MapUtil.gridCoordinateToLatLon(gridCoord,
PixelOrientation.CENTER, gloc);
System.out.println(gridCoord.x + "," + gridCoord.y + " " + latLon);
gridCoord.x = gloc.getNx() - 1;
gridCoord.y = gloc.getNy() - 1;
latLon = MapUtil.gridCoordinateToLatLon(gridCoord,
PixelOrientation.CENTER, gloc);
System.out.println(gridCoord.x + "," + gridCoord.y + " " + latLon);
gridCoord.x = gloc.getNx() - 1;
gridCoord.y = 0;
latLon = MapUtil.gridCoordinateToLatLon(gridCoord,
PixelOrientation.CENTER, gloc);
System.out.println(gridCoord.x + "," + gridCoord.y + " " + latLon);
GridGeometry2D gridGeometry = MapUtil.getGridGeometry(gloc);
System.out.println(gridGeometry.getEnvelope2D().toString());
System.out.println(gridGeometry.toString());
PythonNumpyLatLonGrid latLonGrid = gloc.getLatLonGrid();
float[] data = (float[]) latLonGrid.getNumpy()[0];
for (int x = 0; x < gloc.getNx(); x++) {
for (int y = 0; y < gloc.getNy(); y++) {
int idx = 2 * ((x * gloc.ny) + y);
float lon = data[idx];
float lat = data[idx + 1];
System.out.println(x + "," + y + " " + lon + ", " + lat);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

View file

@ -90,6 +90,9 @@ import com.vividsolutions.jts.geom.Coordinate;
* Aug 06, 2013 2235 bsteffen Added Caching version of TopoQuery.
* Feb 10, 2014 2788 randerso Removed override of CRS from Topo file.
* Fixed handling of fill values (missing data)
* May 19, 2014 3069 randerso Changed to store math transforms and CRS instead of
* GridGeometry2D since GeoTools now changes the supplied
* math transform when creating GridGeometry2D
*
* </pre>
*
@ -149,11 +152,13 @@ public class TopoQuery {
protected Rectangle worldRect;
private GridGeometry2D worldGeomPM;
// private GridGeometry2D worldGeomPM;
private MathTransform worldToCRSPM;
private MathTransform worldToLLPM;
private GridGeometry2D worldGeomDL;
// private GridGeometry2D worldGeomDL;
private MathTransform worldToCRSDL;
private MathTransform llToWorldPM;
@ -163,6 +168,10 @@ public class TopoQuery {
private int numLevels;
private CoordinateReferenceSystem crsPM;
private CoordinateReferenceSystem crsDL;
TopoQuery(File hdf5File) throws TopoException {
this(hdf5File, 0);
}
@ -197,17 +206,17 @@ public class TopoQuery {
worldRect = new Rectangle(0, 0, width, height);
// construct the grid geometry that covers the topo grid
CoordinateReferenceSystem crs = CRSCache.getInstance()
.getCoordinateReferenceSystem(crsString);
crsPM = CRSCache.getInstance().getCoordinateReferenceSystem(
crsString);
double[] input = new double[] { ulLon, ulLat, lrLon, lrLat };
double[] output = new double[4];
MathTransform llToCrsPM = MapUtil.getTransformFromLatLon(crs);
MathTransform llToCrsPM = MapUtil.getTransformFromLatLon(crsPM);
llToCrsPM.transform(input, 0, output, 0, 2);
GeneralEnvelope ge = new GeneralEnvelope(2);
ge.setCoordinateReferenceSystem(crs);
ge.setCoordinateReferenceSystem(crsPM);
ge.setRange(0, output[0], output[2]);
ge.setRange(1, output[3], output[1]);
@ -219,29 +228,24 @@ public class TopoQuery {
mapper.setGridRange(gr);
mapper.setPixelAnchor(PixelInCell.CELL_CENTER);
mapper.setReverseAxis(new boolean[] { false, true });
MathTransform mt = mapper.createTransform();
worldGeomPM = new GridGeometry2D(PixelInCell.CELL_CORNER, mt, ge,
null);
worldToCRSPM = mapper.createTransform();
// set up the transform from grid coordinates to lon/lat
MathTransform worldToCRSPM = worldGeomPM
.getGridToCRS(PixelOrientation.UPPER_LEFT);
MathTransform crsToLL = MapUtil.getTransformToLatLon(crs);
MathTransform crsToLL = MapUtil.getTransformToLatLon(crsPM);
worldToLLPM = dmtf.createConcatenatedTransform(worldToCRSPM,
crsToLL);
llToWorldPM = worldToLLPM.inverse();
crs = MapUtil.constructEquidistantCylindrical(
crsDL = MapUtil.constructEquidistantCylindrical(
MapUtil.AWIPS_EARTH_RADIUS, MapUtil.AWIPS_EARTH_RADIUS,
180, 0);
input = new double[] { 180 + ulLon, ulLat, 180 + lrLon, lrLat };
MathTransform llToCrsDL = MapUtil.getTransformFromLatLon(crs);
MathTransform llToCrsDL = MapUtil.getTransformFromLatLon(crsDL);
llToCrsDL.transform(input, 0, output, 0, 2);
ge = new GeneralEnvelope(2);
ge.setCoordinateReferenceSystem(crs);
ge.setCoordinateReferenceSystem(crsDL);
ge.setRange(0, output[0], output[2]);
ge.setRange(1, output[3], output[1]);
@ -252,10 +256,7 @@ public class TopoQuery {
mapper.setGridRange(gr);
mapper.setPixelAnchor(PixelInCell.CELL_CENTER);
mapper.setReverseAxis(new boolean[] { false, true });
mt = mapper.createTransform();
worldGeomDL = new GridGeometry2D(PixelInCell.CELL_CORNER, mt, ge,
null);
worldToCRSDL = mapper.createTransform();
} catch (Exception e) {
throw new TopoException("Error initializing TopoQuery from "
@ -545,18 +546,16 @@ public class TopoQuery {
worldRect.getMaxY() };
double[] crsCorners = new double[worldCorners.length];
GeneralEnvelope env = new GeneralEnvelope(2);
if (worldCorners[2] > (worldGeomPM.getGridRange().getHigh(0) + 1)) {
worldGeomDL.getGridToCRS(PixelInCell.CELL_CORNER)
.transform(worldCorners, 0, crsCorners, 0,
worldCorners.length / 2);
env.setCoordinateReferenceSystem(worldGeomDL.getEnvelope()
.getCoordinateReferenceSystem());
if (worldCorners[2] > (this.worldRect.width)) {
worldToCRSDL.transform(worldCorners, 0, crsCorners, 0,
worldCorners.length / 2);
env.setCoordinateReferenceSystem(crsDL);
} else {
worldGeomPM.getGridToCRS(PixelInCell.CELL_CORNER)
.transform(worldCorners, 0, crsCorners, 0,
worldCorners.length / 2);
env.setCoordinateReferenceSystem(worldGeomPM.getEnvelope()
.getCoordinateReferenceSystem());
worldToCRSPM
.transform(worldCorners, 0, crsCorners, 0,
worldCorners.length / 2);
env.setCoordinateReferenceSystem(crsPM);
}
double minX = Double.POSITIVE_INFINITY;