Search in sources :

Example 1 with NetLink

use of org.hortonmachine.gears.libs.modules.NetLink in project hortonmachine by TheHortonMachine.

the class OmsNetNumbering method printLinkAsGeoframe.

private void printLinkAsGeoframe(NetLink node, StringBuilder sb) {
    for (NetLink upNode : node.getUpStreamLinks()) {
        sb.append(upNode.num).append(" ").append(node.num).append("\n");
        printLinkAsGeoframe(upNode, sb);
    }
}
Also used : NetLink(org.hortonmachine.gears.libs.modules.NetLink)

Example 2 with NetLink

use of org.hortonmachine.gears.libs.modules.NetLink in project hortonmachine by TheHortonMachine.

the class OmsNetNumbering method printLinkAsIdOutletUpstreamArea.

private void printLinkAsIdOutletUpstreamArea(NetLink node, GridCoverage2D inTca, GridGeometry2D gridGeometry2D, StringBuilder sb) {
    Coordinate coordinate = CoverageUtilities.coordinateFromColRow(node.downCol, node.downRow, gridGeometry2D);
    int tca = node.getTca();
    double area = xres * yres * tca;
    sb.append(node.num).append(";").append(coordinate.x).append(";").append(coordinate.y).append(";").append(area).append("\n");
    for (NetLink upNode : node.getUpStreamLinks()) {
        printLinkAsIdOutletUpstreamArea(upNode, inTca, gridGeometry2D, sb);
    }
}
Also used : NetLink(org.hortonmachine.gears.libs.modules.NetLink) Coordinate(org.locationtech.jts.geom.Coordinate)

Example 3 with NetLink

use of org.hortonmachine.gears.libs.modules.NetLink in project hortonmachine by TheHortonMachine.

the class OmsNetNumbering method process.

@Execute
public void process() throws Exception {
    if (!concatOr(outNetnum == null, doReset)) {
        return;
    }
    checkNull(inFlow, inNet);
    RegionMap regionMap = CoverageUtilities.getRegionParamsFromGridCoverage(inFlow);
    nCols = regionMap.getCols();
    nRows = regionMap.getRows();
    xres = regionMap.getXres();
    yres = regionMap.getYres();
    RenderedImage flowRI = inFlow.getRenderedImage();
    WritableRaster flowWR = CoverageUtilities.renderedImage2IntWritableRaster(flowRI, true);
    WritableRandomIter flowIter = RandomIterFactory.createWritable(flowWR, null);
    RandomIter netIter = CoverageUtilities.getRandomIterator(inNet);
    List<Geometry> pointsList = null;
    if (inPoints != null) {
        pointsList = FeatureUtilities.featureCollectionToGeometriesList(inPoints, true, null);
    }
    WritableRandomIter netNumIter = null;
    try {
        List<NetLink> linksList = new ArrayList<NetLink>();
        WritableRaster netNumWR = ModelsEngine.netNumbering(inFlow, inNet, inTca, pointsList, linksList, pm);
        outNetnum = CoverageUtilities.buildCoverage("netnum", netNumWR, regionMap, inFlow.getCoordinateReferenceSystem());
        netNumIter = RandomIterFactory.createWritable(netNumWR, null);
        int novalue = HMConstants.getIntNovalue(inFlow);
        WritableRaster basinWR = ModelsEngine.extractSubbasins(flowIter, novalue, netIter, netNumIter, nRows, nCols, pm);
        outBasins = CoverageUtilities.buildCoverage("subbasins", basinWR, regionMap, inFlow.getCoordinateReferenceSystem());
        RandomIter subbasinIter = CoverageUtilities.getRandomIterator(outBasins);
        int validCount = 0;
        int invalidCount = 0;
        try {
            for (int r = 0; r < nRows; r++) {
                for (int c = 0; c < nCols; c++) {
                    int value = subbasinIter.getSample(c, r, 0);
                    if (!isNovalue(value)) {
                        validCount++;
                    } else {
                        invalidCount++;
                    }
                }
            }
            // now handle basin hierarchy
            for (NetLink nl1 : linksList) {
                for (NetLink nl2 : linksList) {
                    if (!nl1.equals(nl2)) {
                        nl1.connect(nl2);
                    }
                }
            }
            List<NetLink> rootNetLink = linksList.stream().filter(n -> n.getDownStreamLink() == null).collect(Collectors.toList());
            if (rootNetLink.size() > 1) {
                throw new ModelsRuntimeException("More than one link found to be root link. Check the dataset.", this);
            }
            // create mindmap
            NetLink rootLink = rootNetLink.get(0);
            StringBuilder sb = new StringBuilder();
            sb.append("@startmindmap\n");
            sb.append("* <b>basin stats</b>\\nvalid basin cells: " + validCount + "\\ntotal cells: " + (invalidCount + validCount) + "\\ntotal basin area: " + (validCount * xres * yres) + "\\nx res: " + xres + "\\ny res: " + yres + "\n");
            String level = "*";
            printLinkAsMindMap(rootLink, level, sb);
            sb.append("@endmindmap\n");
            outMindmap = sb.toString();
            if (pDesiredArea != null) {
                HashMap<Integer, Integer> conversionMap = new HashMap<>();
                double desArea = pDesiredArea;
                double minArea = desArea - desArea * pDesiredAreaDelta / 100.0;
                for (NetLink netLink : linksList) {
                    // first handle the most upstream ones and aggregate them with their parents
                    List<NetLink> upStreamLinks = netLink.getUpStreamLinks();
                    if (!netLink.isFixed() && upStreamLinks.isEmpty()) {
                        double area = getLinkOnlyArea(netLink);
                        if (area < minArea) {
                            NetLink parentLink = netLink.getDownStreamLink();
                            if (parentLink != null) {
                                netLink.desiredChainNetLink = parentLink.num;
                                conversionMap.put(netLink.num, parentLink.num);
                                parentLink.getUpStreamLinks().remove(netLink);
                            }
                        }
                    }
                    // point)
                    if (upStreamLinks.size() == 1 && upStreamLinks.get(0).isFixed()) {
                        NetLink fixed = upStreamLinks.get(0);
                        double area = getLinkOnlyArea(netLink);
                        if (area < minArea && !netLink.isFixed()) {
                            // if the area is too small we need to merge it downstream,
                            // but only if the basin itself is not fixed. In that case
                            // it just can't be changed in size, period.
                            NetLink parentLink = netLink.getDownStreamLink();
                            if (parentLink != null) {
                                netLink.desiredChainNetLink = parentLink.num;
                                conversionMap.put(netLink.num, parentLink.num);
                                parentLink.getUpStreamLinks().remove(netLink);
                                parentLink.getUpStreamLinks().add(fixed);
                            }
                        }
                    }
                }
                int convertedSize;
                int postConvertedSize;
                do {
                    convertedSize = conversionMap.size();
                    List<NetLink> links = Arrays.asList(rootLink);
                    aggregateBasins(links, conversionMap, minArea, desArea, 0);
                    postConvertedSize = conversionMap.size();
                } while (postConvertedSize - convertedSize > 0);
                // if (pMaxAllowedConfluences > 0) {
                // // review the tree and solve junctions with more than that number of
                // upstreams
                // do {
                // convertedSize = conversionMap.size();
                // List<NetLink> links = Arrays.asList(rootLink);
                // fixManyChannels(links, conversionMap);
                // postConvertedSize = conversionMap.size();
                // } while( postConvertedSize - convertedSize > 0 );
                // }
                sb = new StringBuilder();
                sb.append("@startmindmap\n");
                sb.append("* <b>basin stats</b>\\nvalid basin cells: " + validCount + "\\ntotal cells: " + (invalidCount + validCount) + "\\ntotal basin area: " + (validCount * xres * yres) + "\\nx res: " + xres + "\\ny res: " + yres + "\\ndesired cells: " + (desArea / xres / yres) + "\n");
                level = "*";
                printLinkAsMindMap(rootLink, level, sb);
                sb.append("@endmindmap\n");
                outDesiredMindmap = sb.toString();
                // build basins info
                StringBuilder basinsInfoSb = new StringBuilder();
                basinsInfoSb.append("basinid;outletX;outletY;area\n");
                printLinkAsIdOutletUpstreamArea(rootLink, inTca, inTca.getGridGeometry(), basinsInfoSb);
                outBasinsInfo = basinsInfoSb.toString();
                WritableRaster desiredSubbasinsWR = CoverageUtilities.createWritableRaster(nCols, nRows, Integer.class, null, HMConstants.intNovalue);
                WritableRandomIter desiredSubbasinsWIter = RandomIterFactory.createWritable(desiredSubbasinsWR, null);
                for (int r = 0; r < nRows; r++) {
                    for (int c = 0; c < nCols; c++) {
                        int value = subbasinIter.getSample(c, r, 0);
                        if (!isNovalue(value)) {
                            Integer convertedBasinNum = conversionMap.get(value);
                            if (convertedBasinNum != null) {
                                // check if the converted has been converted also in some
                                // different thread
                                Integer convertedBasinNumTmp = conversionMap.get(convertedBasinNum);
                                while (convertedBasinNumTmp != null) {
                                    convertedBasinNum = convertedBasinNumTmp;
                                    convertedBasinNumTmp = conversionMap.get(convertedBasinNumTmp);
                                }
                                desiredSubbasinsWIter.setSample(c, r, 0, convertedBasinNum);
                            } else {
                                desiredSubbasinsWIter.setSample(c, r, 0, value);
                            }
                        }
                    }
                }
                desiredSubbasinsWIter.done();
                outDesiredBasins = CoverageUtilities.buildCoverageWithNovalue("desiredsubbasins", desiredSubbasinsWR, regionMap, inFlow.getCoordinateReferenceSystem(), HMConstants.intNovalue);
            }
            // build geoframe topology input
            StringBuilder geoframeSb = new StringBuilder();
            geoframeSb.append(rootLink.num).append(" ").append(0).append("\n");
            printLinkAsGeoframe(rootLink, geoframeSb);
            outGeoframeTopology = geoframeSb.toString();
        } finally {
            subbasinIter.done();
        }
    } finally {
        flowIter.done();
        netIter.done();
        if (netNumIter != null)
            netNumIter.done();
    }
}
Also used : HMModel(org.hortonmachine.gears.libs.modules.HMModel) Arrays(java.util.Arrays) ModelsEngine(org.hortonmachine.gears.libs.modules.ModelsEngine) Label(oms3.annotations.Label) RandomIter(javax.media.jai.iterator.RandomIter) Author(oms3.annotations.Author) GridCoverage2D(org.geotools.coverage.grid.GridCoverage2D) Coordinate(org.locationtech.jts.geom.Coordinate) In(oms3.annotations.In) HashMap(java.util.HashMap) OMSNETNUMBERING_DESCRIPTION(org.hortonmachine.hmachine.modules.network.netnumbering.OmsNetNumbering.OMSNETNUMBERING_DESCRIPTION) License(oms3.annotations.License) Status(oms3.annotations.Status) Execute(oms3.annotations.Execute) ArrayList(java.util.ArrayList) NETWORK(org.hortonmachine.gears.libs.modules.HMConstants.NETWORK) Description(oms3.annotations.Description) OMSNETNUMBERING_AUTHORNAMES(org.hortonmachine.hmachine.modules.network.netnumbering.OmsNetNumbering.OMSNETNUMBERING_AUTHORNAMES) OMSNETNUMBERING_LICENSE(org.hortonmachine.hmachine.modules.network.netnumbering.OmsNetNumbering.OMSNETNUMBERING_LICENSE) Name(oms3.annotations.Name) HMConstants(org.hortonmachine.gears.libs.modules.HMConstants) NetLink(org.hortonmachine.gears.libs.modules.NetLink) Unit(oms3.annotations.Unit) RandomIterFactory(javax.media.jai.iterator.RandomIterFactory) Out(oms3.annotations.Out) OMSNETNUMBERING_LABEL(org.hortonmachine.hmachine.modules.network.netnumbering.OmsNetNumbering.OMSNETNUMBERING_LABEL) SimpleFeatureCollection(org.geotools.data.simple.SimpleFeatureCollection) GridGeometry2D(org.geotools.coverage.grid.GridGeometry2D) RenderedImage(java.awt.image.RenderedImage) HMConstants.isNovalue(org.hortonmachine.gears.libs.modules.HMConstants.isNovalue) WritableRandomIter(javax.media.jai.iterator.WritableRandomIter) OMSNETNUMBERING_STATUS(org.hortonmachine.hmachine.modules.network.netnumbering.OmsNetNumbering.OMSNETNUMBERING_STATUS) FeatureUtilities(org.hortonmachine.gears.utils.features.FeatureUtilities) Collectors(java.util.stream.Collectors) CoverageUtilities(org.hortonmachine.gears.utils.coverage.CoverageUtilities) OMSNETNUMBERING_KEYWORDS(org.hortonmachine.hmachine.modules.network.netnumbering.OmsNetNumbering.OMSNETNUMBERING_KEYWORDS) List(java.util.List) OMSNETNUMBERING_NAME(org.hortonmachine.hmachine.modules.network.netnumbering.OmsNetNumbering.OMSNETNUMBERING_NAME) ModelsRuntimeException(org.hortonmachine.gears.libs.exceptions.ModelsRuntimeException) RegionMap(org.hortonmachine.gears.utils.RegionMap) OMSNETNUMBERING_AUTHORCONTACTS(org.hortonmachine.hmachine.modules.network.netnumbering.OmsNetNumbering.OMSNETNUMBERING_AUTHORCONTACTS) Geometry(org.locationtech.jts.geom.Geometry) WritableRaster(java.awt.image.WritableRaster) Keywords(oms3.annotations.Keywords) HashMap(java.util.HashMap) RegionMap(org.hortonmachine.gears.utils.RegionMap) ArrayList(java.util.ArrayList) RandomIter(javax.media.jai.iterator.RandomIter) WritableRandomIter(javax.media.jai.iterator.WritableRandomIter) Geometry(org.locationtech.jts.geom.Geometry) NetLink(org.hortonmachine.gears.libs.modules.NetLink) WritableRandomIter(javax.media.jai.iterator.WritableRandomIter) WritableRaster(java.awt.image.WritableRaster) ModelsRuntimeException(org.hortonmachine.gears.libs.exceptions.ModelsRuntimeException) RenderedImage(java.awt.image.RenderedImage) Execute(oms3.annotations.Execute)

Example 4 with NetLink

use of org.hortonmachine.gears.libs.modules.NetLink in project hortonmachine by TheHortonMachine.

the class OmsNetNumbering method getLinkOnlyTca.

private int getLinkOnlyTca(NetLink netLink) {
    int upLinksTca = 0;
    for (NetLink nl : netLink.getUpStreamLinks()) {
        upLinksTca += nl.getTca();
    }
    int tca = netLink.getTca() - upLinksTca;
    return tca;
}
Also used : NetLink(org.hortonmachine.gears.libs.modules.NetLink)

Example 5 with NetLink

use of org.hortonmachine.gears.libs.modules.NetLink in project hortonmachine by TheHortonMachine.

the class OmsNetNumbering method aggregateBasins.

private void aggregateBasins(List<NetLink> currentLevelLinks, HashMap<Integer, Integer> conversionMap, double minArea, double desArea, int level) throws Exception {
    for (NetLink netLink : currentLevelLinks) {
        List<NetLink> ups = netLink.getUpStreamLinks();
        double area = getLinkOnlyArea(netLink);
        if (area < minArea) {
            if (!ups.isEmpty()) {
                while (area < minArea) {
                    // find nearest to area
                    double minDelta = Double.POSITIVE_INFINITY;
                    NetLink minDeltaLink = null;
                    double minAddArea = 0;
                    boolean hadOne = false;
                    int fixedCounts = 0;
                    for (NetLink nl : ups) {
                        if (nl.isFixed()) {
                            // fixed ones can't be joined to downstream
                            fixedCounts++;
                            continue;
                        }
                        // check if it wasn't used already (i.e. it has no parent)
                        if (nl.desiredChainNetLink == null) {
                            hadOne = true;
                            double nlArea = getLinkOnlyArea(nl);
                            double delta = Math.abs(desArea - (area + nlArea));
                            if (delta < minDelta) {
                                minDelta = delta;
                                minDeltaLink = nl;
                                minAddArea = nlArea;
                            }
                        }
                    }
                    if (fixedCounts == ups.size() && fixedCounts != 0) {
                        if (!netLink.isFixed()) {
                            // all upstream are fixed and area is small, aggregate downstream
                            // if the last basin is too small, let's aggregate it with the
                            // parent
                            NetLink parentLink = netLink.getDownStreamLink();
                            netLink.desiredChainNetLink = parentLink.num;
                            conversionMap.put(netLink.num, parentLink.num);
                            parentLink.getUpStreamLinks().remove(netLink);
                            for (NetLink nl : ups) {
                                nl.setDownStreamLink(parentLink);
                            }
                            parentLink.getUpStreamLinks().addAll(ups);
                            break;
                        } else {
                            // nothing to do here, go up one level and break out
                            aggregateBasins(ups, conversionMap, minArea, desArea, level + 1);
                            break;
                        }
                    } else {
                        if (!hadOne) {
                            // seems like the basins are not enough
                            break;
                        }
                        if (minDeltaLink != null) {
                            minDeltaLink.desiredChainNetLink = netLink.num;
                            area += minAddArea;
                            // adjust the upstream channel end and area
                            conversionMap.put(minDeltaLink.num, netLink.num);
                            ups.remove(minDeltaLink);
                            List<NetLink> minDeltaUpstreamLinks = minDeltaLink.getUpStreamLinks();
                            for (NetLink nl : minDeltaUpstreamLinks) {
                                nl.setDownStreamLink(netLink);
                            }
                            ups.addAll(minDeltaUpstreamLinks);
                        }
                    }
                }
            } else {
                // if the last basin is too small, let's aggregate it with the parent
                if (!netLink.isFixed()) {
                    NetLink parentLink = netLink.getDownStreamLink();
                    netLink.desiredChainNetLink = parentLink.num;
                    conversionMap.put(netLink.num, parentLink.num);
                    parentLink.getUpStreamLinks().remove(netLink);
                }
            }
        } else {
            // go up one level
            if (!ups.isEmpty()) {
                aggregateBasins(ups, conversionMap, minArea, desArea, level + 1);
            }
        }
    }
}
Also used : NetLink(org.hortonmachine.gears.libs.modules.NetLink)

Aggregations

NetLink (org.hortonmachine.gears.libs.modules.NetLink)6 RenderedImage (java.awt.image.RenderedImage)1 WritableRaster (java.awt.image.WritableRaster)1 ArrayList (java.util.ArrayList)1 Arrays (java.util.Arrays)1 HashMap (java.util.HashMap)1 List (java.util.List)1 Collectors (java.util.stream.Collectors)1 RandomIter (javax.media.jai.iterator.RandomIter)1 RandomIterFactory (javax.media.jai.iterator.RandomIterFactory)1 WritableRandomIter (javax.media.jai.iterator.WritableRandomIter)1 Author (oms3.annotations.Author)1 Description (oms3.annotations.Description)1 Execute (oms3.annotations.Execute)1 In (oms3.annotations.In)1 Keywords (oms3.annotations.Keywords)1 Label (oms3.annotations.Label)1 License (oms3.annotations.License)1 Name (oms3.annotations.Name)1 Out (oms3.annotations.Out)1