Band math to implement Band operation


#1

hello everybody!
I want to use Java API to realize such a band of operation function , This function is the same as the one shown below. entering parameters formulas implements bands calculation ,The parameters are corresponding to the different bands , for example, the input formula of (b1- b2)/(b1+b2) , and then specify b1 and b2 belongs to which bands and finally achieve band operation. can someone give me some advice? I’ve also found the band math tutorial here, but the tutorial doesn’t work.i can’t open the bandmath.
thank you for your any advices!


#2

Maybe the Band Maths dialog doesn’t open because you haven’t resampled your Sentinel-2, if you’re working with Sentinel-2
This should be solved in the latest version. If you go to Help -> Check for Updates you should get the latest updates.
You can also resample the product before hand. Go to Raster -> Geometric Operations -> Resampling and choose a target resolution.
Afterwards, it should be possible to use Band Maths

With the Java API you can do the following to create a band via an expression

Product p = ProductIO.readProduct("path");
p.addBand("bandName", "(b1-b2)/(b1+b2)", ProductData.TYPE_FLOAT32);

#3

Hi marpet ,I’m glad to receive your reply. I’m not use SNAP software,I use the JAVA API to Implement band computing function. in addition,I have two problems and I want to consult you,
firstly ,
Product p = ProductIO.readProduct("path"); p.addBand("bandName", "(b1-b2)/(b1+b2)", ProductData.TYPE_FLOAT32);
How to establish the relationship between parameters("(b1-b2)/(b1+b2)") and remote sensing images? is it by
namespace?
secondly,
my code is as follows:
Band[] band=currentProduct.getBands();//the currentProduct has one band int width=band[0].getRasterWidth(); int height=band[0].getRasterHeight(); Product HDFextrat=new Product("HDF", "GeoTIFF", width, height);// HDFextrat based on the original remote sensing image String code=getCode();//the code is "$2.band_1 + $3.band_1" HDFextrat.addBand("band_1", getCode(), band[0].getDataType());//add a band to HDFproduct String filename=band[0].getName();//the store name String folder="C:\\Users\\雪无尘\\Desktop\\tiff"; //The store path try { System.out.println("nihao"); ProductIO.writeProduct(HDFextrat, folder+"/"+filename+".tif", "GeoTIFF");//Output the product to the hard disk } catch (IOException e) { e.printStackTrace(); } }
the eclipse report an exception :
Exception in thread “AWT-EventQueue-0” java.lang.IllegalArgumentException: [values.length] is less than or equal to [0]
at org.esa.beam.util.Guardian.assertGreaterThan(Guardian.java:154)
at org.esa.beam.dataio.geotiff.internal.TiffType.getType(TiffType.java:134)
at org.esa.beam.dataio.geotiff.internal.TiffDirectoryEntry.(TiffDirectoryEntry.java:44)
at org.esa.beam.dataio.geotiff.internal.TiffIFD.initEntrys(TiffIFD.java:162)
at org.esa.beam.dataio.geotiff.internal.TiffIFD.(TiffIFD.java:59)
at org.esa.beam.dataio.geotiff.internal.TiffHeader.(TiffHeader.java:48)
at org.esa.beam.dataio.geotiff.GeoTiffProductWriter.writeGeoTIFFProduct(GeoTiffProductWriter.java:91)
at org.esa.beam.dataio.geotiff.GeoTiffProductWriter.writeProductNodesImpl(GeoTiffProductWriter.java:81)
at org.esa.beam.framework.dataio.AbstractProductWriter.writeProductNodes(AbstractProductWriter.java:110)
at org.esa.beam.framework.dataio.ProductIO.writeProduct(ProductIO.java:387)
at org.esa.beam.framework.dataio.ProductIO.writeProduct(ProductIO.java:300)
at bandmath.ProductExpression1$ExpressionPaneDialog.onOK(ProductExpression1.java:259)
at org.esa.beam.framework.ui.AbstractDialog$3.actionPerformed(AbstractDialog.java:448)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
Through my repeated search,I think It’S ProductIO.writeProduct(HDFextrat, folder+"/"+filename+".tif", “GeoTIFF”) that reports exception ,however i don‘t know how to solve it. could you help me?
thank you in advance!
best wishes to you!


#4

What I can see from looking at the exception and where it comes from is, that the product which shall be written has no bands.

But it doesn’t come from
ProductIO.writeProduct(HDFextrat, folder+"/"+filename+".tif", "GeoTIFF")
The ‘nihao’ is never printed, I guess.
I think this because I see GUI code in the stacktrace. And I don’t see GUI code in your provided code sample.

I think the class bandmath.ProductExpression1$ExpressionPaneDialog is one of yours.
You call ProductIO.writeProduct() from the onOk() method.


#5

Hi marpet ,i did as you said。however it doesn‘’t work .my codes is as follows:
public static void main(String[] args) throws IOException {
String pro1=“D:\LC81620212013101LGN01\LC81620212013101LGN01_B1.tif”;
String pro2=“D:\LC81620212013101LGN01\LC81620212013101LGN01_B2.tif”;//Tiff path
Product product1=ProductIO.readProduct(pro1);//read tiff
Band band1=product1.getBandAt(0);//get the band of one tiff
int xsize=band1.getRasterWidth();//get the width of the band
int ysize=band1.getRasterHeight();
band1.setName(“band_1”);//rename the band
Product product2=ProductIO.readProduct(pro2);
Band band2=product1.getBandAt(0);
band2.setName(“band_2”);

Product product=new Product(“desProduct”,product1.getProductType(), xsize,ysize);//create a new product to store the computed band
product.addBand(“band_1”, band1.getDataType());
product.addBand(“band_2”, band2.getDataType());
final VirtualBand virtualBand = new VirtualBand(“vb”, band1.getDataType(), xsize, ysize,
“band_1 + band_2”);
product.addBand(virtualBand);//compute the band by the expression of"band_1 + band_2"
final File fileLocation = new File(“D:\LC81620212013101LGN01”);
product.setFileLocation(fileLocation);}

when i use“ProductIO.writeProduct(product, “C:\Users\26078\Desktop”, “GeoTIFF”);”to store the computed Product .it reports
Exception in thread “main” java.lang.IllegalStateException: no product reader for band band_1
at org.esa.beam.jai.BandOpImage.computeProductData(BandOpImage.java:53)
at org.esa.beam.jai.RasterDataNodeOpImage.computeRect(RasterDataNodeOpImage.java:73)
at javax.media.jai.SourcelessOpImage.computeTile(SourcelessOpImage.java:137)
at com.sun.media.jai.util.SunTileScheduler.scheduleTile(SunTileScheduler.java:904)
so how to use the method of addBand(String bandName, String expression, int dataType) of the class of Product。can i
convert the Computed Band to real band? it is a bug in beam
THANK you very much for your help!


#6

This means there is no data attached to the band and no reader is available.
Instead this:

Do this:

ProductUtils.copyBand('band_1', product1, product, true)
ProductUtils.copyBand('band_2', product2, product, true)

But it would be even easier if you read the landsat data as a single product by

Product product=ProductIO.readProduct('D:\LC81620212013101LGN01\LC81620212013101LGN01_MTL.txt' ); //read landsat
# then use GPF to create a product with the result of the expression:
BandDescriptor = jpy.get_type('org.esa.snap.core.gpf.common.BandMathsOp$BandDescriptor')
targetBand1 = BandDescriptor()
targetBand1.name = 'computed'
targetBand1.type = 'float32'
targetBand1.expression = 'band_1 + band_2'

targetBands = jpy.array('org.esa.snap.core.gpf.common.BandMathsOp$BandDescriptor', 1)
targetBands[0] = targetBand1

parameters = HashMap()
parameters.put('targetBands', targetBands)

result = GPF.createProduct('BandMaths', parameters, product)
ProductIO.writeProduct(result, 'C:\Users\26078\Desktop', 'GeoTIFF')