From b9b730aac5a1f54c25ba3490099b419ca295a610 Mon Sep 17 00:00:00 2001 From: Nate Jensen Date: Mon, 4 Feb 2013 14:15:22 -0600 Subject: [PATCH] Issue #1567 refactor updates of plots for efficiency/clarity Change-Id: Id3d52ef2eb671138c078bc721c690867ba3dada3 Former-commit-id: b2788eb6bbc807d6fecc8e097e15dfbcb3ff8105 --- .../CoopPrecipPlotInfoRetriever.java | 3 +- .../viz/pointdata/rsc/PlotResource2.java | 177 +++++++++--------- .../retrieve/FullDataPlotInfoRetriever.java | 2 +- .../retrieve/PointDataPlotInfoRetriever.java | 3 +- .../ScatterometerPlotInfoRetriever.java | 19 +- 5 files changed, 104 insertions(+), 100 deletions(-) diff --git a/cave/com.raytheon.uf.viz.coopprecip/src/com/raytheon/uf/viz/coopprecip/CoopPrecipPlotInfoRetriever.java b/cave/com.raytheon.uf.viz.coopprecip/src/com/raytheon/uf/viz/coopprecip/CoopPrecipPlotInfoRetriever.java index 41b3400cf1..487dfb8a25 100644 --- a/cave/com.raytheon.uf.viz.coopprecip/src/com/raytheon/uf/viz/coopprecip/CoopPrecipPlotInfoRetriever.java +++ b/cave/com.raytheon.uf.viz.coopprecip/src/com/raytheon/uf/viz/coopprecip/CoopPrecipPlotInfoRetriever.java @@ -83,7 +83,8 @@ public class CoopPrecipPlotInfoRetriever extends AbstractPlotInfoRetriever { info.add(stationInfo); } } - listener.resourceChanged(ChangeType.DATA_UPDATE, info.toArray()); + listener.resourceChanged(ChangeType.DATA_UPDATE, + info.toArray(new PlotInfo[0])); } diff --git a/cave/com.raytheon.viz.pointdata/src/com/raytheon/viz/pointdata/rsc/PlotResource2.java b/cave/com.raytheon.viz.pointdata/src/com/raytheon/viz/pointdata/rsc/PlotResource2.java index 0b8c9becb8..8786d7f3cb 100644 --- a/cave/com.raytheon.viz.pointdata/src/com/raytheon/viz/pointdata/rsc/PlotResource2.java +++ b/cave/com.raytheon.viz.pointdata/src/com/raytheon/viz/pointdata/rsc/PlotResource2.java @@ -30,10 +30,10 @@ import java.util.Map; import java.util.Map.Entry; import java.util.TreeMap; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentLinkedQueue; import org.apache.commons.lang.Validate; import org.eclipse.swt.graphics.RGB; +import org.opengis.coverage.grid.GridEnvelope; import org.opengis.referencing.crs.CoordinateReferenceSystem; 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/13/2009 2251 jsanchez Plot profilers. * 04/21/2009 chammack Refactor to common pointData model + * 02/01/2013 1567 njensen Refactor handling of updates * * * @@ -114,8 +115,6 @@ public class PlotResource2 extends private Map frameMap; - private ConcurrentLinkedQueue stationsToParse; - private DataTime displayedTime; private RGB imageColor = null; @@ -174,7 +173,6 @@ public class PlotResource2 extends data.setAlertParser(new PlotAlertParser()); } this.dataTimes = new ArrayList(); - this.stationsToParse = new ConcurrentLinkedQueue(); this.frameMap = new ConcurrentHashMap(); data.addChangeListener(this); } @@ -213,8 +211,6 @@ public class PlotResource2 extends issueRefresh(); } - this.updateRecords(); - List stationList = curFrame.lastComputed; if (stationList.isEmpty()) { @@ -285,7 +281,6 @@ public class PlotResource2 extends } } } - this.updateRecords(); } private synchronized FrameInformation startFrameInit(DataTime time) { @@ -298,100 +293,109 @@ public class PlotResource2 extends return frame; } - protected void updateRecords() throws VizException { - if (stationsToParse.isEmpty()) { - return; - } - + /** + * Checks the plots to ensure they are displayable, ie a frame exists that + * 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> plots = new HashMap>(); - // Sort plots into datatimes - while (!stationsToParse.isEmpty()) { - PlotInfo info = stationsToParse.poll(); + // Sort plots into normalized datatimes that should match frames + for (PlotInfo info : stationsToParse) { DataTime normTime = getNormalizedTime(info.dataTime); - List list = plots.get(normTime); - if (list == null) { - list = new ArrayList(); - plots.put(normTime, list); + if (frameMap.containsKey(normTime)) { + List list = plots.get(normTime); + if (list == null) { + list = new ArrayList(); + plots.put(normTime, list); + } + list.add(info); } - list.add(info); } - PixelExtent worldExtent = new PixelExtent(0, descriptor - .getGridGeometry().getGridRange().getHigh(0), 0, descriptor - .getGridGeometry().getGridRange().getHigh(1)); + GridEnvelope range = descriptor.getGridGeometry().getGridRange(); + PixelExtent worldExtent = new PixelExtent(range.getLow(0), + range.getHigh(0), range.getLow(1), range.getHigh(1)); for (Entry> entry : plots.entrySet()) { DataTime time = entry.getKey(); List info = entry.getValue(); FrameInformation frameInfo = frameMap.get(time); - if (frameInfo == null) { - continue; - } - Map stationMap = frameInfo.stationMap; - for (PlotInfo plot : info) { - 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; + if (frameInfo != null) { + Map stationMap = frameInfo.stationMap; + for (PlotInfo plot : info) { + if (plot.stationId == null) { + plot.stationId = plot.latitude + "#" + plot.longitude; } - boolean dup = false; - for (int i = 0; i < existingStation.info.length; i++) { - if (existingStation.info[i].dataURI - .equals(plot.dataURI)) { - // existingStation.info[i] = plot; - dup = true; - break; + synchronized (stationMap) { + if (stationMap.containsKey(plot.stationId)) { + processUpdatedPlot(stationMap.get(plot.stationId), + plot); + } else { + double[] thisLocationPixel = descriptor + .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() { - @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 { - Validate.notNull(objs); - for (Object obj : objs) { - this.stationsToParse.offer((PlotInfo) obj); + progressiveDisclosure.update(stationMap.values(), time); + } } 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() { + @Override + public int compare(PlotInfo o1, PlotInfo o2) { + return o1.dataTime.compareTo(o2.dataTime); + } + }); + } + } + private DataTime getNormalizedTime(DataTime time) { if (this.resourceData.getBinOffset() != null) { return this.resourceData.getBinOffset().getNormalizedTime(time); @@ -449,6 +453,8 @@ public class PlotResource2 extends resourceData.getMetadataMap()); metadataMap.put("dataTime", time); + // results will be sent to resourceChanged(DATA_UPDATE) on current + // thread resourceData.getPlotInfoRetriever().getStations(this, thisFrameTime, metadataMap); } @@ -536,10 +542,8 @@ public class PlotResource2 extends @Override public void resourceChanged(ChangeType type, Object object) { if (type.equals(ChangeType.DATA_UPDATE)) { - Object[] pdos = (Object[]) object; - try { - addRecord(pdos); + updateRecords((PlotInfo[]) object); } catch (VizException e) { statusHandler.handle(Priority.PROBLEM, "Error updating plot resource", e); @@ -665,7 +669,7 @@ public class PlotResource2 extends @Override public void remove(DataTime dataTime) { super.remove(dataTime); - FrameInformation frameInfo = this.frameMap.get(dataTime); + FrameInformation frameInfo = this.frameMap.remove(dataTime); if (frameInfo != null) { for (Station s : frameInfo.stationMap.values()) { if (s != null && s.plotImage != null) { @@ -674,7 +678,6 @@ public class PlotResource2 extends } } frameInfo.stationMap.clear(); - this.frameMap.remove(dataTime); } } diff --git a/cave/com.raytheon.viz.pointdata/src/com/raytheon/viz/pointdata/rsc/retrieve/FullDataPlotInfoRetriever.java b/cave/com.raytheon.viz.pointdata/src/com/raytheon/viz/pointdata/rsc/retrieve/FullDataPlotInfoRetriever.java index 2398054438..800fc49138 100644 --- a/cave/com.raytheon.viz.pointdata/src/com/raytheon/viz/pointdata/rsc/retrieve/FullDataPlotInfoRetriever.java +++ b/cave/com.raytheon.viz.pointdata/src/com/raytheon/viz/pointdata/rsc/retrieve/FullDataPlotInfoRetriever.java @@ -133,7 +133,7 @@ public class FullDataPlotInfoRetriever extends AbstractPlotInfoRetriever { result.add(info); } listener.resourceChanged(ChangeType.DATA_UPDATE, - result.toArray()); + result.toArray(new PlotInfo[0])); return Status.OK_STATUS; } diff --git a/cave/com.raytheon.viz.pointdata/src/com/raytheon/viz/pointdata/rsc/retrieve/PointDataPlotInfoRetriever.java b/cave/com.raytheon.viz.pointdata/src/com/raytheon/viz/pointdata/rsc/retrieve/PointDataPlotInfoRetriever.java index 600c3861a3..f1cedb0cc4 100644 --- a/cave/com.raytheon.viz.pointdata/src/com/raytheon/viz/pointdata/rsc/retrieve/PointDataPlotInfoRetriever.java +++ b/cave/com.raytheon.viz.pointdata/src/com/raytheon/viz/pointdata/rsc/retrieve/PointDataPlotInfoRetriever.java @@ -116,6 +116,7 @@ public class PointDataPlotInfoRetriever extends AbstractDbPlotInfoRetriever { dq = getQueryObject(metadataMap); } List info = runStationQuery(dq); - listener.resourceChanged(ChangeType.DATA_UPDATE, info.toArray()); + listener.resourceChanged(ChangeType.DATA_UPDATE, + info.toArray(new PlotInfo[0])); } } diff --git a/cave/com.raytheon.viz.pointdata/src/com/raytheon/viz/pointdata/rsc/retrieve/ScatterometerPlotInfoRetriever.java b/cave/com.raytheon.viz.pointdata/src/com/raytheon/viz/pointdata/rsc/retrieve/ScatterometerPlotInfoRetriever.java index 4907bfda2a..3dad54578f 100644 --- a/cave/com.raytheon.viz.pointdata/src/com/raytheon/viz/pointdata/rsc/retrieve/ScatterometerPlotInfoRetriever.java +++ b/cave/com.raytheon.viz.pointdata/src/com/raytheon/viz/pointdata/rsc/retrieve/ScatterometerPlotInfoRetriever.java @@ -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.rsc.IResourceDataChanged; 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.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Envelope; @@ -69,7 +67,8 @@ import com.vividsolutions.jts.geom.Envelope; * @version 1.0 */ 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; @@ -135,7 +134,8 @@ public class ScatterometerPlotInfoRetriever extends PointDataPlotInfoRetriever { List stations = getStations(request.metadataMap); if (stations != null && !stations.isEmpty()) { request.listener.resourceChanged( - ChangeType.DATA_UPDATE, stations.toArray()); + ChangeType.DATA_UPDATE, + stations.toArray(new PlotInfo[0])); } if (stations != null && stations.size() == MAX_RESULT_SIZE) { for (PlotInfo station : stations) { @@ -200,11 +200,12 @@ public class ScatterometerPlotInfoRetriever extends PointDataPlotInfoRetriever { super.addColumns(dq); 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 protected PlotInfo getPlotInfo(Object[] data) { @@ -213,8 +214,6 @@ public class ScatterometerPlotInfoRetriever extends PointDataPlotInfoRetriever { return info; } - - public void getStations(IResourceDataChanged listener, DataTime time, HashMap metadataMap) throws VizException { Request request = new Request(time, WORLD_ENVELOPE);