/// <summary> /// Constructor /// </summary> /// <param name="rTemplate"></param> /// <param name="newRect"></param> /// <param name="rOutputRaster"></param> public PointDensity(Raster rDEM, Vector vPointCloud, Raster OutputRaster, RasterOperators.KernelShapes eKernel, decimal fSize) : base(new List <Raster>() { rDEM }, OutputRaster) { _vinput = vPointCloud; _routput = OutputRaster; _kshape = eKernel; _fsize = (double)fSize; _fsizedec = fSize; // set the rows to be a certain multiple of fSize windows chunkRows = (int)Math.Ceiling((NUMWINDOWS * fSize) / Math.Abs(rDEM.Extent.CellHeight)); // Calling this again after setting the rows will give us a nicer chunk size SetOpExtent(OpExtent); VectorChunkExtent = ChunkExtent.Buffer(_fsizedec); switch (eKernel) { case RasterOperators.KernelShapes.Circle: area = Math.PI * Math.Pow((double)fSize, 2); break; case RasterOperators.KernelShapes.Square: area = Math.Pow((double)fSize * 2, 2); break; } }
/// <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; } } }