Omaha #5539 Fix GFE issues with Wx/Discretes with more than 128 Wx types
Change-Id: I8c66fdcbc8925c23863d6d1e0a8ec5fce67f87c8 Former-commit-id: 81a57e1d4d2062bfcf8acdcc92fbbab062fa9cbf
This commit is contained in:
parent
3d1bee4532
commit
0ffd97f7d3
11 changed files with 190 additions and 115 deletions
|
@ -78,7 +78,8 @@
|
|||
# Sep 11, 2015 4858 dgilling Remove notification processing from publishElements.
|
||||
# Jan 20, 2016 4751 randerso Fix type of mask returned from getComposite() to work with numpy 1.9.2
|
||||
# Jan 28, 2016 5129 dgilling Support changes to IFPClient.
|
||||
# 02/22/2016 5374 randerso Added support for sendWFOMessage
|
||||
# Feb 22, 2016 5374 randerso Added support for sendWFOMessage
|
||||
# Apr 05, 2016 5539 randerso Added exception when attempting create more than 256 Wx keys
|
||||
#
|
||||
########################################################################
|
||||
import types, string, time, sys
|
||||
|
@ -2198,6 +2199,10 @@ class SmartScript(BaseTool.BaseTool):
|
|||
for str in keys:
|
||||
if sortedUglyStr == self.sortUglyStr(str):
|
||||
return keys.index(str)
|
||||
|
||||
if len(keys) >= 256:
|
||||
raise IndexError("Attempt to create more than 256 Wx keys")
|
||||
|
||||
keys.append(uglyStr)
|
||||
return len(keys) - 1
|
||||
|
||||
|
|
|
@ -72,6 +72,7 @@ import com.vividsolutions.jts.geom.MultiPolygon;
|
|||
* 02/19/2013 1637 randerso Added throws declarations to translateDataFrom
|
||||
* 10/31/2013 2508 randerso Change to use DiscreteGridSlice.getKeys()
|
||||
* Apr 23, 2015 4259 njensen Removed unused INumpyable
|
||||
* Apr 04, 2016 5539 randerso Fix unsigned byte issues
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -918,7 +919,7 @@ public class DiscreteGridData extends AbstractGridData {
|
|||
for (int j = 0; j < dim.y; j++) {
|
||||
if (points.get(i, j) == 1) {
|
||||
DiscreteKey combined = DiscreteKey.combine(
|
||||
key.get(values.get(i, j)),
|
||||
key.get(0xFF & values.get(i, j)),
|
||||
doGetDiscreteValue(i, j));
|
||||
grid.set(i, j, lookupKeyValue(combined));
|
||||
}
|
||||
|
|
|
@ -76,6 +76,7 @@ import com.vividsolutions.jts.geom.Coordinate;
|
|||
* 10/31/2013 2508 randerso Change to use DiscreteGridSlice.getKeys()
|
||||
* 09/01/2014 3572 randerso Removed ourSiteMap as it was unused and the only
|
||||
* thing that used Grid2DBoolean
|
||||
* 04/04/2016 5539 randerso Fix unsigned byte issues
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -462,7 +463,7 @@ public class ISCDataAccess implements IISCDataAccess {
|
|||
for (int i = 0; i < siteMask.getXdim(); i++) {
|
||||
if (siteMask.getAsBoolean(i, j)) {
|
||||
byte index = lookupKeyValue(keyIndexMap,
|
||||
iscKey[iscGrid.get(i, j)]);
|
||||
iscKey[0xFF & iscGrid.get(i, j)]);
|
||||
slice.getWeatherGrid().set(i, j, index);
|
||||
}
|
||||
}
|
||||
|
@ -551,7 +552,7 @@ public class ISCDataAccess implements IISCDataAccess {
|
|||
for (int i = 0; i < siteMask.getXdim(); i++) {
|
||||
if (siteMask.getAsBoolean(i, j)) {
|
||||
byte index = lookupKeyValue(keyIndexMap,
|
||||
iscKey[iscGrid.get(i, j)]);
|
||||
iscKey[0xFF & iscGrid.get(i, j)]);
|
||||
slice.getDiscreteGrid().set(i, j, index);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -191,6 +191,7 @@ import com.vividsolutions.jts.geom.Coordinate;
|
|||
* Sep 10, 2015 #4782 randerso Converted inParmEdit to ReentrantLock to force
|
||||
* updates to be run consecutively.
|
||||
* Cleaned up TODOs, FIXMEs and deprecations.
|
||||
* Apr 04, 2016 #5539 randerso Fix unsigned byte issues
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -2161,10 +2162,9 @@ public abstract class Parm implements Comparable<Parm> {
|
|||
.getGridSlice()).getKeys();
|
||||
Grid2DByte grid1 = ((WeatherGridSlice) grids[k]
|
||||
.getGridSlice()).getWeatherGrid();
|
||||
WeatherKey tmpKey = key1[grid1.get(i, j)];
|
||||
WeatherKey tmpKey = key1[0xFF & grid1.get(i, j)];
|
||||
WeatherSubKey gpkeys[] = tmpKey.getSubKeys().toArray(
|
||||
new WeatherSubKey[tmpKey.getSubKeys().size()]);
|
||||
// key1[grid1(i, j)].subKeys();
|
||||
for (int m = 0; m < gpkeys.length; m++) {
|
||||
int index = subKeys.indexOf(gpkeys[m]);
|
||||
if (index == -1) {
|
||||
|
@ -2236,8 +2236,7 @@ public abstract class Parm implements Comparable<Parm> {
|
|||
.getGridSlice()).getKeys();
|
||||
Grid2DByte grid1 = ((DiscreteGridSlice) grids[k]
|
||||
.getGridSlice()).getDiscreteGrid();
|
||||
// TextString kv = key1[grid1(i, j)].keyAsString();
|
||||
DiscreteKey kv = key1[grid1.get(i, j)];
|
||||
DiscreteKey kv = key1[0xFF & grid1.get(i, j)];
|
||||
// add it to the dictionary
|
||||
MutableInteger cnt = values.get(kv);
|
||||
if (cnt == null) {
|
||||
|
@ -3706,7 +3705,7 @@ public abstract class Parm implements Comparable<Parm> {
|
|||
.getGridSlice());
|
||||
WeatherKey[] key1 = slice.getKeys();
|
||||
Grid2DByte grid1 = slice.getWeatherGrid();
|
||||
WeatherKey key1ij = key1[grid1.get(i, j)];
|
||||
WeatherKey key1ij = key1[0xFF & grid1.get(i, j)];
|
||||
subkeys.addAll(key1ij.getSubKeys());
|
||||
}
|
||||
|
||||
|
@ -3760,7 +3759,7 @@ public abstract class Parm implements Comparable<Parm> {
|
|||
.getGridSlice()).getKeys();
|
||||
Grid2DByte grid1 = ((DiscreteGridSlice) grids[k]
|
||||
.getGridSlice()).getDiscreteGrid();
|
||||
DiscreteKey dkv = key1[grid1.get(i, j)];
|
||||
DiscreteKey dkv = key1[0xFF & grid1.get(i, j)];
|
||||
String dks = dkv.toString();
|
||||
// add it to the dictionary
|
||||
Integer count = values.get(dks);
|
||||
|
|
|
@ -121,10 +121,11 @@ import com.raytheon.viz.gfe.Activator;
|
|||
*
|
||||
* <pre>
|
||||
* SOFTWARE HISTORY
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 2, 2008 #1161 randerso Initial creation
|
||||
* Oct 31, 2013 #2508 randerso Change to use DiscreteGridSlice.getKeys()
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 2, 2008 #1161 randerso Initial creation
|
||||
* Oct 31, 2013 #2508 randerso Change to use DiscreteGridSlice.getKeys()
|
||||
* Apr 04, 2016 #5539 randerso Fix unsigned byte issues
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -479,7 +480,7 @@ public class DiscreteInterp extends Interp {
|
|||
// input byte index grids, but with values for the weatherKeys
|
||||
// in _allKeys.
|
||||
|
||||
byte index;
|
||||
int index;
|
||||
DiscreteKey key;
|
||||
|
||||
// For every grid point in the grids, load the new working grids
|
||||
|
@ -488,7 +489,7 @@ public class DiscreteInterp extends Interp {
|
|||
for (i = 0; i < _xDim; i++) {
|
||||
for (j = 0; j < _yDim; j++) {
|
||||
// get the index value from the actual first input grid of bytes
|
||||
index = grid1.get(i, j);
|
||||
index = 0xFF & grid1.get(i, j);
|
||||
|
||||
// Can save a lot of processing here if index=0
|
||||
// ALWAYS means "no weather": the workGrid1 and 2 values
|
||||
|
@ -508,7 +509,7 @@ public class DiscreteInterp extends Interp {
|
|||
|
||||
// get the index value from the actual second input grid of
|
||||
// bytes
|
||||
index = grid2.get(i, j);
|
||||
index = 0xFF & grid2.get(i, j);
|
||||
// get its key
|
||||
key = keys2[index];
|
||||
// find this key in the new list, and save the corresponding
|
||||
|
|
|
@ -75,12 +75,13 @@ import com.vividsolutions.jts.geom.Coordinate;
|
|||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Apr 13, 2011 #8393 dgilling Initial creation
|
||||
* 02/19/13 #1637 randerso Added exception handling for Discrete and Weather
|
||||
* 10/31/2013 #2508 randerso Change to use DiscreteGridSlice.getKeys()
|
||||
* 04/22/2014 #3050 randerso Allow exceptions to propagate to caller from readASCIIGridData
|
||||
* Jan 14, 2016 #5237 tgurney Allow outputAsciiGridData to take
|
||||
* OutputStream as well as File
|
||||
* Apr 13, 2011 #8393 dgilling Initial creation
|
||||
* 02/19/13 #1637 randerso Added exception handling for Discrete and Weather
|
||||
* 10/31/2013 #2508 randerso Change to use DiscreteGridSlice.getKeys()
|
||||
* 04/22/2014 #3050 randerso Allow exceptions to propagate to caller from readASCIIGridData
|
||||
* 01/14/2016 #5237 tgurney Allow outputAsciiGridData to take
|
||||
* OutputStream as well as File
|
||||
* 04/04/2016 #5539 randerso Fixed unsigned byte issues
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -341,7 +342,7 @@ public class ASCIIGrid {
|
|||
WeatherGridSlice weather = (WeatherGridSlice) gs;
|
||||
for (int i = weather.getWeatherGrid().getYdim() - 1; i >= 0; i--) {
|
||||
for (int j = 0; j < weather.getWeatherGrid().getXdim(); j++) {
|
||||
String key = weather.getKeys()[weather
|
||||
String key = weather.getKeys()[0xFF & weather
|
||||
.getWeatherGrid().get(j, i)].toString();
|
||||
printStream.println(key);
|
||||
}
|
||||
|
@ -352,7 +353,7 @@ public class ASCIIGrid {
|
|||
for (int i = discrete.getDiscreteGrid().getYdim() - 1; i >= 0; i--) {
|
||||
for (int j = 0; j < discrete.getDiscreteGrid()
|
||||
.getXdim(); j++) {
|
||||
String key = discrete.getKeys()[discrete
|
||||
String key = discrete.getKeys()[0xFF & discrete
|
||||
.getDiscreteGrid().get(j, i)].toString();
|
||||
printStream.println(key);
|
||||
}
|
||||
|
|
|
@ -35,8 +35,8 @@ import javax.measure.unit.Unit;
|
|||
import com.raytheon.edex.plugin.gfe.server.IFPServer;
|
||||
import com.raytheon.edex.plugin.gfe.server.database.GridDatabase;
|
||||
import com.raytheon.uf.common.dataplugin.gfe.db.objects.DatabaseID;
|
||||
import com.raytheon.uf.common.dataplugin.gfe.db.objects.GridParmInfo.GridType;
|
||||
import com.raytheon.uf.common.dataplugin.gfe.db.objects.GridLocation;
|
||||
import com.raytheon.uf.common.dataplugin.gfe.db.objects.GridParmInfo.GridType;
|
||||
import com.raytheon.uf.common.dataplugin.gfe.db.objects.ParmID;
|
||||
import com.raytheon.uf.common.dataplugin.gfe.point.GFEPointDataContainer;
|
||||
import com.raytheon.uf.common.dataplugin.gfe.point.GFEPointDataContainers;
|
||||
|
@ -70,6 +70,7 @@ import com.vividsolutions.jts.geom.Coordinate;
|
|||
* Jun 13, 2013 #2044 randerso Refactored to use IFPServer
|
||||
* Oct 31, 2013 #2508 randerso Change to use DiscreteGridSlice.getKeys()
|
||||
* Apr 23, 2014 #3006 randerso Restructured code to work with multi-hour grids
|
||||
* Apr 04, 2016 #5539 randerso Fixed unsigned byte issues
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -209,7 +210,7 @@ public class GetPointDataHandler extends BaseGfeRequestHandler implements
|
|||
byte discreteValue = discreteSlice
|
||||
.getDiscreteGrid().get(x, y);
|
||||
String discreteKey = discreteSlice
|
||||
.getKeys()[discreteValue]
|
||||
.getKeys()[0xFF & discreteValue]
|
||||
.toString();
|
||||
type = Type.STRING;
|
||||
view.setData(param, type, unit, discreteKey);
|
||||
|
@ -218,7 +219,7 @@ public class GetPointDataHandler extends BaseGfeRequestHandler implements
|
|||
WeatherGridSlice weatherSlice = (WeatherGridSlice) slice;
|
||||
byte wxValue = weatherSlice
|
||||
.getWeatherGrid().get(x, y);
|
||||
String wxKey = weatherSlice.getKeys()[wxValue]
|
||||
String wxKey = weatherSlice.getKeys()[0xFF & wxValue]
|
||||
.toString();
|
||||
type = Type.STRING;
|
||||
view.setData(param, type, unit, wxKey);
|
||||
|
|
|
@ -41,6 +41,8 @@
|
|||
# 05/13/2015 4427 dgilling Add siteIdOverride field.
|
||||
# 08/06/2015 4718 dgilling Optimize casting when using where with
|
||||
# NumPy 1.9.
|
||||
# 04/07/2016 5539 randerso Reversed order of parameters/return value in collapseKey
|
||||
# to match order of Wx/Discrete tuple
|
||||
#
|
||||
##
|
||||
|
||||
|
@ -924,21 +926,20 @@ def storeVectorWE(we, trList, file, timeRange,
|
|||
|
||||
###-------------------------------------------------------------------------###
|
||||
# Collapse key and bytes. (for discrete and weather)
|
||||
### Returns tuple of (updated key, updated grid)
|
||||
def collapseKey(keys, grid):
|
||||
### Returns tuple of (updated grid, updated key)
|
||||
def collapseKey(grid, keys):
|
||||
#make list of unique indexes in the grid
|
||||
flatGrid = grid.flat
|
||||
used = []
|
||||
used = numpy.zeros((len(keys)), dtype=numpy.bool)
|
||||
for n in range(flatGrid.__array__().shape[0]):
|
||||
if flatGrid[n] not in used:
|
||||
used.append(flatGrid[n])
|
||||
used[0xFF & flatGrid[n]] = True
|
||||
|
||||
#make reverse map
|
||||
map = []
|
||||
newKeys = []
|
||||
j = 0
|
||||
for i in range(len(keys)):
|
||||
if i in used:
|
||||
if used[i]:
|
||||
map.append(j)
|
||||
newKeys.append(keys[i])
|
||||
j = j + 1
|
||||
|
@ -948,10 +949,10 @@ def collapseKey(keys, grid):
|
|||
# modify the data
|
||||
newGrid = grid
|
||||
for k in range(len(map)):
|
||||
mask = numpy.equal(k, grid)
|
||||
mask = numpy.equal(numpy.int8(k), grid)
|
||||
newGrid = numpy.where(mask, numpy.int8(map[k]), newGrid).astype(numpy.int8)
|
||||
|
||||
return (newKeys, newGrid)
|
||||
return (newGrid, newKeys)
|
||||
|
||||
###-------------------------------------------------------------------------###
|
||||
# Stores the specified Weather WE in the netCDF file whose grids fall within
|
||||
|
@ -987,7 +988,7 @@ def storeWeatherWE(we, trList, file, timeRange, databaseID, invMask, clipArea, s
|
|||
# Process the weather keys so we store only what is necessary
|
||||
|
||||
for g in range(byteCube.shape[0]):
|
||||
(keyList[g], byteCube[g]) = collapseKey(keyList[g], byteCube[g])
|
||||
(byteCube[g], keyList[g]) = collapseKey(byteCube[g], keyList[g])
|
||||
|
||||
# Mask the values
|
||||
fillValue = -127
|
||||
|
@ -1072,7 +1073,7 @@ def storeDiscreteWE(we, trList, file, timeRange, databaseID, invMask, clipArea,
|
|||
# Process the discrete keys so we store only what is necessary
|
||||
|
||||
for g in range(byteCube.shape[0]):
|
||||
(keyList[g], byteCube[g]) = collapseKey(keyList[g], byteCube[g])
|
||||
(byteCube[g], keyList[g]) = collapseKey(byteCube[g], keyList[g])
|
||||
|
||||
# Mask the values
|
||||
fillValue = -127
|
||||
|
|
|
@ -39,7 +39,7 @@ import LogStream, fcntl
|
|||
# 11/05/13 2517 randerso Improve memory utilization
|
||||
# 08/06/2015 4718 dgilling Optimize casting when using where with
|
||||
# NumPy 1.9.
|
||||
#
|
||||
# 04/07/2016 5539 randerso Fixed issues with Wx/Discretes with large number of keys
|
||||
#
|
||||
#
|
||||
|
||||
|
@ -79,6 +79,9 @@ class MergeGrid:
|
|||
index = keyMap.index(key)
|
||||
return index
|
||||
except:
|
||||
if (len(keyMap) >= 256):
|
||||
raise IndexError("Attempt to create more than 256 Wx keys")
|
||||
|
||||
keyMap.append(key)
|
||||
return len(keyMap) - 1
|
||||
|
||||
|
@ -186,6 +189,36 @@ class MergeGrid:
|
|||
return (magGrid, dirGrid)
|
||||
|
||||
|
||||
###-------------------------------------------------------------------------###
|
||||
# Collapse key and bytes. (for discrete and weather)
|
||||
### Returns tuple of (updated grid, updated key)
|
||||
def __collapseKey(self, grid, keys):
|
||||
#make list of unique indexes in the grid
|
||||
flatGrid = grid.flat
|
||||
used = numpy.zeros((len(keys)), dtype=numpy.bool)
|
||||
for n in range(flatGrid.__array__().shape[0]):
|
||||
used[0xFF & flatGrid[n]] = True
|
||||
|
||||
#make reverse map
|
||||
map = []
|
||||
newKeys = []
|
||||
j = 0
|
||||
for i in range(len(keys)):
|
||||
if used[i]:
|
||||
map.append(j)
|
||||
newKeys.append(keys[i])
|
||||
j = j + 1
|
||||
else:
|
||||
map.append(-1)
|
||||
|
||||
# modify the data
|
||||
newGrid = grid
|
||||
for k in range(len(map)):
|
||||
mask = numpy.equal(numpy.int8(k), grid)
|
||||
newGrid = numpy.where(mask, numpy.int8(map[k]), newGrid).astype(numpy.int8)
|
||||
|
||||
return (newGrid, newKeys)
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
# merge weather grid
|
||||
#
|
||||
|
@ -208,6 +241,11 @@ class MergeGrid:
|
|||
noWxGrid = numpy.empty_like(gridA[0])
|
||||
noWxGrid.fill(self.__findKey(noWx, noWxKeys))
|
||||
gridB = (noWxGrid, noWxKeys)
|
||||
else:
|
||||
# clear out the masked area in gridB and collapse gridB's keys
|
||||
grid, keys = gridB
|
||||
grid[mask]= self.__findKey(noWx, keys)
|
||||
gridB = self.__collapseKey(grid, keys)
|
||||
(commonkey, remapG, dbG) = self.__commonizeKey(gridA, gridB)
|
||||
mergedGrid = numpy.where(mask, remapG, dbG)
|
||||
return (mergedGrid, commonkey)
|
||||
|
@ -242,6 +280,11 @@ class MergeGrid:
|
|||
noGrid = numpy.empty_like(gridA[0])
|
||||
noGrid.fill(self.__findKey(noKey, noKeys))
|
||||
gridB = (noGrid, noKeys)
|
||||
else:
|
||||
# clear out the masked area in gridB and collapse gridB's keys
|
||||
grid, keys = gridB
|
||||
grid[mask] = self.__findKey(noKey, keys)
|
||||
gridB = self.__collapseKey(grid, keys)
|
||||
|
||||
(commonkey, remapG, dbG) = \
|
||||
self.__commonizeKey(gridA, gridB)
|
||||
|
|
|
@ -42,6 +42,7 @@ import com.vividsolutions.jts.geom.Coordinate;
|
|||
* Oct 22, 2008 1624 wdougherty Speed up translate method
|
||||
* Sep 01, 2014 3572 randerso Changed getNumpy to use getBytes()
|
||||
* Apr 23, 2015 4259 njensen Updated for new JEP API
|
||||
* Apr 04, 2016 5539 randerso Fixed toString method to handle unsigned bytes
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -103,7 +104,7 @@ public class Grid2DByte implements IGrid2D, Cloneable {
|
|||
*/
|
||||
public Grid2DByte(int xDim, int yDim, byte[] data) {
|
||||
this(xDim, yDim);
|
||||
if (xDim * yDim != data.length) {
|
||||
if ((xDim * yDim) != data.length) {
|
||||
throw new IllegalArgumentException(
|
||||
"Dimensions do not match data length (" + xDim + "," + yDim
|
||||
+ ") " + data.length);
|
||||
|
@ -122,7 +123,7 @@ public class Grid2DByte implements IGrid2D, Cloneable {
|
|||
* ByteBuffer of initialization data
|
||||
*/
|
||||
public Grid2DByte(int xDim, int yDim, ByteBuffer data) {
|
||||
if (xDim * yDim != data.limit()) {
|
||||
if ((xDim * yDim) != data.limit()) {
|
||||
throw new IllegalArgumentException(
|
||||
"Dimensions do not match data length (" + xDim + "," + yDim
|
||||
+ ") " + data.limit());
|
||||
|
@ -165,7 +166,7 @@ public class Grid2DByte implements IGrid2D, Cloneable {
|
|||
if (!isValid(xDim, yDim)) {
|
||||
throw new IllegalArgumentException("Dimensions not valid");
|
||||
}
|
||||
return buffer.get(yDim * this.xdim + xDim);
|
||||
return buffer.get((yDim * this.xdim) + xDim);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -180,7 +181,7 @@ public class Grid2DByte implements IGrid2D, Cloneable {
|
|||
if (!isValid(xDim, yDim)) {
|
||||
throw new IllegalArgumentException("Dimensions not valid");
|
||||
}
|
||||
buffer.put(yDim * this.xdim + xDim, aValue);
|
||||
buffer.put((yDim * this.xdim) + xDim, aValue);
|
||||
}
|
||||
|
||||
public void set(int xDim, int yDim, int aValue) {
|
||||
|
@ -205,7 +206,7 @@ public class Grid2DByte implements IGrid2D, Cloneable {
|
|||
|
||||
@Override
|
||||
public boolean isValid(int x, int y) {
|
||||
return (x < xdim && y < ydim && x >= 0 && y >= 0);
|
||||
return ((x < xdim) && (y < ydim) && (x >= 0) && (y >= 0));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -224,7 +225,7 @@ public class Grid2DByte implements IGrid2D, Cloneable {
|
|||
* y coordinate to clear
|
||||
*/
|
||||
public void clear(int x, int y) {
|
||||
buffer.put(y * xdim + x, (byte) 0);
|
||||
buffer.put((y * xdim) + x, (byte) 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -241,7 +242,7 @@ public class Grid2DByte implements IGrid2D, Cloneable {
|
|||
// make another Grid2DByte
|
||||
Grid2DByte rVal = new Grid2DByte(this.xdim, this.ydim, (byte) 0);
|
||||
|
||||
if (Math.abs(deltaCoord.x) < xdim && Math.abs(deltaCoord.y) < ydim) {
|
||||
if ((Math.abs(deltaCoord.x) < xdim) && (Math.abs(deltaCoord.y) < ydim)) {
|
||||
// Find iteration limits for X
|
||||
int fromXStart;
|
||||
int toXStart;
|
||||
|
@ -275,8 +276,8 @@ public class Grid2DByte implements IGrid2D, Cloneable {
|
|||
byte[] toA = rVal.getBuffer().array();
|
||||
|
||||
// Calculate from/to array offsets of the first point.
|
||||
int fromOffset = fromYStart * xdim + fromXStart;
|
||||
int toOffset = toYStart * xdim + toXStart;
|
||||
int fromOffset = (fromYStart * xdim) + fromXStart;
|
||||
int toOffset = (toYStart * xdim) + toXStart;
|
||||
|
||||
// For each row, copy cols bytes of data.
|
||||
// Then update offsets for next row.
|
||||
|
@ -328,9 +329,9 @@ public class Grid2DByte implements IGrid2D, Cloneable {
|
|||
|
||||
@Override
|
||||
public Grid2DByte subGrid(int minX, int minY, int maxX, int maxY) {
|
||||
Grid2DByte rVal = new Grid2DByte(maxX + 1 - minX, maxY + 1 - minY);
|
||||
for (int y = minY; y < maxY + 1; y++) {
|
||||
for (int x = minX; x < maxX + 1; x++) {
|
||||
Grid2DByte rVal = new Grid2DByte((maxX + 1) - minX, (maxY + 1) - minY);
|
||||
for (int y = minY; y < (maxY + 1); y++) {
|
||||
for (int x = minX; x < (maxX + 1); x++) {
|
||||
rVal.buffer.put(this.get(x, y));
|
||||
}
|
||||
}
|
||||
|
@ -345,7 +346,8 @@ public class Grid2DByte implements IGrid2D, Cloneable {
|
|||
|
||||
Grid2DByte rhsGrid2DByte = (Grid2DByte) rhs;
|
||||
|
||||
if (this.xdim != rhsGrid2DByte.xdim || this.ydim != rhsGrid2DByte.ydim) {
|
||||
if ((this.xdim != rhsGrid2DByte.xdim)
|
||||
|| (this.ydim != rhsGrid2DByte.ydim)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -374,9 +376,10 @@ public class Grid2DByte implements IGrid2D, Cloneable {
|
|||
|
||||
Grid2DByte sourceGrid2DByte = (Grid2DByte) sourceGrid;
|
||||
|
||||
if (this.xdim != sourceGrid2DByte.xdim || this.xdim != maskGrid.xdim
|
||||
|| this.ydim != sourceGrid2DByte.ydim
|
||||
|| this.ydim != maskGrid.ydim) {
|
||||
if ((this.xdim != sourceGrid2DByte.xdim)
|
||||
|| (this.xdim != maskGrid.xdim)
|
||||
|| (this.ydim != sourceGrid2DByte.ydim)
|
||||
|| (this.ydim != maskGrid.ydim)) {
|
||||
throw new IllegalArgumentException(
|
||||
"This grid, the input grid, and the input mask grid must have equal dimensions");
|
||||
}
|
||||
|
@ -407,7 +410,7 @@ public class Grid2DByte implements IGrid2D, Cloneable {
|
|||
rVal += xdim + "X" + ydim + "\n[\n";
|
||||
for (int y = 0; y < ydim; y++) {
|
||||
for (int x = 0; x < xdim; x++) {
|
||||
rVal += this.get(x, y) + (x + 1 == xdim ? "" : ",");
|
||||
rVal += (0xFF & this.get(x, y)) + ((x + 1) == xdim ? "" : ",");
|
||||
}
|
||||
rVal += "\n";
|
||||
}
|
||||
|
|
|
@ -53,13 +53,14 @@ import com.raytheon.uf.common.time.TimeRange;
|
|||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Mar 15, 2011 randerso Initial creation
|
||||
* Jan 30, 2013 15719 jdynina Allowed more than 128 char wx string
|
||||
* Aug 13, 2013 1571 randerso Removed toString to stop it from hanging the
|
||||
* debugger when trying to display the grid
|
||||
* Oct 29, 2013 2476 njensen Updated getNumpy() and added getKeyList()
|
||||
* Apr 23, 2015 4259 njensen Updated for new JEP API
|
||||
* Nov 03, 2015 5061 randerso Fixed null pointer in equals()
|
||||
* Mar 15, 2011 randerso Initial creation
|
||||
* Jan 30, 2013 15719 jdynina Allowed more than 128 char wx string
|
||||
* Aug 13, 2013 1571 randerso Removed toString to stop it from hanging the
|
||||
* debugger when trying to display the grid
|
||||
* Oct 29, 2013 2476 njensen Updated getNumpy() and added getKeyList()
|
||||
* Apr 23, 2015 4259 njensen Updated for new JEP API
|
||||
* Nov 03, 2015 5061 randerso Fixed null pointer in equals()
|
||||
* Apr 05, 2016 5539 randerso Cleaned up collapse method
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -645,63 +646,81 @@ public class WeatherGridSlice extends AbstractGridSlice {
|
|||
return;
|
||||
}
|
||||
|
||||
// make a histogram, indicating what is and what isn't
|
||||
// used in the weather keys
|
||||
boolean[] used = new boolean[keys.length];
|
||||
int[] invMapping = new int[keys.length];
|
||||
for (int i = 0; i < used.length; i++) {
|
||||
invMapping[i] = i;
|
||||
used[i] = false;
|
||||
}
|
||||
|
||||
// process the grid
|
||||
for (int i = 0; i < weatherGrid.getXdim(); i++) {
|
||||
for (int j = 0; j < weatherGrid.getYdim(); j++) {
|
||||
used[0xFF & weatherGrid.get(i, j)] = true;
|
||||
}
|
||||
} // indicate used
|
||||
|
||||
// clear the invmapping if not used
|
||||
for (int i = 0; i < used.length; i++) {
|
||||
if (!used[i]) {
|
||||
invMapping[i] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// eliminate duplicate keys
|
||||
int nk = 0;
|
||||
List<WeatherKey> tmpKeys = new ArrayList<WeatherKey>();
|
||||
for (int i = 0; i < used.length; i++) {
|
||||
if (used[i]) {
|
||||
tmpKeys.add(keys[i]);
|
||||
invMapping[i] = nk;
|
||||
for (int j = i + 1; j < used.length; j++) {
|
||||
if (keys[i].equals(keys[j])) {
|
||||
invMapping[j] = nk; // key index
|
||||
used[j] = false; // to prevent reprocessing
|
||||
}
|
||||
try {
|
||||
int max = 0;
|
||||
for (byte b : weatherGrid.getBytes()) {
|
||||
int unsigned = 0xFF & b;
|
||||
if (unsigned > max) {
|
||||
max = unsigned;
|
||||
}
|
||||
nk++;
|
||||
}
|
||||
}
|
||||
WeatherKey[] newKeys = tmpKeys.toArray(new WeatherKey[tmpKeys.size()]);
|
||||
|
||||
// anything to do?
|
||||
if (Arrays.equals(newKeys, keys)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// now remap the data
|
||||
for (int i = 0; i < weatherGrid.getXdim(); i++) {
|
||||
for (int j = 0; j < weatherGrid.getYdim(); j++) {
|
||||
weatherGrid.set(i, j,
|
||||
(byte) invMapping[0xFF & weatherGrid.get(i, j)]);
|
||||
if (max >= keys.length) {
|
||||
throw new IndexOutOfBoundsException("Grid contains index ("
|
||||
+ max + ") > keys.length (" + keys.length + ")");
|
||||
}
|
||||
}
|
||||
|
||||
// store the grid
|
||||
setWeatherGrid(weatherGrid);
|
||||
keys = newKeys;
|
||||
// make a histogram, indicating what is and what isn't
|
||||
// used in the weather keys
|
||||
boolean[] used = new boolean[keys.length];
|
||||
int[] invMapping = new int[keys.length];
|
||||
for (int i = 0; i < used.length; i++) {
|
||||
invMapping[i] = i;
|
||||
used[i] = false;
|
||||
}
|
||||
|
||||
// process the grid
|
||||
for (int i = 0; i < weatherGrid.getXdim(); i++) {
|
||||
for (int j = 0; j < weatherGrid.getYdim(); j++) {
|
||||
used[0xFF & weatherGrid.get(i, j)] = true; // indicate used
|
||||
}
|
||||
}
|
||||
|
||||
// clear the invmapping if not used
|
||||
for (int i = 0; i < used.length; i++) {
|
||||
if (!used[i]) {
|
||||
invMapping[i] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// eliminate duplicate keys
|
||||
int nk = 0;
|
||||
List<WeatherKey> tmpKeys = new ArrayList<WeatherKey>();
|
||||
for (int i = 0; i < used.length; i++) {
|
||||
if (used[i]) {
|
||||
tmpKeys.add(keys[i]);
|
||||
invMapping[i] = nk;
|
||||
for (int j = i + 1; j < used.length; j++) {
|
||||
if (keys[i].equals(keys[j])) {
|
||||
invMapping[j] = nk; // key index
|
||||
used[j] = false; // to prevent reprocessing
|
||||
}
|
||||
}
|
||||
nk++;
|
||||
}
|
||||
}
|
||||
WeatherKey[] newKeys = tmpKeys.toArray(new WeatherKey[tmpKeys
|
||||
.size()]);
|
||||
|
||||
// anything to do?
|
||||
if (Arrays.equals(newKeys, keys)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// now remap the data
|
||||
for (int i = 0; i < weatherGrid.getXdim(); i++) {
|
||||
for (int j = 0; j < weatherGrid.getYdim(); j++) {
|
||||
weatherGrid.set(i, j,
|
||||
(byte) invMapping[0xFF & weatherGrid.get(i, j)]);
|
||||
}
|
||||
}
|
||||
// store the grid
|
||||
setWeatherGrid(weatherGrid);
|
||||
keys = newKeys;
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
statusHandler.error(e.getLocalizedMessage(), e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Add table
Reference in a new issue