/// <summary> /// Chunk op implementation /// </summary> /// <param name="data"></param> /// <param name="outChunk"></param> protected override void ChunkOp(List <double[]> data, List <double[]> outBuffers) { // Get all the points in this chunk VectorChunkExtent = ChunkExtent.Buffer(_fsizedec); List <Geometry>[,] bins = BinPoints(_vinput.GeometriesIntersectExtent(VectorChunkExtent)); for (int cid = 0; cid < outBuffers[0].Length; cid++) { // Save us a metric Tonne of effort by giving up on nodatavals in the DEM if (data[0][cid] == inNodataVals[0]) { outBuffers[0][cid] = outNodataVals[0]; } else { double outval = 0; decimal[] cidxy = ChunkExtent.Id2XY(cid); Geometry pt2 = new Geometry(wkbGeometryType.wkbPoint); pt2.AddPoint((double)cidxy[0], (double)cidxy[1], 0); List <int[]> bins2test = GetRelevantBins(pt2); // create a circle and then buffer it. foreach (int[] binids in bins2test) { if (binids[0] < bins.GetLength(0) && binids[1] < bins.GetLength(1)) { foreach (Geometry pt in bins[binids[0], binids[1]]) { // If we're a circle we have to do a more expensive operation now if (_kshape == RasterOperators.KernelShapes.Circle) { if (InsideRadius(pt, pt2)) { outval++; } } else if (InsideSquare(pt, pt2)) { outval++; } } } } outBuffers[0][cid] = outval / area; } } }
/// <summary> /// /// </summary> /// <param name="data"></param> /// <param name="id"></param> /// <returns></returns> protected override void CellOp(List <double[]> data, List <double[]> outputs, int id) { outputs[0][id] = outNodataVals[0]; // Speed things up by ignoring nodatas if (data[0][id] == inNodataVals[0]) { return; } // With multimethod errors we need to do some fancy footwork if (_hasVectorPolymask) { if (_shapemask.Count > 0) { decimal[] ptcoords = ChunkExtent.Id2XY(id); // Is this point in one (or more) of the shapes? List <string> shapes = _polymask.ShapesContainPoint((double)ptcoords[0], (double)ptcoords[1], _fieldname); // Now we need to decide what to do based on how many intersections we found. if (shapes.Count == 1) { outputs[0][id] = CellChangeCalc(shapes[0], data, id); } else if (shapes.Count > 1) { throw new NotImplementedException("Overlapping shapes is not yet supported"); } } } else if (_hasRasterizedPolymask) { // The rasterized polymask layer will always be Raster [1]. double rPolymaskVal = data[1][id]; if (rPolymaskVal != inNodataVals[1]) { string fldVal = _rasterVectorFieldVals[(int)rPolymaskVal]; outputs[0][id] = CellChangeCalc(fldVal, data, id); } } // Single method is easier else { outputs[0][id] = CellChangeCalc("", data, id); } }
/// <summary> /// The budget seggregator looks to see if a cell is inside any of the features /// </summary> /// <param name="data"></param> /// <param name="id"></param> private void VectorBudgetSegCellOp(List <double[]> data, int id) { if (_shapemask.Count > 0) { decimal[] ptcoords = ChunkExtent.Id2XY(id); List <string> shapes = _polymask.ShapesContainPoint((double)ptcoords[0], (double)ptcoords[1], _fieldname, _shapemask); if (shapes.Count > 0) { foreach (string fldVal in shapes) { if (!SegStats.ContainsKey(fldVal)) { SegStats[fldVal] = new DoDStats(Stats); } CellChangeCalc(data, id, SegStats[fldVal]); } } } }
/// <summary> /// The budget seggregator looks to see if a cell is inside any of the features /// </summary> /// <param name="data"></param> /// <param name="id"></param> private void VectorBudgetSegCellOp(List <double[]> data, int id) { if (_shapemask.Count > 0) { decimal[] ptcoords = ChunkExtent.Id2XY(id); List <string> shapes = _polymask.ShapesContainPoint((double)ptcoords[0], (double)ptcoords[1], _fieldname, _shapemask); if (shapes.Count > 0) { foreach (string fldVal in shapes) { if (!SegHistograms.ContainsKey(fldVal)) { SegHistograms[fldVal] = new Histogram(_segNumBins, _inputRasters[0]); } SegHistograms[fldVal].AddBinVal(data[0][id]); } } } }
/// <summary> /// Find the intersection of each cell /// </summary> /// <param name="data"></param> /// <param name="outputs"></param> /// <param name="id"></param> protected override void CellOp(List <int[]> data, List <int[]> outputs, int id) { outputs[0][id] = outNodataVals[0]; if (_shapemask.Count > 0 && data[0][id] != inNodataVals[0]) { decimal[] ptcoords = ChunkExtent.Id2XY(id); List <string> shapes = _polymask.ShapesContainPoint((double)ptcoords[0], (double)ptcoords[1], _fieldname, _shapemask); if (shapes.Count > 0) { // Add a dictionary entry if we need to if (!_fieldvals.Contains(shapes[0])) { _fieldvals.Add(shapes[0]); } // 0 is our nodataval here so we pad the list by 1. // Now we just need to remember that the raster is perpertually off by one outputs[0][id] = _fieldvals.IndexOf(shapes[0]) + 1; } } }
/// <summary> /// The actual cell-by-cell operations /// </summary> /// <param name="data"></param> /// <param name="id"></param> /// <returns></returns> protected override void CellOp(List <T[]> data, List <T[]> outputs, int id) { T val = outNodataVals[0]; // This is the raster and scalar case if (_scalar) { if (!data[0][id].Equals(inNodataVals[0])) { switch (_type) { // Choose your math operation case RasterOperators.MathOpType.Addition: val = DynamicMath.Add(data[0][id], _operand); break; case RasterOperators.MathOpType.Subtraction: val = DynamicMath.Subtract(data[0][id], _operand); break; case RasterOperators.MathOpType.Multipication: val = DynamicMath.Multiply(data[0][id], _operand); break; case RasterOperators.MathOpType.Division: val = DynamicMath.Divide(data[0][id], _operand); break; } } } // This is the two raster case else { bool masked = false; // Pure vector method. (This is the slow way) if (_hasVectorPolymask) { decimal[] ptcoords = ChunkExtent.Id2XY(id); List <long> shapes = _polymask.ShapesContainPoint((double)ptcoords[0], (double)ptcoords[1], _shapemask); if (shapes.Count == 0) { masked = true; } } // Rasterized vector method else if (_hasRasterizedPolymask && data.Count == 3 && data[2][id].Equals(inNodataVals[2])) { masked = true; } if (!data[0][id].Equals(inNodataVals[0]) && !data[1][id].Equals(inNodataVals[1]) && !masked) { switch (_type) { // Choose your math operation case RasterOperators.MathOpType.Addition: val = DynamicMath.Add(data[0][id], data[1][id]); break; case RasterOperators.MathOpType.Subtraction: val = DynamicMath.Subtract(data[0][id], data[1][id]); break; case RasterOperators.MathOpType.Multipication: val = DynamicMath.Multiply(data[0][id], data[1][id]); break; case RasterOperators.MathOpType.Division: val = DynamicMath.Divide(data[0][id], data[1][id]); break; } } } outputs[0][id] = val; }