Omaha #3721 Changed Grid Data reference to a Soft Reference and reduced memory usage from X*Y to X*3.
Change-Id: I627ded464d411e7f975df088261a975657d41d9a Former-commit-id:636e823956
[formerly 9a6313162a5477863d30ab0a888608ee419067a9] Former-commit-id:531b62d114
This commit is contained in:
parent
7b9653cdad
commit
44120d9fba
1 changed files with 120 additions and 44 deletions
|
@ -19,6 +19,7 @@
|
|||
**/
|
||||
package com.raytheon.uf.common.dataplugin.grid.util;
|
||||
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -32,11 +33,14 @@ import com.vividsolutions.jts.geom.Coordinate;
|
|||
/**
|
||||
* A class for calculating and caching static data for grids.
|
||||
*
|
||||
* Orignally ported from GridAccessor5.C
|
||||
*
|
||||
* <pre>
|
||||
* SOFTWARE HISTORY
|
||||
* Date Ticket# Engineer Description
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jul 24, 2008 brockwoo Initial creation
|
||||
* Jul 24, 2008 brockwoo Initial creation
|
||||
* Oct 21, 2014 3721 dlovely Optimized for reduced memory usage
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -45,7 +49,7 @@ import com.vividsolutions.jts.geom.Coordinate;
|
|||
*/
|
||||
|
||||
public class StaticGridData {
|
||||
private static Map<GridCoverage, StaticGridData> instanceMap = new HashMap<GridCoverage, StaticGridData>();
|
||||
private static Map<GridCoverage, SoftReference<StaticGridData>> instanceMap = new HashMap<GridCoverage, SoftReference<StaticGridData>>();
|
||||
|
||||
private static final double R_EARTH = 6370.0;
|
||||
|
||||
|
@ -61,11 +65,17 @@ public class StaticGridData {
|
|||
|
||||
public static synchronized StaticGridData getInstance(
|
||||
GridCoverage gridCoverage) {
|
||||
StaticGridData rval = instanceMap.get(gridCoverage);
|
||||
SoftReference<StaticGridData> data = instanceMap.get(gridCoverage);
|
||||
|
||||
if (rval == null) {
|
||||
StaticGridData rval = null;
|
||||
if (null != data) {
|
||||
rval = data.get();
|
||||
}
|
||||
|
||||
if (null == data || null == rval) {
|
||||
rval = new StaticGridData(gridCoverage);
|
||||
instanceMap.put(gridCoverage, rval);
|
||||
data = new SoftReference<StaticGridData>(rval);
|
||||
instanceMap.put(gridCoverage, data);
|
||||
}
|
||||
|
||||
return rval;
|
||||
|
@ -83,6 +93,13 @@ public class StaticGridData {
|
|||
return this.dy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the Dx, Dy and Coriolis data from the provided
|
||||
* {@link GridCoverage}.
|
||||
*
|
||||
* @param gridCoverage
|
||||
* Grid Coverage.
|
||||
*/
|
||||
private void initStaticData(GridCoverage gridCoverage) {
|
||||
int nx = gridCoverage.getNx();
|
||||
int ny = gridCoverage.getNy();
|
||||
|
@ -91,52 +108,73 @@ public class StaticGridData {
|
|||
float[] dxPtr = new float[n];
|
||||
float[] dyPtr = new float[n];
|
||||
float[] avgPtr = new float[n];
|
||||
double[] xx = new double[n];
|
||||
double[] yy = new double[n];
|
||||
double[] zz = new double[n];
|
||||
float[] xxU = new float[nx];
|
||||
float[] xxC = new float[nx];
|
||||
float[] xxD = new float[nx];
|
||||
float[] yyU = new float[nx];
|
||||
float[] yyC = new float[nx];
|
||||
float[] yyD = new float[nx];
|
||||
float[] zzU = new float[nx];
|
||||
float[] zzC = new float[nx];
|
||||
float[] zzD = new float[nx];
|
||||
|
||||
float[] tmpXX, tmpYY, tmpZZ;
|
||||
|
||||
int i, j, k;
|
||||
|
||||
for (j = k = 0; j < ny; j++) {
|
||||
for (i = 0; i < nx; i++, k++) {
|
||||
Coordinate location = new Coordinate(i, j);
|
||||
Coordinate latLon = MapUtil.gridCoordinateToLatLon(location,
|
||||
PixelOrientation.CENTER, gridCoverage);
|
||||
latLon.x = Math.toRadians(latLon.x);
|
||||
latLon.y = Math.toRadians(latLon.y);
|
||||
xx[k] = Math.cos(latLon.y);
|
||||
yy[k] = xx[k] * Math.sin(latLon.x);
|
||||
xx[k] *= Math.cos(latLon.x);
|
||||
zz[k] = Math.sin(latLon.y);
|
||||
_coriolis[k] = (float) (zz[k] * 1.458e-4);
|
||||
}
|
||||
// Populate Up rows.
|
||||
for (i = 0; i < nx; i++) {
|
||||
Coordinate location = new Coordinate(i, 1);
|
||||
Coordinate latLon = MapUtil.gridCoordinateToLatLon(location,
|
||||
PixelOrientation.CENTER, gridCoverage);
|
||||
latLon.x = Math.toRadians(latLon.x);
|
||||
latLon.y = Math.toRadians(latLon.y);
|
||||
xxU[i] = (float) Math.cos(latLon.y);
|
||||
yyU[i] = (float) (xxU[i] * Math.sin(latLon.x));
|
||||
xxU[i] *= Math.cos(latLon.x);
|
||||
zzU[i] = (float) Math.sin(latLon.y);
|
||||
}
|
||||
|
||||
this.coriolis = newRecord(_coriolis, nx, ny);
|
||||
// Populate Current rows.
|
||||
for (i = 0; i < nx; i++) {
|
||||
Coordinate location = new Coordinate(i, 0);
|
||||
Coordinate latLon = MapUtil.gridCoordinateToLatLon(location,
|
||||
PixelOrientation.CENTER, gridCoverage);
|
||||
latLon.x = Math.toRadians(latLon.x);
|
||||
latLon.y = Math.toRadians(latLon.y);
|
||||
xxC[i] = (float) Math.cos(latLon.y);
|
||||
yyC[i] = (float) (xxC[i] * Math.sin(latLon.x));
|
||||
xxC[i] *= Math.cos(latLon.x);
|
||||
zzC[i] = (float) Math.sin(latLon.y);
|
||||
}
|
||||
|
||||
int up, dn, lft, rgt;
|
||||
long _nxm = nx - 1;
|
||||
// Init Down as a copy of Current
|
||||
System.arraycopy(xxC, 0, xxD, 0, nx);
|
||||
System.arraycopy(yyC, 0, yyD, 0, nx);
|
||||
System.arraycopy(zzC, 0, zzD, 0, nx);
|
||||
|
||||
int lft, rgt;
|
||||
double d;
|
||||
double icomp, jcomp, kcomp;
|
||||
double dmax = 0.0;
|
||||
dn = 0;
|
||||
up = nx;
|
||||
|
||||
for (j = k = 0; j < ny; j++) {
|
||||
if (up >= n) {
|
||||
up -= nx;
|
||||
}
|
||||
lft = k;
|
||||
|
||||
lft = 0;
|
||||
for (i = 0; i < nx; i++, k++) {
|
||||
rgt = (i < _nxm ? k + 1 : k);
|
||||
icomp = yy[lft] * zz[rgt] - zz[lft] * yy[rgt];
|
||||
jcomp = zz[lft] * xx[rgt] - xx[lft] * zz[rgt];
|
||||
kcomp = xx[lft] * yy[rgt] - yy[lft] * xx[rgt];
|
||||
_coriolis[k] = (float) (zzC[i] * 1.458e-4);
|
||||
rgt = (i < nx - 1 ? i + 1 : i);
|
||||
icomp = yyC[lft] * zzC[rgt] - zzC[lft] * yyC[rgt];
|
||||
jcomp = zzC[lft] * xxC[rgt] - xxC[lft] * zzC[rgt];
|
||||
kcomp = xxC[lft] * yyC[rgt] - yyC[lft] * xxC[rgt];
|
||||
d = Math.sqrt(icomp * icomp + jcomp * jcomp + kcomp * kcomp);
|
||||
dxPtr[k] = (float) (Math.asin(d) * 1000.0 * R_EARTH / (rgt - lft));
|
||||
icomp = yy[dn] * zz[up] - zz[dn] * yy[up];
|
||||
jcomp = zz[dn] * xx[up] - xx[dn] * zz[up];
|
||||
kcomp = xx[dn] * yy[up] - yy[dn] * xx[up];
|
||||
icomp = yyD[i] * zzU[i] - zzD[i] * yyU[i];
|
||||
jcomp = zzD[i] * xxU[i] - xxD[i] * zzU[i];
|
||||
kcomp = xxD[i] * yyU[i] - yyD[i] * xxU[i];
|
||||
d = Math.sqrt(icomp * icomp + jcomp * jcomp + kcomp * kcomp);
|
||||
dyPtr[k] = (float) (Math.asin(d) * 1000.0 * R_EARTH * nx / (up - dn));
|
||||
dyPtr[k] = (float) (Math.asin(d) * 1000.0 * R_EARTH * (j == 0
|
||||
|| j == (ny - 1) ? 1 : 0.5));
|
||||
avgPtr[k] = (dxPtr[k] + dyPtr[k]) / 2.0f;
|
||||
d = dxPtr[k] - dyPtr[k];
|
||||
if (d < 0) {
|
||||
|
@ -146,14 +184,52 @@ public class StaticGridData {
|
|||
if (d > dmax) {
|
||||
dmax = d;
|
||||
}
|
||||
dn++;
|
||||
up++;
|
||||
lft = k;
|
||||
if (i != 0) {
|
||||
lft++;
|
||||
}
|
||||
}
|
||||
if (j == 0) {
|
||||
dn = 0;
|
||||
|
||||
// Move Current to Down and Up to Current.
|
||||
tmpXX = xxD;
|
||||
xxD = xxC;
|
||||
xxC = xxU;
|
||||
|
||||
tmpYY = yyD;
|
||||
yyD = yyC;
|
||||
yyC = yyU;
|
||||
|
||||
tmpZZ = zzD;
|
||||
zzD = zzC;
|
||||
zzC = zzU;
|
||||
|
||||
// Construct the next Up row with new data unless this is the last
|
||||
// pass then duplicate the current row.
|
||||
if (j < ny - 2) {
|
||||
// Populate the next Up row.
|
||||
xxU = tmpXX;
|
||||
yyU = tmpYY;
|
||||
zzU = tmpZZ;
|
||||
for (i = 0; i < nx; i++) {
|
||||
Coordinate location = new Coordinate(i, j + 2);
|
||||
Coordinate latLon = MapUtil.gridCoordinateToLatLon(
|
||||
location, PixelOrientation.CENTER, gridCoverage);
|
||||
latLon.x = Math.toRadians(latLon.x);
|
||||
latLon.y = Math.toRadians(latLon.y);
|
||||
xxU[i] = (float) Math.cos(latLon.y);
|
||||
yyU[i] = (float) (xxU[i] * Math.sin(latLon.x));
|
||||
xxU[i] *= Math.cos(latLon.x);
|
||||
zzU[i] = (float) Math.sin(latLon.y);
|
||||
}
|
||||
} else {
|
||||
// If the last run, Duplicate the Current row to the Up row.
|
||||
xxU = xxC;
|
||||
yyU = yyC;
|
||||
zzU = zzC;
|
||||
}
|
||||
}
|
||||
|
||||
this.coriolis = newRecord(_coriolis, nx, ny);
|
||||
|
||||
if (dmax > 0.01) {
|
||||
this.dx = newRecord(dxPtr, nx, ny);
|
||||
this.dy = newRecord(dyPtr, nx, ny);
|
||||
|
|
Loading…
Add table
Reference in a new issue