Problems when cropping S2 image

Hello, I am currently having problems cropping a S2 to a small area, and I am wondering if there is a rounding-up process in SNAP that I am not aware of.

I have a list of lat-lon coordinates around which I need to crop a 32-pixel side square, with each coordinate pair at the centre of each square. To make this easier, instead of converting the lat-lon coordinates to pixel coordinates, I am converting the 32-pixel length to metres (320m for bands 2, 3, 4 and 8) and from this to degrees (0.0028778 with some rounding), and then cropping using geospatial coordinates rather than pixel coordinates.

However, when trying to do so on the command line using the Subset tool via GPT, I end up with a rectangular-shaped cropped image, rather than square. I tried to do it in the SNAP GUI, and the coordinates of the bounding box I entered were rounded up heavily, and I again end up with a much-larger-than-expected rectangular box.

Can you please tell me if it is possible to crop an image to such a small area? I have many pairs of coordinates to do this with, so doing it manually on the GUI really isn’t ideal. I would also be interested if there is a quick way of mapping geospatial coordinates to pixel coordinates and cropping in pixel coordinates instead.

Thank you!

You might want to have a look at the Pixel Extraction tool (menu: Raster /Export / Extract Pixel Values).
There you can specify a list off coordinates and let it extract data from a batch of source products.
But the the window size must not be even. So you can choose between 31 or 33 pixels. That’s because you have one centre pixel and then equal number of pixels in each direction.
This tool can also be invoked from the command line. But usually it is not necessary because you can do the extraction on a batch of products in the GUI.

Regarding the subsetting you have used so far
How long were the sides of the rectangle? Maybe the resulting it was just a rounding issue and just another pixel was included?

Thank you, I had a look at the Pixel Extraction tool however I want my output cropped image to be in .tif format, not .csv, which is what the pixel extraction tool produces. Is there any way of cropping an image to .tif format through the command line in SNAP?

The rectangle I have ended up with is quite far from being a square, it is something like 41 pixels x 67 pixels. I would have understood if it was 33 pixels x 32 pixels or similar, but 41 x 67 is quite far off from being a square. Any advice you can give me would be much appreciated!

If you have always only one coordinate in a product then enabling the “sub-scene” option could help you. This will export to BEAM-DIMAP, but this could then be converted to GeoTiff.

Maybe, you have not considered the earth radius at the latitude of your coordinates. The distance you have calculated is probably only valid at the equator. But actually the difference to 32 pixels is quite big.

You could also try to resample the data (at least just one product) to 10m resolution and then do the cropping. This could eliminate one source of errors.

Hello Marco, I think I have found a way around this problem using the pixel extraction operator. Can you tell me where it is in the graph builder module in the GUI? I am having problems finding it.

It’s not available in the GraphBuilder because it has a special GUI which is not working there.
But you can do the configuration In the Pixel Extraction dialog and then select from its menu File / Display Parameters. These parameters can be put into a graph xml file.

On the command line you can call

> gpt PixEx -h

This will show an example.

Here you find a guide on how creating graphs:
https://senbox.atlassian.net/wiki/spaces/SNAP/pages/70503590/Creating+a+GPF+Graph

I have tried to create a graph as shown in the attached .xml file pixex.xml (1.7 KB) , where I am feeding in the attached list of coordinates latlong_leaks_fortest.csv (250 Bytes) . However, I am getting the following error:

INFO: org.esa.snap.core.gpf.operators.tooladapter.ToolAdapterIO: Initializing external tool adapters
SEVERE: org.esa.s2tbx.dataio.gdal.activator.GDALDistributionInstaller: The environment variable LD_LIBRARY_PATH is not set. It must contain the current folder ‘.’.
INFO: org.esa.snap.core.util.EngineVersionCheckActivator: Please check regularly for new updates for the best SNAP experience.
Executing processing graph
INFO: org.hsqldb.persist.Logger: dataFileCache open start
done.
java.lang.NullPointerException
at org.esa.snap.pixex.PixExOp.createOriginalMeasurements(PixExOp.java:366)
at org.esa.snap.pixex.PixExOp.initialize(PixExOp.java:289)
at org.esa.snap.core.gpf.internal.OperatorContext.initializeOperator(OperatorContext.java:486)
at org.esa.snap.core.gpf.internal.OperatorContext.getTargetProduct(OperatorContext.java:273)
at org.esa.snap.core.gpf.Operator.getTargetProduct(Operator.java:387)
at org.esa.snap.core.gpf.graph.NodeContext.initTargetProduct(NodeContext.java:77)
at org.esa.snap.core.gpf.graph.GraphContext.initNodeContext(GraphContext.java:195)
at org.esa.snap.core.gpf.graph.GraphContext.initOutput(GraphContext.java:162)
at org.esa.snap.core.gpf.graph.GraphContext.(GraphContext.java:91)
at org.esa.snap.core.gpf.graph.GraphContext.(GraphContext.java:64)
at org.esa.snap.core.gpf.graph.GraphProcessor.executeGraph(GraphProcessor.java:128)
at org.esa.snap.core.gpf.main.DefaultCommandLineContext.executeGraph(DefaultCommandLineContext.java:86)
at org.esa.snap.core.gpf.main.CommandLineTool.executeGraph(CommandLineTool.java:534)
at org.esa.snap.core.gpf.main.CommandLineTool.runGraph(CommandLineTool.java:388)
at org.esa.snap.core.gpf.main.CommandLineTool.runGraphOrOperator(CommandLineTool.java:287)
at org.esa.snap.core.gpf.main.CommandLineTool.run(CommandLineTool.java:188)
at org.esa.snap.core.gpf.main.CommandLineTool.run(CommandLineTool.java:121)
at org.esa.snap.core.gpf.main.GPT.run(GPT.java:54)
at org.esa.snap.core.gpf.main.GPT.main(GPT.java:34)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.esa.snap.runtime.Launcher.lambda$run$0(Launcher.java:55)
at org.esa.snap.runtime.Engine.runClientCode(Engine.java:189)
at org.esa.snap.runtime.Launcher.run(Launcher.java:51)
at org.esa.snap.runtime.Launcher.main(Launcher.java:31)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.exe4j.runtime.LauncherEngine.launch(LauncherEngine.java:65)
at com.install4j.runtime.launcher.UnixLauncher.main(UnixLauncher.java:57)

Do you know what I am doing wrong? Thank you!