#!/usr/bin/env pytest # -*- coding: utf-8 -*- ############################################################################### # $Id$ # # Project: GDAL/OGR Test Suite # Purpose: test librarified gdalmdiminfo # Author: Even Rouault # ############################################################################### # Copyright (c) 2019, Even Rouault # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. ############################################################################### import pathlib import struct import gdaltest import pytest from osgeo import gdal, osr ############################################################################### # Test with non multidim dataset def test_gdalmdiminfo_lib_non_multidim_dataset(): ds = gdal.Open("../gcore/data/byte.tif") with pytest.raises(TypeError): gdal.MultiDimInfo(ds) with pytest.raises(Exception): gdal.MultiDimInfo("../gcore/data/byte.tif") ############################################################################### # Test with a empty MEM dataset def test_gdalmdiminfo_lib_empty_mem_dataset(): drv = gdal.GetDriverByName("MEM") ds = drv.CreateMultiDimensional("") ret = gdal.MultiDimInfo(ds) gdaltest.validate_json(ret, "gdalmdiminfo_output.schema.json") assert ret == {"type": "group", "driver": "MEM", "name": "/"} ############################################################################### # Test with a MEM dataset def test_gdalmdiminfo_lib_mem_dataset(): drv = gdal.GetDriverByName("MEM") ds = drv.CreateMultiDimensional("") rg = ds.GetRootGroup() subg = rg.CreateGroup("subgroup") subg.CreateGroup("subsubgroup") dim0 = rg.CreateDimension("dim0", "my_type", "my_direction", 2) comp0 = gdal.EDTComponent.Create( "x", 0, gdal.ExtendedDataType.Create(gdal.GDT_Int16) ) comp1 = gdal.EDTComponent.Create( "y", 4, gdal.ExtendedDataType.Create(gdal.GDT_Int32) ) dt = gdal.ExtendedDataType.CreateCompound("mytype", 8, [comp0, comp1]) ar = rg.CreateMDArray("ar_compound", [dim0], dt) assert ( ar.Write(struct.pack("hi" * 2, 32767, 1000000, -32768, -1000000)) == gdal.CE_None ) assert ar.SetNoDataValueRaw(struct.pack("hi", 32767, 1000000)) == gdal.CE_None dim1 = rg.CreateDimension("dim1", None, None, 3) ar = rg.CreateMDArray( "ar_2d", [dim0, dim1], gdal.ExtendedDataType.Create(gdal.GDT_Byte) ) ar.SetOffset(1) ar.SetScale(2) ar.SetUnit("foo") srs = osr.SpatialReference() srs.SetFromUserInput("+proj=utm +zone=31 +datum=WGS84") srs.SetDataAxisToSRSAxisMapping([2, 1]) ar.SetSpatialRef(srs) attr = ar.CreateAttribute("myattr", [], gdal.ExtendedDataType.CreateString()) attr.WriteString("bar") ret = gdal.MultiDimInfo(ds, detailed=True, as_text=True) gdaltest.validate_json(ret, "gdalmdiminfo_output.schema.json") expected = """{ "type": "group", "driver": "MEM", "name": "/", "dimensions": [ { "name": "dim0", "full_name": "/dim0", "size": 2, "type": "my_type", "direction": "my_direction" }, { "name": "dim1", "full_name": "/dim1", "size": 3 } ], "arrays": { "ar_2d": { "datatype": "Byte", "dimensions": [ "/dim0", "/dim1" ], "dimension_size": [ 2, 3 ], "attributes": { "myattr": { "datatype": "String", "value": "bar" } }, "unit": "foo", "offset": 1, "scale": 2, "srs": { "wkt": "PROJCRS[\\"unknown\\",BASEGEOGCRS[\\"unknown\\",DATUM[\\"World Geodetic System 1984\\",ELLIPSOID[\\"WGS 84\\",6378137,298.257223563,LENGTHUNIT[\\"metre\\",1]],ID[\\"EPSG\\",6326]],PRIMEM[\\"Greenwich\\",0,ANGLEUNIT[\\"degree\\",0.0174532925199433],ID[\\"EPSG\\",8901]]],CONVERSION[\\"UTM zone 31N\\",METHOD[\\"Transverse Mercator\\",ID[\\"EPSG\\",9807]],PARAMETER[\\"Latitude of natural origin\\",0,ANGLEUNIT[\\"degree\\",0.0174532925199433],ID[\\"EPSG\\",8801]],PARAMETER[\\"Longitude of natural origin\\",3,ANGLEUNIT[\\"degree\\",0.0174532925199433],ID[\\"EPSG\\",8802]],PARAMETER[\\"Scale factor at natural origin\\",0.9996,SCALEUNIT[\\"unity\\",1],ID[\\"EPSG\\",8805]],PARAMETER[\\"False easting\\",500000,LENGTHUNIT[\\"metre\\",1],ID[\\"EPSG\\",8806]],PARAMETER[\\"False northing\\",0,LENGTHUNIT[\\"metre\\",1],ID[\\"EPSG\\",8807]],ID[\\"EPSG\\",16031]],CS[Cartesian,2],AXIS[\\"(E)\\",east,ORDER[1],LENGTHUNIT[\\"metre\\",1,ID[\\"EPSG\\",9001]]],AXIS[\\"(N)\\",north,ORDER[2],LENGTHUNIT[\\"metre\\",1,ID[\\"EPSG\\",9001]]]]", "data_axis_to_srs_axis_mapping": [2, 1] }, "values": [ [0, 0, 0], [0, 0, 0] ] }, "ar_compound": { "datatype": { "name": "mytype", "size": 8, "components": [ { "name": "x", "offset": 0, "type": "Int16" }, { "name": "y", "offset": 4, "type": "Int32" } ] }, "dimensions": [ "/dim0" ], "dimension_size": [ 2 ], "nodata_value": { "x": 32767, "y": 1000000 }, "values": [{"x": 32767, "y": 1000000}, {"x": -32768, "y": -1000000}] } }, "groups": { "subgroup": { "groups": { "subsubgroup": {} } } } }""" try: expected = expected.decode("UTF-8") except Exception: pass if ret != expected: print(ret) assert ret == expected ret = gdal.MultiDimInfo(ds, array="ar_compound", detailed=True, as_text=True) gdaltest.validate_json(ret, "gdalmdiminfo_output.schema.json") expected = """{ "type": "array", "name": "ar_compound", "datatype": { "name": "mytype", "size": 8, "components": [ { "name": "x", "offset": 0, "type": "Int16" }, { "name": "y", "offset": 4, "type": "Int32" } ] }, "dimensions": [ { "name": "dim0", "full_name": "/dim0", "size": 2, "type": "my_type", "direction": "my_direction" } ], "dimension_size": [ 2 ], "nodata_value": { "x": 32767, "y": 1000000 }, "values": [{"x": 32767, "y": 1000000}, {"x": -32768, "y": -1000000}] }""" if ret != expected: print(ret) assert ret == expected ############################################################################### # Test arrayoption @pytest.mark.require_driver("netCDF") def test_gdalmdiminfo_lib_arrayoption(): ret = gdal.MultiDimInfo("../gdrivers/data/netcdf/with_bounds.nc") assert len(ret["arrays"]) == 2 ret = gdal.MultiDimInfo( "../gdrivers/data/netcdf/with_bounds.nc", arrayoptions=["SHOW_BOUNDS=NO"] ) assert len(ret["arrays"]) == 1 ############################################################################### # Test path argument @pytest.mark.require_driver("netCDF") def test_gdalmdiminfo_lib_path_input(): ret = gdal.MultiDimInfo(pathlib.Path("../gdrivers/data/netcdf/with_bounds.nc")) assert ret is not None ############################################################################### def test_gdalmdiminfo_lib_int64(): drv = gdal.GetDriverByName("MEM") ds = drv.CreateMultiDimensional("") rg = ds.GetRootGroup() dim0 = rg.CreateDimension("dim0", "my_type", "my_direction", 1) ar = rg.CreateMDArray("ar", [dim0], gdal.ExtendedDataType.Create(gdal.GDT_Int64)) assert ar.Write(struct.pack("q", -10000000000)) == gdal.CE_None ret = gdal.MultiDimInfo(ds, detailed=True) assert ret["arrays"]["ar"]["values"] == [-10000000000] ############################################################################### def test_gdalmdiminfo_lib_uint64(): drv = gdal.GetDriverByName("MEM") ds = drv.CreateMultiDimensional("") rg = ds.GetRootGroup() dim0 = rg.CreateDimension("dim0", "my_type", "my_direction", 1) ar = rg.CreateMDArray("ar", [dim0], gdal.ExtendedDataType.Create(gdal.GDT_UInt64)) assert ar.Write(struct.pack("Q", 10000000000)) == gdal.CE_None ret = gdal.MultiDimInfo(ds, detailed=True) assert ret["arrays"]["ar"]["values"] == [10000000000]