How to create a new product reader


Warning

This is a very draft version.


New here? See "how to set up an IDE to develop SNAP extensions"

You can put any number of readers in a modules.

Create new module? See "how to create and configure a SNAP extension module"

Engine Integration

Product readers are snap-engine services.

Java code
  1. create package  for example org.esa.snap.dataio.<format-name>
  2.  add Java classes
    • <FormatName>ProductReaderPlugIn implementing org.esa.snap.core.dataio.ProductReaderPlugIn interface
    • <FormatName>ProductReader extending org.esa.snap.core.dataio.AbstractProductReader class
Consider following advices:
  • when implementing AbstractProductReader
    • readBandRasterDataImpl(...)
      • must be thread safe
      • be aware that it can be called in any order
    • make sure to implement close() and clean up resource acquired. Especially close input streams.
  • when implementing ProductReaderPlugIn
    • getDecodeQualification(Object input)
      • make sure method always succeeds; ensure that no exception is thrown
      • make sure that it is fast (terminates within milliseconds)
      • make sure method is thread safe
      • use the INTENDED qualification with care; generic readers shall return SUITABLE at most
  • in general ensure to add appropriate metadata (use e.g. EnvisatProductReader as template)
    • to the product
      • add also IndexCoding, GeoCoding, FlagCoding, MetadataElement, Masks, VectorDataNode etc.
    • to the product reader by implementing ProductIOPlugIn carefully
    • to the module manifest (module.xml)
      • Is there a RGB-Profile associated with this product? If yes, see next section how to provide it to SNAP.
  • Follow advice given in the API doc of interfaces and super classes.


Add unit-level tests in src/test/java.

Add RGB-Profiles

Example:

RGB-Profiles
public class SpotVgtProductReaderPlugIn implements ProductReaderPlugIn {

    public SpotVgtProductReaderPlugIn() {
        RGBImageProfileManager manager = RGBImageProfileManager.getInstance();
        manager.addProfile(new RGBImageProfile("SPOT VGT RGB-1", new String[] {"MIR", "0.5 * (B2 + B3)", "B0 + 0.1 * MIR"}));
        manager.addProfile(new RGBImageProfile("SPOT VGT RGB-2", new String[] {"B3", "0.5 * (B2 + B3)", "B0 + 0.1 * B3"}));
    }
    ...


Service registration

Create resource directory META-INF/services in src/resources

Add file named org.esa.snap.core.dataio.ProductReaderPlugIn

Edit file, for each product reader add its fully qualified class name on a single line (no spaces, no word wrapping):

org.esa.snap.core.dataio.ProductReaderPlugIn
org.esa.snap.dataio.<format-name>.<FormatName>ProductReaderPlugIn

Desktop GUI Integration

If you don't need any special GUI for your reader other than import actions and / or some help pages, then we don't need writing any Java code. Instead we have to add some NetBeans-specific configuration files to the module. Detailed information on NetBeans module development is given here:

First step is to create a resources package named for example

    org.esa.snap.dataio.<format-name> in src/resources

Then add the layer.xml file with following content:

layer.xml
<filesystem>

	<!-- Define action in Actions/Readers/ -->
    <folder name="Actions">
        <folder name="Readers">
            <file name="org-esa-snap-dataio-Import[Format]Product.instance">
                <attr name="instanceCreate" methodvalue="org.openide.awt.Actions.alwaysEnabled"/>
                <attr name="delegate" methodvalue="org.esa.snap.rcp.actions.file.ImportProductAction.create"/>
                <attr name="displayName" stringvalue="[Format-DisplayName]"/>
                <attr name="formatName" stringvalue="[Format-Name]"/>
                <attr name="useAllFileFilter" boolvalue="true"/>
                <attr name="helpId" stringvalue="import[Format]Product"/>
            </file>
        </folder>
    </folder>

	<!-- Place action into menu File/Import/Optical Sensors/[Format] -->
    <folder name="Menu">
        <folder name="File">
            <folder name="Import">
                <folder name="Optical Sensors">
                    <file name="org-esa-snap-dataio-Import[Format]Product.shadow">
                        <attr name="originalFile" 
                              stringvalue="Actions/Readers/org-esa-snap-dataio-Import[Format]Product.instance"/>
                    </file>
                </folder>
            </folder>
        </folder>
    </folder>

</filesystem>
Add extra module metadata

Most of your module's metadata is derived from your project's Maven pom.xml file. However, some so called module "manifest-headers" cannot be derived from it (e.g. the location of the layer.xml file), so we have to provide them in a special configuration file. 

Create source directory src/main/nbm

Add file manifest.mf with following content:

manifest.mf
Manifest-Version: 1.0
AutoUpdate-Show-In-Client: true
AutoUpdate-Essential-Module: true
OpenIDE-Module-Layer: org/esa/snap/dataio/<format-name>/layer.xml
OpenIDE-Module-Java-Dependencies: Java > 1.8
OpenIDE-Module-Display-Category: SNAP

Here is a comprehensive list of all allowed NetBeans "manifest headers": http://bits.netbeans.org/8.0/javadoc/org-openide-modules/org/openide/modules/doc-files/api.html#how-manifest 

Warning: lines in this file must not exceed 72 characters. If so, introduce an LF and start new line with a single space character. 


Code examples in SNAP

snap-geotiff

snap-hdf5

...