Issue #1638 Refactored topo resource to load different topo files. Added GMT TimeZone to TimeUtil.

Change-Id: I4d94a9a2a6dc7ad1261e2ed52c97bab67256b4c8

Former-commit-id: b141397516 [formerly b141397516 [formerly 06107e34a04a2ef0df707a7643daad9e1ec11a0b]]
Former-commit-id: 532211dc69
Former-commit-id: 88211a0f5c
This commit is contained in:
Max Schenkelberg 2013-04-24 15:37:58 -05:00
parent 1bc26f9937
commit 245b3a2fb0
8 changed files with 239 additions and 83 deletions

View file

@ -29,12 +29,14 @@ import javax.xml.bind.annotation.XmlRootElement;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.viz.core.VizConstants;
import com.raytheon.uf.viz.core.drawables.AbstractRenderableDisplay;
import com.raytheon.uf.viz.core.drawables.ResourcePair;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.globals.VizGlobalsManager;
import com.raytheon.uf.viz.core.map.IMapDescriptor;
import com.raytheon.uf.viz.core.maps.display.PlainMapRenderableDisplay;
import com.raytheon.uf.viz.core.maps.scales.MapScales.MapScale;
import com.raytheon.uf.viz.core.procedures.Bundle;
import com.raytheon.uf.viz.core.rsc.ResourceList;
import com.raytheon.viz.ui.actions.LoadSerializedXml;
/**
@ -109,7 +111,13 @@ public class MapScaleRenderableDisplay extends PlainMapRenderableDisplay
VizConstants.SCALE_ID));
}
if (scale != null) {
descriptor.getResourceList().clear();
ResourceList list = descriptor.getResourceList();
for (ResourcePair rp : list) {
if (rp.getProperties().isSystemResource() == false) {
// Keep system resources
list.remove(rp);
}
}
loadScale(scale);
}
}

View file

@ -167,10 +167,14 @@ public class MapScales implements ISerializableObject {
return instance;
}
public static void loadScales(IWorkbenchWindow window) throws VizException {
public static void loadScales(IWorkbenchWindow window, MapScale... scales)
throws VizException {
if (scales == null || scales.length == 0) {
scales = getInstance().getScales();
}
Procedure procedure = new Procedure();
List<Bundle> bundles = new ArrayList<Bundle>();
for (MapScale scale : MapScales.getInstance().getScales()) {
for (MapScale scale : scales) {
String editorId = null;
for (PartId partId : scale.getPartIds()) {
if (partId.isView() == false) {

View file

@ -19,14 +19,17 @@
further_licensing_information.
-->
<styleRuleset>
<!-- GOES Satellite Rules -->
<styleRule>
<paramLevelMatches>
<parameter>topo</parameter>
<parameter>srtm30.hdf</parameter>
</paramLevelMatches>
<imageStyle>
<displayUnits>kft</displayUnits>
<range scale="LINEAR">
<!-- This kft range matches original -19m to 5000m from code -->
<minValue>-0.0062</minValue>
<maxValue>16.404</maxValue>
</range>
<defaultColormap>topo</defaultColormap>
<colorbarLabeling>
<values>0 2 4 6 8 10 12 14</values>

View file

@ -121,4 +121,11 @@
type="java.lang.Object">
</propertyTester>
</extension>
<extension
point="com.raytheon.uf.viz.core.units">
<units
class="com.raytheon.viz.core.topo.TopoUnitRegistrar"
name="Topo Units">
</units>
</extension>
</plugin>

View file

@ -22,10 +22,10 @@ package com.raytheon.viz.core.topo;
import java.io.File;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.Map;
import javax.measure.converter.UnitConverter;
import javax.measure.quantity.Length;
import javax.measure.unit.NonSI;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
@ -34,9 +34,10 @@ import javax.measure.unit.UnitFormat;
import org.geotools.coverage.grid.GeneralGridEnvelope;
import org.geotools.coverage.grid.GridGeometry2D;
import org.geotools.geometry.GeneralEnvelope;
import org.geotools.referencing.operation.builder.GridToEnvelopeMapper;
import org.geotools.referencing.CRS;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.opengis.coverage.grid.GridEnvelope;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.datum.PixelInCell;
import org.opengis.referencing.operation.MathTransform;
import com.raytheon.uf.common.colormap.prefs.ColorMapParameters;
@ -47,7 +48,6 @@ import com.raytheon.uf.common.datastorage.Request;
import com.raytheon.uf.common.datastorage.records.IDataRecord;
import com.raytheon.uf.common.geospatial.CRSCache;
import com.raytheon.uf.common.geospatial.ReferencedCoordinate;
import com.raytheon.uf.common.localization.IPathManager;
import com.raytheon.uf.viz.core.IGraphicsTarget;
import com.raytheon.uf.viz.core.drawables.ColorMapLoader;
import com.raytheon.uf.viz.core.drawables.PaintProperties;
@ -58,8 +58,15 @@ import com.raytheon.uf.viz.core.rsc.IResourceDataChanged;
import com.raytheon.uf.viz.core.rsc.LoadProperties;
import com.raytheon.uf.viz.core.rsc.capabilities.ColorMapCapability;
import com.raytheon.uf.viz.core.rsc.capabilities.ImagingCapability;
import com.raytheon.uf.viz.core.style.LabelingPreferences;
import com.raytheon.uf.viz.core.style.ParamLevelMatchCriteria;
import com.raytheon.uf.viz.core.style.StyleManager;
import com.raytheon.uf.viz.core.style.StyleManager.StyleType;
import com.raytheon.uf.viz.core.style.StyleRule;
import com.raytheon.uf.viz.core.tile.TileSetRenderable;
import com.raytheon.viz.core.drawables.ColorMapParameterFactory;
import com.raytheon.viz.core.style.image.DataScale;
import com.raytheon.viz.core.style.image.ImagePreferences;
import com.raytheon.viz.core.style.image.SamplePreferences;
/**
* Provides an SRTM hdf5-backed topographic map
@ -69,7 +76,8 @@ import com.raytheon.viz.core.drawables.ColorMapParameterFactory;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 14, 2007 chammack Initial Creation.
* Apr 03, 2013 1562 mschenke Fix for custom colormaps
* Apr 03, 2013 1562 mschenke Fix for custom colormaps
* Apr 24, 2013 1638 mschenke Made topo configurable for source data
*
* </pre>
*
@ -79,9 +87,6 @@ import com.raytheon.viz.core.drawables.ColorMapParameterFactory;
public class TopoResource extends
AbstractVizResource<TopoResourceData, IMapDescriptor> {
private static final File DATA_FILE = new File("topo"
+ IPathManager.SEPARATOR + "srtm30.hdf");
private IResourceDataChanged changeListener = new IResourceDataChanged() {
@Override
public void resourceChanged(ChangeType type, Object object) {
@ -89,11 +94,14 @@ public class TopoResource extends
}
};
private File dataFile;
private TileSetRenderable topoTileSet;
protected TopoResource(TopoResourceData topoData,
LoadProperties loadProperties) throws VizException {
LoadProperties loadProperties, File dataFile) throws VizException {
super(topoData, loadProperties);
this.dataFile = dataFile;
}
/*
@ -121,59 +129,98 @@ public class TopoResource extends
protected void initInternal(IGraphicsTarget target) throws VizException {
resourceData.addChangeListener(changeListener);
Unit<Length> dataUnit = SI.METER;
// TODO: create topo style rules for topo and bathymetric topo
ParamLevelMatchCriteria criteria = new ParamLevelMatchCriteria();
criteria.setParameterName(Arrays.asList(resourceData.getTopoFile()));
StyleRule styleRule = StyleManager.getInstance().getStyleRule(
StyleType.IMAGERY, criteria);
ColorMapParameters parameters = ColorMapParameterFactory.build(
(Object) null, "topo", dataUnit, null);
parameters.setDataMin(Short.MIN_VALUE);
parameters.setDataMax(Short.MAX_VALUE);
// Default colormap
String colorMapName = "topo";
parameters.setColorMapMin(-19);
parameters.setColorMapMax(5000);
String colorMapName = parameters.getColorMapName();
if (colorMapName == null) {
colorMapName = "topo";
}
ColorMapParameters existing = getCapability(ColorMapCapability.class)
ColorMapParameters params = getCapability(ColorMapCapability.class)
.getColorMapParameters();
if (existing != null) {
PersistedParameters persisted = existing.getPersisted();
if (persisted != null) {
parameters.applyPersistedParameters(persisted);
PersistedParameters persisted = null;
if (params == null) {
params = new ColorMapParameters();
} else {
persisted = params.getPersisted();
}
// Set data unit, specify in resource data? Look up in data record?
params.setDataUnit(SI.METER);
params.setDisplayUnit(NonSI.FOOT);
params.setColorMapMin(-19);
params.setColorMapMax(5000);
params.setDataMin(Short.MIN_VALUE);
params.setDataMax(Short.MAX_VALUE);
params.setFormatString("0.00");
if (styleRule != null) {
// TODO: This basic logic should be extracted somewhere,
// ColorMapParametersFactory has become overkill of any basic kind
// of colormapping based on style rules and is extremely grib
// specific
ImagePreferences prefs = (ImagePreferences) styleRule
.getPreferences();
Unit<?> prefDisplayUnit = prefs.getDisplayUnits();
if (prefDisplayUnit != null) {
params.setDisplayUnit(prefDisplayUnit);
}
if (existing.getColorMap() != null) {
parameters.setColorMap(existing.getColorMap());
} else if (existing.getColorMapName() != null) {
colorMapName = existing.getColorMapName();
DataScale scale = prefs.getDataScale();
if (scale != null) {
Double minVal = scale.getMinValue();
Double maxVal = scale.getMaxValue();
if (minVal != null) {
params.setColorMapMin((float) params
.getDisplayToDataConverter().convert(minVal));
}
if (maxVal != null) {
params.setColorMapMax((float) params
.getDisplayToDataConverter().convert(maxVal));
}
}
String defaultCmap = prefs.getDefaultColormap();
if (defaultCmap != null) {
colorMapName = defaultCmap;
}
SamplePreferences samplePrefs = prefs.getSamplePrefs();
if (samplePrefs != null && samplePrefs.getFormatString() != null) {
params.setFormatString(samplePrefs.getFormatString());
}
LabelingPreferences labelPrefs = prefs.getColorbarLabeling();
if (labelPrefs != null && labelPrefs.getValues() != null) {
params.setColorBarIntervals(labelPrefs.getValues());
}
}
if (parameters.getColorMap() == null) {
parameters.setColorMap(ColorMapLoader.loadColorMap(colorMapName));
if (params.getColorMap() == null) {
if (params.getColorMapName() != null) {
// Use one specified in params over style rules
colorMapName = params.getColorMapName();
}
params.setColorMap(ColorMapLoader.loadColorMap(colorMapName));
}
if (parameters.getDisplayUnit() == null) {
parameters.setDisplayUnit(NonSI.FOOT);
if (persisted != null) {
params.applyPersistedParameters(persisted);
}
parameters.setFormatString("0");
getCapability(ColorMapCapability.class).setColorMapParameters(
parameters);
getCapability(ColorMapCapability.class).setColorMapParameters(params);
topoTileSet = new TileSetRenderable(
getCapability(ImagingCapability.class), getTopoGeometry(),
new TopoTileImageCreator(this, DATA_FILE),
new TopoTileImageCreator(this, dataFile),
getNumberOfTopoLevels(), 512);
topoTileSet.project(descriptor.getGridGeometry());
}
private int getNumberOfTopoLevels() throws VizException {
IDataStore ds = DataStoreFactory.getDataStore(DATA_FILE);
IDataStore ds = DataStoreFactory.getDataStore(dataFile);
try {
return ds.getDatasets("/interpolated").length + 1;
} catch (Exception e) {
@ -182,7 +229,7 @@ public class TopoResource extends
}
private GridGeometry2D getTopoGeometry() throws VizException {
IDataStore ds = DataStoreFactory.getDataStore(DATA_FILE);
IDataStore ds = DataStoreFactory.getDataStore(dataFile);
Request request = Request.buildSlab(new int[] { 0, 0 }, new int[] { 1,
1 });
@ -198,28 +245,29 @@ public class TopoResource extends
double lrLon = (Double) attributes.get("lrLon");
String crsString = (String) attributes.get("CRS");
// construct the grid geometry that covers the topo grid
// Construct CRS for topo data
CoordinateReferenceSystem crs = CRSCache.getInstance()
.getCoordinateReferenceSystem(crsString);
GeneralEnvelope ge = new GeneralEnvelope(2);
ge.setCoordinateReferenceSystem(crs);
ge.setRange(0, ulLon, lrLon);
ge.setRange(1, lrLat, ulLat);
// Grid range
GridEnvelope gridRange = new GeneralGridEnvelope(
new int[] { 0, 0 }, new int[] { width, height });
GeneralGridEnvelope gr = new GeneralGridEnvelope(
new int[] { 1, 1 }, new int[] { width, height }, false);
// Convert ulLat/ulLon to crs space
MathTransform mt = CRS.findMathTransform(
DefaultGeographicCRS.WGS84, crs);
double[] in = new double[] { ulLon, ulLat, lrLon, lrLat };
double[] out = new double[in.length];
GridToEnvelopeMapper mapper = new GridToEnvelopeMapper();
mapper.setEnvelope(ge);
mapper.setGridRange(gr);
mapper.setPixelAnchor(PixelInCell.CELL_CENTER);
mapper.setReverseAxis(new boolean[] { false, true });
MathTransform mt = mapper.createTransform();
mt.transform(in, 0, out, 0, 2);
GridGeometry2D gridGeom = new GridGeometry2D(
PixelInCell.CELL_CORNER, mt, ge, null);
GeneralEnvelope gridEnvelope = new GeneralEnvelope(2);
gridEnvelope.setCoordinateReferenceSystem(crs);
gridEnvelope.setRange(0, Math.min(out[0], out[2]),
Math.max(out[0], out[2]));
gridEnvelope.setRange(1, Math.min(out[1], out[3]),
Math.max(out[1], out[3]));
return gridGeom;
return new GridGeometry2D(gridRange, gridEnvelope);
} catch (Exception e) {
throw new VizException("Error getting grid geometry", e);
}
@ -276,7 +324,7 @@ public class TopoResource extends
ColorMapCapability.class).getColorMapParameters();
UnitConverter cvt = parameters.getDataToDisplayConverter();
DecimalFormat df = new DecimalFormat("0.00");
DecimalFormat df = new DecimalFormat(parameters.getFormatString());
return String.format(
"%s %s ",
df.format(cvt.convert(height)),

View file

@ -19,10 +19,13 @@
**/
package com.raytheon.viz.core.topo;
import java.io.File;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import com.raytheon.uf.common.localization.IPathManager;
import com.raytheon.uf.viz.core.drawables.IDescriptor;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.rsc.AbstractNameGenerator;
@ -39,6 +42,7 @@ import com.raytheon.uf.viz.core.rsc.LoadProperties;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 19, 2009 chammack Initial creation
* Apr 24, 2013 1638 mschenke Made topo configurable for source data
*
* </pre>
*
@ -48,6 +52,11 @@ import com.raytheon.uf.viz.core.rsc.LoadProperties;
@XmlAccessorType(XmlAccessType.NONE)
public class TopoResourceData extends AbstractResourceData {
private static final String TOPO_DIR = "topo";
@XmlElement
private String topoFile = "srtm30.hdf";
/** The human readable name */
@XmlElement
private String mapName = null;
@ -75,7 +84,24 @@ public class TopoResourceData extends AbstractResourceData {
@Override
public TopoResource construct(LoadProperties loadProperties,
IDescriptor descriptor) throws VizException {
return new TopoResource(this, loadProperties);
return new TopoResource(this, loadProperties, new File(TOPO_DIR
+ IPathManager.SEPARATOR + topoFile));
}
public String getTopoFile() {
return topoFile;
}
public void setTopoFile(String topoFile) {
this.topoFile = topoFile;
}
public String getMapName() {
return mapName;
}
public void setMapName(String mapName) {
this.mapName = mapName;
}
/*
@ -92,22 +118,23 @@ public class TopoResourceData extends AbstractResourceData {
@Override
public boolean equals(Object obj) {
if (this == obj) {
if (this == obj)
return true;
}
if (obj == null || obj instanceof TopoResourceData == false) {
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
}
TopoResourceData other = (TopoResourceData) obj;
if (this.mapName != null && other.mapName == null) {
if (mapName == null) {
if (other.mapName != null)
return false;
} else if (!mapName.equals(other.mapName))
return false;
} else if (this.mapName == null && other.mapName != null) {
if (topoFile == null) {
if (other.topoFile != null)
return false;
} else if (!topoFile.equals(other.topoFile))
return false;
} else if (this.mapName != null
&& this.mapName.equals(other.mapName) == false) {
return false;
}
return true;
}

View file

@ -0,0 +1,57 @@
/**
* 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.core.topo;
import javax.measure.unit.NonSI;
import javax.measure.unit.SI;
import javax.measure.unit.UnitFormat;
import com.raytheon.viz.core.units.IUnitRegistrar;
/**
* Registers units for topo
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Apr 23, 2013 mschenke Initial creation
*
* </pre>
*
* @author mschenke
* @version 1.0
*/
public class TopoUnitRegistrar implements IUnitRegistrar {
/*
* (non-Javadoc)
*
* @see com.raytheon.viz.core.units.IUnitRegistrar#register()
*/
@Override
public void register() {
UnitFormat.getUCUMInstance().label(SI.KILO(NonSI.FOOT), "kft");
}
}

View file

@ -50,7 +50,7 @@ import com.raytheon.uf.common.time.domain.api.ITimePoint;
* Feb 26, 2013 1597 randerso Add SECONDS_PER_HOUR.
* Feb 15, 2013 1638 mschenke Moved Util.getUnixTime into TimeUtil
* Mar 20, 2013 1774 randerso Add SECONDS_PER_DAY, changed SECONDS_PER_HOUR to int.
*
* Apr 24, 2013 1628 mschenke Added GMT TimeZone Object constant
* </pre>
*
* @author njensen
@ -137,6 +137,8 @@ public final class TimeUtil {
*/
public static final long MILLIS_PER_YEAR = MILLIS_PER_DAY * 365;
public static final TimeZone GMT_TIME_ZONE = TimeZone.getTimeZone("GMT");
private static ThreadLocal<SimpleDateFormat> sdf = new ThreadLocal<SimpleDateFormat>() {
@Override
@ -152,7 +154,7 @@ public final class TimeUtil {
@Override
protected SimpleDateFormat initialValue() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
sdf.setTimeZone(GMT_TIME_ZONE);
return sdf;
}
@ -176,7 +178,7 @@ public final class TimeUtil {
*/
public static Date calendarToGMT(Calendar cal) {
Calendar copy = (Calendar) cal.clone();
copy.setTimeZone(TimeZone.getTimeZone("GMT"));
copy.setTimeZone(GMT_TIME_ZONE);
return copy.getTime();
}
@ -231,7 +233,7 @@ public final class TimeUtil {
* @return The formatted date string from the Date instance
*/
public static String formatDate(Date aDate) {
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
Calendar cal = Calendar.getInstance(GMT_TIME_ZONE);
cal.setTimeInMillis(aDate.getTime());
return formatCalendar(cal);
}
@ -341,7 +343,7 @@ public final class TimeUtil {
* @return the calendar
*/
public static Calendar newGmtCalendar() {
return TimeUtil.newCalendar(TimeZone.getTimeZone("GMT"));
return TimeUtil.newCalendar(GMT_TIME_ZONE);
}
/**