Sunday, 7 July 2019

arcobjects - ESRI Raster Remap with Decimals


I have a requirement where the user would like to see the output value in a raster as a decimal. The user will input a series of ranges with a cost associated to them. For instance



0-5, 1.20


5-10, 2.7



10-15, 5.32



These ranges map to values on existing raster. I want to create a new raster using the ReclassOp (or something else that I haven't found yet) that will map the ranges from the existing raster to the appropriate cost value. For example, anything from the initial raster within the 5-10 range will be mapped to 2.7 in the new raster. So my new raster ideally would have 3 values, 1.20, 2.7 and 5.32. When the user clicks on an area in the raster in ArcMap, he should see one of these 3 values (1.20, 2.7 and 5.32) instead of the integer value (1, 3, 5).


This is my current code-


INumberRemap remap = new NumberRemapClass();
remap.MapRange(range.MinValue, range.MaxValue, (int)Math.Round(range.Value));
IReclassOp op = new RasterReclassOpClass();
output = op.ReclassByRemap(_source, remap, _mapNoData);

You can see that I have a value as a decimal (it is representing cost to the user), but INumberRemap.MapRange only accepts an int (currently I am rounding the double). I searched the documentation and could not find a good alternative. Is there a way to remap a range to a decimal value?



EDIT - Code with dividing the raster


My current problem is that this outputRaster (the return raster) has equivalent max and min values (equal to the min value). When I look at the Statistics - Band_1 property in ArcMap on that raster I see "Statistics have not been calculated".


    //Create the remap with ranges
INumberRemap remap = new NumberRemapClass();
foreach (NumberRange range in Ranges)
{
int value = maintainDecimals ? (int)Math.Round(range.Value * 100) : (int)Math.Round(range.Value);

if (range.IsNoData)
remap.MapRangeToNoData(range.MinValue, range.MaxValue);

else if (range.MinValue == range.MaxValue)
remap.MapValue(range.MinValue, value);
else
remap.MapRange(range.MinValue, range.MaxValue, value);
}
IReclassOp reclassOp = new RasterReclassOpClass();

// Reclassify the geodataset
IGeoDataset reclassDataset= reclassOp.ReclassByRemap(_source, remap, false);


//Create const geodataset
RasterMakerOp rasterMaker = new RasterMakerOpClass();
IGeoDataset constDataset = rasterMaker.MakeConstant(100.0, false);

//Divide the reclassed raster to get decimals
IMathOp mathOp = new RasterMathOpsClass();
return mathOp.Divide(reclassDataset, constDataset);

Answer



There are many ways to solve this one. Perhaps the simplest is to remap to 100 times the desired values (which will be integers) and then divide the reclassified grid by 100 (making sure to use floating point division and not integer division).


No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...