Issue #2788 Fix topo for large areas.

Change-Id: Idb4a19ffea527ad40efb5e586913aab9d37602df

Former-commit-id: fcf45916f4 [formerly 882576fcf6f41b9a41ea8f4a31a40c8c31d51aad]
Former-commit-id: 2f067699f2
This commit is contained in:
Ron Anderson 2014-02-11 17:38:22 -06:00
parent 361881dfda
commit 2d7c87ac84
16 changed files with 433 additions and 139 deletions

View file

@ -36,6 +36,8 @@ import com.raytheon.uf.common.colormap.prefs.ColorMapParameters;
import com.raytheon.uf.common.colormap.prefs.ColorMapParameters.PersistedParameters; import com.raytheon.uf.common.colormap.prefs.ColorMapParameters.PersistedParameters;
import com.raytheon.uf.common.datastorage.DataStoreFactory; import com.raytheon.uf.common.datastorage.DataStoreFactory;
import com.raytheon.uf.common.datastorage.IDataStore; import com.raytheon.uf.common.datastorage.IDataStore;
import com.raytheon.uf.common.datastorage.Request;
import com.raytheon.uf.common.datastorage.records.IDataRecord;
import com.raytheon.uf.common.geospatial.ReferencedCoordinate; import com.raytheon.uf.common.geospatial.ReferencedCoordinate;
import com.raytheon.uf.common.style.LabelingPreferences; import com.raytheon.uf.common.style.LabelingPreferences;
import com.raytheon.uf.common.style.ParamLevelMatchCriteria; import com.raytheon.uf.common.style.ParamLevelMatchCriteria;
@ -91,6 +93,8 @@ public class TopoResource extends
protected TileSetRenderable topoTileSet; protected TileSetRenderable topoTileSet;
private double noDataValue;
protected TopoResource(TopoResourceData topoData, protected TopoResource(TopoResourceData topoData,
LoadProperties loadProperties, File dataFile) throws VizException { LoadProperties loadProperties, File dataFile) throws VizException {
super(topoData, loadProperties); super(topoData, loadProperties);
@ -189,12 +193,13 @@ public class TopoResource extends
} }
SamplePreferences samplePrefs = prefs.getSamplePrefs(); SamplePreferences samplePrefs = prefs.getSamplePrefs();
if (samplePrefs != null && samplePrefs.getFormatString() != null) { if ((samplePrefs != null)
&& (samplePrefs.getFormatString() != null)) {
params.setFormatString(samplePrefs.getFormatString()); params.setFormatString(samplePrefs.getFormatString());
} }
LabelingPreferences labelPrefs = prefs.getColorbarLabeling(); LabelingPreferences labelPrefs = prefs.getColorbarLabeling();
if (labelPrefs != null && labelPrefs.getValues() != null) { if ((labelPrefs != null) && (labelPrefs.getValues() != null)) {
params.setColorBarIntervals(labelPrefs.getValues()); params.setColorBarIntervals(labelPrefs.getValues());
} }
} }
@ -213,6 +218,16 @@ public class TopoResource extends
getCapability(ColorMapCapability.class).setColorMapParameters(params); getCapability(ColorMapCapability.class).setColorMapParameters(params);
IDataStore dataStore = DataStoreFactory.getDataStore(this.dataFile);
try {
IDataRecord rec = dataStore.retrieve("/", "full",
Request.buildPointRequest(new java.awt.Point(0, 0)));
noDataValue = rec.getFillValue().doubleValue();
} catch (Exception e) {
statusHandler.error(e.getLocalizedMessage(), e);
noDataValue = Double.NaN;
}
topoTileSet = new TileSetRenderable( topoTileSet = new TileSetRenderable(
getCapability(ImagingCapability.class), getTopoGeometry(), getCapability(ImagingCapability.class), getTopoGeometry(),
getTopoTileImageCreator(), getNumberOfTopoLevels(), 512); getTopoTileImageCreator(), getNumberOfTopoLevels(), 512);
@ -284,7 +299,7 @@ public class TopoResource extends
double height; double height;
try { try {
// height = TopoQuery.getInstance().getHeight(coord.asLatLon()); // height = TopoQuery.getInstance().getHeight(coord.asLatLon());
height = topoTileSet.interrogate(coord.asLatLon()); height = topoTileSet.interrogate(coord.asLatLon(), noDataValue);
} catch (Exception e) { } catch (Exception e) {
throw new VizException("Error transforming", e); throw new VizException("Error transforming", e);
} }

View file

@ -59,6 +59,8 @@ import com.raytheon.viz.gfe.rsc.GFEResource;
* Feb 14, 2013 1616 bsteffen Add option for interpolation of colormap * Feb 14, 2013 1616 bsteffen Add option for interpolation of colormap
* parameters, disable colormap interpolation * parameters, disable colormap interpolation
* by default. * by default.
* 02/11/2014 #2788 randerso Fixed infinite loop in computeIntervalAndPrecision
* when pmax < pmin
* *
* </pre> * </pre>
* *
@ -186,10 +188,10 @@ public class ContinuousColorbar implements IColorBarDisplay {
dstring.font = colorbarResource.getColorbarScaleFont(); dstring.font = colorbarResource.getColorbarScaleFont();
dstring.textStyle = TextStyle.NORMAL; dstring.textStyle = TextStyle.NORMAL;
for (int i = 0; (minParm + i * interval) <= maxParm; i++) { for (int i = 0; (minParm + (i * interval)) <= maxParm; i++) {
// check to see whether this colorTable item needs to be // check to see whether this colorTable item needs to be
// rendered // rendered
float labelValue = minParm + i * interval; float labelValue = minParm + (i * interval);
// Check to see if value is same as previous unless float.... // Check to see if value is same as previous unless float....
if ((tmpValue != (int) labelValue) || (precision > 0)) { if ((tmpValue != (int) labelValue) || (precision > 0)) {
@ -197,7 +199,7 @@ public class ContinuousColorbar implements IColorBarDisplay {
labelValue, precision); labelValue, precision);
labelLoc = llx labelLoc = llx
+ ((labelValue - minParm) / (maxParm - minParm) * xExtent); + (((labelValue - minParm) / (maxParm - minParm)) * xExtent);
if (GFEColorbarResource.isLabelWithin(pe.getMinX(), if (GFEColorbarResource.isLabelWithin(pe.getMinX(),
pe.getMaxX(), labelLoc, 0)) { pe.getMaxX(), labelLoc, 0)) {
@ -219,10 +221,10 @@ public class ContinuousColorbar implements IColorBarDisplay {
labelValue = labelValueObj.floatValue(); labelValue = labelValueObj.floatValue();
if (precision == 0) { if (precision == 0) {
labelLoc = llx labelLoc = llx
+ ((labelValue - minParm) / (maxParm - minParm) * xExtent); + (((labelValue - minParm) / (maxParm - minParm)) * xExtent);
} else { } else {
labelLoc = llx labelLoc = llx
+ ((labelValue - minParm) / (maxParm - minParm) * xExtent); + (((labelValue - minParm) / (maxParm - minParm)) * xExtent);
} }
if (GFEColorbarResource.isLabelWithin(pe.getMinX(), if (GFEColorbarResource.isLabelWithin(pe.getMinX(),
pe.getMaxX(), labelLoc, 0)) { pe.getMaxX(), labelLoc, 0)) {
@ -246,7 +248,7 @@ public class ContinuousColorbar implements IColorBarDisplay {
float floatValue = ((ScalarWxValue) wxv).getValue(); float floatValue = ((ScalarWxValue) wxv).getValue();
if ((floatValue >= minParm) && (floatValue <= maxParm)) { if ((floatValue >= minParm) && (floatValue <= maxParm)) {
labelLoc = llx labelLoc = llx
+ ((floatValue - minParm) / (maxParm - minParm) * xExtent); + (((floatValue - minParm) / (maxParm - minParm)) * xExtent);
String s = wxv.toString(); String s = wxv.toString();
dstring.font = colorbarResource.getPickupValueFont(); dstring.font = colorbarResource.getPickupValueFont();
@ -261,12 +263,11 @@ public class ContinuousColorbar implements IColorBarDisplay {
dstring.shadowColor = new RGB(0, 0, 0); dstring.shadowColor = new RGB(0, 0, 0);
} }
double halfWidth = target.getStringsBounds(dstring).getWidth() double halfWidth = (target.getStringsBounds(dstring).getWidth() * ratio) / 2;
* ratio / 2;
if (labelLoc - halfWidth < pe.getMinX()) { if ((labelLoc - halfWidth) < pe.getMinX()) {
labelLoc = pe.getMinX() + halfWidth; labelLoc = pe.getMinX() + halfWidth;
} else if (labelLoc + halfWidth > pe.getMaxX()) { } else if ((labelLoc + halfWidth) > pe.getMaxX()) {
labelLoc = pe.getMaxX() - halfWidth; labelLoc = pe.getMaxX() - halfWidth;
} }
dstring.setCoordinates(labelLoc, dstring.setCoordinates(labelLoc,
@ -298,7 +299,8 @@ public class ContinuousColorbar implements IColorBarDisplay {
// initial values are good if decade < parmExtent // initial values are good if decade < parmExtent
// loop is infinite if parmExtent is NaN or 0, so avoid it // loop is infinite if parmExtent is NaN or 0, so avoid it
if (decade < parmExtent || Float.isNaN(parmExtent) || parmExtent == 0.0) { if (Float.isNaN(parmExtent) || (parmExtent <= 0.0)
|| (decade < parmExtent)) {
return new float[] { finterval, precision, labelLength }; return new float[] { finterval, precision, labelLength };
} }
@ -438,7 +440,7 @@ public class ContinuousColorbar implements IColorBarDisplay {
switch (parm.getGridInfo().getGridType()) { switch (parm.getGridInfo().getGridType()) {
case SCALAR: case SCALAR:
return new ScalarWxValue(min + (max - min) * fractionX, parm); return new ScalarWxValue(min + ((max - min) * fractionX), parm);
case VECTOR: case VECTOR:
WxValue previous = parm.getParmState().getPickUpValue(); WxValue previous = parm.getParmState().getPickUpValue();
float mag = 0.0f; float mag = 0.0f;
@ -448,7 +450,7 @@ public class ContinuousColorbar implements IColorBarDisplay {
dir = ((VectorWxValue) previous).getDir(); dir = ((VectorWxValue) previous).getDir();
} }
if (mouseButton == 1) { if (mouseButton == 1) {
mag = min + (max - min) * fractionX; mag = min + ((max - min) * fractionX);
} else if (mouseButton == 2) { } else if (mouseButton == 2) {
dir = 360 * fractionX; dir = 360 * fractionX;
} }

View file

@ -74,6 +74,7 @@ import com.raytheon.uf.common.topo.TopoQuery;
* Jun 13, 2013 #2044 randerso Refactored to use non-singleton GridParmManager, * Jun 13, 2013 #2044 randerso Refactored to use non-singleton GridParmManager,
* code cleanup * code cleanup
* Nov 20, 2013 #2331 randerso Changed return type of getTopoData * Nov 20, 2013 #2331 randerso Changed return type of getTopoData
* Feb 11, 2014 #2788 randerso Set missing data points to 0 to match A1
* *
* </pre> * </pre>
* *
@ -236,6 +237,8 @@ public class TopoDatabaseManager {
if (!allowValuesBelowZero && (heights[i] < 0)) { if (!allowValuesBelowZero && (heights[i] < 0)) {
heights[i] = 0.0f; heights[i] = 0.0f;
} }
} else {
heights[i] = 0.0f;
} }
} }

View file

@ -88,6 +88,8 @@ import com.vividsolutions.jts.geom.Coordinate;
* Feb 15, 2013 1638 mschenke Moved from edex.topo project (not edex * Feb 15, 2013 1638 mschenke Moved from edex.topo project (not edex
* specific) * specific)
* Aug 06, 2013 2235 bsteffen Added Caching version of TopoQuery. * 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)
* *
* </pre> * </pre>
* *
@ -198,10 +200,6 @@ public class TopoQuery {
CoordinateReferenceSystem crs = CRSCache.getInstance() CoordinateReferenceSystem crs = CRSCache.getInstance()
.getCoordinateReferenceSystem(crsString); .getCoordinateReferenceSystem(crsString);
crs = MapUtil.constructEquidistantCylindrical(
MapUtil.AWIPS_EARTH_RADIUS, MapUtil.AWIPS_EARTH_RADIUS, 0,
0);
double[] input = new double[] { ulLon, ulLat, lrLon, lrLat }; double[] input = new double[] { ulLon, ulLat, lrLon, lrLat };
double[] output = new double[4]; double[] output = new double[4];
@ -288,6 +286,7 @@ public class TopoQuery {
public double[] getHeight(Coordinate[] coords) { public double[] getHeight(Coordinate[] coords) {
final int size = coords.length; final int size = coords.length;
double[] topo = new double[size]; double[] topo = new double[size];
Arrays.fill(topo, Double.NaN);
double[] input = new double[size * 2]; double[] input = new double[size * 2];
double[] output = new double[input.length]; double[] output = new double[input.length];
@ -310,15 +309,18 @@ public class TopoQuery {
Request request = Request.buildPointRequest(points); Request request = Request.buildPointRequest(points);
ShortDataRecord record = (ShortDataRecord) dataStore.retrieve("/", ShortDataRecord record = (ShortDataRecord) dataStore.retrieve("/",
"full", request); "full", request);
short fillValue = record.getFillValue().shortValue();
short[] data = record.getShortData(); short[] data = record.getShortData();
// bounds checking? // bounds checking?
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
topo[i] = data[i]; short value = data[i];
if (value != fillValue) {
topo[i] = value;
}
} }
} catch (Exception e) { } catch (Exception e) {
statusHandler.handle(Priority.PROBLEM, statusHandler.handle(Priority.PROBLEM,
"Error retriving topo value for lat/lons", e); "Error retriving topo value for lat/lons", e);
Arrays.fill(topo, Double.NaN);
} }
return topo; return topo;
@ -367,8 +369,9 @@ public class TopoQuery {
if (first) { if (first) {
first = false; first = false;
} else if (Math.abs(p1.getOrdinate(0) - prev) > 180.0 } else if ((Math.abs(p1.getOrdinate(0) - prev) > 180.0)
|| (Math.abs(p1.getOrdinate(0)) > 180 && Math.abs(prev) < 180)) { || ((Math.abs(p1.getOrdinate(0)) > 180) && (Math
.abs(prev) < 180))) {
crossedDLHoriz = true; crossedDLHoriz = true;
} }
prev = p1.getOrdinate(0); prev = p1.getOrdinate(0);
@ -424,8 +427,9 @@ public class TopoQuery {
if (first) { if (first) {
first = false; first = false;
} else if (Math.abs(p1.getOrdinate(0) - prev) > 180.0 } else if ((Math.abs(p1.getOrdinate(0) - prev) > 180.0)
|| (Math.abs(p1.getOrdinate(0)) > 180 && Math.abs(prev) < 180)) { || ((Math.abs(p1.getOrdinate(0)) > 180) && (Math
.abs(prev) < 180))) {
crossedDLVert = true; crossedDLVert = true;
} }
prev = p1.getOrdinate(0); prev = p1.getOrdinate(0);
@ -541,7 +545,7 @@ public class TopoQuery {
worldRect.getMaxY() }; worldRect.getMaxY() };
double[] crsCorners = new double[worldCorners.length]; double[] crsCorners = new double[worldCorners.length];
GeneralEnvelope env = new GeneralEnvelope(2); GeneralEnvelope env = new GeneralEnvelope(2);
if (worldCorners[2] > worldGeomPM.getGridRange().getHigh(0) + 1) { if (worldCorners[2] > (worldGeomPM.getGridRange().getHigh(0) + 1)) {
worldGeomDL.getGridToCRS(PixelInCell.CELL_CORNER) worldGeomDL.getGridToCRS(PixelInCell.CELL_CORNER)
.transform(worldCorners, 0, crsCorners, 0, .transform(worldCorners, 0, crsCorners, 0,
worldCorners.length / 2); worldCorners.length / 2);
@ -643,7 +647,7 @@ public class TopoQuery {
} }
// if grid is too big to load into memory // if grid is too big to load into memory
if (width * height > TOPO_LIMIT) { if ((width * height) > TOPO_LIMIT) {
// try the next interpolation level if it exists // try the next interpolation level if it exists
int level = topoLevel + 1; int level = topoLevel + 1;
if (level < numLevels) { if (level < numLevels) {
@ -675,15 +679,18 @@ public class TopoQuery {
y + intersection.height }); y + intersection.height });
rec = (ShortDataRecord) dataStore.retrieve("", dataset, rec = (ShortDataRecord) dataStore.retrieve("", dataset,
request); request);
short fillValue = rec.getFillValue().shortValue();
int xOffset = intersection.x - worldRect.x + rectOffset; int xOffset = (intersection.x - worldRect.x) + rectOffset;
int yOffset = intersection.y - worldRect.y; int yOffset = intersection.y - worldRect.y;
int recOffset = 0; int recOffset = 0;
for (int j = 0; j < intersection.height; j++) { for (int j = 0; j < intersection.height; j++) {
for (int i = 0; i < intersection.width; i++) { for (int i = 0; i < intersection.width; i++) {
topoValues[j + yOffset][i + xOffset] = rec short value = rec.getShortData()[i + recOffset];
.getShortData()[i + recOffset]; if (value != fillValue) {
topoValues[j + yOffset][i + xOffset] = value;
}
} }
recOffset += intersection.width; recOffset += intersection.width;
// someData = true; // someData = true;
@ -697,10 +704,6 @@ public class TopoQuery {
rectOffset += worldRect.width; rectOffset += worldRect.width;
} }
// if (!someData) {
// throw new EdexException("No topo data available");
// }
Envelope env = computeEnv(new Rectangle(rectangles[0].x, Envelope env = computeEnv(new Rectangle(rectangles[0].x,
rectangles[0].y, width, height)); rectangles[0].y, width, height));
@ -789,8 +792,10 @@ public class TopoQuery {
int sx = (int) Math.round(coord[0]); int sx = (int) Math.round(coord[0]);
int sy = (int) Math.round(coord[1]); int sy = (int) Math.round(coord[1]);
if (sx >= 0 && sx < sourceWidth && sy >= 0 && sy < sourceHeight) if ((sx >= 0) && (sx < sourceWidth) && (sy >= 0)
output[y * targetWidth + x] = sourceData[sy][sx]; && (sy < sourceHeight)) {
output[(y * targetWidth) + x] = sourceData[sy][sx];
}
} }
} }
@ -812,9 +817,9 @@ public class TopoQuery {
MathTransform mt = null; MathTransform mt = null;
for (MathTransform mti : transforms) { for (MathTransform mti : transforms) {
if (mt == null) if (mt == null) {
mt = mti; mt = mti;
else { } else {
mt = mtFactory.createConcatenatedTransform(mt, mti); mt = mtFactory.createConcatenatedTransform(mt, mti);
} }
} }

View file

@ -51,6 +51,7 @@ import com.raytheon.uf.common.geospatial.CRSCache;
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------ ---------- ----------- --------------------------
* Aug 2, 2013 bsteffen Initial creation * Aug 2, 2013 bsteffen Initial creation
* Feb 10, 2014 #2788 randerso Changed default topo file name
* *
* </pre> * </pre>
* *
@ -60,7 +61,9 @@ import com.raytheon.uf.common.geospatial.CRSCache;
public class TopoUtils { public class TopoUtils {
private static final String DEFAULT_TOPO_PATH = "/topo/srtm30.hdf"; // NOTE: this file is actually a symbolic link to the desired topo data file
// allowing the topo data set to be changed without updating Java code
private static final String DEFAULT_TOPO_PATH = "/topo/defaultTopo.h5";
private static final String FULL_TOPO_DATASET = "/full"; private static final String FULL_TOPO_DATASET = "/full";

View file

@ -21,7 +21,7 @@
<styleRuleset> <styleRuleset>
<styleRule> <styleRule>
<paramLevelMatches> <paramLevelMatches>
<parameter>srtm30.hdf</parameter> <parameter>defaultTopo.h5</parameter>
</paramLevelMatches> </paramLevelMatches>
<imageStyle> <imageStyle>
<displayUnits>kft</displayUnits> <displayUnits>kft</displayUnits>

View file

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

View file

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

View file

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

View file

@ -0,0 +1,11 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Utilities
Bundle-SymbolicName: com.raytheon.uf.topo.utilities
Bundle-Version: 1.0.0.qualifier
Bundle-Vendor: RAYTHEON
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Require-Bundle: com.raytheon.uf.common.serialization;bundle-version="1.12.1174",
com.raytheon.uf.common.datastorage;bundle-version="1.12.1174",
com.raytheon.uf.common.pypies;bundle-version="1.12.1174",
com.raytheon.uf.common.geospatial;bundle-version="1.12.1174"

View file

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

View file

@ -0,0 +1,68 @@
<configuration debug="false" scan="false">
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%-5p %d [%t] %c{0}: %m%n</pattern>
</encoder>
<filter class="com.raytheon.uf.common.status.logback.InvertedThresholdFilter">
<level>INFO</level>
</filter>
</appender>
<appender name="errConsole" class="ch.qos.logback.core.ConsoleAppender">
<target>System.err</target>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>WARN</level>
</filter>
<encoder>
<pattern>%-5p %d [%t] %c{0}: %m%n</pattern>
</encoder>
</appender>
<logger name="CaveLogger">
<level value="ALL"/>
</logger>
<logger name="PerformanceLogger">
<level value="ALL"/>
</logger>
<logger name="com.raytheon">
<level value="INFO"/>
</logger>
<logger name="com.tc">
<level value="WARN"/>
</logger>
<logger name="mx4j">
<level value="ERROR"/>
</logger>
<logger name="org.apache">
<level value="INFO"/>
</logger>
<logger name="org.apache.activemq.spring">
<level value="WARN"/>
</logger>
<logger name="org.apache.commons.beanutils">
<level value="WARN"/>
</logger>
<logger name="org.apache.qpid">
<level value="WARN"/>
</logger>
<logger name="org.geotools">
<level value="WARN"/>
</logger>
<logger name="org.apache.xbean.spring">
<level value="WARN"/>
</logger>
<logger name="org.springframework">
<level value="ERROR"/>
</logger>
<logger name="uk.ltd.getahead">
<level value="WARN"/>
</logger>
<root>
<level value="INFO"/>
<appender-ref ref="console"/>
<appender-ref ref="errConsole"/>
</root>
</configuration>

View file

@ -17,7 +17,7 @@
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for * See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information. * further licensing information.
**/ **/
package com.raytheon.uf.common.topo.util; package com.raytheon.uf.topo.utilities;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.DataInputStream; import java.io.DataInputStream;
@ -34,7 +34,8 @@ import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import com.raytheon.uf.common.datastorage.DataStoreFactory; import org.opengis.referencing.crs.ProjectedCRS;
import com.raytheon.uf.common.datastorage.IDataStore; import com.raytheon.uf.common.datastorage.IDataStore;
import com.raytheon.uf.common.datastorage.StorageProperties; import com.raytheon.uf.common.datastorage.StorageProperties;
import com.raytheon.uf.common.datastorage.StorageProperties.Compression; import com.raytheon.uf.common.datastorage.StorageProperties.Compression;
@ -44,6 +45,8 @@ import com.raytheon.uf.common.datastorage.records.IntegerDataRecord;
import com.raytheon.uf.common.datastorage.records.LongDataRecord; import com.raytheon.uf.common.datastorage.records.LongDataRecord;
import com.raytheon.uf.common.datastorage.records.ShortDataRecord; import com.raytheon.uf.common.datastorage.records.ShortDataRecord;
import com.raytheon.uf.common.geospatial.MapUtil; import com.raytheon.uf.common.geospatial.MapUtil;
import com.raytheon.uf.common.pypies.PyPiesDataStore;
import com.raytheon.uf.common.pypies.PypiesProperties;
/** /**
* Import topo data into HDF5 * Import topo data into HDF5
@ -54,6 +57,7 @@ import com.raytheon.uf.common.geospatial.MapUtil;
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------ ---------- ----------- --------------------------
* Oct 22, 2009 #3280 randerso Initial creation * Oct 22, 2009 #3280 randerso Initial creation
* Feb 11, 2014 #2788 randerso Changed to use PyPiesDataStore
* *
* </pre> * </pre>
* *
@ -68,22 +72,14 @@ public class TopoImporter {
String byteOrder; String byteOrder;
String layout;
int nRows; int nRows;
int nCols; int nCols;
int nBands;
int nBits; int nBits;
int bandRowBytes;
int totalRowBytes; int totalRowBytes;
int bandGapBytes;
long noData; long noData;
double ulXmap; double ulXmap;
@ -95,6 +91,18 @@ public class TopoImporter {
double yDim; double yDim;
public TopoHdr(File file) { public TopoHdr(File file) {
if (file.getName().endsWith(".HDR")) {
readHdrFile(file);
} else if (file.getName().endsWith(".ers")) {
readErsFile(file);
} else {
throw new IllegalArgumentException(
"Unrecognized header file format: "
+ file.getAbsolutePath());
}
}
private void readHdrFile(File file) {
BufferedReader in = null; BufferedReader in = null;
try { try {
this.file = file; this.file = file;
@ -105,22 +113,14 @@ public class TopoImporter {
if ("BYTEORDER".equals(s[0])) { if ("BYTEORDER".equals(s[0])) {
byteOrder = s[1]; byteOrder = s[1];
} else if ("LAYOUT".equals(s[0])) {
layout = s[1];
} else if ("NROWS".equals(s[0])) { } else if ("NROWS".equals(s[0])) {
nRows = Integer.parseInt(s[1]); nRows = Integer.parseInt(s[1]);
} else if ("NCOLS".equals(s[0])) { } else if ("NCOLS".equals(s[0])) {
nCols = Integer.parseInt(s[1]); nCols = Integer.parseInt(s[1]);
} else if ("NBANDS".equals(s[0])) {
nBands = Integer.parseInt(s[1]);
} else if ("NBITS".equals(s[0])) { } else if ("NBITS".equals(s[0])) {
nBits = Integer.parseInt(s[1]); nBits = Integer.parseInt(s[1]);
} else if ("BANDROWBYTES".equals(s[0])) {
bandRowBytes = Integer.parseInt(s[1]);
} else if ("TOTALROWBYTES".equals(s[0])) { } else if ("TOTALROWBYTES".equals(s[0])) {
totalRowBytes = Integer.parseInt(s[1]); totalRowBytes = Integer.parseInt(s[1]);
} else if ("BANDGAPBYTES".equals(s[0])) {
bandGapBytes = Integer.parseInt(s[1]);
} else if ("NODATA".equals(s[0])) { } else if ("NODATA".equals(s[0])) {
noData = Long.parseLong(s[1]); noData = Long.parseLong(s[1]);
} else if ("ULXMAP".equals(s[0])) { } else if ("ULXMAP".equals(s[0])) {
@ -149,6 +149,91 @@ public class TopoImporter {
} }
} }
private void readErsFile(File file) {
BufferedReader in = null;
try {
this.file = file;
in = new BufferedReader(new FileReader(file));
String line;
while ((line = in.readLine()) != null) {
line = line.replace(" = ", " ");
String[] s = line.split("\\s+");
if ("ByteOrder".equals(s[0])) {
byteOrder = s[1];
} else if ("NrOfLines".equals(s[0])) {
nRows = Integer.parseInt(s[1]);
} else if ("NrOfCellsPerLine".equals(s[0])) {
nCols = Integer.parseInt(s[1]);
} else if ("CellType".equals(s[0])) {
if (s[1].equals("Signed16BitInteger")) {
nBits = 16;
} else if (s[1].equals("Signed32BitInteger")) {
nBits = 32;
} else if (s[1].equals("Signed64BitInteger")) {
nBits = 64;
} else {
throw new IllegalArgumentException(
"Unrecognized data type: " + s[1]);
}
} else if ("NullCellValue".equals(s[0])) {
noData = Long.parseLong(s[1]);
} else if ("Longitude".equals(s[0])) {
ulXmap = parseDMS(s[1]);
} else if ("Latitude".equals(s[0])) {
ulYmap = parseDMS(s[1]);
} else if ("Xdimension".equals(s[0])) {
xDim = Double.parseDouble(s[1]);
} else if ("Ydimension".equals(s[0])) {
yDim = Double.parseDouble(s[1]);
} else {
// TODO: fully recognize the ers header file
System.out.println("Unrecognized line in file "
+ file.getAbsolutePath() + "\n" + line);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
// convert upper left coordinate from corner to
// center of cell
ulXmap += xDim / 2;
ulYmap -= yDim / 2;
totalRowBytes = (nCols * nBits) / 8;
}
}
}
private double parseDMS(String dms) {
// parse a string in degrees:minutes:seconds format into decimal
// degrees
double degrees = Double.NaN;
String[] s = dms.split(":");
if (s.length == 3) {
try {
int deg = Integer.parseInt(s[0]);
int min = Integer.parseInt(s[1]);
double sec = Double.parseDouble(s[2]);
degrees = deg + (min - ((sec / 60.0) / 60.0));
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Unable to parse DMS: "
+ dms, e);
}
} else {
throw new IllegalArgumentException("Unable to parse DMS: "
+ dms);
}
return degrees;
}
/* /*
* (non-Javadoc) * (non-Javadoc)
* *
@ -176,7 +261,7 @@ public class TopoImporter {
@Override @Override
public boolean accept(File dir, String name) { public boolean accept(File dir, String name) {
return name.endsWith(".HDR"); return name.endsWith(".HDR") || name.endsWith(".ers");
} }
}; };
@ -195,6 +280,11 @@ public class TopoImporter {
hdrList.add(new TopoHdr(file)); hdrList.add(new TopoHdr(file));
} }
if (hdrList.isEmpty()) {
throw new IllegalArgumentException(
"No recognized header files found");
}
// sort the hdr files by descending lat/ascending lon // sort the hdr files by descending lat/ascending lon
Collections.sort(hdrList); Collections.sort(hdrList);
@ -202,12 +292,14 @@ public class TopoImporter {
// determine the total dataset dimensions // determine the total dataset dimensions
double startLat = hdrList.get(0).ulYmap; double startLat = hdrList.get(0).ulYmap;
double startLon = hdrList.get(0).ulXmap; double startLon = hdrList.get(0).ulXmap;
double xDim = hdrList.get(0).xDim;
double yDim = hdrList.get(0).yDim;
int last = hdrList.size() - 1; int last = hdrList.size() - 1;
double endLat = hdrList.get(last).ulYmap double endLat = hdrList.get(last).ulYmap
- (hdrList.get(last).nRows - 1) * hdrList.get(last).yDim; - ((hdrList.get(last).nRows - 1) * hdrList.get(last).yDim);
double endLon = hdrList.get(last).ulXmap double endLon = hdrList.get(last).ulXmap
+ (hdrList.get(last).nCols - 1) * hdrList.get(last).xDim; + ((hdrList.get(last).nCols - 1) * hdrList.get(last).xDim);
int bits = hdrList.get(0).nBits; int bits = hdrList.get(0).nBits;
double expectedLat = startLat; double expectedLat = startLat;
@ -233,7 +325,7 @@ public class TopoImporter {
maxCols = Math.max(cols, maxCols); maxCols = Math.max(cols, maxCols);
expectedLat = hdr.ulYmap; expectedLat = hdr.ulYmap;
expectedLon = hdr.ulXmap + hdr.nCols * hdr.xDim; expectedLon = hdr.ulXmap + (hdr.nCols * hdr.xDim);
if ((expectedLon - startLon) > (360.0 - TOL)) { if ((expectedLon - startLon) > (360.0 - TOL)) {
expectedLon = startLon; expectedLon = startLon;
expectedLat -= hdr.nRows * hdr.yDim; expectedLat -= hdr.nRows * hdr.yDim;
@ -244,8 +336,8 @@ public class TopoImporter {
} }
// create the hdf5 file // create the hdf5 file
File hdf = new File(dir.getParent() + File.separatorChar File hdf = new File("topo" + File.separatorChar
+ dir.getName().toLowerCase() + "_unpacked.hdf"); + dir.getName().toLowerCase() + "_unpacked.h5");
if (hdf.exists()) { if (hdf.exists()) {
System.out System.out
.println(hdf.getAbsolutePath() .println(hdf.getAbsolutePath()
@ -253,7 +345,9 @@ public class TopoImporter {
System.exit(-1); System.exit(-1);
} }
IDataStore store = DataStoreFactory.getDataStore(hdf); PypiesProperties pypiesProps = new PypiesProperties();
pypiesProps.setAddress("http://localhost:9582");
IDataStore store = new PyPiesDataStore(hdf, true, pypiesProps);
String dataset = "full"; String dataset = "full";
long[] sizes = new long[] { maxCols, maxRows }; long[] sizes = new long[] { maxCols, maxRows };
@ -263,31 +357,47 @@ public class TopoImporter {
properties.setChunked(true); properties.setChunked(true);
IDataRecord record = null; IDataRecord record = null;
if (bits <= 8) { if (bits <= Byte.SIZE) {
record = new ByteDataRecord(dataset, "/", null, 2, sizes); record = new ByteDataRecord(dataset, null, null, 2, sizes);
record.setFillValue(Byte.MIN_VALUE); record.setFillValue(Byte.MIN_VALUE);
} else if (bits <= 16) { } else if (bits <= Short.SIZE) {
record = new ShortDataRecord(dataset, "/", null, 2, sizes); record = new ShortDataRecord(dataset, null, null, 2, sizes);
record.setFillValue(Short.MIN_VALUE); record.setFillValue(Short.MIN_VALUE);
} else if (bits <= 32) { } else if (bits <= Integer.SIZE) {
record = new IntegerDataRecord(dataset, "/", null, 2, sizes); record = new IntegerDataRecord(dataset, null, null, 2, sizes);
record.setFillValue(Integer.MIN_VALUE); record.setFillValue(Integer.MIN_VALUE);
} else if (bits <= 64) { } else if (bits <= Long.SIZE) {
record = new LongDataRecord(dataset, "/", null, 2, sizes); record = new LongDataRecord(dataset, null, null, 2, sizes);
record.setFillValue(Long.MIN_VALUE); record.setFillValue(Long.MIN_VALUE);
} else { } else {
System.out.println("NBITS > 64"); System.out.println("NBITS > 64");
System.exit(-1); System.exit(-1);
} }
double centralMeridian = 0.0;
double latOfOrigin = 0.0;
double cm = (startLon + endLon) / 2;
centralMeridian = Math.round(cm);
ProjectedCRS crs = MapUtil.constructEquidistantCylindrical(
MapUtil.AWIPS_EARTH_RADIUS, MapUtil.AWIPS_EARTH_RADIUS,
centralMeridian, latOfOrigin);
Map<String, Object> attributes = new LinkedHashMap<String, Object>(); Map<String, Object> attributes = new LinkedHashMap<String, Object>();
attributes.put("Width", maxCols); attributes.put("Width", maxCols);
attributes.put("Height", maxRows); attributes.put("Height", maxRows);
attributes.put("ulLat", startLat);
attributes.put("ulLon", startLon); // Using arrays to work around serialization "feature" that returns
attributes.put("lrLat", endLat); // floats when doubles are stored
attributes.put("lrLon", endLon); // H5DataStore created these arrays automatically, Pypies does not
attributes.put("CRS", MapUtil.LATLON_PROJECTION.toWKT()); attributes.put("xDim", new double[] { xDim });
attributes.put("yDim", new double[] { yDim });
attributes.put("ulLat", new double[] { startLat });
attributes.put("ulLon", new double[] { startLon });
attributes.put("lrLat", new double[] { endLat });
attributes.put("lrLon", new double[] { endLon });
attributes.put("CRS", crs.toWKT());
record.setProperties(properties); record.setProperties(properties);
record.setDataAttributes(attributes); record.setDataAttributes(attributes);
@ -301,8 +411,14 @@ public class TopoImporter {
rows = 0; rows = 0;
cols = 0; cols = 0;
for (TopoHdr hdr : hdrList) { for (TopoHdr hdr : hdrList) {
File dem = new File(hdr.file.getAbsolutePath().replace(".HDR", String demPath = hdr.file.getAbsolutePath();
".DEM")); if (demPath.endsWith(".HDR")) {
demPath = demPath.replace(".HDR", ".DEM");
} else if (demPath.endsWith(".ers")) {
demPath = demPath.replace(".ers", "");
}
File dem = new File(demPath);
System.out.println(cols + ", " + rows + " " + dem.getName()); System.out.println(cols + ", " + rows + " " + dem.getName());
@ -311,76 +427,75 @@ public class TopoImporter {
in = new DataInputStream(new FileInputStream(dem)); in = new DataInputStream(new FileInputStream(dem));
ByteBuffer buffer = ByteBuffer.allocate(hdr.totalRowBytes); ByteBuffer buffer = ByteBuffer.allocate(hdr.totalRowBytes);
if ("M".equals(hdr.byteOrder)) { if (hdr.byteOrder.startsWith("M")) {
buffer.order(ByteOrder.BIG_ENDIAN); buffer.order(ByteOrder.BIG_ENDIAN);
} else { } else {
buffer.order(ByteOrder.LITTLE_ENDIAN); buffer.order(ByteOrder.LITTLE_ENDIAN);
System.out.println("WARNING: unrecognize BYTEORDER \""
+ hdr.byteOrder + "\" assuming LITTLE_ENDIAN");
} }
sizes[0] = hdr.nCols; sizes[0] = hdr.nCols;
sizes[1] = 1; sizes[1] = 1;
record = null; record = null;
long writeSize = 0;
for (int i = 0; i < hdr.nRows; i++) { for (int i = 0; i < hdr.nRows; i++) {
in.read(buffer.array()); in.read(buffer.array());
buffer.rewind(); buffer.rewind();
if (bits <= 8) { if (bits <= Byte.SIZE) {
byte[] byteData = new byte[hdr.nCols]; byte[] byteData = new byte[hdr.nCols];
for (int j = 0; j < byteData.length; j++) { for (int j = 0; j < byteData.length; j++) {
byteData[j] = buffer.get(); byteData[j] = buffer.get();
// replace no data flag with 0 // replace no data flag with 0
if (byteData[j] == (byte) hdr.noData) { if (byteData[j] == (byte) hdr.noData) {
byteData[j] = 0; byteData[j] = Byte.MIN_VALUE;
} }
} }
record = new ByteDataRecord(dataset, "/", null, 2, record = new ByteDataRecord(dataset, null, null, 2,
sizes); sizes);
record.setMinIndex(new long[] { cols, rows + i }); record.setMinIndex(new long[] { cols, rows + i });
record.setFillValue(Byte.MIN_VALUE); record.setFillValue(Byte.MIN_VALUE);
((ByteDataRecord) record).setByteData(buffer.array()); ((ByteDataRecord) record).setByteData(buffer.array());
} else if (bits <= 16) { } else if (bits <= Short.SIZE) {
short[] shortData = new short[hdr.nCols]; short[] shortData = new short[hdr.nCols];
for (int j = 0; j < shortData.length; j++) { for (int j = 0; j < shortData.length; j++) {
shortData[j] = buffer.getShort(); shortData[j] = buffer.getShort();
// replace no data flag with 0 // replace no data flag with 0
if (shortData[j] == (short) hdr.noData) { if (shortData[j] == (short) hdr.noData) {
shortData[j] = 0; shortData[j] = Short.MIN_VALUE;
} }
} }
record = new ShortDataRecord(dataset, "/", null, 2, record = new ShortDataRecord(dataset, null, null, 2,
sizes); sizes);
record.setMinIndex(new long[] { cols, rows + i }); record.setMinIndex(new long[] { cols, rows + i });
record.setFillValue(Short.MIN_VALUE); record.setFillValue(Short.MIN_VALUE);
((ShortDataRecord) record).setShortData(shortData); ((ShortDataRecord) record).setShortData(shortData);
} else if (bits <= 32) { } else if (bits <= Integer.SIZE) {
int[] intData = new int[hdr.nCols]; int[] intData = new int[hdr.nCols];
for (int j = 0; j < intData.length; j++) { for (int j = 0; j < intData.length; j++) {
intData[j] = buffer.getInt(); intData[j] = buffer.getInt();
// replace no data flag with 0 // replace no data flag with 0
if (intData[j] == (int) hdr.noData) { if (intData[j] == (int) hdr.noData) {
intData[j] = 0; intData[j] = Integer.MIN_VALUE;
} }
} }
record = new IntegerDataRecord(dataset, "/", null, 2, record = new IntegerDataRecord(dataset, null, null, 2,
sizes); sizes);
record.setMinIndex(new long[] { cols, rows + i }); record.setMinIndex(new long[] { cols, rows + i });
record.setFillValue(Integer.MIN_VALUE); record.setFillValue(Integer.MIN_VALUE);
((IntegerDataRecord) record).setIntData(intData); ((IntegerDataRecord) record).setIntData(intData);
} else if (bits <= 64) { } else if (bits <= Long.SIZE) {
long[] longData = new long[hdr.nCols]; long[] longData = new long[hdr.nCols];
for (int j = 0; j < longData.length; j++) { for (int j = 0; j < longData.length; j++) {
longData[j] = buffer.getLong(); longData[j] = buffer.getLong();
// replace no data flag with 0 // replace no data flag with 0
if (longData[j] == hdr.noData) { if (longData[j] == hdr.noData) {
longData[j] = 0; longData[j] = Long.MIN_VALUE;
} }
} }
record = new LongDataRecord(dataset, "/", null, 2, record = new LongDataRecord(dataset, null, null, 2,
sizes); sizes);
record.setMinIndex(new long[] { cols, rows + i }); record.setMinIndex(new long[] { cols, rows + i });
record.setFillValue(Long.MIN_VALUE); record.setFillValue(Long.MIN_VALUE);
@ -388,6 +503,11 @@ public class TopoImporter {
} }
store.addDataRecord(record, properties); store.addDataRecord(record, properties);
writeSize += hdr.totalRowBytes;
if (writeSize > (64 * 1024 * 1024)) {
store.store();
writeSize = 0;
}
} }
store.store(); store.store();
} catch (Throwable e) { } catch (Throwable e) {
@ -410,7 +530,7 @@ public class TopoImporter {
cols = 0; cols = 0;
} }
} }
System.out.println("took " + (System.currentTimeMillis() - t0) / 1000 System.out.println("took " + ((System.currentTimeMillis() - t0) / 1000)
+ " seconds"); + " seconds");
} }
} }

View file

@ -17,7 +17,7 @@
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for * See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information. * further licensing information.
**/ **/
package com.raytheon.uf.common.topo.util; package com.raytheon.uf.topo.utilities;
import java.awt.Point; import java.awt.Point;
import java.awt.RenderingHints; import java.awt.RenderingHints;
@ -40,7 +40,6 @@ import javax.media.jai.PlanarImage;
import javax.media.jai.RasterFactory; import javax.media.jai.RasterFactory;
import javax.media.jai.TiledImage; import javax.media.jai.TiledImage;
import com.raytheon.uf.common.datastorage.DataStoreFactory;
import com.raytheon.uf.common.datastorage.IDataStore; import com.raytheon.uf.common.datastorage.IDataStore;
import com.raytheon.uf.common.datastorage.Request; import com.raytheon.uf.common.datastorage.Request;
import com.raytheon.uf.common.datastorage.StorageProperties; import com.raytheon.uf.common.datastorage.StorageProperties;
@ -50,9 +49,11 @@ import com.raytheon.uf.common.datastorage.records.FloatDataRecord;
import com.raytheon.uf.common.datastorage.records.IDataRecord; import com.raytheon.uf.common.datastorage.records.IDataRecord;
import com.raytheon.uf.common.datastorage.records.IntegerDataRecord; import com.raytheon.uf.common.datastorage.records.IntegerDataRecord;
import com.raytheon.uf.common.datastorage.records.ShortDataRecord; import com.raytheon.uf.common.datastorage.records.ShortDataRecord;
import com.raytheon.uf.common.pypies.PyPiesDataStore;
import com.raytheon.uf.common.pypies.PypiesProperties;
/** /**
* TODO Add Description * Interpolator for topo data files
* *
* <pre> * <pre>
* *
@ -62,6 +63,8 @@ import com.raytheon.uf.common.datastorage.records.ShortDataRecord;
* Oct 26, 2009 randerso Initial creation * Oct 26, 2009 randerso Initial creation
* Feb 12, 2013 #1608 randerso Remove exlicit references to HDF5DataStore * Feb 12, 2013 #1608 randerso Remove exlicit references to HDF5DataStore
* Added explicit calls to deleteGroups * Added explicit calls to deleteGroups
* Feb 11, 2014 #2788 randerso Changed to use PyPiesDataStore
* Fixed corner points for interpolated levels
* *
* </pre> * </pre>
* *
@ -72,22 +75,17 @@ import com.raytheon.uf.common.datastorage.records.ShortDataRecord;
public class TopoInterpolator { public class TopoInterpolator {
private static final int BLOCK_SIZE = 2400; private static final int BLOCK_SIZE = 2400;
private static final String DEFAULT_TOPO_FILE = "/topo/srtm30.hdf";
private IDataStore dataStore; private IDataStore dataStore;
public TopoInterpolator() {
this(new File(DEFAULT_TOPO_FILE));
}
/** /**
* Create a TopoInterpolator instance for the specified hdf file * Create a TopoInterpolator instance for the specified hdf file
* *
* @param file * @param file
*/ */
public TopoInterpolator(File hdf) { public TopoInterpolator(File hdf) {
dataStore = DataStoreFactory.getDataStore(hdf); PypiesProperties pypiesProps = new PypiesProperties();
pypiesProps.setAddress("http://localhost:9582");
dataStore = new PyPiesDataStore(hdf, true, pypiesProps);
} }
public void interpolate(String group, String dataSet) { public void interpolate(String group, String dataSet) {
@ -97,8 +95,18 @@ public class TopoInterpolator {
try { try {
IDataRecord record = dataStore.retrieve(group, dataSet, request); IDataRecord record = dataStore.retrieve(group, dataSet, request);
Map<String, Object> attributes = record.getDataAttributes(); Map<String, Object> attributes = record.getDataAttributes();
int srcWidth = (Integer) attributes.get("Width"); int width = (Integer) attributes.get("Width");
int srcHeight = (Integer) attributes.get("Height"); int height = (Integer) attributes.get("Height");
// These attributes are stored as 1x1 arrays in the file to match
// what H5DataStore did
// Pypies automatically returns them as scalars
double xDim = (Double) attributes.get("xDim");
double yDim = (Double) attributes.get("yDim");
double startLat = (Double) attributes.get("ulLat");
double startLon = (Double) attributes.get("ulLon");
double endLat = (Double) attributes.get("lrLat");
double endLon = (Double) attributes.get("lrLon");
int level = 1; int level = 1;
String srcGroup = group; String srcGroup = group;
@ -120,14 +128,33 @@ public class TopoInterpolator {
long t1 = t0; long t1 = t0;
while (level < 6) { while (level < 6) {
System.out.print("\nInterpolating " + srcGroup + srcDataSet System.out.print("\nInterpolating " + srcGroup + srcDataSet
+ " (" + srcWidth + ", " + srcHeight + ")"); + " (" + width + ", " + height + ")");
int srcWidth = width;
int srcHeight = height;
// compute attributes for new level
width /= 2;
height /= 2;
startLon += xDim / 2;
startLat -= yDim / 2;
endLon -= xDim / 2;
endLat += yDim / 2;
xDim *= 2;
yDim *= 2;
String dstDataSet = "" + level; String dstDataSet = "" + level;
record.setName(dstDataSet); record.setName(dstDataSet);
record.setGroup(dstGroup); record.setGroup(dstGroup);
record.setSizes(new long[] { srcWidth / 2, srcHeight / 2 }); record.setSizes(new long[] { width, height });
record.setProperties(properties); record.setProperties(properties);
attributes.put("Width", srcWidth / 2); attributes.put("Width", width);
attributes.put("Height", srcHeight / 2); attributes.put("Height", height);
attributes.put("xDim", new double[] { xDim });
attributes.put("yDim", new double[] { yDim });
attributes.put("ulLat", new double[] { startLat });
attributes.put("ulLon", new double[] { startLon });
attributes.put("lrLat", new double[] { endLat });
attributes.put("lrLon", new double[] { endLon });
record.setDataAttributes(attributes); record.setDataAttributes(attributes);
dataStore.createDataset(record); dataStore.createDataset(record);
@ -159,17 +186,15 @@ public class TopoInterpolator {
} }
long t2 = System.currentTimeMillis(); long t2 = System.currentTimeMillis();
System.out.print(" took " + (t2 - t1) / 1000 + " s"); System.out.print(" took " + ((t2 - t1) / 1000) + " s");
t1 = t2; t1 = t2;
srcGroup = dstGroup; srcGroup = dstGroup;
srcDataSet = dstDataSet; srcDataSet = dstDataSet;
level++; level++;
srcWidth /= 2;
srcHeight /= 2;
} }
System.out.print("\nTotal " + (System.currentTimeMillis() - t0) System.out.print("\nTotal "
/ 1000 + " s"); + ((System.currentTimeMillis() - t0) / 1000) + " s");
} catch (Exception e) { } catch (Exception e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
@ -230,7 +255,7 @@ public class TopoInterpolator {
param.setParameter("xScale", 1.0f / scale); param.setParameter("xScale", 1.0f / scale);
param.setParameter("yScale", 1.0f / scale); param.setParameter("yScale", 1.0f / scale);
Interpolation interpol = Interpolation Interpolation interpol = Interpolation
.getInstance(Interpolation.INTERP_BICUBIC); .getInstance(Interpolation.INTERP_NEAREST);
param.setParameter("interpolation", interpol); param.setParameter("interpolation", interpol);
RenderingHints hint = new RenderingHints(JAI.KEY_BORDER_EXTENDER, RenderingHints hint = new RenderingHints(JAI.KEY_BORDER_EXTENDER,
BorderExtender.createInstance(BorderExtender.BORDER_COPY)); BorderExtender.createInstance(BorderExtender.BORDER_COPY));
@ -263,14 +288,14 @@ public class TopoInterpolator {
public static void main(String[] args) { public static void main(String[] args) {
TopoInterpolator ti; TopoInterpolator ti;
if (args.length < 1) { if (args.length < 1) {
ti = new TopoInterpolator(); System.out.println("usage: TopoInterpolator topofile");
} else { } else {
ti = new TopoInterpolator(new File(args[0])); String fileName = args[0];
} System.out.println("Interpolating " + fileName);
ti = new TopoInterpolator(new File(fileName));
System.out.println("Interpolating "
+ (args.length < 1 ? DEFAULT_TOPO_FILE : args[0]));
ti.interpolate("/", "full"); ti.interpolate("/", "full");
} }
}
} }

View file

@ -78,7 +78,10 @@ fi
TOPO_TO_COPY=\ TOPO_TO_COPY=\
(\ (\
'srtm30.hdf'\ 'gtopo30.h5'\
'srtm30.h5'\
'srtm30_plus.h5'\
'defaultTopo.h5' \
'akTopo.dat.gz' \ 'akTopo.dat.gz' \
'caribTopo.dat.gz' \ 'caribTopo.dat.gz' \
'modelStaticTopo.h5' \ 'modelStaticTopo.h5' \
@ -91,21 +94,13 @@ TOPO_TO_COPY=\
for topoFile in ${TOPO_TO_COPY[*]}; for topoFile in ${TOPO_TO_COPY[*]};
do do
cp -r %{_awipscm_share}/${TOPO_SRC_DIR}/${topoFile} \ cp -Pp %{_awipscm_share}/${TOPO_SRC_DIR}/${topoFile} \
${RPM_BUILD_ROOT}/awips2/edex/data/hdf5/topo ${RPM_BUILD_ROOT}/awips2/edex/data/hdf5/topo
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
exit 1 exit 1
fi fi
done done
# Copy our hlsTopo
mkdir -p ${RPM_BUILD_ROOT}/awips2/edex/data/hdf5/topo/hlsTopo
cp -r %{_awipscm_share}/${TOPO_SRC_DIR}/hlsTopo/* \
${RPM_BUILD_ROOT}/awips2/edex/data/hdf5/topo/hlsTopo
if [ $? -ne 0 ]; then
exit 1
fi
copyLegal "awips2/edex/data/hdf5/topo" copyLegal "awips2/edex/data/hdf5/topo"
%pre %pre

View file

@ -1 +1 @@
20110824 20140211