Search in sources :

Example 46 with RandomIter

use of javax.media.jai.iterator.RandomIter in project hortonmachine by TheHortonMachine.

the class OmsMagnitudo method magnitudo.

public void magnitudo(RandomIter flowIter, int width, int height, WritableRaster magWR) {
    int[] flow = new int[2];
    // get rows and cols from the active region
    int cols = width;
    int rows = height;
    RandomIter magIter = RandomIterFactory.create(magWR, null);
    // $NON-NLS-1$
    pm.beginTask(msg.message("magnitudo.workingon"), rows * 2);
    for (int j = 0; j < rows; j++) {
        for (int i = 0; i < cols; i++) {
            flow[0] = i;
            flow[1] = j;
            // looks for the source
            if (isSourcePixel(flowIter, flow[0], flow[1])) {
                magWR.setSample(flow[0], flow[1], 0, magIter.getSampleDouble(flow[0], flow[1], 0) + 1.0);
                if (!go_downstream(flow, flowIter.getSampleDouble(flow[0], flow[1], 0)))
                    return;
                while (!isNovalue(flowIter.getSampleDouble(flow[0], flow[1], 0)) && flowIter.getSampleDouble(flow[0], flow[1], 0) != 10) {
                    magWR.setSample(flow[0], flow[1], 0, magIter.getSampleDouble(flow[0], flow[1], 0) + 1.0);
                    if (!go_downstream(flow, flowIter.getSampleDouble(flow[0], flow[1], 0)))
                        return;
                }
                if (flowIter.getSampleDouble(flow[0], flow[1], 0) == 10) {
                    magWR.setSample(flow[0], flow[1], 0, magIter.getSampleDouble(flow[0], flow[1], 0) + 1.0);
                }
            }
        }
        pm.worked(1);
    }
    for (int j = 0; j < rows; j++) {
        for (int i = 0; i < cols; i++) {
            if (magIter.getSampleDouble(i, j, 0) == 0.0 && flowIter.getSampleDouble(i, j, 0) == 10.0) {
                magWR.setSample(i, j, 0, 1.0);
            } else if (magIter.getSampleDouble(i, j, 0) == 0.0 && isNovalue(flowIter.getSampleDouble(i, j, 0))) {
                magWR.setSample(i, j, 0, doubleNovalue);
            }
        }
        pm.worked(1);
    }
    pm.done();
}
Also used : RandomIter(javax.media.jai.iterator.RandomIter)

Example 47 with RandomIter

use of javax.media.jai.iterator.RandomIter in project hortonmachine by TheHortonMachine.

the class OmsNetDiff method netdif.

/**
 * Calculates the difference map.
 *
 * @return
 */
private WritableRaster netdif() {
    // get rows and cols from the active region
    HashMap<String, Double> regionMap = CoverageUtilities.getRegionParamsFromGridCoverage(inFlow);
    int cols = regionMap.get(CoverageUtilities.COLS).intValue();
    int rows = regionMap.get(CoverageUtilities.ROWS).intValue();
    int[] flow = new int[2];
    int[] oldflow = new int[2];
    RandomIter flowIter = CoverageUtilities.getRandomIterator(inFlow);
    RandomIter streamIter = CoverageUtilities.getRandomIterator(inStream);
    RandomIter rasterIter = CoverageUtilities.getRandomIterator(inRaster);
    int[][] dir = ModelsSupporter.DIR_WITHFLOW_ENTERING;
    // create new matrix
    double[][] segna = new double[cols][rows];
    pm.beginTask(msg.message("working") + "h.netdif", 3 * rows);
    // of a link or stream
    for (int j = 0; j < rows; j++) {
        for (int i = 0; i < cols; i++) {
            flow[0] = i;
            flow[1] = j;
            // looks for the source
            if (ModelsEngine.isSourcePixel(flowIter, flow[0], flow[1])) {
                segna[i][j] = 1;
            } else if (!isNovalue(flowIter.getSampleDouble(i, j, 0)) && flowIter.getSampleDouble(i, j, 0) != 10.0) {
                for (int k = 1; k <= 8; k++) {
                    if (flowIter.getSampleDouble(flow[0] + dir[k][1], flow[1] + dir[k][0], 0) == dir[k][2]) {
                        if (streamIter.getSampleDouble(flow[0] + dir[k][1], flow[1] + dir[k][0], 0) == streamIter.getSampleDouble(i, j, 0)) {
                            segna[i][j] = 0;
                            break;
                        } else {
                            segna[i][j] = 1;
                        }
                    }
                }
            }
        }
        pm.worked(1);
    }
    WritableRaster diffImage = CoverageUtilities.createWritableRaster(cols, rows, null, inFlow.getRenderedImage().getSampleModel(), null);
    WritableRandomIter diffIter = RandomIterFactory.createWritable(diffImage, null);
    // point of a link
    for (int j = 0; j < rows; j++) {
        for (int i = 0; i < cols; i++) {
            if (segna[i][j] > 0) {
                flow[0] = i;
                flow[1] = j;
                oldflow[0] = i;
                oldflow[1] = j;
                if (!isNovalue(flowIter.getSampleDouble(flow[0], flow[1], 0))) {
                    // call go_downstream in FluidUtils
                    ModelsEngine.go_downstream(flow, flowIter.getSampleDouble(flow[0], flow[1], 0));
                    while (segna[flow[0]][flow[1]] < 1 && !isNovalue(flowIter.getSampleDouble(flow[0], flow[1], 0)) && flowIter.getSampleDouble(flow[0], flow[1], 0) != 10.0 && streamIter.getSampleDouble(flow[0], flow[1], 0) == streamIter.getSampleDouble(i, j, 0)) {
                        oldflow[0] = flow[0];
                        oldflow[1] = flow[1];
                        if (!ModelsEngine.go_downstream(flow, flowIter.getSampleDouble(flow[0], flow[1], 0)))
                            return null;
                    }
                    diffIter.setSample(i, j, 0, Math.abs(rasterIter.getSampleDouble(i, j, 0) - rasterIter.getSampleDouble(oldflow[0], oldflow[1], 0)));
                    // Assign to any point inside the link the value of the
                    // difference
                    flow[0] = i;
                    flow[1] = j;
                    if (!ModelsEngine.go_downstream(flow, flowIter.getSampleDouble(flow[0], flow[1], 0)))
                        return null;
                    while (!isNovalue(flowIter.getSampleDouble(flow[0], flow[1], 0)) && flowIter.getSampleDouble(flow[0], flow[1], 0) != 10.0 && streamIter.getSampleDouble(flow[0], flow[1], 0) == streamIter.getSampleDouble(i, j, 0)) {
                        diffIter.setSample(flow[0], flow[1], 0, diffIter.getSampleDouble(i, j, 0));
                        if (!ModelsEngine.go_downstream(flow, flowIter.getSampleDouble(flow[0], flow[1], 0)))
                            return null;
                    }
                    if (flowIter.getSampleDouble(flow[0], flow[1], 0) == 10 && streamIter.getSampleDouble(flow[0], flow[1], 0) == streamIter.getSampleDouble(i, j, 0)) {
                        diffIter.setSample(flow[0], flow[1], 0, diffIter.getSampleDouble(i, j, 0));
                    }
                }
            }
        }
        pm.worked(1);
    }
    for (int j = 0; j < rows; j++) {
        for (int i = 0; i < cols; i++) {
            if (isNovalue(streamIter.getSampleDouble(i, j, 0))) {
                diffIter.setSample(i, j, 0, doubleNovalue);
            }
        }
        pm.worked(1);
    }
    pm.done();
    diffIter.done();
    flowIter.done();
    rasterIter.done();
    streamIter.done();
    return diffImage;
}
Also used : WritableRandomIter(javax.media.jai.iterator.WritableRandomIter) WritableRaster(java.awt.image.WritableRaster) RandomIter(javax.media.jai.iterator.RandomIter) WritableRandomIter(javax.media.jai.iterator.WritableRandomIter)

Example 48 with RandomIter

use of javax.media.jai.iterator.RandomIter in project hortonmachine by TheHortonMachine.

the class OmsLW10_SingleTree_AreaToNetpointAssociator method process.

@Execute
public void process() throws Exception {
    GridGeometry2D gridGeometry = inFlow.getGridGeometry();
    GeometryFactory gf = GeometryUtilities.gf();
    /*
         * extract the inundated area from the polygon
         */
    PreparedGeometry preparedFloodingArea = getFloodingArea(inInundationArea);
    List<FeatureMate> treesList = FeatureUtilities.featureCollectionToMatesList(inTreePoints);
    /*
         * extract basins calling netnumbering with in input all the network points
         */
    OmsNetNumbering omsnetnumbering = new OmsNetNumbering();
    omsnetnumbering.inFlow = inFlow;
    omsnetnumbering.inNet = inNet;
    omsnetnumbering.inTca = inTca;
    omsnetnumbering.inPoints = inNetPoints;
    omsnetnumbering.pm = pm;
    omsnetnumbering.process();
    outNetnum = omsnetnumbering.outNetnum;
    outBasins = omsnetnumbering.outBasins;
    RandomIter netnumBasinsIter = CoverageUtilities.getRandomIterator(outBasins);
    RandomIter connectivityIter = CoverageUtilities.getRandomIterator(inConnectivity);
    HashMap<Integer, DescriptiveStatistics> heightBasin2ValueMap = new HashMap<Integer, DescriptiveStatistics>();
    HashMap<Integer, DescriptiveStatistics> dbhBasin2ValueMap = new HashMap<Integer, DescriptiveStatistics>();
    HashMap<Integer, DescriptiveStatistics> standBasin2ValueMap = new HashMap<Integer, DescriptiveStatistics>();
    FeatureExtender treesExtender = new FeatureExtender(inTreePoints.getSchema(), new String[] { LWFields.LINKID }, new Class[] { Integer.class });
    List<SimpleFeature> treePointsList = new ArrayList<>();
    pm.beginTask("Calculating vegetation stats.", treesList.size());
    for (FeatureMate treeFeature : treesList) {
        Coordinate treeCoordinate = treeFeature.getGeometry().getCoordinate();
        Point treePoint = gf.createPoint(treeCoordinate);
        double treeHeight = treeFeature.getAttribute(LWFields.FIELD_ELEV, Double.class);
        int[] colRow = CoverageUtilities.colRowFromCoordinate(treeCoordinate, gridGeometry, null);
        int c = colRow[0];
        int r = colRow[1];
        double netnumDouble = netnumBasinsIter.getSampleDouble(c, r, 0);
        if (!isNovalue(netnumDouble)) {
            Integer netNum = (int) netnumDouble;
            double connectivityDouble = connectivityIter.getSampleDouble(c, r, 0);
            /*
                 * check if the point is connected to the network:
                 * - connectivity index less than the threshold
                 * - point is inside the inundated area
                 * and fill the hashmaps with the correspondent positions.
                 */
            if (connectivityDouble < pConnectivityThreshold || preparedFloodingArea.intersects(treePoint)) {
                double[] volume = calculateVolume(treeHeight);
                double dbhDouble = volume[0];
                double standDouble = volume[1];
                // TODO: here use the taper to evaluate the effective length
                double lengthLimitBeforeFlexibility = (dbhDouble - pFlexibleDiameterLimit) / pTreeTaper;
                double usefulHeightForPropagationDownstream = lengthLimitBeforeFlexibility + HEIGHT_FOR_MEASURING_DBH;
                if (treeHeight >= usefulHeightForPropagationDownstream) {
                    treeHeight = usefulHeightForPropagationDownstream;
                }
                DescriptiveStatistics summaryHeightStatistics = heightBasin2ValueMap.get(netNum);
                DescriptiveStatistics summaryDbhStatistics = dbhBasin2ValueMap.get(netNum);
                DescriptiveStatistics summaryStandStatistics = standBasin2ValueMap.get(netNum);
                if (summaryHeightStatistics == null) {
                    summaryHeightStatistics = new DescriptiveStatistics();
                    summaryDbhStatistics = new DescriptiveStatistics();
                    summaryStandStatistics = new DescriptiveStatistics();
                    heightBasin2ValueMap.put(netNum, summaryHeightStatistics);
                    dbhBasin2ValueMap.put(netNum, summaryDbhStatistics);
                    standBasin2ValueMap.put(netNum, summaryStandStatistics);
                }
                summaryHeightStatistics.addValue(treeHeight);
                summaryDbhStatistics.addValue(dbhDouble);
                summaryStandStatistics.addValue(standDouble);
                // for now we put the basin netnum as id, later we substitute it with the linkid
                // (here it is not known yet)
                SimpleFeature newTreeFeature = treesExtender.extendFeature(treeFeature.getFeature(), new Object[] { netNum });
                treePointsList.add(newTreeFeature);
            }
        }
        pm.worked(1);
    }
    pm.done();
    /*
         * create the structure for the output attributes and insert the summary statistics
         * as attributes
         */
    FeatureExtender netPointsExtender = new FeatureExtender(inNetPoints.getSchema(), new String[] { LWFields.VEG_VOL, LWFields.VEG_H, LWFields.VEG_DBH }, new Class[] { Double.class, Double.class, Double.class });
    List<SimpleFeature> inNetworkPointsList = FeatureUtilities.featureCollectionToList(inNetPoints);
    DefaultFeatureCollection finalNetworkPointsFC = new DefaultFeatureCollection();
    final java.awt.Point point = new java.awt.Point();
    HashMap<Integer, Integer> netnum2LinkidMap = new HashMap<>();
    for (SimpleFeature inPointFeature : inNetworkPointsList) {
        Integer id = (Integer) inPointFeature.getAttribute(LWFields.LINKID);
        Geometry geometry = (Geometry) inPointFeature.getDefaultGeometry();
        Coordinate coordinate = geometry.getCoordinate();
        CoverageUtilities.colRowFromCoordinate(coordinate, gridGeometry, point);
        int netnum = netnumBasinsIter.getSample(point.x, point.y, 0);
        netnum2LinkidMap.put(netnum, id);
        DescriptiveStatistics summaryHeightStatistics = heightBasin2ValueMap.get(netnum);
        double medianHeight = 0.0;
        if (summaryHeightStatistics != null) {
            medianHeight = summaryHeightStatistics.getPercentile(pRepresentingHeightDbhPercentile);
        }
        DescriptiveStatistics summaryDbhStatistics = dbhBasin2ValueMap.get(netnum);
        double medianDbh = 0.0;
        if (summaryDbhStatistics != null) {
            medianDbh = summaryDbhStatistics.getPercentile(pRepresentingHeightDbhPercentile);
        }
        DescriptiveStatistics summaryStandStatistics = standBasin2ValueMap.get(netnum);
        double sumStand = 0.0;
        if (summaryStandStatistics != null) {
            sumStand = summaryStandStatistics.getSum();
        }
        SimpleFeature newPointFeature = netPointsExtender.extendFeature(inPointFeature, new Object[] { sumStand, medianHeight, medianDbh });
        finalNetworkPointsFC.add(newPointFeature);
    }
    outNetPoints = finalNetworkPointsFC;
    outTreePoints = new DefaultFeatureCollection();
    for (SimpleFeature treePointFeature : treePointsList) {
        Integer netnum = (Integer) treePointFeature.getAttribute(LWFields.LINKID);
        Integer linkid = netnum2LinkidMap.get(netnum);
        treePointFeature.setAttribute(LWFields.LINKID, linkid);
        ((DefaultFeatureCollection) outTreePoints).add(treePointFeature);
    }
}
Also used : DescriptiveStatistics(org.apache.commons.math3.stat.descriptive.DescriptiveStatistics) GridGeometry2D(org.geotools.coverage.grid.GridGeometry2D) GeometryFactory(org.locationtech.jts.geom.GeometryFactory) PreparedGeometryFactory(org.locationtech.jts.geom.prep.PreparedGeometryFactory) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) FeatureExtender(org.hortonmachine.gears.utils.features.FeatureExtender) FeatureMate(org.hortonmachine.gears.utils.features.FeatureMate) OmsNetNumbering(org.hortonmachine.hmachine.modules.network.netnumbering.OmsNetNumbering) DefaultFeatureCollection(org.geotools.feature.DefaultFeatureCollection) RandomIter(javax.media.jai.iterator.RandomIter) Point(org.locationtech.jts.geom.Point) SimpleFeature(org.opengis.feature.simple.SimpleFeature) Point(org.locationtech.jts.geom.Point) PreparedGeometry(org.locationtech.jts.geom.prep.PreparedGeometry) Geometry(org.locationtech.jts.geom.Geometry) PreparedGeometry(org.locationtech.jts.geom.prep.PreparedGeometry) Coordinate(org.locationtech.jts.geom.Coordinate) Execute(oms3.annotations.Execute)

Example 49 with RandomIter

use of javax.media.jai.iterator.RandomIter in project hortonmachine by TheHortonMachine.

the class OmsBaseflowWaterVolume method process.

@Execute
public void process() throws Exception {
    checkNull(inInfiltration, inNetInfiltration, inFlowdirections, inNet);
    RegionMap regionMap = CoverageUtilities.getRegionParamsFromGridCoverage(inFlowdirections);
    int rows = regionMap.getRows();
    int cols = regionMap.getCols();
    double outNv = HMConstants.doubleNovalue;
    double lsumNv = -1E32;
    WritableRaster outBaseflowWR = CoverageUtilities.createWritableRaster(cols, rows, null, null, outNv);
    WritableRandomIter outBaseflowIter = CoverageUtilities.getWritableRandomIterator(outBaseflowWR);
    WritableRaster outBWR = CoverageUtilities.createWritableRaster(cols, rows, null, null, outNv);
    WritableRandomIter outBIter = CoverageUtilities.getWritableRandomIterator(outBWR);
    WritableRaster outVriWR = CoverageUtilities.createWritableRaster(cols, rows, null, null, outNv);
    WritableRandomIter outVriIter = CoverageUtilities.getWritableRandomIterator(outVriWR);
    RandomIter flowIter = CoverageUtilities.getRandomIterator(inFlowdirections);
    int flowNv = HMConstants.getIntNovalue(inFlowdirections);
    RandomIter netInfiltrationIter = CoverageUtilities.getRandomIterator(inNetInfiltration);
    double netInfNv = HMConstants.getNovalue(inNetInfiltration);
    RandomIter infiltrationIter = CoverageUtilities.getRandomIterator(inInfiltration);
    infNv = HMConstants.getNovalue(inInfiltration);
    RandomIter netIter = CoverageUtilities.getRandomIterator(inNet);
    netNv = HMConstants.getNovalue(inNet);
    List<FlowNode> sourceCells = new ArrayList<>();
    List<FlowNode> exitCells = new ArrayList<>();
    try {
        pm.beginTask("Collect source and exit cells...", rows);
        for (int r = 0; r < rows; r++) {
            if (pm.isCanceled()) {
                return;
            }
            for (int c = 0; c < cols; c++) {
                if (r == 1 && c == 959) {
                    System.out.println();
                }
                FlowNode node = new FlowNode(flowIter, cols, rows, c, r, flowNv);
                // get exit cells
                if (node.isHeadingOutside()) {
                    exitCells.add(node);
                }
                // and source cells on network
                if (node.isSource()) {
                    sourceCells.add(node);
                }
            }
            pm.worked(1);
        }
        pm.done();
        // calculate matrix of cumulated infiltration
        double[][] lSumMatrix = new double[rows][cols];
        for (int row = 0; row < rows; row++) {
            for (int col = 0; col < cols; col++) {
                lSumMatrix[row][col] = lsumNv;
            }
        }
        calculateLsumMatrix(sourceCells, lSumMatrix, infiltrationIter, netIter, lsumNv, pm);
        // calculate matrix of cumulated baseflow
        double[][] bSumMatrix = new double[rows][cols];
        pm.beginTask("Calcuate bsum...", exitCells.size());
        for (FlowNode exitCell : exitCells) {
            if (pm.isCanceled()) {
                return;
            }
            walkUpAndProcess(exitCell, bSumMatrix, lSumMatrix, outBaseflowIter, netIter, infiltrationIter, netInfiltrationIter);
            pm.worked(1);
        }
        pm.done();
        double qb = 0;
        int count = 0;
        pm.beginTask("Calculate total baseflow...", rows);
        for (int row = 0; row < rows; row++) {
            for (int col = 0; col < cols; col++) {
                double li = infiltrationIter.getSampleDouble(col, row, 0);
                if (!HMConstants.isNovalue(li, infNv)) {
                    qb += li;
                    count++;
                }
            }
            pm.worked(1);
        }
        double qbTmp = qb / count;
        outQb = qbTmp;
        pm.done();
        pm.beginTask("Calculate Vri...", rows);
        double vriSum = 0;
        for (int row = 0; row < rows; row++) {
            for (int col = 0; col < cols; col++) {
                double li = infiltrationIter.getSampleDouble(col, row, 0);
                double bSum = outBaseflowIter.getSampleDouble(col, row, 0);
                double lSum = lSumMatrix[row][col];
                if (!HMConstants.isNovalue(li, infNv)) {
                    double vri = li / (qbTmp * count);
                    vriSum += vri;
                    outVriIter.setSample(col, row, 0, vri);
                    double bi = Math.max(bSum * li / lSum, 0);
                    outBIter.setSample(col, row, 0, bi);
                }
            }
            pm.worked(1);
        }
        pm.done();
        outVriSum = vriSum;
        outBaseflow = CoverageUtilities.buildCoverageWithNovalue("baseflow", outBaseflowWR, regionMap, inFlowdirections.getCoordinateReferenceSystem(), outNv);
        outLsum = CoverageUtilities.buildCoverageWithNovalue("lsum", lSumMatrix, regionMap, inFlowdirections.getCoordinateReferenceSystem(), true, lsumNv);
        outB = CoverageUtilities.buildCoverageWithNovalue("b", outBWR, regionMap, inFlowdirections.getCoordinateReferenceSystem(), outNv);
        outVri = CoverageUtilities.buildCoverageWithNovalue("vri", outVriWR, regionMap, inFlowdirections.getCoordinateReferenceSystem(), lsumNv);
    } finally {
        flowIter.done();
        netInfiltrationIter.done();
        infiltrationIter.done();
        netIter.done();
        outBaseflowIter.done();
        outBIter.done();
        outVriIter.done();
    }
}
Also used : WritableRandomIter(javax.media.jai.iterator.WritableRandomIter) WritableRaster(java.awt.image.WritableRaster) RegionMap(org.hortonmachine.gears.utils.RegionMap) ArrayList(java.util.ArrayList) RandomIter(javax.media.jai.iterator.RandomIter) WritableRandomIter(javax.media.jai.iterator.WritableRandomIter) FlowNode(org.hortonmachine.gears.libs.modules.FlowNode) Execute(oms3.annotations.Execute)

Example 50 with RandomIter

use of javax.media.jai.iterator.RandomIter in project hortonmachine by TheHortonMachine.

the class OmsDebrisVandre method process.

@Execute
public void process() throws Exception {
    checkNull(inFlow, inTriggers, inSlope);
    RegionMap regionMap = CoverageUtilities.getRegionParamsFromGridCoverage(inFlow);
    cols = regionMap.getCols();
    rows = regionMap.getRows();
    xRes = regionMap.getXres();
    yRes = regionMap.getYres();
    if (inSoil != null) {
        if (inNet == null) {
            throw new ModelsIllegalargumentException("If the soil map is supplied also the network map is needed.", this, pm);
        }
        outSoilWR = CoverageUtilities.createWritableRaster(cols, rows, null, null, HMConstants.doubleNovalue);
        outSoilIter = RandomIterFactory.createWritable(outSoilWR, null);
        RenderedImage soilRI = inSoil.getRenderedImage();
        soilIter = RandomIterFactory.create(soilRI, null);
        RenderedImage netRI = inNet.getRenderedImage();
        netIter = RandomIterFactory.create(netRI, null);
    }
    switch(pMode) {
        case 1:
            minDegrees = minDegreesModifiedBurton;
            toggleDegrees = toggleDegreesModifiedBurton;
            break;
        case 0:
        default:
            minDegrees = minDegreesBurton;
            toggleDegrees = toggleDegreesBurton;
            break;
    }
    GridGeometry2D gridGeometry = inFlow.getGridGeometry();
    if (inObstacles != null) {
        List<Geometry> obstacleGeometries = FeatureUtilities.featureCollectionToGeometriesList(inObstacles, false, null);
        for (Geometry geometry : obstacleGeometries) {
            java.awt.Point p = new java.awt.Point();
            CoverageUtilities.colRowFromCoordinate(geometry.getCoordinate(), gridGeometry, p);
            obstaclesSet.add(p);
        }
        useObstacles = true;
    }
    RenderedImage elevRI = inElev.getRenderedImage();
    RandomIter elevIter = RandomIterFactory.create(elevRI, null);
    RenderedImage flowRI = inFlow.getRenderedImage();
    WritableRaster flowWR = CoverageUtilities.renderedImage2WritableRaster(flowRI, false);
    flowIter = RandomIterFactory.createWritable(flowWR, null);
    RenderedImage triggerRI = inTriggers.getRenderedImage();
    RandomIter triggerIter = RandomIterFactory.create(triggerRI, null);
    RenderedImage slopeRI = inSlope.getRenderedImage();
    RandomIter slopeIter = RandomIterFactory.create(slopeRI, null);
    outPaths = new DefaultFeatureCollection();
    outIndexedTriggers = new DefaultFeatureCollection();
    SimpleFeatureType triggersType = createTriggersType();
    SimpleFeatureType pathsType = createPathType();
    int featureIndex = 0;
    /*
         * FIXME the common paths are extracted many times, not good
         */
    pm.beginTask("Extracting paths...", cols);
    for (int r = 0; r < rows; r++) {
        for (int c = 0; c < cols; c++) {
            double netflowValue = flowIter.getSampleDouble(c, r, 0);
            if (isNovalue(netflowValue)) {
                continue;
            }
            if (ModelsEngine.isSourcePixel(flowIter, c, r)) {
                // pm.message("NEW SOURCE: " + c + "/" + r);
                // start navigating down until you find a debris trigger
                int[] flowDirColRow = new int[] { c, r };
                if (!moveToNextTriggerpoint(triggerIter, flowIter, flowDirColRow)) {
                    // we reached the exit
                    continue;
                }
                int triggerCol = flowDirColRow[0];
                int triggerRow = flowDirColRow[1];
                /*
                     * analyze for this trigger, after that, continue with the next one down
                     */
                double flowValue = 0;
                do {
                    /*
                         * check if this trigger was already processed, wich can happen if the same path is run
                         * after a confluence
                         */
                    String triggerId = StringUtilities.joinStrings(null, String.valueOf(triggerCol), "_", String.valueOf(triggerRow));
                    if (processedtriggersMap.add(triggerId)) {
                        // trigger point has never been touched, process it
                        // pm.message(StringUtilities.joinStrings(null, "TRIGGER: ",
                        // String.valueOf(triggerCol), "/",
                        // String.valueOf(triggerRow)));
                        List<Coordinate> pathCoordinates = new ArrayList<Coordinate>();
                        /*
                             * the pathCondition defines if the current point (pathCoordinates)
                             * contributes mass to the defined path. 
                             */
                        List<Boolean> isBetweenSlopesCondition = new ArrayList<Boolean>();
                        Coordinate triggerCoord = CoverageUtilities.coordinateFromColRow(flowDirColRow[0], flowDirColRow[1], gridGeometry);
                        double elevationValue = elevIter.getSampleDouble(flowDirColRow[0], flowDirColRow[1], 0);
                        flowValue = flowIter.getSampleDouble(flowDirColRow[0], flowDirColRow[1], 0);
                        triggerCoord.z = elevationValue;
                        pathCoordinates.add(triggerCoord);
                        isBetweenSlopesCondition.add(false);
                        /*
                             * found a trigger, start recording and analizing, once created 
                             */
                        double slopeValue;
                        double triggerValue;
                        double lengthWithDegreeLessThanTogglePoint = 0;
                        double deltaElevWithDegreeLessThanTogglePoint = 0;
                        wasBetweenSlopes = false;
                        // in the triggerpoint we assume it is moving
                        boolean isMoving = true;
                        while (isMoving) {
                            // go one down
                            if (!ModelsEngine.go_downstream(flowDirColRow, flowValue))
                                throw new ModelsIllegalargumentException("Unable to go downstream. There might be problems in the consistency of your data.", this, pm);
                            if (useObstacles) {
                                /*
                                     * if we land on a point in which an obstacle stops the path, 
                                     * add the point and stop the path geometry.
                                     */
                                java.awt.Point currentPoint = new java.awt.Point(flowDirColRow[0], flowDirColRow[1]);
                                if (obstaclesSet.contains(currentPoint)) {
                                    pm.message("Found obstacle in " + currentPoint.x + "/" + currentPoint.y);
                                    // we are passing an obstacle
                                    break;
                                }
                            }
                            elevationValue = elevIter.getSampleDouble(flowDirColRow[0], flowDirColRow[1], 0);
                            slopeValue = slopeIter.getSampleDouble(flowDirColRow[0], flowDirColRow[1], 0);
                            triggerValue = triggerIter.getSampleDouble(flowDirColRow[0], flowDirColRow[1], 0);
                            flowValue = flowIter.getSampleDouble(flowDirColRow[0], flowDirColRow[1], 0);
                            if (flowValue == 10) {
                                break;
                            }
                            // pm.message("---> " + flowDirColRow[0] + "/" + flowDirColRow[1]);
                            /*
                                 * add the current coordinate to the path
                                 */
                            Coordinate tmpCoord = CoverageUtilities.coordinateFromColRow(flowDirColRow[0], flowDirColRow[1], gridGeometry);
                            tmpCoord.z = elevationValue;
                            pathCoordinates.add(tmpCoord);
                            int size = pathCoordinates.size();
                            Coordinate c1 = pathCoordinates.get(size - 1);
                            Coordinate c2 = pathCoordinates.get(size - 2);
                            // length is calculated when slowing down starts (between slopes)
                            if (wasBetweenSlopes) {
                                lengthWithDegreeLessThanTogglePoint = lengthWithDegreeLessThanTogglePoint + distance3d(c1, c2, null);
                                isBetweenSlopesCondition.add(true);
                            // when between slopes, delta elev is constant
                            } else {
                                deltaElevWithDegreeLessThanTogglePoint = deltaElevWithDegreeLessThanTogglePoint + Math.abs(c1.z - c2.z);
                                isBetweenSlopesCondition.add(false);
                            }
                            /*
                                 * and check if we will move on
                                 */
                            if (!isNovalue(triggerValue) || slopeValue >= toggleDegrees) {
                                /*
                                     * in the cases in which we:
                                     *  - have a trigger value
                                     *  - the slope is major than the toggleDegrees
                                     *  
                                     *  => we move
                                     */
                                isMoving = true;
                                if (wasBetweenSlopes) {
                                    /*
                                         * if we came into this condition from being between the slopes
                                         * we have to reset the elevation delta used by Vandre, since
                                         * the debris will get speed again. 
                                         */
                                    deltaElevWithDegreeLessThanTogglePoint = 0.0;
                                    lengthWithDegreeLessThanTogglePoint = 0.0;
                                    wasBetweenSlopes = false;
                                // pm.message("--> RE-ENTERING IN STEEP PART AFTER BETWEEN
                                // SLOPES CONDITION");
                                }
                            } else if (slopeValue <= minDegrees) {
                                /*
                                     * supposed to be stopped if below minDegrees. We add the coordinate
                                     * which will be the last.
                                     */
                                isMoving = false;
                            } else if (slopeValue > minDegrees && slopeValue < toggleDegrees) {
                                /*
                                     * in this case we need to check on the base of the Vandre equation 
                                     * with the chosen criterias
                                     */
                                double w = alphaVandre * deltaElevWithDegreeLessThanTogglePoint;
                                if (lengthWithDegreeLessThanTogglePoint > w) {
                                    // debris stops
                                    isMoving = false;
                                } else {
                                    isMoving = true;
                                    wasBetweenSlopes = true;
                                }
                            } else if (isNovalue(elevationValue) || isNovalue(slopeValue) || isNovalue(triggerValue) || isNovalue(flowValue)) {
                                if (isNovalue(elevationValue)) {
                                    pm.errorMessage("Found an elevation novalue along the way");
                                }
                                if (isNovalue(slopeValue)) {
                                    pm.errorMessage("Found a slope novalue along the way");
                                }
                                if (isNovalue(triggerValue)) {
                                    pm.errorMessage("Found a trigger novalue along the way");
                                }
                                if (isNovalue(flowValue)) {
                                    pm.errorMessage("Found a flow novalue along the way");
                                }
                                isMoving = false;
                            } else {
                                throw new RuntimeException();
                            }
                        }
                        /*
                             * create the trigger and linked path geometry 
                             */
                        if (pathCoordinates.size() > 2) {
                            Point triggerPoint = gf.createPoint(pathCoordinates.get(0));
                            LineString pathLine = gf.createLineString(pathCoordinates.toArray(new Coordinate[0]));
                            if (inSoil != null) {
                                cumulateSoil(pathCoordinates, isBetweenSlopesCondition);
                            }
                            int id = featureIndex;
                            SimpleFeatureBuilder builder = new SimpleFeatureBuilder(pathsType);
                            Object[] values = new Object[] { pathLine, id };
                            builder.addAll(values);
                            SimpleFeature pathFeature = builder.buildFeature(null);
                            ((DefaultFeatureCollection) outPaths).add(pathFeature);
                            builder = new SimpleFeatureBuilder(triggersType);
                            values = new Object[] { triggerPoint, id };
                            builder.addAll(values);
                            SimpleFeature triggerFeature = builder.buildFeature(null);
                            ((DefaultFeatureCollection) outIndexedTriggers).add(triggerFeature);
                            featureIndex++;
                        }
                    }
                    /*
                         * we have to go back and start again from after the trigger that 
                         * created the previous calculus 
                         */
                    flowDirColRow[0] = triggerCol;
                    flowDirColRow[1] = triggerRow;
                    // search for the next trigger
                    if (!moveToNextTriggerpoint(triggerIter, flowIter, flowDirColRow)) {
                        // we reached the exit
                        break;
                    }
                    triggerCol = flowDirColRow[0];
                    triggerRow = flowDirColRow[1];
                    flowValue = flowIter.getSampleDouble(flowDirColRow[0], flowDirColRow[1], 0);
                } while (flowValue != 10);
            }
        // isSource
        }
        pm.worked(1);
    }
    pm.done();
    if (inSoil != null) {
        /*
             * make volume
             */
        for (int r = 0; r < rows; r++) {
            for (int c = 0; c < cols; c++) {
                double value = outSoilIter.getSampleDouble(c, r, 0);
                if (isNovalue(value)) {
                    continue;
                }
                value = value * xRes * yRes;
                outSoilIter.setSample(c, r, 0, value);
            }
        }
        outSoil = CoverageUtilities.buildCoverage("cumulatedsoil", outSoilWR, regionMap, inSoil.getCoordinateReferenceSystem());
    }
}
Also used : GridGeometry2D(org.geotools.coverage.grid.GridGeometry2D) RegionMap(org.hortonmachine.gears.utils.RegionMap) ArrayList(java.util.ArrayList) LineString(org.locationtech.jts.geom.LineString) ModelsIllegalargumentException(org.hortonmachine.gears.libs.exceptions.ModelsIllegalargumentException) WritableRaster(java.awt.image.WritableRaster) DefaultFeatureCollection(org.geotools.feature.DefaultFeatureCollection) RandomIter(javax.media.jai.iterator.RandomIter) WritableRandomIter(javax.media.jai.iterator.WritableRandomIter) Point(org.locationtech.jts.geom.Point) Point(org.locationtech.jts.geom.Point) SimpleFeature(org.opengis.feature.simple.SimpleFeature) Geometry(org.locationtech.jts.geom.Geometry) SimpleFeatureType(org.opengis.feature.simple.SimpleFeatureType) Coordinate(org.locationtech.jts.geom.Coordinate) LineString(org.locationtech.jts.geom.LineString) RenderedImage(java.awt.image.RenderedImage) SimpleFeatureBuilder(org.geotools.feature.simple.SimpleFeatureBuilder) Execute(oms3.annotations.Execute)

Aggregations

RandomIter (javax.media.jai.iterator.RandomIter)126 WritableRandomIter (javax.media.jai.iterator.WritableRandomIter)79 WritableRaster (java.awt.image.WritableRaster)71 RegionMap (org.hortonmachine.gears.utils.RegionMap)62 Execute (oms3.annotations.Execute)57 RenderedImage (java.awt.image.RenderedImage)29 GridGeometry2D (org.geotools.coverage.grid.GridGeometry2D)29 Coordinate (org.locationtech.jts.geom.Coordinate)26 GridCoverage2D (org.geotools.coverage.grid.GridCoverage2D)22 Point (java.awt.Point)17 ArrayList (java.util.ArrayList)17 ModelsIllegalargumentException (org.hortonmachine.gears.libs.exceptions.ModelsIllegalargumentException)16 SimpleFeature (org.opengis.feature.simple.SimpleFeature)16 DefaultFeatureCollection (org.geotools.feature.DefaultFeatureCollection)15 Geometry (org.locationtech.jts.geom.Geometry)15 Point (org.locationtech.jts.geom.Point)14 GridCoordinates2D (org.geotools.coverage.grid.GridCoordinates2D)12 GridNode (org.hortonmachine.gears.libs.modules.GridNode)12 SimpleFeatureBuilder (org.geotools.feature.simple.SimpleFeatureBuilder)10 FlowNode (org.hortonmachine.gears.libs.modules.FlowNode)9