public ElevationTreeSmoother( IConvolutionTools <float> convolutionTools, ConvolutionMaskSize contextSize, NullInfillMode nullInfillMode) : base(convolutionTools, contextSize, new ConvolutionAccumulator_Float(CellPassConsts.NullHeight, contextSize), (accum, cSize) => new MeanFilter <float>(accum, cSize, nullInfillMode)) { }
protected static double[,] CreateFilter(ConvolutionMaskSize contextSize, double centerWeight) { var contextSizeAsInt = (int)contextSize; if (contextSizeAsInt < 3 || contextSizeAsInt > 11) { throw new ArgumentException($"Context size of {contextSize} is out of range: 3..11"); } var totalWeight = (contextSizeAsInt * contextSizeAsInt) - 1 + centerWeight; var result = new double[contextSizeAsInt, contextSizeAsInt]; for (var i = 0; i < contextSizeAsInt; i++) { for (var j = 0; j < contextSizeAsInt; j++) { result[i, j] = 1.0d / totalWeight; } } result[contextSizeAsInt / 2, contextSizeAsInt / 2] = centerWeight / totalWeight; return(result); }
public void SingleSubGrid_AtOrigin(ConvolutionMaskSize contextSize) { const float ELEVATION = 10.0f; var tree = DataSmoothingTestUtilities.ConstructSingleSubGridElevationSubGridTreeAtOrigin(ELEVATION); var subGrid = tree.LocateSubGridContaining(SubGridTreeConsts.DefaultIndexOriginOffset, SubGridTreeConsts.DefaultIndexOriginOffset, SubGridTreeConsts.SubGridTreeLevels) as GenericLeafSubGrid <float>; subGrid.Should().NotBeNull(); var result = DataSmoothingTestUtilities.ConstructElevationSubGrid(CellPassConsts.NullHeight); result.Should().NotBeNull(); var accumulator = new ConvolutionAccumulator_Float(CellPassConsts.NullHeight, contextSize); var filter = new MeanFilter <float>(accumulator, contextSize, NullInfillMode.NoInfill); var smoother = new ConvolutionTools <float>(); smoother.Convolve(subGrid, result, filter); // All cell values should remain mostly unchanged due to non-null values around perimeter of subgrid in smoothing context // Check all acquired values in the single subgrid are the same elevation, except for the perimeter values which // will be 2/3 * Elevation due to null values. Some corner vales will have 0.44444 * ElEVATION for same reason SubGridUtilities.SubGridDimensionalIterator((x, y) => { var ok = Math.Abs(result.Items[x, y] = ELEVATION) < 0.0001 || Math.Abs(result.Items[x, y] = (2 / 3) * ELEVATION) < 0.0001 || Math.Abs(result.Items[x, y] = 0.44444f * ELEVATION) < 0.0001; ok.Should().BeTrue(); }); }
public ConvolutionAccumulator_Float(float nullValue, ConvolutionMaskSize contextSize) { NullValue = nullValue; _contextSize = contextSize; _contextSizeSquare = (int)_contextSize * (int)_contextSize; ClearState(); }
public TreeDataSmoother( IConvolutionTools <TV> convolutionTools, ConvolutionMaskSize contextSize, IConvolutionAccumulator <TV> accumulator, Func <IConvolutionAccumulator <TV>, ConvolutionMaskSize, IConvolver <TV> > convolverFactory) { _convolutionTools = convolutionTools ?? throw new ArgumentException("ConvolutionTools is null", nameof(convolutionTools)); _contextSize = contextSize; _accumulator = accumulator; _convolverFactory = convolverFactory; }
public void NullInfillResult_BelowConcensus(ConvolutionMaskSize contextSize) { const float accumValue = 100.0f; var contextSizeAsInt = (int)contextSize; var accum = new ConvolutionAccumulator_Float(CellPassConsts.NullHeight, contextSize) { ConvolutionSourceValue = CellPassConsts.NullHeight }; var concensusFraction = (int)Math.Truncate(0.5 * (contextSizeAsInt * contextSizeAsInt)); for (var i = 0; i < concensusFraction; i++) { accum.Accumulate(accumValue, 1.0); } accum.NullInfillResult().Should().Be(CellPassConsts.NullHeight); }
public void NullInfillResult_AboveConcensus(ConvolutionMaskSize contextSize) { const float accumValue = 100.0f; var contextSizeAsInt = (int)contextSize; var accum = new ConvolutionAccumulator_Float(CellPassConsts.NullHeight, contextSize) { ConvolutionSourceValue = CellPassConsts.NullHeight }; float contextSizeSquare = contextSizeAsInt * contextSizeAsInt; var concensusFraction = (int)Math.Truncate(0.5f * contextSizeSquare); for (var i = 0; i < concensusFraction + 1; i++) { accum.Accumulate(accumValue, 1.0); } var expectedInfillResult = (contextSizeSquare / (concensusFraction + 1)) * ((concensusFraction + 1) * accumValue); accum.NullInfillResult().Should().Be(expectedInfillResult); }
public async Task Test_CutFillTile_TAGFile_FlatDesign(ElevationSource elevationSource, bool useSmoothing, ConvolutionMaskSize maskSize, NullInfillMode nullInfillMode) { AddApplicationGridRouting(); AddClusterComputeGridRouting(); AddDesignProfilerGridRouting(); _fixture.smoothingActive = useSmoothing; _fixture.smootherMaskSize = maskSize; _fixture.smootherNullInfillMode = nullInfillMode; // Construct a site model from a single TAG file var tagFiles = new[] { Path.Combine(TestHelper.CommonTestDataPath, "TestTAGFile.tag") }; var siteModel = DITAGFileAndSubGridRequestsFixture.BuildModel(tagFiles, out _); // Add a flat design to the site model at the minimum elevation in the site model var elevation = elevationSource switch { ElevationSource.MinimumElevation => (float)siteModel.SiteModelExtent.MinZ, ElevationSource.MaximumElevation => (float)siteModel.SiteModelExtent.MaxZ, _ => (float)siteModel.SiteModelExtent.MinZ }; var designUid = DITAGFileAndSubGridRequestsWithIgniteFixture.ConstructFlatTTMDesignEncompassingSiteModel(ref siteModel, elevation); var referenceDesign = new DesignOffset(designUid, 0.0); var palette = PVMPaletteFactory.GetPalette(siteModel, DisplayMode.CutFill, siteModel.SiteModelExtent); var request = new TileRenderRequest(); var arg = SimpleTileRequestArgument(siteModel, DisplayMode.CutFill, palette, volumeType: VolumeComputationType.BetweenFilterAndDesign); // Add the cut/fill design reference to the request, and set the rendering extents to the cell in question, // with an additional 1 meter border around the cell arg.ReferenceDesign = referenceDesign; arg.Extents = siteModel.SiteModelExtent; arg.Extents.Expand(1.0, 1.0); var response = await request.ExecuteAsync(arg); var fileName = @$ "Flat-Elevation-{elevation}-Smoothing-{useSmoothing}-{maskSize}-{nullInfillMode}.bmp"; var path = Path.Combine("TestData", "RenderedTiles", "CutFillTile", fileName); var saveFileName = ""; // @$"C:\Temp\Flat-Elevation-{elevation}-Smoothing-{useSmoothing}-{maskSize}-{nullInfillMode}.bmp"; CheckSimpleRenderTileResponse(response, DisplayMode.CutFill, saveFileName, path); }
public WeightedMeanFilter(IConvolutionAccumulator <T> accumulator, ConvolutionMaskSize contextSize, double centerWeight, NullInfillMode nullInfillMode) : base(accumulator, CreateFilter(contextSize, centerWeight), nullInfillMode) { }
public MeanFilter(IConvolutionAccumulator <T> accumulator, ConvolutionMaskSize contextSize, NullInfillMode nullInfillMode) : base(accumulator, CreateFilter(contextSize, 1), nullInfillMode) { }
public void MultipleSubGrids_AtOrigin(ConvolutionMaskSize contextSize) { const float ELEVATION = 10.0f; var subGridMap = new[]