2

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);
  • 1
    As far as I know, ESRI has never implemented a double-precision floating point grid format. Could you explain why the user needs doubles? There may be a workaround, but it depends on what they will be doing with the raster. – whuber Jul 24 '13 at 15:51
  • I'm waiting to hear back from the PO and customer on why the user wants double precision in the raster. I had the same question, but thought it could be beneficial to see if there is a way to implement this while waiting to hear back from the user. – Darlene Jul 24 '13 at 16:34
  • 1
    It is difficult to fathom why doubles would be needed to display costs: nobody needs more than six decimal places of precision for comparing costs and nobody can discern six orders of magnitude of variation in a map, anyway. – whuber Jul 24 '13 at 17:38
  • I don't need doubles specifically. All I need is 2 decimal places. Sorry for the confusion. Is there a way to get 2 decimal places instead of an int? – Darlene Jul 24 '13 at 17:44
  • 1
    Please tell us what you really want to do, then! Are you trying to display a raster? (Your question is about the legend in that case.) Perform some analysis on it (and if so, what analysis)? And please edit your question to reflect your new understanding of the requirements. – whuber Jul 24 '13 at 18:09
3

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).

  • How would I divide the reclassified grid? I have tried implementing this using ArithmeticFunction and IFunctionRasterDataset and my output raster max and min values are equivalent (both equal to the min value). When I look at the raster properties in ArcMap I see a message under band 1 that "Statistics have not been calculated". Is there something I need to do to calculate the various bands that I have? I shared my new code as end edit in my question above. – Darlene Jul 25 '13 at 13:55
  • I don't see any part of your code that attempts to divide, Darlene. For the syntax please see the help page at help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#/Divide/…. – whuber Jul 25 '13 at 13:59
  • I just posted the code. I've looked at that link but it's doesn't provide an example in .net arcobjects. – Darlene Jul 25 '13 at 14:00
  • 1
    Older help (webhelp.esri.com/arcgisdesktop/9.3/index.cfm?TopicName=divide) asserts you cannot divide by a constant: you first have to create a constant raster. (See the last ArcObjects usage tip.) BTW--this is no reflection on you--I don't think I have ever seen a longer or more painful way to divide one set of numbers by a constant. Even an assembly language program would be shorter! – whuber Jul 25 '13 at 14:28
  • Using the constant raster makes the code much simpler, but I'm still seeing the same issue. This looks like the right approach so there is either a bug somewhere in my code or esri's code. Thanks for your help. – Darlene Jul 25 '13 at 15:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.