/* * JGrass - Free Open Source Java GIS http://www.jgrass.org * (C) HydroloGIS - www.hydrologis.com * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Library General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) any * later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more * details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Foundation, Inc., 59 * Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.jgrasstools.hortonmachine.modules.hydrogeomorphology.adige.utils; import static org.jgrasstools.hortonmachine.modules.network.networkattributes.NetworkChannel.NETNUMNAME; import static org.jgrasstools.hortonmachine.modules.network.networkattributes.NetworkChannel.PFAFNAME; import java.util.ArrayList; import java.util.List; import org.geotools.feature.FeatureCollection; import org.geotools.feature.FeatureIterator; import org.jgrasstools.gears.libs.monitor.IJGTProgressMonitor; import org.jgrasstools.hortonmachine.modules.hydrogeomorphology.adige.core.HillSlope; import org.jgrasstools.hortonmachine.modules.hydrogeomorphology.adige.core.IHillSlope; import org.jgrasstools.hortonmachine.modules.network.PfafstetterNumber; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; /** * @author Andrea Antonello (www.hydrologis.com) */ public class AdigeUtilities { /** * Generates {@link HillSlope}s from the informations gathered in the provided feature layers. * * @param netFeatureCollection the network features * @param hillslopeFeatureCollection the hillslope features * @param out a printstream for logging * @return the list of ordered hillslopes, starting from the most downstream one * @throws Exception */ public static List<IHillSlope> generateHillSlopes( FeatureCollection<SimpleFeatureType, SimpleFeature> netFeatureCollection, FeatureCollection<SimpleFeatureType, SimpleFeature> hillslopeFeatureCollection, IJGTProgressMonitor out ) throws Exception { out.message("Analizing the network layer..."); List<SimpleFeature> netFeaturesList = new ArrayList<SimpleFeature>(); List<Integer> netIdsList = new ArrayList<Integer>(); ArrayList<PfafstetterNumber> netPfaffsList = new ArrayList<PfafstetterNumber>(); FeatureIterator<SimpleFeature> netFeatureIterator = netFeatureCollection.features(); PfafstetterNumber mostDownStreamPNumber = null; SimpleFeature mostDownStreamNetFeature = null; Integer mostDownStreamLinkId = -1; while( netFeatureIterator.hasNext() ) { SimpleFeature netFeature = (SimpleFeature) netFeatureIterator.next(); String attribute = (String) netFeature.getAttribute(PFAFNAME); PfafstetterNumber current = new PfafstetterNumber(attribute); int tmpId = ((Number) netFeature.getAttribute(NETNUMNAME)).intValue(); if (mostDownStreamPNumber == null) { mostDownStreamPNumber = current; } else { if (current.isDownStreamOf(mostDownStreamPNumber)) { mostDownStreamLinkId = tmpId; mostDownStreamNetFeature = netFeature; mostDownStreamPNumber = current; } } netFeaturesList.add(netFeature); netIdsList.add(tmpId); netPfaffsList.add(current); } netFeatureIterator.close(); /* * search subbasins */ out.message("Analyzing the hillslopes layer..."); List<SimpleFeature> hillslopeFeaturesList = new ArrayList<SimpleFeature>(); List<Integer> hillslopeIdsList = new ArrayList<Integer>(); FeatureIterator<SimpleFeature> hillslopeIterator = hillslopeFeatureCollection.features(); SimpleFeature mostDownstreamHillslopeFeature = null; while( hillslopeIterator.hasNext() ) { SimpleFeature f = hillslopeIterator.next(); int linkAttribute = ((Number) f.getAttribute(NETNUMNAME)).intValue(); if (mostDownStreamLinkId == linkAttribute) { mostDownstreamHillslopeFeature = f; } hillslopeIdsList.add(linkAttribute); hillslopeFeaturesList.add(f); } /* * create all the hillslopes and connect them with their net feature and other hillslopes */ out.message("Linking together network and hillslopes layers..."); ArrayList<IHillSlope> hillslopeElements = new ArrayList<IHillSlope>(); IHillSlope mostDownstreamHillslope = null; if (mostDownStreamPNumber.isEndPiece()) { Integer basinId = hillslopeIdsList.get(0); IHillSlope tmpHslp = new HillSlope(mostDownStreamNetFeature, mostDownstreamHillslopeFeature, mostDownStreamPNumber, basinId.intValue()); hillslopeElements.add(tmpHslp); mostDownstreamHillslope = tmpHslp; } else { /* * almost there, now get from the basins list the ones with that netNums */ ArrayList<SimpleFeature> selectedNetFeatureList = new ArrayList<SimpleFeature>(); ArrayList<Integer> selectedNetId = new ArrayList<Integer>(); for( int i = 0; i < hillslopeFeaturesList.size(); i++ ) { SimpleFeature basinFeature = hillslopeFeaturesList.get(i); Integer link = hillslopeIdsList.get(i); for( int j = 0; j < netFeaturesList.size(); j++ ) { Integer netNum = netIdsList.get(j); if (netNum.equals(link)) { SimpleFeature netFeature = netFeaturesList.get(j); IHillSlope tmpHslp = new HillSlope(netFeature, basinFeature, netPfaffsList.get(j), netNum.intValue()); hillslopeElements.add(tmpHslp); selectedNetFeatureList.add(netFeature); selectedNetId.add(netNum); break; } } } mostDownStreamPNumber = null; Integer mostDownStreamNetId = null; for( SimpleFeature feature : selectedNetFeatureList ) { String attribute = (String) feature.getAttribute(PFAFNAME); PfafstetterNumber current = new PfafstetterNumber(attribute); Integer tmpId = ((Number) feature.getAttribute(NETNUMNAME)).intValue(); if (mostDownStreamPNumber == null) { mostDownStreamPNumber = current; } else { if (current.isDownStreamOf(mostDownStreamPNumber)) { mostDownStreamNetId = tmpId; mostDownStreamPNumber = current; } } } for( int i = 0; i < hillslopeElements.size(); i++ ) { Integer hId = hillslopeIdsList.get(i); if (hId.equals(mostDownStreamNetId)) { mostDownstreamHillslope = hillslopeElements.get(i); break; } } if (hillslopeElements.size() == 1) { mostDownstreamHillslope = hillslopeElements.get(0); } } if (mostDownstreamHillslope == null) throw new RuntimeException(); HillSlope.connectElements(hillslopeElements); List<IHillSlope> orderedHillslopes = new ArrayList<IHillSlope>(); mostDownstreamHillslope.getAllUpstreamElements(orderedHillslopes, null); return orderedHillslopes; } /** * Method to do the routing of a discharge along the link of {@link IHillSlope}. * * @param discharge the discharge to be transported. * @param hillslope the current hillslope. * @param routingType the routing type to use: * <ul> * <li>2 = No Chezi explicitly</li> * <li>3 = Chezi explicitly</li> * <li>4 = Manning equation</li> * </ul> * @return the routing cuencas coefficient. */ public static double doRouting( double discharge, IHillSlope hillslope, int routingType ) { double linkWidth = hillslope.getLinkWidth(8.66, 0.6, 0.0); double linkLength = hillslope.getLinkLength(); double linkSlope = hillslope.getLinkSlope(); double chezLawExpon = -1. / 3.; double chezLawCoeff = 200. / Math.pow(0.000357911, chezLawExpon); double linkChezy = hillslope.getLinkChezi(chezLawCoeff, chezLawExpon); double K_Q = 0; /* ROUTING RATE (K_Q) and CHANNEL VELOCITY (vc) */ // System.out.println(routingtype); switch( routingType ) { case 2: /* No Chezi explicitly */ K_Q = 8.796 * Math.pow(discharge, 1 / 3.) * Math.pow(linkWidth, -1 / 3.) * Math.pow(linkLength, -1) * Math.pow(linkSlope, 2 / 9.); // units // 1/s*/ break; case 3: /* Chezi explicit */ // System.out.println("Chezy"); K_Q = 3 / 2. * Math.pow(discharge, 1. / 3.) * Math.pow(linkChezy, 2. / 3.) * Math.pow(linkWidth, -1. / 3.) * Math.pow(linkLength, -1) * Math.pow(linkSlope, 1. / 3.); // units 1/s break; case 4: /* Mannings equation */ double flowdepth = (1. / 3.) * Math.pow(discharge, 1. / 3.); // depth // m, // input m^3/s; // general // observed // relation for // gc from // molnar and // ramirez 1998 double hydrad = (flowdepth * linkWidth) / (2.f * flowdepth + linkWidth); // m double mannings_n = 1; // 0.030f; // mannings n suggested by Jason via his // observations at // Whitewater for high flows. Low flows will have higher // n ... up to 2x more. K_Q = (Math.pow(hydrad, 2. / 3.) * Math.pow(linkSlope, 1 / 2.) / mannings_n) // m/s // ; // this // term // is v // from // mannings // eqn * Math.pow(linkLength, -1); // 1/s break; } return K_Q; } }