From 43c45be7b3ec7bc27037a545c5fab235c1fc85db Mon Sep 17 00:00:00 2001 From: Ben Steffensmeier Date: Wed, 3 Jun 2015 11:20:14 -0500 Subject: [PATCH] Omaha #4079 Move contours to ufcore. Former-commit-id: bd6f391f1213d02b8f11dc06dd920c3f0caaf824 --- .../feature.xml | 7 - .../com.raytheon.viz.core.contours/.classpath | 7 - cave/com.raytheon.viz.core.contours/.project | 28 - .../META-INF/MANIFEST.MF | 22 - .../build.properties | 4 - .../com.raytheon.viz.core.contours.ecl | 0 .../core/contours/ContourCreateRequest.java | 279 --- .../viz/core/contours/ContourManagerJob.java | 140 -- .../viz/core/contours/ContourRenderable.java | 550 ----- .../viz/core/contours/ContourSupport.java | 1424 ------------ .../core/contours/cache/SubGridCacheKey.java | 123 -- .../viz/core/contours/package-info.java | 24 - .../rsc/displays/GriddedContourDisplay.java | 96 - .../displays/GriddedStreamlineDisplay.java | 75 - .../core/contours/util/ContourContainer.java | 62 - .../viz/core/contours/util/FortConBuf.java | 1952 ----------------- .../viz/core/contours/util/FortConConfig.java | 62 - .../viz/core/contours/util/PointBuffer.java | 169 -- .../contours/util/StreamLineContainer.java | 85 - .../viz/core/contours/util/StrmPak.java | 1071 --------- .../viz/core/contours/util/StrmPakConfig.java | 75 - 21 files changed, 6255 deletions(-) delete mode 100644 cave/com.raytheon.viz.core.contours/.classpath delete mode 100644 cave/com.raytheon.viz.core.contours/.project delete mode 100644 cave/com.raytheon.viz.core.contours/META-INF/MANIFEST.MF delete mode 100644 cave/com.raytheon.viz.core.contours/build.properties delete mode 100644 cave/com.raytheon.viz.core.contours/com.raytheon.viz.core.contours.ecl delete mode 100644 cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/ContourCreateRequest.java delete mode 100644 cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/ContourManagerJob.java delete mode 100644 cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/ContourRenderable.java delete mode 100644 cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/ContourSupport.java delete mode 100644 cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/cache/SubGridCacheKey.java delete mode 100644 cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/package-info.java delete mode 100644 cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/rsc/displays/GriddedContourDisplay.java delete mode 100644 cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/rsc/displays/GriddedStreamlineDisplay.java delete mode 100644 cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/util/ContourContainer.java delete mode 100644 cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/util/FortConBuf.java delete mode 100644 cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/util/FortConConfig.java delete mode 100644 cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/util/PointBuffer.java delete mode 100644 cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/util/StreamLineContainer.java delete mode 100644 cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/util/StrmPak.java delete mode 100644 cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/util/StrmPakConfig.java diff --git a/cave/com.raytheon.uf.viz.core.feature/feature.xml b/cave/com.raytheon.uf.viz.core.feature/feature.xml index 3352c1301e..b0528969d1 100644 --- a/cave/com.raytheon.uf.viz.core.feature/feature.xml +++ b/cave/com.raytheon.uf.viz.core.feature/feature.xml @@ -96,13 +96,6 @@ version="0.0.0" unpack="false"/> - - - - - - - - diff --git a/cave/com.raytheon.viz.core.contours/.project b/cave/com.raytheon.viz.core.contours/.project deleted file mode 100644 index 8785de6776..0000000000 --- a/cave/com.raytheon.viz.core.contours/.project +++ /dev/null @@ -1,28 +0,0 @@ - - - com.raytheon.viz.core.contours - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - diff --git a/cave/com.raytheon.viz.core.contours/META-INF/MANIFEST.MF b/cave/com.raytheon.viz.core.contours/META-INF/MANIFEST.MF deleted file mode 100644 index 8c5c7ebfef..0000000000 --- a/cave/com.raytheon.viz.core.contours/META-INF/MANIFEST.MF +++ /dev/null @@ -1,22 +0,0 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Contour Generation and Display -Bundle-SymbolicName: com.raytheon.viz.core.contours -Bundle-Version: 1.15.2.qualifier -Bundle-Vendor: Raytheon -Bundle-RequiredExecutionEnvironment: JavaSE-1.7 -Bundle-ActivationPolicy: lazy -Require-Bundle: com.raytheon.uf.viz.core;bundle-version="1.14.1", - org.eclipse.core.runtime;bundle-version="3.8.0", - org.eclipse.ui;bundle-version="3.8.0", - com.raytheon.uf.common.geospatial;bundle-version="1.14.0", - com.raytheon.uf.common.util, - com.raytheon.uf.common.wxmath, - com.raytheon.uf.common.style, - com.raytheon.uf.common.status, - com.raytheon.uf.common.numeric;bundle-version="1.14.0", - org.apache.commons.collections -Import-Package: com.raytheon.viz.core.interval -Export-Package: com.raytheon.viz.core.contours, - com.raytheon.viz.core.contours.rsc.displays, - com.raytheon.viz.core.contours.util diff --git a/cave/com.raytheon.viz.core.contours/build.properties b/cave/com.raytheon.viz.core.contours/build.properties deleted file mode 100644 index 5b359b5b78..0000000000 --- a/cave/com.raytheon.viz.core.contours/build.properties +++ /dev/null @@ -1,4 +0,0 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . \ No newline at end of file diff --git a/cave/com.raytheon.viz.core.contours/com.raytheon.viz.core.contours.ecl b/cave/com.raytheon.viz.core.contours/com.raytheon.viz.core.contours.ecl deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/ContourCreateRequest.java b/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/ContourCreateRequest.java deleted file mode 100644 index fa420d7d18..0000000000 --- a/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/ContourCreateRequest.java +++ /dev/null @@ -1,279 +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.viz.core.contours; - -import org.geotools.coverage.grid.GeneralGridGeometry; - -import com.raytheon.uf.common.numeric.source.DataSource; -import com.raytheon.uf.common.style.contour.ContourPreferences; -import com.raytheon.uf.viz.core.IExtent; -import com.raytheon.uf.viz.core.IGraphicsTarget; -import com.raytheon.uf.viz.core.map.IMapDescriptor; -import com.raytheon.viz.core.contours.ContourSupport.ContourGroup; - -/** - * ContourCreateRequest - * - * A request containing all the data needed for a ContourManagerJob to create - * contours. The created contours are placed back into this object so keep a - * reference around to check for finished contours. - * - *
- * 
- *    SOFTWARE HISTORY
- *   
- * Date          Ticket#  Engineer    Description
- * ------------- -------- ----------- --------------------------
- * Feb 25, 2011           ekladstrup  Initial creation
- * Feb 27, 2014  2791     bsteffen    Switch from IDataRecord to DataSource
- * 
- * 
- * 
- * - * @author ekladstrup - * @version 1 - */ -public class ContourCreateRequest { - - public ContourCreateRequest(String identifier, DataSource[] source, - float level, IExtent pixelExtent, double currentDensity, - double currentMagnification, GeneralGridGeometry imageGridGeometry, - IGraphicsTarget target, IMapDescriptor descriptor, - ContourPreferences prefs, float zoom) { - super(); - this.identifier = identifier; - this.source = source; - this.level = level; - this.pixelExtent = pixelExtent; - this.imageGridGeometry = imageGridGeometry; - this.target = target; - this.descriptor = descriptor; - this.prefs = prefs; - this.currentDensity = currentDensity; - this.currentMagnification = currentMagnification; - this.zoom = zoom; - this.canceled = false; - this.contourGroup = null; - } - - public String getIdentifier() { - return identifier; - } - - public void setIdentifier(String identifier) { - this.identifier = identifier; - } - - public DataSource[] getSource() { - return source; - } - - public void setSource(DataSource[] source) { - this.source = source; - } - - public float getLevel() { - return level; - } - - public void setLevel(float level) { - this.level = level; - } - - public IExtent getPixelExtent() { - return pixelExtent; - } - - public void setPixelExtent(IExtent pixelExtent) { - this.pixelExtent = pixelExtent; - } - - public double getCurrentDensity() { - return currentDensity; - } - - public void setCurrentDensity(double currentDensity) { - this.currentDensity = currentDensity; - } - - public double getCurrentMagnification() { - return currentMagnification; - } - - public void setCurrentMagnification(double currentMagnification) { - this.currentMagnification = currentMagnification; - } - - public GeneralGridGeometry getImageGridGeometry() { - return imageGridGeometry; - } - - public void setImageGridGeometry(GeneralGridGeometry imageGridGeometry) { - this.imageGridGeometry = imageGridGeometry; - } - - public IGraphicsTarget getTarget() { - return target; - } - - public void setTarget(IGraphicsTarget target) { - this.target = target; - } - - public IMapDescriptor getDescriptor() { - return descriptor; - } - - public void setDescriptor(IMapDescriptor descriptor) { - this.descriptor = descriptor; - } - - public ContourPreferences getPrefs() { - return prefs; - } - - public void setPrefs(ContourPreferences prefs) { - this.prefs = prefs; - } - - public float getZoom() { - return zoom; - } - - public void setZoom(float zoom) { - this.zoom = zoom; - } - - public boolean isCanceled() { - return canceled; - } - - public void setCanceled(boolean cancel) { - this.canceled = cancel; - } - - public ContourGroup getContourGroup() { - return contourGroup; - } - - public synchronized void setContourGroup(ContourGroup contourGroup) { - // synchronized so disposed can't get set after it is checked - if (!this.disposed) { - this.contourGroup = contourGroup; - } else { - contourGroup.negValueShape.dispose(); - contourGroup.posValueShape.dispose(); - } - } - - private String identifier; - - private DataSource[] source; - - private float level; - - private IExtent pixelExtent; - - private double currentDensity; - - private double currentMagnification; - - private GeneralGridGeometry imageGridGeometry; - - private IGraphicsTarget target; - - private IMapDescriptor descriptor; - - private ContourPreferences prefs; - - private float zoom; - - private boolean canceled; - - private ContourGroup contourGroup; - - private boolean disposed = false; - - public boolean equals(Object arg) { - boolean rval = true; - - if (!(arg instanceof ContourCreateRequest)) { - return false; - } - - ContourCreateRequest rhs = (ContourCreateRequest) arg; - - // right now comparing: - // identifier, level, pixelExtent, currentDensity, currentMagnification, - // prefs, zoom, imageGridGeometry, mapGridGeometry - // NOT COMPARING: - // record, worldGridToCRSTransform, target, descriptor - // Should never use canceled or contourGroup to check equality - if (identifier != null && !identifier.equals(rhs.getIdentifier())) { - rval = false; - } else if (!(level == rhs.getLevel())) { - rval = false; - } else if (pixelExtent != null - && !(pixelExtent.equals(rhs.getPixelExtent()))) { - rval = false; - } else if (!(currentDensity == rhs.getCurrentDensity())) { - rval = false; - } else if (!(currentMagnification == rhs.getCurrentMagnification())) { - rval = false; - } else if (prefs != null && !(this.prefs.equals(rhs.getPrefs()))) { - rval = false; - } else if (!(zoom == rhs.getZoom())) { - rval = false; - } else if (imageGridGeometry != null - && !(this.imageGridGeometry.equals(rhs.getImageGridGeometry()))) { - rval = false; - } - - // if nothing set rval to false (not equal) - // check that references to null are the same - // if this instances references are not null then - // rhs with null references should be caught above - // so only worry about this.* == null and rhs.* != null - if (rval == true) { - if (identifier == null && rhs.getIdentifier() != null) { - rval = false; - } else if (pixelExtent == null && rhs.getPixelExtent() != null) { - rval = false; - } else if (prefs == null && rhs.getPrefs() != null) { - rval = false; - } else if (imageGridGeometry == null - && rhs.getImageGridGeometry() != null) { - rval = false; - } - } - - return rval; - } - - public synchronized void dispose() { - // synchronized to avoid leaking memory because of a missed dispose - this.disposed = true; - if (contourGroup != null) { - this.contourGroup.posValueShape.dispose(); - this.contourGroup.negValueShape.dispose(); - this.contourGroup = null; - } - } -} diff --git a/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/ContourManagerJob.java b/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/ContourManagerJob.java deleted file mode 100644 index 28d1fd9698..0000000000 --- a/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/ContourManagerJob.java +++ /dev/null @@ -1,140 +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.viz.core.contours; - -import java.util.concurrent.ConcurrentLinkedQueue; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.Job; - -import com.raytheon.viz.core.contours.ContourSupport.ContourGroup; - -/** - * ContourManagerJob - * - * Provides a job that can create contours asynchronously - * - *
- * 
- *    SOFTWARE HISTORY
- *   
- * Date          Ticket#   Engineer   Description
- * ------------- -------- ----------- --------------------------
- * Oct 24, 2007           chammack    Initial Creation.
- * Feb 27, 2014  2791     bsteffen    Switch from IDataRecord to DataSource
- * 
- * 
- * - * @author chammack - * @version 1 - */ -public class ContourManagerJob extends Job { - - private static ContourManagerJob instance; - - private ConcurrentLinkedQueue requestQueue; - - private ContourManagerJob() { - super("Contouring..."); - this.requestQueue = new ConcurrentLinkedQueue(); - } - - /** - * Get instance - * - * @return - */ - public static synchronized ContourManagerJob getInstance() { - if (instance == null) { - instance = new ContourManagerJob(); - instance.setSystem(false); - instance.schedule(); - } - - return instance; - } - - /** - * Request a contour group - * - * @param identifier - * @param record - * @param level - * @param extent - * @param currentDensity - * @param worldGridToCRSTransform - * @param imageGridGeometry - * @param mapGridGeometry - * @param target - * @param descriptor - * @param prefs - * @return - */ - public void request(ContourCreateRequest request) { - this.requestQueue.add(request); - - if (this.getState() != Job.RUNNING) { - this.schedule(); - } - } - - /* - * (non-Javadoc) - * - * @seeorg.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime. - * IProgressMonitor) - */ - @Override - protected IStatus run(IProgressMonitor monitor) { - - ContourCreateRequest req; - while ((req = this.requestQueue.poll()) != null) { - this.setName("Contouring"); - - try { - if (req.isCanceled() || req.getContourGroup() != null) { - ;// request has been canceled or contours exist - } else { - long t0 = System.currentTimeMillis(); - ContourGroup cg = null; - cg = ContourSupport.createContours(req.getSource(), - req.getLevel(), req.getPixelExtent(), - req.getCurrentDensity(), - req.getCurrentMagnification(), - req.getImageGridGeometry(), req.getTarget(), - req.getDescriptor(), req.getPrefs(), req.getZoom()); - // setContourGroup will check if cg needs to be disposed - req.setContourGroup(cg); - System.out.println("Total time taken: " - + (System.currentTimeMillis() - t0)); - } - } catch (Throwable e) { - return new Status(Status.ERROR, ContourManagerJob.class - .getPackage().getName(), - "Error creating contours", e); - - } - } - - return Status.OK_STATUS; - } -} diff --git a/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/ContourRenderable.java b/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/ContourRenderable.java deleted file mode 100644 index 393979ee96..0000000000 --- a/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/ContourRenderable.java +++ /dev/null @@ -1,550 +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.viz.core.contours; - -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import java.util.UUID; - -import org.eclipse.swt.graphics.RGB; -import org.geotools.coverage.grid.GeneralGridGeometry; -import org.geotools.geometry.DirectPosition2D; -import org.geotools.geometry.jts.JTS; -import org.opengis.coverage.grid.GridEnvelope; -import org.opengis.referencing.operation.MathTransform; - -import com.raytheon.uf.common.geospatial.MapUtil; -import com.raytheon.uf.common.geospatial.data.GeographicDataSource; -import com.raytheon.uf.common.numeric.DataUtilities; -import com.raytheon.uf.common.numeric.buffer.FloatBufferWrapper; -import com.raytheon.uf.common.numeric.dest.DataDestination; -import com.raytheon.uf.common.numeric.filter.FillValueFilter; -import com.raytheon.uf.common.numeric.filter.InverseFillValueFilter; -import com.raytheon.uf.common.numeric.source.DataSource; -import com.raytheon.uf.common.style.contour.ContourPreferences; -import com.raytheon.uf.common.wxmath.Constants; -import com.raytheon.uf.common.wxmath.DistFilter; -import com.raytheon.uf.viz.core.IGraphicsTarget; -import com.raytheon.uf.viz.core.IGraphicsTarget.LineStyle; -import com.raytheon.uf.viz.core.PixelExtent; -import com.raytheon.uf.viz.core.datastructure.LoopProperties; -import com.raytheon.uf.viz.core.drawables.IFont; -import com.raytheon.uf.viz.core.drawables.IFont.Style; -import com.raytheon.uf.viz.core.drawables.IRenderable; -import com.raytheon.uf.viz.core.drawables.PaintProperties; -import com.raytheon.uf.viz.core.exception.VizException; -import com.raytheon.uf.viz.core.map.IMapDescriptor; -import com.raytheon.uf.viz.core.map.MapDescriptor; -import com.raytheon.viz.core.contours.ContourSupport.ContourGroup; -import com.vividsolutions.jts.geom.Coordinate; - -/** - * Generalized contour renderable - * - * May be embedded in other renderable displays or form the basis of contour - * resources - * - *
- * SOFTWARE HISTORY
- * Date          Ticket#  Engineer    Description
- * ------------- -------- ----------- --------------------------
- * Jul 10, 2008	 1233	  chammack	  Initial creation
- * Jul 18, 2013  2199     mschenke    Made code only smooth data once
- * Aug 23, 2013  2157     dgilling    Remove meteolib dependency.
- * Feb 27, 2014  2791     bsteffen    Switch from IDataRecord to DataSource and
- *                                    reduce loop freezing.
- * 
- * 
- * - * @author chammack - * @version 1.0 - */ - -public abstract class ContourRenderable implements IRenderable { - - private ContourGroup[] contourGroup; - - private Map requestMap; - - private final IMapDescriptor descriptor; - - private LineStyle lineStyle; - - private RGB color; - - private double density = 1.0; - - private double magnification = 1.0; - - private int outlineWidth; - - private final String uuid; - - private DataSource[] data; - - // This is the width of CONUS - private static final double METERS_AT_BASE_ZOOMLEVEL = 5878649.0; - - private static final double BASE_CANVAS_SIZE = 1000.0; - - private static final double ZOOM_REACTION_FACTOR = .45; - - private static final int NUMBER_CONTOURING_LEVELS = 10; - - public abstract DataSource[] getData() throws VizException; - - public abstract GeneralGridGeometry getGridGeometry() throws VizException; - - public abstract ContourPreferences getPreferences() throws VizException; - - private IFont font; - - private IFont minMaxFont; - - /** - * Constructor - * - * @param styleRule - * @param descriptor - * @param callback - * @param lineStyle - */ - public ContourRenderable(IMapDescriptor descriptor) { - - this.descriptor = descriptor; - uuid = UUID.randomUUID().toString(); - this.requestMap = new HashMap(); - } - - private DataSource[] getContourData() throws VizException { - if (data == null) { - data = getData(); - if (data != null) { - GeneralGridGeometry gridGeometry = getGridGeometry(); - ContourPreferences contourPrefs = getPreferences(); - if (gridGeometry != null && contourPrefs != null) { - data = smoothData(data, gridGeometry, contourPrefs); - } - } - } - return data; - } - - /** - * Set color - * - * @param color - * the color to set - */ - public void setColor(RGB color) { - this.color = color; - } - - /** - * @param density - * the density to set - */ - public void setDensity(double density) { - if (density > 4.0f) { - density = 4.0f; - } - this.density = density; - } - - /** - * @param magnification - * the magnification to set - */ - public void setMagnification(double magnification) { - if (this.magnification != magnification) { - if (font != null) { - font.dispose(); - font = null; - } - if (minMaxFont != null) { - minMaxFont.dispose(); - minMaxFont = null; - } - } - this.magnification = magnification; - } - - /** - * Set outline width - * - * @param outlineWidth - * the outlineWidth to set - */ - public void setOutlineWidth(int outlineWidth) { - this.outlineWidth = outlineWidth; - } - - /** - * Set the line style - * - * @param lineStyle - * the lineStyle to set - */ - public void setLineStyle(LineStyle lineStyle) { - this.lineStyle = lineStyle; - } - - /* - * (non-Javadoc) - * - * @see - * com.raytheon.viz.core.drawables.IRenderable#paint(com.raytheon.viz.core - * .IGraphicsTarget, com.raytheon.viz.core.drawables.PaintProperties) - */ - @Override - public void paint(IGraphicsTarget target, PaintProperties paintProps) - throws VizException { - synchronized (this) { - if (this.density == 0) { - return; - } - - if (contourGroup == null) { - contourGroup = new ContourGroup[NUMBER_CONTOURING_LEVELS]; - } - - if (contourGroup != null) { - if (font == null) { - font = target.getDefaultFont(); - - font = target.initializeFont(font.getFontName(), - (float) (font.getFontSize() / 1.4 * magnification), - null); - } - - if (minMaxFont == null) { - minMaxFont = target.getDefaultFont(); - - minMaxFont = target - .initializeFont( - minMaxFont.getFontName(), - (float) (minMaxFont.getFontSize() / 1.3 * magnification), - new Style[] { Style.BOLD }); - } - - // To convert from i to zoomLevel, take i + 1.0 / 2 so - // contourGroup[0] is at zoomLevel 0.5, contourGroup[1] is at - // zoomLevel 1, etc. - int i = contourGroup.length - 1; - double mapWidth = ((MapDescriptor) this.descriptor) - .getMapWidth(); - double widthInMeters = mapWidth * paintProps.getZoomLevel(); - while (i >= 0) { - double curlvl = (METERS_AT_BASE_ZOOMLEVEL) - * (Math.pow(ZOOM_REACTION_FACTOR, (i - 1.0) / 2)); - curlvl *= paintProps.getCanvasBounds().width - / BASE_CANVAS_SIZE; - if (widthInMeters <= curlvl || i == 0) { - boolean contains = (contourGroup[i] == null || contourGroup[i].lastUsedPixelExtent == null) ? false - : (contourGroup[i].lastUsedPixelExtent - .getEnvelope() - .contains(((PixelExtent) paintProps - .getView().getExtent()) - .getEnvelope())); - // calculate the pixel density - float pixelDensity = (float) (paintProps - .getCanvasBounds().width / paintProps.getView() - .getExtent().getWidth()); - - double pdRatio = contourGroup[i] == null ? 1 - : pixelDensity - / contourGroup[i].lastPixelDensity; - // Run contours if: - // 1. Contours was never ran before -or- - // 2. The area currently viewed is outside of the - // contoured window -or- - // 3. The density has changed - // 4. The pixel density has changed significantly - if (contourGroup[i] == null || !contains - || contourGroup[i].lastDensity != density - || pdRatio > 2 || pdRatio < 0.5) { - - GeneralGridGeometry gridGeometry = getGridGeometry(); - ContourPreferences contourPrefs = getPreferences(); - - // If required data unavailable, quit now - if (gridGeometry == null) { - return; - } - - DataSource[] dataRecord = getContourData(); - if (dataRecord == null) { - return; - } - - ContourGroup cg = null; - // generate the identifier - String identifier = uuid + "::" + this + "::" + i; - // grab the existing request - ContourCreateRequest existingRequest = requestMap - .get(identifier); - // create a new request - ContourCreateRequest request = new ContourCreateRequest( - identifier, dataRecord, (i + 1) / 2.0f, - paintProps.getView().getExtent(), density, - magnification, gridGeometry, target, - descriptor, contourPrefs, pixelDensity); - - if (existingRequest != null) { - // check if new request needs to replace old - if (!(request.equals(existingRequest))) { - // cancel old request - existingRequest.setCanceled(true); - // add new request - requestMap.put(identifier, request); - // send request - ContourManagerJob.getInstance().request( - request); - } - } else { - // there is no exiting request, insert new one - requestMap.put(identifier, request); - ContourManagerJob.getInstance() - .request(request); - } - - int retries = 0; - LoopProperties loopProps = paintProps - .getLoopProperties(); - if (loopProps != null && loopProps.isLooping()) { - /** - * If the display is looping, wait a few ms to - * let contouring finish so that if the - * contouring is fast enough the user is not - * presented with empty frames. If too many - * resources do this, it freezes the UI so scale - * the sleep time based off the number of - * resources because empty frames are better - * than freezing. This scaling also gives - * everyone a chance to queue up work so that - * multiprocessing is done more efficiently. - */ - retries = 100 / descriptor.getResourceList() - .size(); - } - do { - // grab request from map - request = requestMap.get(identifier); - cg = request.getContourGroup(); - retries--; - try { - if (cg == null && retries > 0) { - Thread.sleep(10); - } - } catch (InterruptedException e) { - retries = 0; - } - } while (cg == null && retries > 0); - - if (cg != null) { - if (cg != contourGroup[i]) { - // Dispose old wireframe shapes - if (contourGroup[i] != null - && contourGroup[i].posValueShape != null) { - contourGroup[i].posValueShape.dispose(); - } - - if (contourGroup[i] != null - && contourGroup[i].negValueShape != null) { - contourGroup[i].negValueShape.dispose(); - } - - contourGroup[i] = cg; - contourGroup[i].posValueShape.compile(); - contourGroup[i].negValueShape.compile(); - } - } else { - target.setNeedsRefresh(true); - } - - } - - if (contourGroup[i] != null - && paintProps - .getView() - .getExtent() - .intersects( - contourGroup[i].lastUsedPixelExtent)) { - // System.out.println("Painting group at " + i); - drawContourGroup(target, contourGroup[i]); - } else { - // see if we can display a higher level - if (i > 0) { - int j = i - 1; - if (contourGroup[j] != null) { - if (contourGroup[j].posValueShape != null) { - if (contourGroup[j].lastUsedPixelExtent - .intersects(paintProps - .getView().getExtent())) { - drawContourGroup(target, - contourGroup[j]); - } - } - } - } - - target.setNeedsRefresh(true); - - } - break; - - } - i--; - } - } - } - } - - private DataSource[] smoothData(DataSource[] dataRecord, - GeneralGridGeometry gridGeometry, ContourPreferences contourPrefs) - throws VizException { - if (contourPrefs != null && contourPrefs.getSmoothingDistance() != null) { - // Calculate the Diagnol Distance of the Grid In Meters. - DirectPosition2D upperCorner = new DirectPosition2D(gridGeometry - .getEnvelope().getUpperCorner()); - DirectPosition2D lowerCorner = new DirectPosition2D(gridGeometry - .getEnvelope().getLowerCorner()); - double distanceInM; - try { - MathTransform crs2ll = MapUtil - .getTransformToLatLon(gridGeometry - .getCoordinateReferenceSystem()); - crs2ll.transform(upperCorner, upperCorner); - crs2ll.transform(lowerCorner, lowerCorner); - upperCorner.x = MapUtil.correctLon(upperCorner.x); - lowerCorner.x = MapUtil.correctLon(lowerCorner.x); - distanceInM = JTS - .orthodromicDistance( - new Coordinate(lowerCorner.getOrdinate(0), - lowerCorner.getOrdinate(1)), - new Coordinate(upperCorner.getOrdinate(0), - upperCorner.getOrdinate(1)), MapUtil - .getLatLonProjection()); - } catch (Exception e) { - throw new VizException(e); - } - // Calculate the Diagnol Distance in Points - GridEnvelope range = gridGeometry.getGridRange(); - int nx = range.getSpan(0); - int ny = range.getSpan(1); - double distanceInPoints = Math.sqrt(nx * nx + ny * ny); - // Determine the number of points to smooth, assume - // smoothingDistance is in km - float npts = (float) (distanceInPoints - * contourPrefs.getSmoothingDistance() / (distanceInM / 1000)); - FloatBufferWrapper data = new FloatBufferWrapper(nx, ny); - DataDestination dest = InverseFillValueFilter.apply( - (DataDestination) data, Constants.LEGACY_NAN); - DataUtilities.copy(dataRecord[0], dest, nx, ny); - float[] dataArray = data.getArray(); - dataArray = DistFilter.filter(dataArray, npts, nx, ny, 1); - data = new FloatBufferWrapper(dataArray, nx, ny); - DataSource source = FillValueFilter.apply((DataSource) data, - Constants.LEGACY_NAN); - source = new GeographicDataSource(source, gridGeometry); - return new DataSource[] { source }; - } else { - return dataRecord; - } - } - - /** - * Dispose the renderable - */ - public void dispose() { - if (contourGroup != null) { - for (ContourGroup c : contourGroup) { - if (c == null) { - continue; - } - - if (c.posValueShape != null) { - c.posValueShape.dispose(); - } - if (c.negValueShape != null) { - c.negValueShape.dispose(); - } - } - } - Set keys = requestMap.keySet(); - for (String key : keys) { - requestMap.get(key).dispose(); - } - requestMap.clear(); - - if (font != null) { - font.dispose(); - font = null; - } - if (minMaxFont != null) { - minMaxFont.dispose(); - minMaxFont = null; - } - } - - private void drawContourGroup(IGraphicsTarget target, - ContourGroup contourGroup) throws VizException { - - LineStyle posLineStyle = null; - LineStyle negLineStyle = null; - - ContourPreferences prefs = getPreferences(); - - if (prefs != null - && prefs.getPositiveLinePattern() != null - && (this.lineStyle == null || this.lineStyle == LineStyle.DEFAULT)) { - posLineStyle = LineStyle.valueOf(prefs.getPositiveLinePattern()); - } else if (this.lineStyle == null - || this.lineStyle == LineStyle.DEFAULT) { - posLineStyle = LineStyle.SOLID; - } else { - posLineStyle = this.lineStyle; - } - - if (prefs != null - && prefs.getNegativeLinePattern() != null - && (this.lineStyle == null || this.lineStyle == LineStyle.DEFAULT)) { - negLineStyle = LineStyle.valueOf(prefs.getNegativeLinePattern()); - } else if (this.lineStyle == null - || this.lineStyle == LineStyle.DEFAULT) { - negLineStyle = LineStyle.DASHED_LARGE; - } else { - negLineStyle = this.lineStyle; - } - - // if (this.lineStyle == null || this.lineStyle == LineStyle.DEFAULT) { - // posLineStyle = LineStyle.SOLID; - // negLineStyle = LineStyle.DASHED_LARGE; - // } else { - // posLineStyle = this.lineStyle; - // negLineStyle = this.lineStyle; - // } - - contourGroup.drawContours(target, this.color, this.outlineWidth, - posLineStyle, negLineStyle, font, minMaxFont); - } - -} diff --git a/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/ContourSupport.java b/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/ContourSupport.java deleted file mode 100644 index 54d1f8d2ed..0000000000 --- a/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/ContourSupport.java +++ /dev/null @@ -1,1424 +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.viz.core.contours; - -import java.text.DecimalFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; -import java.util.SortedSet; -import java.util.TreeSet; - -import org.apache.commons.collections.map.LRUMap; -import org.eclipse.swt.graphics.RGB; -import org.geotools.coverage.grid.GeneralGridEnvelope; -import org.geotools.coverage.grid.GeneralGridGeometry; -import org.geotools.coverage.grid.GridEnvelope2D; -import org.geotools.coverage.grid.GridGeometry2D; -import org.geotools.geometry.Envelope2D; -import org.geotools.geometry.GeneralEnvelope; -import org.geotools.referencing.operation.DefaultMathTransformFactory; -import org.opengis.coverage.grid.GridEnvelope; -import org.opengis.referencing.crs.CoordinateReferenceSystem; -import org.opengis.referencing.datum.PixelInCell; -import org.opengis.referencing.operation.MathTransform; -import org.opengis.referencing.operation.TransformException; - -import com.raytheon.uf.common.geospatial.CRSCache; -import com.raytheon.uf.common.geospatial.MapUtil; -import com.raytheon.uf.common.geospatial.util.GridGeometryWrapChecker; -import com.raytheon.uf.common.geospatial.util.WorldWrapChecker; -import com.raytheon.uf.common.numeric.DataUtilities; -import com.raytheon.uf.common.numeric.DataUtilities.MinMax; -import com.raytheon.uf.common.numeric.buffer.FloatBufferWrapper; -import com.raytheon.uf.common.numeric.source.DataSource; -import com.raytheon.uf.common.numeric.source.OffsetDataSource; -import com.raytheon.uf.common.status.IPerformanceStatusHandler; -import com.raytheon.uf.common.status.IUFStatusHandler; -import com.raytheon.uf.common.status.PerformanceStatus; -import com.raytheon.uf.common.status.UFStatus; -import com.raytheon.uf.common.status.UFStatus.Priority; -import com.raytheon.uf.common.style.LabelingPreferences; -import com.raytheon.uf.common.style.contour.ContourPreferences; -import com.raytheon.uf.common.util.GridUtil; -import com.raytheon.uf.viz.core.DrawableString; -import com.raytheon.uf.viz.core.IExtent; -import com.raytheon.uf.viz.core.IGraphicsTarget; -import com.raytheon.uf.viz.core.IGraphicsTarget.HorizontalAlignment; -import com.raytheon.uf.viz.core.IGraphicsTarget.LineStyle; -import com.raytheon.uf.viz.core.IGraphicsTarget.VerticalAlignment; -import com.raytheon.uf.viz.core.PixelExtent; -import com.raytheon.uf.viz.core.drawables.IFont; -import com.raytheon.uf.viz.core.drawables.IWireframeShape; -import com.raytheon.uf.viz.core.exception.VizException; -import com.raytheon.uf.viz.core.map.IMapDescriptor; -import com.raytheon.viz.core.contours.cache.SubGridCacheKey; -import com.raytheon.viz.core.contours.util.ContourContainer; -import com.raytheon.viz.core.contours.util.FortConBuf; -import com.raytheon.viz.core.contours.util.FortConConfig; -import com.raytheon.viz.core.contours.util.StreamLineContainer; -import com.raytheon.viz.core.contours.util.StreamLineContainer.StreamLinePoint; -import com.raytheon.viz.core.contours.util.StrmPak; -import com.raytheon.viz.core.contours.util.StrmPakConfig; -import com.raytheon.viz.core.interval.XFormFunctions; -import com.vividsolutions.jts.geom.Geometry; - -/** - * Provides contouring wrapper. - * - *
- *
- * SOFTWARE HISTORY
- *
- * Date          Ticket#  Engineer     Description
- * ------------- -------- ------------ ----------------------------------------
- * Oct 22, 2007           chammack     Initial Creation.
- * May 26, 2009  2172     chammack     Use zoomLevel to calculate label spacing
- * Apr 26, 2010  4583     rjpeter      Replaced fortran fortconbuf with java
- *                                     port.
- * Mar 04, 2011  7747     njensen      Cached subgrid envelopes
- * Jul 09, 2012  14940    M.Porricelli Adjust arrow size for streamlines
- * Feb 15, 2013  1638     mschenke     Moved edex.common Util functions into
- *                                     common Util
- * Jun 26, 2013  1999     dgilling     Replace native fortran strmpak call
- *                                     with java port.
- * Jul 18, 2013  2199     mschenke     Ensured contouring is only occurring
- *                                     over visible area
- * Jul 23, 2013  2157     dgilling     Remove legacy stream line drawing code.
- * Feb 27, 2014  2791     bsteffen     Switch from IDataRecord to DataSource
- * Mar 17, 2015  4261     nabowle      Move performance logging to the
- *                                     performance log.
- * Mar 19, 2015  4292     nabowle      Add contour range using A1 configuration
- *                                     rules.
- *
- * 
- * - * @author chammack - * @version 1.0 - */ -public class ContourSupport { - - private static final transient IUFStatusHandler statusHandler = UFStatus - .getHandler(ContourSupport.class); - - private static final transient IPerformanceStatusHandler perfLog = PerformanceStatus - .getHandler("ContourSupport:"); - - /* - * By default contour any data source that is passed in. This is much more - * efficient than copying the data and allows us to contour any DataSource. - * - * The downside is that FortConBuf accesses each data point multiple times - * and it is possible that DataSources with lots of transformation will have - * poor performance. Since different sources will exhibit different behavior - * and it is impossible to test all sources this field provides a runtime - * flag to copy all the data so that slow sources will only need to access - * each point once at the cost of more memory and taking the time to copy. - * Hopefully this is just paranoia and this flag can be removed in the - * future. If it turns out this is necessary we will likely want to find a - * more fine grained approach to tuning this. - */ - private static boolean copyData = Boolean.getBoolean(ContourSupport.class - .getPackage().getName() + ".copyData"); - - private static float smallestContourValue = GridUtil.GRID_FILL_VALUE - 1; - - private static float largestContourValue = GridUtil.GRID_FILL_VALUE + 1; - - private static LRUMap subgridCache = new LRUMap(10); - - private ContourSupport() { - // No constructor - } - - /** - * Data structure for contouring - */ - public static class ContourGroup { - public double zoomLevel; - - public IWireframeShape posValueShape; - - public IWireframeShape negValueShape; - - public ContourGroup parent; - - public PixelExtent lastUsedPixelExtent; - - public double lastDensity; - - public double lastPixelDensity; - - public Geometry contourGeometry; - - public String minMark; - - public String[] minVals; - - public double[][] minLabelPoints; - - public String maxMark; - - public String[] maxVals; - - public double[][] maxLabelPoints; - - public void drawContours(IGraphicsTarget target, RGB color, - float lineWidth, LineStyle posLineStyle, - LineStyle negLineStyle, IFont contourLabelFont, - IFont minMaxLabelFont) throws VizException { - target.drawWireframeShape(posValueShape, color, lineWidth, - posLineStyle, contourLabelFont); - target.drawWireframeShape(negValueShape, color, lineWidth, - negLineStyle, contourLabelFont); - drawLabels(target, minMaxLabelFont, color, maxLabelPoints, maxVals, - maxMark); - drawLabels(target, minMaxLabelFont, color, minLabelPoints, minVals, - minMark); - } - - private void drawLabels(IGraphicsTarget target, IFont labelFont, - RGB color, double[][] labelPoints, String[] vals, String mark) - throws VizException { - if (labelPoints != null) { - int size = labelPoints.length; - boolean isMark = mark != null; - boolean isVal = vals != null; - VerticalAlignment markVert = VerticalAlignment.MIDDLE; - VerticalAlignment valVert = VerticalAlignment.MIDDLE; - if (isMark && isVal) { - markVert = VerticalAlignment.BOTTOM; - valVert = VerticalAlignment.TOP; - } - List strings = new ArrayList( - size); - for (int i = 0; i < size; i++) { - double point[] = labelPoints[i]; - if (isMark) { - DrawableString string = new DrawableString(mark, color); - string.font = labelFont; - string.setCoordinates(point[0], point[1], 1.0); - string.horizontalAlignment = HorizontalAlignment.CENTER; - string.verticallAlignment = markVert; - strings.add(string); - } - if (isVal) { - DrawableString string = new DrawableString(vals[i], - color); - string.font = labelFont; - string.setCoordinates(point[0], point[1], 1.0); - string.horizontalAlignment = HorizontalAlignment.CENTER; - string.verticallAlignment = valVert; - strings.add(string); - } - } - // draw all strings in a bulk operation for better performance - target.drawStrings(strings); - } - } - - } - - /** - * Create contours from provided parameters - * - * @param sources - * @param level - * @param extent - * @param currentDensity - * @param worldGridToCRSTransform - * @param imageGridGeometry - * @param mapGridGeometry - * @param target - * @param descriptor - * @param prefs - * @param zoom - * @return the ContourGroup - * @throws VizException - */ - public static ContourGroup createContours(DataSource[] sources, - float level, IExtent extent, double currentDensity, - double currentMagnification, GeneralGridGeometry imageGridGeometry, - IGraphicsTarget target, IMapDescriptor descriptor, - ContourPreferences prefs, float zoom) throws VizException { - - ContourGroup contourGroup = new ContourGroup(); - contourGroup.lastDensity = currentDensity; - contourGroup.lastPixelDensity = zoom; - contourGroup.posValueShape = target.createWireframeShape(false, - descriptor); - contourGroup.negValueShape = target.createWireframeShape(false, - descriptor); - contourGroup.zoomLevel = level; - - // Copy the pixel extent (deep copy required!) - // expand by 50% to cover the subgrid expansion - PixelExtent workingExtent = (PixelExtent) extent.clone(); - workingExtent.getEnvelope().expandBy(workingExtent.getWidth() * .5, - workingExtent.getHeight() * .5); - - // Recontour whenever outside by more than 25% - contourGroup.lastUsedPixelExtent = (PixelExtent) extent.clone(); - contourGroup.lastUsedPixelExtent.getEnvelope().expandBy( - contourGroup.lastUsedPixelExtent.getWidth() * .25, - contourGroup.lastUsedPixelExtent.getHeight() * .25); - - GeneralGridGeometry mapGridGeometry = descriptor.getGridGeometry(); - - // Step 0: Set up necessary math transforms - MathTransform rastPosToWorldGrid = null; - MathTransform rastPosToLatLon = null; - try { - DefaultMathTransformFactory factory = new DefaultMathTransformFactory(); - - CoordinateReferenceSystem rastCrs = imageGridGeometry - .getCoordinateReferenceSystem(); - CoordinateReferenceSystem mapCrs = mapGridGeometry - .getCoordinateReferenceSystem(); - - MathTransform rastGridToCrs = imageGridGeometry - .getGridToCRS(PixelInCell.CELL_CENTER); - MathTransform mapCrsToGrid = mapGridGeometry.getGridToCRS( - PixelInCell.CELL_CENTER).inverse(); - - MathTransform rastCrsToLatLon = MapUtil - .getTransformToLatLon(rastCrs); - - MathTransform crs2crs = CRSCache.getInstance().findMathTransform( - rastCrs, mapCrs); - - rastPosToWorldGrid = factory - .createConcatenatedTransform( - factory.createConcatenatedTransform(rastGridToCrs, - crs2crs), mapCrsToGrid); - - rastPosToLatLon = factory.createConcatenatedTransform( - rastGridToCrs, rastCrsToLatLon); - } catch (Exception e) { - throw new VizException("Error building Transforms", e); - } - - // Step 1:First determine the subgrid to contour - long tsg0 = System.currentTimeMillis(); - SubGridCacheKey key = new SubGridCacheKey(workingExtent, - mapGridGeometry, imageGridGeometry); - GeneralEnvelope env = (GeneralEnvelope) subgridCache.get(key); - if (env == null) { - env = calculateSubGrid(workingExtent, mapGridGeometry, - imageGridGeometry); - subgridCache.put(key, env); - } - long tsg1 = System.currentTimeMillis(); - perfLog.logDuration("Calculating sub grid", tsg1 - tsg0); - - // Step 3: Get the actual data - - if (sources.length == 1 && sources[0] != null) { - // Step 4: Determine the subgrid, if any - GridEnvelope imageRange = imageGridGeometry.getGridRange(); - - int minX = (int) Math.floor(Math.max(env.getMinimum(0), 0)); - int minY = (int) Math.floor(Math.max(env.getMinimum(1), 0)); - int maxX = (int) Math.ceil(Math.min(env.getMaximum(0), - imageRange.getHigh(0))); - int maxY = (int) Math.ceil(Math.min(env.getMaximum(1), - imageRange.getHigh(1))); - int szX = (maxX - minX) + 1; - int szY = (maxY - minY) + 1; - if (szX * szY <= 0) { - return contourGroup; - } - - /* Make contours continous for world wrapping grids. */ - int wrapNumber = GridGeometryWrapChecker - .checkForWrapping(imageGridGeometry); - if (wrapNumber >= szX - 1) { - szX = wrapNumber + 1; - } - - DataSource subgridSource = sources[0]; - if (minX != 0 || minY != 0) { - subgridSource = new OffsetDataSource(sources[0], minX, minY); - } - - if (copyData) { - subgridSource = DataUtilities.copy(subgridSource, - new FloatBufferWrapper(szX, szY), szX, szY); - } - - // Use ported legacy code to determine contour interval - ContourContainer contours = null; - FortConConfig config = new FortConConfig(); - long t0 = System.currentTimeMillis(); - String minMaxLabelFormat = null; - String minLabel = null; - String maxLabel = null; - String labelFormat = null; - int labelTrimLeft = 0; - int maxMinTrimLeft = 0; - config.badlo = smallestContourValue; - config.badhi = largestContourValue; - // The +/- 0.5 is necessary to match the contouring location on - // Awips 1 - config.xOffset = minX; - config.yOffset = minY; - config.labelSpacingLine = szX / 3; - if (config.labelSpacingLine < 1) { - config.labelSpacingLine = 1; - } - - config.labelSpacingOverall = (int) (szX * 60 - * currentMagnification / ((PixelExtent) extent).getWidth() + 0.5); - - // If nothing provided, attempt to get approximately 50 contours - if (prefs == null || prefs.getContourLabeling() == null) { - // TODO this is fairly inefficient to do every time. - MinMax mm = DataUtilities.getMinMax(subgridSource, szX, szY); - float interval = XFormFunctions - .newDataIntervalFromZoom((float) mm.getSpan() / 50, - (float) (contourGroup.lastDensity * zoom), - true, "", 10); - config.seed = new float[] { interval }; - config.mode = -50; - contours = FortConBuf.contour(subgridSource, szX, szY, config); - } else { - LabelingPreferences contourLabeling = prefs - .getContourLabeling(); - if (contourLabeling.getLabelSpacing() > 0) { - config.labelSpacingLine = szX - / contourLabeling.getLabelSpacing(); - if (config.labelSpacingLine < 1) { - config.labelSpacingLine = 1; - } - } - - // setup min/max processing - minMaxLabelFormat = contourLabeling.getMinMaxLabelFormat(); - minLabel = contourLabeling.getMinLabel(); - maxLabel = contourLabeling.getMaxLabel(); - labelFormat = contourLabeling.getLabelFormat(); - labelTrimLeft = contourLabeling.getLabelTrimLeft(); - maxMinTrimLeft = contourLabeling.getMaxMinTrimLeft(); - config.labelFormat = labelFormat; - config.generateMins = minLabel != null - && (!minLabel.equals(".") || (minMaxLabelFormat != null && minLabel - .equals("."))); - config.generateMaxes = maxLabel != null - && (!maxLabel.equals(".") || (minMaxLabelFormat != null && maxLabel - .equals("."))); - - config.minMaxRadius = (int) (currentMagnification * 3 * szX / 90); - if (config.minMaxRadius < 1) { - config.minMaxRadius = 1; - } - if (config.minMaxRadius > 7) { - config.minMaxRadius = 7; - } - - if (contourLabeling.getValues() == null - && prefs.getContourLabeling().getIncrement() > 0.0) { - // interval provided - float initialInterval = prefs.getContourLabeling() - .getIncrement(); - float interval; - if (contourLabeling.getNumberOfContours() > 0) { - MinMax mm = DataUtilities.getMinMax(subgridSource, szX, - szY); - interval = (float) mm.getSpan() - / contourLabeling.getNumberOfContours(); - if (interval < 0) { - interval = -interval; - } - if (interval > initialInterval) { - initialInterval = interval; - prefs.getContourLabeling().setIncrement( - initialInterval); - } - - // removed +1 to fix EPTC plan view and T_std - interval = XFormFunctions.newDataIntervalFromZoom( - initialInterval, - (float) ((level) * contourGroup.lastDensity), - false, "", 10); - } else { - interval = XFormFunctions.newDataIntervalFromZoom( - initialInterval, - (float) ((level) * contourGroup.lastDensity), - true, "", 10); - } - - float[] controls = new float[] { interval }; - config.mode = 0; - config.seed = controls; - - contours = FortConBuf.contour(subgridSource, szX, szY, config); - } else if (contourLabeling.getValues() != null) { - // explicit contouring values provided - float[] vals = contourLabeling.getValues(); - - /* - * A contour range is specified by setting - * numberOfContours=1000 and values={interval, minContour, - * maxContour} based on AWIPS1 configuration rules. - */ - if (vals.length == 2 - && contourLabeling.getNumberOfContours() == 1000) { - // non-positive increments treated as 1 by ForConBuf - vals = new float[] { contourLabeling.getIncrement(), - vals[0], vals[1] }; - } else { - /* - * the +0.1 makes it so numbers greater than 0.9 are - * rounded up and all other numbers are rounded down. - * This seems to make it match A1 better when the - * density is 0.67 than 2.98507 is rounded to 3 instead - * of 2 - */ - int d = (int) (2 / ((level) * contourGroup.lastDensity) + 0.1); - if (d > 1) { - int myCount = (vals.length + d - 1) / d; - float[] newVals = new float[myCount]; - int i, j; - for (i = j = 0; j < myCount; i += d, j++) { - newVals[j] = vals[i]; - } - vals = newVals; - } - if (prefs.getContourLabeling().isCreateNegativeValues()) { - float[] newVals = new float[vals.length * 2]; - for (int i = 0; i < vals.length; i++) { - newVals[vals.length + i] = vals[i]; - newVals[vals.length - i - 1] = -1 * vals[i]; - } - vals = newVals; - } - } - config.seed = vals; - if (contourLabeling.getNumberOfContours() > 0) { - config.mode = contourLabeling.getNumberOfContours(); - } else { - config.mode = vals.length; - } - contours = FortConBuf.contour(subgridSource, szX, szY, config); - } - } - - long t1 = System.currentTimeMillis(); - perfLog.logDuration("Contouring", t1 - t0); - - float contourValue = 0; - - long tTransformAccum = 0; - long tLabelAccum = 0; - long tMinMaxAccum = 0; - List labelPoints = new ArrayList(512); - - try { - DecimalFormat dfLabel = null; - - if (labelFormat != null) { - dfLabel = new DecimalFormat(labelFormat); - } else { - dfLabel = determineLabelFormat(contours.contourVals); - } - - long tZ0 = System.currentTimeMillis(); - // process min/max - processMinMaxLabels(contours, minMaxLabelFormat, minLabel, - maxLabel, rastPosToWorldGrid, contourGroup, - labelPoints, maxMinTrimLeft); - long tZ1 = System.currentTimeMillis(); - tMinMaxAccum += tZ1 - tZ0; - - correctWorldWrapping(contours, descriptor, rastPosToLatLon); - - int size = contours.xyContourPoints.size(); - // total coordinates - int totalPosCoords = 0; - int totalNegCoords = 0; - for (int i = 0; i < size; i++) { - if (contours.contourVals.get(i) > 0) { - totalPosCoords += contours.xyContourPoints.get(i).length / 2; - } else { - totalNegCoords += contours.xyContourPoints.get(i).length / 2; - } - } - - contourGroup.posValueShape.allocate(totalPosCoords); - contourGroup.negValueShape.allocate(totalNegCoords); - - for (int i = 0; i < size; i++) { - float[] contourGridPoints = contours.xyContourPoints.get(i); - float[] contourWorldPoints = new float[contourGridPoints.length]; - - try { - int contourPoints = contourGridPoints.length / 2; - tZ0 = System.currentTimeMillis(); - rastPosToWorldGrid.transform(contourGridPoints, 0, - contourWorldPoints, 0, contourPoints); - tZ1 = System.currentTimeMillis(); - tTransformAccum += (tZ1 - tZ0); - double[][] contourWorldPointsArr = new double[contourPoints][2]; - int index = 0; - for (int j = 0; j < contourPoints; j++) { - contourWorldPointsArr[j][0] = contourWorldPoints[index++]; - contourWorldPointsArr[j][1] = contourWorldPoints[index++]; - } - contourValue = contours.contourVals.get(i); - String label = dfLabel.format(contourValue); - label = label.substring(labelTrimLeft); - if (prefs != null - && prefs.getContourLabeling() != null - && prefs.getContourLabeling().getValues() != null - && labelFormat == null) { - // If we have explicit values and no explicit format - // use the default String representation of the - // given values - float[] values = prefs.getContourLabeling() - .getValues(); - for (int k = 0; k < values.length; k++) { - if (contourValue == values[k]) { - label = Float.toString(values[k]); - break; - } - } - } - IWireframeShape shapeToAddTo = null; - - if (contourValue >= 0) { - shapeToAddTo = contourGroup.posValueShape; - } else { - shapeToAddTo = contourGroup.negValueShape; - } - - shapeToAddTo.addLineSegment(contourWorldPointsArr); - - // process contour labels - // TODO perform formatting - tZ0 = System.currentTimeMillis(); - prepareLabel(shapeToAddTo, zoom, label, labelPoints, - contourWorldPointsArr); - tZ1 = System.currentTimeMillis(); - tLabelAccum += tZ1 - tZ0; - } catch (TransformException e) { - statusHandler - .handle(Priority.PROBLEM, - "Error transforming points: " - + Arrays.toString(contourGridPoints), - e); - } - } - - perfLog.logDuration("Min/Max processing", tMinMaxAccum); - perfLog.logDuration("Labeling", tLabelAccum); - perfLog.logDuration("Transformation", tTransformAccum); - } catch (Throwable e) { - throw new VizException("Error postprocessing contours", e); - } - } else if (sources.length == 2) { - GridEnvelope range = imageGridGeometry.getGridRange(); - long[] sz = { range.getSpan(0), range.getSpan(1) }; - - // Step 4: Determine the subgrid, if any - - int minX = (int) Math.floor(Math.max(env.getMinimum(0), 0)); - int minY = (int) Math.floor(Math.max(env.getMinimum(1), 0)); - int maxX = (int) Math.ceil(Math.min(env.getMaximum(0), sz[0] - 1)); - int maxY = (int) Math.ceil(Math.min(env.getMaximum(1), sz[1] - 1)); - - makeStreamLines(sources[0], sources[1], minX, minY, maxX, maxY, sz, - contourGroup, - currentMagnification, zoom, contourGroup.lastDensity, - rastPosToWorldGrid); - } - - return contourGroup; - - } - - public static GeneralEnvelope calculateSubGrid(IExtent workingExtent, - GeneralGridGeometry mapGridGeometry, - GeneralGridGeometry imageGridGeometry) { - GeneralEnvelope env = new GeneralEnvelope(2); - try { - GridGeometry2D imageGeometry2D = GridGeometry2D - .wrap(imageGridGeometry); - - GridGeometry2D mapGeometry2D = GridGeometry2D.wrap(mapGridGeometry); - - // Start with a grid envelope in screen space0 - GridEnvelope2D screenGridEnvelope = new GridEnvelope2D( - (int) Math.floor(workingExtent.getMinX()), - (int) Math.floor(workingExtent.getMinY()), - (int) Math.ceil(workingExtent.getWidth()), - (int) Math.ceil(workingExtent.getHeight())); - // intersect with mapGeometry so we only have points on the actual - // display - screenGridEnvelope = new GridEnvelope2D( - screenGridEnvelope.intersection(mapGeometry2D - .getGridRange2D())); - // convert from screen grid space to screen crs space. - Envelope2D screenCRSEnvelope = mapGeometry2D - .gridToWorld(screenGridEnvelope); - - org.opengis.geometry.Envelope subgridCRSEnvelope = MapUtil - .reprojectAndIntersect(screenCRSEnvelope, - imageGridGeometry.getEnvelope()); - - GridEnvelope2D subgridEnv = imageGeometry2D - .worldToGrid(new Envelope2D(subgridCRSEnvelope)); - // Add a 1 pixel border since worldToGrid is only guaranteed to - // include a cell if the cell center is in the envelope but we want - // to include the data in the subgrid if even a tiny bit of the edge - // overlaps. - subgridEnv.grow(1, 1); - if (!subgridEnv.isEmpty()) { - // Convert GridEnvelope to general envelope. - env.setRange(0, subgridEnv.getMinX(), subgridEnv.getMaxX()); - env.setRange(1, subgridEnv.getMinY(), subgridEnv.getMaxY()); - } - } catch (Exception e) { - statusHandler.handle(Priority.WARN, - "Cannot compute subgrid, contouring may be slow.", e); - // Don't use a subgrid, just contour the complete image. - // This may result in doing way too much contouring which can be - // slow, but it is better than no contouring at all. It's also worth - // noting that it gets slower as you zoom in and more contours are - // generated, but as you zoom in it also becomes more likely you - // will be successful in your transformation since the smaller area - // is less likely to contain invalid points. - env.setRange(0, imageGridGeometry.getGridRange().getLow(0), - imageGridGeometry.getGridRange().getHigh(0)); - env.setRange(1, imageGridGeometry.getGridRange().getLow(1), - imageGridGeometry.getGridRange().getHigh(1)); - } - statusHandler.handle(Priority.DEBUG, "Subgrid: " + env); - return env; - } - - /** - * Create labels for a linestring - * - * @param shapeToAddTo - * @param levelOffset - * @param contourValue - * @param labelPoints - * @param valsArr - */ - private static void prepareLabel(IWireframeShape shapeToAddTo, - double screenToPixel, String label, List labelPoints, - double[][] valsArr) { - double[] lastPoint = new double[] { Double.POSITIVE_INFINITY, - Double.POSITIVE_INFINITY }; - - double d = 0.0; - - final double threshold1 = (200.0 / screenToPixel); - final double threshold2 = (50.0 / screenToPixel); - - double q1, q2, p1, p2; - for (int n = 0; n < valsArr.length; n++) { - - // Distance approximation between last label point - // and current point - - // Absolute value logic inlined for performance - q1 = lastPoint[0] - valsArr[n][0]; - q2 = lastPoint[1] - valsArr[n][1]; - q1 = (q1 <= 0.0D) ? 0.0D - q1 : q1; - q2 = (q2 <= 0.0D) ? 0.0D - q2 : q2; - - d = q1 + q2; - - // If distance has been enough, add a label - if (d > (threshold1) - /* || (labeledAtLeastOnce == false && n == valsArr.length - 1) */) { - // Search for any labels that are too close - // to the current one - boolean tooClose = false; - p1 = valsArr[n][0]; - p2 = valsArr[n][1]; - q1 = 0; - q2 = 0; - for (double[] test : labelPoints) { - // Distance approximation between each label - // point and current point - // Absolute value logic inlined for performance - q1 = test[0] - p1; - q2 = test[1] - p2; - q1 = (q1 <= 0.0D) ? -1.0D * q1 : q1; - q2 = (q2 <= 0.0D) ? -1.0D * q2 : q2; - d = q1 + q2; - if (d < threshold2) { - tooClose = true; - break; - } - } - if (!tooClose - /* || (labeledAtLeastOnce == false && n == valsArr.length - 1) */) { - shapeToAddTo.addLabel(label, valsArr[n]); - labelPoints.add(valsArr[n]); - lastPoint = valsArr[n]; - } - } - } - - } - - public static ContourGroup createContours(Object data, int level, - IExtent extent, double currentDensity, - GeneralGridGeometry imageGridGeometry, IGraphicsTarget target, - ContourPreferences prefs) throws VizException { - - GeneralEnvelope imageEnvelope = new GeneralEnvelope(new double[] { - extent.getMinX(), extent.getMinY() }, new double[] { - extent.getMaxX(), extent.getMaxY() }); - GeneralGridEnvelope imageRange = new GeneralGridEnvelope(new int[] { 0, - 0 }, new int[] { imageGridGeometry.getGridRange().getSpan(0), - imageGridGeometry.getGridRange().getSpan(1) }, false); - GridGeometry2D imageGeom = new GridGeometry2D(imageRange, imageEnvelope); - imageGeom = GridGeometry2D.wrap(imageGridGeometry); - MathTransform gridToPixel = imageGeom - .getGridToCRS(PixelInCell.CELL_CENTER); - - ContourGroup contourGroup = new ContourGroup(); - contourGroup.lastDensity = currentDensity; - contourGroup.zoomLevel = 1.0 / Math.pow(2.0, level); - - GeneralEnvelope pixelEnvelope = new GeneralEnvelope(new double[] { - extent.getMinX(), extent.getMinY() }, new double[] { - extent.getMaxX(), extent.getMaxY() }); - - GeneralGridEnvelope range = new GeneralGridEnvelope(new int[] { - (int) extent.getMinX(), (int) extent.getMinY() }, new int[] { - (int) (extent.getMaxX()), (int) extent.getMaxY() }, false); - GridGeometry2D pixelGeom = new GridGeometry2D(range, pixelEnvelope); - - contourGroup.posValueShape = target.createWireframeShape(false, - pixelGeom); - contourGroup.posValueShape.allocate(1000); - contourGroup.negValueShape = target.createWireframeShape(false, - pixelGeom); - contourGroup.negValueShape.allocate(1000); - - // Step 3: Get the actual data - - float[] data1D = null; - long[] sz = new long[] { imageGridGeometry.getGridRange().getSpan(0), - imageGridGeometry.getGridRange().getSpan(1) }; - - if (data instanceof float[]) { - data1D = (float[]) data; - - int minX = 0; - int minY = 0; - int maxX = (int) (sz[0] - 1); - int maxY = (int) (sz[1] - 1); - - int szX = (maxX - minX) + 1; - int szY = (maxY - minY) + 1; - int totalSz = szX * szY; - if (totalSz <= 0) { - return contourGroup; - } - - float[][] subgriddedData = new float[szX][szY]; - - for (int j = 0; j < szY; j++) { - for (int i = 0; i < szX; i++) { - subgriddedData[i][j] = data1D[((int) sz[0] * (j + minY)) - + (i + minX)]; - } - } - - // Use ported legacy code to determine contour interval - ContourContainer contours = null; - FortConConfig config = new FortConConfig(); - long t0 = System.currentTimeMillis(); - String minMaxLabelFormat = null; - String minLabel = null; - String maxLabel = null; - String labelFormat = null; - config.badlo = smallestContourValue; - config.badhi = largestContourValue; - config.xOffset = minX; - config.yOffset = minY; - config.labelSpacingLine = subgriddedData.length / 3; - if (config.labelSpacingLine < 1) { - config.labelSpacingLine = 1; - } - - // If nothing provided, attempt to get approximately 50 contours - if (prefs == null || prefs.getContourLabeling() == null) { - - float interval = XFormFunctions.newDataIntervalFromZoom(0.5f, - (float) ((level + 1) * contourGroup.lastDensity), true, - "", 10); - - config.seed = new float[] { interval }; - config.mode = -50; - contours = FortConBuf.contour(subgriddedData, config); - } else { - LabelingPreferences contourLabeling = prefs - .getContourLabeling(); - if (contourLabeling.getLabelSpacing() > 0) { - config.labelSpacingLine = subgriddedData.length - / contourLabeling.getLabelSpacing(); - if (config.labelSpacingLine < 1) { - config.labelSpacingLine = 1; - } - } - - // setup min/max processing - minMaxLabelFormat = contourLabeling.getMinMaxLabelFormat(); - minLabel = contourLabeling.getMinLabel(); - maxLabel = contourLabeling.getMaxLabel(); - labelFormat = contourLabeling.getLabelFormat(); - config.generateMins = minLabel != null - && (!minLabel.equals(".") || (minMaxLabelFormat != null && minLabel - .equals("."))); - config.generateMaxes = maxLabel != null - && (!maxLabel.equals(".") || (minMaxLabelFormat != null && maxLabel - .equals("."))); - - config.minMaxRadius = (int) (1.0 * 3 * ((PixelExtent) extent) - .getWidth() / 90); - if (config.minMaxRadius < 1) { - config.minMaxRadius = 1; - } - if (config.minMaxRadius > 7) { - config.minMaxRadius = 7; - } - - if (prefs.getContourLabeling().getValues() == null - && prefs.getContourLabeling().getIncrement() > 0.0) { - // interval provided - float initialInterval = prefs.getContourLabeling() - .getIncrement(); - float interval; - if (contourLabeling.getNumberOfContours() > 0) { - // use numberOfContours - float minData = 1e37f; - float maxData = -1e37f; - for (float[] dataRow : subgriddedData) { - for (float dataCell : dataRow) { - if (dataCell < minData && dataCell != -999999) { - minData = dataCell; - } else if (dataCell < 999998 - && dataCell > maxData) { - maxData = dataCell; - } - } - } - interval = (maxData - minData) - / contourLabeling.getNumberOfContours(); - if (interval < 0) { - interval = -interval; - } - - if (interval > initialInterval) { - initialInterval = interval; - // why would this be done we want to maintain the - // configured minimum, it will cause problems when - // showing the same parameter on cross section and - // time - // height? - - // prefs.getContourLabeling() - // .setIncrement(initialInterval); - } - - interval = XFormFunctions - .newDataIntervalFromZoom( - initialInterval, - (float) ((level + 1) * contourGroup.lastDensity), - false, "", 10); - } else { - interval = XFormFunctions - .newDataIntervalFromZoom( - initialInterval, - (float) ((level + 1) * contourGroup.lastDensity), - true, "", 10); - } - - float[] controls = new float[] { interval }; - config.mode = 0; - config.seed = controls; - - contours = FortConBuf.contour(subgriddedData, config); - } else if (prefs.getContourLabeling().getValues() != null) { - // explicit contouring values provided - - // convert Float[] to float[] - float[] vals = prefs.getContourLabeling().getValues(); - // the +0.1 makes it so numbers greater than 0.9 are rounded - // up - // and all other numbers are rounded down. - int d = (int) (2 / ((level + 1) * contourGroup.lastDensity) + 0.1); - if (d > 1) { - int myCount = (vals.length + d - 1) / d; - float[] newVals = new float[myCount]; - int i, j; - for (i = j = 0; j < myCount; i += d, j++) { - newVals[j] = vals[i]; - } - vals = newVals; - } - if (prefs.getContourLabeling().isCreateNegativeValues()) { - float[] newVals = new float[vals.length * 2]; - for (int i = 0; i < vals.length; i++) { - newVals[vals.length + i] = vals[i]; - newVals[vals.length - i - 1] = -1 * vals[i]; - } - vals = newVals; - } - config.seed = vals; - if (contourLabeling.getNumberOfContours() > 0) { - config.mode = contourLabeling.getNumberOfContours(); - } else { - config.mode = vals.length; - } - contours = FortConBuf.contour(subgriddedData, config); - } - } - - long t1 = System.currentTimeMillis(); - perfLog.logDuration("Contouring", t1 - t0); - - double levelOffset = Math.pow(2, (level - 1)); - - float contourValue = 0; - long tTransformAccum = 0; - long tLabelAccum = 0; - long tMinMaxAccum = 0; - List labelPoints = new ArrayList(); - - try { - int size = contours.xyContourPoints.size(); - - if (size > 0) { - DecimalFormat dfLabel = null; - - if (labelFormat != null) { - dfLabel = new DecimalFormat(labelFormat); - } else { - dfLabel = determineLabelFormat(contours.contourVals); - } - - long tZ0 = System.currentTimeMillis(); - // process min/max - processMinMaxLabels(contours, minMaxLabelFormat, minLabel, - maxLabel, gridToPixel, contourGroup, labelPoints, 0); - long tZ1 = System.currentTimeMillis(); - tMinMaxAccum += tZ1 - tZ0; - - for (int i = 0; i < size; i++) { - float[] contourGridPoints = contours.xyContourPoints - .get(i); - float[] contourWorldPoints = new float[contourGridPoints.length]; - - try { - int contourPoints = contourGridPoints.length / 2; - tZ0 = System.currentTimeMillis(); - gridToPixel.transform(contourGridPoints, 0, - contourWorldPoints, 0, contourPoints); - tZ1 = System.currentTimeMillis(); - tTransformAccum += (tZ1 - tZ0); - double[][] contourWorldPointsArr = new double[contourPoints][2]; - int index = 0; - for (int j = 0; j < contourPoints; j++) { - contourWorldPointsArr[j][0] = contourWorldPoints[index++]; - contourWorldPointsArr[j][1] = contourWorldPoints[index++]; - } - contourValue = contours.contourVals.get(i); - - String label = dfLabel.format(contourValue); - IWireframeShape shapeToAddTo = null; - - if (contourValue >= 0) { - shapeToAddTo = contourGroup.posValueShape; - } else { - shapeToAddTo = contourGroup.negValueShape; - } - - shapeToAddTo.addLineSegment(contourWorldPointsArr); - prepareLabel(shapeToAddTo, levelOffset, label, - labelPoints, contourWorldPointsArr); - } catch (TransformException e) { - statusHandler - .handle(Priority.PROBLEM, - "Error transforming points: " - + Arrays.toString(contourGridPoints), - e); - } - } - } - perfLog.logDuration("Min/Max processing", tMinMaxAccum); - perfLog.logDuration("Labeling", tLabelAccum); - perfLog.logDuration("Transformation", tTransformAccum); - } catch (Exception e) { - throw new VizException("Error postprocessing contours", e); - } - - return contourGroup; - } else if (data instanceof List && ((List) data).size() == 2) { - // Step 1:First determine the subgrid to contour - - // Step 3: Get the actual data - - float[] uW = (float[]) ((List) data).get(0); - float[] vW = (float[]) ((List) data).get(1); - - // Step 4: Determine the subgrid, if any - - int minX = 0; - int minY = 0; - int maxX = (int) (sz[0] - 1); - int maxY = (int) (sz[1] - 1); - - DataSource uWSource = new FloatBufferWrapper(uW, (int) sz[0], - (int) sz[1]); - DataSource vWSource = new FloatBufferWrapper(vW, (int) sz[0], - (int) sz[1]); - - makeStreamLines(uWSource, vWSource, minX, minY, maxX, maxY, sz, - contourGroup, - 1, 1, contourGroup.lastDensity * 2, gridToPixel); - - return contourGroup; - } else { - throw new UnsupportedOperationException( - "Contouring is not supported for data type: " - + data.getClass().getName()); - } - - } - - private static void makeStreamLines(DataSource uW, DataSource vW, int minX, - int minY, int maxX, int maxY, long[] sz, ContourGroup contourGroup, - double currentMagnification, float zoom, double density, - MathTransform rastPosToWorldGrid) throws VizException { - - int szX = (maxX - minX) + 1; - int szY = (maxY - minY) + 1; - int totalSz = szX * szY; - if (totalSz <= 0) { - return; - } - int x = (int) sz[0]; - int y = (int) sz[1]; - - // Use ported legacy code to determine contour interval - long t0 = System.currentTimeMillis(); - - double[] center = new double[2]; - double[] offCenter = new double[2]; - - try { - rastPosToWorldGrid.transform(new double[] { x / 2.0, y / 2.0 }, 0, - center, 0, 1); - rastPosToWorldGrid.transform(new double[] { (x / 2.0) + 1.0, - y / 2.0 }, 0, offCenter, 0, 1); - } catch (TransformException e) { - throw new VizException( - "Could not perform center calculations for stream lines.", - e); - } - - double gridPixelSize = offCenter[0] - center[0]; - double gridPixelMax = 2000.; - - // If gridPixelSize is large, arrows on streamline will be too small, so - // adjust here - if (gridPixelSize > gridPixelMax) { - gridPixelSize = gridPixelSize / 5; - } - float arrowSize = (float) (currentMagnification * 5 / zoom / gridPixelSize); - - double spadiv = zoom * density * gridPixelSize / 25; - - double minSpacing = 1.0 / spadiv; - double maxSpacing = 3.0 / spadiv; - float minspc = 0; - float maxspc = 0; - - if (minSpacing > 1) { - minspc = (float) Math.sqrt(minSpacing); - } - if (minspc < 0.1) { - minspc = 0.1f; - } - if (maxSpacing > 1) { - maxspc = (float) Math.sqrt(maxSpacing); - } - if (maxspc < 0.25) { - maxspc = 0.25f; - } - - if (minX != 0 || minY != 0) { - uW = new OffsetDataSource(uW, minX, minY); - vW = new OffsetDataSource(vW, minX, minY); - } - - StrmPakConfig config = new StrmPakConfig(arrowSize, minspc, maxspc, - -1000000f, -999998f); - StreamLineContainer container = StrmPak.strmpak(uW, vW, - szX, szY, config); - - long t1 = System.currentTimeMillis(); - perfLog.logDuration("Contouring", t1 - t0); - - long tAccum = 0; - - try { - for (List points : container.streamLines) { - double[][] valsArr = new double[points.size()][2]; - - for (int i = 0; i < points.size(); i++) { - StreamLinePoint point = points.get(i); - try { - long tZ0 = System.currentTimeMillis(); - rastPosToWorldGrid.transform( - new double[] { point.getX() + minX, - point.getY() + minY }, 0, valsArr[i], - 0, 1); - long tZ1 = System.currentTimeMillis(); - tAccum += (tZ1 - tZ0); - } catch (TransformException e) { - throw new VizException( - "Could not transform stream line coordinate into world grid space.", - e); - } - } - - contourGroup.posValueShape.addLineSegment(valsArr); - } - - perfLog.logDuration("Streamline transformation", tAccum); - } catch (Throwable e) { - throw new VizException("Error postprocessing contours", e); - } - } - - private static void processMinMaxLabels(ContourContainer contours, - String minMaxLabelFormat, String minLabel, String maxLabel, - MathTransform transform, ContourGroup contourGroup, - List labelPoints, int maxMinTrimLeft) - throws TransformException { - if (contours.minLabelPoints != null) { - if (minLabel != null && !minLabel.equals(".")) { - contourGroup.minMark = minLabel; - } - if (minMaxLabelFormat != null) { - if (minMaxLabelFormat.trim().length() > 0) { - DecimalFormat df = new DecimalFormat(minMaxLabelFormat); - int size = contours.minVals.size(); - contourGroup.minVals = new String[size]; - for (int i = 0; i < size; i++) { - String label = df.format(contours.minVals.get(i)); - label = label.substring(maxMinTrimLeft); - contourGroup.minVals[i] = label; - } - } else { - int size = contours.minVals.size(); - contourGroup.minVals = new String[size]; - for (int i = 0; i < size; i++) { - float val = contours.minVals.get(i); - DecimalFormat df = determineLabelFormat(val); - contourGroup.minVals[i] = df.format(val); - } - } - } - contourGroup.minLabelPoints = transformPointList( - contours.minLabelPoints, transform); - for (double[] vals : contourGroup.minLabelPoints) { - labelPoints.add(vals); - } - } - if (contours.maxLabelPoints != null) { - if (maxLabel != null && !maxLabel.equals(".")) { - contourGroup.maxMark = maxLabel; - } - if (minMaxLabelFormat != null) { - if (minMaxLabelFormat.trim().length() > 0) { - DecimalFormat df = new DecimalFormat(minMaxLabelFormat); - int size = contours.maxVals.size(); - contourGroup.maxVals = new String[size]; - for (int i = 0; i < size; i++) { - String label = df.format(contours.maxVals.get(i)); - label = label.substring(maxMinTrimLeft); - contourGroup.maxVals[i] = label; - } - } else { - int size = contours.maxVals.size(); - contourGroup.maxVals = new String[size]; - for (int i = 0; i < size; i++) { - float val = contours.maxVals.get(i); - DecimalFormat df = determineLabelFormat(val); - contourGroup.maxVals[i] = df.format(val); - } - } - } - contourGroup.maxLabelPoints = transformPointList( - contours.maxLabelPoints, transform); - for (double[] vals : contourGroup.maxLabelPoints) { - labelPoints.add(vals); - } - } - - } - - private static double[][] transformPointList(List xyPoints, - MathTransform transformToApply) throws TransformException { - int size = xyPoints.size(); - float in[] = new float[size * 2]; - int index = 0; - for (float[] xy : xyPoints) { - in[index++] = xy[0]; - in[index++] = xy[1]; - } - - float out[] = new float[in.length]; - for (int i = 0; i < size; i++) { - transformToApply.transform(in, 0, out, 0, size); - } - double[][] rval = new double[size][2]; - index = 0; - for (int i = 0; i < rval.length; i++) { - rval[i][0] = out[index++]; - rval[i][1] = out[index++]; - } - - return rval; - } - - // determine based on spread of values - private static DecimalFormat determineLabelFormat(List vals) { - // determine format based on the average difference between the contours - SortedSet sortedValues = new TreeSet(vals); - Iterator iter = sortedValues.iterator(); - if (iter.hasNext()) { - float prevVal = iter.next(); - int count = 0; - double diffSum = 0; - while (iter.hasNext()) { - float val = iter.next(); - diffSum += val - prevVal; - count++; - prevVal = val; - } - return determineLabelFormat((float) (diffSum / count)); - } else { - return determineLabelFormat(0.0f); - } - - } - - // determine based on spread of values - private static DecimalFormat determineLabelFormat(float val) { - float absval = Math.abs(val); - - DecimalFormat rval = null; - if (absval == 0) { - rval = new DecimalFormat("0.#"); - } else if (absval < 0.001 || absval > 1e7) { - rval = new DecimalFormat("0.###E0"); - } else if (absval < 0.01) { - rval = new DecimalFormat("0.###"); - } else if (absval < 0.1) { - rval = new DecimalFormat("0.##"); - } else { - rval = new DecimalFormat("0.#"); - } - - return rval; - } - - /** - * Check the contour lines in a ContourContainer and split any lines that - * need to wrap over the "seam" in the display crs. If changes are needed - * the lines within contours are modified directly. - * - * @param contours - * container holding contour lines - * @param descriptor - * the discriptor for the dispaly - * @param rastPosToLatLon - * transform for converting the coordinates within contours to - * LatLon coordinates. - * @throws TransformException - */ - private static void correctWorldWrapping(ContourContainer contours, - IMapDescriptor descriptor, MathTransform rastPosToLatLon) - throws TransformException { - long tZ0 = System.currentTimeMillis(); - - WorldWrapChecker wwc = new WorldWrapChecker( - descriptor.getGridGeometry()); - if (!wwc.needsChecking()) { - return; - } - - List splitLines = new ArrayList(); - List dupValues = new ArrayList(); - - Iterator lineIter = contours.xyContourPoints.iterator(); - Iterator valueIter = contours.contourVals.iterator(); - - while (lineIter.hasNext()) { - float[] data = lineIter.next(); - Float val = valueIter.next(); - double[] ll = new double[data.length]; - rastPosToLatLon.transform(data, 0, ll, 0, data.length / 2); - boolean remove = false; - int startIndex = 0; - double lastLon = ll[0]; - for (int i = 2; i < ll.length; i += 2) { - double lon = ll[i]; - if (wwc.check(lastLon, lon)) { - remove = true; - if (startIndex + 1 < i) { - splitLines.add(Arrays.copyOfRange(data, startIndex, i)); - dupValues.add(val); - } - startIndex = i; - } - lastLon = lon; - } - if (remove) { - lineIter.remove(); - valueIter.remove(); - if (startIndex + 1 < data.length) { - splitLines.add(Arrays.copyOfRange(data, startIndex, - data.length)); - dupValues.add(val); - } - } - - } - contours.xyContourPoints.addAll(splitLines); - contours.contourVals.addAll(dupValues); - - long tZ1 = System.currentTimeMillis(); - - perfLog.logDuration("Checking world wrapping", tZ1 - tZ0); - } -} diff --git a/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/cache/SubGridCacheKey.java b/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/cache/SubGridCacheKey.java deleted file mode 100644 index d417de72ec..0000000000 --- a/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/cache/SubGridCacheKey.java +++ /dev/null @@ -1,123 +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.viz.core.contours.cache; - -import org.geotools.coverage.grid.GeneralGridGeometry; - -import com.raytheon.uf.viz.core.IExtent; - -/** - * Key for a cache for an envelope of a subgrid - * - *
- * 
- * SOFTWARE HISTORY
- * 
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * Mar 4, 2011   7747   njensen     Initial creation
- * 
- * 
- * - * @author njensen - * @version 1.0 - */ - -public class SubGridCacheKey { - - private IExtent extent; - - private GeneralGridGeometry mapGridGeometry; - - private GeneralGridGeometry imageGridGeometry; - - public SubGridCacheKey(IExtent extent, GeneralGridGeometry mapGridGeometry, - GeneralGridGeometry imageGridGeometry) { - this.extent = extent; - this.mapGridGeometry = mapGridGeometry; - this.imageGridGeometry = imageGridGeometry; - } - - public IExtent getExtent() { - return extent; - } - - public void setExtent(IExtent extent) { - this.extent = extent; - } - - public GeneralGridGeometry getMapGridGeometry() { - return mapGridGeometry; - } - - public void setMapGridGeometry(GeneralGridGeometry mapGridGeometry) { - this.mapGridGeometry = mapGridGeometry; - } - - public GeneralGridGeometry getImageGridGeometry() { - return imageGridGeometry; - } - - public void setImageGridGeometry(GeneralGridGeometry imageGridGeometry) { - this.imageGridGeometry = imageGridGeometry; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((extent == null) ? 0 : extent.hashCode()); - result = prime - * result - + ((imageGridGeometry == null) ? 0 : imageGridGeometry - .hashCode()); - result = prime * result - + ((mapGridGeometry == null) ? 0 : mapGridGeometry.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - SubGridCacheKey other = (SubGridCacheKey) obj; - if (extent == null) { - if (other.extent != null) - return false; - } else if (!extent.equals(other.extent)) - return false; - if (imageGridGeometry == null) { - if (other.imageGridGeometry != null) - return false; - } else if (!imageGridGeometry.equals(other.imageGridGeometry)) - return false; - if (mapGridGeometry == null) { - if (other.mapGridGeometry != null) - return false; - } else if (!mapGridGeometry.equals(other.mapGridGeometry)) - return false; - return true; - } - -} diff --git a/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/package-info.java b/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/package-info.java deleted file mode 100644 index f501046a9f..0000000000 --- a/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/package-info.java +++ /dev/null @@ -1,24 +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. - **/ -/** - * Provides contouring support - * - */ -package com.raytheon.viz.core.contours; \ No newline at end of file diff --git a/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/rsc/displays/GriddedContourDisplay.java b/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/rsc/displays/GriddedContourDisplay.java deleted file mode 100644 index c583da3092..0000000000 --- a/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/rsc/displays/GriddedContourDisplay.java +++ /dev/null @@ -1,96 +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.viz.core.contours.rsc.displays; - -import java.nio.FloatBuffer; - -import org.geotools.coverage.grid.GeneralGridGeometry; -import org.geotools.coverage.grid.GridGeometry2D; - -import com.raytheon.uf.common.geospatial.data.GeographicDataSource; -import com.raytheon.uf.common.numeric.source.DataSource; -import com.raytheon.uf.common.style.contour.ContourPreferences; -import com.raytheon.uf.viz.core.exception.VizException; -import com.raytheon.uf.viz.core.map.IMapDescriptor; -import com.raytheon.viz.core.contours.ContourRenderable; - -/** - * Displays contours from any data source - * - * Currently implemented using the D2D contouring capability - * - *
- * SOFTWARE HISTORY
- * Date          Ticket#  Engineer    Description
- * ------------- -------- ----------- --------------------------
- * Jul 11, 2008  1233     chammack    Initial creation
- * Feb 27, 2014  2791     bsteffen    Switch from IDataRecord to DataSource
- * 
- * 
- * - * @author chammack - * @version 1.0 - */ - -public class GriddedContourDisplay extends ContourRenderable { - - private ContourPreferences preferences; - - protected GridGeometry2D gridGeometry; - - protected DataSource source; - - public GriddedContourDisplay(IMapDescriptor descriptor, - final GridGeometry2D gridGeometry, final FloatBuffer fb) { - this(descriptor, gridGeometry, new GeographicDataSource(fb, - gridGeometry)); - } - - public GriddedContourDisplay(IMapDescriptor descriptor, - final GridGeometry2D gridGeometry, final DataSource source) { - super(descriptor); - this.gridGeometry = gridGeometry; - this.source = source; - } - - @Override - public DataSource[] getData() throws VizException { - return new DataSource[] { source }; - } - - @Override - public GeneralGridGeometry getGridGeometry() throws VizException { - return gridGeometry; - } - - @Override - public ContourPreferences getPreferences() throws VizException { - return preferences; - } - - /** - * @param preferences - * the preferences to set - */ - public void setPreferences(ContourPreferences preferences) { - this.preferences = preferences; - } - -} diff --git a/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/rsc/displays/GriddedStreamlineDisplay.java b/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/rsc/displays/GriddedStreamlineDisplay.java deleted file mode 100644 index 87215dfc27..0000000000 --- a/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/rsc/displays/GriddedStreamlineDisplay.java +++ /dev/null @@ -1,75 +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.viz.core.contours.rsc.displays; - -import java.nio.FloatBuffer; - -import org.geotools.coverage.grid.GridGeometry2D; - -import com.raytheon.uf.common.geospatial.data.GeographicDataSource; -import com.raytheon.uf.common.numeric.source.DataSource; -import com.raytheon.uf.viz.core.exception.VizException; -import com.raytheon.uf.viz.core.map.IMapDescriptor; - -/** - * - * Performs same functions as the original GriddedVectorDisplay using wireframe - * shapes instead of svg for much faster performance. This is still slightly - * experimental but seems to work well. It should also have the drawing code - * extracted to a class similar to PointWindDisplay so wireframe shape barbs and - * arrows can be used elsewhere. - * - *
- * 
- * SOFTWARE HISTORY
- * Date          Ticket#  Engineer    Description
- * ------------- -------- ----------- --------------------------
- * Jun 22, 2010           bsteffen    Initial creation
- * Feb 07, 2011  7948     bkowal      added a public method to get the
- *                                    direction.
- * Feb 27, 2014  2791     bsteffen    Switch from IDataRecord to DataSource
- * 
- * 
- * - * @author bsteffen - * @version 1.0 - */ -public class GriddedStreamlineDisplay extends GriddedContourDisplay { - - private DataSource vSource; - - public GriddedStreamlineDisplay(IMapDescriptor descriptor, - GridGeometry2D gridGeometry, FloatBuffer ufb, FloatBuffer vfb) { - super(descriptor, gridGeometry, ufb); - this.vSource = new GeographicDataSource(vfb, gridGeometry); - } - - public GriddedStreamlineDisplay(IMapDescriptor descriptor, - GridGeometry2D gridGeometry, DataSource ufb, DataSource vfb) { - super(descriptor, gridGeometry, ufb); - this.vSource = vfb; - } - - @Override - public DataSource[] getData() throws VizException { - return new DataSource[] { source, vSource }; - } - -} diff --git a/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/util/ContourContainer.java b/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/util/ContourContainer.java deleted file mode 100644 index c23ae65041..0000000000 --- a/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/util/ContourContainer.java +++ /dev/null @@ -1,62 +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.viz.core.contours.util; - -import java.util.ArrayList; -import java.util.List; - -/** - * Contains a list of the contours and their associated values. - * - *
- * 
- * SOFTWARE HISTORY
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * Apr 23, 2010 #4583      rjpeter     Initial creation
- * 
- * 
- * - * @author rjpeter - * @version 1.0 - */ - -public class ContourContainer { - public final List xyContourPoints; - - public final List contourVals; - - public final List minLabelPoints; - - public final List maxLabelPoints; - - public final List minVals; - - public final List maxVals; - - public ContourContainer(int capacity) { - xyContourPoints = new ArrayList(capacity); - contourVals = new ArrayList(capacity); - minLabelPoints = new ArrayList(); - maxLabelPoints = new ArrayList(); - minVals = new ArrayList(); - maxVals = new ArrayList(); - } -} diff --git a/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/util/FortConBuf.java b/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/util/FortConBuf.java deleted file mode 100644 index 7e0c2f085d..0000000000 --- a/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/util/FortConBuf.java +++ /dev/null @@ -1,1952 +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.viz.core.contours.util; - -import java.text.DecimalFormat; -import java.text.ParseException; -import java.util.Queue; -import java.util.concurrent.ConcurrentLinkedQueue; - -import com.raytheon.uf.common.numeric.array.FloatArray2DWrapper; -import com.raytheon.uf.common.numeric.filter.InvalidRangeFilter; -import com.raytheon.uf.common.numeric.source.AxisSwapDataSource; -import com.raytheon.uf.common.numeric.source.DataSource; - -/** - * Port of the fortCon.f routine. Minimal changes made to make it perform better - * in java. Not object orientated and not thread safe! - * - *
- * 
- * SOFTWARE HISTORY
- * Date          Ticket#  Engineer    Description
- * ------------- -------- ----------- --------------------------
- * Apr 22, 2010  4583     rjpeter     Initial creation
- * Feb 27, 2014  2791     bsteffen    Use DataSource for generic data access.
- * 
- * 
- * - * @author rjpeter - * @version 1.0 - */ -public class FortConBuf { - private static final byte b02 = 0x02; - - private static final byte b12 = 0x12; - - private static final byte b40 = 0x40; - - private static final byte b52 = 0x52; - - private static final byte bC0 = (byte) 0xc0; - - private static final byte bD2 = (byte) 0xd2; - - private static final int maxContours = 500; - - private static final byte[] CMask = new byte[maxContours]; - - static { - byte mask = 0x1; - for (int i = 0; i < CMask.length; i++) { - CMask[i] = mask; - mask <<= 1; - if (mask == 0) { - mask = 1; - } - } - } - - private PointBuffer ijPntBuffer = new PointBuffer(2000, 1000); - - private DataSource dataToContour; - - private int nxMaxIndex; - - private int nyMaxIndex; - - private byte[][] work1; - - private byte[][] work2; - - private byte[][] work3; - - private byte[][] work4; - - private float[] ConVal = new float[maxContours]; - - private boolean[] ConNo = new boolean[maxContours]; - - private float[] MnAvg = new float[maxContours]; - - private float[] MxAvg = new float[maxContours]; - - private int c; - - private int labsep2; - - private ContourContainer rval; - - private FortConBuf() { - - } - - private static Queue instancePool = new ConcurrentLinkedQueue(); - - public static ContourContainer contour(float[][] data, FortConConfig config) { - int ny = data.length; - int nx = data[0].length; - DataSource source = new FloatArray2DWrapper(data, nx, ny); - source = new AxisSwapDataSource(source); - if (config.badlo < config.badhi) { - source = InvalidRangeFilter.apply(source, config.badlo, - config.badhi); - } - return contour(source, ny, nx, config); - } - - /** - * Perform contouring. This method ignores config.badlo and config.badhi and - * only treats NaN as bad data. - * - * @param data - * the source for data to contouring. - * @param nx - * The number of points to contour in the x direction - * @param ny - * The number of points to contour in the y direction - * @param config - * configuration options - * @return a ContourContainer - */ - public static ContourContainer contour(DataSource data, int nx, int ny, - FortConConfig config) { - - ContourContainer rval = null; - FortConBuf instance = null; - try { - instance = instancePool.poll(); - if (instance == null) { - instance = new FortConBuf(); - } - - rval = instance.contourInternal(data, nx, ny, config); - } finally { - if (instance != null) { - instancePool.add(instance); - } - } - - return rval; - } - - private ContourContainer contourInternal(DataSource data, int nx, int ny, - FortConConfig config) { - dataToContour = data; - - nxMaxIndex = nx - 1; - nyMaxIndex = ny - 1; - ijPntBuffer.setSize(0); - ijPntBuffer.setXOffset(config.xOffset); - ijPntBuffer.setYOffset(config.yOffset); - - double rawmax = -Double.MAX_VALUE; - double rawmin = Double.MAX_VALUE; - work1 = new byte[nx][ny]; - work2 = new byte[nx][ny]; - work3 = new byte[nx][ny]; - work4 = new byte[nx][ny]; - - // contourCount is number of contour values - int contourCount, mmm; - int i, j, xmode, turn1, turn2, turn3, turn4, ii, jj; - - double val, val1, val2, dval, minval, maxval, D2; - Byte bbb; - - // map out missing values - // Figure out which vertical sides can accept contours. - for (int cIdx = 0; cIdx < nx; cIdx++) { - val2 = dataToContour.getDataValue(cIdx, nyMaxIndex); - for (int rIdx = nyMaxIndex - 1; rIdx >= 0; rIdx--) { - val1 = dataToContour.getDataValue(cIdx, rIdx); - if (val1 < val2) { - if (val1 < rawmin) { - rawmin = val1; - } - work4[cIdx][rIdx] = b40; - } else if (Double.isNaN(val1) || Double.isNaN(val2)) { - work4[cIdx][rIdx] = 1; - } else { - if (val2 < rawmin) { - rawmin = val2; - } - if (val2 < val1) { - work4[cIdx][rIdx] = bC0; - } - } - val2 = val1; - } - } - - // Figure out which horizontal sides can accept contours. - for (int rIdx = 0; rIdx < ny; rIdx++) { - val2 = dataToContour.getDataValue(nxMaxIndex, rIdx); - for (int cIdx = nxMaxIndex - 1; cIdx >= 0; cIdx--) { - val1 = dataToContour.getDataValue(cIdx, rIdx); - if (val1 < val2) { - if (val2 > rawmax) { - rawmax = val2; - } - work3[cIdx][rIdx] = b40; - } else if (Double.isNaN(val1) || Double.isNaN(val2)) { - work3[cIdx][rIdx] = 1; - } else { - if (val1 > rawmax) { - rawmax = val1; - } - if (val2 < val1) { - work3[cIdx][rIdx] = bC0; - } - } - val2 = val1; - } - } - - // Handle case of no good points. - if (rawmin >= rawmax) { - return new ContourContainer(0); - } - - // Scale absolute extrema from grid as specified. - minval = rawmin; - maxval = rawmax; - - // Limit number of contours by size of work arrays, check for alternate - // modes. - if (config.mode > 0) { - xmode = config.mode / 1000; - mmm = Math.min(maxContours, config.mode - xmode * 1000); - } else { - xmode = (-config.mode) / 1000; - mmm = Math.max(-maxContours, config.mode + xmode * 1000); - } - - if (xmode == 1) { - if (mmm <= 0) { - minval = Math.max(minval, config.seed[1]); - maxval = Math.min(maxval, config.seed[2]); - } - xmode = 0; - } else if (xmode == 2) { - if (mmm <= 0) { - xmode = 0; - } else if (config.seed[0] < 0.0 - || (mmm < config.seed.length && config.seed[mmm] < config.seed[1])) { - // added mmm to seed.length check, perhaps always enter if mmm < - // seed.length also? - xmode = 0; - } else { - mmm = Math.min(maxContours / 2, mmm); - } - } else { - xmode = 0; - } - - // not enumerated contours - if (mmm <= 0) { - // Make sure contouring increment has some finite positive value and - // that no more contours are drawn than we have room for in work - // arrays - val = (maxval - minval) / maxContours; - dval = config.seed[0]; - if (dval < val) { - dval = val; - if (mmm == 0) { - mmm = -25; - } - } - - // Handle case of routine picks contouring interval - if (mmm < 0) { - dval = (float) Math.pow(10.0, - ((int) (Math.log10(dval) + 100.01)) - 100); - float t10 = -5 * mmm; - float t5 = -2 * mmm; - float t2 = -1 * mmm; - val = (maxval - minval) / dval; - - while (val > t10) { - dval *= 10; - val = (maxval - minval) / dval; - } - - if (val > t5) { - dval *= 5; - } - if (val > t2) { - dval *= 2; - } - } - - // force offset to be in same format as outputted to screen - // e.g. dont calculate contours with an offset of 1.5 when - // contours are printed as integers, will cause contours - // to go missing in that case - if (config.labelFormat != null) { - DecimalFormat df = new DecimalFormat(config.labelFormat); - float temp = Float.valueOf(df.format(dval)); - if (temp != 0) { - dval = temp; - } - } - // See to it that contour values are multiples of dval - val1 = dval * Math.round(minval / dval); - if (val1 < minval) { - val1 += dval; - } - val2 = dval * Math.round(maxval / dval); - if (val2 > maxval) { - val2 -= dval; - } - - if (val1 > val2) { - return new ContourContainer(0); - } - - int numSteps = (int) ((val2 - val1) / dval + 1); - val = val1; - for (contourCount = 0; contourCount < numSteps; contourCount++) { - ConVal[contourCount] = (float) val; - val = val + dval; - } - // remove ncon-- as now ncon is the number of contour values - } else { - // user enumerated contours - contourCount = -1; - dval = Float.MAX_VALUE; - val1 = Float.MAX_VALUE; - val2 = -Float.MAX_VALUE; - boolean mirror = xmode == 2; - boolean ascend = ((config.seed[0] > config.seed[mmm - 1]) != mirror); - int seedsgn = 1; - if (mirror) { - seedsgn = -1; - } - - int iq, jq, kq; - boolean continueWork = true; - // mirroring loop - while (continueWork) { - continueWork = false; - // Handle a negative scale and/or descending order in seed - // values. - if (ascend) { - iq = mmm - 1; - jq = 0; - kq = -1; - } else { - iq = 0; - jq = mmm; - kq = 1; - } - - float seedwrk = 0; - // Load values for enumerated contours into internal work array, - // record max, min and approximation of delta value. - for (c = iq; (kq > 0 && c < jq) || (kq < 0 && c >= jq); c += kq) { - seedwrk = seedsgn * config.seed[c]; - if ((mirror && seedwrk == 0) - || (seedwrk < minval || seedwrk > maxval)) { - continue; - } - if (contourCount > 0) { - val = Math.abs(seedwrk - ConVal[contourCount]); - if (val != 0) { - dval = Math.min(dval, val); - } - } - if (seedwrk != 0) { - dval = Math.min(dval, Math.abs(seedwrk)); - } - val1 = Math.min(val1, seedwrk); - val2 = Math.max(val2, seedwrk); - contourCount++; - ConVal[contourCount] = seedwrk; - if (contourCount >= maxContours - 1) { - break; - } - // see if we loop back for xmode == 2, negative version of - // input list - if (mirror) { - mirror = false; - ascend = !ascend; - seedsgn *= -1; - if (contourCount < maxContours - 1) { - continueWork = true; - } - } - } - - // ncon no longer index and is now the count of contour vals - contourCount++; - } - } // end loading contour value array16 - - contourCount = formatContourValues(config, contourCount); - - // Get plotting coordinates ranges ... unused RJP - // 1939 Continue - // nxm=nx-1 - // nym=ny-1 - - if (config.generateMins || config.generateMaxes) { - labsep2 = config.labelSpacingOverall + 1; - // set mmfmt and mmlen - - // mmtol processing always amount to 0 - float dmm = 0; - double mmlim1 = 0; - double mmlim2 = 0; - - // Figure out limits of values which may be marked for. - if (mmm > 1 && val2 < 0) { - mmlim1 = minval; - mmlim2 = val2; - } else if (mmm > 1 && val1 > 0) { - mmlim1 = val1; - mmlim2 = maxval; - } else { - mmlim1 = minval; - mmlim2 = maxval; - } - // Loop for searching for Maxes and Mins - int jm = 0; - j = 1; - for (int jp = 2; jp < ny; jm = j, j = jp, jp++) { - int im = 0; - i = 1; - MIN_MAX_SEARCH: for (int ip = 2; ip < nx; im = i, i = ip, ip++) { - // check that this is not already too close to - // something marked - bbb = work4[i][j]; - if ((bbb & b02) == b02) { - continue MIN_MAX_SEARCH; - } - // check that this falls within markable limits - val = dataToContour.getDataValue(i, j); - if (val < mmlim1 || val > mmlim2) { - continue MIN_MAX_SEARCH; - } - // decide type of extrema that this could be - if (config.generateMins && work3[i][j] >= 2) { - // check if this point is a valid local min - if (work4[i][j] < 2 || work3[im][j] > -2 - || work4[i][jm] > -2) { - continue MIN_MAX_SEARCH; - } - // check corner points - if ((work3[im][jm] >= 2 && work4[im][jm] >= 2 && val >= dataToContour - .getDataValue(im, jm)) - || (work3[im][jp] >= 2 && work4[im][j] <= -2 && val >= dataToContour - .getDataValue(jp, im)) - || (work3[i][jm] <= -2 && work4[ip][jm] >= 2 && val >= dataToContour - .getDataValue(ip, jm)) - || (work3[i][jp] <= -2 && work4[ip][j] <= -2 && val >= dataToContour - .getDataValue(ip, jp))) { - continue MIN_MAX_SEARCH; - } - // sharp min check - if (dmm > 0) { - val = val + dmm; - if (val > dataToContour.getDataValue(im, j) - || val > dataToContour.getDataValue(i, jm) - || val > dataToContour.getDataValue(ip, j) - || val > dataToContour.getDataValue(i, jp)) { - continue MIN_MAX_SEARCH; - } - } - // broad min check - if (config.minMaxRadius > 1) { - int tmp = Math.min(im + config.minMaxRadius, - nxMaxIndex); - for (ii = ip; ii <= tmp; ii++) { - if (work3[ii][j] <= -2) { - continue MIN_MAX_SEARCH; - } - } - tmp = Math - .min(jm + config.minMaxRadius, nyMaxIndex); - for (jj = jp; jj <= tmp; jj++) { - if (work4[i][jj] <= -2) { - continue MIN_MAX_SEARCH; - } - } - for (ii = Math.max(i - config.minMaxRadius, 0); ii < im; ii++) { - if (work3[ii][j] >= 2) { - continue MIN_MAX_SEARCH; - } - } - for (jj = Math.max(j - config.minMaxRadius, 0); jj < jm; jj++) { - if (work4[i][jj] >= 2) { - continue MIN_MAX_SEARCH; - } - } - } - } else if (config.generateMaxes && work3[i][j] <= -2) { - // check if this point is a valid local max - if (work4[i][j] > -2 || work3[im][j] < 2 - || work4[i][jm] < 2) { - continue MIN_MAX_SEARCH; - } - // check corner points - if ((work3[im][jm] <= -2 && work4[im][jm] <= -2 && val <= dataToContour - .getDataValue(im, jm)) - || (work3[im][jp] <= -2 && work4[im][j] >= 2 && val <= dataToContour - .getDataValue(ip, jp)) - || (work3[i][jm] >= 2 && work4[ip][jm] <= -2 && val <= dataToContour - .getDataValue(ip, jm)) - || (work3[i][jp] >= 2 && work4[ip][j] >= 2 && val <= dataToContour - .getDataValue(ip, jp))) { - continue MIN_MAX_SEARCH; - } - // sharp max check - if (dmm > 0) { - val = val - dmm; - if (val < dataToContour.getDataValue(im, j) - || val < dataToContour.getDataValue(i, jm) - || val < dataToContour.getDataValue(ip, j) - || val < dataToContour.getDataValue(i, jp)) { - continue MIN_MAX_SEARCH; - } - } - // broad max check - if (config.minMaxRadius > 1) { - int tmp = Math.min(im + config.minMaxRadius, - nxMaxIndex); - for (ii = ip; ii <= tmp; ii++) { - if (work3[ii][j] >= 2) { - continue MIN_MAX_SEARCH; - } - } - tmp = Math - .min(jm + config.minMaxRadius, nyMaxIndex); - for (jj = jp; jj <= tmp; jj++) { - if (work4[i][jj] >= 2) { - continue MIN_MAX_SEARCH; - } - } - for (ii = Math.max(i - config.minMaxRadius, 0); ii < im; ii++) { - if (work3[ii][j] <= -2) { - continue MIN_MAX_SEARCH; - } - } - for (jj = Math.max(j - config.minMaxRadius, 0); jj < jm; jj++) { - if (work4[i][jj] <= -2) { - continue MIN_MAX_SEARCH; - } - } - } - } else { - continue MIN_MAX_SEARCH; - } - // Okay, set this as a valid extremum - work3[i][j] |= b12; - work3[im][j] |= b02; - work4[i][j] |= b02; - work4[i][jm] |= b02; - work3[i][jm] |= b02; - work3[im][jm] |= b02; - - markVrt(work3, work4, im, j); - } - - } - } - - // Escape point for bypassing locating maxes and mins...Skip drawing - // contours if there are none - if (contourCount <= 0) { - return new ContourContainer(0); - } - - rval = new ContourContainer(maxContours); - int nconMaxIndex = contourCount - 1; - - // Initialize counters for total cells, labels, and label separations on - // lines. - labsep2 = config.labelSpacingOverall; - - // Fill line pattern array, scale contour value array, and set use count - // mask. - for (c = 0; c < contourCount; c++) { - // No line pattern or scaling of contour value - ConNo[c] = true; - } - - // Set bracketing values which define whether cell side is best suited - // for - // labeling a particular contour. - int c1; - MnAvg[0] = -1e37f; - for (c1 = 0, c = 1; c < contourCount; c++, c1++) { - MxAvg[c1] = ConVal[c] + ConVal[c1]; - MnAvg[c] = MxAvg[c1]; - } - MxAvg[nconMaxIndex] = 1e37f; - - // Initialize spiral search for places to start contours. - turn1 = nxMaxIndex; - turn2 = nyMaxIndex; - turn3 = 0; - turn4 = 1; - // initialize c to the middle of the possible contours - c = (contourCount) / 2; - - // start at UL - i = 0; - ii = 0; - j = 0; - jj = 0; - - // simulate fortran goto - int jumpLabel = 10011; - JUMP_LOOP: while (jumpLabel > 0) { - switch (jumpLabel) { - case 10011: { - // Move along side 1 after missing values - i = ii; - if (i >= turn1) { - if (j >= turn2) { - jumpLabel = -1; - continue JUMP_LOOP; - } - turn1--; - jumpLabel = 20011; - continue JUMP_LOOP; - } - ii = i + 1; - bbb = work3[i][j]; - if (((bbb & 0x01) == 1) || (bbb == 0)) { - jumpLabel = 10011; - continue JUMP_LOOP; - } - - // Cell side does not have missing values, reinitialize search. - D2 = dataToContour.getDataValue(i, j); - if (bbb > 0) { - for (c = 0; c < contourCount; c++) { - if (ConVal[c] > D2) { - jumpLabel = 10022; - continue JUMP_LOOP; - } - } - jumpLabel = 10021; - continue JUMP_LOOP; - } else { - for (c = nconMaxIndex; c >= 0; c--) { - if (ConVal[c] < D2) { - jumpLabel = 10032; - continue JUMP_LOOP; - } - } - jumpLabel = 10031; - continue JUMP_LOOP; - } - } - case 10021: { - // Move along side 1, values increasing as we go - i = ii; - if (i >= turn1) { - if (j >= turn2) { - jumpLabel = -1; - continue JUMP_LOOP; - } - turn1--; - jumpLabel = 20021; - continue JUMP_LOOP; - } - ii = i + 1; - bbb = work3[i][j]; - if ((bbb & 0x01) == 1) { - jumpLabel = 10011; - continue JUMP_LOOP; - } - if (bbb < 0) { - c--; - if (c < 0) { - jumpLabel = 10031; - continue JUMP_LOOP; - } - jumpLabel = 10032; - continue JUMP_LOOP; - } - if (c == contourCount || bbb == 0) { - jumpLabel = 10021; - continue JUMP_LOOP; - } - } - case 10022: { - // Step through possible contours we can start - D2 = dataToContour.getDataValue(ii, jj); - boolean keepProcessing = true; - while (keepProcessing) { - if (ConVal[c] < D2) { - if (ConNo[c] || (work1[i][j] & CMask[c]) == 0) { - Contr1_E(i, j, 1); - } - c++; - if (c == contourCount) { - jumpLabel = 10021; - continue JUMP_LOOP; - } - } else { - keepProcessing = false; - } - } - jumpLabel = 10021; - continue JUMP_LOOP; - } - case 10031: { - // Move along side 1, values decreasing as we go - i = ii; - if (i >= turn1) { - if (j >= turn2) { - jumpLabel = -1; - continue JUMP_LOOP; - } - turn1--; - jumpLabel = 20031; - continue JUMP_LOOP; - } - ii = i + 1; - bbb = work3[i][j]; - if ((bbb & 0x01) == 1) { - jumpLabel = 10011; - continue JUMP_LOOP; - } - if (bbb > 0) { - c++; - if (c == contourCount) { - jumpLabel = 10021; - continue JUMP_LOOP; - } - jumpLabel = 10022; - continue JUMP_LOOP; - } - if (c < 0 || bbb == 0) { - jumpLabel = 10031; - continue JUMP_LOOP; - } - } - case 10032: { - // Step through possible contours we can start - D2 = dataToContour.getDataValue(ii, jj); - boolean keepProcessing = true; - while (keepProcessing) { - if (ConVal[c] > D2) { - if (ConNo[c] || (work1[i][j] & CMask[c]) == 0) { - Contr1_E(i, j, 1); - } - c--; - if (c < 0) { - jumpLabel = 10031; - continue JUMP_LOOP; - } - } else { - keepProcessing = false; - } - } - jumpLabel = 10031; - continue JUMP_LOOP; - } - case 20011: { - // Move up side 2 after missing values - j = jj; - if (j >= turn2) { - if (i <= turn3) { - jumpLabel = -1; - continue JUMP_LOOP; - } - turn2--; - jumpLabel = 30011; - continue JUMP_LOOP; - } - jj = j + 1; - bbb = work4[i][j]; - if (((bbb & 0x01) == 1) || (bbb == 0)) { - jumpLabel = 20011; - continue JUMP_LOOP; - } - - // Cell side does not have missing values, reinitialize search. - D2 = dataToContour.getDataValue(i, j); - if (bbb > 0) { - for (c = 0; c < contourCount; c++) { - if (ConVal[c] > D2) { - jumpLabel = 20022; - continue JUMP_LOOP; - } - } - jumpLabel = 20021; - continue JUMP_LOOP; - } else { - for (c = nconMaxIndex; c >= 0; c--) { - if (ConVal[c] < D2) { - jumpLabel = 20032; - continue JUMP_LOOP; - } - } - jumpLabel = 20031; - continue JUMP_LOOP; - } - } - case 20021: { - // Move up side 2, values increasing as we go - j = jj; - if (j >= turn2) { - if (i <= turn3) { - jumpLabel = -1; - continue JUMP_LOOP; - } - turn2--; - jumpLabel = 30021; - continue JUMP_LOOP; - } - jj = j + 1; - bbb = work4[i][j]; - if ((bbb & 0x01) == 1) { - jumpLabel = 20011; - continue JUMP_LOOP; - } - if (bbb < 0) { - c--; - if (c < 0) { - jumpLabel = 20031; - continue JUMP_LOOP; - } - jumpLabel = 20032; - continue JUMP_LOOP; - } - if (c == contourCount || bbb == 0) { - jumpLabel = 20021; - continue JUMP_LOOP; - } - } - case 20022: { - // Step through possible contours we can start - D2 = dataToContour.getDataValue(ii, jj); - boolean keepProcessing = true; - while (keepProcessing) { - if (ConVal[c] < D2) { - if (ConNo[c] || (work2[i][j] & CMask[c]) == 0) { - Contr1_E(i, j, 2); - } - c++; - if (c == contourCount) { - jumpLabel = 20021; - continue JUMP_LOOP; - } - } else { - keepProcessing = false; - } - } - jumpLabel = 20021; - continue JUMP_LOOP; - } - case 20031: { - // Move up side 2, values decreasing as we go - j = jj; - if (j >= turn2) { - if (i <= turn3) { - jumpLabel = -1; - continue JUMP_LOOP; - } - turn2--; - jumpLabel = 30031; - continue JUMP_LOOP; - } - jj = j + 1; - bbb = work4[i][j]; - if ((bbb & 0x01) == 1) { - jumpLabel = 20011; - continue JUMP_LOOP; - } - if (bbb > 0) { - c++; - if (c == contourCount) { - jumpLabel = 20021; - continue JUMP_LOOP; - } - jumpLabel = 20022; - continue JUMP_LOOP; - } - if (c < 0 || bbb == 0) { - jumpLabel = 20031; - continue JUMP_LOOP; - } - } - case 20032: { - // Find group of contours which are bracketed - D2 = dataToContour.getDataValue(ii, jj); - boolean keepProcessing = true; - while (keepProcessing) { - if (ConVal[c] > D2) { - if (ConNo[c] || (work2[i][j] & CMask[c]) == 0) { - Contr1_E(i, j, 2); - } - c--; - if (c < 0) { - jumpLabel = 20031; - continue JUMP_LOOP; - } - } else { - keepProcessing = false; - } - } - jumpLabel = 20031; - continue JUMP_LOOP; - } - case 30011: { - // Move back along side 3 after missing values - i = ii; - if (i <= turn3) { - if (j <= turn4) { - jumpLabel = -1; - continue JUMP_LOOP; - } - turn3++; - jumpLabel = 40011; - continue JUMP_LOOP; - } - ii = i - 1; - bbb = work3[ii][jj]; - if (((bbb & 0x01) == 1) || (bbb == 0)) { - jumpLabel = 30011; - continue JUMP_LOOP; - } - - // Cell side does not have missing values, reinitialize search. - D2 = dataToContour.getDataValue(i, j); - if (bbb < 0) { - for (c = 0; c < contourCount; c++) { - if (ConVal[c] > D2) { - jumpLabel = 30022; - continue JUMP_LOOP; - } - } - jumpLabel = 30021; - continue JUMP_LOOP; - } else { - for (c = nconMaxIndex; c >= 0; c--) { - if (ConVal[c] < D2) { - jumpLabel = 30032; - continue JUMP_LOOP; - } - } - jumpLabel = 30031; - continue JUMP_LOOP; - } - } - case 30021: { - // Move back along side 3, values increasing as we go - i = ii; - if (i <= turn3) { - if (j <= turn4) { - jumpLabel = -1; - continue JUMP_LOOP; - } - turn3++; - jumpLabel = 40021; - continue JUMP_LOOP; - } - ii = i - 1; - bbb = work3[ii][jj]; - if ((bbb & 0x01) == 1) { - jumpLabel = 30011; - continue JUMP_LOOP; - } - if (bbb > 0) { - c--; - if (c < 0) { - jumpLabel = 30031; - continue JUMP_LOOP; - } - jumpLabel = 30032; - continue JUMP_LOOP; - } - if (c == contourCount || bbb == 0) { - jumpLabel = 30021; - continue JUMP_LOOP; - } - } - case 30022: { - // Step through possible contours we can start - D2 = dataToContour.getDataValue(ii, jj); - boolean keepProcessing = true; - while (keepProcessing) { - if (ConVal[c] < D2) { - if (ConNo[c] || (work1[ii][jj] & CMask[c]) == 0) { - Contr1_E(ii, jj, 3); - } - c++; - if (c == contourCount) { - jumpLabel = 30021; - continue JUMP_LOOP; - } - } else { - keepProcessing = false; - } - } - jumpLabel = 30021; - continue JUMP_LOOP; - } - case 30031: { - // Move back along side 3, values decreasing as we go - i = ii; - if (i <= turn3) { - if (j <= turn4) { - jumpLabel = -1; - continue JUMP_LOOP; - } - turn3++; - jumpLabel = 40031; - continue JUMP_LOOP; - } - ii = i - 1; - bbb = work3[ii][jj]; - if ((bbb & 0x01) == 1) { - jumpLabel = 30011; - continue JUMP_LOOP; - } - if (bbb < 0) { - c++; - if (c == contourCount) { - jumpLabel = 30021; - continue JUMP_LOOP; - } - jumpLabel = 30022; - continue JUMP_LOOP; - } - if (c < 0 || bbb == 0) { - jumpLabel = 30031; - continue JUMP_LOOP; - } - } - case 30032: { - // Step through possible contours we can start - D2 = dataToContour.getDataValue(ii, jj); - boolean keepProcessing = true; - while (keepProcessing) { - if (ConVal[c] > D2) { - if (ConNo[c] || (work1[ii][jj] & CMask[c]) == 0) { - Contr1_E(ii, jj, 3); - } - c--; - if (c < 0) { - jumpLabel = 30031; - continue JUMP_LOOP; - } - } else { - keepProcessing = false; - } - } - jumpLabel = 30031; - continue JUMP_LOOP; - } - case 40011: { - // Move down side 4 after missing values - j = jj; - if (j <= turn4) { - if (i >= turn1) { - jumpLabel = -1; - continue JUMP_LOOP; - } - turn4++; - jumpLabel = 10011; - continue JUMP_LOOP; - } - jj = j - 1; - bbb = work4[ii][jj]; - if (((bbb & 0x01) == 1) || (bbb == 0)) { - jumpLabel = 40011; - continue JUMP_LOOP; - } - - // Cell side does not have missing values, reinitialize search. - D2 = dataToContour.getDataValue(i, j); - if (bbb < 0) { - for (c = 0; c < contourCount; c++) { - if (ConVal[c] > D2) { - jumpLabel = 40022; - continue JUMP_LOOP; - } - } - jumpLabel = 40021; - continue JUMP_LOOP; - } else { - for (c = nconMaxIndex; c >= 0; c--) { - if (ConVal[c] < D2) { - jumpLabel = 40032; - continue JUMP_LOOP; - } - } - jumpLabel = 40031; - continue JUMP_LOOP; - } - } - case 40021: { - // Move down side 4, values increasing as we go - j = jj; - if (j <= turn4) { - if (i >= turn1) { - jumpLabel = -1; - continue JUMP_LOOP; - } - turn4++; - jumpLabel = 10021; - continue JUMP_LOOP; - } - jj = j - 1; - bbb = work4[ii][jj]; - if ((bbb & 0x01) == 1) { - jumpLabel = 40011; - continue JUMP_LOOP; - } - if (bbb > 0) { - c--; - if (c < 0) { - jumpLabel = 40031; - continue JUMP_LOOP; - } - jumpLabel = 40032; - continue JUMP_LOOP; - } - if (c == contourCount || bbb == 0) { - jumpLabel = 40021; - continue JUMP_LOOP; - } - } - case 40022: { - // Step through possible contours we can start - D2 = dataToContour.getDataValue(ii, jj); - boolean keepProcessing = true; - while (keepProcessing) { - if (ConVal[c] < D2) { - if (ConNo[c] || (work2[ii][jj] & CMask[c]) == 0) { - Contr1_E(ii, jj, 4); - } - c++; - if (c == contourCount) { - jumpLabel = 40021; - continue JUMP_LOOP; - } - } else { - keepProcessing = false; - } - } - jumpLabel = 40021; - continue JUMP_LOOP; - } - case 40031: { - // Move down side 4, values decreasing as we go - j = jj; - if (j <= turn4) { - if (i >= turn1) { - jumpLabel = -1; - continue JUMP_LOOP; - } - turn4++; - jumpLabel = 10031; - continue JUMP_LOOP; - } - jj = j - 1; - bbb = work4[ii][jj]; - if ((bbb & 0x01) == 1) { - jumpLabel = 40011; - continue JUMP_LOOP; - } - if (bbb < 0) { - c++; - if (c == contourCount) { - jumpLabel = 40021; - continue JUMP_LOOP; - } - jumpLabel = 40022; - continue JUMP_LOOP; - } - if (c < 0 || bbb == 0) { - jumpLabel = 40031; - continue JUMP_LOOP; - } - } - case 40032: { - // Step through possible contours we can start - D2 = dataToContour.getDataValue(ii, jj); - boolean keepProcessing = true; - while (keepProcessing) { - if (ConVal[c] > D2) { - if (ConNo[c] || (work2[ii][jj] & CMask[c]) == 0) { - Contr1_E(ii, jj, 4); - } - c--; - if (c < 0) { - jumpLabel = 40031; - continue JUMP_LOOP; - } - } else { - keepProcessing = false; - } - } - jumpLabel = 40031; - continue JUMP_LOOP; - } - } - - // exit loop - jumpLabel = -1; - } // jump loop - - // Skip generating maxes and mins if we don't need to - if (config.generateMins || config.generateMaxes) { - // loop for drawing Maxes and Mins - for (j = 1; j < nyMaxIndex; j++) { - for (i = 1; i < nxMaxIndex; i++) { - // See what kind, if any, this extremum is. - bbb = work3[i][j]; - if (bbb == b52) { - // minima - rval.minVals.add((float) dataToContour.getDataValue(i, - j)); - rval.minLabelPoints.add(new float[] { - i + config.xOffset, j + config.yOffset }); - } else if (bbb == bD2) { - // maxima - rval.maxVals.add((float) dataToContour.getDataValue(i, - j)); - rval.maxLabelPoints.add(new float[] { - i + config.xOffset, j + config.yOffset }); - } - } - } - } - - // clean up references to release memory - dataToContour = null; - work1 = null; - work2 = null; - work3 = null; - work4 = null; - ContourContainer tmp = rval; - rval = null; - return tmp; - } - - /** - * @param config - * the FortConConfig - * @param contourCount - * The contour count - * @return If changed, the new contourCount. - */ - private int formatContourValues(FortConConfig config, int contourCount) { - if (config.labelFormat != null) { - DecimalFormat decimalFormat = new DecimalFormat(config.labelFormat); - int curIndex = -1; - for (int i = 0; i < contourCount; i++) { - try { - Number number = decimalFormat.parse(decimalFormat - .format(ConVal[i])); - // previous formated value is not the same as cur value - if (curIndex < 0 || ConVal[curIndex] != number.floatValue()) { - curIndex++; - ConVal[curIndex] = number.floatValue(); - } - } catch (ParseException e) { - // Unable to parse, just leave the array alone; - } - } - contourCount = curIndex + 1; - } - return contourCount; - } - - private void Contr1_E(int istart, int jstart, int sstart) { - // Nomenclature for cell (i,j) - // point 4 (i,j+1)-----side 3------(i+1,j+1) point 3 - // | | - // | | - // | | - // side 4 side 2 - // | | - // | | - // | | - // point 1 (i,j)-------side 1------(i+1,j) point 2 - float val = ConVal[c]; - byte cmw = CMask[c]; - boolean GGG1 = false; - boolean GGG2 = false; - boolean GGG3 = false; - boolean GGG4 = false; - boolean GGGD = false; - float val4 = val * 4; - boolean clos1 = false; - boolean clos2 = false; - boolean clos3 = false; - boolean clos4 = false; - boolean backok = false; - int icell = 0; - int jcell = 0; - int iplus = 0; - int jplus = 0; - float D1 = 0; - float D2 = 0; - float D3 = 0; - float D4 = 0; - - // reset point buffer - ijPntBuffer.setSize(0); - ijPntBuffer.setDirection(true); - ijPntBuffer.setNextWriteIndex(ijPntBuffer.capacity() / 2); - - int jumpLabel = 0; - switch (sstart) { - case 1: - jumpLabel = 51; - break; - case 2: - jumpLabel = 52; - break; - case 3: - jumpLabel = 53; - break; - case 4: - jumpLabel = 54; - } - - JUMP_LOOP: while (jumpLabel > 0) { - switch (jumpLabel) { - case 51: { - // start contour on side one - if (jstart > 0) { - backok = true; - } - // fall through - } - case 61: { - jcell = jstart; - jplus = jstart + 1; - icell = istart; - iplus = istart + 1; - clos1 = true; - D3 = (float) dataToContour.getDataValue(iplus, jcell); - D4 = (float) dataToContour.getDataValue(icell, jcell); - GGG3 = val >= D3; - GGG4 = val >= D4; - if (GGG3 == GGG4) { - jumpLabel = 9000; - continue JUMP_LOOP; - } - work1[icell][jcell] = (byte) (work1[icell][jcell] | cmw); - ConNo[c] = false; - ijPntBuffer.put(icell + (val - D4) / (D3 - D4), jcell); - jumpLabel = 101; - continue JUMP_LOOP; - } - case 52: { - // start contour on side two - if (istart < nxMaxIndex) { - backok = true; - } - // fall through - } - case 62: { - icell = istart - 1; - iplus = istart; - jcell = jstart; - jplus = jstart + 1; - clos2 = true; - D1 = (float) dataToContour.getDataValue(iplus, jcell); - D4 = (float) dataToContour.getDataValue(iplus, jplus); - GGG1 = val >= D1; - GGG4 = val >= D4; - if (GGG1 == GGG4) { - jumpLabel = 9000; - continue JUMP_LOOP; - } - work2[iplus][jcell] = (byte) (work2[iplus][jcell] | cmw); - ConNo[c] = false; - ijPntBuffer.put(iplus, jcell + (val - D1) / (D4 - D1)); - jumpLabel = 102; - continue JUMP_LOOP; - } - case 53: { - // Start contour on side three - if (jstart < nyMaxIndex) { - backok = true; - } - // fall through - } - case 63: { - jcell = jstart - 1; - jplus = jstart; - icell = istart; - iplus = istart + 1; - clos3 = true; - D1 = (float) dataToContour.getDataValue(icell, jplus); - D2 = (float) dataToContour.getDataValue(iplus, jplus); - GGG1 = val >= D1; - GGG2 = val >= D2; - if (GGG1 == GGG2) { - jumpLabel = 9000; - continue JUMP_LOOP; - } - work1[icell][jplus] = (byte) (work1[icell][jplus] | cmw); - ConNo[c] = false; - ijPntBuffer.put(icell + (val - D1) / (D2 - D1), jplus); - jumpLabel = 103; - continue JUMP_LOOP; - } - case 54: { - // Start contour on side four - if (istart > 0) { - backok = true; - } - // fall through - } - case 64: { - icell = istart; - iplus = istart + 1; - jcell = jstart; - jplus = jstart + 1; - clos4 = true; - D3 = (float) dataToContour.getDataValue(icell, jplus); - D2 = (float) dataToContour.getDataValue(icell, jcell); - GGG3 = val >= D3; - GGG2 = val >= D2; - if (GGG3 == GGG2) { - jumpLabel = 9000; - continue JUMP_LOOP; - } - work2[icell][jcell] = (byte) (work2[icell][jcell] | cmw); - ConNo[c] = false; - ijPntBuffer.put(icell, jcell + (val - D2) / (D3 - D2)); - jumpLabel = 104; - continue JUMP_LOOP; - } - case 101: { - // Entering side one, establish cell boundary information - GGG1 = GGG4; - D1 = D4; - GGG2 = GGG3; - D2 = D3; - D3 = (float) dataToContour.getDataValue(iplus, jplus); - D4 = (float) dataToContour.getDataValue(icell, jplus); - GGG3 = val >= D3; - GGG4 = val >= D4; - - // handle case of missing data - if ((work3[icell][jplus] & 1) == 1) { - if ((work4[icell][jcell] & 1) == 0) { - if (GGG4 != GGG2) { - jumpLabel = 9000; - continue JUMP_LOOP; - } - jumpLabel = 4422; - continue JUMP_LOOP; - } else if ((work4[iplus][jcell] & 1) == 0) { - if (GGG3 != GGG1) { - jumpLabel = 9000; - continue JUMP_LOOP; - } - jumpLabel = 2244; - continue JUMP_LOOP; - } - jumpLabel = 9000; - continue JUMP_LOOP; - } - - // Determine proper path through cell from side one - if (GGG3 == GGG4) { - if (GGG2 == GGG3) { - jumpLabel = 4422; - continue JUMP_LOOP; - } - jumpLabel = 2244; - continue JUMP_LOOP; - } else { - if (GGG1 == GGG4) { - jumpLabel = 3311; - continue JUMP_LOOP; - } - GGGD = val4 >= (D1 + D2 + D3 + D4); - if (GGG1 != GGGD) { - jumpLabel = 4422; - continue JUMP_LOOP; - } - jumpLabel = 2244; - continue JUMP_LOOP; - } - } - case 102: { - // Entering side two, establish cell boundary information - GGG2 = GGG1; - D2 = D1; - GGG3 = GGG4; - D3 = D4; - D1 = (float) dataToContour.getDataValue(icell, jcell); - D4 = (float) dataToContour.getDataValue(icell, jplus); - GGG1 = val >= D1; - GGG4 = val >= D4; - - // handle case of missing data - if ((work4[icell][jcell] & 1) == 1) { - if ((work3[icell][jplus] & 1) == 0) { - if (GGG4 != GGG2) { - jumpLabel = 9000; - continue JUMP_LOOP; - } - jumpLabel = 3311; - continue JUMP_LOOP; - } else if ((work3[icell][jcell] & 1) == 0) { - if (GGG3 != GGG1) { - jumpLabel = 9000; - continue JUMP_LOOP; - } - jumpLabel = 1133; - continue JUMP_LOOP; - } - jumpLabel = 9000; - continue JUMP_LOOP; - } - - // Determine proper path through cell from side two. - if (GGG1 == GGG4) { - if (GGG3 == GGG4) { - jumpLabel = 1133; - continue JUMP_LOOP; - } - jumpLabel = 3311; - continue JUMP_LOOP; - } else { - if (GGG1 == GGG2) { - jumpLabel = 4422; - continue JUMP_LOOP; - } - GGGD = val4 >= (D1 + D2 + D3 + D4); - if (GGG2 != GGGD) { - jumpLabel = 1133; - continue JUMP_LOOP; - } - jumpLabel = 3311; - continue JUMP_LOOP; - } - } - case 103: { - // Entering side three, establish cell boundary information - GGG3 = GGG2; - D3 = D2; - GGG4 = GGG1; - D4 = D1; - D1 = (float) dataToContour.getDataValue(icell, jcell); - D2 = (float) dataToContour.getDataValue(iplus, jcell); - GGG1 = val >= D1; - GGG2 = val >= D2; - - // handle case of missing data - if ((work3[icell][jcell] & 1) == 1) { - if ((work4[iplus][jcell] & 1) == 0) { - if (GGG4 != GGG2) { - jumpLabel = 9000; - continue JUMP_LOOP; - } - jumpLabel = 2244; - continue JUMP_LOOP; - } else if ((work4[icell][jcell] & 1) == 0) { - if (GGG3 != GGG1) { - jumpLabel = 9000; - continue JUMP_LOOP; - } - jumpLabel = 4422; - continue JUMP_LOOP; - } - jumpLabel = 9000; - continue JUMP_LOOP; - } - - // Determine proper path through cell from side three - if (GGG1 == GGG2) { - if (GGG1 == GGG4) { - jumpLabel = 2244; - continue JUMP_LOOP; - } - jumpLabel = 4422; - continue JUMP_LOOP; - } else { - if (GGG2 == GGG3) { - jumpLabel = 1133; - continue JUMP_LOOP; - } - GGGD = val4 >= (D1 + D2 + D3 + D4); - if (GGG3 != GGGD) { - jumpLabel = 2244; - continue JUMP_LOOP; - } - jumpLabel = 4422; - continue JUMP_LOOP; - } - } - case 104: { - // Entering side four, establish cell boundary information - GGG4 = GGG3; - D4 = D3; - GGG1 = GGG2; - D1 = D2; - D3 = (float) dataToContour.getDataValue(iplus, jplus); - D2 = (float) dataToContour.getDataValue(iplus, jcell); - GGG3 = val >= D3; - GGG2 = val >= D2; - - // handle case of missing data - if ((work4[iplus][jcell] & 1) == 1) { - if ((work3[icell][jcell] & 1) == 0) { - if (GGG4 != GGG2) { - jumpLabel = 9000; - continue JUMP_LOOP; - } - jumpLabel = 1133; - continue JUMP_LOOP; - } else if ((work3[icell][jplus] & 1) == 0) { - if (GGG3 != GGG1) { - jumpLabel = 9000; - continue JUMP_LOOP; - } - jumpLabel = 3311; - continue JUMP_LOOP; - } - jumpLabel = 9000; - continue JUMP_LOOP; - } - - // Determine proper path through cell from side four. - if (GGG2 == GGG3) { - if (GGG1 == GGG2) { - jumpLabel = 3311; - continue JUMP_LOOP; - } - jumpLabel = 1133; - continue JUMP_LOOP; - } else { - if (GGG3 == GGG4) { - jumpLabel = 2244; - continue JUMP_LOOP; - } - GGGD = val4 >= (D1 + D2 + D3 + D4); - if (GGG4 != GGGD) { - jumpLabel = 3311; - continue JUMP_LOOP; - } - jumpLabel = 1133; - continue JUMP_LOOP; - } - } - case 1133: { - // Cross to side 1 and enter new cell from side 3. - ijPntBuffer.put(icell + (val - D1) / (D2 - D1), jcell); - work1[icell][jcell] = (byte) (work1[icell][jcell] | cmw); - if (jcell == 0) { - jumpLabel = 9000; - continue JUMP_LOOP; - } - - // check if contour has closed off, advance values for cell - // bounds indices - if (clos3) { - if (icell == istart && jcell == jstart) { - jumpLabel = 8999; - continue JUMP_LOOP; - } - } - jplus = jcell; - jcell--; - jumpLabel = 103; - continue JUMP_LOOP; - } - case 2244: { - // Cross to side 2 and enter new cell from side 4 - ijPntBuffer.put(iplus, jcell + (val - D2) / (D3 - D2)); - work2[iplus][jcell] = (byte) (work2[iplus][jcell] | cmw); - if (iplus == nxMaxIndex) { - jumpLabel = 9000; - continue JUMP_LOOP; - } - - // check if contour has closed off, advance values for cell - // bounds indices - if (clos4) { - if (iplus == istart && jcell == jstart) { - jumpLabel = 8999; - continue JUMP_LOOP; - } - } - icell = iplus; - iplus++; - jumpLabel = 104; - continue JUMP_LOOP; - } - case 3311: { - // Cross to side 3 and enter new cell from side 1. - ijPntBuffer.put(icell + (val - D4) / (D3 - D4), jplus); - work1[icell][jplus] = (byte) (work1[icell][jplus] | cmw); - if (jplus == nyMaxIndex) { - jumpLabel = 9000; - continue JUMP_LOOP; - } - - // check if contour has closed off, advance values for cell - // bounds indices - if (clos1) { - if (icell == istart && jplus == jstart) { - jumpLabel = 8999; - continue JUMP_LOOP; - } - } - jcell = jplus; - jplus++; - jumpLabel = 101; - continue JUMP_LOOP; - } - case 4422: { - // Cross to side 4 and enter new cell from side 2 - ijPntBuffer.put(icell, jcell + (val - D1) / (D4 - D1)); - work2[icell][jcell] = (byte) (work2[icell][jcell] | cmw); - if (icell == 0) { - jumpLabel = 9000; - continue JUMP_LOOP; - } - - // check if contour has closed off, advance values for cell - // bounds indices - if (clos2) { - if (icell == istart && jcell == jstart) { - jumpLabel = 8999; - continue JUMP_LOOP; - } - } - iplus = icell; - icell--; - jumpLabel = 102; - continue JUMP_LOOP; - } - case 8999: { - // Finished - backok = false; - // fall through - } - case 9000: { - if (backok) { - backok = false; - clos1 = false; - clos2 = false; - clos3 = false; - clos4 = false; - ijPntBuffer.setDirection(false); - ijPntBuffer.setNextWriteIndex(ijPntBuffer.getMinIndex()); - - switch (sstart) { - case 1: - jumpLabel = 63; - break; - case 2: - jumpLabel = 64; - break; - case 3: - jumpLabel = 61; - break; - case 4: - jumpLabel = 62; - } - continue JUMP_LOOP; - } - - // check if we have anything to draw - if (ijPntBuffer.size() == 0) { - return; - } - - // System.out.println("i/j PntBuffer size " + - // iPntBuffer.size()); - // put points into global buffer - rval.contourVals.add(val); - rval.xyContourPoints.add(ijPntBuffer.getPoints()); - return; - } - } - } - } - - private void markVrt(byte[][] workH, byte[][] workV, int i, int j) { - markCheck(workV, i, j); - if (labsep2 <= 0) - return; - - markCheck(workH, i - 1, j); - markCheck(workH, i - 1, j + 1); - markCheck(workH, i, j); - markCheck(workH, i, j + 1); - - markCheck(workV, i, j - 1); - markCheck(workV, i, j + 1); - if (labsep2 <= 1) - return; - - markCheck(workH, i - 2, j); - markCheck(workH, i - 2, j + 1); - markCheck(workH, i - 1, j - 1); - markCheck(workH, i - 1, j + 2); - markCheck(workH, i, j - 1); - markCheck(workH, i, j + 2); - markCheck(workH, i + 1, j); - markCheck(workH, i + 1, j + 1); - - markCheck(workV, i - 1, j - 1); - markCheck(workV, i - 1, j); - markCheck(workV, i - 1, j + 1); - markCheck(workV, i, j - 2); - markCheck(workV, i, j + 2); - markCheck(workV, i + 1, j - 1); - markCheck(workV, i + 1, j); - markCheck(workV, i + 1, j + 1); - if (labsep2 <= 2) - return; - - markCheck(workH, i - 3, j); - markCheck(workH, i - 3, j + 1); - markCheck(workH, i - 2, j - 1); - markCheck(workH, i - 2, j + 2); - markCheck(workH, i - 1, j - 2); - markCheck(workH, i - 1, j + 3); - markCheck(workH, i, j - 2); - markCheck(workH, i, j + 3); - markCheck(workH, i + 1, j - 1); - markCheck(workH, i + 1, j + 2); - markCheck(workH, i + 2, j); - markCheck(workH, i + 2, j + 1); - - markCheck(workV, i - 2, j - 1); - markCheck(workV, i - 2, j); - markCheck(workV, i - 2, j + 1); - markCheck(workV, i - 1, j - 2); - markCheck(workV, i - 1, j + 2); - markCheck(workV, i, j - 3); - markCheck(workV, i, j + 3); - markCheck(workV, i + 1, j - 2); - markCheck(workV, i + 1, j + 2); - markCheck(workV, i + 2, j - 1); - markCheck(workV, i + 2, j); - markCheck(workV, i + 2, j + 1); - if (labsep2 <= 3) - return; - - markCheck(workH, i - 4, j); - markCheck(workH, i - 4, j + 1); - markCheck(workH, i - 3, j - 1); - markCheck(workH, i - 3, j + 2); - markCheck(workH, i - 2, j - 2); - markCheck(workH, i - 2, j + 3); - markCheck(workH, i - 1, j - 3); - markCheck(workH, i - 1, j + 4); - markCheck(workH, i, j - 3); - markCheck(workH, i, j + 4); - markCheck(workH, i + 1, j - 2); - markCheck(workH, i + 1, j + 3); - markCheck(workH, i + 2, j - 1); - markCheck(workH, i + 2, j + 2); - markCheck(workH, i + 3, j); - markCheck(workH, i + 3, j + 1); - - markCheck(workV, i - 3, j - 1); - markCheck(workV, i - 3, j); - markCheck(workV, i - 3, j + 1); - markCheck(workV, i - 2, j - 2); - markCheck(workV, i - 2, j + 2); - markCheck(workV, i - 1, j - 3); - markCheck(workV, i - 1, j + 3); - markCheck(workV, i, j - 4); - markCheck(workV, i, j + 4); - markCheck(workV, i + 1, j - 3); - markCheck(workV, i + 1, j + 3); - markCheck(workV, i + 2, j - 2); - markCheck(workV, i + 2, j + 2); - markCheck(workV, i + 3, j - 1); - markCheck(workV, i + 3, j); - markCheck(workV, i + 3, j + 1); - if (labsep2 <= 4) - return; - - markCheck(workH, i - 5, j); - markCheck(workH, i - 5, j + 1); - markCheck(workH, i - 4, j - 1); - markCheck(workH, i - 4, j + 2); - markCheck(workH, i - 3, j - 2); - markCheck(workH, i - 3, j + 3); - markCheck(workH, i - 2, j - 3); - markCheck(workH, i - 2, j + 4); - markCheck(workH, i - 1, j - 4); - markCheck(workH, i - 1, j + 5); - markCheck(workH, i, j - 4); - markCheck(workH, i, j + 5); - markCheck(workH, i + 1, j - 3); - markCheck(workH, i + 1, j + 4); - markCheck(workH, i + 2, j - 2); - markCheck(workH, i + 2, j + 3); - markCheck(workH, i + 3, j - 1); - markCheck(workH, i + 3, j + 2); - markCheck(workH, i + 4, j); - markCheck(workH, i + 4, j + 1); - - markCheck(workV, i - 4, j - 1); - markCheck(workV, i - 4, j); - markCheck(workV, i - 4, j + 1); - markCheck(workV, i - 3, j - 2); - markCheck(workV, i - 3, j + 2); - markCheck(workV, i - 2, j - 3); - markCheck(workV, i - 2, j + 3); - markCheck(workV, i - 1, j - 4); - markCheck(workV, i - 1, j + 4); - markCheck(workV, i, j - 5); - markCheck(workV, i, j + 5); - markCheck(workV, i + 1, j - 4); - markCheck(workV, i + 1, j + 4); - markCheck(workV, i + 2, j - 3); - markCheck(workV, i + 2, j + 3); - markCheck(workV, i + 3, j - 2); - markCheck(workV, i + 3, j + 2); - markCheck(workV, i + 4, j - 1); - markCheck(workV, i + 4, j); - markCheck(workV, i + 4, j + 1); - } - - private static void markCheck(byte[][] work, int i, int j) { - if (i >= 0 && i < work.length && j >= 0 && j < work[0].length) { - work[i][j] |= b02; - } - } -} diff --git a/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/util/FortConConfig.java b/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/util/FortConConfig.java deleted file mode 100644 index 6365dd7e33..0000000000 --- a/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/util/FortConConfig.java +++ /dev/null @@ -1,62 +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.viz.core.contours.util; - -/** - * TODO Add Description - * - *
- * 
- * SOFTWARE HISTORY
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * May 27, 2010            rjpeter     Initial creation
- * 
- * 
- * - * @author rjpeter - * @version 1.0 - */ - -public class FortConConfig { - public int mode; - - public float[] seed; - - public float badlo; - - public float badhi; - - public float xOffset; - - public float yOffset; - - public int labelSpacingLine; - - public int labelSpacingOverall; - - public int minMaxRadius; - - public boolean generateMins; - - public boolean generateMaxes; - - public String labelFormat; -} diff --git a/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/util/PointBuffer.java b/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/util/PointBuffer.java deleted file mode 100644 index 5db5b0dde0..0000000000 --- a/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/util/PointBuffer.java +++ /dev/null @@ -1,169 +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.viz.core.contours.util; - -/** - * Bidirectional x/y point buffer. - * - *
- * 
- * SOFTWARE HISTORY
- * Date          Ticket#  Engineer    Description
- * ------------- -------- ----------- --------------------------
- * Apr 23, 2010  4583     rjpeter     Initial creation
- * Feb 27, 2014  2791     bsteffen    Remove unused constructor arg
- * 
- * 
- * - * @author rjpeter - * @version 1.0 - */ - -public class PointBuffer { - private float[] buffer; - - private boolean forwardDirection = true; - - // location of the next write - private int index = 0; - - private int size = 0; - - // inclusive - private int minIndex = 0; - - private float xOffset; - - private float yOffset; - - /** - * - * @param capacity - * Capacity in x,y points - * @param initialIndex - * @param forwardDirection - */ - public PointBuffer(int capacity, int initialIndex) { - buffer = new float[capacity * 2]; - minIndex = initialIndex; - index = initialIndex; - } - - public void setDirection(boolean forward) { - forwardDirection = forward; - } - - public void setSize(int size) { - this.size = size; - } - - public void setNextWriteIndex(int index) { - this.index = index; - if (size == 0) { - minIndex = this.index; - } - - // not reseting size, will happen automatically first time data is - // written - } - - public void setXOffset(float offset) { - xOffset = offset; - } - - public void setYOffset(float offset) { - yOffset = offset; - } - - /** - * - * @param numberToAdd - * number of vals to add to the buffer. Ex: for a single x/y - * point this should be 2 - */ - protected void ensureCapacityFor(int numberToAdd) { - if (forwardDirection) { - int minSize = index + numberToAdd; - if (minSize >= buffer.length) { - int newSize = buffer.length * 2; - if (newSize < minSize) { - newSize = minSize; - } - - float[] tmp = new float[newSize]; - System.arraycopy(buffer, minIndex, tmp, minIndex, size); - buffer = tmp; - } - } else { - int numNeeded = numberToAdd - index; - if (numNeeded > 0) { - int newSize = buffer.length * 2; - if (newSize - buffer.length < numNeeded) { - newSize += numNeeded; - } - - int sizeOffset = newSize - buffer.length; - int newMinIndex = minIndex + sizeOffset; - float[] tmp = new float[newSize]; - System.arraycopy(buffer, minIndex, tmp, newMinIndex, size); - buffer = tmp; - minIndex = newMinIndex; - index += sizeOffset; - } - } - } - - public void put(float x, float y) { - ensureCapacityFor(2); - buffer[index++] = x + xOffset; - buffer[index++] = y + yOffset; - - if (forwardDirection) { - if (index > minIndex + size) { - size = index - minIndex; - } - } else { - index -= 4; - if (index < minIndex) { - int oldIndex = minIndex; - minIndex = index + 2; - size += oldIndex - minIndex; - } - } - } - - public int capacity() { - return buffer.length; - } - - public int size() { - return size; - } - - public float[] getPoints() { - float[] rval = new float[size]; - System.arraycopy(buffer, minIndex, rval, 0, size); - return rval; - } - - public int getMinIndex() { - return minIndex; - } -} diff --git a/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/util/StreamLineContainer.java b/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/util/StreamLineContainer.java deleted file mode 100644 index a943e48096..0000000000 --- a/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/util/StreamLineContainer.java +++ /dev/null @@ -1,85 +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.viz.core.contours.util; - -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; - -/** - * An object that contains a list of coordinates used to draw stream lines over - * a grid. - * - *
- * 
- * SOFTWARE HISTORY
- * 
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * Jun 21, 2013  #1999     dgilling     Initial creation
- * 
- * 
- * - * @author dgilling - * @version 1.0 - */ - -public class StreamLineContainer { - - public static class StreamLinePoint { - - private final float x; - - private final float y; - - public StreamLinePoint(float xPoint, float yPoint) { - this.x = xPoint; - this.y = yPoint; - } - - public float getX() { - return x; - } - - public float getY() { - return y; - } - - } - - public final List> streamLines; - - public StreamLineContainer() { - this(new LinkedList>()); - } - - private StreamLineContainer(List> listImpl) { - streamLines = listImpl; - } - - public static StreamLineContainer emptyContainer() { - List> listImpl = Collections.emptyList(); - return new StreamLineContainer(listImpl); - } - - public boolean addLine(List points) { - return streamLines.add(points); - } -} diff --git a/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/util/StrmPak.java b/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/util/StrmPak.java deleted file mode 100644 index ac21779e7b..0000000000 --- a/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/util/StrmPak.java +++ /dev/null @@ -1,1071 +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.viz.core.contours.util; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.raytheon.uf.common.numeric.array.FloatArray2DWrapper; -import com.raytheon.uf.common.numeric.filter.DataFilter; -import com.raytheon.uf.common.numeric.source.AxisSwapDataSource; -import com.raytheon.uf.common.numeric.source.DataSource; -import com.raytheon.uf.common.numeric.source.FilteredDataSource; -import com.raytheon.viz.core.contours.util.StreamLineContainer.StreamLinePoint; - -/** - * Port of strmpak.f. - *

- * This routine draws a set of streamlines. Works in area defined by current. - * - *

- * 
- * SOFTWARE HISTORY
- * 
- * Date          Ticket#  Engineer    Description
- * ------------- -------- ----------- --------------------------
- * Jun 10, 2013  1999     dgilling    Initial creation
- * Feb 27, 2014  2791     bsteffen    Use DataSource for generic data access.
- * 
- * 
- * - * @author dgilling - * @version 1.0 - */ - -public final class StrmPak { - - private final class PointValueBuffer { - - private final Map buffer; - - private final V defaultValue; - - public PointValueBuffer(int initialSize, V defaultValue) { - buffer = new HashMap(initialSize, 1f); - this.defaultValue = defaultValue; - } - - public V get(int key) { - // TODO: introduce a bounds check so that this class throws an - // equivalent to an ArrayIndexOutOfBoundsException when data is - // requested that would have been outside of the original array's - // bounds. - // For now, neglecting for performance reasons - V retVal = buffer.get(key); - if (retVal == null) { - retVal = defaultValue; - } - return retVal; - } - - public V put(int key, V value) { - // TODO: introduce a bounds check so that this class throws an - // equivalent to an ArrayIndexOutOfBoundsException when data is - // requested that would have been outside of the original array's - // bounds. - // For now, neglecting for performance reasons - return buffer.put(key, value); - } - - public void clear() { - buffer.clear(); - } - } - - private static final float minmag = 0.0f; - - private static final float maxmag = 1e36f; - - @SuppressWarnings("unused") - private static final float checkval = 1e36f; - - // private static Queue instancePool = new - // ConcurrentLinkedQueue(); - - private int ill; - - private int iur; - - private int jll; - - private int jur; - - private int ium; - - private int jum; - - private float asiz; - - // in fortran itrack/jtrack were size 2000 arrays, indexed 1 -> - // 2000 - private final PointValueBuffer itrack; - - private final PointValueBuffer jtrack; - - // A2 porting note: LCPnt was a byte array in the original - // source, but the only values ever assigned to the array were 0 or 1, - // so a boolean array will work just as well. - // in fortran LCPnt/IPnt/JPnt were size 8001 arrays, indexed -4000 -> - // 4000 - private final PointValueBuffer LCPnt; - - private final PointValueBuffer IPnt; - - private final PointValueBuffer JPnt; - - /** - * Generate streamlines using column major float data. The u component is - * assumed to moving in the opposite direction of the x axis. - * - * @param uComp - * data values for the u component of the vector - * @param vComp - * data values for the v component of the vector - * @param xSize - * unused - * @param nx - * number of x coordinates - * @param ny - * number of y coordinates - * @param config - * configuration options - * @return - */ - public static StreamLineContainer strmpak(float[][] uComp, float[][] vComp, - int xSize, int nx, int ny, StrmPakConfig config) { - DataSource uSource = new FloatArray2DWrapper(uComp, ny, nx); - DataSource vSource = new FloatArray2DWrapper(vComp, ny, nx); - uSource = new AxisSwapDataSource(uSource); - vSource = new AxisSwapDataSource(vSource); - uSource = FilteredDataSource.addFilters(uSource, new DataFilter() { - - @Override - public double filter(double value) { - return -value; - } - }); - return strmpak(uSource, vSource, nx, ny, config); - } - - /** - * Generate streamlines using any data source. - * - * @param uComp - * data values for the u component of the vector - * @param vComp - * data values for the v component of the vector - * @param nx - * number of x coordinates - * @param ny - * number of y coordinates - * @param config - * configuration options - * @return - */ - public static StreamLineContainer strmpak(DataSource uComp, - DataSource vComp, int nx, int ny, StrmPakConfig config) { - StrmPak instance = new StrmPak(); - StreamLineContainer rval = instance.strmpakInternal(uComp, vComp, nx, - ny, config); - return rval; - } - - private StrmPak() { - itrack = new PointValueBuffer(512, 0); - jtrack = new PointValueBuffer(512, 0); - LCPnt = new PointValueBuffer(64, Boolean.TRUE); - IPnt = new PointValueBuffer(512, 0.0f); - JPnt = new PointValueBuffer(512, 0.0f); - } - - /** - * This routine draws a set of streamlines. Works in area defined by - * current. - * - * @param U - * Array of U components - * @param V - * Array of V components - * @param nx - * Inner dimension of grid. - * @param ny - * Outer dimension of grid. - * @param config - * Parameters for drawing the stream lines. - * - * @return A StreamLineContainer containing the coordinates for - * the stream lines. Line segments will be divided by the sentinel - * value (-99999, -99999). - */ - private StreamLineContainer strmpakInternal(DataSource U, DataSource V, - int nx, int ny, StrmPakConfig config) { - StreamLineContainer rVal = new StreamLineContainer(); - - // Initialize environment of streamline output. - float minmag2 = minmag * minmag; - float maxmag2 = maxmag * maxmag; - ill = 0; - jll = 0; - iur = nx - 1; - jur = ny - 1; - ium = iur - 1; - jum = jur - 1; - asiz = config.asize; - - // Initialize work arrays. - // A2 porting note: In the fortran, Work was an int/short array, but I'm - // using byte because it seems the only values ever used in this - // algorithm are -1, 0, and 1. - byte[][][] Work = new byte[2][nx][ny]; - for (int i = ill; i <= ium; i++) { - int ii = i + 1; - - for (int j = jll; j <= jum; j++) { - int jj = j + 1; - - if ((!((U.getDataValue(i, j) < config.badlo) || U.getDataValue( - i, j) > config.badhi)) - || (!((U.getDataValue(i, jj) < config.badlo) || U - .getDataValue(i, jj) > config.badhi)) - || (!((U.getDataValue(ii, j) < config.badlo) || U - .getDataValue(ii, j) > config.badhi)) - || (!((U.getDataValue(ii, jj) < config.badlo) || U - .getDataValue(ii, jj) > config.badhi)) - || (!((V.getDataValue(i, j) < config.badlo) || V - .getDataValue(i, j) > config.badhi)) - || (!((V.getDataValue(i, jj) < config.badlo) || V - .getDataValue(i, jj) > config.badhi)) - || (!((V.getDataValue(ii, j) < config.badlo) || V - .getDataValue(ii, j) > config.badhi)) - || (!((V.getDataValue(ii, jj) < config.badlo) || V - .getDataValue(ii, jj) > config.badhi))) { - Work[0][i][j] = -1; - Work[1][i][j] = -1; - continue; - } - - if ((minmag <= 0.0f) && (maxmag >= config.badlo)) { - continue; - } - double mag2 = U.getDataValue(i, j) * U.getDataValue(i, j) - + V.getDataValue(i, j) * V.getDataValue(i, j); - if ((mag2 >= minmag2) && (mag2 <= maxmag2)) { - continue; - } - mag2 = U.getDataValue(ii, j) * U.getDataValue(ii, j) - + V.getDataValue(ii, j) * V.getDataValue(ii, j); - if ((mag2 >= minmag2) && (mag2 <= maxmag2)) { - continue; - } - mag2 = U.getDataValue(i, jj) * U.getDataValue(i, jj) - + V.getDataValue(i, jj) * V.getDataValue(i, jj); - if ((mag2 >= minmag2) && (mag2 <= maxmag2)) { - continue; - } - mag2 = U.getDataValue(ii, jj) * U.getDataValue(ii, jj) - + V.getDataValue(ii, jj) * V.getDataValue(ii, jj); - if ((mag2 >= minmag2) && (mag2 <= maxmag2)) { - continue; - } - Work[0][i][j] = -1; - Work[1][i][j] = -1; - } - } - - float maxspc4 = (config.maxspc * 4); - int k = (int) ((maxspc4 >= 0) ? (maxspc4 + 0.5f) : (maxspc4 - 0.5f)); - if (k < 1) { - k = 1; - } - - do { - int i1 = (ill + iur) / 2; - int i2 = i1 + 1; - int j1 = (jll + jur) / 2; - int j2 = j1 + 1; - - boolean again; - do { - again = false; - float mymax = config.maxspc; - if (k > mymax) { - mymax = k; - } - - if (j1 >= jll) { - float rj0 = j1; - for (int i = i1; i <= i2 - 1; i += k) { - float ri0 = i + 0.5f; - StrmLin(U, V, Work, ri0, rj0, config.minspc, mymax, - rVal); - } - j1 -= k; - again = true; - } - - if (i1 >= ill) { - float ri0 = i1; - for (int j = j1; j <= j2 - 1; j += k) { - float rj0 = j + 0.5f; - StrmLin(U, V, Work, ri0, rj0, config.minspc, mymax, - rVal); - - } - i1 -= k; - again = true; - } - - if (j2 < jur) { - float rj0 = j2; - for (int i = i1; i <= i2 - 1; i += k) { - float ri0 = i + 0.5f; - StrmLin(U, V, Work, ri0, rj0, config.minspc, mymax, - rVal); - } - j2 += k; - again = true; - } - - if (i2 <= iur) { - float ri0 = i2; - for (int j = j1; j <= j2 - 1; j += k) { - float rj0 = j + 0.5f; - StrmLin(U, V, Work, ri0, rj0, config.minspc, mymax, - rVal); - } - i2 += k; - again = true; - } - } while (again); - - k /= 2; - } while (k >= 1); - - return rVal; - } - - /** - * This routine draws a single streamline through the point (ri0, rj0). ri0 - * are rj0 real numbers in array index space. - * - * @param U - * Array of U components - * @param V - * Array of V components - * @param Work - * Workspace which keeps track of how many streamlines have been - * drawn in each cell. A value of -1 designates a cell as having - * bad or missing data. 1 is for previously drawn streamlines, 2 - * includes the streamline currently being drawn. - * @param ri0 - * X-coordinate to draw the streamline through. Coordinates are - * in array index space. - * @param rj0 - * Y-coordinate to draw the streamline through. Coordinates are - * in array index space. - * @param minspc - * If greater than one, no two streamlines will approach any - * closer than this number of cells. If less than zero, a - * streamline will terminate if it runs through 1/minspc - * consecutive already occupied cells. - * @param maxspc - * No streamline will be started any closer than this number of - * cells to an existing streamline. - * @param container - * StreamLineContainer object accumulating all line - * segments necessary to draw stream lines for U and V. - */ - private void StrmLin(DataSource U, DataSource V, byte[][][] Work, - float ri0, float rj0, float minspc, float maxspc, - StreamLineContainer container) { - if ((ri0 < ill) || (ri0 > iur) || (rj0 < jll) || (rj0 > jur)) { - return; - } - - // declare formal arguments - int side0; - int i; - int ii; - int iii; - int j; - int jj; - int jjj; - int k; - int kk; - int kkk; - int ovrlap = 0; - float x; - float y; - // FIXME? in fortran SgSide was a size 8 array, indexed 1 -> 8 - int[] SgSide = new int[9]; - float[] SgLoc = new float[9]; - float[] SgSF = new float[9]; - // FIXME? in fortran SgCont was a size 8 array, indexed 1 -> 8 - float[] SgCont = new float[9]; - - itrack.clear(); - jtrack.clear(); - LCPnt.clear(); - IPnt.clear(); - JPnt.clear(); - - // Initialize some variables. - int ntb = 1 + Math.min(iur - ill, jur - jll) / 4; - int track = 0; - int ntrack = (int) ((maxspc >= 0) ? (maxspc + 0.5f) : (maxspc - 0.5f)); - if (ntrack < ntb) { - ntrack = ntb; - } - int qi0 = (int) ((ri0 >= 0) ? (ri0 + 0.5f) : (ri0 - 0.5f)); - int qj0 = (int) ((rj0 >= 0) ? (rj0 + 0.5f) : (rj0 - 0.5f)); - int kpnt1 = 0; - int kpnt2 = 0; - - // Loop for trying streamlines in both directions from this point. - for (int kstrm = 1; kstrm <= 2; kstrm++) { - int kpnt = 0; - int dkpnt = 0; - int btrack = track + 1; - - // NOTE on A2 port: we use named blocks to substitute for common - // goto points within the original fortran code. - LABEL_7777: { - LABEL_7775: { - // Determine which side and which cell we are starting with - if (Math.abs(ri0 - qi0) < Math.abs(rj0 - qj0)) { - if (kstrm == 1) { - side0 = 4; - i = (int) ((ri0 >= 0) ? (ri0 + 0.5f) : (ri0 - 0.5f)); - j = (int) rj0; - k = Math.max( - ((int) ((maxspc >= 0) ? (maxspc + 0.5f) - : (maxspc - 0.5f)) - 1), 0); - for (jjj = Math.max(jll, (j - k)); jjj <= Math.min( - jum, j + k); jjj++) { - for (iii = Math.max(ill, (i - k - 1)); iii <= Math - .min(ium, i + k); iii++) { - if (Work[0][iii][jjj] > 0) { - return; - } - } - } - if (i > ium) { - break LABEL_7775; - } - } else { - side0 = 2; - i = (int) ((ri0 >= 0) ? (ri0 + 0.5f) : (ri0 - 0.5f)) - 1; - j = (int) rj0; - if (i < 1) { - break LABEL_7775; - } - } - - x = qi0 - (float) i; - y = rj0 - j; - } else { - if (kstrm == 1) { - side0 = 1; - i = (int) ri0; - j = (int) ((rj0 >= 0) ? (rj0 + 0.5f) : (rj0 - 0.5f)); - k = Math.max( - ((int) ((maxspc >= 0) ? (maxspc + 0.5f) - : (maxspc - 0.5f)) - 1), 0); - for (jjj = Math.max(jll, (j - k)); jjj <= Math.min( - jum, (j + k)); jjj++) { - for (iii = Math.max(ill, (i - k - 1)); iii <= Math - .min(ium, (i + k)); iii++) { - if (Work[0][iii][jjj] > 0) { - return; - } - } - } - if (j > jum) { - break LABEL_7775; - } - } else { - side0 = 3; - i = (int) ri0; - j = (int) ((rj0 >= 0) ? (rj0 + 0.5f) : (rj0 - 0.5f)) - 1; - if (j < 1) { - break LABEL_7775; - } - } - - x = ri0 - i; - y = qj0 - (float) j; - } - - ii = i + 1; - jj = j + 1; - - // Check if cell has missing values. - if (Work[0][i][j] == -1) { - break LABEL_7777; - } - - // Determine whether we are working with or against the - // flow. - float dirflg; - double influx; - if (side0 == 1) { - influx = V.getDataValue(i, j) * (1.0f - x) - + V.getDataValue(ii, j) * x; - } else if (side0 == 2) { - influx = U.getDataValue(ii, j) * (1.0f - y) - + U.getDataValue(ii, jj) * y; - } else if (side0 == 3) { - influx = -(V.getDataValue(i, jj) * (1.0f - x) + V - .getDataValue(ii, jj) * x); - } else { - influx = -(U.getDataValue(i, j) * (1.0f - y) + U - .getDataValue(i, jj) * y); - } - if (influx < 0.0f) { - dirflg = -1.0f; - dkpnt = -1; - } else if (influx > 0.0f) { - dirflg = 1.0f; - dkpnt = 1; - } else { - break LABEL_7777; - } - - // Set some initialize values at streamline start point. - float rpxi = i; - float rpyj = j; - int narrow = (ntb + 3) * 3 / 4; - boolean done = false; - int ntot = (narrow + 1) / 2; - int loopct = 0; - IPnt.put(kpnt, rpxi + x); - JPnt.put(kpnt, rpyj + y); - - int i1 = 0; - int j1 = 0; - int i0 = 0; - int j0 = 0; - int icheck = 0; - - float xx; - float yy; - - // Start process of crossing this cell, check if we have - // missing data. - while (true) { - if (Work[0][i][j] == -1) { - break LABEL_7777; - } - - // Determine if there are already too many streamlines - // around. - if (track > btrack) { - if (minspc < 1.5f) { - if (Work[icheck][i][j] == 0) { - ovrlap = 0; - } else { - ovrlap += Work[icheck][i][j]; - float minspcInv = 1.0f / minspc; - if (ovrlap >= (int) ((minspcInv >= 0) ? (minspcInv + 0.5f) - : (minspcInv - 0.5f))) { - break LABEL_7777; - } - } - - icheck = 1; - } else { - if (Work[icheck][i][j] > 0) { - break LABEL_7777; - } - for (int djj = -1; djj <= 0; djj++) { - LABEL_20: for (int dii = -1; dii <= 0; dii++) { - if ((dii == 0) && (djj == 0)) { - continue; - } - - if ((dii != 0) && (djj != 0)) { - float minspc707 = minspc * .707f; - k = (int) ((minspc707 >= 0) ? (minspc707 + 0.5f) - : (minspc707 - 0.5f)) - 1; - } else { - k = (int) ((minspc >= 0) ? (minspc + 0.5f) - : (minspc - 0.5f)) - 1; - } - if (k > (track - btrack)) { - k = track - btrack; - } - if (k < 1) { - continue; - } - - iii = i; - jjj = j; - LABEL_18: for (int l = 1; l <= k; l++) { - iii += dii; - if ((iii < ill) || (iii > ium)) { - continue LABEL_20; - } - jjj += djj; - if ((jjj < jll) || (jjj > jum)) { - continue LABEL_20; - } - - if (Work[0][iii][jjj] > 0) { - break LABEL_7777; - } - if (Work[1][iii][jjj] <= 0) { - continue; - } - - for (int kkkk = (1 + track - k); kkkk <= track; kkkk++) { - if ((itrack.get(kkkk) == iii) - && (jtrack.get(kkkk) == jjj)) { - continue LABEL_18; - } - } - break LABEL_7777; - } - } - } - } - - icheck = 1; - } - - // Determine flux contributions from each component. - // FIXME? in fortran Flux was a size 8 array, indexed 1 - // -> 8 - float[] Flux = { Float.NaN, - (-dirflg) * (float) V.getDataValue(i, j), - (-dirflg) * (float) V.getDataValue(ii, j), - (-dirflg) * (float) U.getDataValue(ii, j), - (-dirflg) * (float) U.getDataValue(ii, jj), - dirflg * (float) V.getDataValue(ii, jj), - dirflg * (float) V.getDataValue(i, jj), - dirflg * (float) U.getDataValue(i, jj), - dirflg * (float) U.getDataValue(i, j) }; - - // Count total number of in, out, and zero contributions - // to net flux. - int nin = 0; - int nout = 0; - for (k = 1; k <= 8; k++) { - if (Flux[k] < 0.0f) { - nin++; - } else if (Flux[k] > 0.0f) { - nout++; - } - } - if (nin == 0) { - break LABEL_7777; - } - - // Check if there are no exit points in this cell. - LABEL_77: { - if (nout == 0) { - // Determine termination point within this cell. - float x1 = -Flux[8] - Flux[7]; - float x2 = -Flux[4] - Flux[3]; - if ((x1 + x2) <= 0.0f) { - xx = 0.5f; - } else { - xx = x1 / (x1 + x2); - } - - float y1 = -Flux[5] - Flux[6]; - float y2 = -Flux[1] - Flux[2]; - if ((y1 + y2) <= 0.0f) { - yy = 0.5f; - } else { - yy = y1 / (y1 + y2); - } - done = true; - - // go to drawing portion - break LABEL_77; - } - - // Make a list of segments on cell border with like - // contribution to flux. Record location, side, and - // flux contribution. - influx = 0.0f; - float outflux = 0.0f; - int nsg = 0; - SgLoc[0] = 0.0f; - for (k = 1; k <= 4; k++) { - kkk = k + k; - kk = kkk - 1; - boolean flxflg; - if (Flux[kk] < 0.0f) { - flxflg = (Flux[kkk] > 0.0f); - } else if (Flux[kk] > 0.0f) { - flxflg = (Flux[kkk] < 0.0f); - } else { - flxflg = false; - } - - if (flxflg) { - float xy = Flux[kk] - / (Flux[kk] - Flux[kkk]); - if (xy > 0.0f) { - nsg++; - SgSide[nsg] = k; - SgLoc[nsg] = (k - 1f) + xy; - SgCont[nsg] = xy * Flux[kk] / 2f; - if (SgCont[nsg] < 0.0f) { - influx += SgCont[nsg]; - } else { - outflux += SgCont[nsg]; - } - } - - if (xy < 1.0f) { - nsg++; - SgSide[nsg] = k; - SgCont[nsg] = (1.0f - xy) * Flux[kkk] - / 2f; - } - - SgLoc[nsg] = k; - } else { - nsg++; - SgLoc[nsg] = k; - SgSide[nsg] = k; - SgCont[nsg] = Flux[kk] + Flux[kkk]; - } - - if (SgCont[nsg] < 0.0f) { - influx += SgCont[nsg]; - } else { - outflux += SgCont[nsg]; - } - } - - // Adjust the magnitude of the flux segments to make - // total flux integrated around the cell zero. - // Integrate to get stream function values. - float mult = (float) Math.sqrt((-outflux) / influx); - SgSF[0] = 0.0f; - for (k = 1; k < nsg; k++) { - if (SgCont[k] > 0.0f) { - SgSF[k] = SgSF[k - 1] + SgCont[k] / mult; - } else { - SgSF[k] = SgSF[k - 1] + SgCont[k] * mult; - } - } - k = nsg + 1; - SgSF[nsg] = 0.0f; - - // Based on side of entry, determine circular - // location of endpoint and direction to search for - // exit point. - float curloc; - boolean forward; - if (side0 == 1) { - curloc = x; - forward = ((dirflg * (U.getDataValue(i, j) - * (1.0f - x) + U.getDataValue(ii, j) - * x)) > 0.0f); - } else if (side0 == 2) { - curloc = 1.0f + y; - forward = ((dirflg * (V.getDataValue(ii, j) - * (1.0f - y) + V.getDataValue(ii, jj) - * y)) > 0.0f); - } else if (side0 == 3) { - curloc = 3.0f - x; - forward = ((dirflg * (U.getDataValue(i, jj) * x + U - .getDataValue(ii, jj) * (1.0f - x))) < 0.0f); - } else { - curloc = 4.0f - y; - forward = ((dirflg * (V.getDataValue(i, j) * y + V - .getDataValue(i, jj) * (1.0f - y))) < 0.0f); - } - - // Determine stream function value of entry - // location. - float curSF = 0.0f; - for (kk = 1; kk <= nsg; kk++) { - if ((SgLoc[kk] > curloc) || (kk == nsg)) { - k = kk - 1; - if (SgCont[kk] >= 0.0f) { - break LABEL_7777; - } - curSF = SgSF[k] + (SgSF[kk] - SgSF[k]) - * (curloc - SgLoc[k]) - / (SgLoc[kk] - SgLoc[k]); - if (k < 1) { - k = nsg; - } - break; - } - } - - // Search for next occurrence of this value of the - // stream function. - kkk = k; - if (forward) { - do { - k = kk; - kk++; - if (kk > nsg) { - kk = 1; - } - if (k == kkk) { - break LABEL_7777; - } - } while ((SgCont[kk] <= 0.0f) - || ((SgSF[k] <= curSF) != (curSF < SgSF[kk]))); - } else { - do { - kk = k; - k--; - if (k < 1) { - k = nsg; - } - if (k == kkk) { - break LABEL_7777; - } - } while ((SgCont[kk] <= 0.0f) - || ((SgSF[k] <= curSF) != (curSF < SgSF[kk]))); - } - if (k == nsg) { - k = 0; - } - float outloc = SgLoc[k] + (SgLoc[kk] - SgLoc[k]) - * (curSF - SgSF[k]) / (SgSF[kk] - SgSF[k]); - side0 = SgSide[kk]; - - // Based upon exit side, figure out location in x/y - // space. - if (side0 == 1) { - xx = outloc; - yy = 0.0f; - } else if (side0 == 2) { - xx = 1.0f; - yy = outloc - 1.0f; - } else if (side0 == 3) { - xx = 3.0f - outloc; - yy = 1.0f; - } else { - xx = 0.0f; - yy = 4.0f - outloc; - } - } - - // Record plotting location for this cell. - ntot++; - kpnt += dkpnt; - if ((ntot > narrow) && (Work[1][i][j] == 0)) { - float dx = xx - x; - float dy = yy - y; - float mag = (float) Math.sqrt(dx * dx + dy * dy); - if (mag >= 0.2f) { - LCPnt.put(kpnt, Boolean.FALSE); - ntot = 0; - } - } - IPnt.put(kpnt, rpxi + xx); - JPnt.put(kpnt, rpyj + yy); - - // Patch to prevent infinite loop. - i1 = i0; - j1 = j0; - i0 = i; - j0 = j; - - // Keep track of cells used so far. - Work[1][i][j]++; - track++; - itrack.put(track, i); - jtrack.put(track, j); - - // Based on exit side, figure out stuff for next cell. - if (done) { - break LABEL_7775; - } - if (side0 == 1) { - side0 = 3; - jj = j; - j--; - if (j < 1) { - break LABEL_7775; - } - rpyj -= 1.0f; - x = xx; - y = 1.0f; - } else if (side0 == 2) { - side0 = 4; - i = ii; - ii++; - if (i > ium) { - break LABEL_7775; - } - rpxi += 1.0f; - x = 0.0f; - y = yy; - } else if (side0 == 3) { - side0 = 1; - j = jj; - jj++; - if (j > jum) { - break LABEL_7775; - } - rpyj += 1.0f; - x = xx; - y = 0.0f; - } else if (side0 == 4) { - side0 = 2; - ii = i; - i--; - if (i < 1) { - break LABEL_7775; - } - rpxi -= 1.0f; - x = 1.0f; - y = yy; - } - - // Patch to prevent infinite loop. - if ((i == i1) && (j == j1)) { - loopct++; - if (loopct >= 3) { - break LABEL_7777; - } - } else { - loopct = 0; - } - } - } - - // Escape point for streamline hitting grid border, source, or - // sink. - // allow shorter streamlines in this case. - ntrack = (ntrack + 1) / 2; - } - - // Escape point for all others...record kpnt value. - if (dkpnt == -1) { - kpnt1 = kpnt; - } else if (dkpnt == 1) { - kpnt2 = kpnt; - } - } - - // Don't draw this streamline if it is too short. - if (track < ntrack) { - for (k = 1; k <= track; k++) { - Work[1][itrack.get(k)][jtrack.get(k)]--; - } - // A2 porting note: this code appeared in the original algorithm but - // is unnecessary since the values stored to LCPnt don't persist - // between calls to StrmLin(). - // for (k = kpnt1; k <= kpnt2; k++) { - // LCPnt.put(k, Boolean.TRUE); - // } - return; - } else { - for (k = 1; k <= track; k++) { - Work[0][itrack.get(k)][jtrack.get(k)]++; - } - } - - int npass = 5; - int wgt1 = 6; - int wgt2 = 88; - - // Do smoothing. - if (npass > 0) { - for (int kkkk = 1; kkkk <= npass; kkkk++) { - k = kpnt1 + 1; - float im = IPnt.get(kpnt1); - float xx = IPnt.get(k); - float jm = JPnt.get(kpnt1); - float yy = JPnt.get(k); - - for (int kp = kpnt1 + 2; kp <= kpnt2; kp++) { - float ip = IPnt.get(kp); - float jp = JPnt.get(kp); - IPnt.put(k, (wgt1 * (ip + im) + wgt2 * xx) / 100f); - JPnt.put(k, (wgt1 * (jp + jm) + wgt2 * yy) / 100f); - im = xx; - jm = yy; - xx = ip; - yy = jp; - k = kp; - } - } - } - - // Draw streamline. - List lineSegment = new ArrayList( - kpnt2 - kpnt1 + 1); - for (i = kpnt1; i <= kpnt2; i++) { - lineSegment.add(new StreamLinePoint(IPnt.get(i), JPnt.get(i))); - } - container.addLine(lineSegment); - - // Draw arrows. - if (kpnt1 < 0) { - kkk = kpnt1 + 2; - LCPnt.put(kkk, - LCPnt.get(kpnt1).booleanValue() - && LCPnt.get(kpnt1 + 1).booleanValue()); - } else { - kkk = kpnt1; - } - - for (k = kkk; k <= kpnt2; k++) { - if (!LCPnt.get(k)) { - LCPnt.put(k, Boolean.TRUE); - - int km = ((k < 0) ? k : k - 1); - int kp = ((k < 0) ? k + 1 : k); - - float dx = IPnt.get(kp) - IPnt.get(km); - float dy = JPnt.get(kp) - JPnt.get(km); - float mag = (float) Math.sqrt(dx * dx + dy * dy); - if (mag != 0.0f) { - mag /= asiz; - dx /= mag; - dy /= mag; - x = (IPnt.get(km) + IPnt.get(kp)) / 2f; - y = (JPnt.get(km) + JPnt.get(kp)) / 2f; - - // A2 porting note: these variables are not required in our - // port of this code--they were used specifically by the A1 - // D2D drawing routines - // float[] px = { (dy - dx), 0, (0 - dx - dx) }; - // float[] py = { px[2], 0, (0 - px[0]) }; - - List arrowHead = new ArrayList( - 3); - arrowHead.add(new StreamLinePoint((x - (dy - dx)), - (y - (-dy - dx)))); - arrowHead.add(new StreamLinePoint(x, y)); - arrowHead.add(new StreamLinePoint((x - (-dy - dx)), - (y + (dy - dx)))); - container.addLine(arrowHead); - } - } - } - } -} diff --git a/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/util/StrmPakConfig.java b/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/util/StrmPakConfig.java deleted file mode 100644 index ed33f7f923..0000000000 --- a/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/util/StrmPakConfig.java +++ /dev/null @@ -1,75 +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.viz.core.contours.util; - -/** - * Configuration parameters for calculating stream lines. - * - *
- * 
- * SOFTWARE HISTORY
- * 
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * Jun 26, 2013  #1999     dgilling     Initial creation
- * 
- * 
- * - * @author dgilling - * @version 1.0 - */ - -public final class StrmPakConfig { - - public float asize; - - public float minspc; - - public float maxspc; - - public float badlo; - - public float badhi; - - /** - * Creates a new configuration to run StrmPak. - * - * @param asize - * Size of arrows in MVI. - * @param minspc - * If greater than one, no two streamlines will approach any - * closer than this number of cells. If less than one, a - * streamline will terminate if it runs through 1/minspc - * consecutive already occupied cells. - * @param maxspc - * No streamline will be started any closer than this number of - * cells to an existing streamline. - * @param badlo - * @param badhi - */ - public StrmPakConfig(float asize, float minspc, float maxspc, float badlo, - float badhi) { - this.asize = asize; - this.minspc = minspc; - this.maxspc = maxspc; - this.badlo = badlo; - this.badhi = badhi; - } -}