Package ucar.nc2.ui.grid
Class ContourGrid
- java.lang.Object
-
- ucar.nc2.ui.grid.ContourGrid
-
public class ContourGrid extends Object
ContourGrid Class to make an ArrayList of ContourFeature-s from a regular 2D data grid. Creates contours, and adds all the contours to an ArrayList of ContourFeatures, given some input data grid. Contour levels desired are an input argument list. Constructor input: ucar.ma2.Array dataGrid: the 2D grid of values at grid points to contour; double []-s xPosition, yPosition: the list of coordinates of grid points along x and y axes; ArrayList allContourValues a list of the desired contour level values; GeoGridImpl geogrid How it works: Contouring is activated by calling the function getContourLines(). The contours for the dataGrid input to the cstr are made. internal variables direction is indicated by the char values N, S, E, and W, indicating directions in the grid contourValues are the contour levels used to make contours; derived from the input contour values to the constructor. If the input array contourValues is of zero length, contour values are automatically generated. xMaxInd and yMaxInd are the largest array indices in x and y permitted for this grid. One less than dimension. contourOnVertlEdge is an int array the size of the data grid, with each value 0 or 1. This is used for an indication whether a contour of a certain level crosses between this point and the next one of one larger y index. This array is recalculated for each contour level. contourOnHorizEdge is similar indication whether a contour of a certain level crosses between this point and the next one of one larger x index. These arrays are recalculated for each contour level. conLevel is the active contour level during computations. The algorithm works as follows. Each grid cell is identified by the lower left grid point (i,j). The cell edge to the right of (i,j) is the horizontal edge for grid cell (i,j) and the cell edge above (i,j) is the vertical edge. i increases to the right and j increases upward. Contouring proceeds one level at a time, starting at the lowest level. For each level the crossing indicators contourOnVertlEdge and contourOnHorizEdge are set first. When a contour level value lies between the grid value at (i,j) and value at (i+1,j) then contourOnHorizEdge(i,j) is set to 1; otherwise 0. When a contour level value lies between the grid value at (i,j) and the value at (i,j+1) then contourOnVertlEdge(i,j) is set to 1; otherwise 0. This is done by the function setupForContoursAt(double level). Note that only one contour crossing for one level is allowed between two grid points. This is consistent with the sampling of the actual data field by the grid points, though it is possible that higher data resolution could sometimes show two or more contours at a level passing between two of the grid points. Then the cell edges along the west edge of the grid are checked to see if any contour crossings occur (function searchWestEdge()). If a contour is found crossing the edge associated with the cell (i,j) the function followContour(Dir, i, j) is called, where Dir is one of the directions indicating a contour was found starting on the west edge. followContour follows this contour through the grid until it reaches its end against a grid edge (it can't close on itself since it started on an edge and only one crossing is permitted at a cell edge). As it works through the contour, contour positions are appended to the current line. This contouring code works in the (i,j) main GRID INDEX system, and contour positions have double (non-integer) values in the main grid "index" units. But the code ends by computing all contour positions in the x and y coord system input to the cstr. So as followContour works along the contour it finds the points where the contour crossed each cell edge, using the indicators contourOnVertlEdge and contourOnHorizEdge, and the function contourEdgeIntersection(side, int i, int j). The function contourEdgeIntersection() returns the position where the contour crosses the edge in main grid coordinates. The conversion is made to desired coordinate units, and that position is appended to the current contourLine. Having a position where a contour enters a main grid cell, the heading or side where the contour leaves the cell is returned by function directionToGoFrom(side, i, j). Intermediate points inside the main cell are found by contourEdgeIntersection() which also returns the next main grid point on the cell edge. This process is continued until the contour reaches its end against an edge. The functions followContour(...), contourEdgeIntersection(...)& directionToGoFrom(...) are the core of contouring. Having found all contours starting on the west edge of the main grid, the south and east edges are checked in the same way with functions searchSouthEdge() and searchEastEdge(). Then the north edges of all cells on the north edge, and all interior points, are checked to find any contours not yet found, including internal contours which close on themselves. All this was for one contour level. The process is repeated for every contour level. Some tricks to contouring appear when details of how contours can cross a cell are considered. Normally a single contour for one level comes in one side of a cell and goes out a different side. It is possible for a data grid point to exactly equal the contour level, in which case the side associated with that level is not determined. In this case the data value is shifted by adding ((gridmax - gridmin) /100000.0) This is simpler than changing the code to deal with this case, and has no observable effect on earth science data displays which is presumed to always have a much larger data range than ((gridmax - gridmin) /100000.0). Two contours of the same level may cross one cell, each crossing two differing edges. This is the case of a saddle point. Crossing point pairs are selected by choosing the nearest crossing point to the incoming point, in function directionToGoFrom. It does not appear possible to have three edges be crossed or touched by a single contour. If you think otherwise, please try to find four data values for cell corners which fit the case.
-
-
Constructor Summary
Constructors Constructor Description ContourGrid(Array dataGrid, List<Double> allContourValues, double[] xPosition, double[] yPosition, GridDatatype geogrid)
Construct the ContourGrid object for this input data of datagrid, contour level values, and x and y edge position values.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description List<ContourFeature>
getContourLines()
Make contour lines from the datagrid input to the constructor of this object.
-
-
-
Constructor Detail
-
ContourGrid
public ContourGrid(Array dataGrid, List<Double> allContourValues, double[] xPosition, double[] yPosition, GridDatatype geogrid)
Construct the ContourGrid object for this input data of datagrid, contour level values, and x and y edge position values. Supplied contour levels may be an empty object; if so then this cstr will create some reasonable levels for the data supplied. The object made contains the data used to make contours.- Parameters:
dataGrid
- the data grid of valueallContourValues
- list of level or values or contour linesxPosition
- the x position values of columns in the gridyPosition
- the y position values of rows in the gridgeogrid
- a GeoGridImpl which is used for its missing data methods.
-
-
Method Detail
-
getContourLines
public List<ContourFeature> getContourLines()
Make contour lines from the datagrid input to the constructor of this object. Before calling this routine, first construct the ContourGrid object like this: ContourGrid gridToContour(dataGrid, contourValues, xPosition, yPosition, geoGridImpl); then call gridToContour.getContourLines();- Returns:
- an ArrayList of ContourFeature objects
-
-