Search in sources :

Example 1 with PixelMap

use of uk.ac.rdg.resc.edal.cdm.PixelMap in project ncWMS by Unidata.

the class NcwmsController method readSmoothedDataGrid.

private List<Float> readSmoothedDataGrid(ScalarLayer layer, DateTime dateTime, double elevation, RegularGrid imageGrid, UsageLogEntry usageLogEntry) throws InvalidDimensionValueException, IOException {
    int width = imageGrid.getXAxis().getSize();
    int height = imageGrid.getYAxis().getSize();
    RectilinearGrid dataGrid;
    if (!(layer.getHorizontalGrid() instanceof RectilinearGrid)) {
        return layer.readHorizontalPoints(dateTime, elevation, imageGrid);
    } else {
        dataGrid = (RectilinearGrid) layer.getHorizontalGrid();
    }
    PixelMap pixelMap = new PixelMap(dataGrid, imageGrid);
    /*
         * Check whether it is worth smoothing this data
         */
    int imageSize = width * height;
    if (pixelMap.getNumUniqueIJPairs() >= imageSize || pixelMap.getNumUniqueIJPairs() == 0) {
        /*
             * We don't need to smooth the data
             */
        return layer.readHorizontalPoints(dateTime, elevation, imageGrid);
    }
    ReferenceableAxis xAxis = dataGrid.getXAxis();
    ReferenceableAxis yAxis = dataGrid.getYAxis();
    SortedSet<Double> xCoords = new TreeSet<Double>();
    SortedSet<Double> yCoords = new TreeSet<Double>();
    double minX = imageGrid.getXAxis().getCoordinateValue(0);
    /*
         * Loop through all points on the data grid which are needed, and add
         * them to sorted sets
         */
    Iterator<PixelMapEntry> iterator = pixelMap.iterator();
    while (iterator.hasNext()) {
        PixelMapEntry pme = iterator.next();
        xCoords.add(Utils.getNextEquivalentLongitude(minX, xAxis.getCoordinateValue(pme.getSourceGridIIndex())));
        yCoords.add(yAxis.getCoordinateValue(pme.getSourceGridJIndex()));
    }
    Float[][] data = new Float[xCoords.size()][yCoords.size()];
    final CoordinateReferenceSystem crs = layer.getHorizontalGrid().getCoordinateReferenceSystem();
    final List<HorizontalPosition> pointsToRead = new ArrayList<HorizontalPosition>();
    /*
         * Loop through required coords and add to a list to read
         */
    for (Double x : xCoords) {
        for (Double y : yCoords) {
            pointsToRead.add(new HorizontalPositionImpl(x, y, crs));
        }
    }
    /*
         * Use the list to read all required points at once
         */
    List<Float> points;
    try {
        points = layer.readHorizontalPoints(dateTime, elevation, new Domain<HorizontalPosition>() {

            @Override
            public CoordinateReferenceSystem getCoordinateReferenceSystem() {
                return crs;
            }

            @Override
            public List<HorizontalPosition> getDomainObjects() {
                return pointsToRead;
            }

            @Override
            public long size() {
                return pointsToRead.size();
            }
        });
    } catch (InvalidDimensionValueException e) {
        e.printStackTrace();
        throw new IllegalArgumentException("Problem reading data");
    } catch (IOException e) {
        e.printStackTrace();
        throw new IllegalArgumentException("Problem reading data");
    }
    /*
         * Now populate the data array
         */
    int index = 0;
    for (int i = 0; i < xCoords.size(); i++) {
        for (int j = 0; j < yCoords.size(); j++) {
            data[i][j] = points.get(index++);
        }
    }
    /*
         * All data reading is done at this point. We now interpolate onto each
         * image point, using a BilinearInterpolator
         */
    BilinearInterpolator interpolator = new BilinearInterpolator(xCoords, yCoords, data);
    List<Float> retData = new ArrayList<Float>();
    for (int j = 0; j < height; j++) {
        double y = imageGrid.getYAxis().getCoordinateValue(j);
        for (int i = 0; i < width; i++) {
            double x = imageGrid.getXAxis().getCoordinateValue(i);
            retData.add(interpolator.getValue(x, y));
        // retData[i][height - 1 - j] = interpolator.getValue(x,y);
        }
    }
    return retData;
}
Also used : RectilinearGrid(uk.ac.rdg.resc.edal.coverage.grid.RectilinearGrid) BilinearInterpolator(uk.ac.rdg.resc.ncwms.graphics.BilinearInterpolator) PixelMap(uk.ac.rdg.resc.edal.cdm.PixelMap) InvalidDimensionValueException(uk.ac.rdg.resc.ncwms.exceptions.InvalidDimensionValueException) ArrayList(java.util.ArrayList) HorizontalPositionImpl(uk.ac.rdg.resc.edal.geometry.impl.HorizontalPositionImpl) IOException(java.io.IOException) PixelMapEntry(uk.ac.rdg.resc.edal.cdm.PixelMap.PixelMapEntry) ReferenceableAxis(uk.ac.rdg.resc.edal.coverage.grid.ReferenceableAxis) HorizontalPosition(uk.ac.rdg.resc.edal.geometry.HorizontalPosition) TreeSet(java.util.TreeSet) CoordinateReferenceSystem(org.opengis.referencing.crs.CoordinateReferenceSystem) Domain(uk.ac.rdg.resc.edal.coverage.domain.Domain)

Example 2 with PixelMap

use of uk.ac.rdg.resc.edal.cdm.PixelMap in project ncWMS by Unidata.

the class AbstractWmsController method readDataGrid.

/**
 * Reads a grid of data from the given layer, used by the GetMap operation.
 * <p>This implementation simply defers to {@link
 * ScalarLayer#readPointList(org.joda.time.DateTime, double,
 * uk.ac.rdg.resc.ncwms.datareader.PointList) layer.readPointList()},
 * ignoring the usage log entry.  No data are cached.  Other implementations
 * may choose to implement in a different way, perhaps to allow for caching
 * of the data.  If implementations return cached data they must indicate
 * this by setting {@link UsageLogEntry#setUsedCache(boolean)}.</p>
 * @param layer The layer containing the data
 * @param time The time instant for which we require data.  If this does not
 * match a time instant in {@link Layer#getTimeValues()} an {@link InvalidDimensionValueException}
 * will be thrown.  (If this Layer has no time axis, this parameter will be ignored.)
 * @param elevation The elevation for which we require data (in the
 * {@link Layer#getElevationUnits() units of this Layer's elevation axis}).  If
 * this does not match a valid {@link Layer#getElevationValues() elevation value}
 * in this Layer, this method will throw an {@link InvalidDimensionValueException}.
 * (If this Layer has no elevation axis, this parameter will be ignored.)
 * @param imageGrid The grid of points, one point per pixel in the image that will
 * be created in the GetMap operation
 * @param usageLogEntry
 * @return a List of data values, one for each point in
 * the {@code grid}, in the same order.
 * @throws InvalidDimensionValueException if {@code dateTime} or {@code elevation}
 * do not represent valid values along the time and elevation axes.
 * @throws IOException if there was an error reading from the data source
 */
protected List<Float> readDataGrid(ScalarLayer layer, DateTime dateTime, double elevation, RegularGrid imageGrid, UsageLogEntry usageLogEntry, boolean smoothed) throws InvalidDimensionValueException, IOException {
    if (!smoothed) {
        return layer.readHorizontalPoints(dateTime, elevation, imageGrid);
    } else {
        int width = imageGrid.getXAxis().getSize();
        int height = imageGrid.getYAxis().getSize();
        RectilinearGrid dataGrid;
        if (!(layer.getHorizontalGrid() instanceof RectilinearGrid)) {
            return layer.readHorizontalPoints(dateTime, elevation, imageGrid);
        } else {
            dataGrid = (RectilinearGrid) layer.getHorizontalGrid();
        }
        PixelMap pixelMap = new PixelMap(dataGrid, imageGrid);
        /*
             * Check whether it is worth smoothing this data
             */
        int imageSize = width * height;
        if (pixelMap.getNumUniqueIJPairs() >= imageSize || pixelMap.getNumUniqueIJPairs() == 0) {
            /*
                 * We don't need to smooth the data
                 */
            return layer.readHorizontalPoints(dateTime, elevation, imageGrid);
        }
        ReferenceableAxis xAxis = dataGrid.getXAxis();
        ReferenceableAxis yAxis = dataGrid.getYAxis();
        SortedSet<Double> xCoords = new TreeSet<Double>();
        SortedSet<Double> yCoords = new TreeSet<Double>();
        double minX = imageGrid.getXAxis().getCoordinateValue(0);
        /*
             * Loop through all points on the data grid which are needed, and add
             * them to sorted sets
             */
        Iterator<PixelMapEntry> iterator = pixelMap.iterator();
        while (iterator.hasNext()) {
            PixelMapEntry pme = iterator.next();
            xCoords.add(Utils.getNextEquivalentLongitude(minX, xAxis.getCoordinateValue(pme.getSourceGridIIndex())));
            yCoords.add(yAxis.getCoordinateValue(pme.getSourceGridJIndex()));
        }
        Float[][] data = new Float[xCoords.size()][yCoords.size()];
        final CoordinateReferenceSystem crs = layer.getHorizontalGrid().getCoordinateReferenceSystem();
        final List<HorizontalPosition> pointsToRead = new ArrayList<HorizontalPosition>();
        /*
             * Loop through required coords and add to a list to read
             */
        for (Double x : xCoords) {
            for (Double y : yCoords) {
                pointsToRead.add(new HorizontalPositionImpl(x, y, crs));
            }
        }
        /*
             * Use the list to read all required points at once
             */
        List<Float> points;
        try {
            points = layer.readHorizontalPoints(dateTime, elevation, new Domain<HorizontalPosition>() {

                @Override
                public CoordinateReferenceSystem getCoordinateReferenceSystem() {
                    return crs;
                }

                @Override
                public List<HorizontalPosition> getDomainObjects() {
                    return pointsToRead;
                }

                @Override
                public long size() {
                    return pointsToRead.size();
                }
            });
        } catch (InvalidDimensionValueException e) {
            e.printStackTrace();
            throw new IllegalArgumentException("Problem reading data");
        } catch (IOException e) {
            e.printStackTrace();
            throw new IllegalArgumentException("Problem reading data");
        }
        /*
             * Now populate the data array
             */
        int index = 0;
        for (int i = 0; i < xCoords.size(); i++) {
            for (int j = 0; j < yCoords.size(); j++) {
                data[i][j] = points.get(index++);
            }
        }
        /*
             * All data reading is done at this point. We now interpolate onto each
             * image point, using a BilinearInterpolator
             */
        BilinearInterpolator interpolator = new BilinearInterpolator(xCoords, yCoords, data);
        List<Float> retData = new ArrayList<Float>();
        for (int j = 0; j < height; j++) {
            double y = imageGrid.getYAxis().getCoordinateValue(j);
            for (int i = 0; i < width; i++) {
                double x = imageGrid.getXAxis().getCoordinateValue(i);
                retData.add(interpolator.getValue(x, y));
            }
        }
        return retData;
    }
}
Also used : RectilinearGrid(uk.ac.rdg.resc.edal.coverage.grid.RectilinearGrid) BilinearInterpolator(uk.ac.rdg.resc.ncwms.graphics.BilinearInterpolator) PixelMap(uk.ac.rdg.resc.edal.cdm.PixelMap) InvalidDimensionValueException(uk.ac.rdg.resc.ncwms.exceptions.InvalidDimensionValueException) ArrayList(java.util.ArrayList) HorizontalPositionImpl(uk.ac.rdg.resc.edal.geometry.impl.HorizontalPositionImpl) IOException(java.io.IOException) PixelMapEntry(uk.ac.rdg.resc.edal.cdm.PixelMap.PixelMapEntry) ReferenceableAxis(uk.ac.rdg.resc.edal.coverage.grid.ReferenceableAxis) HorizontalPosition(uk.ac.rdg.resc.edal.geometry.HorizontalPosition) TreeSet(java.util.TreeSet) CoordinateReferenceSystem(org.opengis.referencing.crs.CoordinateReferenceSystem) HorizontalDomain(uk.ac.rdg.resc.edal.coverage.domain.impl.HorizontalDomain) Domain(uk.ac.rdg.resc.edal.coverage.domain.Domain)

Example 3 with PixelMap

use of uk.ac.rdg.resc.edal.cdm.PixelMap in project ncWMS by Unidata.

the class PhaveosDataReader method read.

@Override
public List<Float> read(String filename, Layer layer, int tIndex, int zIndex, Domain<HorizontalPosition> targetDomain) throws IOException {
    NetcdfDataset nc = null;
    try {
        nc = NetcdfDataset.openDataset(filename);
        ucar.nc2.Variable var = nc.findVariable(layer.getId());
        // We read in data using a "bounding box" strategy
        PixelMap pm = new PixelMap(layer.getHorizontalGrid(), targetDomain);
        int iSize = pm.getMaxIIndex() - pm.getMinIIndex() + 1;
        int jSize = pm.getMaxJIndex() - pm.getMinJIndex() + 1;
        int[] origin = new int[] { pm.getMinJIndex(), pm.getMinIIndex() };
        int[] shape = new int[] { jSize, iSize };
        Array data = var.read(origin, shape);
        // Now copy the data to an array of floats
        Index index = data.getIndex();
        index.set(new int[index.getRank()]);
        float[] arr = new float[(int) targetDomain.size()];
        Arrays.fill(arr, Float.NaN);
        for (PixelMapEntry pme : pm) {
            int i = pme.getSourceGridIIndex() - pm.getMinIIndex();
            int j = pme.getSourceGridJIndex() - pm.getMinJIndex();
            index.set(new int[] { j, i });
            float val = data.getFloat(index);
            // Hack to deal with factor-1000 scale in L4 data
            if ("mtci_l4".equals(layer.getId())) {
                val /= 1000.0f;
            }
            for (int targetGridPoint : pme.getTargetGridPoints()) {
                arr[targetGridPoint] = val > 0.0f ? val : Float.NaN;
            }
        }
        return CdmUtils.wrap(arr);
    } catch (InvalidRangeException ire) {
        // Shouldn't happen: this would be a programming error
        throw new RuntimeException(ire);
    } finally {
        if (nc != null) {
            nc.close();
        }
    }
}
Also used : PixelMap(uk.ac.rdg.resc.edal.cdm.PixelMap) InvalidRangeException(ucar.ma2.InvalidRangeException) Index(ucar.ma2.Index) NetcdfDataset(ucar.nc2.dataset.NetcdfDataset) PixelMapEntry(uk.ac.rdg.resc.edal.cdm.PixelMap.PixelMapEntry) Array(ucar.ma2.Array)

Aggregations

PixelMap (uk.ac.rdg.resc.edal.cdm.PixelMap)3 PixelMapEntry (uk.ac.rdg.resc.edal.cdm.PixelMap.PixelMapEntry)3 IOException (java.io.IOException)2 ArrayList (java.util.ArrayList)2 TreeSet (java.util.TreeSet)2 CoordinateReferenceSystem (org.opengis.referencing.crs.CoordinateReferenceSystem)2 Domain (uk.ac.rdg.resc.edal.coverage.domain.Domain)2 RectilinearGrid (uk.ac.rdg.resc.edal.coverage.grid.RectilinearGrid)2 ReferenceableAxis (uk.ac.rdg.resc.edal.coverage.grid.ReferenceableAxis)2 HorizontalPosition (uk.ac.rdg.resc.edal.geometry.HorizontalPosition)2 HorizontalPositionImpl (uk.ac.rdg.resc.edal.geometry.impl.HorizontalPositionImpl)2 InvalidDimensionValueException (uk.ac.rdg.resc.ncwms.exceptions.InvalidDimensionValueException)2 BilinearInterpolator (uk.ac.rdg.resc.ncwms.graphics.BilinearInterpolator)2 Array (ucar.ma2.Array)1 Index (ucar.ma2.Index)1 InvalidRangeException (ucar.ma2.InvalidRangeException)1 NetcdfDataset (ucar.nc2.dataset.NetcdfDataset)1 HorizontalDomain (uk.ac.rdg.resc.edal.coverage.domain.impl.HorizontalDomain)1