use of javax.media.jai.iterator.WritableRandomIter in project hortonmachine by TheHortonMachine.
the class OmsExtractNetwork method extractNetMode1.
/**
* this method calculates the network imposing a threshold value on the
* product of two quantities, for example the contributing area and the
* slope.
* @throws Exception
*/
private WritableRaster extractNetMode1(RenderedImage flowRI, int novalue, RenderedImage tcaRI, RenderedImage slopeRI) throws Exception {
RandomIter flowRandomIter = RandomIterFactory.create(flowRI, null);
RandomIter tcaRandomIter = RandomIterFactory.create(tcaRI, null);
RandomIter slopeRandomIter = RandomIterFactory.create(slopeRI, null);
// create new RasterData for the network matrix
WritableRaster networkWR = CoverageUtilities.createWritableRaster(cols, rows, Short.class, null, shortNovalue);
WritableRandomIter netRandomIter = RandomIterFactory.createWritable(networkWR, null);
try {
// $NON-NLS-1$
pm.beginTask(msg.message("extractnetwork.extracting"), rows * cols);
processGrid(cols, rows, false, (c, r) -> {
if (pm.isCanceled()) {
return;
}
double tcaValue = tcaRandomIter.getSample(c, r, 0);
double slopeValue = slopeRandomIter.getSampleDouble(c, r, 0);
if (!isNovalue(tcaValue) && !isNovalue(slopeValue)) {
tcaValue = pow(tcaValue, pExp);
if (tcaValue * slopeValue >= pThres) {
netRandomIter.setSample(c, r, 0, NETVALUE);
FlowNode flowNode = new FlowNode(flowRandomIter, cols, rows, c, r, novalue);
FlowNode runningNode = flowNode;
while ((runningNode = runningNode.goDownstream()) != null) {
int rCol = runningNode.col;
int rRow = runningNode.row;
int tmpNetValue = netRandomIter.getSample(rCol, rRow, 0);
if (!isNovalue(tmpNetValue)) {
break;
}
if (runningNode.isMarkedAsOutlet()) {
netRandomIter.setSample(rCol, rRow, 0, NETVALUE);
break;
} else if (runningNode.touchesBound()) {
Node goDownstream = runningNode.goDownstream();
if (goDownstream == null || !goDownstream.isValid()) {
netRandomIter.setSample(rCol, rRow, 0, NETVALUE);
break;
}
}
netRandomIter.setSample(rCol, rRow, 0, NETVALUE);
}
}
} else {
netRandomIter.setSample(c, r, 0, shortNovalue);
}
pm.worked(1);
});
pm.done();
return networkWR;
} finally {
flowRandomIter.done();
tcaRandomIter.done();
slopeRandomIter.done();
netRandomIter.done();
}
}
use of javax.media.jai.iterator.WritableRandomIter 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();
}
}
use of javax.media.jai.iterator.WritableRandomIter in project hortonmachine by TheHortonMachine.
the class OmsMorpher method dilate.
/**
* Morphologically dilates an input raster by a given kernel.
*
* @param inWR the input raster.
* @param regionMap the {@link RegionMap}.
* @param outWR the raster to modify.
* @param kernelArray the kernel to use.
* @param binary if <code>true</code>, binary mode is used.
* @param pm
*/
public static void dilate(WritableRaster inWR, double inNovalue, RegionMap regionMap, WritableRaster outWR, int[] kernelArray, boolean binary, IHMProgressMonitor pm) {
int cols = regionMap.getCols();
int rows = regionMap.getRows();
double xres = regionMap.getXres();
double yres = regionMap.getYres();
WritableRandomIter inIter = RandomIterFactory.createWritable(inWR, null);
WritableRandomIter outIter = RandomIterFactory.createWritable(outWR, null);
int[][] kernel = MorpherHelp.getSquareKernelMatrix(kernelArray);
pm.beginTask("Perform dilation...", cols);
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
GridNode node = new GridNode(inIter, cols, rows, xres, yres, c, r, inNovalue);
if (!node.isValid()) {
double[][] nodeNeighbours = node.getWindow(kernel.length, false);
// apply the kernel
boolean set = false;
boolean doBreak = false;
double max = Double.NEGATIVE_INFINITY;
for (int kr = 0; kr < kernel.length; kr++) {
for (int kc = 0; kc < kernel[0].length; kc++) {
if (kernel[kr][kc] == 1) {
// valid kernel value
if (!isNovalue(nodeNeighbours[kr][kc]) && nodeNeighbours[kr][kc] > max) {
max = nodeNeighbours[kr][kc];
set = true;
if (binary) {
break;
}
}
}
}
if (doBreak) {
break;
}
}
if (set) {
node.setDoubleValueInMap(outIter, max);
} else {
node.setDoubleValueInMap(outIter, HMConstants.doubleNovalue);
}
continue;
} else {
node.setDoubleValueInMap(outIter, node.elevation);
}
}
pm.worked(1);
}
pm.done();
}
use of javax.media.jai.iterator.WritableRandomIter in project hortonmachine by TheHortonMachine.
the class OmsMorpher method skeletonize.
public static void skeletonize(WritableRaster inWR, RegionMap regionMap, WritableRaster outWR, int[][] kernels) {
int cols = regionMap.getCols();
int rows = regionMap.getRows();
WritableRandomIter inIter = RandomIterFactory.createWritable(inWR, null);
WritableRandomIter outIter = RandomIterFactory.createWritable(outWR, null);
BinaryFast binaryData = toBinaryFast(cols, rows, inIter);
new Thin().processSkeleton(binaryData, kernels);
fromBinaryFast(cols, rows, outIter, binaryData);
}
use of javax.media.jai.iterator.WritableRandomIter in project hortonmachine by TheHortonMachine.
the class OmsMorpher method erode.
/**
* Morphologically erodes an input raster by a given kernel.
*
* @param inWR the input raster.
* @param regionMap the {@link RegionMap}.
* @param outWR the raster to modify.
* @param kernelArray the kernel to use.
*/
public static void erode(WritableRaster inWR, double inNovalue, RegionMap regionMap, WritableRaster outWR, int[] kernelArray, IHMProgressMonitor pm) {
int cols = regionMap.getCols();
int rows = regionMap.getRows();
double xres = regionMap.getXres();
double yres = regionMap.getYres();
WritableRandomIter inIter = RandomIterFactory.createWritable(inWR, null);
WritableRandomIter outIter = RandomIterFactory.createWritable(outWR, null);
int[][] kernel = MorpherHelp.getSquareKernelMatrix(kernelArray);
pm.beginTask("Perform erosion...", cols);
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
GridNode node = new GridNode(inIter, cols, rows, xres, yres, c, r, inNovalue);
if (node.isValid()) {
double[][] nodeNeighbours = node.getWindow(kernel.length, false);
// apply the kernel
boolean set = false;
double min = Double.POSITIVE_INFINITY;
for (int kr = 0; kr < kernel.length; kr++) {
for (int kc = 0; kc < kernel[0].length; kc++) {
if (kernel[kr][kc] == 1) {
// valid kernel value
if (isNovalue(nodeNeighbours[kr][kc])) {
// novalue is the absolute min
min = doubleNovalue;
set = true;
break;
} else if (nodeNeighbours[kr][kc] < min) {
min = nodeNeighbours[kr][kc];
set = true;
}
}
}
if (isNovalue(min)) {
break;
}
}
if (set) {
node.setDoubleValueInMap(outIter, min);
} else {
node.setDoubleValueInMap(outIter, node.elevation);
}
continue;
}
}
pm.worked(1);
}
pm.done();
}
Aggregations