Issue #1567 refactor updates of plots for efficiency/clarity

Change-Id: Id3d52ef2eb671138c078bc721c690867ba3dada3

Former-commit-id: b2788eb6bbc807d6fecc8e097e15dfbcb3ff8105
This commit is contained in:
Nate Jensen 2013-02-04 14:15:22 -06:00
parent ea6dec5db8
commit b9b730aac5
5 changed files with 104 additions and 100 deletions

View file

@ -83,7 +83,8 @@ public class CoopPrecipPlotInfoRetriever extends AbstractPlotInfoRetriever {
info.add(stationInfo); info.add(stationInfo);
} }
} }
listener.resourceChanged(ChangeType.DATA_UPDATE, info.toArray()); listener.resourceChanged(ChangeType.DATA_UPDATE,
info.toArray(new PlotInfo[0]));
} }

View file

@ -30,10 +30,10 @@ import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.graphics.RGB;
import org.opengis.coverage.grid.GridEnvelope;
import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.referencing.crs.CoordinateReferenceSystem;
import com.raytheon.uf.common.dataquery.requests.RequestConstraint; import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
@ -89,6 +89,7 @@ import com.vividsolutions.jts.geom.Coordinate;
* 04/09/2009 952 jsanchez Plot acars. * 04/09/2009 952 jsanchez Plot acars.
* 04/13/2009 2251 jsanchez Plot profilers. * 04/13/2009 2251 jsanchez Plot profilers.
* 04/21/2009 chammack Refactor to common pointData model * 04/21/2009 chammack Refactor to common pointData model
* 02/01/2013 1567 njensen Refactor handling of updates
* *
* *
* </pre> * </pre>
@ -114,8 +115,6 @@ public class PlotResource2 extends
private Map<DataTime, FrameInformation> frameMap; private Map<DataTime, FrameInformation> frameMap;
private ConcurrentLinkedQueue<PlotInfo> stationsToParse;
private DataTime displayedTime; private DataTime displayedTime;
private RGB imageColor = null; private RGB imageColor = null;
@ -174,7 +173,6 @@ public class PlotResource2 extends
data.setAlertParser(new PlotAlertParser()); data.setAlertParser(new PlotAlertParser());
} }
this.dataTimes = new ArrayList<DataTime>(); this.dataTimes = new ArrayList<DataTime>();
this.stationsToParse = new ConcurrentLinkedQueue<PlotInfo>();
this.frameMap = new ConcurrentHashMap<DataTime, FrameInformation>(); this.frameMap = new ConcurrentHashMap<DataTime, FrameInformation>();
data.addChangeListener(this); data.addChangeListener(this);
} }
@ -213,8 +211,6 @@ public class PlotResource2 extends
issueRefresh(); issueRefresh();
} }
this.updateRecords();
List<Station> stationList = curFrame.lastComputed; List<Station> stationList = curFrame.lastComputed;
if (stationList.isEmpty()) { if (stationList.isEmpty()) {
@ -285,7 +281,6 @@ public class PlotResource2 extends
} }
} }
} }
this.updateRecords();
} }
private synchronized FrameInformation startFrameInit(DataTime time) { private synchronized FrameInformation startFrameInit(DataTime time) {
@ -298,100 +293,109 @@ public class PlotResource2 extends
return frame; return frame;
} }
protected void updateRecords() throws VizException { /**
if (stationsToParse.isEmpty()) { * Checks the plots to ensure they are displayable, ie a frame exists that
return; * matches their time and they are within the descriptor's world extent. If
} * so, schedules them for disclosure. Also checks if a plot already exists
* and this is an update, and if so, updates the plot.
*
* @param stationsToParse
* stations to potentially process and display
* @throws VizException
*/
protected void updateRecords(PlotInfo[] stationsToParse)
throws VizException {
Validate.notNull(stationsToParse);
Map<DataTime, List<PlotInfo>> plots = new HashMap<DataTime, List<PlotInfo>>(); Map<DataTime, List<PlotInfo>> plots = new HashMap<DataTime, List<PlotInfo>>();
// Sort plots into datatimes // Sort plots into normalized datatimes that should match frames
while (!stationsToParse.isEmpty()) { for (PlotInfo info : stationsToParse) {
PlotInfo info = stationsToParse.poll();
DataTime normTime = getNormalizedTime(info.dataTime); DataTime normTime = getNormalizedTime(info.dataTime);
List<PlotInfo> list = plots.get(normTime); if (frameMap.containsKey(normTime)) {
if (list == null) { List<PlotInfo> list = plots.get(normTime);
list = new ArrayList<PlotInfo>(); if (list == null) {
plots.put(normTime, list); list = new ArrayList<PlotInfo>();
plots.put(normTime, list);
}
list.add(info);
} }
list.add(info);
} }
PixelExtent worldExtent = new PixelExtent(0, descriptor GridEnvelope range = descriptor.getGridGeometry().getGridRange();
.getGridGeometry().getGridRange().getHigh(0), 0, descriptor PixelExtent worldExtent = new PixelExtent(range.getLow(0),
.getGridGeometry().getGridRange().getHigh(1)); range.getHigh(0), range.getLow(1), range.getHigh(1));
for (Entry<DataTime, List<PlotInfo>> entry : plots.entrySet()) { for (Entry<DataTime, List<PlotInfo>> entry : plots.entrySet()) {
DataTime time = entry.getKey(); DataTime time = entry.getKey();
List<PlotInfo> info = entry.getValue(); List<PlotInfo> info = entry.getValue();
FrameInformation frameInfo = frameMap.get(time); FrameInformation frameInfo = frameMap.get(time);
if (frameInfo == null) { if (frameInfo != null) {
continue; Map<String, Station> stationMap = frameInfo.stationMap;
} for (PlotInfo plot : info) {
Map<String, Station> stationMap = frameInfo.stationMap; if (plot.stationId == null) {
for (PlotInfo plot : info) { plot.stationId = plot.latitude + "#" + plot.longitude;
if (plot.stationId == null) {
plot.stationId = plot.latitude + "#" + plot.longitude;
}
if (stationMap.containsKey(plot.stationId)) {
Station existingStation = stationMap.get(plot.stationId);
if (existingStation.plotImage != null) {
existingStation.plotImage.getImage().dispose();
existingStation.plotImage = null;
} }
boolean dup = false; synchronized (stationMap) {
for (int i = 0; i < existingStation.info.length; i++) { if (stationMap.containsKey(plot.stationId)) {
if (existingStation.info[i].dataURI processUpdatedPlot(stationMap.get(plot.stationId),
.equals(plot.dataURI)) { plot);
// existingStation.info[i] = plot; } else {
dup = true; double[] thisLocationPixel = descriptor
break; .worldToPixel(new double[] {
plot.longitude, plot.latitude });
if (thisLocationPixel != null
&& worldExtent.contains(
thisLocationPixel[0],
thisLocationPixel[1])) {
Station station = new Station();
station.info = new PlotInfo[] { plot };
station.pixelLocation = new Coordinate(
thisLocationPixel[0],
thisLocationPixel[1]);
stationMap.put(plot.stationId, station);
}
} }
} }
if (!dup) {
existingStation.info = Arrays.copyOf(
existingStation.info,
existingStation.info.length + 1);
existingStation.info[existingStation.info.length - 1] = plot;
Arrays.sort(existingStation.info,
new Comparator<PlotInfo>() {
@Override
public int compare(PlotInfo o1, PlotInfo o2) {
return o1.dataTime
.compareTo(o2.dataTime);
}
});
}
} else {
Station station = new Station();
station.info = new PlotInfo[] { plot };
double[] thisLocationPixel = descriptor
.worldToPixel(new double[] { plot.longitude,
plot.latitude });
if (thisLocationPixel == null
|| !worldExtent.contains(thisLocationPixel[0],
thisLocationPixel[1])) {
continue;
}
station.pixelLocation = new Coordinate(
thisLocationPixel[0], thisLocationPixel[1]);
stationMap.put(plot.stationId, station);
} }
}
// if (time.equals(displayedTime)) {
progressiveDisclosure.update(stationMap.values(), time);
// }
}
}
public void addRecord(Object[] objs) throws VizException { progressiveDisclosure.update(stationMap.values(), time);
Validate.notNull(objs); }
for (Object obj : objs) {
this.stationsToParse.offer((PlotInfo) obj);
} }
issueRefresh(); issueRefresh();
} }
/**
* Updates an existing station with a new plot.
*
* @param existingStation
* the existing station
* @param plot
* the newly received plot
*/
protected void processUpdatedPlot(Station existingStation, PlotInfo plot) {
if (existingStation.plotImage != null) {
existingStation.plotImage.getImage().dispose();
existingStation.plotImage = null;
}
boolean dup = false;
for (int i = 0; i < existingStation.info.length; i++) {
if (existingStation.info[i].dataURI.equals(plot.dataURI)) {
dup = true;
break;
}
}
if (!dup) {
existingStation.info = Arrays.copyOf(existingStation.info,
existingStation.info.length + 1);
existingStation.info[existingStation.info.length - 1] = plot;
Arrays.sort(existingStation.info, new Comparator<PlotInfo>() {
@Override
public int compare(PlotInfo o1, PlotInfo o2) {
return o1.dataTime.compareTo(o2.dataTime);
}
});
}
}
private DataTime getNormalizedTime(DataTime time) { private DataTime getNormalizedTime(DataTime time) {
if (this.resourceData.getBinOffset() != null) { if (this.resourceData.getBinOffset() != null) {
return this.resourceData.getBinOffset().getNormalizedTime(time); return this.resourceData.getBinOffset().getNormalizedTime(time);
@ -449,6 +453,8 @@ public class PlotResource2 extends
resourceData.getMetadataMap()); resourceData.getMetadataMap());
metadataMap.put("dataTime", time); metadataMap.put("dataTime", time);
// results will be sent to resourceChanged(DATA_UPDATE) on current
// thread
resourceData.getPlotInfoRetriever().getStations(this, thisFrameTime, resourceData.getPlotInfoRetriever().getStations(this, thisFrameTime,
metadataMap); metadataMap);
} }
@ -536,10 +542,8 @@ public class PlotResource2 extends
@Override @Override
public void resourceChanged(ChangeType type, Object object) { public void resourceChanged(ChangeType type, Object object) {
if (type.equals(ChangeType.DATA_UPDATE)) { if (type.equals(ChangeType.DATA_UPDATE)) {
Object[] pdos = (Object[]) object;
try { try {
addRecord(pdos); updateRecords((PlotInfo[]) object);
} catch (VizException e) { } catch (VizException e) {
statusHandler.handle(Priority.PROBLEM, statusHandler.handle(Priority.PROBLEM,
"Error updating plot resource", e); "Error updating plot resource", e);
@ -665,7 +669,7 @@ public class PlotResource2 extends
@Override @Override
public void remove(DataTime dataTime) { public void remove(DataTime dataTime) {
super.remove(dataTime); super.remove(dataTime);
FrameInformation frameInfo = this.frameMap.get(dataTime); FrameInformation frameInfo = this.frameMap.remove(dataTime);
if (frameInfo != null) { if (frameInfo != null) {
for (Station s : frameInfo.stationMap.values()) { for (Station s : frameInfo.stationMap.values()) {
if (s != null && s.plotImage != null) { if (s != null && s.plotImage != null) {
@ -674,7 +678,6 @@ public class PlotResource2 extends
} }
} }
frameInfo.stationMap.clear(); frameInfo.stationMap.clear();
this.frameMap.remove(dataTime);
} }
} }

View file

@ -133,7 +133,7 @@ public class FullDataPlotInfoRetriever extends AbstractPlotInfoRetriever {
result.add(info); result.add(info);
} }
listener.resourceChanged(ChangeType.DATA_UPDATE, listener.resourceChanged(ChangeType.DATA_UPDATE,
result.toArray()); result.toArray(new PlotInfo[0]));
return Status.OK_STATUS; return Status.OK_STATUS;
} }

View file

@ -116,6 +116,7 @@ public class PointDataPlotInfoRetriever extends AbstractDbPlotInfoRetriever {
dq = getQueryObject(metadataMap); dq = getQueryObject(metadataMap);
} }
List<PlotInfo> info = runStationQuery(dq); List<PlotInfo> info = runStationQuery(dq);
listener.resourceChanged(ChangeType.DATA_UPDATE, info.toArray()); listener.resourceChanged(ChangeType.DATA_UPDATE,
info.toArray(new PlotInfo[0]));
} }
} }

View file

@ -46,8 +46,6 @@ import com.raytheon.uf.viz.core.catalog.DbQuery;
import com.raytheon.uf.viz.core.exception.VizException; import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.rsc.IResourceDataChanged; import com.raytheon.uf.viz.core.rsc.IResourceDataChanged;
import com.raytheon.uf.viz.core.rsc.IResourceDataChanged.ChangeType; import com.raytheon.uf.viz.core.rsc.IResourceDataChanged.ChangeType;
import com.raytheon.uf.viz.core.status.StatusConstants;
import com.raytheon.viz.pointdata.Activator;
import com.raytheon.viz.pointdata.PlotInfo; import com.raytheon.viz.pointdata.PlotInfo;
import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Envelope; import com.vividsolutions.jts.geom.Envelope;
@ -69,7 +67,8 @@ import com.vividsolutions.jts.geom.Envelope;
* @version 1.0 * @version 1.0
*/ */
public class ScatterometerPlotInfoRetriever extends PointDataPlotInfoRetriever { public class ScatterometerPlotInfoRetriever extends PointDataPlotInfoRetriever {
private static final transient IUFStatusHandler statusHandler = UFStatus.getHandler(ScatterometerPlotInfoRetriever.class); private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(ScatterometerPlotInfoRetriever.class);
private static final int MAX_RESULT_SIZE = 2000; private static final int MAX_RESULT_SIZE = 2000;
@ -135,7 +134,8 @@ public class ScatterometerPlotInfoRetriever extends PointDataPlotInfoRetriever {
List<PlotInfo> stations = getStations(request.metadataMap); List<PlotInfo> stations = getStations(request.metadataMap);
if (stations != null && !stations.isEmpty()) { if (stations != null && !stations.isEmpty()) {
request.listener.resourceChanged( request.listener.resourceChanged(
ChangeType.DATA_UPDATE, stations.toArray()); ChangeType.DATA_UPDATE,
stations.toArray(new PlotInfo[0]));
} }
if (stations != null && stations.size() == MAX_RESULT_SIZE) { if (stations != null && stations.size() == MAX_RESULT_SIZE) {
for (PlotInfo station : stations) { for (PlotInfo station : stations) {
@ -200,11 +200,12 @@ public class ScatterometerPlotInfoRetriever extends PointDataPlotInfoRetriever {
super.addColumns(dq); super.addColumns(dq);
dq.addColumn("id"); dq.addColumn("id");
} }
/* (non-Javadoc) /*
* @see com.raytheon.viz.pointdata.rsc.retrieve.PointDataPlotInfoRetriever#getPlotInfo(java.lang.Object[]) * (non-Javadoc)
*
* @see com.raytheon.viz.pointdata.rsc.retrieve.PointDataPlotInfoRetriever#
* getPlotInfo(java.lang.Object[])
*/ */
@Override @Override
protected PlotInfo getPlotInfo(Object[] data) { protected PlotInfo getPlotInfo(Object[] data) {
@ -213,8 +214,6 @@ public class ScatterometerPlotInfoRetriever extends PointDataPlotInfoRetriever {
return info; return info;
} }
public void getStations(IResourceDataChanged listener, DataTime time, public void getStations(IResourceDataChanged listener, DataTime time,
HashMap<String, RequestConstraint> metadataMap) throws VizException { HashMap<String, RequestConstraint> metadataMap) throws VizException {
Request request = new Request(time, WORLD_ENVELOPE); Request request = new Request(time, WORLD_ENVELOPE);