Issue #358 Fixed painting and sampling regression in radar mosaic due to
core improvements from NPP in GL mosaic imaging extension and discovered while testing IMesh improvements Former-commit-id:556a270a09
[formerly10b720381b
[formerly719f87c261
] [formerly556a270a09
[formerly f739d79bfd547adc295c716a1804f55f09b1bde1]]] Former-commit-id:10b720381b
[formerly719f87c261
] Former-commit-id:10b720381b
Former-commit-id:732c2ddb5c
This commit is contained in:
parent
66efb10629
commit
d0818c08e6
11 changed files with 267 additions and 313 deletions
|
@ -21,11 +21,11 @@ package com.raytheon.uf.viz.core;
|
|||
|
||||
import org.geotools.coverage.grid.GeneralGridGeometry;
|
||||
|
||||
import com.raytheon.uf.viz.core.drawables.IRenderable;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
|
||||
/**
|
||||
* Base for any mesh 2D/3D, Quad/Triangle -- etc
|
||||
* Base for any mesh 2D/3D, Quad/Triangle -- etc. See {@link PixelCoverage} /
|
||||
* {@link DrawableImage}
|
||||
*
|
||||
* <pre>
|
||||
* SOFTWARE HISTORY
|
||||
|
@ -39,7 +39,7 @@ import com.raytheon.uf.viz.core.exception.VizException;
|
|||
* @version 1.0
|
||||
*/
|
||||
|
||||
public interface IMesh extends IRenderable {
|
||||
public interface IMesh {
|
||||
|
||||
/**
|
||||
* Dispose of the mesh data
|
||||
|
|
|
@ -59,7 +59,7 @@ public class GLRadialMeshExtension extends GraphicsExtension<IGLTarget>
|
|||
throws VizException {
|
||||
String format = radarData.getFormat();
|
||||
if ("Radial".equals(format)) {
|
||||
return RadarRadialMeshCache.getMesh(radarData, descriptor);
|
||||
return RadarRadialMesh.getMesh(radarData, descriptor);
|
||||
} else {
|
||||
throw new VizException(
|
||||
"Cannot construct radial meshes for non radial RadarRecords");
|
||||
|
|
|
@ -19,6 +19,10 @@
|
|||
**/
|
||||
package com.raytheon.uf.viz.radar.gl;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.media.opengl.GL;
|
||||
|
||||
import org.geotools.coverage.grid.GeneralGridGeometry;
|
||||
|
@ -31,6 +35,7 @@ import com.raytheon.uf.common.dataplugin.radar.util.RadarUtil;
|
|||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
import com.raytheon.uf.viz.core.drawables.IDescriptor;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.viz.core.gl.AbstractGLMesh;
|
||||
import com.raytheon.viz.core.gl.SharedCoordMap.SharedCoordinateKey;
|
||||
|
@ -55,18 +60,122 @@ public class RadarRadialMesh extends AbstractGLMesh {
|
|||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(RadarRadialMesh.class);
|
||||
|
||||
private static class CacheKey {
|
||||
private final float latitude;
|
||||
|
||||
private final float longitude;
|
||||
|
||||
private final int hashCode;
|
||||
|
||||
private final int numBins;
|
||||
|
||||
private final int numRadials;
|
||||
|
||||
private final int gateResolution;
|
||||
|
||||
private final float trueElevationAngle;
|
||||
|
||||
private final int jStart;
|
||||
|
||||
private final float[] angleData;
|
||||
|
||||
private final GeneralGridGeometry gridGeometry;
|
||||
|
||||
public CacheKey(float latitude, float longitude, int numBins,
|
||||
int numRadials, int gateResolution, float trueElevationAngle,
|
||||
int jStart, float[] angleData, GeneralGridGeometry gridGeometry) {
|
||||
this.latitude = latitude;
|
||||
this.longitude = longitude;
|
||||
this.numBins = numBins;
|
||||
this.numRadials = numRadials;
|
||||
this.gateResolution = gateResolution;
|
||||
this.trueElevationAngle = trueElevationAngle;
|
||||
this.jStart = jStart;
|
||||
this.angleData = angleData;
|
||||
this.gridGeometry = gridGeometry;
|
||||
final int prime = 31;
|
||||
int hashCode = 1;
|
||||
hashCode = prime * hashCode + Arrays.hashCode(angleData);
|
||||
hashCode = prime * hashCode + gateResolution;
|
||||
hashCode = prime * hashCode + jStart;
|
||||
hashCode = prime * hashCode + Float.floatToIntBits(latitude);
|
||||
hashCode = prime * hashCode + Float.floatToIntBits(longitude);
|
||||
hashCode = prime * hashCode + numBins;
|
||||
hashCode = prime * hashCode + numRadials;
|
||||
hashCode = prime * hashCode
|
||||
+ Float.floatToIntBits(trueElevationAngle);
|
||||
hashCode = prime * hashCode + gridGeometry.hashCode();
|
||||
this.hashCode = hashCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
CacheKey other = (CacheKey) obj;
|
||||
if (hashCode != other.hashCode)
|
||||
return false;
|
||||
if (gateResolution != other.gateResolution)
|
||||
return false;
|
||||
if (jStart != other.jStart)
|
||||
return false;
|
||||
if (latitude != other.latitude)
|
||||
return false;
|
||||
if (longitude != other.longitude)
|
||||
return false;
|
||||
if (numBins != other.numBins)
|
||||
return false;
|
||||
if (numRadials != other.numRadials)
|
||||
return false;
|
||||
if (Float.floatToIntBits(trueElevationAngle) != Float
|
||||
.floatToIntBits(other.trueElevationAngle))
|
||||
return false;
|
||||
if (!Arrays.equals(angleData, other.angleData))
|
||||
return false;
|
||||
if (gridGeometry != null && other.gridGeometry == null) {
|
||||
return false;
|
||||
}
|
||||
if (gridGeometry == null && other.gridGeometry != null) {
|
||||
return false;
|
||||
}
|
||||
if (gridGeometry != null
|
||||
&& !gridGeometry.equals(other.gridGeometry)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<CacheKey, RadarRadialMesh> cache = new HashMap<CacheKey, RadarRadialMesh>();
|
||||
|
||||
/** The record to build the mesh for */
|
||||
private RadarRecord record;
|
||||
|
||||
private CacheKey cacheKey;
|
||||
|
||||
private int refCount;
|
||||
|
||||
public RadarRadialMesh(RadarRecord record,
|
||||
GeneralGridGeometry targetGeometry) throws VizException {
|
||||
GeneralGridGeometry targetGeometry, CacheKey cacheKey)
|
||||
throws VizException {
|
||||
super(GL.GL_TRIANGLE_STRIP);
|
||||
this.record = record;
|
||||
this.cacheKey = cacheKey;
|
||||
initialize(
|
||||
RadarUtil.constructGridGeometry(record.getCRS(),
|
||||
RadarUtil.calculateExtent(record),
|
||||
Math.max(record.getNumBins(), record.getNumRadials())),
|
||||
targetGeometry);
|
||||
refCount = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -276,4 +385,54 @@ public class RadarRadialMesh extends AbstractGLMesh {
|
|||
}
|
||||
}
|
||||
|
||||
private void use() {
|
||||
refCount += 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.viz.core.gl.AbstractGLMesh#dispose()
|
||||
*/
|
||||
@Override
|
||||
public synchronized void dispose() {
|
||||
refCount -= 1;
|
||||
synchronized (cache) {
|
||||
if (refCount == 0) {
|
||||
super.dispose();
|
||||
cache.remove(cacheKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static RadarRadialMesh getMesh(RadarRecord radarData,
|
||||
IDescriptor descriptor) throws VizException {
|
||||
float latitude = radarData.getLatitude();
|
||||
float longitude = radarData.getLongitude();
|
||||
int numBins = radarData.getNumBins();
|
||||
int numRadials = radarData.getNumRadials();
|
||||
int gateResolution = radarData.getGateResolution();
|
||||
float trueElevationAngle = radarData.getTrueElevationAngle();
|
||||
Integer jStart = radarData.getJstart();
|
||||
if (jStart == null) {
|
||||
jStart = 0;
|
||||
}
|
||||
float[] angleData = radarData.getAngleData();
|
||||
CacheKey key = new CacheKey(latitude, longitude, numBins, numRadials,
|
||||
gateResolution, trueElevationAngle, jStart, angleData,
|
||||
descriptor.getGridGeometry());
|
||||
synchronized (cache) {
|
||||
RadarRadialMesh mesh = cache.get(key);
|
||||
if (mesh == null) {
|
||||
// System.out.println("Mesh Cache miss");
|
||||
mesh = new RadarRadialMesh(radarData,
|
||||
descriptor.getGridGeometry(), key);
|
||||
cache.put(key, mesh);
|
||||
} else {
|
||||
// System.out.println("Mesh Cache hit");
|
||||
}
|
||||
mesh.use();
|
||||
return mesh;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,238 +0,0 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.radar.gl;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.geotools.coverage.grid.GeneralGridGeometry;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.radar.RadarRecord;
|
||||
import com.raytheon.uf.viz.core.IExtent;
|
||||
import com.raytheon.uf.viz.core.IGraphicsTarget;
|
||||
import com.raytheon.uf.viz.core.IMesh;
|
||||
import com.raytheon.uf.viz.core.drawables.IDescriptor;
|
||||
import com.raytheon.uf.viz.core.drawables.PaintProperties;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
|
||||
/**
|
||||
*
|
||||
* TODO Add Description
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jul 28, 2011 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class RadarRadialMeshCache {
|
||||
|
||||
private static class CacheKey {
|
||||
|
||||
private final float latitude;
|
||||
|
||||
private final float longitude;
|
||||
|
||||
private final int hashCode;
|
||||
|
||||
private final int numBins;
|
||||
|
||||
private final int numRadials;
|
||||
|
||||
private final int gateResolution;
|
||||
|
||||
private final float trueElevationAngle;
|
||||
|
||||
private final int jStart;
|
||||
|
||||
private final float[] angleData;
|
||||
|
||||
private final GeneralGridGeometry gridGeometry;
|
||||
|
||||
public CacheKey(float latitude, float longitude, int numBins,
|
||||
int numRadials, int gateResolution, float trueElevationAngle,
|
||||
int jStart, float[] angleData, GeneralGridGeometry gridGeometry) {
|
||||
this.latitude = latitude;
|
||||
this.longitude = longitude;
|
||||
this.numBins = numBins;
|
||||
this.numRadials = numRadials;
|
||||
this.gateResolution = gateResolution;
|
||||
this.trueElevationAngle = trueElevationAngle;
|
||||
this.jStart = jStart;
|
||||
this.angleData = angleData;
|
||||
this.gridGeometry = gridGeometry;
|
||||
final int prime = 31;
|
||||
int hashCode = 1;
|
||||
hashCode = prime * hashCode + Arrays.hashCode(angleData);
|
||||
hashCode = prime * hashCode + gateResolution;
|
||||
hashCode = prime * hashCode + jStart;
|
||||
hashCode = prime * hashCode + Float.floatToIntBits(latitude);
|
||||
hashCode = prime * hashCode + Float.floatToIntBits(longitude);
|
||||
hashCode = prime * hashCode + numBins;
|
||||
hashCode = prime * hashCode + numRadials;
|
||||
hashCode = prime * hashCode
|
||||
+ Float.floatToIntBits(trueElevationAngle);
|
||||
hashCode = prime * hashCode + gridGeometry.hashCode();
|
||||
this.hashCode = hashCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
CacheKey other = (CacheKey) obj;
|
||||
if (hashCode != other.hashCode)
|
||||
return false;
|
||||
if (gateResolution != other.gateResolution)
|
||||
return false;
|
||||
if (jStart != other.jStart)
|
||||
return false;
|
||||
if (latitude != other.latitude)
|
||||
return false;
|
||||
if (longitude != other.longitude)
|
||||
return false;
|
||||
if (numBins != other.numBins)
|
||||
return false;
|
||||
if (numRadials != other.numRadials)
|
||||
return false;
|
||||
if (Float.floatToIntBits(trueElevationAngle) != Float
|
||||
.floatToIntBits(other.trueElevationAngle))
|
||||
return false;
|
||||
if (!Arrays.equals(angleData, other.angleData))
|
||||
return false;
|
||||
if (gridGeometry != null && other.gridGeometry == null) {
|
||||
return false;
|
||||
}
|
||||
if (gridGeometry == null && other.gridGeometry != null) {
|
||||
return false;
|
||||
}
|
||||
if (gridGeometry != null
|
||||
&& !gridGeometry.equals(other.gridGeometry)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static class RadarSharedMesh implements IMesh {
|
||||
|
||||
private final CacheKey key;
|
||||
|
||||
private final IMesh mesh;
|
||||
|
||||
private int refCount = 0;
|
||||
|
||||
private RadarSharedMesh(IMesh mesh, CacheKey key) {
|
||||
this.mesh = mesh;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(IGraphicsTarget target, PaintProperties paintProps)
|
||||
throws VizException {
|
||||
mesh.paint(target, paintProps);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
refCount -= 1;
|
||||
synchronized (cache) {
|
||||
if (refCount == 0) {
|
||||
mesh.dispose();
|
||||
cache.remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void use() {
|
||||
refCount += 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* com.raytheon.uf.viz.core.IMesh#reproject(org.geotools.coverage.grid
|
||||
* .GeneralGridGeometry)
|
||||
*/
|
||||
@Override
|
||||
public void reproject(GeneralGridGeometry targetGeometry)
|
||||
throws VizException {
|
||||
mesh.reproject(targetGeometry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean intersects(IExtent extent) {
|
||||
return mesh.intersects(extent);
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<CacheKey, RadarSharedMesh> cache = new HashMap<CacheKey, RadarSharedMesh>();
|
||||
|
||||
public static RadarSharedMesh getMesh(RadarRecord radarData,
|
||||
IDescriptor descriptor) throws VizException {
|
||||
float latitude = radarData.getLatitude();
|
||||
float longitude = radarData.getLongitude();
|
||||
int numBins = radarData.getNumBins();
|
||||
int numRadials = radarData.getNumRadials();
|
||||
int gateResolution = radarData.getGateResolution();
|
||||
float trueElevationAngle = radarData.getTrueElevationAngle();
|
||||
Integer jStart = radarData.getJstart();
|
||||
if (jStart == null) {
|
||||
jStart = 0;
|
||||
}
|
||||
float[] angleData = radarData.getAngleData();
|
||||
CacheKey key = new CacheKey(latitude, longitude, numBins, numRadials,
|
||||
gateResolution, trueElevationAngle, jStart, angleData,
|
||||
descriptor.getGridGeometry());
|
||||
synchronized (cache) {
|
||||
RadarSharedMesh mesh = cache.get(key);
|
||||
if (mesh == null) {
|
||||
// System.out.println("Mesh Cache miss");
|
||||
IMesh baseMesh = new RadarRadialMesh(radarData,
|
||||
descriptor.getGridGeometry());
|
||||
mesh = new RadarSharedMesh(baseMesh, key);
|
||||
cache.put(key, mesh);
|
||||
} else {
|
||||
// System.out.println("Mesh Cache hit");
|
||||
}
|
||||
mesh.use();
|
||||
return mesh;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -88,6 +88,14 @@ public class GLMosaicImage extends GLDelegateImage<AbstractGLImage> implements
|
|||
return repaint;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param repaint
|
||||
* @return
|
||||
*/
|
||||
public void setRepaint(boolean repaint) {
|
||||
this.repaint = repaint;
|
||||
}
|
||||
|
||||
public DrawableImage[] getImagesToMosaic() {
|
||||
return images;
|
||||
}
|
||||
|
|
|
@ -101,7 +101,9 @@ public class GLRadarMosaicImageExtension extends AbstractGLSLImagingExtension
|
|||
.getImagesToMosaic();
|
||||
// Make sure images are staged before we mosaic them
|
||||
ImagingSupport.prepareImages(target, imagesToMosaic);
|
||||
drawRasters(paintProps, imagesToMosaic);
|
||||
// Need to set repaint based on if drawing completed
|
||||
mosaicImage.setRepaint(drawRasters(paintProps,
|
||||
imagesToMosaic) == false);
|
||||
} finally {
|
||||
extension.renderOnscreen();
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ import com.raytheon.uf.viz.core.IExtent;
|
|||
import com.raytheon.uf.viz.core.IGraphicsTarget;
|
||||
import com.raytheon.uf.viz.core.IMesh;
|
||||
import com.raytheon.uf.viz.core.drawables.PaintProperties;
|
||||
import com.raytheon.uf.viz.core.drawables.PaintStatus;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.core.jobs.JobPool;
|
||||
import com.raytheon.viz.core.gl.GLGeometryObject2D.GLGeometryObjectData;
|
||||
|
@ -123,21 +124,15 @@ public abstract class AbstractGLMesh implements IMesh {
|
|||
reproject(targetGeometry);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* com.raytheon.viz.core.IMesh#paint(com.raytheon.viz.core.IGraphicsTarget)
|
||||
*/
|
||||
@Override
|
||||
public final synchronized void paint(IGraphicsTarget target,
|
||||
public final synchronized PaintStatus paint(IGraphicsTarget target,
|
||||
PaintProperties paintProps) throws VizException {
|
||||
State internalState = this.internalState;
|
||||
if (internalState == State.NEW) {
|
||||
throw new VizException(
|
||||
"Class did not properly call initialize on construction");
|
||||
} else if (internalState == State.INVALID) {
|
||||
// Don't paint if invalid to avoid crashes
|
||||
return;
|
||||
return PaintStatus.ERROR;
|
||||
}
|
||||
|
||||
IGLTarget glTarget;
|
||||
|
@ -147,28 +142,32 @@ public abstract class AbstractGLMesh implements IMesh {
|
|||
|
||||
glTarget = (IGLTarget) target;
|
||||
|
||||
if (internalState == State.CALCULATED) {
|
||||
// We finished calculating the mesh, compile it
|
||||
try {
|
||||
try {
|
||||
if (internalState == State.CALCULATED) {
|
||||
// We finished calculating the mesh, compile it
|
||||
sharedTextureCoords = SharedCoordMap.get(key, glTarget);
|
||||
vertexCoords.compile(glTarget.getGl());
|
||||
internalState = State.COMPILED;
|
||||
} catch (VizException e) {
|
||||
internalState = State.INVALID;
|
||||
throw e;
|
||||
this.internalState = internalState = State.COMPILED;
|
||||
}
|
||||
}
|
||||
|
||||
if (internalState == State.COMPILED) {
|
||||
GLGeometryPainter.paintGeometries(glTarget.getGl(), vertexCoords,
|
||||
sharedTextureCoords.getTextureCoords());
|
||||
} else {
|
||||
target.setNeedsRefresh(true);
|
||||
if (internalState == State.COMPILED) {
|
||||
GLGeometryPainter.paintGeometries(glTarget.getGl(),
|
||||
vertexCoords, sharedTextureCoords.getTextureCoords());
|
||||
return PaintStatus.PAINTED;
|
||||
} else if (internalState == State.CALCULATING) {
|
||||
target.setNeedsRefresh(true);
|
||||
return PaintStatus.REPAINT;
|
||||
} else {
|
||||
return PaintStatus.ERROR;
|
||||
}
|
||||
} catch (VizException e) {
|
||||
this.internalState = State.INVALID;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final synchronized void dispose() {
|
||||
public synchronized void dispose() {
|
||||
// Synchronize on calculate so we don't dispose while running
|
||||
synchronized (calculate) {
|
||||
// Cancel calculation job from running
|
||||
|
|
|
@ -22,9 +22,7 @@ package com.raytheon.viz.core.gl.ext;
|
|||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.media.opengl.GL;
|
||||
|
@ -37,9 +35,11 @@ import com.raytheon.uf.viz.core.PixelCoverage;
|
|||
import com.raytheon.uf.viz.core.drawables.IImage;
|
||||
import com.raytheon.uf.viz.core.drawables.IImage.Status;
|
||||
import com.raytheon.uf.viz.core.drawables.PaintProperties;
|
||||
import com.raytheon.uf.viz.core.drawables.PaintStatus;
|
||||
import com.raytheon.uf.viz.core.drawables.ext.GraphicsExtension;
|
||||
import com.raytheon.uf.viz.core.drawables.ext.IImagingExtension;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.viz.core.gl.AbstractGLMesh;
|
||||
import com.raytheon.viz.core.gl.GLCapabilities;
|
||||
import com.raytheon.viz.core.gl.IGLTarget;
|
||||
import com.raytheon.viz.core.gl.glsl.GLSLFactory;
|
||||
|
@ -107,9 +107,8 @@ public abstract class AbstractGLImagingExtension extends
|
|||
// Get shader program extension uses
|
||||
String shaderProgram = getShaderProgramName();
|
||||
|
||||
int continues = 0;
|
||||
int repaints = 0;
|
||||
Set<String> errorMsgs = new HashSet<String>();
|
||||
List<DrawableImage> notDrawn = new ArrayList<DrawableImage>();
|
||||
|
||||
GLShaderProgram program = null;
|
||||
boolean attemptedToLoadShader = false;
|
||||
|
@ -123,12 +122,12 @@ public abstract class AbstractGLImagingExtension extends
|
|||
if (glImage.getStatus() == Status.STAGED) {
|
||||
glImage.target(target);
|
||||
}
|
||||
|
||||
|
||||
if (glImage.getStatus() != Status.LOADED) {
|
||||
++continues;
|
||||
++repaints;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
int textureType = glImage.getTextureStorageType();
|
||||
|
||||
if (lastTextureType != textureType) {
|
||||
|
@ -146,7 +145,7 @@ public abstract class AbstractGLImagingExtension extends
|
|||
dataObj = preImageRender(paintProps, glImage, extent);
|
||||
|
||||
if (dataObj == null) {
|
||||
continues++;
|
||||
// Skip image if preImageRender returned null
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -183,8 +182,11 @@ public abstract class AbstractGLImagingExtension extends
|
|||
gl.glColor4f(1.0f, 1.0f, 1.0f, paintProps.getAlpha());
|
||||
}
|
||||
|
||||
drawCoverage(paintProps, extent,
|
||||
glImage.getTextureCoords(), 0);
|
||||
if (drawCoverage(paintProps, extent,
|
||||
glImage.getTextureCoords(), 0) == PaintStatus.REPAINT) {
|
||||
// Coverage not ready, needs repaint
|
||||
++repaints;
|
||||
}
|
||||
|
||||
gl.glActiveTexture(GL.GL_TEXTURE0);
|
||||
gl.glBindTexture(textureType, 0);
|
||||
|
@ -210,8 +212,6 @@ public abstract class AbstractGLImagingExtension extends
|
|||
}
|
||||
} else {
|
||||
errorMsgs.add("Texture did not bind");
|
||||
continues++;
|
||||
notDrawn.add(di);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -230,12 +230,12 @@ public abstract class AbstractGLImagingExtension extends
|
|||
+ " images: " + errorMsgs);
|
||||
}
|
||||
|
||||
boolean allDrawn = continues == 0;
|
||||
if (!allDrawn) {
|
||||
boolean needsRepaint = repaints > 0;
|
||||
if (needsRepaint) {
|
||||
target.setNeedsRefresh(true);
|
||||
}
|
||||
|
||||
return allDrawn;
|
||||
return needsRepaint == false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -247,11 +247,12 @@ public abstract class AbstractGLImagingExtension extends
|
|||
* @param corrFactor
|
||||
* @throws VizException
|
||||
*/
|
||||
protected void drawCoverage(PaintProperties paintProps, PixelCoverage pc,
|
||||
TextureCoords coords, float corrFactor) throws VizException {
|
||||
protected PaintStatus drawCoverage(PaintProperties paintProps,
|
||||
PixelCoverage pc, TextureCoords coords, float corrFactor)
|
||||
throws VizException {
|
||||
GL gl = target.getGl();
|
||||
if (pc == null) {
|
||||
return;
|
||||
return PaintStatus.ERROR;
|
||||
}
|
||||
// gl.glPolygonMode(GL.GL_BACK, GL.GL_FILL);
|
||||
// gl.glColor3d(1.0, 0.0, 0.0);
|
||||
|
@ -262,7 +263,9 @@ public abstract class AbstractGLImagingExtension extends
|
|||
|
||||
// if mesh exists, use it
|
||||
if (mesh != null) {
|
||||
mesh.paint(target, paintProps);
|
||||
if (mesh instanceof AbstractGLMesh) {
|
||||
return ((AbstractGLMesh) mesh).paint(target, paintProps);
|
||||
}
|
||||
} else if (coords != null) {
|
||||
FloatBuffer fb = ByteBuffer.allocateDirect(4 * 5 * 4)
|
||||
.order(ByteOrder.nativeOrder()).asFloatBuffer();
|
||||
|
@ -304,7 +307,9 @@ public abstract class AbstractGLImagingExtension extends
|
|||
|
||||
gl.glDisableClientState(GL.GL_VERTEX_ARRAY);
|
||||
gl.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY);
|
||||
return PaintStatus.PAINTED;
|
||||
}
|
||||
return PaintStatus.ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -302,8 +302,16 @@ public class AbstractRadarResource<D extends IDescriptor> extends
|
|||
if (resourceData.mode.equals("CZ-Pg")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Grab current time
|
||||
DataTime displayedDate = descriptor.getTimeForResource(this);
|
||||
|
||||
if (displayedDate == null) {
|
||||
displayedDate = this.displayedDate;
|
||||
}
|
||||
|
||||
try {
|
||||
dataMap = interrogate(latLon.asLatLon());
|
||||
dataMap = interrogate(displayedDate, latLon.asLatLon());
|
||||
} catch (Exception e) {
|
||||
throw new VizException("Error converting coordinate for hover", e);
|
||||
}
|
||||
|
@ -333,20 +341,23 @@ public class AbstractRadarResource<D extends IDescriptor> extends
|
|||
boolean visible = descriptor.getRenderableDisplay().getContainer()
|
||||
.getActiveDisplayPane().getDescriptor() == descriptor;
|
||||
if (visible && primary) {
|
||||
return "=" + inspect(primaryInspectLabels, dataMap);
|
||||
return "="
|
||||
+ inspect(displayedDate, primaryInspectLabels, dataMap);
|
||||
} else {
|
||||
return " " + inspect(offscreenInspectLabels, dataMap);
|
||||
return " "
|
||||
+ inspect(displayedDate, offscreenInspectLabels,
|
||||
dataMap);
|
||||
}
|
||||
} else if (primary) {
|
||||
return inspect(dataMap);
|
||||
return inspect(displayedDate, dataMap);
|
||||
} else {
|
||||
// The secondary returns slightly less data
|
||||
return inspect(secondaryInspectLabels, dataMap);
|
||||
return inspect(displayedDate, secondaryInspectLabels, dataMap);
|
||||
}
|
||||
}
|
||||
|
||||
public String inspect(Map<String, String> dataMap) {
|
||||
return inspect(defaultInspectLabels, dataMap);
|
||||
public String inspect(DataTime dataTime, Map<String, String> dataMap) {
|
||||
return inspect(dataTime, defaultInspectLabels, dataMap);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -355,7 +366,7 @@ public class AbstractRadarResource<D extends IDescriptor> extends
|
|||
* @param dataMap
|
||||
* @return
|
||||
*/
|
||||
public String inspect(List<InspectLabels> labels,
|
||||
public String inspect(DataTime dataTime, List<InspectLabels> labels,
|
||||
Map<String, String> dataMap) {
|
||||
if (dataMap == null) {
|
||||
return "NO DATA";
|
||||
|
@ -416,8 +427,13 @@ public class AbstractRadarResource<D extends IDescriptor> extends
|
|||
public Map<String, Object> interrogate(ReferencedCoordinate coord)
|
||||
throws VizException {
|
||||
try {
|
||||
return new HashMap<String, Object>(this.interrogate(coord
|
||||
.asLatLon()));
|
||||
DataTime displayedDate = descriptor.getTimeForResource(this);
|
||||
|
||||
if (displayedDate == null) {
|
||||
displayedDate = this.displayedDate;
|
||||
}
|
||||
return new HashMap<String, Object>(interrogate(displayedDate,
|
||||
coord.asLatLon()));
|
||||
} catch (TransformException e) {
|
||||
throw new VizException(
|
||||
"Transformation error creating lat/lon from referenced coordinate",
|
||||
|
@ -428,7 +444,7 @@ public class AbstractRadarResource<D extends IDescriptor> extends
|
|||
}
|
||||
}
|
||||
|
||||
public Map<String, String> interrogate(Coordinate latLon) {
|
||||
public Map<String, String> interrogate(DataTime dataTime, Coordinate latLon) {
|
||||
if (interrogator == null) {
|
||||
return new HashMap<String, String>();
|
||||
}
|
||||
|
@ -438,13 +454,7 @@ public class AbstractRadarResource<D extends IDescriptor> extends
|
|||
.getColorMapParameters();
|
||||
}
|
||||
|
||||
DataTime displayedDate = descriptor.getTimeForResource(this);
|
||||
|
||||
if (displayedDate == null) {
|
||||
displayedDate = this.displayedDate;
|
||||
}
|
||||
|
||||
VizRadarRecord radarRecord = getRadarRecord(displayedDate);
|
||||
VizRadarRecord radarRecord = getRadarRecord(dataTime);
|
||||
if (radarRecord != null && radarRecord.getStoredDataAsync() != null) {
|
||||
return interrogator.sample(radarRecord, latLon, params);
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ import org.opengis.referencing.crs.CoordinateReferenceSystem;
|
|||
|
||||
import com.raytheon.uf.common.dataplugin.IDecoderGettable.Amount;
|
||||
import com.raytheon.uf.common.dataplugin.radar.RadarRecord;
|
||||
import com.raytheon.uf.common.time.DataTime;
|
||||
import com.raytheon.uf.viz.core.DrawableImage;
|
||||
import com.raytheon.uf.viz.core.IGraphicsTarget;
|
||||
import com.raytheon.uf.viz.core.IMesh;
|
||||
|
@ -133,8 +134,8 @@ public class RadarRadialResource extends RadarImageResource<MapDescriptor> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String inspect(Map<String, String> dataMap) {
|
||||
StringBuilder sb = new StringBuilder(super.inspect(dataMap));
|
||||
public String inspect(DataTime dataTime, Map<String, String> dataMap) {
|
||||
StringBuilder sb = new StringBuilder(super.inspect(dataTime, dataMap));
|
||||
|
||||
if (dataMap != null && dataMap.containsKey(EAV_VALUE)) {
|
||||
sb.append(" ").append(dataMap.get(EAV_VALUE));
|
||||
|
@ -143,8 +144,8 @@ public class RadarRadialResource extends RadarImageResource<MapDescriptor> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> interrogate(Coordinate latLon) {
|
||||
Map<String, String> dataMap = super.interrogate(latLon);
|
||||
public Map<String, String> interrogate(DataTime dataTime, Coordinate latLon) {
|
||||
Map<String, String> dataMap = super.interrogate(dataTime, latLon);
|
||||
|
||||
// add EAV values to dataMap, if necessary
|
||||
if (hasCapability(EAVCapability.class)) {
|
||||
|
|
|
@ -42,6 +42,7 @@ import com.raytheon.uf.common.geospatial.ReferencedCoordinate;
|
|||
import com.raytheon.uf.common.time.DataTime;
|
||||
import com.raytheon.uf.viz.core.IGraphicsTarget;
|
||||
import com.raytheon.uf.viz.core.drawables.ColorMapParameters;
|
||||
import com.raytheon.uf.viz.core.drawables.IDescriptor.FramesInfo;
|
||||
import com.raytheon.uf.viz.core.drawables.PaintProperties;
|
||||
import com.raytheon.uf.viz.core.drawables.ResourcePair;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
|
@ -226,11 +227,11 @@ public class RadarMosaicResource extends
|
|||
if (recordsToMosaic.isEmpty() == false) {
|
||||
DataTime curTime = getTimeForResource(this);
|
||||
synchronized (this) {
|
||||
force = force || !curTime.equals(lastTime);
|
||||
mosaicRenderer.mosaic(target, new MosaicPaintProperties(
|
||||
paintProps, force), this);
|
||||
boolean forceIt = force || !curTime.equals(lastTime);
|
||||
force = false;
|
||||
lastTime = curTime;
|
||||
mosaicRenderer.mosaic(target, new MosaicPaintProperties(
|
||||
paintProps, forceIt), this);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -423,6 +424,9 @@ public class RadarMosaicResource extends
|
|||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
FramesInfo descInfo = descriptor.getFramesInfo();
|
||||
FramesInfo rscFrameInfo = new FramesInfo(descInfo.getFrameTimes(),
|
||||
descInfo.getFrameIndex(), timeMatchingMap);
|
||||
Map<AbstractRadarResource<?>, Map<String, String>> rscInspectMap = new HashMap<AbstractRadarResource<?>, Map<String, String>>();
|
||||
AbstractRadarResource<?> highestRsc = null;
|
||||
String inspectString = null;
|
||||
|
@ -475,8 +479,10 @@ public class RadarMosaicResource extends
|
|||
if (resources.isEmpty() && highestRsc != null) {
|
||||
resources.add(highestRsc);
|
||||
}
|
||||
|
||||
for (AbstractRadarResource<?> rr : resources) {
|
||||
Map<String, String> vals = rr.interrogate(coord);
|
||||
Map<String, String> vals = rr.interrogate(
|
||||
rscFrameInfo.getTimeForResource(rr), coord);
|
||||
if (vals != null) {
|
||||
rscInspectMap.put(rr, vals);
|
||||
}
|
||||
|
@ -497,7 +503,9 @@ public class RadarMosaicResource extends
|
|||
}
|
||||
|
||||
if (highestRsc != null) {
|
||||
inspectString = highestRsc.inspect(rscInspectMap.get(highestRsc));
|
||||
inspectString = highestRsc.inspect(
|
||||
rscFrameInfo.getTimeForResource(highestRsc),
|
||||
rscInspectMap.get(highestRsc));
|
||||
}
|
||||
return inspectString == null ? "NO DATA" : inspectString;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue