| --- |
| title: Read raster from a netCDF file |
| --- |
| |
| This example reads data in netCDF format. |
| Contrarily to other formats such as PNG or JPEG, |
| a netCDF file can contain an arbitrary number of variables |
| with none of them identified as the main data. |
| Furthermore those data are not necessarily rasters. |
| For this reason, `NetcdfStore` does not implement directly `GridCoverageResource`. |
| Instead, `NetcdfStore` implements the `Aggregate` interface |
| and the desired variable must be specified. |
| The variables may be instances of `GridCoverageResource`, but not necessarily. |
| |
| |
| # Direct dependencies |
| |
| Maven coordinates | Module info | Remarks |
| ----------------------------------- | ------------------------------- | -------------------- |
| `org.apache.sis.storage:sis-netcdf` | `org.apache.sis.storage.netcdf` | |
| `edu.ucar:cdm-core` | | For netCDF-4 or HDF5 |
| |
| The `cdm-core` dependency can be omitted for netCDF-3 (a.k.a. "classic"), |
| |
| |
| # Code example |
| |
| The file name, resource name and geographic coordinates |
| in following code need to be updated for yours data. |
| |
| ```java |
| import java.io.File; |
| import org.apache.sis.storage.Resource; |
| import org.apache.sis.storage.Aggregate; |
| import org.apache.sis.storage.DataStore; |
| import org.apache.sis.storage.DataStores; |
| import org.apache.sis.storage.DataStoreException; |
| import org.apache.sis.storage.GridCoverageResource; |
| import org.apache.sis.coverage.grid.GridCoverage; |
| import org.apache.sis.coverage.grid.GridGeometry; |
| import org.apache.sis.geometry.GeneralEnvelope; |
| import org.apache.sis.referencing.CommonCRS; |
| |
| public class ReadNetCDF { |
| /** |
| * Demo entry point. |
| * |
| * @param args ignored. |
| * @throws DataStoreException if an error occurred while reading the raster. |
| */ |
| public static void main(String[] args) throws DataStoreException { |
| example(); |
| } |
| |
| /** |
| * Reads an example file and prints some information about it. |
| * |
| * @return the raster data. |
| * @throws DataStoreException if an error occurred while reading the raster. |
| */ |
| public static GridCoverage example() throws DataStoreException { |
| GridCoverage data; |
| try (DataStore store = DataStores.open(new File("CMEMS_20220516.nc"))) { |
| /* |
| * See what is inside this file. One of the components listed |
| * below can be given in argument to `findResource(String)`. |
| * For this example we use a hard-coded variable name. |
| */ |
| printComponents(store); |
| Resource resource = store.findResource("sea_surface_height_above_geoid"); |
| if (resource instanceof GridCoverageResource gridded) { |
| /* |
| * Read the resource immediately and fully. |
| * `data` can be used outside the `try` block. |
| */ |
| data = gridded.read(null, null); |
| System.out.printf("Information about the selected resource:%n%s%n", data); |
| /* |
| * Read only a subset of the resource. The Area Of Interest can be specified |
| * in any Coordinate Reference System (CRS). The envelope will be transformed |
| * automatically to the CRS of the data (the data are not transformed). |
| */ |
| var areaOfInterest = new GeneralEnvelope(CommonCRS.WGS84.geographic()); |
| areaOfInterest.setRange(0, 30, 40); // Minimal and maximal latitude values. |
| areaOfInterest.setRange(1, -5, 4); // Minimal and maximal longitude values. |
| data = gridded.read(new GridGeometry(areaOfInterest), null); |
| System.out.printf("Information about the resource subset:%n%s%n", |
| data.getGridGeometry().getExtent()); |
| } else { |
| throw new DataStoreException("Unexpected type of resource."); |
| } |
| } |
| /* |
| * By default, it is possible to continue to use the `GridCoverage` (but not the `Resource`) after |
| * the `DataStore` has been closed because data are in memory. Note that it would not be the case |
| * if deferred data loading was enabled has shown in "Handle rasters bigger than memory" example. |
| */ |
| return data; |
| } |
| |
| /** |
| * Lists the components found in the given data store. |
| * They are the values that can be given to {@link DataStore#findResource(String). |
| * |
| * @param store the data store from which to get the components. |
| * @throws DataStoreException if an error occurred while reading the raster. |
| */ |
| private static void printComponents(DataStore store) throws DataStoreException { |
| if (store instanceof Aggregate agg) { |
| System.out.println("Components found in the data store:"); |
| for (Resource component : agg.components()) { |
| component.getIdentifier().ifPresent((id) -> System.out.println("- " + id)); |
| } |
| } else { |
| System.out.println("The data store is not an aggregate."); |
| } |
| System.out.println(); |
| } |
| } |
| ``` |
| |
| |
| # Output |
| |
| If logging at fine level is enabled, the logs should contain some entries like below. |
| The "Slowness" level is an Apache SIS custom level for operations taking more than an arbitrary time limit. |
| |
| ``` |
| Slowness [GridCoverageResource] Loaded grid coverage between 25°N – 57°N and 19°W – 6°E from file “CMEMS.nc” in 1.03 seconds. |
| FINE [GridCoverageResource] Loaded grid coverage between 29°N – 41°N and 5°W – 5°E from file “CMEMS.nc” in 0.246 seconds. |
| ``` |
| |
| The output depends on the raster data and the locale. |
| Below is an example: |
| |
| ``` |
| Components found in the data store: |
| - sea_surface_height_above_geoid |
| - sea_water_velocity |
| |
| Information about the selected resource: |
| Raster |
| ├─Coverage domain |
| │ ├─Grid extent |
| │ │ ├─Column: [0 … 864] (865 cells) |
| │ │ ├─Row: [0 … 1080] (1081 cells) |
| │ │ └─Time: [0 … 95] (96 cells) |
| │ ├─Geographic extent |
| │ │ ├─Lower bound: 25°59′09″N 19°00′50″W 2022-05-16T00:00:00Z |
| │ │ └─Upper bound: 56°00′50″N 05°00′50″E 2022-05-17T00:00:00Z |
| │ ├─Envelope |
| │ │ ├─Geodetic longitude: -19.01388888888889 … 5.013888888888888 ∆Lon = 0.02777778° |
| │ │ ├─Geodetic latitude: 25.98611111111111 … 56.013888888888886 ∆Lat = 0.02777778° |
| │ │ └─time: 634,392.0 … 634,416.0 ∆t = 0.25 h |
| │ ├─Coordinate reference system |
| │ │ └─time latitude longitude |
| │ └─Conversion (origin in a cell center) |
| │ └─┌ ┐ |
| │ │ 0.027777777777777776 0 0 -19.000 │ |
| │ │ 0 0.027777777777777776 0 26.000 │ |
| │ │ 0 0 0.25 634392.125 │ |
| │ │ 0 0 0 1 │ |
| │ └ ┘ |
| └─Sample dimensions |
| └─┌────────────────────┬────────────────────────┬────────────────────┐ |
| │ Values │ Measures │ Name │ |
| ╞════════════════════╧════════════════════════╧════════════════════╡ |
| │ zos │ |
| ├────────────────────┬────────────────────────┬────────────────────┤ |
| │ -32,767 │ NaN #0 │ Fill value │ |
| │ [-10,000 … 10,000] │ [-10.0000 … 10.0000] m │ Sea surface height │ |
| └────────────────────┴────────────────────────┴────────────────────┘ |
| |
| Information about the resource subset: |
| Column: [504 … 828] (325 cellules) |
| Row: [144 … 504] (361 cellules) |
| Time: [ 0 … 95] (96 cellules) |
| ``` |